aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/88pm860x-core.c165
-rw-r--r--drivers/regulator/88pm8607.c46
2 files changed, 128 insertions, 83 deletions
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index cec375c534b8..96ea0c64bbbc 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h> 18#include <linux/mfd/core.h>
19#include <linux/mfd/88pm860x.h> 19#include <linux/mfd/88pm860x.h>
20#include <linux/regulator/machine.h>
20 21
21#define INT_STATUS_NUM 3 22#define INT_STATUS_NUM 3
22 23
@@ -35,6 +36,27 @@ static struct resource led_resources[] __initdata = {
35 {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,}, 36 {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,},
36}; 37};
37 38
39static struct resource regulator_resources[] __initdata = {
40 {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
41 {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
42 {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
43 {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,},
44 {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,},
45 {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,},
46 {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,},
47 {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,},
48 {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,},
49 {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,},
50 {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO,},
51 {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO,},
52 {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,},
53 {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,},
54 {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,},
55 {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,},
56 {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,},
57 {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
58};
59
38static struct mfd_cell bk_devs[] __initdata = { 60static struct mfd_cell bk_devs[] __initdata = {
39 {"88pm860x-backlight", 0,}, 61 {"88pm860x-backlight", 0,},
40 {"88pm860x-backlight", 1,}, 62 {"88pm860x-backlight", 1,},
@@ -50,8 +72,30 @@ static struct mfd_cell led_devs[] __initdata = {
50 {"88pm860x-led", 5,}, 72 {"88pm860x-led", 5,},
51}; 73};
52 74
75static struct mfd_cell regulator_devs[] __initdata = {
76 {"88pm860x-regulator", 0,},
77 {"88pm860x-regulator", 1,},
78 {"88pm860x-regulator", 2,},
79 {"88pm860x-regulator", 3,},
80 {"88pm860x-regulator", 4,},
81 {"88pm860x-regulator", 5,},
82 {"88pm860x-regulator", 6,},
83 {"88pm860x-regulator", 7,},
84 {"88pm860x-regulator", 8,},
85 {"88pm860x-regulator", 9,},
86 {"88pm860x-regulator", 10,},
87 {"88pm860x-regulator", 11,},
88 {"88pm860x-regulator", 12,},
89 {"88pm860x-regulator", 13,},
90 {"88pm860x-regulator", 14,},
91 {"88pm860x-regulator", 15,},
92 {"88pm860x-regulator", 16,},
93 {"88pm860x-regulator", 17,},
94};
95
53static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)]; 96static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)];
54static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)]; 97static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)];
98static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)];
55 99
56static struct resource touch_resources[] = { 100static struct resource touch_resources[] = {
57 { 101 {
@@ -69,13 +113,6 @@ static struct mfd_cell touch_devs[] = {
69 }, 113 },
70}; 114};
71 115
72#define PM8607_REG_RESOURCE(_start, _end) \
73{ \
74 .start = PM8607_##_start, \
75 .end = PM8607_##_end, \
76 .flags = IORESOURCE_IO, \
77}
78
79static struct resource power_supply_resources[] = { 116static struct resource power_supply_resources[] = {
80 { 117 {
81 .name = "88pm860x-power", 118 .name = "88pm860x-power",
@@ -149,52 +186,6 @@ static struct mfd_cell codec_devs[] = {
149 }, 186 },
150}; 187};
151 188
152static struct resource regulator_resources[] = {
153 PM8607_REG_RESOURCE(BUCK1, BUCK1),
154 PM8607_REG_RESOURCE(BUCK2, BUCK2),
155 PM8607_REG_RESOURCE(BUCK3, BUCK3),
156 PM8607_REG_RESOURCE(LDO1, LDO1),
157 PM8607_REG_RESOURCE(LDO2, LDO2),
158 PM8607_REG_RESOURCE(LDO3, LDO3),
159 PM8607_REG_RESOURCE(LDO4, LDO4),
160 PM8607_REG_RESOURCE(LDO5, LDO5),
161 PM8607_REG_RESOURCE(LDO6, LDO6),
162 PM8607_REG_RESOURCE(LDO7, LDO7),
163 PM8607_REG_RESOURCE(LDO8, LDO8),
164 PM8607_REG_RESOURCE(LDO9, LDO9),
165 PM8607_REG_RESOURCE(LDO10, LDO10),
166 PM8607_REG_RESOURCE(LDO12, LDO12),
167 PM8607_REG_RESOURCE(VIBRATOR_SET, VIBRATOR_SET),
168 PM8607_REG_RESOURCE(LDO14, LDO14),
169};
170
171#define PM8607_REG_DEVS(_id) \
172{ \
173 .name = "88pm860x-regulator", \
174 .num_resources = 1, \
175 .resources = &regulator_resources[PM8607_ID_##_id], \
176 .id = PM8607_ID_##_id, \
177}
178
179static struct mfd_cell regulator_devs[] = {
180 PM8607_REG_DEVS(BUCK1),
181 PM8607_REG_DEVS(BUCK2),
182 PM8607_REG_DEVS(BUCK3),
183 PM8607_REG_DEVS(LDO1),
184 PM8607_REG_DEVS(LDO2),
185 PM8607_REG_DEVS(LDO3),
186 PM8607_REG_DEVS(LDO4),
187 PM8607_REG_DEVS(LDO5),
188 PM8607_REG_DEVS(LDO6),
189 PM8607_REG_DEVS(LDO7),
190 PM8607_REG_DEVS(LDO8),
191 PM8607_REG_DEVS(LDO9),
192 PM8607_REG_DEVS(LDO10),
193 PM8607_REG_DEVS(LDO12),
194 PM8607_REG_DEVS(LDO13),
195 PM8607_REG_DEVS(LDO14),
196};
197
198struct pm860x_irq_data { 189struct pm860x_irq_data {
199 int reg; 190 int reg;
200 int mask_reg; 191 int mask_reg;
@@ -623,6 +614,64 @@ static void __devinit device_led_init(struct pm860x_chip *chip,
623 } 614 }
624} 615}
625 616
617static void __devinit device_regulator_init(struct pm860x_chip *chip,
618 struct i2c_client *i2c,
619 struct pm860x_platform_data *pdata)
620{
621 struct regulator_init_data *initdata;
622 int ret;
623 int i, j;
624
625 if ((pdata == NULL) || (pdata->regulator == NULL))
626 return;
627
628 if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
629 pdata->num_regulators = ARRAY_SIZE(regulator_devs);
630
631 for (i = 0, j = -1; i < pdata->num_regulators; i++) {
632 initdata = &pdata->regulator[i];
633 if (strstr(initdata->constraints.name, "BUCK")) {
634 sscanf(initdata->constraints.name, "BUCK%d", &j);
635 /* BUCK1 ~ BUCK3 */
636 if ((j < 1) || (j > 3)) {
637 dev_err(chip->dev, "Failed to add constraint "
638 "(%s)\n", initdata->constraints.name);
639 goto out;
640 }
641 j = (j - 1) + PM8607_ID_BUCK1;
642 }
643 if (strstr(initdata->constraints.name, "LDO")) {
644 sscanf(initdata->constraints.name, "LDO%d", &j);
645 /* LDO1 ~ LDO15 */
646 if ((j < 1) || (j > 15)) {
647 dev_err(chip->dev, "Failed to add constraint "
648 "(%s)\n", initdata->constraints.name);
649 goto out;
650 }
651 j = (j - 1) + PM8607_ID_LDO1;
652 }
653 if (j == -1) {
654 dev_err(chip->dev, "Failed to add constraint (%s)\n",
655 initdata->constraints.name);
656 goto out;
657 }
658 memcpy(&regulator_pdata[i], &pdata->regulator[i],
659 sizeof(struct regulator_init_data));
660 regulator_devs[i].mfd_data = &regulator_pdata[i];
661 regulator_devs[i].num_resources = 1;
662 regulator_devs[i].resources = &regulator_resources[j];
663
664 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
665 &regulator_resources[j], 0);
666 if (ret < 0) {
667 dev_err(chip->dev, "Failed to add regulator subdev\n");
668 goto out;
669 }
670 }
671out:
672 return;
673}
674
626static void __devinit device_8607_init(struct pm860x_chip *chip, 675static void __devinit device_8607_init(struct pm860x_chip *chip,
627 struct i2c_client *i2c, 676 struct i2c_client *i2c,
628 struct pm860x_platform_data *pdata) 677 struct pm860x_platform_data *pdata)
@@ -678,14 +727,6 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
678 if (ret < 0) 727 if (ret < 0)
679 goto out; 728 goto out;
680 729
681 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
682 ARRAY_SIZE(regulator_devs),
683 &regulator_resources[0], 0);
684 if (ret < 0) {
685 dev_err(chip->dev, "Failed to add regulator subdev\n");
686 goto out_dev;
687 }
688
689 if (pdata && pdata->touch) { 730 if (pdata && pdata->touch) {
690 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], 731 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
691 ARRAY_SIZE(touch_devs), 732 ARRAY_SIZE(touch_devs),
@@ -723,6 +764,8 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
723 dev_err(chip->dev, "Failed to add codec subdev\n"); 764 dev_err(chip->dev, "Failed to add codec subdev\n");
724 goto out_dev; 765 goto out_dev;
725 } 766 }
767
768 device_regulator_init(chip, i2c, pdata);
726 return; 769 return;
727out_dev: 770out_dev:
728 mfd_remove_devices(chip->dev); 771 mfd_remove_devices(chip->dev);
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index dd6308499bd4..859251250b55 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -15,6 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h> 16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h> 17#include <linux/regulator/machine.h>
18#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 19#include <linux/mfd/88pm860x.h>
19 20
20struct pm8607_regulator_info { 21struct pm8607_regulator_info {
@@ -394,47 +395,48 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
394 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), 395 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6),
395}; 396};
396 397
397static inline struct pm8607_regulator_info *find_regulator_info(int id) 398static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
398{ 399{
399 struct pm8607_regulator_info *info; 400 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
401 struct pm8607_regulator_info *info = NULL;
402 struct regulator_init_data *pdata;
403 struct mfd_cell *cell;
400 int i; 404 int i;
401 405
406 cell = pdev->dev.platform_data;
407 if (cell == NULL)
408 return -ENODEV;
409 pdata = cell->mfd_data;
410 if (pdata == NULL)
411 return -EINVAL;
412
402 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { 413 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
403 info = &pm8607_regulator_info[i]; 414 info = &pm8607_regulator_info[i];
404 if (info->desc.id == id) 415 if (!strcmp(info->desc.name, pdata->constraints.name))
405 return info; 416 break;
406 } 417 }
407 return NULL; 418 if (i > ARRAY_SIZE(pm8607_regulator_info)) {
408} 419 dev_err(&pdev->dev, "Failed to find regulator %s\n",
409 420 pdata->constraints.name);
410static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
411{
412 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
413 struct pm860x_platform_data *pdata = chip->dev->platform_data;
414 struct pm8607_regulator_info *info = NULL;
415
416 info = find_regulator_info(pdev->id);
417 if (info == NULL) {
418 dev_err(&pdev->dev, "invalid regulator ID specified\n");
419 return -EINVAL; 421 return -EINVAL;
420 } 422 }
421 423
422 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 424 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
423 info->chip = chip; 425 info->chip = chip;
424 426
427 /* check DVC ramp slope double */
428 if (!strcmp(info->desc.name, "BUCK3"))
429 if (info->chip->buck3_double)
430 info->slope_double = 1;
431
425 info->regulator = regulator_register(&info->desc, &pdev->dev, 432 info->regulator = regulator_register(&info->desc, &pdev->dev,
426 pdata->regulator[pdev->id], info); 433 pdata, info);
427 if (IS_ERR(info->regulator)) { 434 if (IS_ERR(info->regulator)) {
428 dev_err(&pdev->dev, "failed to register regulator %s\n", 435 dev_err(&pdev->dev, "failed to register regulator %s\n",
429 info->desc.name); 436 info->desc.name);
430 return PTR_ERR(info->regulator); 437 return PTR_ERR(info->regulator);
431 } 438 }
432 439
433 /* check DVC ramp slope double */
434 if (info->desc.id == PM8607_ID_BUCK3)
435 if (info->chip->buck3_double)
436 info->slope_double = 1;
437
438 platform_set_drvdata(pdev, info); 440 platform_set_drvdata(pdev, info);
439 return 0; 441 return 0;
440} 442}