diff options
-rw-r--r-- | Documentation/devicetree/bindings/regulator/max8973-regulator.txt | 14 | ||||
-rw-r--r-- | drivers/regulator/max8973-regulator.c | 85 |
2 files changed, 79 insertions, 20 deletions
diff --git a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt index 4f15d8a1bfd0..f63de7d8dc23 100644 --- a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt | |||
@@ -8,6 +8,20 @@ Required properties: | |||
8 | Any standard regulator properties can be used to configure the single max8973 | 8 | Any standard regulator properties can be used to configure the single max8973 |
9 | DCDC. | 9 | DCDC. |
10 | 10 | ||
11 | Optional properties: | ||
12 | |||
13 | -maxim,externally-enable: boolean, externally control the regulator output | ||
14 | enable/disable. | ||
15 | -maxim,dvs-gpio: GPIO which is connected to DVS pin of device. | ||
16 | -maxim,dvs-default-state: Default state of GPIO during initialisation. | ||
17 | 1 for HIGH and 0 for LOW. | ||
18 | -maxim,enable-remote-sense: boolean, enable reote sense. | ||
19 | -maxim,enable-falling-slew-rate: boolean, enable falling slew rate. | ||
20 | -maxim,enable-active-discharge: boolean: enable active discharge. | ||
21 | -maxim,enable-frequency-shift: boolean, enable 9% frequency shift. | ||
22 | -maxim,enable-bias-control: boolean, enable bias control. By enabling this | ||
23 | startup delay can be reduce to 20us from 220us. | ||
24 | |||
11 | Example: | 25 | Example: |
12 | 26 | ||
13 | max8973@1b { | 27 | max8973@1b { |
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 190db9c3e6b7..1442f920c80e 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/regulator/max8973-regulator.h> | 33 | #include <linux/regulator/max8973-regulator.h> |
34 | #include <linux/regulator/of_regulator.h> | 34 | #include <linux/regulator/of_regulator.h> |
35 | #include <linux/gpio.h> | 35 | #include <linux/gpio.h> |
36 | #include <linux/of_gpio.h> | ||
36 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
37 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
38 | #include <linux/regmap.h> | 39 | #include <linux/regmap.h> |
@@ -364,6 +365,46 @@ static const struct regmap_config max8973_regmap_config = { | |||
364 | .cache_type = REGCACHE_RBTREE, | 365 | .cache_type = REGCACHE_RBTREE, |
365 | }; | 366 | }; |
366 | 367 | ||
368 | static struct max8973_regulator_platform_data *max8973_parse_dt( | ||
369 | struct device *dev) | ||
370 | { | ||
371 | struct max8973_regulator_platform_data *pdata; | ||
372 | struct device_node *np = dev->of_node; | ||
373 | int ret; | ||
374 | u32 pval; | ||
375 | |||
376 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
377 | if (!pdata) | ||
378 | return NULL; | ||
379 | |||
380 | pdata->enable_ext_control = of_property_read_bool(np, | ||
381 | "maxim,externally-enable"); | ||
382 | pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0); | ||
383 | |||
384 | ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval); | ||
385 | if (!ret) | ||
386 | pdata->dvs_def_state = pval; | ||
387 | |||
388 | if (of_property_read_bool(np, "maxim,enable-remote-sense")) | ||
389 | pdata->control_flags |= MAX8973_CONTROL_REMOTE_SENSE_ENABLE; | ||
390 | |||
391 | if (of_property_read_bool(np, "maxim,enable-falling-slew-rate")) | ||
392 | pdata->control_flags |= | ||
393 | MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE; | ||
394 | |||
395 | if (of_property_read_bool(np, "maxim,enable-active-discharge")) | ||
396 | pdata->control_flags |= | ||
397 | MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE; | ||
398 | |||
399 | if (of_property_read_bool(np, "maxim,enable-frequency-shift")) | ||
400 | pdata->control_flags |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE; | ||
401 | |||
402 | if (of_property_read_bool(np, "maxim,enable-bias-control")) | ||
403 | pdata->control_flags |= MAX8973_BIAS_ENABLE; | ||
404 | |||
405 | return pdata; | ||
406 | } | ||
407 | |||
367 | static int max8973_probe(struct i2c_client *client, | 408 | static int max8973_probe(struct i2c_client *client, |
368 | const struct i2c_device_id *id) | 409 | const struct i2c_device_id *id) |
369 | { | 410 | { |
@@ -371,15 +412,24 @@ static int max8973_probe(struct i2c_client *client, | |||
371 | struct regulator_config config = { }; | 412 | struct regulator_config config = { }; |
372 | struct regulator_dev *rdev; | 413 | struct regulator_dev *rdev; |
373 | struct max8973_chip *max; | 414 | struct max8973_chip *max; |
415 | bool pdata_from_dt = false; | ||
374 | int ret; | 416 | int ret; |
375 | 417 | ||
376 | pdata = dev_get_platdata(&client->dev); | 418 | pdata = dev_get_platdata(&client->dev); |
377 | 419 | ||
378 | if (!pdata && !client->dev.of_node) { | 420 | if (!pdata && client->dev.of_node) { |
421 | pdata = max8973_parse_dt(&client->dev); | ||
422 | pdata_from_dt = true; | ||
423 | } | ||
424 | |||
425 | if (!pdata) { | ||
379 | dev_err(&client->dev, "No Platform data"); | 426 | dev_err(&client->dev, "No Platform data"); |
380 | return -EIO; | 427 | return -EIO; |
381 | } | 428 | } |
382 | 429 | ||
430 | if (pdata->dvs_gpio == -EPROBE_DEFER) | ||
431 | return -EPROBE_DEFER; | ||
432 | |||
383 | max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); | 433 | max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); |
384 | if (!max) | 434 | if (!max) |
385 | return -ENOMEM; | 435 | return -ENOMEM; |
@@ -403,7 +453,7 @@ static int max8973_probe(struct i2c_client *client, | |||
403 | max->desc.uV_step = MAX8973_VOLATGE_STEP; | 453 | max->desc.uV_step = MAX8973_VOLATGE_STEP; |
404 | max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE; | 454 | max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE; |
405 | 455 | ||
406 | if (!pdata || !pdata->enable_ext_control) { | 456 | if (!pdata->enable_ext_control) { |
407 | max->desc.enable_reg = MAX8973_VOUT; | 457 | max->desc.enable_reg = MAX8973_VOUT; |
408 | max->desc.enable_mask = MAX8973_VOUT_ENABLE; | 458 | max->desc.enable_mask = MAX8973_VOUT_ENABLE; |
409 | max->ops.enable = regulator_enable_regmap; | 459 | max->ops.enable = regulator_enable_regmap; |
@@ -411,15 +461,10 @@ static int max8973_probe(struct i2c_client *client, | |||
411 | max->ops.is_enabled = regulator_is_enabled_regmap; | 461 | max->ops.is_enabled = regulator_is_enabled_regmap; |
412 | } | 462 | } |
413 | 463 | ||
414 | if (pdata) { | 464 | max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL; |
415 | max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL; | 465 | max->enable_external_control = pdata->enable_ext_control; |
416 | max->enable_external_control = pdata->enable_ext_control; | 466 | max->curr_gpio_val = pdata->dvs_def_state; |
417 | max->curr_gpio_val = pdata->dvs_def_state; | 467 | max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; |
418 | max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; | ||
419 | } else { | ||
420 | max->dvs_gpio = -EINVAL; | ||
421 | max->curr_vout_reg = MAX8973_VOUT; | ||
422 | } | ||
423 | 468 | ||
424 | max->lru_index[0] = max->curr_vout_reg; | 469 | max->lru_index[0] = max->curr_vout_reg; |
425 | 470 | ||
@@ -448,18 +493,18 @@ static int max8973_probe(struct i2c_client *client, | |||
448 | max->lru_index[max->curr_vout_reg] = 0; | 493 | max->lru_index[max->curr_vout_reg] = 0; |
449 | } | 494 | } |
450 | 495 | ||
451 | if (pdata) { | 496 | if (pdata_from_dt) |
452 | ret = max8973_init_dcdc(max, pdata); | 497 | pdata->reg_init_data = of_get_regulator_init_data(&client->dev, |
453 | if (ret < 0) { | 498 | client->dev.of_node, &max->desc); |
454 | dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret); | 499 | |
455 | return ret; | 500 | ret = max8973_init_dcdc(max, pdata); |
456 | } | 501 | if (ret < 0) { |
502 | dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret); | ||
503 | return ret; | ||
457 | } | 504 | } |
458 | 505 | ||
459 | config.dev = &client->dev; | 506 | config.dev = &client->dev; |
460 | config.init_data = pdata ? pdata->reg_init_data : | 507 | config.init_data = pdata->reg_init_data; |
461 | of_get_regulator_init_data(&client->dev, client->dev.of_node, | ||
462 | &max->desc); | ||
463 | config.driver_data = max; | 508 | config.driver_data = max; |
464 | config.of_node = client->dev.of_node; | 509 | config.of_node = client->dev.of_node; |
465 | config.regmap = max->regmap; | 510 | config.regmap = max->regmap; |