diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-05 12:01:30 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-05 12:01:30 +0900 |
commit | 578f1ef91aa92beb571bfb9af8f4d18f405f3b9e (patch) | |
tree | 8ff59e772d09180b7e7f952a8c90a1bcf25e1d19 /drivers/regulator/palmas-regulator.c | |
parent | ecefbd94b834fa32559d854646d777c56749ef1c (diff) | |
parent | 74d8378159de16a0a1d1975d4778120d263d6000 (diff) | |
download | linux-578f1ef91aa92beb571bfb9af8f4d18f405f3b9e.tar.bz2 |
Merge tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFD changes from Samuel Ortiz:
"MFD bits for the 3.7 merge window.
As usual we have a few new drivers:
- TI LP8788
- TI OMAP USB TLL
- Maxim MAX8907
- SMSC ECE1099
- Dialog Semiconductor DA9055
- A simpler syscon driver that allow us to get rid of the anatop one.
Drivers are also gradually getting Device Tree and IRQ domain support.
The following drivers got DT support:
- palmas, 88pm860x, tc3589x and twl4030-audio
And those ones now use the IRQ domain APIs:
- 88pm860x, tc3589x, db8500_prcmu
Also some other interesting changes:
- Intel's ICH LPC now supports Lynx Point
- TI's twl4030-audio added a GPO child
- tps6527 enabled its backlight subdevice
- The twl6030 pwm driver moved to the new PWM subsystem
And finally a bunch of cleanup and casual fixes for mc13xxx, 88pm860x,
palmas, ab8500, wm8994, wm5110, max8907 and the tps65xxx family."
Fix up various annoying conflicts: the DT and IRQ domain support came in
twice and was already in 3.6. And then it was apparently rebased.
Guys, DON'T REBASE!
* tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (89 commits)
ARM: dts: Enable 88pm860x pmic
mfd: 88pm860x: Move gpadc init into touch
mfd: 88pm860x: Device tree support
mfd: 88pm860x: Use irqdomain
mfd: smsc: Add support for smsc gpio io/keypad driver
backlight: tps65217_bl: Add missing platform_set_drvdata in tps65217_bl_probe
mfd: DA9055 core driver
mfd: tps65910: Add alarm interrupt of TPS65910 RTC to mfd device list
mfd: wm5110: Add register patches for revision B
mfd: wm5110: Disable control interface error report for WM5110 rev B
mfd: max8907: Remove regulator-compatible from DT docs
backlight: Add TPS65217 WLED driver
mfd: Add backlight as subdevice to the tps65217
mfd: Provide the PRCMU with its own IRQ domain
mfd: Fix max8907 sparse warning
mfd: Add lp8788 mfd driver
mfd: dbx500: Provide a more accurate smp_twd clock
mfd: rc5t583: Fix warning messages
regulator: palmas: Add DT support
mfd: palmas: Change regulator defns to better suite DT
...
Diffstat (limited to 'drivers/regulator/palmas-regulator.c')
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 127 |
1 files changed, 119 insertions, 8 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 2ba7502fa3b2..07aee694ba92 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -22,6 +22,9 @@ #include <linux/slab.h> #include <linux/regmap.h> #include <linux/mfd/palmas.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/regulator/of_regulator.h> struct regs_info { char *name; @@ -568,10 +571,103 @@ static int palmas_ldo_init(struct palmas *palmas, int id, return 0; } +static struct of_regulator_match palmas_matches[] = { + { .name = "smps12", }, + { .name = "smps123", }, + { .name = "smps3", }, + { .name = "smps45", }, + { .name = "smps457", }, + { .name = "smps6", }, + { .name = "smps7", }, + { .name = "smps8", }, + { .name = "smps9", }, + { .name = "smps10", }, + { .name = "ldo1", }, + { .name = "ldo2", }, + { .name = "ldo3", }, + { .name = "ldo4", }, + { .name = "ldo5", }, + { .name = "ldo6", }, + { .name = "ldo7", }, + { .name = "ldo8", }, + { .name = "ldo9", }, + { .name = "ldoln", }, + { .name = "ldousb", }, +}; + +static void __devinit palmas_dt_to_pdata(struct device *dev, + struct device_node *node, + struct palmas_pmic_platform_data *pdata) +{ + struct device_node *regulators; + u32 prop; + int idx, ret; + + regulators = of_find_node_by_name(node, "regulators"); + if (!regulators) { + dev_info(dev, "regulator node not found\n"); + return; + } + + ret = of_regulator_match(dev, regulators, palmas_matches, + PALMAS_NUM_REGS); + if (ret < 0) { + dev_err(dev, "Error parsing regulator init data: %d\n", ret); + return; + } + + for (idx = 0; idx < PALMAS_NUM_REGS; idx++) { + if (!palmas_matches[idx].init_data || + !palmas_matches[idx].of_node) + continue; + + pdata->reg_data[idx] = palmas_matches[idx].init_data; + + pdata->reg_init[idx] = devm_kzalloc(dev, + sizeof(struct palmas_reg_init), GFP_KERNEL); + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,warm_reset", &prop); + if (!ret) + pdata->reg_init[idx]->warm_reset = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,roof_floor", &prop); + if (!ret) + pdata->reg_init[idx]->roof_floor = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,mode_sleep", &prop); + if (!ret) + pdata->reg_init[idx]->mode_sleep = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,warm_reset", &prop); + if (!ret) + pdata->reg_init[idx]->warm_reset = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,tstep", &prop); + if (!ret) + pdata->reg_init[idx]->tstep = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,vsel", &prop); + if (!ret) + pdata->reg_init[idx]->vsel = prop; + } + + ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop); + if (!ret) + pdata->ldo6_vibrator = prop; +} + + static __devinit int palmas_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; + struct device_node *node = pdev->dev.of_node; struct regulator_dev *rdev; struct regulator_config config = { }; struct palmas_pmic *pmic; @@ -579,10 +675,14 @@ static __devinit int palmas_probe(struct platform_device *pdev) int id = 0, ret; unsigned int addr, reg; - if (!pdata) - return -EINVAL; - if (!pdata->reg_data) - return -EINVAL; + if (node && !pdata) { + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + + if (!pdata) + return -ENOMEM; + + palmas_dt_to_pdata(&pdev->dev, node, pdata); + } pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) @@ -661,7 +761,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].owner = THIS_MODULE; /* Initialise sleep/init values from platform data */ - if (pdata && pdata->reg_init) { + if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { ret = palmas_smps_init(palmas, id, reg_init); @@ -685,11 +785,13 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->range[id] = 1; } - if (pdata && pdata->reg_data) + if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; + config.of_node = palmas_matches[id].of_node; + rdev = regulator_register(&pmic->desc[id], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, @@ -726,11 +828,13 @@ static __devinit int palmas_probe(struct platform_device *pdev) palmas_regs_info[id].ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; - if (pdata && pdata->reg_data) + if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; + config.of_node = palmas_matches[id].of_node; + rdev = regulator_register(&pmic->desc[id], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, @@ -744,7 +848,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->rdev[id] = rdev; /* Initialise sleep/init values from platform data */ - if (pdata->reg_init) { + if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { ret = palmas_ldo_init(palmas, id, reg_init); @@ -774,9 +878,15 @@ static int __devexit palmas_remove(struct platform_device *pdev) return 0; } +static struct of_device_id __devinitdata of_palmas_match_tbl[] = { + { .compatible = "ti,palmas-pmic", }, + { /* end */ } +}; + static struct platform_driver palmas_driver = { .driver = { .name = "palmas-pmic", + .of_match_table = of_palmas_match_tbl, .owner = THIS_MODULE, }, .probe = palmas_probe, @@ -799,3 +909,4 @@ MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); MODULE_DESCRIPTION("Palmas voltage regulator driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:palmas-pmic"); +MODULE_DEVICE_TABLE(of, of_palmas_match_tbl); |