aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@gmail.com>2012-08-08 11:17:26 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-09-11 05:38:03 -0400
commita6ccdcd98c39ac13508570dbd943a1cf1b569f55 (patch)
treecabab74ae3665d0d3e4a59a7b74d9a39d2d03854
parent015625a20f630c798a8c5fdf5d472be091b8ac7d (diff)
mfd: 88pm860x: Use REG resource for backlight
Now resource of 88pm860x backlight is changed from IORESOURCE_IO to IORESOURCE_REG. In original driver, the resource is using self-defined IORESOURCE_IO. So change the resource to register offset to match the definition of IORESOURCE_REG. Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/88pm860x-core.c78
-rw-r--r--drivers/video/backlight/88pm860x_bl.c114
-rw-r--r--include/linux/mfd/88pm860x.h8
3 files changed, 89 insertions, 111 deletions
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 75864383573d..b72628e8d6ee 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -21,10 +21,20 @@
21 21
22#define INT_STATUS_NUM 3 22#define INT_STATUS_NUM 3
23 23
24static struct resource bk_resources[] __devinitdata = { 24static struct resource bk0_resources[] __devinitdata = {
25 {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_REG,}, 25 {2, 2, "duty cycle", IORESOURCE_REG, },
26 {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_REG,}, 26 {3, 3, "always on", IORESOURCE_REG, },
27 {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_REG,}, 27 {3, 3, "current", IORESOURCE_REG, },
28};
29static struct resource bk1_resources[] __devinitdata = {
30 {4, 4, "duty cycle", IORESOURCE_REG, },
31 {5, 5, "always on", IORESOURCE_REG, },
32 {5, 5, "current", IORESOURCE_REG, },
33};
34static struct resource bk2_resources[] __devinitdata = {
35 {6, 6, "duty cycle", IORESOURCE_REG, },
36 {7, 7, "always on", IORESOURCE_REG, },
37 {5, 5, "current", IORESOURCE_REG, },
28}; 38};
29 39
30static struct resource led_resources[] __devinitdata = { 40static struct resource led_resources[] __devinitdata = {
@@ -99,9 +109,22 @@ static struct resource rtc_resources[] __devinitdata = {
99}; 109};
100 110
101static struct mfd_cell bk_devs[] = { 111static struct mfd_cell bk_devs[] = {
102 {"88pm860x-backlight", 0,}, 112 {
103 {"88pm860x-backlight", 1,}, 113 .name = "88pm860x-backlight",
104 {"88pm860x-backlight", 2,}, 114 .id = 0,
115 .num_resources = ARRAY_SIZE(bk0_resources),
116 .resources = bk0_resources,
117 }, {
118 .name = "88pm860x-backlight",
119 .id = 1,
120 .num_resources = ARRAY_SIZE(bk1_resources),
121 .resources = bk1_resources,
122 }, {
123 .name = "88pm860x-backlight",
124 .id = 2,
125 .num_resources = ARRAY_SIZE(bk2_resources),
126 .resources = bk2_resources,
127 },
105}; 128};
106 129
107static struct mfd_cell led_devs[] = { 130static struct mfd_cell led_devs[] = {
@@ -615,36 +638,21 @@ static void __devinit device_osc_init(struct i2c_client *i2c)
615static void __devinit device_bk_init(struct pm860x_chip *chip, 638static void __devinit device_bk_init(struct pm860x_chip *chip,
616 struct pm860x_platform_data *pdata) 639 struct pm860x_platform_data *pdata)
617{ 640{
618 int ret; 641 int ret, i;
619 int i, j, id; 642
620 643 if (pdata && pdata->backlight) {
621 if ((pdata == NULL) || (pdata->backlight == NULL)) 644 if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
622 return; 645 pdata->num_backlights = ARRAY_SIZE(bk_devs);
623 646 for (i = 0; i < pdata->num_backlights; i++) {
624 if (pdata->num_backlights > ARRAY_SIZE(bk_devs)) 647 bk_devs[i].platform_data = &pdata->backlight[i];
625 pdata->num_backlights = ARRAY_SIZE(bk_devs); 648 bk_devs[i].pdata_size =
626 649 sizeof(struct pm860x_backlight_pdata);
627 for (i = 0; i < pdata->num_backlights; i++) {
628 bk_devs[i].platform_data = &pdata->backlight[i];
629 bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
630
631 for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
632 id = bk_resources[j].start;
633 if (pdata->backlight[i].flags != id)
634 continue;
635
636 bk_devs[i].num_resources = 1;
637 bk_devs[i].resources = &bk_resources[j];
638 ret = mfd_add_devices(chip->dev, 0,
639 &bk_devs[i], 1,
640 &bk_resources[j], 0);
641 if (ret < 0) {
642 dev_err(chip->dev, "Failed to add "
643 "backlight subdev\n");
644 return;
645 }
646 } 650 }
647 } 651 }
652 ret = mfd_add_devices(chip->dev, 0, bk_devs,
653 ARRAY_SIZE(bk_devs), NULL, 0);
654 if (ret < 0)
655 dev_err(chip->dev, "Failed to add backlight subdev\n");
648} 656}
649 657
650static void __devinit device_led_init(struct pm860x_chip *chip, 658static void __devinit device_led_init(struct pm860x_chip *chip,
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index d65472e9b30d..965161cacefa 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -31,57 +31,26 @@ struct pm860x_backlight_data {
31 int port; 31 int port;
32 int pwm; 32 int pwm;
33 int iset; 33 int iset;
34 int reg_duty_cycle;
35 int reg_always_on;
36 int reg_current;
34}; 37};
35 38
36static inline int wled_a(int port)
37{
38 int ret;
39
40 ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
41 return ret;
42}
43
44static inline int wled_b(int port)
45{
46 int ret;
47
48 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
49 return ret;
50}
51
52/* WLED2 & WLED3 share the same IDC */
53static inline int wled_idc(int port)
54{
55 int ret;
56
57 switch (port) {
58 case PM8606_BACKLIGHT1:
59 case PM8606_BACKLIGHT2:
60 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
61 break;
62 case PM8606_BACKLIGHT3:
63 default:
64 ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
65 break;
66 }
67 return ret;
68}
69
70static int backlight_power_set(struct pm860x_chip *chip, int port, 39static int backlight_power_set(struct pm860x_chip *chip, int port,
71 int on) 40 int on)
72{ 41{
73 int ret = -EINVAL; 42 int ret = -EINVAL;
74 43
75 switch (port) { 44 switch (port) {
76 case PM8606_BACKLIGHT1: 45 case 0:
77 ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) : 46 ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
78 pm8606_osc_disable(chip, WLED1_DUTY); 47 pm8606_osc_disable(chip, WLED1_DUTY);
79 break; 48 break;
80 case PM8606_BACKLIGHT2: 49 case 1:
81 ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) : 50 ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
82 pm8606_osc_disable(chip, WLED2_DUTY); 51 pm8606_osc_disable(chip, WLED2_DUTY);
83 break; 52 break;
84 case PM8606_BACKLIGHT3: 53 case 2:
85 ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) : 54 ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
86 pm8606_osc_disable(chip, WLED3_DUTY); 55 pm8606_osc_disable(chip, WLED3_DUTY);
87 break; 56 break;
@@ -104,13 +73,13 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
104 if (brightness) 73 if (brightness)
105 backlight_power_set(chip, data->port, 1); 74 backlight_power_set(chip, data->port, 1);
106 75
107 ret = pm860x_reg_write(data->i2c, wled_a(data->port), value); 76 ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
108 if (ret < 0) 77 if (ret < 0)
109 goto out; 78 goto out;
110 79
111 if ((data->current_brightness == 0) && brightness) { 80 if ((data->current_brightness == 0) && brightness) {
112 if (data->iset) { 81 if (data->iset) {
113 ret = pm860x_set_bits(data->i2c, wled_idc(data->port), 82 ret = pm860x_set_bits(data->i2c, data->reg_current,
114 CURRENT_BITMASK, data->iset); 83 CURRENT_BITMASK, data->iset);
115 if (ret < 0) 84 if (ret < 0)
116 goto out; 85 goto out;
@@ -123,17 +92,17 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
123 } 92 }
124 if (brightness == MAX_BRIGHTNESS) { 93 if (brightness == MAX_BRIGHTNESS) {
125 /* set WLED_ON bit as 100% */ 94 /* set WLED_ON bit as 100% */
126 ret = pm860x_set_bits(data->i2c, wled_b(data->port), 95 ret = pm860x_set_bits(data->i2c, data->reg_always_on,
127 PM8606_WLED_ON, PM8606_WLED_ON); 96 PM8606_WLED_ON, PM8606_WLED_ON);
128 } 97 }
129 } else { 98 } else {
130 if (brightness == MAX_BRIGHTNESS) { 99 if (brightness == MAX_BRIGHTNESS) {
131 /* set WLED_ON bit as 100% */ 100 /* set WLED_ON bit as 100% */
132 ret = pm860x_set_bits(data->i2c, wled_b(data->port), 101 ret = pm860x_set_bits(data->i2c, data->reg_always_on,
133 PM8606_WLED_ON, PM8606_WLED_ON); 102 PM8606_WLED_ON, PM8606_WLED_ON);
134 } else { 103 } else {
135 /* clear WLED_ON bit since it's not 100% */ 104 /* clear WLED_ON bit since it's not 100% */
136 ret = pm860x_set_bits(data->i2c, wled_b(data->port), 105 ret = pm860x_set_bits(data->i2c, data->reg_always_on,
137 PM8606_WLED_ON, 0); 106 PM8606_WLED_ON, 0);
138 } 107 }
139 } 108 }
@@ -174,7 +143,7 @@ static int pm860x_backlight_get_brightness(struct backlight_device *bl)
174 struct pm860x_chip *chip = data->chip; 143 struct pm860x_chip *chip = data->chip;
175 int ret; 144 int ret;
176 145
177 ret = pm860x_reg_read(data->i2c, wled_a(data->port)); 146 ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
178 if (ret < 0) 147 if (ret < 0)
179 goto out; 148 goto out;
180 data->current_brightness = ret; 149 data->current_brightness = ret;
@@ -193,43 +162,50 @@ static const struct backlight_ops pm860x_backlight_ops = {
193static int pm860x_backlight_probe(struct platform_device *pdev) 162static int pm860x_backlight_probe(struct platform_device *pdev)
194{ 163{
195 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 164 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
196 struct pm860x_backlight_pdata *pdata = NULL; 165 struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data;
197 struct pm860x_backlight_data *data; 166 struct pm860x_backlight_data *data;
198 struct backlight_device *bl; 167 struct backlight_device *bl;
199 struct resource *res; 168 struct resource *res;
200 struct backlight_properties props; 169 struct backlight_properties props;
201 char name[MFD_NAME_SIZE]; 170 char name[MFD_NAME_SIZE];
202 int ret; 171 int ret = 0;
203
204 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
205 if (res == NULL) {
206 dev_err(&pdev->dev, "No I/O resource!\n");
207 return -EINVAL;
208 }
209
210 pdata = pdev->dev.platform_data;
211 if (pdata == NULL) {
212 dev_err(&pdev->dev, "platform data isn't assigned to "
213 "backlight\n");
214 return -EINVAL;
215 }
216 172
217 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data), 173 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
218 GFP_KERNEL); 174 GFP_KERNEL);
219 if (data == NULL) 175 if (data == NULL)
220 return -ENOMEM; 176 return -ENOMEM;
221 strncpy(name, res->name, MFD_NAME_SIZE); 177 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
178 if (!res) {
179 dev_err(&pdev->dev, "No REG resource for duty cycle\n");
180 ret = -ENXIO;
181 goto out;
182 }
183 data->reg_duty_cycle = res->start;
184 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
185 if (!res) {
186 dev_err(&pdev->dev, "No REG resorce for always on\n");
187 ret = -ENXIO;
188 goto out;
189 }
190 data->reg_always_on = res->start;
191 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
192 if (!res) {
193 dev_err(&pdev->dev, "No REG resource for current\n");
194 ret = -ENXIO;
195 goto out;
196 }
197 data->reg_current = res->start;
198
199 memset(name, 0, MFD_NAME_SIZE);
200 sprintf(name, "backlight-%d", pdev->id);
201 data->port = pdev->id;
222 data->chip = chip; 202 data->chip = chip;
223 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \ 203 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
224 : chip->companion; 204 : chip->companion;
225 data->current_brightness = MAX_BRIGHTNESS; 205 data->current_brightness = MAX_BRIGHTNESS;
226 data->pwm = pdata->pwm; 206 if (pdata) {
227 data->iset = pdata->iset; 207 data->pwm = pdata->pwm;
228 data->port = pdata->flags; 208 data->iset = pdata->iset;
229 if (data->port < 0) {
230 dev_err(&pdev->dev, "wrong platform data is assigned");
231 kfree(data);
232 return -EINVAL;
233 } 209 }
234 210
235 memset(&props, 0, sizeof(struct backlight_properties)); 211 memset(&props, 0, sizeof(struct backlight_properties));
@@ -248,12 +224,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
248 /* read current backlight */ 224 /* read current backlight */
249 ret = pm860x_backlight_get_brightness(bl); 225 ret = pm860x_backlight_get_brightness(bl);
250 if (ret < 0) 226 if (ret < 0)
251 goto out; 227 goto out_brt;
252 228
253 backlight_update_status(bl); 229 backlight_update_status(bl);
254 return 0; 230 return 0;
255out: 231out_brt:
256 backlight_device_unregister(bl); 232 backlight_device_unregister(bl);
233out:
234 devm_kfree(&pdev->dev, data);
257 return ret; 235 return ret;
258} 236}
259 237
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 7b24943779fa..b7e656d29be3 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -35,12 +35,6 @@ enum {
35}; 35};
36 36
37enum { 37enum {
38 PM8606_BACKLIGHT1 = 0,
39 PM8606_BACKLIGHT2,
40 PM8606_BACKLIGHT3,
41};
42
43enum {
44 PM8606_LED1_RED = 0, 38 PM8606_LED1_RED = 0,
45 PM8606_LED1_GREEN, 39 PM8606_LED1_GREEN,
46 PM8606_LED1_BLUE, 40 PM8606_LED1_BLUE,
@@ -340,10 +334,8 @@ enum {
340}; 334};
341 335
342struct pm860x_backlight_pdata { 336struct pm860x_backlight_pdata {
343 int id;
344 int pwm; 337 int pwm;
345 int iset; 338 int iset;
346 unsigned long flags;
347}; 339};
348 340
349struct pm860x_led_pdata { 341struct pm860x_led_pdata {