aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/as3711-regulator.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-03-22 12:15:48 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-24 21:08:09 -0400
commit416d67599e744bcaef4a5ac45d263a630351b778 (patch)
tree21ac48e6df5427f7fd9ed9cac4a572cac4a64d8f /drivers/regulator/as3711-regulator.c
parenta937536b868b8369b98967929045f1df54234323 (diff)
regulator: as3711: add OF support
AS3711 regulator OF support only evaluates standard regulator DT properties. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/as3711-regulator.c')
-rw-r--r--drivers/regulator/as3711-regulator.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c
index f0ba8c4eefa9..0539b3e8f83b 100644
--- a/drivers/regulator/as3711-regulator.c
+++ b/drivers/regulator/as3711-regulator.c
@@ -13,9 +13,11 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/mfd/as3711.h> 14#include <linux/mfd/as3711.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/of.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/regmap.h> 18#include <linux/regmap.h>
18#include <linux/regulator/driver.h> 19#include <linux/regulator/driver.h>
20#include <linux/regulator/of_regulator.h>
19#include <linux/slab.h> 21#include <linux/slab.h>
20 22
21struct as3711_regulator_info { 23struct as3711_regulator_info {
@@ -276,6 +278,60 @@ static struct as3711_regulator_info as3711_reg_info[] = {
276 278
277#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info) 279#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info)
278 280
281static const char *as3711_regulator_of_names[AS3711_REGULATOR_NUM] = {
282 [AS3711_REGULATOR_SD_1] = "sd1",
283 [AS3711_REGULATOR_SD_2] = "sd2",
284 [AS3711_REGULATOR_SD_3] = "sd3",
285 [AS3711_REGULATOR_SD_4] = "sd4",
286 [AS3711_REGULATOR_LDO_1] = "ldo1",
287 [AS3711_REGULATOR_LDO_2] = "ldo2",
288 [AS3711_REGULATOR_LDO_3] = "ldo3",
289 [AS3711_REGULATOR_LDO_4] = "ldo4",
290 [AS3711_REGULATOR_LDO_5] = "ldo5",
291 [AS3711_REGULATOR_LDO_6] = "ldo6",
292 [AS3711_REGULATOR_LDO_7] = "ldo7",
293 [AS3711_REGULATOR_LDO_8] = "ldo8",
294};
295
296static int as3711_regulator_parse_dt(struct device *dev,
297 struct device_node **of_node, const int count)
298{
299 struct as3711_regulator_pdata *pdata = dev_get_platdata(dev);
300 struct device_node *regulators =
301 of_find_node_by_name(dev->parent->of_node, "regulators");
302 struct of_regulator_match *matches, *match;
303 int ret, i;
304
305 if (!regulators) {
306 dev_err(dev, "regulator node not found\n");
307 return -ENODEV;
308 }
309
310 matches = devm_kzalloc(dev, sizeof(*matches) * count, GFP_KERNEL);
311 if (!matches)
312 return -ENOMEM;
313
314 for (i = 0, match = matches; i < count; i++, match++) {
315 match->name = as3711_regulator_of_names[i];
316 match->driver_data = as3711_reg_info + i;
317 }
318
319 ret = of_regulator_match(dev->parent, regulators, matches, count);
320 of_node_put(regulators);
321 if (ret < 0) {
322 dev_err(dev, "Error parsing regulator init data: %d\n", ret);
323 return ret;
324 }
325
326 for (i = 0, match = matches; i < count; i++, match++)
327 if (match->of_node) {
328 pdata->init_data[i] = match->init_data;
329 of_node[i] = match->of_node;
330 }
331
332 return 0;
333}
334
279static int as3711_regulator_probe(struct platform_device *pdev) 335static int as3711_regulator_probe(struct platform_device *pdev)
280{ 336{
281 struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); 337 struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev);
@@ -284,13 +340,24 @@ static int as3711_regulator_probe(struct platform_device *pdev)
284 struct regulator_config config = {.dev = &pdev->dev,}; 340 struct regulator_config config = {.dev = &pdev->dev,};
285 struct as3711_regulator *reg = NULL; 341 struct as3711_regulator *reg = NULL;
286 struct as3711_regulator *regs; 342 struct as3711_regulator *regs;
343 struct device_node *of_node[AS3711_REGULATOR_NUM] = {};
287 struct regulator_dev *rdev; 344 struct regulator_dev *rdev;
288 struct as3711_regulator_info *ri; 345 struct as3711_regulator_info *ri;
289 int ret; 346 int ret;
290 int id; 347 int id;
291 348
292 if (!pdata) 349 if (!pdata) {
293 dev_dbg(&pdev->dev, "No platform data...\n"); 350 dev_err(&pdev->dev, "No platform data...\n");
351 return -ENODEV;
352 }
353
354 if (pdev->dev.parent->of_node) {
355 ret = as3711_regulator_parse_dt(&pdev->dev, of_node, AS3711_REGULATOR_NUM);
356 if (ret < 0) {
357 dev_err(&pdev->dev, "DT parsing failed: %d\n", ret);
358 return ret;
359 }
360 }
294 361
295 regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * 362 regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM *
296 sizeof(struct as3711_regulator), GFP_KERNEL); 363 sizeof(struct as3711_regulator), GFP_KERNEL);
@@ -300,7 +367,7 @@ static int as3711_regulator_probe(struct platform_device *pdev)
300 } 367 }
301 368
302 for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { 369 for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) {
303 reg_data = pdata ? pdata->init_data[id] : NULL; 370 reg_data = pdata->init_data[id];
304 371
305 /* No need to register if there is no regulator data */ 372 /* No need to register if there is no regulator data */
306 if (!reg_data) 373 if (!reg_data)
@@ -312,6 +379,7 @@ static int as3711_regulator_probe(struct platform_device *pdev)
312 config.init_data = reg_data; 379 config.init_data = reg_data;
313 config.driver_data = reg; 380 config.driver_data = reg;
314 config.regmap = as3711->regmap; 381 config.regmap = as3711->regmap;
382 config.of_node = of_node[id];
315 383
316 rdev = regulator_register(&ri->desc, &config); 384 rdev = regulator_register(&ri->desc, &config);
317 if (IS_ERR(rdev)) { 385 if (IS_ERR(rdev)) {