aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/tps6586x-regulator.c181
1 files changed, 155 insertions, 26 deletions
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index b91400cdbd95..7206f4e3e760 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -17,10 +17,12 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/of.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/regulator/driver.h> 23#include <linux/regulator/driver.h>
23#include <linux/regulator/machine.h> 24#include <linux/regulator/machine.h>
25#include <linux/regulator/of_regulator.h>
24#include <linux/mfd/tps6586x.h> 26#include <linux/mfd/tps6586x.h>
25 27
26/* supply control and voltage setting */ 28/* supply control and voltage setting */
@@ -255,10 +257,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
255 1 << ri->enable_bit[1]); 257 1 << ri->enable_bit[1]);
256} 258}
257 259
258static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev) 260static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev,
261 int id, struct regulator_init_data *p)
259{ 262{
260 struct device *parent = pdev->dev.parent; 263 struct device *parent = pdev->dev.parent;
261 struct regulator_init_data *p = pdev->dev.platform_data;
262 struct tps6586x_settings *setting = p->driver_data; 264 struct tps6586x_settings *setting = p->driver_data;
263 uint8_t reg; 265 uint8_t reg;
264 266
@@ -269,7 +271,7 @@ static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
269 return 0; 271 return 0;
270 272
271 /* only SM0 and SM1 can have the slew rate settings */ 273 /* only SM0 and SM1 can have the slew rate settings */
272 switch (pdev->id) { 274 switch (id) {
273 case TPS6586X_ID_SM_0: 275 case TPS6586X_ID_SM_0:
274 reg = TPS6586X_SM0SL; 276 reg = TPS6586X_SM0SL;
275 break; 277 break;
@@ -298,54 +300,181 @@ static inline struct tps6586x_regulator *find_regulator_info(int id)
298 return NULL; 300 return NULL;
299} 301}
300 302
303#ifdef CONFIG_OF
304static struct of_regulator_match tps6586x_matches[] = {
305 { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS },
306 { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 },
307 { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 },
308 { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 },
309 { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 },
310 { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 },
311 { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 },
312 { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 },
313 { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 },
314 { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 },
315 { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 },
316 { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 },
317 { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 },
318 { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 },
319 { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
320};
321
322static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
323 struct platform_device *pdev,
324 struct of_regulator_match **tps6586x_reg_matches)
325{
326 const unsigned int num = ARRAY_SIZE(tps6586x_matches);
327 struct device_node *np = pdev->dev.parent->of_node;
328 struct device_node *regs;
329 const char *sys_rail = NULL;
330 unsigned int i;
331 struct tps6586x_platform_data *pdata;
332 int err;
333
334 regs = of_find_node_by_name(np, "regulators");
335 if (!regs) {
336 dev_err(&pdev->dev, "regulator node not found\n");
337 return NULL;
338 }
339
340 err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num);
341 if (err < 0) {
342 dev_err(&pdev->dev, "Regulator match failed, e %d\n", err);
343 of_node_put(regs);
344 return NULL;
345 }
346
347 of_node_put(regs);
348
349 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
350 if (!pdata) {
351 dev_err(&pdev->dev, "Memory alloction failed\n");
352 return NULL;
353 }
354
355 for (i = 0; i < num; i++) {
356 int id;
357 if (!tps6586x_matches[i].init_data)
358 continue;
359
360 pdata->reg_init_data[i] = tps6586x_matches[i].init_data;
361 id = (int)tps6586x_matches[i].driver_data;
362 if (id == TPS6586X_ID_SYS)
363 sys_rail = pdata->reg_init_data[i]->constraints.name;
364
365 if ((id == TPS6586X_ID_LDO_5) || (id == TPS6586X_ID_LDO_RTC))
366 pdata->reg_init_data[i]->supply_regulator = sys_rail;
367 }
368 *tps6586x_reg_matches = tps6586x_matches;
369 return pdata;
370}
371#else
372static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
373 struct platform_device *pdev,
374 struct of_regulator_match **tps6586x_reg_matches)
375{
376 *tps6586x_reg_matches = NULL;
377 return NULL;
378}
379#endif
380
301static int tps6586x_regulator_probe(struct platform_device *pdev) 381static int tps6586x_regulator_probe(struct platform_device *pdev)
302{ 382{
303 struct tps6586x_regulator *ri = NULL; 383 struct tps6586x_regulator *ri = NULL;
304 struct regulator_config config = { }; 384 struct regulator_config config = { };
305 struct regulator_dev *rdev; 385 struct regulator_dev **rdev;
306 int id = pdev->id; 386 struct regulator_init_data *reg_data;
387 struct tps6586x_platform_data *pdata;
388 struct of_regulator_match *tps6586x_reg_matches = NULL;
389 int id;
307 int err; 390 int err;
308 391
309 dev_dbg(&pdev->dev, "Probing regulator %d\n", id); 392 dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
310 393
311 ri = find_regulator_info(id); 394 pdata = dev_get_platdata(pdev->dev.parent);
312 if (ri == NULL) { 395 if ((!pdata) && (pdev->dev.parent->of_node))
313 dev_err(&pdev->dev, "invalid regulator ID specified\n"); 396 pdata = tps6586x_parse_regulator_dt(pdev,
314 return -EINVAL; 397 &tps6586x_reg_matches);
315 }
316 398
317 err = tps6586x_regulator_preinit(pdev->dev.parent, ri); 399 if (!pdata) {
318 if (err) 400 dev_err(&pdev->dev, "Platform data not available, exiting\n");
319 return err; 401 return -ENODEV;
402 }
320 403
321 config.dev = pdev->dev.parent; 404 rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR *
322 config.of_node = pdev->dev.of_node; 405 sizeof(*rdev), GFP_KERNEL);
323 config.init_data = pdev->dev.platform_data; 406 if (!rdev) {
324 config.driver_data = ri; 407 dev_err(&pdev->dev, "Mmemory alloc failed\n");
408 return -ENOMEM;
409 }
325 410
326 rdev = regulator_register(&ri->desc, &config); 411 for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) {
327 if (IS_ERR(rdev)) { 412 reg_data = pdata->reg_init_data[id];
328 dev_err(&pdev->dev, "failed to register regulator %s\n", 413
329 ri->desc.name); 414 ri = find_regulator_info(id);
330 return PTR_ERR(rdev); 415 if (!ri) {
416 dev_err(&pdev->dev, "invalid regulator ID specified\n");
417 err = -EINVAL;
418 goto fail;
419 }
420
421 err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
422 if (err) {
423 dev_err(&pdev->dev,
424 "regulator %d preinit failed, e %d\n", id, err);
425 goto fail;
426 }
427
428 config.dev = pdev->dev.parent;
429 config.init_data = reg_data;
430 config.driver_data = ri;
431
432 if (tps6586x_reg_matches)
433 config.of_node = tps6586x_reg_matches[id].of_node;
434
435 rdev[id] = regulator_register(&ri->desc, &config);
436 if (IS_ERR(rdev[id])) {
437 dev_err(&pdev->dev, "failed to register regulator %s\n",
438 ri->desc.name);
439 err = PTR_ERR(rdev[id]);
440 goto fail;
441 }
442
443 if (reg_data) {
444 err = tps6586x_regulator_set_slew_rate(pdev, id,
445 reg_data);
446 if (err < 0) {
447 dev_err(&pdev->dev,
448 "Slew rate config failed, e %d\n", err);
449 regulator_unregister(rdev[id]);
450 goto fail;
451 }
452 }
331 } 453 }
332 454
333 platform_set_drvdata(pdev, rdev); 455 platform_set_drvdata(pdev, rdev);
456 return 0;
334 457
335 return tps6586x_regulator_set_slew_rate(pdev); 458fail:
459 while (--id >= 0)
460 regulator_unregister(rdev[id]);
461 return err;
336} 462}
337 463
338static int __devexit tps6586x_regulator_remove(struct platform_device *pdev) 464static int __devexit tps6586x_regulator_remove(struct platform_device *pdev)
339{ 465{
340 struct regulator_dev *rdev = platform_get_drvdata(pdev); 466 struct regulator_dev **rdev = platform_get_drvdata(pdev);
467 int id = TPS6586X_ID_MAX_REGULATOR;
468
469 while (--id >= 0)
470 regulator_unregister(rdev[id]);
341 471
342 regulator_unregister(rdev);
343 return 0; 472 return 0;
344} 473}
345 474
346static struct platform_driver tps6586x_regulator_driver = { 475static struct platform_driver tps6586x_regulator_driver = {
347 .driver = { 476 .driver = {
348 .name = "tps6586x-regulator", 477 .name = "tps6586x-pmic",
349 .owner = THIS_MODULE, 478 .owner = THIS_MODULE,
350 }, 479 },
351 .probe = tps6586x_regulator_probe, 480 .probe = tps6586x_regulator_probe,