aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mfd/88pm860x.txt85
-rw-r--r--Documentation/devicetree/bindings/regulator/88pm860x.txt30
-rw-r--r--Documentation/devicetree/bindings/video/backlight/88pm860x.txt15
-rw-r--r--drivers/input/touchscreen/88pm860x-ts.c46
-rw-r--r--drivers/leds/leds-88pm860x.c33
-rw-r--r--drivers/mfd/88pm860x-core.c62
-rw-r--r--drivers/regulator/88pm8607.c35
-rw-r--r--drivers/rtc/rtc-88pm860x.c43
-rw-r--r--drivers/video/backlight/88pm860x_bl.c39
-rw-r--r--include/linux/mfd/88pm860x.h4
10 files changed, 351 insertions, 41 deletions
diff --git a/Documentation/devicetree/bindings/mfd/88pm860x.txt b/Documentation/devicetree/bindings/mfd/88pm860x.txt
new file mode 100644
index 000000000000..63f3ee33759c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/88pm860x.txt
@@ -0,0 +1,85 @@
1* Marvell 88PM860x Power Management IC
2
3Required parent device properties:
4- compatible : "marvell,88pm860x"
5- reg : the I2C slave address for the 88pm860x chip
6- interrupts : IRQ line for the 88pm860x chip
7- interrupt-controller: describes the 88pm860x as an interrupt controller (has its own domain)
8- #interrupt-cells : should be 1.
9 - The cell is the 88pm860x local IRQ number
10
11Optional parent device properties:
12- marvell,88pm860x-irq-read-clr: inicates whether interrupt status is cleared by read
13- marvell,88pm860x-slave-addr: 88pm860x are two chips solution. <reg> stores the I2C address
14 of one chip, and this property stores the I2C address of
15 another chip.
16
1788pm860x consists of a large and varied group of sub-devices:
18
19Device Supply Names Description
20------ ------------ -----------
2188pm860x-onkey : : On key
2288pm860x-rtc : : RTC
2388pm8607 : : Regulators
2488pm860x-backlight : : Backlight
2588pm860x-led : : Led
2688pm860x-touch : : Touchscreen
27
28Example:
29
30 pmic: 88pm860x@34 {
31 compatible = "marvell,88pm860x";
32 reg = <0x34>;
33 interrupts = <4>;
34 interrupt-parent = <&intc>;
35 interrupt-controller;
36 #interrupt-cells = <1>;
37
38 marvell,88pm860x-irq-read-clr;
39 marvell,88pm860x-slave-addr = <0x11>;
40
41 regulators {
42 BUCK1 {
43 regulator-min-microvolt = <1000000>;
44 regulator-max-microvolt = <1500000>;
45 regulator-boot-on;
46 regulator-always-on;
47 };
48 LDO1 {
49 regulator-min-microvolt = <1200000>;
50 regulator-max-microvolt = <2800000>;
51 regulator-boot-on;
52 regulator-always-on;
53 };
54 };
55 rtc {
56 marvell,88pm860x-vrtc = <1>;
57 };
58 touch {
59 marvell,88pm860x-gpadc-prebias = <1>;
60 marvell,88pm860x-gpadc-slot-cycle = <1>;
61 marvell,88pm860x-tsi-prebias = <6>;
62 marvell,88pm860x-pen-prebias = <16>;
63 marvell,88pm860x-pen-prechg = <2>;
64 marvell,88pm860x-resistor-X = <300>;
65 };
66 backlights {
67 backlight-0 {
68 marvell,88pm860x-iset = <4>;
69 marvell,88pm860x-pwm = <3>;
70 };
71 backlight-2 {
72 };
73 };
74 leds {
75 led0-red {
76 marvell,88pm860x-iset = <12>;
77 };
78 led0-green {
79 marvell,88pm860x-iset = <12>;
80 };
81 led0-blue {
82 marvell,88pm860x-iset = <12>;
83 };
84 };
85 };
diff --git a/Documentation/devicetree/bindings/regulator/88pm860x.txt b/Documentation/devicetree/bindings/regulator/88pm860x.txt
new file mode 100644
index 000000000000..1267b3e1a2cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/88pm860x.txt
@@ -0,0 +1,30 @@
1Marvell 88PM860x regulator
2
3Required properties:
4- compatible: "marvell,88pm860x"
5- reg: I2C slave address
6- regulators: A node that houses a sub-node for each regulator within the
7 device. Each sub-node is identified using the regulator-compatible
8 property, with valid values listed below.
9
10Example:
11
12 pmic: 88pm860x@34 {
13 compatible = "marvell,88pm860x";
14 reg = <0x34>;
15
16 regulators {
17 BUCK1 {
18 regulator-min-microvolt = <1000000>;
19 regulator-max-microvolt = <1500000>;
20 regulator-boot-on;
21 regulator-always-on;
22 };
23 BUCK3 {
24 regulator-min-microvolt = <1000000>;
25 regulator-max-microvolt = <3000000>;
26 regulator-boot-on;
27 regulator-always-on;
28 };
29 };
30 };
diff --git a/Documentation/devicetree/bindings/video/backlight/88pm860x.txt b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
new file mode 100644
index 000000000000..261df2799315
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
@@ -0,0 +1,15 @@
188pm860x-backlight bindings
2
3Optional properties:
4 - marvell,88pm860x-iset: Current supplies on backlight device.
5 - marvell,88pm860x-pwm: PWM frequency on backlight device.
6
7Example:
8
9 backlights {
10 backlight-0 {
11 marvell,88pm860x-iset = <4>;
12 marvell,88pm860x-pwm = <3>;
13 };
14 backlight-2 {
15 };
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 05f30b73c3c3..4f81e6eb74b6 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -10,6 +10,7 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of.h>
13#include <linux/platform_device.h> 14#include <linux/platform_device.h>
14#include <linux/i2c.h> 15#include <linux/i2c.h>
15#include <linux/input.h> 16#include <linux/input.h>
@@ -113,14 +114,31 @@ static void pm860x_touch_close(struct input_dev *dev)
113 pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); 114 pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
114} 115}
115 116
117#ifdef CONFIG_OF
118static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
119 int *res_x)
120{
121 struct device_node *np = pdev->dev.parent->of_node;
122 if (!np)
123 return -ENODEV;
124 np = of_find_node_by_name(np, "touch");
125 if (!np) {
126 dev_err(&pdev->dev, "Can't find touch node\n");
127 return -EINVAL;
128 }
129 of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
130 return 0;
131}
132#else
133#define pm860x_touch_dt_init(x, y) (-1)
134#endif
135
116static int __devinit pm860x_touch_probe(struct platform_device *pdev) 136static int __devinit pm860x_touch_probe(struct platform_device *pdev)
117{ 137{
118 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 138 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
119 struct pm860x_platform_data *pm860x_pdata = \ 139 struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
120 pdev->dev.parent->platform_data;
121 struct pm860x_touch_pdata *pdata = NULL;
122 struct pm860x_touch *touch; 140 struct pm860x_touch *touch;
123 int irq, ret; 141 int irq, ret, res_x = 0;
124 142
125 irq = platform_get_irq(pdev, 0); 143 irq = platform_get_irq(pdev, 0);
126 if (irq < 0) { 144 if (irq < 0) {
@@ -128,15 +146,13 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
128 return -EINVAL; 146 return -EINVAL;
129 } 147 }
130 148
131 if (!pm860x_pdata) { 149 if (pm860x_touch_dt_init(pdev, &res_x)) {
132 dev_err(&pdev->dev, "platform data is missing\n"); 150 if (pdata)
133 return -EINVAL; 151 res_x = pdata->res_x;
134 } 152 else {
135 153 dev_err(&pdev->dev, "failed to get platform data\n");
136 pdata = pm860x_pdata->touch; 154 return -EINVAL;
137 if (!pdata) { 155 }
138 dev_err(&pdev->dev, "touchscreen data is missing\n");
139 return -EINVAL;
140 } 156 }
141 157
142 touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); 158 touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
@@ -159,8 +175,8 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
159 touch->idev->close = pm860x_touch_close; 175 touch->idev->close = pm860x_touch_close;
160 touch->chip = chip; 176 touch->chip = chip;
161 touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 177 touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
162 touch->irq = irq + chip->irq_base; 178 touch->irq = irq;
163 touch->res_x = pdata->res_x; 179 touch->res_x = res_x;
164 input_set_drvdata(touch->idev, touch); 180 input_set_drvdata(touch->idev, touch);
165 181
166 ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, 182 ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 70232b1756f9..b7e8cc0957fc 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/of.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/leds.h> 18#include <linux/leds.h>
@@ -123,6 +124,33 @@ static void pm860x_led_set(struct led_classdev *cdev,
123 schedule_work(&data->work); 124 schedule_work(&data->work);
124} 125}
125 126
127#ifdef CONFIG_OF
128static int pm860x_led_dt_init(struct platform_device *pdev,
129 struct pm860x_led *data)
130{
131 struct device_node *nproot = pdev->dev.parent->of_node, *np;
132 int iset = 0;
133 if (!nproot)
134 return -ENODEV;
135 nproot = of_find_node_by_name(nproot, "leds");
136 if (!nproot) {
137 dev_err(&pdev->dev, "failed to find leds node\n");
138 return -ENODEV;
139 }
140 for_each_child_of_node(nproot, np) {
141 if (!of_node_cmp(np->name, data->name)) {
142 of_property_read_u32(np, "marvell,88pm860x-iset",
143 &iset);
144 data->iset = PM8606_LED_CURRENT(iset);
145 break;
146 }
147 }
148 return 0;
149}
150#else
151#define pm860x_led_dt_init(x, y) (-1)
152#endif
153
126static int pm860x_led_probe(struct platform_device *pdev) 154static int pm860x_led_probe(struct platform_device *pdev)
127{ 155{
128 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 156 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -179,8 +207,9 @@ static int pm860x_led_probe(struct platform_device *pdev)
179 data->chip = chip; 207 data->chip = chip;
180 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 208 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
181 data->port = pdev->id; 209 data->port = pdev->id;
182 if (pdata && pdata->iset) 210 if (pm860x_led_dt_init(pdev, data))
183 data->iset = pdata->iset; 211 if (pdata)
212 data->iset = pdata->iset;
184 213
185 data->current_brightness = 0; 214 data->current_brightness = 0;
186 data->cdev.name = data->name; 215 data->cdev.name = data->name;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 5b56fe8250b4..fdaf6861ce95 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -16,6 +16,8 @@
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/irqdomain.h> 18#include <linux/irqdomain.h>
19#include <linux/of.h>
20#include <linux/of_platform.h>
19#include <linux/platform_device.h> 21#include <linux/platform_device.h>
20#include <linux/regmap.h> 22#include <linux/regmap.h>
21#include <linux/slab.h> 23#include <linux/slab.h>
@@ -1112,12 +1114,6 @@ static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
1112 mfd_remove_devices(chip->dev); 1114 mfd_remove_devices(chip->dev);
1113} 1115}
1114 1116
1115static const struct i2c_device_id pm860x_id_table[] = {
1116 { "88PM860x", 0 },
1117 {}
1118};
1119MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
1120
1121static int verify_addr(struct i2c_client *i2c) 1117static int verify_addr(struct i2c_client *i2c)
1122{ 1118{
1123 unsigned short addr_8607[] = {0x30, 0x34}; 1119 unsigned short addr_8607[] = {0x30, 0x34};
@@ -1144,21 +1140,52 @@ static struct regmap_config pm860x_regmap_config = {
1144 .val_bits = 8, 1140 .val_bits = 8,
1145}; 1141};
1146 1142
1143static int __devinit pm860x_dt_init(struct device_node *np,
1144 struct device *dev,
1145 struct pm860x_platform_data *pdata)
1146{
1147 int ret;
1148
1149 if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
1150 pdata->irq_mode = 1;
1151 ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
1152 &pdata->companion_addr);
1153 if (ret) {
1154 dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
1155 "property\n");
1156 pdata->companion_addr = 0;
1157 }
1158 return 0;
1159}
1160
1147static int __devinit pm860x_probe(struct i2c_client *client, 1161static int __devinit pm860x_probe(struct i2c_client *client,
1148 const struct i2c_device_id *id) 1162 const struct i2c_device_id *id)
1149{ 1163{
1150 struct pm860x_platform_data *pdata = client->dev.platform_data; 1164 struct pm860x_platform_data *pdata = client->dev.platform_data;
1165 struct device_node *node = client->dev.of_node;
1151 struct pm860x_chip *chip; 1166 struct pm860x_chip *chip;
1152 int ret; 1167 int ret;
1153 1168
1154 if (!pdata) { 1169 if (node && !pdata) {
1170 /* parse DT to get platform data */
1171 pdata = devm_kzalloc(&client->dev,
1172 sizeof(struct pm860x_platform_data),
1173 GFP_KERNEL);
1174 if (!pdata)
1175 return -ENOMEM;
1176 ret = pm860x_dt_init(node, &client->dev, pdata);
1177 if (ret)
1178 goto err;
1179 } else if (!pdata) {
1155 pr_info("No platform data in %s!\n", __func__); 1180 pr_info("No platform data in %s!\n", __func__);
1156 return -EINVAL; 1181 return -EINVAL;
1157 } 1182 }
1158 1183
1159 chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL); 1184 chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
1160 if (chip == NULL) 1185 if (chip == NULL) {
1161 return -ENOMEM; 1186 ret = -ENOMEM;
1187 goto err;
1188 }
1162 1189
1163 chip->id = verify_addr(client); 1190 chip->id = verify_addr(client);
1164 chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); 1191 chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
@@ -1198,6 +1225,10 @@ static int __devinit pm860x_probe(struct i2c_client *client,
1198 1225
1199 pm860x_device_init(chip, pdata); 1226 pm860x_device_init(chip, pdata);
1200 return 0; 1227 return 0;
1228err:
1229 if (node)
1230 devm_kfree(&client->dev, pdata);
1231 return ret;
1201} 1232}
1202 1233
1203static int __devexit pm860x_remove(struct i2c_client *client) 1234static int __devexit pm860x_remove(struct i2c_client *client)
@@ -1238,11 +1269,24 @@ static int pm860x_resume(struct device *dev)
1238 1269
1239static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume); 1270static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
1240 1271
1272static const struct i2c_device_id pm860x_id_table[] = {
1273 { "88PM860x", 0 },
1274 {}
1275};
1276MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
1277
1278static const struct of_device_id pm860x_dt_ids[] = {
1279 { .compatible = "marvell,88pm860x", },
1280 {},
1281};
1282MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
1283
1241static struct i2c_driver pm860x_driver = { 1284static struct i2c_driver pm860x_driver = {
1242 .driver = { 1285 .driver = {
1243 .name = "88PM860x", 1286 .name = "88PM860x",
1244 .owner = THIS_MODULE, 1287 .owner = THIS_MODULE,
1245 .pm = &pm860x_pm_ops, 1288 .pm = &pm860x_pm_ops,
1289 .of_match_table = of_match_ptr(pm860x_dt_ids),
1246 }, 1290 },
1247 .probe = pm860x_probe, 1291 .probe = pm860x_probe,
1248 .remove = __devexit_p(pm860x_remove), 1292 .remove = __devexit_p(pm860x_remove),
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index f96fbe38ff6f..1c5ab0172ea2 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -12,6 +12,8 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/of.h>
16#include <linux/regulator/of_regulator.h>
15#include <linux/platform_device.h> 17#include <linux/platform_device.h>
16#include <linux/regulator/driver.h> 18#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h> 19#include <linux/regulator/machine.h>
@@ -364,6 +366,34 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = {
364 PM8606_PREG(PREREGULATORB, 5), 366 PM8606_PREG(PREREGULATORB, 5),
365}; 367};
366 368
369#ifdef CONFIG_OF
370static int pm8607_regulator_dt_init(struct platform_device *pdev,
371 struct pm8607_regulator_info *info,
372 struct regulator_config *config)
373{
374 struct device_node *nproot, *np;
375 nproot = pdev->dev.parent->of_node;
376 if (!nproot)
377 return -ENODEV;
378 nproot = of_find_node_by_name(nproot, "regulators");
379 if (!nproot) {
380 dev_err(&pdev->dev, "failed to find regulators node\n");
381 return -ENODEV;
382 }
383 for_each_child_of_node(nproot, np) {
384 if (!of_node_cmp(np->name, info->desc.name)) {
385 config->init_data =
386 of_get_regulator_init_data(&pdev->dev, np);
387 config->of_node = np;
388 break;
389 }
390 }
391 return 0;
392}
393#else
394#define pm8607_regulator_dt_init(x, y, z) (-1)
395#endif
396
367static int __devinit pm8607_regulator_probe(struct platform_device *pdev) 397static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
368{ 398{
369 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 399 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -402,9 +432,12 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
402 info->slope_double = 1; 432 info->slope_double = 1;
403 433
404 config.dev = &pdev->dev; 434 config.dev = &pdev->dev;
405 config.init_data = pdata;
406 config.driver_data = info; 435 config.driver_data = info;
407 436
437 if (pm8607_regulator_dt_init(pdev, info, &config))
438 if (pdata)
439 config.init_data = pdata;
440
408 if (chip->id == CHIP_PM8607) 441 if (chip->id == CHIP_PM8607)
409 config.regmap = chip->regmap; 442 config.regmap = chip->regmap;
410 else 443 else
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index feddefc42109..de9e854b326a 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/of.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/mutex.h> 17#include <linux/mutex.h>
@@ -284,6 +285,28 @@ out:
284} 285}
285#endif 286#endif
286 287
288#ifdef CONFIG_OF
289static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev,
290 struct pm860x_rtc_info *info)
291{
292 struct device_node *np = pdev->dev.parent->of_node;
293 int ret;
294 if (!np)
295 return -ENODEV;
296 np = of_find_node_by_name(np, "rtc");
297 if (!np) {
298 dev_err(&pdev->dev, "failed to find rtc node\n");
299 return -ENODEV;
300 }
301 ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
302 if (ret)
303 info->vrtc = 0;
304 return 0;
305}
306#else
307#define pm860x_rtc_dt_init(x, y) (-1)
308#endif
309
287static int __devinit pm860x_rtc_probe(struct platform_device *pdev) 310static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
288{ 311{
289 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 312 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -294,8 +317,6 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
294 int ret; 317 int ret;
295 318
296 pdata = pdev->dev.platform_data; 319 pdata = pdev->dev.platform_data;
297 if (pdata == NULL)
298 dev_warn(&pdev->dev, "No platform data!\n");
299 320
300 info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); 321 info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
301 if (!info) 322 if (!info)
@@ -345,9 +366,11 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
345 } 366 }
346 } 367 }
347 rtc_tm_to_time(&tm, &ticks); 368 rtc_tm_to_time(&tm, &ticks);
348 if (pdata && pdata->sync) { 369 if (pm860x_rtc_dt_init(pdev, info)) {
349 pdata->sync(ticks); 370 if (pdata && pdata->sync) {
350 info->sync = pdata->sync; 371 pdata->sync(ticks);
372 info->sync = pdata->sync;
373 }
351 } 374 }
352 375
353 info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, 376 info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
@@ -366,10 +389,12 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
366 389
367#ifdef VRTC_CALIBRATION 390#ifdef VRTC_CALIBRATION
368 /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ 391 /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
369 if (pdata && pdata->vrtc) 392 if (pm860x_rtc_dt_init(pdev, info)) {
370 info->vrtc = pdata->vrtc & 0x3; 393 if (pdata && pdata->vrtc)
371 else 394 info->vrtc = pdata->vrtc & 0x3;
372 info->vrtc = 1; 395 else
396 info->vrtc = 1;
397 }
373 pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); 398 pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
374 399
375 /* calibrate VRTC */ 400 /* calibrate VRTC */
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index 965161cacefa..b7ec34c57f46 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/of.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/fb.h> 17#include <linux/fb.h>
@@ -159,6 +160,36 @@ static const struct backlight_ops pm860x_backlight_ops = {
159 .get_brightness = pm860x_backlight_get_brightness, 160 .get_brightness = pm860x_backlight_get_brightness,
160}; 161};
161 162
163#ifdef CONFIG_OF
164static int pm860x_backlight_dt_init(struct platform_device *pdev,
165 struct pm860x_backlight_data *data,
166 char *name)
167{
168 struct device_node *nproot = pdev->dev.parent->of_node, *np;
169 int iset = 0;
170 if (!nproot)
171 return -ENODEV;
172 nproot = of_find_node_by_name(nproot, "backlights");
173 if (!nproot) {
174 dev_err(&pdev->dev, "failed to find backlights node\n");
175 return -ENODEV;
176 }
177 for_each_child_of_node(nproot, np) {
178 if (!of_node_cmp(np->name, name)) {
179 of_property_read_u32(np, "marvell,88pm860x-iset",
180 &iset);
181 data->iset = PM8606_WLED_CURRENT(iset);
182 of_property_read_u32(np, "marvell,88pm860x-pwm",
183 &data->pwm);
184 break;
185 }
186 }
187 return 0;
188}
189#else
190#define pm860x_backlight_dt_init(x, y, z) (-1)
191#endif
192
162static int pm860x_backlight_probe(struct platform_device *pdev) 193static int pm860x_backlight_probe(struct platform_device *pdev)
163{ 194{
164 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 195 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -203,9 +234,11 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
203 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \ 234 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
204 : chip->companion; 235 : chip->companion;
205 data->current_brightness = MAX_BRIGHTNESS; 236 data->current_brightness = MAX_BRIGHTNESS;
206 if (pdata) { 237 if (pm860x_backlight_dt_init(pdev, data, name)) {
207 data->pwm = pdata->pwm; 238 if (pdata) {
208 data->iset = pdata->iset; 239 data->pwm = pdata->pwm;
240 data->iset = pdata->iset;
241 }
209 } 242 }
210 243
211 memset(&props, 0, sizeof(struct backlight_properties)); 244 memset(&props, 0, sizeof(struct backlight_properties));
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index d515e5c438f0..ef3e6b701179 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -306,7 +306,7 @@ struct pm860x_chip {
306 struct regmap *regmap_companion; 306 struct regmap *regmap_companion;
307 307
308 int buck3_double; /* DVC ramp slope double */ 308 int buck3_double; /* DVC ramp slope double */
309 unsigned short companion_addr; 309 int companion_addr;
310 unsigned short osc_vote; 310 unsigned short osc_vote;
311 int id; 311 int id;
312 int irq_mode; 312 int irq_mode;
@@ -376,7 +376,7 @@ struct pm860x_platform_data {
376 struct regulator_init_data *ldo_vibrator; 376 struct regulator_init_data *ldo_vibrator;
377 struct regulator_init_data *ldo14; 377 struct regulator_init_data *ldo14;
378 378
379 unsigned short companion_addr; /* I2C address of companion chip */ 379 int companion_addr; /* I2C address of companion chip */
380 int i2c_port; /* Controlled by GI2C or PI2C */ 380 int i2c_port; /* Controlled by GI2C or PI2C */
381 int irq_mode; /* Clear interrupt by read/write(0/1) */ 381 int irq_mode; /* Clear interrupt by read/write(0/1) */
382 int irq_base; /* IRQ base number of 88pm860x */ 382 int irq_base; /* IRQ base number of 88pm860x */