diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/Kconfig | 7 | ||||
-rw-r--r-- | drivers/regulator/act8865-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/arizona-ldo1.c | 2 | ||||
-rw-r--r-- | drivers/regulator/as3722-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/bcm590xx-regulator.c | 5 | ||||
-rw-r--r-- | drivers/regulator/ltc3589.c | 2 | ||||
-rw-r--r-- | drivers/regulator/max14577.c | 277 | ||||
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 14 | ||||
-rw-r--r-- | drivers/regulator/tps65218-regulator.c | 5 | ||||
-rw-r--r-- | drivers/regulator/vexpress.c | 50 | ||||
-rw-r--r-- | drivers/regulator/virtual.c | 10 |
11 files changed, 289 insertions, 87 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c2fa0b4367b1..789eb46090e3 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -281,11 +281,12 @@ config REGULATOR_LTC3589 8-output regulators controlled via I2C. config REGULATOR_MAX14577 - tristate "Maxim 14577 regulator" + tristate "Maxim 14577/77836 regulator" depends on MFD_MAX14577 help - This driver controls a Maxim 14577 regulator via I2C bus. - The regulators include safeout LDO and current regulator 'CHARGER'. + This driver controls a Maxim MAX14577/77836 regulator via I2C bus. + The MAX14577 regulators include safeout LDO and charger current + regulator. The MAX77836 has two additional LDOs. config REGULATOR_MAX1586 tristate "Maxim 1586/1587 voltage regulator" diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index b92d7dd01a18..89f9f0c0f64d 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -230,7 +230,7 @@ static int act8865_pdata_from_dt(struct device *dev, if (!pdata->regulators) return -ENOMEM; - pdata->num_regulators = matched; + pdata->num_regulators = ARRAY_SIZE(act8865_matches); regulator = pdata->regulators; for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) { diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 04f262a836b2..4c9db589f6c1 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -143,8 +143,6 @@ static struct regulator_ops arizona_ldo1_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_bypass = regulator_get_bypass_regmap, - .set_bypass = regulator_set_bypass_regmap, }; static const struct regulator_desc arizona_ldo1 = { diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 85585219ce82..ad9e0c9b7daf 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -433,6 +433,7 @@ static struct regulator_ops as3722_ldo3_extcntrl_ops = { }; static const struct regulator_linear_range as3722_ldo_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0), REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000), REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000), }; @@ -609,6 +610,7 @@ static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs) } static const struct regulator_linear_range as3722_sd2345_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0), REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500), REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000), REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000), diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 57544e254a78..58ece59367ae 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -119,6 +119,10 @@ static const unsigned int ldo_c_table[] = { 2900000, 3000000, 3300000, }; +static const unsigned int ldo_vbus[] = { + 5000000, +}; + /* DCDC group CSR: supported voltages in microvolts */ static const struct regulator_linear_range dcdc_csr_ranges[] = { REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), @@ -192,6 +196,7 @@ static struct bcm590xx_info bcm590xx_regs[] = { BCM590XX_REG_TABLE(gpldo4, ldo_a_table), BCM590XX_REG_TABLE(gpldo5, ldo_a_table), BCM590XX_REG_TABLE(gpldo6, ldo_a_table), + BCM590XX_REG_TABLE(vbus, ldo_vbus), }; struct bcm590xx_reg { diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index 110a99ee1162..c8105182b8b8 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -255,7 +255,7 @@ static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) struct device_node *node; int i, ret; - node = of_find_node_by_name(dev->of_node, "regulators"); + node = of_get_child_by_name(dev->of_node, "regulators"); if (!node) { dev_err(dev, "regulators node not found\n"); return -EINVAL; diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index ed60baaeceec..5d9c605cf534 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c @@ -1,5 +1,5 @@ /* - * max14577.c - Regulator driver for the Maxim 14577 + * max14577.c - Regulator driver for the Maxim 14577/77836 * * Copyright (C) 2013,2014 Samsung Electronics * Krzysztof Kozlowski <k.kozlowski@samsung.com> @@ -22,6 +22,42 @@ #include <linux/mfd/max14577-private.h> #include <linux/regulator/of_regulator.h> +/* + * Valid limits of current for max14577 and max77836 chargers. + * They must correspond to MBCICHWRCL and MBCICHWRCH fields in CHGCTRL4 + * register for given chipset. + */ +struct maxim_charger_current { + /* Minimal current, set in CHGCTRL4/MBCICHWRCL, uA */ + unsigned int min; + /* + * Minimal current when high setting is active, + * set in CHGCTRL4/MBCICHWRCH, uA + */ + unsigned int high_start; + /* Value of one step in high setting, uA */ + unsigned int high_step; + /* Maximum current of high setting, uA */ + unsigned int max; +}; + +/* Table of valid charger currents for different Maxim chipsets */ +static const struct maxim_charger_current maxim_charger_currents[] = { + [MAXIM_DEVICE_TYPE_UNKNOWN] = { 0, 0, 0, 0 }, + [MAXIM_DEVICE_TYPE_MAX14577] = { + .min = MAX14577_REGULATOR_CURRENT_LIMIT_MIN, + .high_start = MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START, + .high_step = MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP, + .max = MAX14577_REGULATOR_CURRENT_LIMIT_MAX, + }, + [MAXIM_DEVICE_TYPE_MAX77836] = { + .min = MAX77836_REGULATOR_CURRENT_LIMIT_MIN, + .high_start = MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_START, + .high_step = MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_STEP, + .max = MAX77836_REGULATOR_CURRENT_LIMIT_MAX, + }, +}; + static int max14577_reg_is_enabled(struct regulator_dev *rdev) { int rid = rdev_get_id(rdev); @@ -47,6 +83,9 @@ static int max14577_reg_get_current_limit(struct regulator_dev *rdev) { u8 reg_data; struct regmap *rmap = rdev->regmap; + struct max14577 *max14577 = rdev_get_drvdata(rdev); + const struct maxim_charger_current *limits = + &maxim_charger_currents[max14577->dev_type]; if (rdev_get_id(rdev) != MAX14577_CHARGER) return -EINVAL; @@ -54,12 +93,11 @@ static int max14577_reg_get_current_limit(struct regulator_dev *rdev) max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, ®_data); if ((reg_data & CHGCTRL4_MBCICHWRCL_MASK) == 0) - return MAX14577_REGULATOR_CURRENT_LIMIT_MIN; + return limits->min; reg_data = ((reg_data & CHGCTRL4_MBCICHWRCH_MASK) >> CHGCTRL4_MBCICHWRCH_SHIFT); - return MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START + - reg_data * MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP; + return limits->high_start + reg_data * limits->high_step; } static int max14577_reg_set_current_limit(struct regulator_dev *rdev, @@ -67,33 +105,39 @@ static int max14577_reg_set_current_limit(struct regulator_dev *rdev, { int i, current_bits = 0xf; u8 reg_data; + struct max14577 *max14577 = rdev_get_drvdata(rdev); + const struct maxim_charger_current *limits = + &maxim_charger_currents[max14577->dev_type]; if (rdev_get_id(rdev) != MAX14577_CHARGER) return -EINVAL; - if (min_uA > MAX14577_REGULATOR_CURRENT_LIMIT_MAX || - max_uA < MAX14577_REGULATOR_CURRENT_LIMIT_MIN) + if (min_uA > limits->max || max_uA < limits->min) return -EINVAL; - if (max_uA < MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START) { - /* Less than 200 mA, so set 90mA (turn only Low Bit off) */ + if (max_uA < limits->high_start) { + /* + * Less than high_start, + * so set the minimal current (turn only Low Bit off) + */ u8 reg_data = 0x0 << CHGCTRL4_MBCICHWRCL_SHIFT; return max14577_update_reg(rdev->regmap, MAX14577_CHG_REG_CHG_CTRL4, CHGCTRL4_MBCICHWRCL_MASK, reg_data); } - /* max_uA is in range: <LIMIT_HIGH_START, inifinite>, so search for - * valid current starting from LIMIT_MAX. */ - for (i = MAX14577_REGULATOR_CURRENT_LIMIT_MAX; - i >= MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START; - i -= MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP) { + /* + * max_uA is in range: <high_start, inifinite>, so search for + * valid current starting from maximum current. + */ + for (i = limits->max; i >= limits->high_start; i -= limits->high_step) { if (i <= max_uA) break; current_bits--; } BUG_ON(current_bits < 0); /* Cannot happen */ - /* Turn Low Bit on (use range 200mA-950 mA) */ + + /* Turn Low Bit on (use range high_start-max)... */ reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT; /* and set proper High Bits */ reg_data |= current_bits << CHGCTRL4_MBCICHWRCH_SHIFT; @@ -118,7 +162,7 @@ static struct regulator_ops max14577_charger_ops = { .set_current_limit = max14577_reg_set_current_limit, }; -static const struct regulator_desc supported_regulators[] = { +static const struct regulator_desc max14577_supported_regulators[] = { [MAX14577_SAFEOUT] = { .name = "SAFEOUT", .id = MAX14577_SAFEOUT, @@ -141,16 +185,88 @@ static const struct regulator_desc supported_regulators[] = { }, }; +static struct regulator_ops max77836_ldo_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + /* TODO: add .set_suspend_mode */ +}; + +static const struct regulator_desc max77836_supported_regulators[] = { + [MAX14577_SAFEOUT] = { + .name = "SAFEOUT", + .id = MAX14577_SAFEOUT, + .ops = &max14577_safeout_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .n_voltages = 1, + .min_uV = MAX14577_REGULATOR_SAFEOUT_VOLTAGE, + .enable_reg = MAX14577_REG_CONTROL2, + .enable_mask = CTRL2_SFOUTORD_MASK, + }, + [MAX14577_CHARGER] = { + .name = "CHARGER", + .id = MAX14577_CHARGER, + .ops = &max14577_charger_ops, + .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, + .enable_reg = MAX14577_CHG_REG_CHG_CTRL2, + .enable_mask = CHGCTRL2_MBCHOSTEN_MASK, + }, + [MAX77836_LDO1] = { + .name = "LDO1", + .id = MAX77836_LDO1, + .ops = &max77836_ldo_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .n_voltages = MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM, + .min_uV = MAX77836_REGULATOR_LDO_VOLTAGE_MIN, + .uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP, + .enable_reg = MAX77836_LDO_REG_CNFG1_LDO1, + .enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK, + .vsel_reg = MAX77836_LDO_REG_CNFG1_LDO1, + .vsel_mask = MAX77836_CNFG1_LDO_TV_MASK, + }, + [MAX77836_LDO2] = { + .name = "LDO2", + .id = MAX77836_LDO2, + .ops = &max77836_ldo_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .n_voltages = MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM, + .min_uV = MAX77836_REGULATOR_LDO_VOLTAGE_MIN, + .uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP, + .enable_reg = MAX77836_LDO_REG_CNFG1_LDO2, + .enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK, + .vsel_reg = MAX77836_LDO_REG_CNFG1_LDO2, + .vsel_mask = MAX77836_CNFG1_LDO_TV_MASK, + }, +}; + #ifdef CONFIG_OF static struct of_regulator_match max14577_regulator_matches[] = { { .name = "SAFEOUT", }, { .name = "CHARGER", }, }; -static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) +static struct of_regulator_match max77836_regulator_matches[] = { + { .name = "SAFEOUT", }, + { .name = "CHARGER", }, + { .name = "LDO1", }, + { .name = "LDO2", }, +}; + +static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev, + enum maxim_device_type dev_type) { int ret; struct device_node *np; + struct of_regulator_match *regulator_matches; + unsigned int regulator_matches_size; np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); if (!np) { @@ -158,8 +274,19 @@ static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) return -EINVAL; } - ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, - MAX14577_REG_MAX); + switch (dev_type) { + case MAXIM_DEVICE_TYPE_MAX77836: + regulator_matches = max77836_regulator_matches; + regulator_matches_size = ARRAY_SIZE(max77836_regulator_matches); + break; + case MAXIM_DEVICE_TYPE_MAX14577: + default: + regulator_matches = max14577_regulator_matches; + regulator_matches_size = ARRAY_SIZE(max14577_regulator_matches); + } + + ret = of_regulator_match(&pdev->dev, np, regulator_matches, + regulator_matches_size); if (ret < 0) dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); else @@ -170,31 +297,74 @@ static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) return ret; } -static inline struct regulator_init_data *match_init_data(int index) +static inline struct regulator_init_data *match_init_data(int index, + enum maxim_device_type dev_type) { - return max14577_regulator_matches[index].init_data; + switch (dev_type) { + case MAXIM_DEVICE_TYPE_MAX77836: + return max77836_regulator_matches[index].init_data; + + case MAXIM_DEVICE_TYPE_MAX14577: + default: + return max14577_regulator_matches[index].init_data; + } } -static inline struct device_node *match_of_node(int index) +static inline struct device_node *match_of_node(int index, + enum maxim_device_type dev_type) { - return max14577_regulator_matches[index].of_node; + switch (dev_type) { + case MAXIM_DEVICE_TYPE_MAX77836: + return max77836_regulator_matches[index].of_node; + + case MAXIM_DEVICE_TYPE_MAX14577: + default: + return max14577_regulator_matches[index].of_node; + } } #else /* CONFIG_OF */ -static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) +static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev, + enum maxim_device_type dev_type) { return 0; } -static inline struct regulator_init_data *match_init_data(int index) +static inline struct regulator_init_data *match_init_data(int index, + enum maxim_device_type dev_type) { return NULL; } -static inline struct device_node *match_of_node(int index) +static inline struct device_node *match_of_node(int index, + enum maxim_device_type dev_type) { return NULL; } #endif /* CONFIG_OF */ +/** + * Registers for regulators of max77836 use different I2C slave addresses so + * different regmaps must be used for them. + * + * Returns proper regmap for accessing regulator passed by id. + */ +static struct regmap *max14577_get_regmap(struct max14577 *max14577, + int reg_id) +{ + switch (max14577->dev_type) { + case MAXIM_DEVICE_TYPE_MAX77836: + switch (reg_id) { + case MAX77836_SAFEOUT ... MAX77836_CHARGER: + return max14577->regmap; + default: + /* MAX77836_LDO1 ... MAX77836_LDO2 */ + return max14577->regmap_pmic; + } + + case MAXIM_DEVICE_TYPE_MAX14577: + default: + return max14577->regmap; + } +} static int max14577_regulator_probe(struct platform_device *pdev) { @@ -202,15 +372,29 @@ static int max14577_regulator_probe(struct platform_device *pdev) struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev); int i, ret; struct regulator_config config = {}; + const struct regulator_desc *supported_regulators; + unsigned int supported_regulators_size; + enum maxim_device_type dev_type = max14577->dev_type; - ret = max14577_regulator_dt_parse_pdata(pdev); + ret = max14577_regulator_dt_parse_pdata(pdev, dev_type); if (ret) return ret; + switch (dev_type) { + case MAXIM_DEVICE_TYPE_MAX77836: + supported_regulators = max77836_supported_regulators; + supported_regulators_size = ARRAY_SIZE(max77836_supported_regulators); + break; + case MAXIM_DEVICE_TYPE_MAX14577: + default: + supported_regulators = max14577_supported_regulators; + supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators); + } + config.dev = &pdev->dev; - config.regmap = max14577->regmap; + config.driver_data = max14577; - for (i = 0; i < ARRAY_SIZE(supported_regulators); i++) { + for (i = 0; i < supported_regulators_size; i++) { struct regulator_dev *regulator; /* * Index of supported_regulators[] is also the id and must @@ -220,17 +404,19 @@ static int max14577_regulator_probe(struct platform_device *pdev) config.init_data = pdata->regulators[i].initdata; config.of_node = pdata->regulators[i].of_node; } else { - config.init_data = match_init_data(i); - config.of_node = match_of_node(i); + config.init_data = match_init_data(i, dev_type); + config.of_node = match_of_node(i, dev_type); } + config.regmap = max14577_get_regmap(max14577, + supported_regulators[i].id); regulator = devm_regulator_register(&pdev->dev, &supported_regulators[i], &config); if (IS_ERR(regulator)) { ret = PTR_ERR(regulator); dev_err(&pdev->dev, - "Regulator init failed for ID %d with error: %d\n", - i, ret); + "Regulator init failed for %d/%s with error: %d\n", + i, supported_regulators[i].name, ret); return ret; } } @@ -238,20 +424,41 @@ static int max14577_regulator_probe(struct platform_device *pdev) return ret; } +static const struct platform_device_id max14577_regulator_id[] = { + { "max14577-regulator", MAXIM_DEVICE_TYPE_MAX14577, }, + { "max77836-regulator", MAXIM_DEVICE_TYPE_MAX77836, }, + { } +}; +MODULE_DEVICE_TABLE(platform, max14577_regulator_id); + static struct platform_driver max14577_regulator_driver = { .driver = { .owner = THIS_MODULE, .name = "max14577-regulator", }, - .probe = max14577_regulator_probe, + .probe = max14577_regulator_probe, + .id_table = max14577_regulator_id, }; static int __init max14577_regulator_init(void) { + /* Check for valid values for charger */ BUILD_BUG_ON(MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START + MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP * 0xf != MAX14577_REGULATOR_CURRENT_LIMIT_MAX); - BUILD_BUG_ON(ARRAY_SIZE(supported_regulators) != MAX14577_REG_MAX); + BUILD_BUG_ON(MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_START + + MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_STEP * 0xf != + MAX77836_REGULATOR_CURRENT_LIMIT_MAX); + /* Valid charger current values must be provided for each chipset */ + BUILD_BUG_ON(ARRAY_SIZE(maxim_charger_currents) != MAXIM_DEVICE_TYPE_NUM); + + BUILD_BUG_ON(ARRAY_SIZE(max14577_supported_regulators) != MAX14577_REGULATOR_NUM); + BUILD_BUG_ON(ARRAY_SIZE(max77836_supported_regulators) != MAX77836_REGULATOR_NUM); + + BUILD_BUG_ON(MAX77836_REGULATOR_LDO_VOLTAGE_MIN + + (MAX77836_REGULATOR_LDO_VOLTAGE_STEP * + (MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM - 1)) != + MAX77836_REGULATOR_LDO_VOLTAGE_MAX); return platform_driver_register(&max14577_regulator_driver); } @@ -264,6 +471,6 @@ static void __exit max14577_regulator_exit(void) module_exit(max14577_regulator_exit); MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>"); -MODULE_DESCRIPTION("MAXIM 14577 regulator driver"); +MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:max14577-regulator"); diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 864ed02ce4b7..93b4ad842901 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -37,12 +37,14 @@ struct regs_info { }; static const struct regulator_linear_range smps_low_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0), REGULATOR_LINEAR_RANGE(510000, 0x7, 0x79, 10000), REGULATOR_LINEAR_RANGE(1650000, 0x7A, 0x7f, 0), }; static const struct regulator_linear_range smps_high_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x6, 0), REGULATOR_LINEAR_RANGE(1020000, 0x7, 0x79, 20000), REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0), @@ -323,6 +325,10 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) if (rail_enable) palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); + + /* Switch the enable value to ensure this is used for enable */ + pmic->desc[id].enable_val = pmic->current_reg_mode[id]; + return 0; } @@ -962,6 +968,14 @@ static int palmas_regulators_probe(struct platform_device *pdev) return ret; pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_mask = + PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + /* set_mode overrides this value */ + pmic->desc[id].enable_val = SMPS_CTRL_MODE_ON; } pmic->desc[id].type = REGULATOR_VOLTAGE; diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 69b4b7750410..8b7a0a9ebdfe 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -68,7 +68,7 @@ static const struct regulator_linear_range ldo1_dcdc3_ranges[] = { static const struct regulator_linear_range dcdc4_ranges[] = { REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), - REGULATOR_LINEAR_RANGE(1550000, 0x10, 0x34, 50000), + REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000), }; static struct tps_info tps65218_pmic_regs[] = { @@ -209,7 +209,7 @@ static const struct regulator_desc regulators[] = { 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, - TPS65218_REG_CONTROL_DCDC4, + TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, 2, 0), @@ -240,6 +240,7 @@ static int tps65218_regulator_probe(struct platform_device *pdev) config.init_data = init_data; config.driver_data = tps; config.regmap = tps->regmap; + config.of_node = pdev->dev.of_node; rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config); if (IS_ERR(rdev)) { diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index 147ecc7c11bf..02e7267ccf92 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c @@ -26,14 +26,14 @@ struct vexpress_regulator { struct regulator_desc desc; struct regulator_dev *regdev; - struct vexpress_config_func *func; + struct regmap *regmap; }; static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) { struct vexpress_regulator *reg = rdev_get_drvdata(regdev); u32 uV; - int err = vexpress_config_read(reg->func, 0, &uV); + int err = regmap_read(reg->regmap, 0, &uV); return err ? err : uV; } @@ -43,7 +43,7 @@ static int vexpress_regulator_set_voltage(struct regulator_dev *regdev, { struct vexpress_regulator *reg = rdev_get_drvdata(regdev); - return vexpress_config_write(reg->func, 0, min_uV); + return regmap_write(reg->regmap, 0, min_uV); } static struct regulator_ops vexpress_regulator_ops_ro = { @@ -57,22 +57,17 @@ static struct regulator_ops vexpress_regulator_ops = { static int vexpress_regulator_probe(struct platform_device *pdev) { - int err; struct vexpress_regulator *reg; struct regulator_init_data *init_data; struct regulator_config config = { }; reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); - if (!reg) { - err = -ENOMEM; - goto error_kzalloc; - } + if (!reg) + return -ENOMEM; - reg->func = vexpress_config_func_get_by_dev(&pdev->dev); - if (!reg->func) { - err = -ENXIO; - goto error_get_func; - } + reg->regmap = devm_regmap_init_vexpress_config(&pdev->dev); + if (IS_ERR(reg->regmap)) + return PTR_ERR(reg->regmap); reg->desc.name = dev_name(&pdev->dev); reg->desc.type = REGULATOR_VOLTAGE; @@ -80,10 +75,8 @@ static int vexpress_regulator_probe(struct platform_device *pdev) reg->desc.continuous_voltage_range = true; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); - if (!init_data) { - err = -EINVAL; - goto error_get_regulator_init_data; - } + if (!init_data) + return -EINVAL; init_data->constraints.apply_uV = 0; if (init_data->constraints.min_uV && init_data->constraints.max_uV) @@ -97,30 +90,12 @@ static int vexpress_regulator_probe(struct platform_device *pdev) config.of_node = pdev->dev.of_node; reg->regdev = devm_regulator_register(&pdev->dev, ®->desc, &config); - if (IS_ERR(reg->regdev)) { - err = PTR_ERR(reg->regdev); - goto error_regulator_register; - } + if (IS_ERR(reg->regdev)) + return PTR_ERR(reg->regdev); platform_set_drvdata(pdev, reg); return 0; - -error_regulator_register: -error_get_regulator_init_data: - vexpress_config_func_put(reg->func); -error_get_func: -error_kzalloc: - return err; -} - -static int vexpress_regulator_remove(struct platform_device *pdev) -{ - struct vexpress_regulator *reg = platform_get_drvdata(pdev); - - vexpress_config_func_put(reg->func); - - return 0; } static const struct of_device_id vexpress_regulator_of_match[] = { @@ -130,7 +105,6 @@ static const struct of_device_id vexpress_regulator_of_match[] = { static struct platform_driver vexpress_regulator_driver = { .probe = vexpress_regulator_probe, - .remove = vexpress_regulator_remove, .driver = { .name = DRVNAME, .owner = THIS_MODULE, diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index f53e78b9a84e..6ff95b045984 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -266,11 +266,11 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(min_microvolts, 0666, show_min_uV, set_min_uV); -static DEVICE_ATTR(max_microvolts, 0666, show_max_uV, set_max_uV); -static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA); -static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA); -static DEVICE_ATTR(mode, 0666, show_mode, set_mode); +static DEVICE_ATTR(min_microvolts, 0664, show_min_uV, set_min_uV); +static DEVICE_ATTR(max_microvolts, 0664, show_max_uV, set_max_uV); +static DEVICE_ATTR(min_microamps, 0664, show_min_uA, set_min_uA); +static DEVICE_ATTR(max_microamps, 0664, show_max_uA, set_max_uA); +static DEVICE_ATTR(mode, 0664, show_mode, set_mode); static struct attribute *regulator_virtual_attributes[] = { &dev_attr_min_microvolts.attr, |