aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 15:04:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 15:04:35 -0500
commit8b0cab14951fbf8126795ab301835a8f8126a988 (patch)
tree2bf23662944ac9bfcd34d13ef81a6e331266ebf9 /drivers/mfd
parentfd62c5450324af7f6cc12897b09b77285cd48a92 (diff)
parent4ffc45c3604dd8e283884ce006faf0e955cbd9e6 (diff)
Merge tag 'regulator-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown: "A fairly quiet release again, a couple of relatively small new features and a bunch of driver specific work including yet more code elimination and fixes from Axel Lin. - Addidion of linear_min_sel for offsetting linear selectors in the helpers. - Support for continuous voltage ranges for regulators with extremely high resolution. - Drivers for AS3711, DA9055, MAX9873, TPS51632, TPS80031 and ARM vexpress." Fix up trivial conflict (due to typo fix) in palmas-regulator.c * tag 'regulator-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (80 commits) regulator: core: Fix logic to determinate if regulator can change voltage regulator: s5m8767: Fix to work even if no DVS gpio present regulator: s5m8767: Fix to read the first DVS register. regulator: s5m8767: Fix to work when platform registers less regulators regulator: gpio-regulator: gpio_set_value should use cansleep regulator: gpio-regulator: Fix logical error in for() loop regulator: anatop: Use regulator_[get|set]_voltage_sel_regmap regulator: anatop: Use linear_min_sel with linear mapping regulator: max1586: Implement get_voltage_sel callback regulator: lp8788-buck: Kill _gpio_request function regulator: tps80031: Convert tps80031_ldo_ops to linear_min_sel and list_voltage_linear regulator: lp8788-ldo: Remove val array in lp8788_config_ldo_enable_mode regulator: gpio-regulator: Add ifdef CONFIG_OF guard for regulator_gpio_of_match regulator: palmas: Convert palmas_ops_smps to regulator_[get|set]_voltage_sel_regmap regulator: palmas: Return raw register values as the selectors in [get|set]_voltage_sel regulators: add regulator_can_change_voltage() function regulator: tps51632: Ensure [base|max]_voltage_uV pdata settings are valid regulator: wm831x-dcdc: Add MODULE_ALIAS for wm831x-boostp regulator: wm831x-dcdc: Ensure selected voltage falls within requested range regulator: tps51632: Use linear_min_sel and regulator_[map|list]_voltage_linear ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/max8997.c73
-rw-r--r--drivers/mfd/tps6586x.c76
-rw-r--r--drivers/mfd/wm5102-tables.c3
4 files changed, 83 insertions, 70 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 94bdf83b4bc8..b63987c6ed20 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -211,7 +211,6 @@ config MFD_TPS6586X
211 depends on I2C=y && GENERIC_HARDIRQS 211 depends on I2C=y && GENERIC_HARDIRQS
212 select MFD_CORE 212 select MFD_CORE
213 select REGMAP_I2C 213 select REGMAP_I2C
214 depends on REGULATOR
215 help 214 help
216 If you say yes here you get support for the TPS6586X series of 215 If you say yes here you get support for the TPS6586X series of
217 Power Management chips. 216 Power Management chips.
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index f123517065ec..abd5c80c7cf5 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -21,8 +21,10 @@
21 * This driver is based on max8998.c 21 * This driver is based on max8998.c
22 */ 22 */
23 23
24#include <linux/err.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/of_irq.h>
26#include <linux/interrupt.h> 28#include <linux/interrupt.h>
27#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
28#include <linux/module.h> 30#include <linux/module.h>
@@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = {
47 { .name = "max8997-led", .id = 2 }, 49 { .name = "max8997-led", .id = 2 },
48}; 50};
49 51
52#ifdef CONFIG_OF
53static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
54 { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
55 {},
56};
57#endif
58
50int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) 59int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
51{ 60{
52 struct max8997_dev *max8997 = i2c_get_clientdata(i2c); 61 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
@@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
123} 132}
124EXPORT_SYMBOL_GPL(max8997_update_reg); 133EXPORT_SYMBOL_GPL(max8997_update_reg);
125 134
135#ifdef CONFIG_OF
136/*
137 * Only the common platform data elements for max8997 are parsed here from the
138 * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
139 * to parse their own platform data elements from device tree.
140 *
141 * The max8997 platform data structure is instantiated here and the drivers for
142 * the sub-modules need not instantiate another instance while parsing their
143 * platform data.
144 */
145static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
146 struct device *dev)
147{
148 struct max8997_platform_data *pd;
149
150 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
151 if (!pd) {
152 dev_err(dev, "could not allocate memory for pdata\n");
153 return ERR_PTR(-ENOMEM);
154 }
155
156 pd->ono = irq_of_parse_and_map(dev->of_node, 1);
157
158 /*
159 * ToDo: the 'wakeup' member in the platform data is more of a linux
160 * specfic information. Hence, there is no binding for that yet and
161 * not parsed here.
162 */
163
164 return pd;
165}
166#else
167static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
168 struct device *dev)
169{
170 return 0;
171}
172#endif
173
174static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
175 const struct i2c_device_id *id)
176{
177#ifdef CONFIG_OF
178 if (i2c->dev.of_node) {
179 const struct of_device_id *match;
180 match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
181 return (int)match->data;
182 }
183#endif
184 return (int)id->driver_data;
185}
186
126static int max8997_i2c_probe(struct i2c_client *i2c, 187static int max8997_i2c_probe(struct i2c_client *i2c,
127 const struct i2c_device_id *id) 188 const struct i2c_device_id *id)
128{ 189{
@@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
137 i2c_set_clientdata(i2c, max8997); 198 i2c_set_clientdata(i2c, max8997);
138 max8997->dev = &i2c->dev; 199 max8997->dev = &i2c->dev;
139 max8997->i2c = i2c; 200 max8997->i2c = i2c;
140 max8997->type = id->driver_data; 201 max8997->type = max8997_i2c_get_driver_data(i2c, id);
141 max8997->irq = i2c->irq; 202 max8997->irq = i2c->irq;
142 203
204 if (max8997->dev->of_node) {
205 pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
206 if (IS_ERR(pdata)) {
207 ret = PTR_ERR(pdata);
208 goto err;
209 }
210 }
211
143 if (!pdata) 212 if (!pdata)
144 goto err; 213 goto err;
145 214
215 max8997->pdata = pdata;
146 max8997->ono = pdata->ono; 216 max8997->ono = pdata->ono;
147 217
148 mutex_init(&max8997->iolock); 218 mutex_init(&max8997->iolock);
@@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = {
434 .name = "max8997", 504 .name = "max8997",
435 .owner = THIS_MODULE, 505 .owner = THIS_MODULE,
436 .pm = &max8997_pm, 506 .pm = &max8997_pm,
507 .of_match_table = of_match_ptr(max8997_pmic_dt_match),
437 }, 508 },
438 .probe = max8997_i2c_probe, 509 .probe = max8997_i2c_probe,
439 .remove = max8997_i2c_remove, 510 .remove = max8997_i2c_remove,
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 9f92c3b22093..87ba7ada3bbc 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -24,8 +24,6 @@
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/regulator/of_regulator.h>
28#include <linux/regulator/machine.h>
29 27
30#include <linux/mfd/core.h> 28#include <linux/mfd/core.h>
31#include <linux/mfd/tps6586x.h> 29#include <linux/mfd/tps6586x.h>
@@ -99,6 +97,9 @@ static struct mfd_cell tps6586x_cell[] = {
99 .name = "tps6586x-gpio", 97 .name = "tps6586x-gpio",
100 }, 98 },
101 { 99 {
100 .name = "tps6586x-pmic",
101 },
102 {
102 .name = "tps6586x-rtc", 103 .name = "tps6586x-rtc",
103 }, 104 },
104 { 105 {
@@ -350,80 +351,19 @@ failed:
350} 351}
351 352
352#ifdef CONFIG_OF 353#ifdef CONFIG_OF
353static struct of_regulator_match tps6586x_matches[] = {
354 { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS },
355 { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 },
356 { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 },
357 { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 },
358 { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 },
359 { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 },
360 { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 },
361 { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 },
362 { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 },
363 { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 },
364 { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 },
365 { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 },
366 { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 },
367 { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 },
368 { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
369};
370
371static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) 354static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
372{ 355{
373 const unsigned int num = ARRAY_SIZE(tps6586x_matches);
374 struct device_node *np = client->dev.of_node; 356 struct device_node *np = client->dev.of_node;
375 struct tps6586x_platform_data *pdata; 357 struct tps6586x_platform_data *pdata;
376 struct tps6586x_subdev_info *devs;
377 struct device_node *regs;
378 const char *sys_rail_name = NULL;
379 unsigned int count;
380 unsigned int i, j;
381 int err;
382
383 regs = of_find_node_by_name(np, "regulators");
384 if (!regs)
385 return NULL;
386
387 err = of_regulator_match(&client->dev, regs, tps6586x_matches, num);
388 if (err < 0) {
389 of_node_put(regs);
390 return NULL;
391 }
392
393 of_node_put(regs);
394 count = err;
395
396 devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL);
397 if (!devs)
398 return NULL;
399
400 for (i = 0, j = 0; i < num && j < count; i++) {
401 struct regulator_init_data *reg_idata;
402
403 if (!tps6586x_matches[i].init_data)
404 continue;
405
406 reg_idata = tps6586x_matches[i].init_data;
407 devs[j].name = "tps6586x-regulator";
408 devs[j].platform_data = tps6586x_matches[i].init_data;
409 devs[j].id = (int)tps6586x_matches[i].driver_data;
410 if (devs[j].id == TPS6586X_ID_SYS)
411 sys_rail_name = reg_idata->constraints.name;
412
413 if ((devs[j].id == TPS6586X_ID_LDO_5) ||
414 (devs[j].id == TPS6586X_ID_LDO_RTC))
415 reg_idata->supply_regulator = sys_rail_name;
416
417 devs[j].of_node = tps6586x_matches[i].of_node;
418 j++;
419 }
420 358
421 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 359 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
422 if (!pdata) 360 if (!pdata) {
361 dev_err(&client->dev, "Memory allocation failed\n");
423 return NULL; 362 return NULL;
363 }
424 364
425 pdata->num_subdevs = count; 365 pdata->num_subdevs = 0;
426 pdata->subdevs = devs; 366 pdata->subdevs = NULL;
427 pdata->gpio_base = -1; 367 pdata->gpio_base = -1;
428 pdata->irq_base = -1; 368 pdata->irq_base = -1;
429 pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller"); 369 pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 14490cc785d2..3141c4a173a7 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -258,6 +258,7 @@ static const struct reg_default wm5102_reg_default[] = {
258 { 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */ 258 { 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */
259 { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ 259 { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */
260 { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ 260 { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */
261 { 0x00000161, 0x0000 }, /* R353 - Dynamic Frequency Scaling 1 */
261 { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */ 262 { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */
262 { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ 263 { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */
263 { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ 264 { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */
@@ -1047,6 +1048,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
1047 case ARIZONA_RATE_ESTIMATOR_3: 1048 case ARIZONA_RATE_ESTIMATOR_3:
1048 case ARIZONA_RATE_ESTIMATOR_4: 1049 case ARIZONA_RATE_ESTIMATOR_4:
1049 case ARIZONA_RATE_ESTIMATOR_5: 1050 case ARIZONA_RATE_ESTIMATOR_5:
1051 case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1:
1050 case ARIZONA_FLL1_CONTROL_1: 1052 case ARIZONA_FLL1_CONTROL_1:
1051 case ARIZONA_FLL1_CONTROL_2: 1053 case ARIZONA_FLL1_CONTROL_2:
1052 case ARIZONA_FLL1_CONTROL_3: 1054 case ARIZONA_FLL1_CONTROL_3:
@@ -1079,6 +1081,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
1079 case ARIZONA_FLL2_GPIO_CLOCK: 1081 case ARIZONA_FLL2_GPIO_CLOCK:
1080 case ARIZONA_MIC_CHARGE_PUMP_1: 1082 case ARIZONA_MIC_CHARGE_PUMP_1:
1081 case ARIZONA_LDO1_CONTROL_1: 1083 case ARIZONA_LDO1_CONTROL_1:
1084 case ARIZONA_LDO1_CONTROL_2:
1082 case ARIZONA_LDO2_CONTROL_1: 1085 case ARIZONA_LDO2_CONTROL_1:
1083 case ARIZONA_MIC_BIAS_CTRL_1: 1086 case ARIZONA_MIC_BIAS_CTRL_1:
1084 case ARIZONA_MIC_BIAS_CTRL_2: 1087 case ARIZONA_MIC_BIAS_CTRL_2: