diff options
Diffstat (limited to 'drivers/regulator/lp8788-ldo.c')
| -rw-r--r-- | drivers/regulator/lp8788-ldo.c | 276 |
1 files changed, 38 insertions, 238 deletions
diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 3792741708c..b9a29a29933 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -88,11 +88,6 @@ #define ENABLE GPIOF_OUT_INIT_HIGH #define DISABLE GPIOF_OUT_INIT_LOW -enum lp8788_enable_mode { - REGISTER, - EXTPIN, -}; - enum lp8788_ldo_id { DLDO1, DLDO2, @@ -161,144 +156,6 @@ static const int lp8788_aldo7_vtbl[] = { 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000, }; -static enum lp8788_ldo_id lp8788_dldo_id[] = { - DLDO1, - DLDO2, - DLDO3, - DLDO4, - DLDO5, - DLDO6, - DLDO7, - DLDO8, - DLDO9, - DLDO10, - DLDO11, - DLDO12, -}; - -static enum lp8788_ldo_id lp8788_aldo_id[] = { - ALDO1, - ALDO2, - ALDO3, - ALDO4, - ALDO5, - ALDO6, - ALDO7, - ALDO8, - ALDO9, - ALDO10, -}; - -/* DLDO 7, 9 and 11, ALDO 1 ~ 5 and 7 - : can be enabled either by external pin or by i2c register */ -static enum lp8788_enable_mode -lp8788_get_ldo_enable_mode(struct lp8788_ldo *ldo, enum lp8788_ldo_id id) -{ - int ret; - u8 val, mask; - - ret = lp8788_read_byte(ldo->lp, LP8788_EN_SEL, &val); - if (ret) - return ret; - - switch (id) { - case DLDO7: - mask = LP8788_EN_SEL_DLDO7_M; - break; - case DLDO9: - case DLDO11: - mask = LP8788_EN_SEL_DLDO911_M; - break; - case ALDO1: - mask = LP8788_EN_SEL_ALDO1_M; - break; - case ALDO2 ... ALDO4: - mask = LP8788_EN_SEL_ALDO234_M; - break; - case ALDO5: - mask = LP8788_EN_SEL_ALDO5_M; - break; - case ALDO7: - mask = LP8788_EN_SEL_ALDO7_M; - break; - default: - return REGISTER; - } - - return val & mask ? EXTPIN : REGISTER; -} - -static int lp8788_ldo_ctrl_by_extern_pin(struct lp8788_ldo *ldo, int pinstate) -{ - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - - if (!pin) - return -EINVAL; - - if (gpio_is_valid(pin->gpio)) - gpio_set_value(pin->gpio, pinstate); - - return 0; -} - -static int lp8788_ldo_is_enabled_by_extern_pin(struct lp8788_ldo *ldo) -{ - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - - if (!pin) - return -EINVAL; - - return gpio_get_value(pin->gpio) ? 1 : 0; -} - -static int lp8788_ldo_enable(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id); - - switch (mode) { - case EXTPIN: - return lp8788_ldo_ctrl_by_extern_pin(ldo, ENABLE); - case REGISTER: - return regulator_enable_regmap(rdev); - default: - return -EINVAL; - } -} - -static int lp8788_ldo_disable(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id); - - switch (mode) { - case EXTPIN: - return lp8788_ldo_ctrl_by_extern_pin(ldo, DISABLE); - case REGISTER: - return regulator_disable_regmap(rdev); - default: - return -EINVAL; - } -} - -static int lp8788_ldo_is_enabled(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id); - - switch (mode) { - case EXTPIN: - return lp8788_ldo_is_enabled_by_extern_pin(ldo); - case REGISTER: - return regulator_is_enabled_regmap(rdev); - default: - return -EINVAL; - } -} - static int lp8788_ldo_enable_time(struct regulator_dev *rdev) { struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); @@ -313,38 +170,21 @@ static int lp8788_ldo_enable_time(struct regulator_dev *rdev) return ENABLE_TIME_USEC * val; } -static int lp8788_ldo_fixed_get_voltage(struct regulator_dev *rdev) -{ - enum lp8788_ldo_id id = rdev_get_id(rdev); - - switch (id) { - case ALDO2 ... ALDO5: - return 2850000; - case DLDO12: - case ALDO8 ... ALDO9: - return 2500000; - case ALDO10: - return 1100000; - default: - return -EINVAL; - } -} - static struct regulator_ops lp8788_ldo_voltage_table_ops = { .list_voltage = regulator_list_voltage_table, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = lp8788_ldo_enable, - .disable = lp8788_ldo_disable, - .is_enabled = lp8788_ldo_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .enable_time = lp8788_ldo_enable_time, }; static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { - .get_voltage = lp8788_ldo_fixed_get_voltage, - .enable = lp8788_ldo_enable, - .disable = lp8788_ldo_disable, - .is_enabled = lp8788_ldo_is_enabled, + .list_voltage = regulator_list_voltage_linear, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .enable_time = lp8788_ldo_enable_time, }; @@ -501,6 +341,7 @@ static struct regulator_desc lp8788_dldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_B, .enable_mask = LP8788_EN_DLDO12_M, + .min_uV = 2500000, }, }; @@ -527,6 +368,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_B, .enable_mask = LP8788_EN_ALDO2_M, + .min_uV = 2850000, }, { .name = "aldo3", @@ -537,6 +379,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_B, .enable_mask = LP8788_EN_ALDO3_M, + .min_uV = 2850000, }, { .name = "aldo4", @@ -547,6 +390,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_B, .enable_mask = LP8788_EN_ALDO4_M, + .min_uV = 2850000, }, { .name = "aldo5", @@ -557,6 +401,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_C, .enable_mask = LP8788_EN_ALDO5_M, + .min_uV = 2850000, }, { .name = "aldo6", @@ -593,6 +438,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_C, .enable_mask = LP8788_EN_ALDO8_M, + .min_uV = 2500000, }, { .name = "aldo9", @@ -603,6 +449,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_C, .enable_mask = LP8788_EN_ALDO9_M, + .min_uV = 2500000, }, { .name = "aldo10", @@ -613,44 +460,14 @@ static struct regulator_desc lp8788_aldo_desc[] = { .owner = THIS_MODULE, .enable_reg = LP8788_EN_LDO_C, .enable_mask = LP8788_EN_ALDO10_M, + .min_uV = 1100000, }, }; -static int lp8788_gpio_request_ldo_en(struct lp8788_ldo *ldo, - enum lp8788_ext_ldo_en_id id) -{ - struct device *dev = ldo->lp->dev; - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - int ret, gpio, pinstate; - char *name[] = { - [EN_ALDO1] = "LP8788_EN_ALDO1", - [EN_ALDO234] = "LP8788_EN_ALDO234", - [EN_ALDO5] = "LP8788_EN_ALDO5", - [EN_ALDO7] = "LP8788_EN_ALDO7", - [EN_DLDO7] = "LP8788_EN_DLDO7", - [EN_DLDO911] = "LP8788_EN_DLDO911", - }; - - gpio = pin->gpio; - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio: %d\n", gpio); - return -EINVAL; - } - - pinstate = pin->init_state; - ret = devm_gpio_request_one(dev, gpio, pinstate, name[id]); - if (ret == -EBUSY) { - dev_warn(dev, "gpio%d already used\n", gpio); - return 0; - } - - return ret; -} - -static int lp8788_config_ldo_enable_mode(struct lp8788_ldo *ldo, +static int lp8788_config_ldo_enable_mode(struct platform_device *pdev, + struct lp8788_ldo *ldo, enum lp8788_ldo_id id) { - int ret; struct lp8788 *lp = ldo->lp; struct lp8788_platform_data *pdata = lp->pdata; enum lp8788_ext_ldo_en_id enable_id; @@ -692,12 +509,7 @@ static int lp8788_config_ldo_enable_mode(struct lp8788_ldo *ldo, goto set_default_ldo_enable_mode; ldo->en_pin = pdata->ldo_pin[enable_id]; - - ret = lp8788_gpio_request_ldo_en(ldo, enable_id); - if (ret) - goto set_default_ldo_enable_mode; - - return ret; + return 0; set_default_ldo_enable_mode: return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0); @@ -712,24 +524,29 @@ static int lp8788_dldo_probe(struct platform_device *pdev) struct regulator_dev *rdev; int ret; - ldo = devm_kzalloc(lp->dev, sizeof(struct lp8788_ldo), GFP_KERNEL); + ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL); if (!ldo) return -ENOMEM; ldo->lp = lp; - ret = lp8788_config_ldo_enable_mode(ldo, lp8788_dldo_id[id]); + ret = lp8788_config_ldo_enable_mode(pdev, ldo, id); if (ret) return ret; - cfg.dev = lp->dev; + if (ldo->en_pin) { + cfg.ena_gpio = ldo->en_pin->gpio; + cfg.ena_gpio_flags = ldo->en_pin->init_state; + } + + cfg.dev = pdev->dev.parent; cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL; cfg.driver_data = ldo; cfg.regmap = lp->regmap; - rdev = regulator_register(&lp8788_dldo_desc[id], &cfg); + rdev = devm_regulator_register(&pdev->dev, &lp8788_dldo_desc[id], &cfg); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); - dev_err(lp->dev, "DLDO%d regulator register err = %d\n", + dev_err(&pdev->dev, "DLDO%d regulator register err = %d\n", id + 1, ret); return ret; } @@ -740,19 +557,8 @@ static int lp8788_dldo_probe(struct platform_device *pdev) return 0; } -static int lp8788_dldo_remove(struct platform_device *pdev) -{ - struct lp8788_ldo *ldo = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - regulator_unregister(ldo->regulator); - - return 0; -} - static struct platform_driver lp8788_dldo_driver = { .probe = lp8788_dldo_probe, - .remove = lp8788_dldo_remove, .driver = { .name = LP8788_DEV_DLDO, .owner = THIS_MODULE, @@ -768,24 +574,29 @@ static int lp8788_aldo_probe(struct platform_device *pdev) struct regulator_dev *rdev; int ret; - ldo = devm_kzalloc(lp->dev, sizeof(struct lp8788_ldo), GFP_KERNEL); + ldo = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_ldo), GFP_KERNEL); if (!ldo) return -ENOMEM; ldo->lp = lp; - ret = lp8788_config_ldo_enable_mode(ldo, lp8788_aldo_id[id]); + ret = lp8788_config_ldo_enable_mode(pdev, ldo, id + ALDO1); if (ret) return ret; - cfg.dev = lp->dev; + if (ldo->en_pin) { + cfg.ena_gpio = ldo->en_pin->gpio; + cfg.ena_gpio_flags = ldo->en_pin->init_state; + } + + cfg.dev = pdev->dev.parent; cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL; cfg.driver_data = ldo; cfg.regmap = lp->regmap; - rdev = regulator_register(&lp8788_aldo_desc[id], &cfg); + rdev = devm_regulator_register(&pdev->dev, &lp8788_aldo_desc[id], &cfg); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); - dev_err(lp->dev, "ALDO%d regulator register err = %d\n", + dev_err(&pdev->dev, "ALDO%d regulator register err = %d\n", id + 1, ret); return ret; } @@ -796,19 +607,8 @@ static int lp8788_aldo_probe(struct platform_device *pdev) return 0; } -static int lp8788_aldo_remove(struct platform_device *pdev) -{ - struct lp8788_ldo *ldo = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - regulator_unregister(ldo->regulator); - - return 0; -} - static struct platform_driver lp8788_aldo_driver = { .probe = lp8788_aldo_probe, - .remove = lp8788_aldo_remove, .driver = { .name = LP8788_DEV_ALDO, .owner = THIS_MODULE, |
