diff options
author | Haojian Zhuang <haojian.zhuang@gmail.com> | 2012-08-08 11:17:26 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-09-11 05:38:03 -0400 |
commit | a6ccdcd98c39ac13508570dbd943a1cf1b569f55 (patch) | |
tree | cabab74ae3665d0d3e4a59a7b74d9a39d2d03854 | |
parent | 015625a20f630c798a8c5fdf5d472be091b8ac7d (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.c | 78 | ||||
-rw-r--r-- | drivers/video/backlight/88pm860x_bl.c | 114 | ||||
-rw-r--r-- | include/linux/mfd/88pm860x.h | 8 |
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 | ||
24 | static struct resource bk_resources[] __devinitdata = { | 24 | static 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 | }; | ||
29 | static 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 | }; | ||
34 | static 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 | ||
30 | static struct resource led_resources[] __devinitdata = { | 40 | static struct resource led_resources[] __devinitdata = { |
@@ -99,9 +109,22 @@ static struct resource rtc_resources[] __devinitdata = { | |||
99 | }; | 109 | }; |
100 | 110 | ||
101 | static struct mfd_cell bk_devs[] = { | 111 | static 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 | ||
107 | static struct mfd_cell led_devs[] = { | 130 | static struct mfd_cell led_devs[] = { |
@@ -615,36 +638,21 @@ static void __devinit device_osc_init(struct i2c_client *i2c) | |||
615 | static void __devinit device_bk_init(struct pm860x_chip *chip, | 638 | static 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 | ||
650 | static void __devinit device_led_init(struct pm860x_chip *chip, | 658 | static 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 | ||
36 | static inline int wled_a(int port) | ||
37 | { | ||
38 | int ret; | ||
39 | |||
40 | ret = ((port - PM8606_BACKLIGHT1) << 1) + 2; | ||
41 | return ret; | ||
42 | } | ||
43 | |||
44 | static 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 */ | ||
53 | static 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 | |||
70 | static int backlight_power_set(struct pm860x_chip *chip, int port, | 39 | static 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 = { | |||
193 | static int pm860x_backlight_probe(struct platform_device *pdev) | 162 | static 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; |
255 | out: | 231 | out_brt: |
256 | backlight_device_unregister(bl); | 232 | backlight_device_unregister(bl); |
233 | out: | ||
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 | ||
37 | enum { | 37 | enum { |
38 | PM8606_BACKLIGHT1 = 0, | ||
39 | PM8606_BACKLIGHT2, | ||
40 | PM8606_BACKLIGHT3, | ||
41 | }; | ||
42 | |||
43 | enum { | ||
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 | ||
342 | struct pm860x_backlight_pdata { | 336 | struct 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 | ||
349 | struct pm860x_led_pdata { | 341 | struct pm860x_led_pdata { |