* [PATCHv5 0/3] mfd: sec-core: Add support S2MPU02 PMIC device
@ 2014-06-16 4:42 Chanwoo Choi
2014-06-16 4:42 ` [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device Chanwoo Choi
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Chanwoo Choi @ 2014-06-16 4:42 UTC (permalink / raw)
To: lee.jones, sbkim73, sameo
Cc: k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel,
Chanwoo Choi
his patchset add Samsung S2MPU02 PMIC device driver in exiting S2MPS11 PMIC
driver because S2MPU02 has a little different between S2MPU02 and S2MPS1x.
The S2MPU02 PMIC has LDO[1-28] and BUCK[1-7] regulators.
Changes from v4:
- This patchset is rebased on 'Linux 3.16-rc1'.
Changes from v3:
- Fix bug of s2mps14_regulator_set_suspend_disable()
Changes from v2:
- Change patchset name
- Remove un-necessary switch statement
- Add acked message by Mark Brown for regulator patch
- Add reviewed message by Krzysztof Kozlowski for all patchs
Changes from v1:
- Fix typo about patch description
- Use existing suspend_state variable instead of defining new variable for S2MPU02
- Remove unnecessary parameter of s2mps11_pmic_dt_parse()
- Remove unfit comment of s2mpu02.h file
- Both patch2 and patch3 should be squashed on patch2
Chanwoo Choi (3):
mfd: sec-core: Add support for S2MPU02 device
regulator: s2mps11: Add support S2MPU02 regulator device
dt-bindings: mfd: s2mps11: Add support S2MPU02 PMIC
Documentation/devicetree/bindings/mfd/s2mps11.txt | 7 +-
drivers/mfd/sec-core.c | 44 +++
drivers/mfd/sec-irq.c | 88 ++++++
drivers/regulator/s2mps11.c | 321 ++++++++++++++++++++--
include/linux/mfd/samsung/core.h | 1 +
include/linux/mfd/samsung/irq.h | 24 ++
include/linux/mfd/samsung/s2mpu02.h | 201 ++++++++++++++
7 files changed, 663 insertions(+), 23 deletions(-)
create mode 100644 include/linux/mfd/samsung/s2mpu02.h
--
1.8.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device 2014-06-16 4:42 [PATCHv5 0/3] mfd: sec-core: Add support S2MPU02 PMIC device Chanwoo Choi @ 2014-06-16 4:42 ` Chanwoo Choi 2014-06-16 13:03 ` Lee Jones 2014-06-16 4:42 ` [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 3/3] dt-bindings: mfd: s2mps11: Add support S2MPU02 PMIC Chanwoo Choi 2 siblings, 1 reply; 8+ messages in thread From: Chanwoo Choi @ 2014-06-16 4:42 UTC (permalink / raw) To: lee.jones, sbkim73, sameo Cc: k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel, Chanwoo Choi Add support for Samsung S2MPU02 PMIC device to the MFD sec-core driver. The S2MPU02 device includes PMIC/RTC/Clock devices. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> --- drivers/mfd/sec-core.c | 19 +++++++++ drivers/mfd/sec-irq.c | 88 ++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/samsung/core.h | 1 + include/linux/mfd/samsung/irq.h | 24 +++++++++++ 4 files changed, 132 insertions(+) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index be06d0a..5e8784b 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -89,6 +89,17 @@ static const struct mfd_cell s2mpa01_devs[] = { }, }; +static const struct mfd_cell s2mpu02_devs[] = { + { + .name = "s2mpu02-pmic", + }, { + .name = "s2mpu02-rtc", + }, { + .name = "s2mpu02-clk", + .of_compatible = "samsung,s2mpu02-clk", + } +}; + #ifdef CONFIG_OF static const struct of_device_id sec_dt_match[] = { { .compatible = "samsung,s5m8767-pmic", @@ -103,6 +114,9 @@ static const struct of_device_id sec_dt_match[] = { .compatible = "samsung,s2mpa01-pmic", .data = (void *)S2MPA01, }, { + .compatible = "samsung,s2mpu02-pmic", + .data = (void *)S2MPU02, + }, { /* Sentinel */ }, }; @@ -342,6 +356,11 @@ static int sec_pmic_probe(struct i2c_client *i2c, ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs, ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL); break; + case S2MPU02: + ret = mfd_add_devices(sec_pmic->dev, -1, s2mpu02_devs, + ARRAY_SIZE(s2mpu02_devs), NULL, 0, NULL); + break; + default: /* If this happens the probe function is problem */ BUG(); diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 654e2c1..0cabd03 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c @@ -20,6 +20,7 @@ #include <linux/mfd/samsung/irq.h> #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps14.h> +#include <linux/mfd/samsung/s2mpu02.h> #include <linux/mfd/samsung/s5m8763.h> #include <linux/mfd/samsung/s5m8767.h> @@ -161,6 +162,77 @@ static const struct regmap_irq s2mps14_irqs[] = { }, }; +static const struct regmap_irq s2mpu02_irqs[] = { + [S2MPU02_IRQ_PWRONF] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_PWRONF_MASK, + }, + [S2MPU02_IRQ_PWRONR] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_PWRONR_MASK, + }, + [S2MPU02_IRQ_JIGONBF] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_JIGONBF_MASK, + }, + [S2MPU02_IRQ_JIGONBR] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_JIGONBR_MASK, + }, + [S2MPU02_IRQ_ACOKBF] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_ACOKBF_MASK, + }, + [S2MPU02_IRQ_ACOKBR] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_ACOKBR_MASK, + }, + [S2MPU02_IRQ_PWRON1S] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_PWRON1S_MASK, + }, + [S2MPU02_IRQ_MRB] = { + .reg_offset = 0, + .mask = S2MPS11_IRQ_MRB_MASK, + }, + [S2MPU02_IRQ_RTC60S] = { + .reg_offset = 1, + .mask = S2MPS11_IRQ_RTC60S_MASK, + }, + [S2MPU02_IRQ_RTCA1] = { + .reg_offset = 1, + .mask = S2MPS11_IRQ_RTCA1_MASK, + }, + [S2MPU02_IRQ_RTCA0] = { + .reg_offset = 1, + .mask = S2MPS11_IRQ_RTCA0_MASK, + }, + [S2MPU02_IRQ_SMPL] = { + .reg_offset = 1, + .mask = S2MPS11_IRQ_SMPL_MASK, + }, + [S2MPU02_IRQ_RTC1S] = { + .reg_offset = 1, + .mask = S2MPS11_IRQ_RTC1S_MASK, + }, + [S2MPU02_IRQ_WTSR] = { + .reg_offset = 1, + .mask = S2MPS11_IRQ_WTSR_MASK, + }, + [S2MPU02_IRQ_INT120C] = { + .reg_offset = 2, + .mask = S2MPS11_IRQ_INT120C_MASK, + }, + [S2MPU02_IRQ_INT140C] = { + .reg_offset = 2, + .mask = S2MPS11_IRQ_INT140C_MASK, + }, + [S2MPU02_IRQ_TSD] = { + .reg_offset = 2, + .mask = S2MPS14_IRQ_TSD_MASK, + }, +}; + static const struct regmap_irq s5m8767_irqs[] = { [S5M8767_IRQ_PWRR] = { .reg_offset = 0, @@ -327,6 +399,16 @@ static const struct regmap_irq_chip s2mps14_irq_chip = { .ack_base = S2MPS14_REG_INT1, }; +static const struct regmap_irq_chip s2mpu02_irq_chip = { + .name = "s2mpu02", + .irqs = s2mpu02_irqs, + .num_irqs = ARRAY_SIZE(s2mpu02_irqs), + .num_regs = 3, + .status_base = S2MPU02_REG_INT1, + .mask_base = S2MPU02_REG_INT1M, + .ack_base = S2MPU02_REG_INT1, +}; + static const struct regmap_irq_chip s5m8767_irq_chip = { .name = "s5m8767", .irqs = s5m8767_irqs, @@ -384,6 +466,12 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) sec_pmic->irq_base, &s2mps14_irq_chip, &sec_pmic->irq_data); break; + case S2MPU02: + ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + sec_pmic->irq_base, &s2mpu02_irq_chip, + &sec_pmic->irq_data); + break; default: dev_err(sec_pmic->dev, "Unknown device type %lu\n", sec_pmic->device_type); diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 47d8424..b5f73de 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -21,6 +21,7 @@ enum sec_device_type { S2MPA01, S2MPS11X, S2MPS14X, + S2MPU02, }; /** diff --git a/include/linux/mfd/samsung/irq.h b/include/linux/mfd/samsung/irq.h index 1224f44..f35af73 100644 --- a/include/linux/mfd/samsung/irq.h +++ b/include/linux/mfd/samsung/irq.h @@ -129,6 +129,30 @@ enum s2mps14_irq { S2MPS14_IRQ_NR, }; +enum s2mpu02_irq { + S2MPU02_IRQ_PWRONF, + S2MPU02_IRQ_PWRONR, + S2MPU02_IRQ_JIGONBF, + S2MPU02_IRQ_JIGONBR, + S2MPU02_IRQ_ACOKBF, + S2MPU02_IRQ_ACOKBR, + S2MPU02_IRQ_PWRON1S, + S2MPU02_IRQ_MRB, + + S2MPU02_IRQ_RTC60S, + S2MPU02_IRQ_RTCA1, + S2MPU02_IRQ_RTCA0, + S2MPU02_IRQ_SMPL, + S2MPU02_IRQ_RTC1S, + S2MPU02_IRQ_WTSR, + + S2MPU02_IRQ_INT120C, + S2MPU02_IRQ_INT140C, + S2MPU02_IRQ_TSD, + + S2MPU02_IRQ_NR, +}; + /* Masks for interrupts are the same as in s2mps11 */ #define S2MPS14_IRQ_TSD_MASK (1 << 2) -- 1.8.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device 2014-06-16 4:42 ` [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device Chanwoo Choi @ 2014-06-16 13:03 ` Lee Jones 2014-06-17 0:18 ` Chanwoo Choi 0 siblings, 1 reply; 8+ messages in thread From: Lee Jones @ 2014-06-16 13:03 UTC (permalink / raw) To: Chanwoo Choi Cc: sbkim73, sameo, k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel On Mon, 16 Jun 2014, Chanwoo Choi wrote: > Add support for Samsung S2MPU02 PMIC device to the MFD sec-core driver. > The S2MPU02 device includes PMIC/RTC/Clock devices. > > Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> > Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> > --- > drivers/mfd/sec-core.c | 19 +++++++++ > drivers/mfd/sec-irq.c | 88 ++++++++++++++++++++++++++++++++++++++++ > include/linux/mfd/samsung/core.h | 1 + > include/linux/mfd/samsung/irq.h | 24 +++++++++++ > 4 files changed, 132 insertions(+) > > diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c > index be06d0a..5e8784b 100644 > --- a/drivers/mfd/sec-core.c > +++ b/drivers/mfd/sec-core.c > @@ -89,6 +89,17 @@ static const struct mfd_cell s2mpa01_devs[] = { > }, > }; > > +static const struct mfd_cell s2mpu02_devs[] = { > + { > + .name = "s2mpu02-pmic", > + }, { > + .name = "s2mpu02-rtc", Make these two one liners, so: { .name = "s2mpu02-pmic" }, { .name = "s2mpu02-rtc" ), > + }, { > + .name = "s2mpu02-clk", > + .of_compatible = "samsung,s2mpu02-clk", > + } > +}; > + > #ifdef CONFIG_OF > static const struct of_device_id sec_dt_match[] = { > { .compatible = "samsung,s5m8767-pmic", > @@ -103,6 +114,9 @@ static const struct of_device_id sec_dt_match[] = { > .compatible = "samsung,s2mpa01-pmic", > .data = (void *)S2MPA01, > }, { > + .compatible = "samsung,s2mpu02-pmic", > + .data = (void *)S2MPU02, > + }, { > /* Sentinel */ > }, > }; > @@ -342,6 +356,11 @@ static int sec_pmic_probe(struct i2c_client *i2c, > ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs, > ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL); > break; > + case S2MPU02: > + ret = mfd_add_devices(sec_pmic->dev, -1, s2mpu02_devs, > + ARRAY_SIZE(s2mpu02_devs), NULL, 0, NULL); > + break; This is a bit bonkers. Instead of passing S2MPU02, why don't you pass a new container which holds s2mpu02_devs and s2mpu02_irq_chip, then you won't need new mfd_add_devices() and regmap_add_irq_chip() calls for every device you want to support. [...] -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device 2014-06-16 13:03 ` Lee Jones @ 2014-06-17 0:18 ` Chanwoo Choi 0 siblings, 0 replies; 8+ messages in thread From: Chanwoo Choi @ 2014-06-17 0:18 UTC (permalink / raw) To: Lee Jones Cc: sbkim73, sameo, k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel Hi Lee, On 06/16/2014 10:03 PM, Lee Jones wrote: > On Mon, 16 Jun 2014, Chanwoo Choi wrote: > >> Add support for Samsung S2MPU02 PMIC device to the MFD sec-core driver. >> The S2MPU02 device includes PMIC/RTC/Clock devices. >> >> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> >> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> >> --- >> drivers/mfd/sec-core.c | 19 +++++++++ >> drivers/mfd/sec-irq.c | 88 ++++++++++++++++++++++++++++++++++++++++ >> include/linux/mfd/samsung/core.h | 1 + >> include/linux/mfd/samsung/irq.h | 24 +++++++++++ >> 4 files changed, 132 insertions(+) >> >> diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c >> index be06d0a..5e8784b 100644 >> --- a/drivers/mfd/sec-core.c >> +++ b/drivers/mfd/sec-core.c >> @@ -89,6 +89,17 @@ static const struct mfd_cell s2mpa01_devs[] = { >> }, >> }; >> >> +static const struct mfd_cell s2mpu02_devs[] = { >> + { >> + .name = "s2mpu02-pmic", >> + }, { >> + .name = "s2mpu02-rtc", > > Make these two one liners, so: > > { .name = "s2mpu02-pmic" }, > { .name = "s2mpu02-rtc" ), OK, I'll modify it. > >> + }, { >> + .name = "s2mpu02-clk", >> + .of_compatible = "samsung,s2mpu02-clk", >> + } >> +}; >> + >> #ifdef CONFIG_OF >> static const struct of_device_id sec_dt_match[] = { >> { .compatible = "samsung,s5m8767-pmic", >> @@ -103,6 +114,9 @@ static const struct of_device_id sec_dt_match[] = { >> .compatible = "samsung,s2mpa01-pmic", >> .data = (void *)S2MPA01, >> }, { >> + .compatible = "samsung,s2mpu02-pmic", >> + .data = (void *)S2MPU02, >> + }, { >> /* Sentinel */ >> }, >> }; >> @@ -342,6 +356,11 @@ static int sec_pmic_probe(struct i2c_client *i2c, >> ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs, >> ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL); >> break; >> + case S2MPU02: >> + ret = mfd_add_devices(sec_pmic->dev, -1, s2mpu02_devs, >> + ARRAY_SIZE(s2mpu02_devs), NULL, 0, NULL); >> + break; > > This is a bit bonkers. Instead of passing S2MPU02, why don't you pass > a new container which holds s2mpu02_devs and s2mpu02_irq_chip, then > you won't need new mfd_add_devices() and regmap_add_irq_chip() calls > for every device you want to support. OK, I'll remove duplicate code of mfd_add_devices() and regmap_add_irq_chip(). Best Regards, Chanwoo Choi ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device 2014-06-16 4:42 [PATCHv5 0/3] mfd: sec-core: Add support S2MPU02 PMIC device Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device Chanwoo Choi @ 2014-06-16 4:42 ` Chanwoo Choi 2014-06-16 13:19 ` Lee Jones 2014-06-16 4:42 ` [PATCHv5 3/3] dt-bindings: mfd: s2mps11: Add support S2MPU02 PMIC Chanwoo Choi 2 siblings, 1 reply; 8+ messages in thread From: Chanwoo Choi @ 2014-06-16 4:42 UTC (permalink / raw) To: lee.jones, sbkim73, sameo Cc: k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel, Chanwoo Choi, Jonghwa Lee This patch add S2MPU02 regulator device to existing S2MPS11 device driver because of little difference between S2MPS1x and S2MPU02. The S2MPU02 regulator device includes LDO[1-28] and BUCK[1-7]. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> [Add missing linear_min_sel of S2MPU02 LDO regulators by Jonghwa Lee] Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Mark Brown <broonie@linaro.org> --- drivers/mfd/sec-core.c | 25 +++ drivers/regulator/s2mps11.c | 321 +++++++++++++++++++++++++++++++++--- include/linux/mfd/samsung/s2mpu02.h | 201 ++++++++++++++++++++++ 3 files changed, 526 insertions(+), 21 deletions(-) create mode 100644 include/linux/mfd/samsung/s2mpu02.h diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 5e8784b..9eae5ab 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -28,6 +28,7 @@ #include <linux/mfd/samsung/s2mpa01.h> #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps14.h> +#include <linux/mfd/samsung/s2mpu02.h> #include <linux/mfd/samsung/s5m8763.h> #include <linux/mfd/samsung/s5m8767.h> #include <linux/regmap.h> @@ -146,6 +147,18 @@ static bool s2mps11_volatile(struct device *dev, unsigned int reg) } } +static bool s2mpu02_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case S2MPU02_REG_INT1M: + case S2MPU02_REG_INT2M: + case S2MPU02_REG_INT3M: + return false; + default: + return true; + } +} + static bool s5m8763_volatile(struct device *dev, unsigned int reg) { switch (reg) { @@ -191,6 +204,15 @@ static const struct regmap_config s2mps14_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct regmap_config s2mpu02_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = S2MPU02_REG_DVSDATA, + .volatile_reg = s2mpu02_volatile, + .cache_type = REGCACHE_FLAT, +}; + static const struct regmap_config s5m8763_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -311,6 +333,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, case S5M8767X: regmap = &s5m8767_regmap_config; break; + case S2MPU02: + regmap = &s2mpu02_regmap_config; + break; default: regmap = &sec_regmap_config; break; diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 02e2fb2..2daacc6 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -31,6 +31,7 @@ #include <linux/mfd/samsung/core.h> #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps14.h> +#include <linux/mfd/samsung/s2mpu02.h> struct s2mps11_info { unsigned int rdev_num; @@ -40,11 +41,15 @@ struct s2mps11_info { int ramp_delay16; int ramp_delay7810; int ramp_delay9; + + enum sec_device_type dev_type; + /* - * One bit for each S2MPS14 regulator whether the suspend mode + * One bit for each S2MPS14/S2MPU02 regulator whether the suspend mode * was enabled. */ - unsigned int s2mps14_suspend_state:30; + unsigned long long s2mps14_suspend_state:35; + /* Array of size rdev_num with GPIO-s for external sleep control */ int *ext_control_gpio; }; @@ -415,12 +420,24 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); unsigned int val; - if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) - val = S2MPS14_ENABLE_SUSPEND; - else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) - val = S2MPS14_ENABLE_EXT_CONTROL; - else - val = rdev->desc->enable_mask; + switch (s2mps11->dev_type) { + case S2MPS14X: + if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) + val = S2MPS14_ENABLE_SUSPEND; + else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) + val = S2MPS14_ENABLE_EXT_CONTROL; + else + val = rdev->desc->enable_mask; + break; + case S2MPU02: + if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) + val = S2MPU02_ENABLE_SUSPEND; + else + val = rdev->desc->enable_mask; + break; + default: + return -EINVAL; + }; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val); @@ -429,12 +446,38 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) { int ret; - unsigned int val; + unsigned int val, state; struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); + int rdev_id = rdev_get_id(rdev); - /* LDO3 should be always on and does not support suspend mode */ - if (rdev_get_id(rdev) == S2MPS14_LDO3) - return 0; + /* Below LDO should be always on or does not support suspend mode. */ + switch (s2mps11->dev_type) { + case S2MPS14X: + switch (rdev_id) { + case S2MPS14_LDO3: + return 0; + default: + state = S2MPS14_ENABLE_SUSPEND; + break; + }; + break; + case S2MPU02: + switch (rdev_id) { + case S2MPU02_LDO13: + case S2MPU02_LDO14: + case S2MPU02_LDO15: + case S2MPU02_LDO17: + case S2MPU02_BUCK7: + state = S2MPU02_DISABLE_SUSPEND; + break; + default: + state = S2MPU02_ENABLE_SUSPEND; + break; + }; + break; + default: + return -EINVAL; + }; ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); if (ret < 0) @@ -452,7 +495,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) return 0; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); + rdev->desc->enable_mask, state); } static struct regulator_ops s2mps14_reg_ops = { @@ -605,8 +648,7 @@ static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev, } static int s2mps11_pmic_dt_parse(struct platform_device *pdev, - struct of_regulator_match *rdata, struct s2mps11_info *s2mps11, - enum sec_device_type dev_type) + struct of_regulator_match *rdata, struct s2mps11_info *s2mps11) { struct device_node *reg_np; @@ -617,7 +659,7 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, } of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); - if (dev_type == S2MPS14X) + if (s2mps11->dev_type == S2MPS14X) s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); of_node_put(reg_np); @@ -625,6 +667,238 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, return 0; } +static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) +{ + unsigned int ramp_val, ramp_shift, ramp_reg; + + switch (rdev_get_id(rdev)) { + case S2MPU02_BUCK1: + ramp_shift = S2MPU02_BUCK1_RAMP_SHIFT; + break; + case S2MPU02_BUCK2: + ramp_shift = S2MPU02_BUCK2_RAMP_SHIFT; + break; + case S2MPU02_BUCK3: + ramp_shift = S2MPU02_BUCK3_RAMP_SHIFT; + break; + case S2MPU02_BUCK4: + ramp_shift = S2MPU02_BUCK4_RAMP_SHIFT; + break; + default: + return 0; + } + ramp_reg = S2MPU02_REG_RAMP1; + ramp_val = get_ramp_delay(ramp_delay); + + return regmap_update_bits(rdev->regmap, ramp_reg, + S2MPU02_BUCK1234_RAMP_MASK << ramp_shift, + ramp_val << ramp_shift); +} + +static struct regulator_ops s2mpu02_ldo_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = s2mps14_regulator_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_disable = s2mps14_regulator_set_suspend_disable, +}; + +static struct regulator_ops s2mpu02_buck_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = s2mps14_regulator_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_disable = s2mps14_regulator_set_suspend_disable, + .set_ramp_delay = s2mpu02_set_ramp_delay, +}; + +#define regulator_desc_s2mpu02_ldo1(num) { \ + .name = "LDO"#num, \ + .id = S2MPU02_LDO##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_LDO_MIN_900MV, \ + .uV_step = S2MPU02_LDO_STEP_12_5MV, \ + .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \ + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ + .vsel_reg = S2MPU02_REG_L1CTRL, \ + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_L1CTRL, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_ldo2(num) { \ + .name = "LDO"#num, \ + .id = S2MPU02_LDO##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_LDO_MIN_1050MV, \ + .uV_step = S2MPU02_LDO_STEP_25MV, \ + .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \ + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ + .vsel_reg = S2MPU02_REG_L2CTRL1, \ + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_L2CTRL1, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_ldo3(num) { \ + .name = "LDO"#num, \ + .id = S2MPU02_LDO##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_LDO_MIN_900MV, \ + .uV_step = S2MPU02_LDO_STEP_12_5MV, \ + .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \ + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ + .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_ldo4(num) { \ + .name = "LDO"#num, \ + .id = S2MPU02_LDO##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_LDO_MIN_1050MV, \ + .uV_step = S2MPU02_LDO_STEP_25MV, \ + .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \ + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ + .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_ldo5(num) { \ + .name = "LDO"#num, \ + .id = S2MPU02_LDO##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_LDO_MIN_1600MV, \ + .uV_step = S2MPU02_LDO_STEP_50MV, \ + .linear_min_sel = S2MPU02_LDO_GROUP3_START_SEL, \ + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ + .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} + +#define regulator_desc_s2mpu02_buck1234(num) { \ + .name = "BUCK"#num, \ + .id = S2MPU02_BUCK##num, \ + .ops = &s2mpu02_buck_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_BUCK1234_MIN_600MV, \ + .uV_step = S2MPU02_BUCK1234_STEP_6_25MV, \ + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ + .linear_min_sel = S2MPU02_BUCK1234_START_SEL, \ + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPU02_REG_B1CTRL2 + (num - 1) * 2, \ + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_B1CTRL1 + (num - 1) * 2, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_buck5(num) { \ + .name = "BUCK"#num, \ + .id = S2MPU02_BUCK##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_BUCK5_MIN_1081_25MV, \ + .uV_step = S2MPU02_BUCK5_STEP_6_25MV, \ + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ + .linear_min_sel = S2MPU02_BUCK5_START_SEL, \ + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPU02_REG_B5CTRL2, \ + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_B5CTRL1, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_buck6(num) { \ + .name = "BUCK"#num, \ + .id = S2MPU02_BUCK##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_BUCK6_MIN_1700MV, \ + .uV_step = S2MPU02_BUCK6_STEP_2_50MV, \ + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ + .linear_min_sel = S2MPU02_BUCK6_START_SEL, \ + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPU02_REG_B6CTRL2, \ + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_B6CTRL1, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} +#define regulator_desc_s2mpu02_buck7(num) { \ + .name = "BUCK"#num, \ + .id = S2MPU02_BUCK##num, \ + .ops = &s2mpu02_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = S2MPU02_BUCK7_MIN_900MV, \ + .uV_step = S2MPU02_BUCK7_STEP_6_25MV, \ + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ + .linear_min_sel = S2MPU02_BUCK7_START_SEL, \ + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPU02_REG_B7CTRL2, \ + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ + .enable_reg = S2MPU02_REG_B7CTRL1, \ + .enable_mask = S2MPU02_ENABLE_MASK \ +} + +static const struct regulator_desc s2mpu02_regulators[] = { + regulator_desc_s2mpu02_ldo1(1), + regulator_desc_s2mpu02_ldo2(2), + regulator_desc_s2mpu02_ldo4(3), + regulator_desc_s2mpu02_ldo5(4), + regulator_desc_s2mpu02_ldo4(5), + regulator_desc_s2mpu02_ldo3(6), + regulator_desc_s2mpu02_ldo3(7), + regulator_desc_s2mpu02_ldo4(8), + regulator_desc_s2mpu02_ldo5(9), + regulator_desc_s2mpu02_ldo3(10), + regulator_desc_s2mpu02_ldo4(11), + regulator_desc_s2mpu02_ldo5(12), + regulator_desc_s2mpu02_ldo5(13), + regulator_desc_s2mpu02_ldo5(14), + regulator_desc_s2mpu02_ldo5(15), + regulator_desc_s2mpu02_ldo5(16), + regulator_desc_s2mpu02_ldo4(17), + regulator_desc_s2mpu02_ldo5(18), + regulator_desc_s2mpu02_ldo3(19), + regulator_desc_s2mpu02_ldo4(20), + regulator_desc_s2mpu02_ldo5(21), + regulator_desc_s2mpu02_ldo5(22), + regulator_desc_s2mpu02_ldo5(23), + regulator_desc_s2mpu02_ldo4(24), + regulator_desc_s2mpu02_ldo5(25), + regulator_desc_s2mpu02_ldo4(26), + regulator_desc_s2mpu02_ldo5(27), + regulator_desc_s2mpu02_ldo5(28), + regulator_desc_s2mpu02_buck1234(1), + regulator_desc_s2mpu02_buck1234(2), + regulator_desc_s2mpu02_buck1234(3), + regulator_desc_s2mpu02_buck1234(4), + regulator_desc_s2mpu02_buck5(5), + regulator_desc_s2mpu02_buck6(6), + regulator_desc_s2mpu02_buck7(7), +}; + static int s2mps11_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); @@ -634,15 +908,14 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) struct s2mps11_info *s2mps11; int i, ret = 0; const struct regulator_desc *regulators; - enum sec_device_type dev_type; s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), GFP_KERNEL); if (!s2mps11) return -ENOMEM; - dev_type = platform_get_device_id(pdev)->driver_data; - switch (dev_type) { + s2mps11->dev_type = platform_get_device_id(pdev)->driver_data; + switch (s2mps11->dev_type) { case S2MPS11X: s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); regulators = s2mps11_regulators; @@ -651,8 +924,13 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); regulators = s2mps14_regulators; break; + case S2MPU02: + s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators); + regulators = s2mpu02_regulators; + break; default: - dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); + dev_err(&pdev->dev, "Invalid device type: %u\n", + s2mps11->dev_type); return -EINVAL; }; @@ -686,7 +964,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) for (i = 0; i < s2mps11->rdev_num; i++) rdata[i].name = regulators[i].name; - ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type); + ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11); if (ret) goto out; @@ -739,6 +1017,7 @@ out: static const struct platform_device_id s2mps11_pmic_id[] = { { "s2mps11-pmic", S2MPS11X}, { "s2mps14-pmic", S2MPS14X}, + { "s2mpu02-pmic", S2MPU02}, { }, }; MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); diff --git a/include/linux/mfd/samsung/s2mpu02.h b/include/linux/mfd/samsung/s2mpu02.h new file mode 100644 index 0000000..47ae9bc --- /dev/null +++ b/include/linux/mfd/samsung/s2mpu02.h @@ -0,0 +1,201 @@ +/* + * s2mpu02.h + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __LINUX_MFD_S2MPU02_H +#define __LINUX_MFD_S2MPU02_H + +/* S2MPU02 registers */ +enum S2MPU02_reg { + S2MPU02_REG_ID, + S2MPU02_REG_INT1, + S2MPU02_REG_INT2, + S2MPU02_REG_INT3, + S2MPU02_REG_INT1M, + S2MPU02_REG_INT2M, + S2MPU02_REG_INT3M, + S2MPU02_REG_ST1, + S2MPU02_REG_ST2, + S2MPU02_REG_PWRONSRC, + S2MPU02_REG_OFFSRC, + S2MPU02_REG_BU_CHG, + S2MPU02_REG_RTCCTRL, + S2MPU02_REG_PMCTRL1, + S2MPU02_REG_RSVD1, + S2MPU02_REG_RSVD2, + S2MPU02_REG_RSVD3, + S2MPU02_REG_RSVD4, + S2MPU02_REG_RSVD5, + S2MPU02_REG_RSVD6, + S2MPU02_REG_RSVD7, + S2MPU02_REG_WRSTEN, + S2MPU02_REG_RSVD8, + S2MPU02_REG_RSVD9, + S2MPU02_REG_RSVD10, + S2MPU02_REG_B1CTRL1, + S2MPU02_REG_B1CTRL2, + S2MPU02_REG_B2CTRL1, + S2MPU02_REG_B2CTRL2, + S2MPU02_REG_B3CTRL1, + S2MPU02_REG_B3CTRL2, + S2MPU02_REG_B4CTRL1, + S2MPU02_REG_B4CTRL2, + S2MPU02_REG_B5CTRL1, + S2MPU02_REG_B5CTRL2, + S2MPU02_REG_B5CTRL3, + S2MPU02_REG_B5CTRL4, + S2MPU02_REG_B5CTRL5, + S2MPU02_REG_B6CTRL1, + S2MPU02_REG_B6CTRL2, + S2MPU02_REG_B7CTRL1, + S2MPU02_REG_B7CTRL2, + S2MPU02_REG_RAMP1, + S2MPU02_REG_RAMP2, + S2MPU02_REG_L1CTRL, + S2MPU02_REG_L2CTRL1, + S2MPU02_REG_L2CTRL2, + S2MPU02_REG_L2CTRL3, + S2MPU02_REG_L2CTRL4, + S2MPU02_REG_L3CTRL, + S2MPU02_REG_L4CTRL, + S2MPU02_REG_L5CTRL, + S2MPU02_REG_L6CTRL, + S2MPU02_REG_L7CTRL, + S2MPU02_REG_L8CTRL, + S2MPU02_REG_L9CTRL, + S2MPU02_REG_L10CTRL, + S2MPU02_REG_L11CTRL, + S2MPU02_REG_L12CTRL, + S2MPU02_REG_L13CTRL, + S2MPU02_REG_L14CTRL, + S2MPU02_REG_L15CTRL, + S2MPU02_REG_L16CTRL, + S2MPU02_REG_L17CTRL, + S2MPU02_REG_L18CTRL, + S2MPU02_REG_L19CTRL, + S2MPU02_REG_L20CTRL, + S2MPU02_REG_L21CTRL, + S2MPU02_REG_L22CTRL, + S2MPU02_REG_L23CTRL, + S2MPU02_REG_L24CTRL, + S2MPU02_REG_L25CTRL, + S2MPU02_REG_L26CTRL, + S2MPU02_REG_L27CTRL, + S2MPU02_REG_L28CTRL, + S2MPU02_REG_LDODSCH1, + S2MPU02_REG_LDODSCH2, + S2MPU02_REG_LDODSCH3, + S2MPU02_REG_LDODSCH4, + S2MPU02_REG_SELMIF, + S2MPU02_REG_RSVD11, + S2MPU02_REG_RSVD12, + S2MPU02_REG_RSVD13, + S2MPU02_REG_DVSSEL, + S2MPU02_REG_DVSPTR, + S2MPU02_REG_DVSDATA, +}; + +/* S2MPU02 regulator ids */ +enum S2MPU02_regulators { + S2MPU02_LDO1, + S2MPU02_LDO2, + S2MPU02_LDO3, + S2MPU02_LDO4, + S2MPU02_LDO5, + S2MPU02_LDO6, + S2MPU02_LDO7, + S2MPU02_LDO8, + S2MPU02_LDO9, + S2MPU02_LDO10, + S2MPU02_LDO11, + S2MPU02_LDO12, + S2MPU02_LDO13, + S2MPU02_LDO14, + S2MPU02_LDO15, + S2MPU02_LDO16, + S2MPU02_LDO17, + S2MPU02_LDO18, + S2MPU02_LDO19, + S2MPU02_LDO20, + S2MPU02_LDO21, + S2MPU02_LDO22, + S2MPU02_LDO23, + S2MPU02_LDO24, + S2MPU02_LDO25, + S2MPU02_LDO26, + S2MPU02_LDO27, + S2MPU02_LDO28, + S2MPU02_BUCK1, + S2MPU02_BUCK2, + S2MPU02_BUCK3, + S2MPU02_BUCK4, + S2MPU02_BUCK5, + S2MPU02_BUCK6, + S2MPU02_BUCK7, + + S2MPU02_REGULATOR_MAX, +}; + +/* Regulator constraints for BUCKx */ +#define S2MPU02_BUCK1234_MIN_600MV 600000 +#define S2MPU02_BUCK5_MIN_1081_25MV 1081250 +#define S2MPU02_BUCK6_MIN_1700MV 1700000 +#define S2MPU02_BUCK7_MIN_900MV 900000 + +#define S2MPU02_BUCK1234_STEP_6_25MV 6250 +#define S2MPU02_BUCK5_STEP_6_25MV 6250 +#define S2MPU02_BUCK6_STEP_2_50MV 2500 +#define S2MPU02_BUCK7_STEP_6_25MV 6250 + +#define S2MPU02_BUCK1234_START_SEL 0x00 +#define S2MPU02_BUCK5_START_SEL 0x4D +#define S2MPU02_BUCK6_START_SEL 0x28 +#define S2MPU02_BUCK7_START_SEL 0x30 + +#define S2MPU02_BUCK_RAMP_DELAY 12500 + +/* Regulator constraints for different types of LDOx */ +#define S2MPU02_LDO_MIN_900MV 900000 +#define S2MPU02_LDO_MIN_1050MV 1050000 +#define S2MPU02_LDO_MIN_1600MV 1600000 +#define S2MPU02_LDO_STEP_12_5MV 12500 +#define S2MPU02_LDO_STEP_25MV 25000 +#define S2MPU02_LDO_STEP_50MV 50000 + +#define S2MPU02_LDO_GROUP1_START_SEL 0x8 +#define S2MPU02_LDO_GROUP2_START_SEL 0xA +#define S2MPU02_LDO_GROUP3_START_SEL 0x10 + +#define S2MPU02_LDO_VSEL_MASK 0x3F +#define S2MPU02_BUCK_VSEL_MASK 0xFF +#define S2MPU02_ENABLE_MASK (0x03 << S2MPU02_ENABLE_SHIFT) +#define S2MPU02_ENABLE_SHIFT 6 + +/* On/Off controlled by PWREN */ +#define S2MPU02_ENABLE_SUSPEND (0x01 << S2MPU02_ENABLE_SHIFT) +#define S2MPU02_DISABLE_SUSPEND (0x11 << S2MPU02_ENABLE_SHIFT) +#define S2MPU02_LDO_N_VOLTAGES (S2MPU02_LDO_VSEL_MASK + 1) +#define S2MPU02_BUCK_N_VOLTAGES (S2MPU02_BUCK_VSEL_MASK + 1) + +/* RAMP delay for BUCK1234*/ +#define S2MPU02_BUCK1_RAMP_SHIFT 6 +#define S2MPU02_BUCK2_RAMP_SHIFT 4 +#define S2MPU02_BUCK3_RAMP_SHIFT 2 +#define S2MPU02_BUCK4_RAMP_SHIFT 0 +#define S2MPU02_BUCK1234_RAMP_MASK 0x3 + +#endif /* __LINUX_MFD_S2MPU02_H */ -- 1.8.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device 2014-06-16 4:42 ` [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device Chanwoo Choi @ 2014-06-16 13:19 ` Lee Jones 2014-06-16 23:41 ` Chanwoo Choi 0 siblings, 1 reply; 8+ messages in thread From: Lee Jones @ 2014-06-16 13:19 UTC (permalink / raw) To: Chanwoo Choi Cc: sbkim73, sameo, k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel, Jonghwa Lee On Mon, 16 Jun 2014, Chanwoo Choi wrote: > This patch add S2MPU02 regulator device to existing S2MPS11 device driver > because of little difference between S2MPS1x and S2MPU02. The S2MPU02 > regulator device includes LDO[1-28] and BUCK[1-7]. > > Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> > [Add missing linear_min_sel of S2MPU02 LDO regulators by Jonghwa Lee] > Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com> > Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> > Acked-by: Mark Brown <broonie@linaro.org> > --- > drivers/mfd/sec-core.c | 25 +++ > drivers/regulator/s2mps11.c | 321 +++++++++++++++++++++++++++++++++--- > include/linux/mfd/samsung/s2mpu02.h | 201 ++++++++++++++++++++++ > 3 files changed, 526 insertions(+), 21 deletions(-) > create mode 100644 include/linux/mfd/samsung/s2mpu02.h MFD changes look good to me. Acked-by: Lee Jones <lee.jones@linaro.org> I assume we have to wait for the other patches to be ready before applying this one? > diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c > index 5e8784b..9eae5ab 100644 > --- a/drivers/mfd/sec-core.c > +++ b/drivers/mfd/sec-core.c > @@ -28,6 +28,7 @@ > #include <linux/mfd/samsung/s2mpa01.h> > #include <linux/mfd/samsung/s2mps11.h> > #include <linux/mfd/samsung/s2mps14.h> > +#include <linux/mfd/samsung/s2mpu02.h> > #include <linux/mfd/samsung/s5m8763.h> > #include <linux/mfd/samsung/s5m8767.h> > #include <linux/regmap.h> > @@ -146,6 +147,18 @@ static bool s2mps11_volatile(struct device *dev, unsigned int reg) > } > } > > +static bool s2mpu02_volatile(struct device *dev, unsigned int reg) > +{ > + switch (reg) { > + case S2MPU02_REG_INT1M: > + case S2MPU02_REG_INT2M: > + case S2MPU02_REG_INT3M: > + return false; > + default: > + return true; > + } > +} > + > static bool s5m8763_volatile(struct device *dev, unsigned int reg) > { > switch (reg) { > @@ -191,6 +204,15 @@ static const struct regmap_config s2mps14_regmap_config = { > .cache_type = REGCACHE_FLAT, > }; > > +static const struct regmap_config s2mpu02_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + > + .max_register = S2MPU02_REG_DVSDATA, > + .volatile_reg = s2mpu02_volatile, > + .cache_type = REGCACHE_FLAT, > +}; > + > static const struct regmap_config s5m8763_regmap_config = { > .reg_bits = 8, > .val_bits = 8, > @@ -311,6 +333,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, > case S5M8767X: > regmap = &s5m8767_regmap_config; > break; > + case S2MPU02: > + regmap = &s2mpu02_regmap_config; > + break; > default: > regmap = &sec_regmap_config; > break; > diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c > index 02e2fb2..2daacc6 100644 > --- a/drivers/regulator/s2mps11.c > +++ b/drivers/regulator/s2mps11.c > @@ -31,6 +31,7 @@ > #include <linux/mfd/samsung/core.h> > #include <linux/mfd/samsung/s2mps11.h> > #include <linux/mfd/samsung/s2mps14.h> > +#include <linux/mfd/samsung/s2mpu02.h> > > struct s2mps11_info { > unsigned int rdev_num; > @@ -40,11 +41,15 @@ struct s2mps11_info { > int ramp_delay16; > int ramp_delay7810; > int ramp_delay9; > + > + enum sec_device_type dev_type; > + > /* > - * One bit for each S2MPS14 regulator whether the suspend mode > + * One bit for each S2MPS14/S2MPU02 regulator whether the suspend mode > * was enabled. > */ > - unsigned int s2mps14_suspend_state:30; > + unsigned long long s2mps14_suspend_state:35; > + > /* Array of size rdev_num with GPIO-s for external sleep control */ > int *ext_control_gpio; > }; > @@ -415,12 +420,24 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) > struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); > unsigned int val; > > - if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) > - val = S2MPS14_ENABLE_SUSPEND; > - else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) > - val = S2MPS14_ENABLE_EXT_CONTROL; > - else > - val = rdev->desc->enable_mask; > + switch (s2mps11->dev_type) { > + case S2MPS14X: > + if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) > + val = S2MPS14_ENABLE_SUSPEND; > + else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) > + val = S2MPS14_ENABLE_EXT_CONTROL; > + else > + val = rdev->desc->enable_mask; > + break; > + case S2MPU02: > + if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) > + val = S2MPU02_ENABLE_SUSPEND; > + else > + val = rdev->desc->enable_mask; > + break; > + default: > + return -EINVAL; > + }; > > return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, > rdev->desc->enable_mask, val); > @@ -429,12 +446,38 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) > static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) > { > int ret; > - unsigned int val; > + unsigned int val, state; > struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); > + int rdev_id = rdev_get_id(rdev); > > - /* LDO3 should be always on and does not support suspend mode */ > - if (rdev_get_id(rdev) == S2MPS14_LDO3) > - return 0; > + /* Below LDO should be always on or does not support suspend mode. */ > + switch (s2mps11->dev_type) { > + case S2MPS14X: > + switch (rdev_id) { > + case S2MPS14_LDO3: > + return 0; > + default: > + state = S2MPS14_ENABLE_SUSPEND; > + break; > + }; > + break; > + case S2MPU02: > + switch (rdev_id) { > + case S2MPU02_LDO13: > + case S2MPU02_LDO14: > + case S2MPU02_LDO15: > + case S2MPU02_LDO17: > + case S2MPU02_BUCK7: > + state = S2MPU02_DISABLE_SUSPEND; > + break; > + default: > + state = S2MPU02_ENABLE_SUSPEND; > + break; > + }; > + break; > + default: > + return -EINVAL; > + }; > > ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); > if (ret < 0) > @@ -452,7 +495,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) > return 0; > > return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, > - rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); > + rdev->desc->enable_mask, state); > } > > static struct regulator_ops s2mps14_reg_ops = { > @@ -605,8 +648,7 @@ static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev, > } > > static int s2mps11_pmic_dt_parse(struct platform_device *pdev, > - struct of_regulator_match *rdata, struct s2mps11_info *s2mps11, > - enum sec_device_type dev_type) > + struct of_regulator_match *rdata, struct s2mps11_info *s2mps11) > { > struct device_node *reg_np; > > @@ -617,7 +659,7 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, > } > > of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); > - if (dev_type == S2MPS14X) > + if (s2mps11->dev_type == S2MPS14X) > s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); > > of_node_put(reg_np); > @@ -625,6 +667,238 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, > return 0; > } > > +static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) > +{ > + unsigned int ramp_val, ramp_shift, ramp_reg; > + > + switch (rdev_get_id(rdev)) { > + case S2MPU02_BUCK1: > + ramp_shift = S2MPU02_BUCK1_RAMP_SHIFT; > + break; > + case S2MPU02_BUCK2: > + ramp_shift = S2MPU02_BUCK2_RAMP_SHIFT; > + break; > + case S2MPU02_BUCK3: > + ramp_shift = S2MPU02_BUCK3_RAMP_SHIFT; > + break; > + case S2MPU02_BUCK4: > + ramp_shift = S2MPU02_BUCK4_RAMP_SHIFT; > + break; > + default: > + return 0; > + } > + ramp_reg = S2MPU02_REG_RAMP1; > + ramp_val = get_ramp_delay(ramp_delay); > + > + return regmap_update_bits(rdev->regmap, ramp_reg, > + S2MPU02_BUCK1234_RAMP_MASK << ramp_shift, > + ramp_val << ramp_shift); > +} > + > +static struct regulator_ops s2mpu02_ldo_ops = { > + .list_voltage = regulator_list_voltage_linear, > + .map_voltage = regulator_map_voltage_linear, > + .is_enabled = regulator_is_enabled_regmap, > + .enable = s2mps14_regulator_enable, > + .disable = regulator_disable_regmap, > + .get_voltage_sel = regulator_get_voltage_sel_regmap, > + .set_voltage_sel = regulator_set_voltage_sel_regmap, > + .set_voltage_time_sel = regulator_set_voltage_time_sel, > + .set_suspend_disable = s2mps14_regulator_set_suspend_disable, > +}; > + > +static struct regulator_ops s2mpu02_buck_ops = { > + .list_voltage = regulator_list_voltage_linear, > + .map_voltage = regulator_map_voltage_linear, > + .is_enabled = regulator_is_enabled_regmap, > + .enable = s2mps14_regulator_enable, > + .disable = regulator_disable_regmap, > + .get_voltage_sel = regulator_get_voltage_sel_regmap, > + .set_voltage_sel = regulator_set_voltage_sel_regmap, > + .set_voltage_time_sel = regulator_set_voltage_time_sel, > + .set_suspend_disable = s2mps14_regulator_set_suspend_disable, > + .set_ramp_delay = s2mpu02_set_ramp_delay, > +}; > + > +#define regulator_desc_s2mpu02_ldo1(num) { \ > + .name = "LDO"#num, \ > + .id = S2MPU02_LDO##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_LDO_MIN_900MV, \ > + .uV_step = S2MPU02_LDO_STEP_12_5MV, \ > + .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \ > + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ > + .vsel_reg = S2MPU02_REG_L1CTRL, \ > + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_L1CTRL, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_ldo2(num) { \ > + .name = "LDO"#num, \ > + .id = S2MPU02_LDO##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_LDO_MIN_1050MV, \ > + .uV_step = S2MPU02_LDO_STEP_25MV, \ > + .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \ > + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ > + .vsel_reg = S2MPU02_REG_L2CTRL1, \ > + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_L2CTRL1, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_ldo3(num) { \ > + .name = "LDO"#num, \ > + .id = S2MPU02_LDO##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_LDO_MIN_900MV, \ > + .uV_step = S2MPU02_LDO_STEP_12_5MV, \ > + .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \ > + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ > + .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ > + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_ldo4(num) { \ > + .name = "LDO"#num, \ > + .id = S2MPU02_LDO##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_LDO_MIN_1050MV, \ > + .uV_step = S2MPU02_LDO_STEP_25MV, \ > + .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \ > + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ > + .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ > + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_ldo5(num) { \ > + .name = "LDO"#num, \ > + .id = S2MPU02_LDO##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_LDO_MIN_1600MV, \ > + .uV_step = S2MPU02_LDO_STEP_50MV, \ > + .linear_min_sel = S2MPU02_LDO_GROUP3_START_SEL, \ > + .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ > + .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ > + .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > + > +#define regulator_desc_s2mpu02_buck1234(num) { \ > + .name = "BUCK"#num, \ > + .id = S2MPU02_BUCK##num, \ > + .ops = &s2mpu02_buck_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_BUCK1234_MIN_600MV, \ > + .uV_step = S2MPU02_BUCK1234_STEP_6_25MV, \ > + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ > + .linear_min_sel = S2MPU02_BUCK1234_START_SEL, \ > + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ > + .vsel_reg = S2MPU02_REG_B1CTRL2 + (num - 1) * 2, \ > + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_B1CTRL1 + (num - 1) * 2, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_buck5(num) { \ > + .name = "BUCK"#num, \ > + .id = S2MPU02_BUCK##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_BUCK5_MIN_1081_25MV, \ > + .uV_step = S2MPU02_BUCK5_STEP_6_25MV, \ > + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ > + .linear_min_sel = S2MPU02_BUCK5_START_SEL, \ > + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ > + .vsel_reg = S2MPU02_REG_B5CTRL2, \ > + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_B5CTRL1, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_buck6(num) { \ > + .name = "BUCK"#num, \ > + .id = S2MPU02_BUCK##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_BUCK6_MIN_1700MV, \ > + .uV_step = S2MPU02_BUCK6_STEP_2_50MV, \ > + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ > + .linear_min_sel = S2MPU02_BUCK6_START_SEL, \ > + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ > + .vsel_reg = S2MPU02_REG_B6CTRL2, \ > + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_B6CTRL1, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > +#define regulator_desc_s2mpu02_buck7(num) { \ > + .name = "BUCK"#num, \ > + .id = S2MPU02_BUCK##num, \ > + .ops = &s2mpu02_ldo_ops, \ > + .type = REGULATOR_VOLTAGE, \ > + .owner = THIS_MODULE, \ > + .min_uV = S2MPU02_BUCK7_MIN_900MV, \ > + .uV_step = S2MPU02_BUCK7_STEP_6_25MV, \ > + .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ > + .linear_min_sel = S2MPU02_BUCK7_START_SEL, \ > + .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ > + .vsel_reg = S2MPU02_REG_B7CTRL2, \ > + .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ > + .enable_reg = S2MPU02_REG_B7CTRL1, \ > + .enable_mask = S2MPU02_ENABLE_MASK \ > +} > + > +static const struct regulator_desc s2mpu02_regulators[] = { > + regulator_desc_s2mpu02_ldo1(1), > + regulator_desc_s2mpu02_ldo2(2), > + regulator_desc_s2mpu02_ldo4(3), > + regulator_desc_s2mpu02_ldo5(4), > + regulator_desc_s2mpu02_ldo4(5), > + regulator_desc_s2mpu02_ldo3(6), > + regulator_desc_s2mpu02_ldo3(7), > + regulator_desc_s2mpu02_ldo4(8), > + regulator_desc_s2mpu02_ldo5(9), > + regulator_desc_s2mpu02_ldo3(10), > + regulator_desc_s2mpu02_ldo4(11), > + regulator_desc_s2mpu02_ldo5(12), > + regulator_desc_s2mpu02_ldo5(13), > + regulator_desc_s2mpu02_ldo5(14), > + regulator_desc_s2mpu02_ldo5(15), > + regulator_desc_s2mpu02_ldo5(16), > + regulator_desc_s2mpu02_ldo4(17), > + regulator_desc_s2mpu02_ldo5(18), > + regulator_desc_s2mpu02_ldo3(19), > + regulator_desc_s2mpu02_ldo4(20), > + regulator_desc_s2mpu02_ldo5(21), > + regulator_desc_s2mpu02_ldo5(22), > + regulator_desc_s2mpu02_ldo5(23), > + regulator_desc_s2mpu02_ldo4(24), > + regulator_desc_s2mpu02_ldo5(25), > + regulator_desc_s2mpu02_ldo4(26), > + regulator_desc_s2mpu02_ldo5(27), > + regulator_desc_s2mpu02_ldo5(28), > + regulator_desc_s2mpu02_buck1234(1), > + regulator_desc_s2mpu02_buck1234(2), > + regulator_desc_s2mpu02_buck1234(3), > + regulator_desc_s2mpu02_buck1234(4), > + regulator_desc_s2mpu02_buck5(5), > + regulator_desc_s2mpu02_buck6(6), > + regulator_desc_s2mpu02_buck7(7), > +}; > + > static int s2mps11_pmic_probe(struct platform_device *pdev) > { > struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); > @@ -634,15 +908,14 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) > struct s2mps11_info *s2mps11; > int i, ret = 0; > const struct regulator_desc *regulators; > - enum sec_device_type dev_type; > > s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), > GFP_KERNEL); > if (!s2mps11) > return -ENOMEM; > > - dev_type = platform_get_device_id(pdev)->driver_data; > - switch (dev_type) { > + s2mps11->dev_type = platform_get_device_id(pdev)->driver_data; > + switch (s2mps11->dev_type) { > case S2MPS11X: > s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); > regulators = s2mps11_regulators; > @@ -651,8 +924,13 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) > s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); > regulators = s2mps14_regulators; > break; > + case S2MPU02: > + s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators); > + regulators = s2mpu02_regulators; > + break; > default: > - dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); > + dev_err(&pdev->dev, "Invalid device type: %u\n", > + s2mps11->dev_type); > return -EINVAL; > }; > > @@ -686,7 +964,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) > for (i = 0; i < s2mps11->rdev_num; i++) > rdata[i].name = regulators[i].name; > > - ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type); > + ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11); > if (ret) > goto out; > > @@ -739,6 +1017,7 @@ out: > static const struct platform_device_id s2mps11_pmic_id[] = { > { "s2mps11-pmic", S2MPS11X}, > { "s2mps14-pmic", S2MPS14X}, > + { "s2mpu02-pmic", S2MPU02}, > { }, > }; > MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); > diff --git a/include/linux/mfd/samsung/s2mpu02.h b/include/linux/mfd/samsung/s2mpu02.h > new file mode 100644 > index 0000000..47ae9bc > --- /dev/null > +++ b/include/linux/mfd/samsung/s2mpu02.h > @@ -0,0 +1,201 @@ > +/* > + * s2mpu02.h > + * > + * Copyright (c) 2014 Samsung Electronics Co., Ltd > + * http://www.samsung.com > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + */ > + > +#ifndef __LINUX_MFD_S2MPU02_H > +#define __LINUX_MFD_S2MPU02_H > + > +/* S2MPU02 registers */ > +enum S2MPU02_reg { > + S2MPU02_REG_ID, > + S2MPU02_REG_INT1, > + S2MPU02_REG_INT2, > + S2MPU02_REG_INT3, > + S2MPU02_REG_INT1M, > + S2MPU02_REG_INT2M, > + S2MPU02_REG_INT3M, > + S2MPU02_REG_ST1, > + S2MPU02_REG_ST2, > + S2MPU02_REG_PWRONSRC, > + S2MPU02_REG_OFFSRC, > + S2MPU02_REG_BU_CHG, > + S2MPU02_REG_RTCCTRL, > + S2MPU02_REG_PMCTRL1, > + S2MPU02_REG_RSVD1, > + S2MPU02_REG_RSVD2, > + S2MPU02_REG_RSVD3, > + S2MPU02_REG_RSVD4, > + S2MPU02_REG_RSVD5, > + S2MPU02_REG_RSVD6, > + S2MPU02_REG_RSVD7, > + S2MPU02_REG_WRSTEN, > + S2MPU02_REG_RSVD8, > + S2MPU02_REG_RSVD9, > + S2MPU02_REG_RSVD10, > + S2MPU02_REG_B1CTRL1, > + S2MPU02_REG_B1CTRL2, > + S2MPU02_REG_B2CTRL1, > + S2MPU02_REG_B2CTRL2, > + S2MPU02_REG_B3CTRL1, > + S2MPU02_REG_B3CTRL2, > + S2MPU02_REG_B4CTRL1, > + S2MPU02_REG_B4CTRL2, > + S2MPU02_REG_B5CTRL1, > + S2MPU02_REG_B5CTRL2, > + S2MPU02_REG_B5CTRL3, > + S2MPU02_REG_B5CTRL4, > + S2MPU02_REG_B5CTRL5, > + S2MPU02_REG_B6CTRL1, > + S2MPU02_REG_B6CTRL2, > + S2MPU02_REG_B7CTRL1, > + S2MPU02_REG_B7CTRL2, > + S2MPU02_REG_RAMP1, > + S2MPU02_REG_RAMP2, > + S2MPU02_REG_L1CTRL, > + S2MPU02_REG_L2CTRL1, > + S2MPU02_REG_L2CTRL2, > + S2MPU02_REG_L2CTRL3, > + S2MPU02_REG_L2CTRL4, > + S2MPU02_REG_L3CTRL, > + S2MPU02_REG_L4CTRL, > + S2MPU02_REG_L5CTRL, > + S2MPU02_REG_L6CTRL, > + S2MPU02_REG_L7CTRL, > + S2MPU02_REG_L8CTRL, > + S2MPU02_REG_L9CTRL, > + S2MPU02_REG_L10CTRL, > + S2MPU02_REG_L11CTRL, > + S2MPU02_REG_L12CTRL, > + S2MPU02_REG_L13CTRL, > + S2MPU02_REG_L14CTRL, > + S2MPU02_REG_L15CTRL, > + S2MPU02_REG_L16CTRL, > + S2MPU02_REG_L17CTRL, > + S2MPU02_REG_L18CTRL, > + S2MPU02_REG_L19CTRL, > + S2MPU02_REG_L20CTRL, > + S2MPU02_REG_L21CTRL, > + S2MPU02_REG_L22CTRL, > + S2MPU02_REG_L23CTRL, > + S2MPU02_REG_L24CTRL, > + S2MPU02_REG_L25CTRL, > + S2MPU02_REG_L26CTRL, > + S2MPU02_REG_L27CTRL, > + S2MPU02_REG_L28CTRL, > + S2MPU02_REG_LDODSCH1, > + S2MPU02_REG_LDODSCH2, > + S2MPU02_REG_LDODSCH3, > + S2MPU02_REG_LDODSCH4, > + S2MPU02_REG_SELMIF, > + S2MPU02_REG_RSVD11, > + S2MPU02_REG_RSVD12, > + S2MPU02_REG_RSVD13, > + S2MPU02_REG_DVSSEL, > + S2MPU02_REG_DVSPTR, > + S2MPU02_REG_DVSDATA, > +}; > + > +/* S2MPU02 regulator ids */ > +enum S2MPU02_regulators { > + S2MPU02_LDO1, > + S2MPU02_LDO2, > + S2MPU02_LDO3, > + S2MPU02_LDO4, > + S2MPU02_LDO5, > + S2MPU02_LDO6, > + S2MPU02_LDO7, > + S2MPU02_LDO8, > + S2MPU02_LDO9, > + S2MPU02_LDO10, > + S2MPU02_LDO11, > + S2MPU02_LDO12, > + S2MPU02_LDO13, > + S2MPU02_LDO14, > + S2MPU02_LDO15, > + S2MPU02_LDO16, > + S2MPU02_LDO17, > + S2MPU02_LDO18, > + S2MPU02_LDO19, > + S2MPU02_LDO20, > + S2MPU02_LDO21, > + S2MPU02_LDO22, > + S2MPU02_LDO23, > + S2MPU02_LDO24, > + S2MPU02_LDO25, > + S2MPU02_LDO26, > + S2MPU02_LDO27, > + S2MPU02_LDO28, > + S2MPU02_BUCK1, > + S2MPU02_BUCK2, > + S2MPU02_BUCK3, > + S2MPU02_BUCK4, > + S2MPU02_BUCK5, > + S2MPU02_BUCK6, > + S2MPU02_BUCK7, > + > + S2MPU02_REGULATOR_MAX, > +}; > + > +/* Regulator constraints for BUCKx */ > +#define S2MPU02_BUCK1234_MIN_600MV 600000 > +#define S2MPU02_BUCK5_MIN_1081_25MV 1081250 > +#define S2MPU02_BUCK6_MIN_1700MV 1700000 > +#define S2MPU02_BUCK7_MIN_900MV 900000 > + > +#define S2MPU02_BUCK1234_STEP_6_25MV 6250 > +#define S2MPU02_BUCK5_STEP_6_25MV 6250 > +#define S2MPU02_BUCK6_STEP_2_50MV 2500 > +#define S2MPU02_BUCK7_STEP_6_25MV 6250 > + > +#define S2MPU02_BUCK1234_START_SEL 0x00 > +#define S2MPU02_BUCK5_START_SEL 0x4D > +#define S2MPU02_BUCK6_START_SEL 0x28 > +#define S2MPU02_BUCK7_START_SEL 0x30 > + > +#define S2MPU02_BUCK_RAMP_DELAY 12500 > + > +/* Regulator constraints for different types of LDOx */ > +#define S2MPU02_LDO_MIN_900MV 900000 > +#define S2MPU02_LDO_MIN_1050MV 1050000 > +#define S2MPU02_LDO_MIN_1600MV 1600000 > +#define S2MPU02_LDO_STEP_12_5MV 12500 > +#define S2MPU02_LDO_STEP_25MV 25000 > +#define S2MPU02_LDO_STEP_50MV 50000 > + > +#define S2MPU02_LDO_GROUP1_START_SEL 0x8 > +#define S2MPU02_LDO_GROUP2_START_SEL 0xA > +#define S2MPU02_LDO_GROUP3_START_SEL 0x10 > + > +#define S2MPU02_LDO_VSEL_MASK 0x3F > +#define S2MPU02_BUCK_VSEL_MASK 0xFF > +#define S2MPU02_ENABLE_MASK (0x03 << S2MPU02_ENABLE_SHIFT) > +#define S2MPU02_ENABLE_SHIFT 6 > + > +/* On/Off controlled by PWREN */ > +#define S2MPU02_ENABLE_SUSPEND (0x01 << S2MPU02_ENABLE_SHIFT) > +#define S2MPU02_DISABLE_SUSPEND (0x11 << S2MPU02_ENABLE_SHIFT) > +#define S2MPU02_LDO_N_VOLTAGES (S2MPU02_LDO_VSEL_MASK + 1) > +#define S2MPU02_BUCK_N_VOLTAGES (S2MPU02_BUCK_VSEL_MASK + 1) > + > +/* RAMP delay for BUCK1234*/ > +#define S2MPU02_BUCK1_RAMP_SHIFT 6 > +#define S2MPU02_BUCK2_RAMP_SHIFT 4 > +#define S2MPU02_BUCK3_RAMP_SHIFT 2 > +#define S2MPU02_BUCK4_RAMP_SHIFT 0 > +#define S2MPU02_BUCK1234_RAMP_MASK 0x3 > + > +#endif /* __LINUX_MFD_S2MPU02_H */ -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device 2014-06-16 13:19 ` Lee Jones @ 2014-06-16 23:41 ` Chanwoo Choi 0 siblings, 0 replies; 8+ messages in thread From: Chanwoo Choi @ 2014-06-16 23:41 UTC (permalink / raw) To: Lee Jones Cc: sbkim73, sameo, k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel, Jonghwa Lee Hi Lee, On 06/16/2014 10:19 PM, Lee Jones wrote: > On Mon, 16 Jun 2014, Chanwoo Choi wrote: > >> This patch add S2MPU02 regulator device to existing S2MPS11 device driver >> because of little difference between S2MPS1x and S2MPU02. The S2MPU02 >> regulator device includes LDO[1-28] and BUCK[1-7]. >> >> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> >> [Add missing linear_min_sel of S2MPU02 LDO regulators by Jonghwa Lee] >> Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com> >> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> >> Acked-by: Mark Brown <broonie@linaro.org> >> --- >> drivers/mfd/sec-core.c | 25 +++ >> drivers/regulator/s2mps11.c | 321 +++++++++++++++++++++++++++++++++--- >> include/linux/mfd/samsung/s2mpu02.h | 201 ++++++++++++++++++++++ >> 3 files changed, 526 insertions(+), 21 deletions(-) >> create mode 100644 include/linux/mfd/samsung/s2mpu02.h > > MFD changes look good to me. > > Acked-by: Lee Jones <lee.jones@linaro.org> Thanks. > > I assume we have to wait for the other patches to be ready before > applying this one? We don't need to wait for the other patches because related patches was already merged on Linux 3.16-rc1. Best Regards, Chanwoo Choi ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv5 3/3] dt-bindings: mfd: s2mps11: Add support S2MPU02 PMIC 2014-06-16 4:42 [PATCHv5 0/3] mfd: sec-core: Add support S2MPU02 PMIC device Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device Chanwoo Choi @ 2014-06-16 4:42 ` Chanwoo Choi 2 siblings, 0 replies; 8+ messages in thread From: Chanwoo Choi @ 2014-06-16 4:42 UTC (permalink / raw) To: lee.jones, sbkim73, sameo Cc: k.kozlowski, myungjoo.ham, kyungmin.park, linux-kernel, Chanwoo Choi, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap, Mark Brown, Yadwinder Singh Brar, Tomasz Figa, Sachin Kamat, devicetree, linux-doc This patch add documentation for S2MPU02 PMIC device. S2MPU02 has a little difference from S2MPS11/S2MPS14 PMIC and has LDO[1-28]/Buck[1-7]. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Cc: Rob Herring <robh+dt@kernel.org> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk> Cc: Kumar Gala <galak@codeaurora.org> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Lee Jones <lee.jones@linaro.org> Cc: Mark Brown <broonie@linaro.org> Cc: Krzysztof Kozlowski <k.kozlowski@samsung.com> Cc: Yadwinder Singh Brar <yadi.brar@samsung.com> Cc: Tomasz Figa <t.figa@samsung.com> Cc: Sachin Kamat <sachin.kamat@linaro.org> Cc: devicetree@vger.kernel.org Cc: linux-doc@vger.kernel.org --- Documentation/devicetree/bindings/mfd/s2mps11.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt index d81ba30..f7c9180 100644 --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt @@ -1,5 +1,5 @@ -* Samsung S2MPS11 and S2MPS14 Voltage and Current Regulator +* Samsung S2MPS11, S2MPS14 and S2MPU02 Voltage and Current Regulator The Samsung S2MPS11 is a multi-function device which includes voltage and current regulators, RTC, charger controller and other sub-blocks. It is @@ -7,7 +7,8 @@ interfaced to the host controller using an I2C interface. Each sub-block is addressed by the host system using different I2C slave addresses. Required properties: -- compatible: Should be "samsung,s2mps11-pmic" or "samsung,s2mps14-pmic". +- compatible: Should be "samsung,s2mps11-pmic" or "samsung,s2mps14-pmic" + or "samsung,s2mpu02-pmic". - reg: Specifies the I2C slave address of the pmic block. It should be 0x66. Optional properties: @@ -81,11 +82,13 @@ as per the datasheet of s2mps11. - valid values for n are: - S2MPS11: 1 to 38 - S2MPS14: 1 to 25 + - S2MPU02: 1 to 28 - Example: LDO1, LD02, LDO28 - BUCKn - valid values for n are: - S2MPS11: 1 to 10 - S2MPS14: 1 to 5 + - S2MPU02: 1 to 7 - Example: BUCK1, BUCK2, BUCK9 Example: -- 1.8.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-06-17 0:18 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-06-16 4:42 [PATCHv5 0/3] mfd: sec-core: Add support S2MPU02 PMIC device Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 1/3] mfd: sec-core: Add support for S2MPU02 device Chanwoo Choi 2014-06-16 13:03 ` Lee Jones 2014-06-17 0:18 ` Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 2/3] regulator: s2mps11: Add support S2MPU02 regulator device Chanwoo Choi 2014-06-16 13:19 ` Lee Jones 2014-06-16 23:41 ` Chanwoo Choi 2014-06-16 4:42 ` [PATCHv5 3/3] dt-bindings: mfd: s2mps11: Add support S2MPU02 PMIC Chanwoo Choi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox