diff options
Diffstat (limited to 'drivers/mfd')
| -rw-r--r-- | drivers/mfd/sec-common.c | 34 | ||||
| -rw-r--r-- | drivers/mfd/sec-i2c.c | 29 | ||||
| -rw-r--r-- | drivers/mfd/sec-irq.c | 73 |
3 files changed, 130 insertions, 6 deletions
diff --git a/drivers/mfd/sec-common.c b/drivers/mfd/sec-common.c index bd8b5f968689..22f6c74eb6c0 100644 --- a/drivers/mfd/sec-common.c +++ b/drivers/mfd/sec-common.c @@ -16,6 +16,7 @@ #include <linux/mfd/samsung/irq.h> #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps13.h> +#include <linux/mfd/samsung/s2mu005.h> #include <linux/module.h> #include <linux/of.h> #include <linux/pm.h> @@ -105,22 +106,39 @@ static const struct mfd_cell s2mpu05_devs[] = { MFD_CELL_RES("s2mps15-rtc", s2mpu05_rtc_resources), }; +static const struct resource s2mu005_muic_resources[] = { + DEFINE_RES_IRQ_NAMED(S2MU005_IRQ_MUIC_ATTACH, "attach"), + DEFINE_RES_IRQ_NAMED(S2MU005_IRQ_MUIC_DETACH, "detach"), +}; + +static const struct mfd_cell s2mu005_devs[] = { + MFD_CELL_NAME("s2mu005-charger"), + MFD_CELL_OF("s2mu005-flash", NULL, NULL, 0, 0, "samsung,s2mu005-flash"), + MFD_CELL_OF("s2mu005-muic", s2mu005_muic_resources, NULL, 0, 0, "samsung,s2mu005-muic"), + MFD_CELL_OF("s2mu005-rgb", NULL, NULL, 0, 0, "samsung,s2mu005-rgb"), +}; + static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic) { - unsigned int val; + unsigned int reg, mask, val; - /* For s2mpg1x, the revision is in a different regmap */ switch (sec_pmic->device_type) { case S2MPG10: case S2MPG11: + /* For s2mpg1x, the revision is in a different regmap */ return; - default: + case S2MU005: + reg = S2MU005_REG_ID; + mask = S2MU005_ID_MASK; break; + default: + /* For other device types, REG_ID is always the first register. */ + reg = S2MPS11_REG_ID; + mask = ~0; } - /* For each device type, the REG_ID is always the first register */ - if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val)) - dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val); + if (!regmap_read(sec_pmic->regmap_pmic, reg, &val)) + dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", field_get(mask, val)); } static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic) @@ -250,6 +268,10 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq, sec_devs = s2mpu05_devs; num_sec_devs = ARRAY_SIZE(s2mpu05_devs); break; + case S2MU005: + sec_devs = s2mu005_devs; + num_sec_devs = ARRAY_SIZE(s2mu005_devs); + break; default: return dev_err_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n", diff --git a/drivers/mfd/sec-i2c.c b/drivers/mfd/sec-i2c.c index 3132b849b4bc..d8609886fcc8 100644 --- a/drivers/mfd/sec-i2c.c +++ b/drivers/mfd/sec-i2c.c @@ -17,6 +17,7 @@ #include <linux/mfd/samsung/s2mps14.h> #include <linux/mfd/samsung/s2mps15.h> #include <linux/mfd/samsung/s2mpu02.h> +#include <linux/mfd/samsung/s2mu005.h> #include <linux/mfd/samsung/s5m8767.h> #include <linux/mod_devicetable.h> #include <linux/module.h> @@ -66,6 +67,19 @@ static bool s2mpu02_volatile(struct device *dev, unsigned int reg) } } +static bool s2mu005_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case S2MU005_REG_CHGR_INT1M: + case S2MU005_REG_FLED_INT1M: + case S2MU005_REG_MUIC_INT1M: + case S2MU005_REG_MUIC_INT2M: + return false; + default: + return true; + } +} + static const struct regmap_config s2dos05_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -130,6 +144,15 @@ static const struct regmap_config s2mpu05_regmap_config = { .val_bits = 8, }; +static const struct regmap_config s2mu005_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = S2MU005_REG_MUIC_LDOADC_H, + .volatile_reg = s2mu005_volatile, + .cache_type = REGCACHE_FLAT_S, +}; + static const struct regmap_config s5m8767_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -203,6 +226,11 @@ static const struct sec_pmic_i2c_platform_data s2mpu05_data = { .device_type = S2MPU05, }; +static const struct sec_pmic_i2c_platform_data s2mu005_data = { + .regmap_cfg = &s2mu005_regmap_config, + .device_type = S2MU005, +}; + static const struct sec_pmic_i2c_platform_data s5m8767_data = { .regmap_cfg = &s5m8767_regmap_config, .device_type = S5M8767X, @@ -217,6 +245,7 @@ static const struct of_device_id sec_pmic_i2c_of_match[] = { { .compatible = "samsung,s2mps15-pmic", .data = &s2mps15_data, }, { .compatible = "samsung,s2mpu02-pmic", .data = &s2mpu02_data, }, { .compatible = "samsung,s2mpu05-pmic", .data = &s2mpu05_data, }, + { .compatible = "samsung,s2mu005-pmic", .data = &s2mu005_data, }, { .compatible = "samsung,s5m8767-pmic", .data = &s5m8767_data, }, { }, }; diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 133188391f7c..42862807be1a 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c @@ -16,6 +16,7 @@ #include <linux/mfd/samsung/s2mps14.h> #include <linux/mfd/samsung/s2mpu02.h> #include <linux/mfd/samsung/s2mpu05.h> +#include <linux/mfd/samsung/s2mu005.h> #include <linux/mfd/samsung/s5m8767.h> #include <linux/regmap.h> #include "sec-core.h" @@ -223,6 +224,65 @@ static const struct regmap_irq s2mpu05_irqs[] = { REGMAP_IRQ_REG(S2MPU05_IRQ_TSD, 2, S2MPU05_IRQ_TSD_MASK), }; +static const struct regmap_irq s2mu005_irqs[] = { + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_DETBAT, 0, S2MU005_IRQ_CHGR_DETBAT_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_BAT, 0, S2MU005_IRQ_CHGR_BAT_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_IVR, 0, S2MU005_IRQ_CHGR_IVR_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_EVENT, 0, S2MU005_IRQ_CHGR_EVENT_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_CHG, 0, S2MU005_IRQ_CHGR_CHG_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_VMID, 0, S2MU005_IRQ_CHGR_VMID_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_WCIN, 0, S2MU005_IRQ_CHGR_WCIN_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_CHGR_VBUS, 0, S2MU005_IRQ_CHGR_VBUS_MASK), + + REGMAP_IRQ_REG(S2MU005_IRQ_FLED_LBPROT, 1, S2MU005_IRQ_FLED_LBPROT_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_FLED_OPENCH2, 1, S2MU005_IRQ_FLED_OPENCH2_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_FLED_OPENCH1, 1, S2MU005_IRQ_FLED_OPENCH1_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_FLED_SHORTCH2, 1, S2MU005_IRQ_FLED_SHORTCH2_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_FLED_SHORTCH1, 1, S2MU005_IRQ_FLED_SHORTCH1_MASK), + + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_ATTACH, 2, S2MU005_IRQ_MUIC_ATTACH_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_DETACH, 2, S2MU005_IRQ_MUIC_DETACH_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_KP, 2, S2MU005_IRQ_MUIC_KP_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_LKP, 2, S2MU005_IRQ_MUIC_LKP_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_LKR, 2, S2MU005_IRQ_MUIC_LKR_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_RIDCHG, 2, S2MU005_IRQ_MUIC_RIDCHG_MASK), + + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_VBUSON, 3, S2MU005_IRQ_MUIC_VBUSON_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_RSVD, 3, S2MU005_IRQ_MUIC_RSVD_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_ADC, 3, S2MU005_IRQ_MUIC_ADC_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_STUCK, 3, S2MU005_IRQ_MUIC_STUCK_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_STUCKRCV, 3, S2MU005_IRQ_MUIC_STUCKRCV_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_MHDL, 3, S2MU005_IRQ_MUIC_MHDL_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_AVCHG, 3, S2MU005_IRQ_MUIC_AVCHG_MASK), + REGMAP_IRQ_REG(S2MU005_IRQ_MUIC_VBUSOFF, 3, S2MU005_IRQ_MUIC_VBUSOFF_MASK), +}; + +static unsigned int s2mu005_irq_get_reg(struct regmap_irq_chip_data *data, + unsigned int base, int index) +{ + const unsigned int irqf_regs[] = { + S2MU005_REG_CHGR_INT1, + S2MU005_REG_FLED_INT1, + S2MU005_REG_MUIC_INT1, + S2MU005_REG_MUIC_INT2, + }; + const unsigned int mask_regs[] = { + S2MU005_REG_CHGR_INT1M, + S2MU005_REG_FLED_INT1M, + S2MU005_REG_MUIC_INT1M, + S2MU005_REG_MUIC_INT2M, + }; + + switch (base) { + case S2MU005_REG_CHGR_INT1: + return irqf_regs[index]; + case S2MU005_REG_CHGR_INT1M: + return mask_regs[index]; + } + + return base; +} + static const struct regmap_irq s5m8767_irqs[] = { REGMAP_IRQ_REG(S5M8767_IRQ_PWRR, 0, S5M8767_IRQ_PWRR_MASK), REGMAP_IRQ_REG(S5M8767_IRQ_PWRF, 0, S5M8767_IRQ_PWRF_MASK), @@ -337,6 +397,16 @@ static const struct regmap_irq_chip s2mpu05_irq_chip = { .ack_base = S2MPU05_REG_INT1, }; +static const struct regmap_irq_chip s2mu005_irq_chip = { + .name = "s2mu005", + .irqs = s2mu005_irqs, + .num_irqs = ARRAY_SIZE(s2mu005_irqs), + .num_regs = 4, + .status_base = S2MU005_REG_CHGR_INT1, + .mask_base = S2MU005_REG_CHGR_INT1M, + .get_irq_reg = s2mu005_irq_get_reg, +}; + static const struct regmap_irq_chip s5m8767_irq_chip = { .name = "s5m8767", .irqs = s5m8767_irqs, @@ -442,6 +512,9 @@ struct regmap_irq_chip_data *sec_irq_init(struct sec_pmic_dev *sec_pmic) case S2MPU05: sec_irq_chip = &s2mpu05_irq_chip; break; + case S2MU005: + sec_irq_chip = &s2mu005_irq_chip; + break; default: return dev_err_ptr_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n", sec_pmic->device_type); |
