diff options
-rw-r--r-- | Documentation/devicetree/bindings/regulator/tps65217.txt | 91 | ||||
-rw-r--r-- | drivers/mfd/tps65217.c | 67 | ||||
-rw-r--r-- | drivers/regulator/tps65217-regulator.c | 1 | ||||
-rw-r--r-- | include/linux/mfd/tps65217.h | 3 |
4 files changed, 159 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/regulator/tps65217.txt b/Documentation/devicetree/bindings/regulator/tps65217.txt new file mode 100644 index 000000000000..0487e9675ba0 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/tps65217.txt | |||
@@ -0,0 +1,91 @@ | |||
1 | TPS65217 family of regulators | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "ti,tps65217" | ||
5 | - reg: I2C slave address | ||
6 | - regulators: list of regulators provided by this controller, must be named | ||
7 | after their hardware counterparts: dcdc[1-3] and ldo[1-4] | ||
8 | - regulators: This is the list of child nodes that specify the regulator | ||
9 | initialization data for defined regulators. Not all regulators for the given | ||
10 | device need to be present. The definition for each of these nodes is defined | ||
11 | using the standard binding for regulators found at | ||
12 | Documentation/devicetree/bindings/regulator/regulator.txt. | ||
13 | |||
14 | The valid names for regulators are: | ||
15 | tps65217: dcdc1, dcdc2, dcdc3, ldo1, ldo2, ldo3 and ldo4 | ||
16 | |||
17 | Each regulator is defined using the standard binding for regulators. | ||
18 | |||
19 | Example: | ||
20 | |||
21 | tps: tps@24 { | ||
22 | compatible = "ti,tps65217"; | ||
23 | |||
24 | regulators { | ||
25 | #address-cells = <1>; | ||
26 | #size-cells = <0>; | ||
27 | |||
28 | dcdc1_reg: regulator@0 { | ||
29 | reg = <0>; | ||
30 | regulator-compatible = "dcdc1"; | ||
31 | regulator-min-microvolt = <900000>; | ||
32 | regulator-max-microvolt = <1800000>; | ||
33 | regulator-boot-on; | ||
34 | regulator-always-on; | ||
35 | }; | ||
36 | |||
37 | dcdc2_reg: regulator@1 { | ||
38 | reg = <1>; | ||
39 | regulator-compatible = "dcdc2"; | ||
40 | regulator-min-microvolt = <900000>; | ||
41 | regulator-max-microvolt = <3300000>; | ||
42 | regulator-boot-on; | ||
43 | regulator-always-on; | ||
44 | }; | ||
45 | |||
46 | dcdc3_reg: regulator@2 { | ||
47 | reg = <2>; | ||
48 | regulator-compatible = "dcdc3"; | ||
49 | regulator-min-microvolt = <900000>; | ||
50 | regulator-max-microvolt = <1500000>; | ||
51 | regulator-boot-on; | ||
52 | regulator-always-on; | ||
53 | }; | ||
54 | |||
55 | ldo1_reg: regulator@3 { | ||
56 | reg = <3>; | ||
57 | regulator-compatible = "ldo1"; | ||
58 | regulator-min-microvolt = <1000000>; | ||
59 | regulator-max-microvolt = <3300000>; | ||
60 | regulator-boot-on; | ||
61 | regulator-always-on; | ||
62 | }; | ||
63 | |||
64 | ldo2_reg: regulator@4 { | ||
65 | reg = <4>; | ||
66 | regulator-compatible = "ldo2"; | ||
67 | regulator-min-microvolt = <900000>; | ||
68 | regulator-max-microvolt = <3300000>; | ||
69 | regulator-boot-on; | ||
70 | regulator-always-on; | ||
71 | }; | ||
72 | |||
73 | ldo3_reg: regulator@5 { | ||
74 | reg = <5>; | ||
75 | regulator-compatible = "ldo3"; | ||
76 | regulator-min-microvolt = <1800000>; | ||
77 | regulator-max-microvolt = <3300000>; | ||
78 | regulator-boot-on; | ||
79 | regulator-always-on; | ||
80 | }; | ||
81 | |||
82 | ldo4_reg: regulator@6 { | ||
83 | reg = <6>; | ||
84 | regulator-compatible = "ldo4"; | ||
85 | regulator-min-microvolt = <1800000>; | ||
86 | regulator-max-microvolt = <3300000>; | ||
87 | regulator-boot-on; | ||
88 | regulator-always-on; | ||
89 | }; | ||
90 | }; | ||
91 | }; | ||
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index db194e433c08..61c097a98f5d 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/regulator/of_regulator.h> | ||
27 | 28 | ||
28 | #include <linux/mfd/core.h> | 29 | #include <linux/mfd/core.h> |
29 | #include <linux/mfd/tps65217.h> | 30 | #include <linux/mfd/tps65217.h> |
@@ -132,6 +133,61 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg, | |||
132 | } | 133 | } |
133 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); | 134 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); |
134 | 135 | ||
136 | #ifdef CONFIG_OF | ||
137 | static struct of_regulator_match reg_matches[] = { | ||
138 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
139 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
140 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
141 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
142 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
143 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
144 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
145 | }; | ||
146 | |||
147 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
148 | { | ||
149 | struct device_node *node = client->dev.of_node; | ||
150 | struct tps65217_board *pdata; | ||
151 | struct device_node *regs; | ||
152 | int count = ARRAY_SIZE(reg_matches); | ||
153 | int ret, i; | ||
154 | |||
155 | regs = of_find_node_by_name(node, "regulators"); | ||
156 | if (!regs) | ||
157 | return NULL; | ||
158 | |||
159 | ret = of_regulator_match(&client->dev, regs, reg_matches, count); | ||
160 | of_node_put(regs); | ||
161 | if ((ret < 0) || (ret > count)) | ||
162 | return NULL; | ||
163 | |||
164 | count = ret; | ||
165 | pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); | ||
166 | if (!pdata) | ||
167 | return NULL; | ||
168 | |||
169 | for (i = 0; i < count; i++) { | ||
170 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
171 | continue; | ||
172 | |||
173 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
174 | pdata->of_node[i] = reg_matches[i].of_node; | ||
175 | } | ||
176 | |||
177 | return pdata; | ||
178 | } | ||
179 | |||
180 | static struct of_device_id tps65217_of_match[] = { | ||
181 | { .compatible = "ti,tps65217", }, | ||
182 | { }, | ||
183 | }; | ||
184 | #else | ||
185 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
186 | { | ||
187 | return NULL; | ||
188 | } | ||
189 | #endif | ||
190 | |||
135 | static struct regmap_config tps65217_regmap_config = { | 191 | static struct regmap_config tps65217_regmap_config = { |
136 | .reg_bits = 8, | 192 | .reg_bits = 8, |
137 | .val_bits = 8, | 193 | .val_bits = 8, |
@@ -141,10 +197,14 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
141 | const struct i2c_device_id *ids) | 197 | const struct i2c_device_id *ids) |
142 | { | 198 | { |
143 | struct tps65217 *tps; | 199 | struct tps65217 *tps; |
200 | struct regulator_init_data *reg_data; | ||
144 | struct tps65217_board *pdata = client->dev.platform_data; | 201 | struct tps65217_board *pdata = client->dev.platform_data; |
145 | int i, ret; | 202 | int i, ret; |
146 | unsigned int version; | 203 | unsigned int version; |
147 | 204 | ||
205 | if (!pdata && client->dev.of_node) | ||
206 | pdata = tps65217_parse_dt(client); | ||
207 | |||
148 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 208 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
149 | if (!tps) | 209 | if (!tps) |
150 | return -ENOMEM; | 210 | return -ENOMEM; |
@@ -182,8 +242,9 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
182 | } | 242 | } |
183 | 243 | ||
184 | pdev->dev.parent = tps->dev; | 244 | pdev->dev.parent = tps->dev; |
185 | platform_device_add_data(pdev, &pdata->tps65217_init_data[i], | 245 | pdev->dev.of_node = pdata->of_node[i]; |
186 | sizeof(pdata->tps65217_init_data[i])); | 246 | reg_data = pdata->tps65217_init_data[i]; |
247 | platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); | ||
187 | tps->regulator_pdev[i] = pdev; | 248 | tps->regulator_pdev[i] = pdev; |
188 | 249 | ||
189 | platform_device_add(pdev); | 250 | platform_device_add(pdev); |
@@ -212,6 +273,8 @@ MODULE_DEVICE_TABLE(i2c, tps65217_id_table); | |||
212 | static struct i2c_driver tps65217_driver = { | 273 | static struct i2c_driver tps65217_driver = { |
213 | .driver = { | 274 | .driver = { |
214 | .name = "tps65217", | 275 | .name = "tps65217", |
276 | .owner = THIS_MODULE, | ||
277 | .of_match_table = of_match_ptr(tps65217_of_match), | ||
215 | }, | 278 | }, |
216 | .id_table = tps65217_id_table, | 279 | .id_table = tps65217_id_table, |
217 | .probe = tps65217_probe, | 280 | .probe = tps65217_probe, |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index f7d0495b003e..6caa222af77a 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -293,6 +293,7 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev) | |||
293 | tps->info[pdev->id] = info; | 293 | tps->info[pdev->id] = info; |
294 | 294 | ||
295 | config.dev = &pdev->dev; | 295 | config.dev = &pdev->dev; |
296 | config.of_node = pdev->dev.of_node; | ||
296 | config.init_data = pdev->dev.platform_data; | 297 | config.init_data = pdev->dev.platform_data; |
297 | config.driver_data = tps; | 298 | config.driver_data = tps; |
298 | 299 | ||
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index 3a80da103f3f..12c06870829a 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h | |||
@@ -217,7 +217,8 @@ enum tps65217_regulator_id { | |||
217 | * Board data may be used to initialize regulator. | 217 | * Board data may be used to initialize regulator. |
218 | */ | 218 | */ |
219 | struct tps65217_board { | 219 | struct tps65217_board { |
220 | struct regulator_init_data *tps65217_init_data; | 220 | struct regulator_init_data *tps65217_init_data[TPS65217_NUM_REGULATOR]; |
221 | struct device_node *of_node[TPS65217_NUM_REGULATOR]; | ||
221 | }; | 222 | }; |
222 | 223 | ||
223 | /** | 224 | /** |