diff options
author | Mark Brown <broonie@sirena.org.uk> | 2013-04-27 21:13:40 -0400 |
---|---|---|
committer | Mark Brown <broonie@sirena.org.uk> | 2013-04-27 21:13:40 -0400 |
commit | 3dc06c1baf2b28e5365a1159755eac2e95142601 (patch) | |
tree | 771e1dcfd1ac5f0d2e14bec7973bcd58c9f7dfea /drivers/regulator | |
parent | 5f19a85ba728de8a1eca8b8ae239cc27f9449985 (diff) | |
parent | 407945fd78c3fddef83ba17bf2250112c07dc7c1 (diff) |
Merge remote-tracking branch 'regulator/topic/gpio' into v3.9-rc8
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/core.c | 142 | ||||
-rw-r--r-- | drivers/regulator/lp8788-ldo.c | 98 |
2 files changed, 140 insertions, 100 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2434e2e1afcc..6e5017841582 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -51,6 +51,7 @@ | |||
51 | static DEFINE_MUTEX(regulator_list_mutex); | 51 | static DEFINE_MUTEX(regulator_list_mutex); |
52 | static LIST_HEAD(regulator_list); | 52 | static LIST_HEAD(regulator_list); |
53 | static LIST_HEAD(regulator_map_list); | 53 | static LIST_HEAD(regulator_map_list); |
54 | static LIST_HEAD(regulator_ena_gpio_list); | ||
54 | static bool has_full_constraints; | 55 | static bool has_full_constraints; |
55 | static bool board_wants_dummy_regulator; | 56 | static bool board_wants_dummy_regulator; |
56 | 57 | ||
@@ -69,6 +70,19 @@ struct regulator_map { | |||
69 | }; | 70 | }; |
70 | 71 | ||
71 | /* | 72 | /* |
73 | * struct regulator_enable_gpio | ||
74 | * | ||
75 | * Management for shared enable GPIO pin | ||
76 | */ | ||
77 | struct regulator_enable_gpio { | ||
78 | struct list_head list; | ||
79 | int gpio; | ||
80 | u32 enable_count; /* a number of enabled shared GPIO */ | ||
81 | u32 request_count; /* a number of requested shared GPIO */ | ||
82 | unsigned int ena_gpio_invert:1; | ||
83 | }; | ||
84 | |||
85 | /* | ||
72 | * struct regulator | 86 | * struct regulator |
73 | * | 87 | * |
74 | * One for each consumer device. | 88 | * One for each consumer device. |
@@ -1465,6 +1479,101 @@ void devm_regulator_put(struct regulator *regulator) | |||
1465 | } | 1479 | } |
1466 | EXPORT_SYMBOL_GPL(devm_regulator_put); | 1480 | EXPORT_SYMBOL_GPL(devm_regulator_put); |
1467 | 1481 | ||
1482 | /* Manage enable GPIO list. Same GPIO pin can be shared among regulators */ | ||
1483 | static int regulator_ena_gpio_request(struct regulator_dev *rdev, | ||
1484 | const struct regulator_config *config) | ||
1485 | { | ||
1486 | struct regulator_enable_gpio *pin; | ||
1487 | int ret; | ||
1488 | |||
1489 | list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { | ||
1490 | if (pin->gpio == config->ena_gpio) { | ||
1491 | rdev_dbg(rdev, "GPIO %d is already used\n", | ||
1492 | config->ena_gpio); | ||
1493 | goto update_ena_gpio_to_rdev; | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1497 | ret = gpio_request_one(config->ena_gpio, | ||
1498 | GPIOF_DIR_OUT | config->ena_gpio_flags, | ||
1499 | rdev_get_name(rdev)); | ||
1500 | if (ret) | ||
1501 | return ret; | ||
1502 | |||
1503 | pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); | ||
1504 | if (pin == NULL) { | ||
1505 | gpio_free(config->ena_gpio); | ||
1506 | return -ENOMEM; | ||
1507 | } | ||
1508 | |||
1509 | pin->gpio = config->ena_gpio; | ||
1510 | pin->ena_gpio_invert = config->ena_gpio_invert; | ||
1511 | list_add(&pin->list, ®ulator_ena_gpio_list); | ||
1512 | |||
1513 | update_ena_gpio_to_rdev: | ||
1514 | pin->request_count++; | ||
1515 | rdev->ena_pin = pin; | ||
1516 | return 0; | ||
1517 | } | ||
1518 | |||
1519 | static void regulator_ena_gpio_free(struct regulator_dev *rdev) | ||
1520 | { | ||
1521 | struct regulator_enable_gpio *pin, *n; | ||
1522 | |||
1523 | if (!rdev->ena_pin) | ||
1524 | return; | ||
1525 | |||
1526 | /* Free the GPIO only in case of no use */ | ||
1527 | list_for_each_entry_safe(pin, n, ®ulator_ena_gpio_list, list) { | ||
1528 | if (pin->gpio == rdev->ena_pin->gpio) { | ||
1529 | if (pin->request_count <= 1) { | ||
1530 | pin->request_count = 0; | ||
1531 | gpio_free(pin->gpio); | ||
1532 | list_del(&pin->list); | ||
1533 | kfree(pin); | ||
1534 | } else { | ||
1535 | pin->request_count--; | ||
1536 | } | ||
1537 | } | ||
1538 | } | ||
1539 | } | ||
1540 | |||
1541 | /** | ||
1542 | * Balance enable_count of each GPIO and actual GPIO pin control. | ||
1543 | * GPIO is enabled in case of initial use. (enable_count is 0) | ||
1544 | * GPIO is disabled when it is not shared any more. (enable_count <= 1) | ||
1545 | */ | ||
1546 | static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) | ||
1547 | { | ||
1548 | struct regulator_enable_gpio *pin = rdev->ena_pin; | ||
1549 | |||
1550 | if (!pin) | ||
1551 | return -EINVAL; | ||
1552 | |||
1553 | if (enable) { | ||
1554 | /* Enable GPIO at initial use */ | ||
1555 | if (pin->enable_count == 0) | ||
1556 | gpio_set_value_cansleep(pin->gpio, | ||
1557 | !pin->ena_gpio_invert); | ||
1558 | |||
1559 | pin->enable_count++; | ||
1560 | } else { | ||
1561 | if (pin->enable_count > 1) { | ||
1562 | pin->enable_count--; | ||
1563 | return 0; | ||
1564 | } | ||
1565 | |||
1566 | /* Disable GPIO if not used */ | ||
1567 | if (pin->enable_count <= 1) { | ||
1568 | gpio_set_value_cansleep(pin->gpio, | ||
1569 | pin->ena_gpio_invert); | ||
1570 | pin->enable_count = 0; | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1574 | return 0; | ||
1575 | } | ||
1576 | |||
1468 | static int _regulator_do_enable(struct regulator_dev *rdev) | 1577 | static int _regulator_do_enable(struct regulator_dev *rdev) |
1469 | { | 1578 | { |
1470 | int ret, delay; | 1579 | int ret, delay; |
@@ -1480,9 +1589,10 @@ static int _regulator_do_enable(struct regulator_dev *rdev) | |||
1480 | 1589 | ||
1481 | trace_regulator_enable(rdev_get_name(rdev)); | 1590 | trace_regulator_enable(rdev_get_name(rdev)); |
1482 | 1591 | ||
1483 | if (rdev->ena_gpio) { | 1592 | if (rdev->ena_pin) { |
1484 | gpio_set_value_cansleep(rdev->ena_gpio, | 1593 | ret = regulator_ena_gpio_ctrl(rdev, true); |
1485 | !rdev->ena_gpio_invert); | 1594 | if (ret < 0) |
1595 | return ret; | ||
1486 | rdev->ena_gpio_state = 1; | 1596 | rdev->ena_gpio_state = 1; |
1487 | } else if (rdev->desc->ops->enable) { | 1597 | } else if (rdev->desc->ops->enable) { |
1488 | ret = rdev->desc->ops->enable(rdev); | 1598 | ret = rdev->desc->ops->enable(rdev); |
@@ -1584,9 +1694,10 @@ static int _regulator_do_disable(struct regulator_dev *rdev) | |||
1584 | 1694 | ||
1585 | trace_regulator_disable(rdev_get_name(rdev)); | 1695 | trace_regulator_disable(rdev_get_name(rdev)); |
1586 | 1696 | ||
1587 | if (rdev->ena_gpio) { | 1697 | if (rdev->ena_pin) { |
1588 | gpio_set_value_cansleep(rdev->ena_gpio, | 1698 | ret = regulator_ena_gpio_ctrl(rdev, false); |
1589 | rdev->ena_gpio_invert); | 1699 | if (ret < 0) |
1700 | return ret; | ||
1590 | rdev->ena_gpio_state = 0; | 1701 | rdev->ena_gpio_state = 0; |
1591 | 1702 | ||
1592 | } else if (rdev->desc->ops->disable) { | 1703 | } else if (rdev->desc->ops->disable) { |
@@ -1859,7 +1970,7 @@ EXPORT_SYMBOL_GPL(regulator_disable_regmap); | |||
1859 | static int _regulator_is_enabled(struct regulator_dev *rdev) | 1970 | static int _regulator_is_enabled(struct regulator_dev *rdev) |
1860 | { | 1971 | { |
1861 | /* A GPIO control always takes precedence */ | 1972 | /* A GPIO control always takes precedence */ |
1862 | if (rdev->ena_gpio) | 1973 | if (rdev->ena_pin) |
1863 | return rdev->ena_gpio_state; | 1974 | return rdev->ena_gpio_state; |
1864 | 1975 | ||
1865 | /* If we don't know then assume that the regulator is always on */ | 1976 | /* If we don't know then assume that the regulator is always on */ |
@@ -3293,7 +3404,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
3293 | if (status < 0) | 3404 | if (status < 0) |
3294 | return status; | 3405 | return status; |
3295 | } | 3406 | } |
3296 | if (rdev->ena_gpio || ops->is_enabled) { | 3407 | if (rdev->ena_pin || ops->is_enabled) { |
3297 | status = device_create_file(dev, &dev_attr_state); | 3408 | status = device_create_file(dev, &dev_attr_state); |
3298 | if (status < 0) | 3409 | if (status < 0) |
3299 | return status; | 3410 | return status; |
@@ -3495,22 +3606,17 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3495 | dev_set_drvdata(&rdev->dev, rdev); | 3606 | dev_set_drvdata(&rdev->dev, rdev); |
3496 | 3607 | ||
3497 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { | 3608 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { |
3498 | ret = gpio_request_one(config->ena_gpio, | 3609 | ret = regulator_ena_gpio_request(rdev, config); |
3499 | GPIOF_DIR_OUT | config->ena_gpio_flags, | ||
3500 | rdev_get_name(rdev)); | ||
3501 | if (ret != 0) { | 3610 | if (ret != 0) { |
3502 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", | 3611 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", |
3503 | config->ena_gpio, ret); | 3612 | config->ena_gpio, ret); |
3504 | goto wash; | 3613 | goto wash; |
3505 | } | 3614 | } |
3506 | 3615 | ||
3507 | rdev->ena_gpio = config->ena_gpio; | ||
3508 | rdev->ena_gpio_invert = config->ena_gpio_invert; | ||
3509 | |||
3510 | if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) | 3616 | if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) |
3511 | rdev->ena_gpio_state = 1; | 3617 | rdev->ena_gpio_state = 1; |
3512 | 3618 | ||
3513 | if (rdev->ena_gpio_invert) | 3619 | if (config->ena_gpio_invert) |
3514 | rdev->ena_gpio_state = !rdev->ena_gpio_state; | 3620 | rdev->ena_gpio_state = !rdev->ena_gpio_state; |
3515 | } | 3621 | } |
3516 | 3622 | ||
@@ -3590,8 +3696,7 @@ unset_supplies: | |||
3590 | scrub: | 3696 | scrub: |
3591 | if (rdev->supply) | 3697 | if (rdev->supply) |
3592 | _regulator_put(rdev->supply); | 3698 | _regulator_put(rdev->supply); |
3593 | if (rdev->ena_gpio) | 3699 | regulator_ena_gpio_free(rdev); |
3594 | gpio_free(rdev->ena_gpio); | ||
3595 | kfree(rdev->constraints); | 3700 | kfree(rdev->constraints); |
3596 | wash: | 3701 | wash: |
3597 | device_unregister(&rdev->dev); | 3702 | device_unregister(&rdev->dev); |
@@ -3626,8 +3731,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
3626 | unset_regulator_supplies(rdev); | 3731 | unset_regulator_supplies(rdev); |
3627 | list_del(&rdev->list); | 3732 | list_del(&rdev->list); |
3628 | kfree(rdev->constraints); | 3733 | kfree(rdev->constraints); |
3629 | if (rdev->ena_gpio) | 3734 | regulator_ena_gpio_free(rdev); |
3630 | gpio_free(rdev->ena_gpio); | ||
3631 | device_unregister(&rdev->dev); | 3735 | device_unregister(&rdev->dev); |
3632 | mutex_unlock(®ulator_list_mutex); | 3736 | mutex_unlock(®ulator_list_mutex); |
3633 | } | 3737 | } |
diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index cd5a14ad9263..fcba90a4c26c 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c | |||
@@ -184,40 +184,6 @@ static enum lp8788_ldo_id lp8788_aldo_id[] = { | |||
184 | ALDO10, | 184 | ALDO10, |
185 | }; | 185 | }; |
186 | 186 | ||
187 | static int lp8788_ldo_enable(struct regulator_dev *rdev) | ||
188 | { | ||
189 | struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); | ||
190 | |||
191 | if (ldo->en_pin) { | ||
192 | gpio_set_value(ldo->en_pin->gpio, ENABLE); | ||
193 | return 0; | ||
194 | } else { | ||
195 | return regulator_enable_regmap(rdev); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | static int lp8788_ldo_disable(struct regulator_dev *rdev) | ||
200 | { | ||
201 | struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); | ||
202 | |||
203 | if (ldo->en_pin) { | ||
204 | gpio_set_value(ldo->en_pin->gpio, DISABLE); | ||
205 | return 0; | ||
206 | } else { | ||
207 | return regulator_disable_regmap(rdev); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | static int lp8788_ldo_is_enabled(struct regulator_dev *rdev) | ||
212 | { | ||
213 | struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); | ||
214 | |||
215 | if (ldo->en_pin) | ||
216 | return gpio_get_value(ldo->en_pin->gpio) ? 1 : 0; | ||
217 | else | ||
218 | return regulator_is_enabled_regmap(rdev); | ||
219 | } | ||
220 | |||
221 | static int lp8788_ldo_enable_time(struct regulator_dev *rdev) | 187 | static int lp8788_ldo_enable_time(struct regulator_dev *rdev) |
222 | { | 188 | { |
223 | struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); | 189 | struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); |
@@ -253,17 +219,17 @@ static struct regulator_ops lp8788_ldo_voltage_table_ops = { | |||
253 | .list_voltage = regulator_list_voltage_table, | 219 | .list_voltage = regulator_list_voltage_table, |
254 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 220 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
255 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 221 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
256 | .enable = lp8788_ldo_enable, | 222 | .enable = regulator_enable_regmap, |
257 | .disable = lp8788_ldo_disable, | 223 | .disable = regulator_disable_regmap, |
258 | .is_enabled = lp8788_ldo_is_enabled, | 224 | .is_enabled = regulator_is_enabled_regmap, |
259 | .enable_time = lp8788_ldo_enable_time, | 225 | .enable_time = lp8788_ldo_enable_time, |
260 | }; | 226 | }; |
261 | 227 | ||
262 | static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { | 228 | static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { |
263 | .get_voltage = lp8788_ldo_fixed_get_voltage, | 229 | .get_voltage = lp8788_ldo_fixed_get_voltage, |
264 | .enable = lp8788_ldo_enable, | 230 | .enable = regulator_enable_regmap, |
265 | .disable = lp8788_ldo_disable, | 231 | .disable = regulator_disable_regmap, |
266 | .is_enabled = lp8788_ldo_is_enabled, | 232 | .is_enabled = regulator_is_enabled_regmap, |
267 | .enable_time = lp8788_ldo_enable_time, | 233 | .enable_time = lp8788_ldo_enable_time, |
268 | }; | 234 | }; |
269 | 235 | ||
@@ -535,43 +501,10 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
535 | }, | 501 | }, |
536 | }; | 502 | }; |
537 | 503 | ||
538 | static int lp8788_gpio_request_ldo_en(struct platform_device *pdev, | ||
539 | struct lp8788_ldo *ldo, | ||
540 | enum lp8788_ext_ldo_en_id id) | ||
541 | { | ||
542 | struct device *dev = &pdev->dev; | ||
543 | struct lp8788_ldo_enable_pin *pin = ldo->en_pin; | ||
544 | int ret, gpio, pinstate; | ||
545 | char *name[] = { | ||
546 | [EN_ALDO1] = "LP8788_EN_ALDO1", | ||
547 | [EN_ALDO234] = "LP8788_EN_ALDO234", | ||
548 | [EN_ALDO5] = "LP8788_EN_ALDO5", | ||
549 | [EN_ALDO7] = "LP8788_EN_ALDO7", | ||
550 | [EN_DLDO7] = "LP8788_EN_DLDO7", | ||
551 | [EN_DLDO911] = "LP8788_EN_DLDO911", | ||
552 | }; | ||
553 | |||
554 | gpio = pin->gpio; | ||
555 | if (!gpio_is_valid(gpio)) { | ||
556 | dev_err(dev, "invalid gpio: %d\n", gpio); | ||
557 | return -EINVAL; | ||
558 | } | ||
559 | |||
560 | pinstate = pin->init_state; | ||
561 | ret = devm_gpio_request_one(dev, gpio, pinstate, name[id]); | ||
562 | if (ret == -EBUSY) { | ||
563 | dev_warn(dev, "gpio%d already used\n", gpio); | ||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | return ret; | ||
568 | } | ||
569 | |||
570 | static int lp8788_config_ldo_enable_mode(struct platform_device *pdev, | 504 | static int lp8788_config_ldo_enable_mode(struct platform_device *pdev, |
571 | struct lp8788_ldo *ldo, | 505 | struct lp8788_ldo *ldo, |
572 | enum lp8788_ldo_id id) | 506 | enum lp8788_ldo_id id) |
573 | { | 507 | { |
574 | int ret; | ||
575 | struct lp8788 *lp = ldo->lp; | 508 | struct lp8788 *lp = ldo->lp; |
576 | struct lp8788_platform_data *pdata = lp->pdata; | 509 | struct lp8788_platform_data *pdata = lp->pdata; |
577 | enum lp8788_ext_ldo_en_id enable_id; | 510 | enum lp8788_ext_ldo_en_id enable_id; |
@@ -613,14 +546,7 @@ static int lp8788_config_ldo_enable_mode(struct platform_device *pdev, | |||
613 | goto set_default_ldo_enable_mode; | 546 | goto set_default_ldo_enable_mode; |
614 | 547 | ||
615 | ldo->en_pin = pdata->ldo_pin[enable_id]; | 548 | ldo->en_pin = pdata->ldo_pin[enable_id]; |
616 | 549 | return 0; | |
617 | ret = lp8788_gpio_request_ldo_en(pdev, ldo, enable_id); | ||
618 | if (ret) { | ||
619 | ldo->en_pin = NULL; | ||
620 | goto set_default_ldo_enable_mode; | ||
621 | } | ||
622 | |||
623 | return ret; | ||
624 | 550 | ||
625 | set_default_ldo_enable_mode: | 551 | set_default_ldo_enable_mode: |
626 | return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0); | 552 | return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0); |
@@ -644,6 +570,11 @@ static int lp8788_dldo_probe(struct platform_device *pdev) | |||
644 | if (ret) | 570 | if (ret) |
645 | return ret; | 571 | return ret; |
646 | 572 | ||
573 | if (ldo->en_pin) { | ||
574 | cfg.ena_gpio = ldo->en_pin->gpio; | ||
575 | cfg.ena_gpio_flags = ldo->en_pin->init_state; | ||
576 | } | ||
577 | |||
647 | cfg.dev = pdev->dev.parent; | 578 | cfg.dev = pdev->dev.parent; |
648 | cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL; | 579 | cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL; |
649 | cfg.driver_data = ldo; | 580 | cfg.driver_data = ldo; |
@@ -700,6 +631,11 @@ static int lp8788_aldo_probe(struct platform_device *pdev) | |||
700 | if (ret) | 631 | if (ret) |
701 | return ret; | 632 | return ret; |
702 | 633 | ||
634 | if (ldo->en_pin) { | ||
635 | cfg.ena_gpio = ldo->en_pin->gpio; | ||
636 | cfg.ena_gpio_flags = ldo->en_pin->init_state; | ||
637 | } | ||
638 | |||
703 | cfg.dev = pdev->dev.parent; | 639 | cfg.dev = pdev->dev.parent; |
704 | cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL; | 640 | cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL; |
705 | cfg.driver_data = ldo; | 641 | cfg.driver_data = ldo; |