diff options
| author | Daniel Mack <zonque@gmail.com> | 2013-08-02 06:59:44 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@linaro.org> | 2013-08-02 12:29:54 -0400 |
| commit | abe4c51afda02423c81da6f1eaaa50b733f1ecc2 (patch) | |
| tree | d4c2e2303ab360ac7773caca54ce9d36884ab176 /drivers/regulator | |
| parent | de492e8de8d05f29cc496871d42763d0a8a74610 (diff) | |
regulators: max8660: add DT bindings
This patch adds devicetree bindings for max8660, along with some
documentation.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/regulator')
| -rw-r--r-- | drivers/regulator/max8660.c | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 74c11aa00c8a..a4f2f1a38342 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
| @@ -44,6 +44,9 @@ | |||
| 44 | #include <linux/regulator/driver.h> | 44 | #include <linux/regulator/driver.h> |
| 45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
| 46 | #include <linux/regulator/max8660.h> | 46 | #include <linux/regulator/max8660.h> |
| 47 | #include <linux/of.h> | ||
| 48 | #include <linux/of_device.h> | ||
| 49 | #include <linux/regulator/of_regulator.h> | ||
| 47 | 50 | ||
| 48 | #define MAX8660_DCDC_MIN_UV 725000 | 51 | #define MAX8660_DCDC_MIN_UV 725000 |
| 49 | #define MAX8660_DCDC_MAX_UV 1800000 | 52 | #define MAX8660_DCDC_MAX_UV 1800000 |
| @@ -310,6 +313,63 @@ enum { | |||
| 310 | MAX8661 = 1, | 313 | MAX8661 = 1, |
| 311 | }; | 314 | }; |
| 312 | 315 | ||
| 316 | #ifdef CONFIG_OF | ||
| 317 | static const struct of_device_id max8660_dt_ids[] = { | ||
| 318 | { .compatible = "maxim,max8660", .data = (void *) MAX8660 }, | ||
| 319 | { .compatible = "maxim,max8661", .data = (void *) MAX8661 }, | ||
| 320 | { } | ||
| 321 | }; | ||
| 322 | MODULE_DEVICE_TABLE(of, max8660_dt_ids); | ||
| 323 | |||
| 324 | static int max8660_pdata_from_dt(struct device *dev, | ||
| 325 | struct device_node **of_node, | ||
| 326 | struct max8660_platform_data *pdata) | ||
| 327 | { | ||
| 328 | int matched, i; | ||
| 329 | struct device_node *np; | ||
| 330 | struct max8660_subdev_data *sub; | ||
| 331 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; | ||
| 332 | |||
| 333 | np = of_find_node_by_name(dev->of_node, "regulators"); | ||
| 334 | if (!np) { | ||
| 335 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | ||
| 336 | return -EINVAL; | ||
| 337 | } | ||
| 338 | |||
| 339 | for (i = 0; i < ARRAY_SIZE(rmatch); i++) | ||
| 340 | rmatch[i].name = max8660_reg[i].name; | ||
| 341 | |||
| 342 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); | ||
| 343 | if (matched <= 0) | ||
| 344 | return matched; | ||
| 345 | |||
| 346 | pdata->subdevs = devm_kzalloc(dev, sizeof(struct max8660_subdev_data) * | ||
| 347 | matched, GFP_KERNEL); | ||
| 348 | if (!pdata->subdevs) | ||
| 349 | return -ENOMEM; | ||
| 350 | |||
| 351 | pdata->num_subdevs = matched; | ||
| 352 | sub = pdata->subdevs; | ||
| 353 | |||
| 354 | for (i = 0; i < matched; i++) { | ||
| 355 | sub->id = i; | ||
| 356 | sub->name = rmatch[i].name; | ||
| 357 | sub->platform_data = rmatch[i].init_data; | ||
| 358 | of_node[i] = rmatch[i].of_node; | ||
| 359 | sub++; | ||
| 360 | } | ||
| 361 | |||
| 362 | return 0; | ||
| 363 | } | ||
| 364 | #else | ||
| 365 | static inline int max8660_pdata_from_dt(struct device *dev, | ||
| 366 | struct device_node **of_node, | ||
| 367 | struct max8660_platform_data **pdata) | ||
| 368 | { | ||
| 369 | return 0; | ||
| 370 | } | ||
| 371 | #endif | ||
| 372 | |||
| 313 | static int max8660_probe(struct i2c_client *client, | 373 | static int max8660_probe(struct i2c_client *client, |
| 314 | const struct i2c_device_id *i2c_id) | 374 | const struct i2c_device_id *i2c_id) |
| 315 | { | 375 | { |
| @@ -319,8 +379,28 @@ static int max8660_probe(struct i2c_client *client, | |||
| 319 | struct regulator_config config = { }; | 379 | struct regulator_config config = { }; |
| 320 | struct max8660 *max8660; | 380 | struct max8660 *max8660; |
| 321 | int boot_on, i, id, ret = -EINVAL; | 381 | int boot_on, i, id, ret = -EINVAL; |
| 382 | struct device_node *of_node[MAX8660_V_END]; | ||
| 322 | unsigned int type; | 383 | unsigned int type; |
| 323 | 384 | ||
| 385 | if (dev->of_node && !pdata) { | ||
| 386 | const struct of_device_id *id; | ||
| 387 | struct max8660_platform_data pdata_of; | ||
| 388 | |||
| 389 | id = of_match_device(of_match_ptr(max8660_dt_ids), dev); | ||
| 390 | if (!id) | ||
| 391 | return -ENODEV; | ||
| 392 | |||
| 393 | ret = max8660_pdata_from_dt(dev, of_node, &pdata_of); | ||
| 394 | if (ret < 0) | ||
| 395 | return ret; | ||
| 396 | |||
| 397 | pdata = &pdata_of; | ||
| 398 | type = (unsigned int) id->data; | ||
| 399 | } else { | ||
| 400 | type = i2c_id->driver_data; | ||
| 401 | memset(of_node, 0, sizeof(of_node)); | ||
| 402 | } | ||
| 403 | |||
| 324 | if (pdata->num_subdevs > MAX8660_V_END) { | 404 | if (pdata->num_subdevs > MAX8660_V_END) { |
| 325 | dev_err(dev, "Too many regulators found!\n"); | 405 | dev_err(dev, "Too many regulators found!\n"); |
| 326 | return -EINVAL; | 406 | return -EINVAL; |
| @@ -334,7 +414,6 @@ static int max8660_probe(struct i2c_client *client, | |||
| 334 | 414 | ||
| 335 | max8660->client = client; | 415 | max8660->client = client; |
| 336 | rdev = max8660->rdev; | 416 | rdev = max8660->rdev; |
| 337 | type = i2c_id->driver_data; | ||
| 338 | 417 | ||
| 339 | if (pdata->en34_is_high) { | 418 | if (pdata->en34_is_high) { |
| 340 | /* Simulate always on */ | 419 | /* Simulate always on */ |
| @@ -407,6 +486,7 @@ static int max8660_probe(struct i2c_client *client, | |||
| 407 | 486 | ||
| 408 | config.dev = dev; | 487 | config.dev = dev; |
| 409 | config.init_data = pdata->subdevs[i].platform_data; | 488 | config.init_data = pdata->subdevs[i].platform_data; |
| 489 | config.of_node = of_node[i]; | ||
| 410 | config.driver_data = max8660; | 490 | config.driver_data = max8660; |
| 411 | 491 | ||
| 412 | rdev[i] = regulator_register(&max8660_reg[id], &config); | 492 | rdev[i] = regulator_register(&max8660_reg[id], &config); |
