diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/axp20x-regulator.c | 93 | ||||
-rw-r--r-- | drivers/regulator/core.c | 267 | ||||
-rw-r--r-- | drivers/regulator/fan53555.c | 4 | ||||
-rw-r--r-- | drivers/regulator/internal.h | 2 | ||||
-rw-r--r-- | drivers/regulator/of_regulator.c | 11 | ||||
-rw-r--r-- | drivers/regulator/qcom_rpm-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/s2mps11.c | 61 |
7 files changed, 234 insertions, 206 deletions
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index f23d7e1f2ee7..e4331f5e5d7d 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -32,11 +32,13 @@ #define AXP20X_FREQ_DCDC_MASK 0x0f -#define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \ - _emask, _enable_val, _disable_val) \ +#define AXP20X_DESC_IO(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \ + _ereg, _emask, _enable_val, _disable_val) \ [AXP20X_##_id] = { \ .name = #_id, \ .supply_name = (_supply), \ + .of_match = of_match_ptr(_match), \ + .regulators_node = of_match_ptr("regulators"), \ .type = REGULATOR_VOLTAGE, \ .id = AXP20X_##_id, \ .n_voltages = (((_max) - (_min)) / (_step) + 1), \ @@ -52,11 +54,13 @@ .ops = &axp20x_ops, \ } -#define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \ - _emask) \ +#define AXP20X_DESC(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \ + _ereg, _emask) \ [AXP20X_##_id] = { \ .name = #_id, \ .supply_name = (_supply), \ + .of_match = of_match_ptr(_match), \ + .regulators_node = of_match_ptr("regulators"), \ .type = REGULATOR_VOLTAGE, \ .id = AXP20X_##_id, \ .n_voltages = (((_max) - (_min)) / (_step) + 1), \ @@ -70,10 +74,12 @@ .ops = &axp20x_ops, \ } -#define AXP20X_DESC_FIXED(_id, _supply, _volt) \ +#define AXP20X_DESC_FIXED(_id, _match, _supply, _volt) \ [AXP20X_##_id] = { \ .name = #_id, \ .supply_name = (_supply), \ + .of_match = of_match_ptr(_match), \ + .regulators_node = of_match_ptr("regulators"), \ .type = REGULATOR_VOLTAGE, \ .id = AXP20X_##_id, \ .n_voltages = 1, \ @@ -82,10 +88,13 @@ .ops = &axp20x_ops_fixed \ } -#define AXP20X_DESC_TABLE(_id, _supply, _table, _vreg, _vmask, _ereg, _emask) \ +#define AXP20X_DESC_TABLE(_id, _match, _supply, _table, _vreg, _vmask, _ereg, \ + _emask) \ [AXP20X_##_id] = { \ .name = #_id, \ .supply_name = (_supply), \ + .of_match = of_match_ptr(_match), \ + .regulators_node = of_match_ptr("regulators"), \ .type = REGULATOR_VOLTAGE, \ .id = AXP20X_##_id, \ .n_voltages = ARRAY_SIZE(_table), \ @@ -127,36 +136,20 @@ static struct regulator_ops axp20x_ops = { }; static const struct regulator_desc axp20x_regulators[] = { - AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f, - AXP20X_PWR_OUT_CTRL, 0x10), - AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f, - AXP20X_PWR_OUT_CTRL, 0x02), - AXP20X_DESC_FIXED(LDO1, "acin", 1300), - AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0, - AXP20X_PWR_OUT_CTRL, 0x04), - AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f, - AXP20X_PWR_OUT_CTRL, 0x40), - AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f, - AXP20X_PWR_OUT_CTRL, 0x08), - AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0, - AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED, - AXP20X_IO_DISABLED), -}; - -#define AXP_MATCH(_name, _id) \ - [AXP20X_##_id] = { \ - .name = #_name, \ - .driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \ - } - -static struct of_regulator_match axp20x_matches[] = { - AXP_MATCH(dcdc2, DCDC2), - AXP_MATCH(dcdc3, DCDC3), - AXP_MATCH(ldo1, LDO1), - AXP_MATCH(ldo2, LDO2), - AXP_MATCH(ldo3, LDO3), - AXP_MATCH(ldo4, LDO4), - AXP_MATCH(ldo5, LDO5), + AXP20X_DESC(DCDC2, "dcdc2", "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, + 0x3f, AXP20X_PWR_OUT_CTRL, 0x10), + AXP20X_DESC(DCDC3, "dcdc3", "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, + 0x7f, AXP20X_PWR_OUT_CTRL, 0x02), + AXP20X_DESC_FIXED(LDO1, "ldo1", "acin", 1300), + AXP20X_DESC(LDO2, "ldo2", "ldo24in", 1800, 3300, 100, + AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04), + AXP20X_DESC(LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, + 0x7f, AXP20X_PWR_OUT_CTRL, 0x40), + AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data, + AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08), + AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100, + AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07, + AXP20X_IO_ENABLED, AXP20X_IO_DISABLED), }; static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) @@ -193,13 +186,6 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev) if (!regulators) { dev_warn(&pdev->dev, "regulators node not found\n"); } else { - ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches, - ARRAY_SIZE(axp20x_matches)); - if (ret < 0) { - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); - return ret; - } - dcdcfreq = 1500; of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq); ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); @@ -233,23 +219,17 @@ static int axp20x_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; - struct regulator_init_data *init_data; + struct regulator_config config = { + .dev = pdev->dev.parent, + .regmap = axp20x->regmap, + }; int ret, i; u32 workmode; - ret = axp20x_regulator_parse_dt(pdev); - if (ret) - return ret; + /* This only sets the dcdc freq. Ignore any errors */ + axp20x_regulator_parse_dt(pdev); for (i = 0; i < AXP20X_REG_ID_MAX; i++) { - init_data = axp20x_matches[i].init_data; - - config.dev = pdev->dev.parent; - config.init_data = init_data; - config.regmap = axp20x->regmap; - config.of_node = axp20x_matches[i].of_node; - rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i], &config); if (IS_ERR(rdev)) { @@ -259,7 +239,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev) return PTR_ERR(rdev); } - ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode", + ret = of_property_read_u32(rdev->dev.of_node, + "x-powers,dcdc-workmode", &workmode); if (!ret) { if (axp20x_set_dcdc_workmode(rdev, i, workmode)) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e225711bb8bc..e607bafa7c09 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -632,30 +632,6 @@ static ssize_t regulator_bypass_show(struct device *dev, static DEVICE_ATTR(bypass, 0444, regulator_bypass_show, NULL); -/* - * These are the only attributes are present for all regulators. - * Other attributes are a function of regulator functionality. - */ -static struct attribute *regulator_dev_attrs[] = { - &dev_attr_name.attr, - &dev_attr_num_users.attr, - &dev_attr_type.attr, - NULL, -}; -ATTRIBUTE_GROUPS(regulator_dev); - -static void regulator_dev_release(struct device *dev) -{ - struct regulator_dev *rdev = dev_get_drvdata(dev); - kfree(rdev); -} - -static struct class regulator_class = { - .name = "regulator", - .dev_release = regulator_dev_release, - .dev_groups = regulator_dev_groups, -}; - /* Calculate the new optimum regulator operating mode based on the new total * consumer load. All locks held by caller */ static void drms_uA_update(struct regulator_dev *rdev) @@ -1488,7 +1464,7 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_optional); -/* Locks held by regulator_put() */ +/* regulator_list_mutex lock held by regulator_put() */ static void _regulator_put(struct regulator *regulator) { struct regulator_dev *rdev; @@ -1503,12 +1479,14 @@ static void _regulator_put(struct regulator *regulator) /* remove any sysfs entries */ if (regulator->dev) sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); + mutex_lock(&rdev->mutex); kfree(regulator->supply_name); list_del(®ulator->list); kfree(regulator); rdev->open_count--; rdev->exclusive = 0; + mutex_unlock(&rdev->mutex); module_put(rdev->owner); } @@ -3434,126 +3412,136 @@ int regulator_mode_to_status(unsigned int mode) } EXPORT_SYMBOL_GPL(regulator_mode_to_status); +static struct attribute *regulator_dev_attrs[] = { + &dev_attr_name.attr, + &dev_attr_num_users.attr, + &dev_attr_type.attr, + &dev_attr_microvolts.attr, + &dev_attr_microamps.attr, + &dev_attr_opmode.attr, + &dev_attr_state.attr, + &dev_attr_status.attr, + &dev_attr_bypass.attr, + &dev_attr_requested_microamps.attr, + &dev_attr_min_microvolts.attr, + &dev_attr_max_microvolts.attr, + &dev_attr_min_microamps.attr, + &dev_attr_max_microamps.attr, + &dev_attr_suspend_standby_state.attr, + &dev_attr_suspend_mem_state.attr, + &dev_attr_suspend_disk_state.attr, + &dev_attr_suspend_standby_microvolts.attr, + &dev_attr_suspend_mem_microvolts.attr, + &dev_attr_suspend_disk_microvolts.attr, + &dev_attr_suspend_standby_mode.attr, + &dev_attr_suspend_mem_mode.attr, + &dev_attr_suspend_disk_mode.attr, + NULL +}; + /* * To avoid cluttering sysfs (and memory) with useless state, only * create attributes that can be meaningfully displayed. */ -static int add_regulator_attributes(struct regulator_dev *rdev) +static umode_t regulator_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int idx) { - struct device *dev = &rdev->dev; + struct device *dev = kobj_to_dev(kobj); + struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev); const struct regulator_ops *ops = rdev->desc->ops; - int status = 0; + umode_t mode = attr->mode; + + /* these three are always present */ + if (attr == &dev_attr_name.attr || + attr == &dev_attr_num_users.attr || + attr == &dev_attr_type.attr) + return mode; /* some attributes need specific methods to be displayed */ - if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || - (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || - (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || - (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1))) { - status = device_create_file(dev, &dev_attr_microvolts); - if (status < 0) - return status; - } - if (ops->get_current_limit) { - status = device_create_file(dev, &dev_attr_microamps); - if (status < 0) - return status; - } - if (ops->get_mode) { - status = device_create_file(dev, &dev_attr_opmode); - if (status < 0) - return status; - } - if (rdev->ena_pin || ops->is_enabled) { - status = device_create_file(dev, &dev_attr_state); - if (status < 0) - return status; - } - if (ops->get_status) { - status = device_create_file(dev, &dev_attr_status); - if (status < 0) - return status; - } - if (ops->get_bypass) { - status = device_create_file(dev, &dev_attr_bypass); - if (status < 0) - return status; + if (attr == &dev_attr_microvolts.attr) { + if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || + (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || + (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || + (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)) + return mode; + return 0; } + if (attr == &dev_attr_microamps.attr) + return ops->get_current_limit ? mode : 0; + + if (attr == &dev_attr_opmode.attr) + return ops->get_mode ? mode : 0; + + if (attr == &dev_attr_state.attr) + return (rdev->ena_pin || ops->is_enabled) ? mode : 0; + + if (attr == &dev_attr_status.attr) + return ops->get_status ? mode : 0; + + if (attr == &dev_attr_bypass.attr) + return ops->get_bypass ? mode : 0; + /* some attributes are type-specific */ - if (rdev->desc->type == REGULATOR_CURRENT) { - status = device_create_file(dev, &dev_attr_requested_microamps); - if (status < 0) - return status; - } + if (attr == &dev_attr_requested_microamps.attr) + return rdev->desc->type == REGULATOR_CURRENT ? mode : 0; /* all the other attributes exist to support constraints; * don't show them if there are no constraints, or if the * relevant supporting methods are missing. */ if (!rdev->constraints) - return status; + return 0; /* constraints need specific supporting methods */ - if (ops->set_voltage || ops->set_voltage_sel) { - status = device_create_file(dev, &dev_attr_min_microvolts); - if (status < 0) - return status; - status = device_create_file(dev, &dev_attr_max_microvolts); - if (status < 0) - return status; - } - if (ops->set_current_limit) { - status = device_create_file(dev, &dev_attr_min_microamps); - if (status < 0) - return status; - status = device_create_file(dev, &dev_attr_max_microamps); - if (status < 0) - return status; - } - - status = device_create_file(dev, &dev_attr_suspend_standby_state); - if (status < 0) - return status; - status = device_create_file(dev, &dev_attr_suspend_mem_state); - if (status < 0) - return status; - status = device_create_file(dev, &dev_attr_suspend_disk_state); - if (status < 0) - return status; + if (attr == &dev_attr_min_microvolts.attr || + attr == &dev_attr_max_microvolts.attr) + return (ops->set_voltage || ops->set_voltage_sel) ? mode : 0; + + if (attr == &dev_attr_min_microamps.attr || + attr == &dev_attr_max_microamps.attr) + return ops->set_current_limit ? mode : 0; + + if (attr == &dev_attr_suspend_standby_state.attr || + attr == &dev_attr_suspend_mem_state.attr || + attr == &dev_attr_suspend_disk_state.attr) + return mode; + + if (attr == &dev_attr_suspend_standby_microvolts.attr || + attr == &dev_attr_suspend_mem_microvolts.attr || + attr == &dev_attr_suspend_disk_microvolts.attr) + return ops->set_suspend_voltage ? mode : 0; + + if (attr == &dev_attr_suspend_standby_mode.attr || + attr == &dev_attr_suspend_mem_mode.attr || + attr == &dev_attr_suspend_disk_mode.attr) + return ops->set_suspend_mode ? mode : 0; + + return mode; +} + +static const struct attribute_group regulator_dev_group = { + .attrs = regulator_dev_attrs, + .is_visible = regulator_attr_is_visible, +}; + +static const struct attribute_group *regulator_dev_groups[] = { + ®ulator_dev_group, + NULL +}; - if (ops->set_suspend_voltage) { - status = device_create_file(dev, - &dev_attr_suspend_standby_microvolts); - if (status < 0) - return status; - status = device_create_file(dev, - &dev_attr_suspend_mem_microvolts); - if (status < 0) - return status; - status = device_create_file(dev, - &dev_attr_suspend_disk_microvolts); - if (status < 0) - return status; - } - - if (ops->set_suspend_mode) { - status = device_create_file(dev, - &dev_attr_suspend_standby_mode); - if (status < 0) - return status; - status = device_create_file(dev, - &dev_attr_suspend_mem_mode); - if (status < 0) - return status; - status = device_create_file(dev, - &dev_attr_suspend_disk_mode); - if (status < 0) - return status; - } - - return status; +static void regulator_dev_release(struct device *dev) +{ + struct regulator_dev *rdev = dev_get_drvdata(dev); + kfree(rdev); } +static struct class regulator_class = { + .name = "regulator", + .dev_release = regulator_dev_release, + .dev_groups = regulator_dev_groups, +}; + static void rdev_init_debugfs(struct regulator_dev *rdev) { rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); @@ -3573,7 +3561,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) /** * regulator_register - register regulator * @regulator_desc: regulator to register - * @config: runtime configuration for regulator + * @cfg: runtime configuration for regulator * * Called by regulator drivers to register a regulator. * Returns a valid pointer to struct regulator_dev on success @@ -3581,20 +3569,21 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) */ struct regulator_dev * regulator_register(const struct regulator_desc *regulator_desc, - const struct regulator_config *config) + const struct regulator_config *cfg) { const struct regulation_constraints *constraints = NULL; const struct regulator_init_data *init_data; - static atomic_t regulator_no = ATOMIC_INIT(0); + struct regulator_config *config = NULL; + static atomic_t regulator_no = ATOMIC_INIT(-1); struct regulator_dev *rdev; struct device *dev; int ret, i; const char *supply = NULL; - if (regulator_desc == NULL || config == NULL) + if (regulator_desc == NULL || cfg == NULL) return ERR_PTR(-EINVAL); - dev = config->dev; + dev = cfg->dev; WARN_ON(!dev); if (regulator_desc->name == NULL || regulator_desc->ops == NULL) @@ -3624,7 +3613,17 @@ regulator_register(const struct regulator_desc *regulator_desc, if (rdev == NULL) return ERR_PTR(-ENOMEM); - init_data = regulator_of_get_init_data(dev, regulator_desc, + /* + * Duplicate the config so the driver could override it after + * parsing init data. + */ + config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL); + if (config == NULL) { + kfree(rdev); + return ERR_PTR(-ENOMEM); + } + + init_data = regulator_of_get_init_data(dev, regulator_desc, config, &rdev->dev.of_node); if (!init_data) { init_data = config->init_data; @@ -3658,8 +3657,8 @@ regulator_register(const struct regulator_desc *regulator_desc, /* register with sysfs */ rdev->dev.class = ®ulator_class; rdev->dev.parent = dev; - dev_set_name(&rdev->dev, "regulator.%d", - atomic_inc_return(®ulator_no) - 1); + dev_set_name(&rdev->dev, "regulator.%lu", + (unsigned long) atomic_inc_return(®ulator_no)); ret = device_register(&rdev->dev); if (ret != 0) { put_device(&rdev->dev); @@ -3692,11 +3691,6 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret < 0) goto scrub; - /* add attributes supported by this regulator */ - ret = add_regulator_attributes(rdev); - if (ret < 0) - goto scrub; - if (init_data && init_data->supply_regulator) supply = init_data->supply_regulator; else if (regulator_desc->supply_name) @@ -3752,6 +3746,7 @@ add_dev: rdev_init_debugfs(rdev); out: mutex_unlock(®ulator_list_mutex); + kfree(config); return rdev; unset_supplies: diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 6c43ab2d5121..3c25db89a021 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -147,7 +147,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; } -static int slew_rates[] = { +static const int slew_rates[] = { 64000, 32000, 16000, @@ -296,7 +296,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, return PTR_ERR_OR_ZERO(di->rdev); } -static struct regmap_config fan53555_regmap_config = { +static const struct regmap_config fan53555_regmap_config = { .reg_bits = 8, .val_bits = 8, }; diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 80ba2a35a04b..c74ac8734023 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -38,11 +38,13 @@ struct regulator { #ifdef CONFIG_OF struct regulator_init_data *regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, + struct regulator_config *config, struct device_node **node); #else static inline struct regulator_init_data * regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, + struct regulator_config *config, struct device_node **node) { return NULL; diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 91eaaf010524..24e812c48d93 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -270,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match); struct regulator_init_data *regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, + struct regulator_config *config, struct device_node **node) { struct device_node *search, *child; @@ -307,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, break; } + if (desc->of_parse_cb) { + if (desc->of_parse_cb(child, desc, config)) { + dev_err(dev, + "driver callback failed to parse DT for regulator %s\n", + child->name); + init_data = NULL; + break; + } + } + of_node_get(child); *node = child; break; diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 8364ff331a81..3ab65c62fdd5 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -768,7 +768,7 @@ static int rpm_reg_probe(struct platform_device *pdev) break; } - if (force_mode < 0) { + if (force_mode == -1) { dev_err(&pdev->dev, "invalid force mode\n"); return -EINVAL; } diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index c1444c3d84c2..ff828117798f 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -405,6 +405,40 @@ static struct regulator_ops s2mps14_reg_ops; .enable_mask = S2MPS14_ENABLE_MASK \ } +#define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \ + .name = "BUCK"#num, \ + .id = S2MPS13_BUCK##num, \ + .ops = &s2mps14_reg_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = min, \ + .uV_step = step, \ + .linear_min_sel = min_sel, \ + .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ + .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ + .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ + .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \ + .enable_mask = S2MPS14_ENABLE_MASK \ +} + +#define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \ + .name = "BUCK"#num, \ + .id = S2MPS13_BUCK##num, \ + .ops = &s2mps14_reg_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = min, \ + .uV_step = step, \ + .linear_min_sel = min_sel, \ + .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ + .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ + .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ + .enable_reg = S2MPS13_REG_B1CTRL + (num) * 2 - 1, \ + .enable_mask = S2MPS14_ENABLE_MASK \ +} + static const struct regulator_desc s2mps13_regulators[] = { regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00), regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C), @@ -452,10 +486,10 @@ static const struct regulator_desc s2mps13_regulators[] = { regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10), regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10), regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10), - regulator_desc_s2mps13_buck(7, MIN_500_MV, STEP_6_25_MV, 0x10), - regulator_desc_s2mps13_buck(8, MIN_1000_MV, STEP_12_5_MV, 0x20), - regulator_desc_s2mps13_buck(9, MIN_1000_MV, STEP_12_5_MV, 0x20), - regulator_desc_s2mps13_buck(10, MIN_500_MV, STEP_6_25_MV, 0x10), + regulator_desc_s2mps13_buck7(7, MIN_500_MV, STEP_6_25_MV, 0x10), + regulator_desc_s2mps13_buck8_10(8, MIN_1000_MV, STEP_12_5_MV, 0x20), + regulator_desc_s2mps13_buck8_10(9, MIN_1000_MV, STEP_12_5_MV, 0x20), + regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10), }; static int s2mps14_regulator_enable(struct regulator_dev *rdev) @@ -570,7 +604,7 @@ static struct regulator_ops s2mps14_reg_ops = { .enable_mask = S2MPS14_ENABLE_MASK \ } -#define regulator_desc_s2mps14_buck(num, min, step) { \ +#define regulator_desc_s2mps14_buck(num, min, step, min_sel) { \ .name = "BUCK"#num, \ .id = S2MPS14_BUCK##num, \ .ops = &s2mps14_reg_ops, \ @@ -579,7 +613,7 @@ static struct regulator_ops s2mps14_reg_ops = { .min_uV = min, \ .uV_step = step, \ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ - .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ + .linear_min_sel = min_sel, \ .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ @@ -613,11 +647,16 @@ static const struct regulator_desc s2mps14_regulators[] = { regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV), regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV), regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV), - regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV), - regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), + regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), + regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), + regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV, + S2MPS14_BUCK4_START_SEL), + regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), }; static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, |