diff --git a/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt b/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt index c58db75f959e..c3f6546ebac7 100644 --- a/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt @@ -14,8 +14,8 @@ Required Properties: - "setup-address" - contains setup register address of ABB module (ti,abb-v3) - "int-address" - contains address of interrupt register for ABB module (also see Optional properties) -- #address-cell: should be 0 -- #size-cell: should be 0 +- #address-cells: should be 0 +- #size-cells: should be 0 - clocks: should point to the clock node used by ABB module - ti,settling-time: Settling time in uSecs from SoC documentation for ABB module to settle down(target time for SR2_WTCNT_VALUE). @@ -69,7 +69,7 @@ Example #1: Simplest configuration (no efuse data, hard coded ABB table): abb_x: regulator-abb-x { compatible = "ti,abb-v1"; regulator-name = "abb_x"; - #address-cell = <0>; + #address-cells = <0>; #size-cells = <0>; reg = <0x483072f0 0x8>, <0x48306818 0x4>; reg-names = "base-address", "int-address"; @@ -89,7 +89,7 @@ Example #2: Efuse bits contain ABB mode setting (no LDO override capability) abb_y: regulator-abb-y { compatible = "ti,abb-v2"; regulator-name = "abb_y"; - #address-cell = <0>; + #address-cells = <0>; #size-cells = <0>; reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>, <0x4A002268 0x8>; reg-names = "base-address", "int-address", "efuse-address"; @@ -110,7 +110,7 @@ Example #3: Efuse bits contain ABB mode setting and LDO override capability abb_z: regulator-abb-z { compatible = "ti,abb-v2"; regulator-name = "abb_z"; - #address-cell = <0>; + #address-cells = <0>; #size-cells = <0>; reg = <0x4ae07ce4 0x8>, <0x4ae06010 0x4>, <0x4a002194 0x8>, <0x4ae0C314 0x4>; diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 000d566e32a4..a1cd0d4f8257 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -139,6 +139,74 @@ struct act8865 { int off_mask; }; +static const struct regmap_range act8600_reg_ranges[] = { + regmap_reg_range(0x00, 0x01), + regmap_reg_range(0x10, 0x10), + regmap_reg_range(0x12, 0x12), + regmap_reg_range(0x20, 0x20), + regmap_reg_range(0x22, 0x22), + regmap_reg_range(0x30, 0x30), + regmap_reg_range(0x32, 0x32), + regmap_reg_range(0x40, 0x41), + regmap_reg_range(0x50, 0x51), + regmap_reg_range(0x60, 0x61), + regmap_reg_range(0x70, 0x71), + regmap_reg_range(0x80, 0x81), + regmap_reg_range(0x91, 0x91), + regmap_reg_range(0xA1, 0xA1), + regmap_reg_range(0xA8, 0xAA), + regmap_reg_range(0xB0, 0xB0), + regmap_reg_range(0xB2, 0xB2), + regmap_reg_range(0xC1, 0xC1), +}; + +static const struct regmap_range act8600_reg_ro_ranges[] = { + regmap_reg_range(0xAA, 0xAA), + regmap_reg_range(0xC1, 0xC1), +}; + +static const struct regmap_range act8600_reg_volatile_ranges[] = { + regmap_reg_range(0x00, 0x01), + regmap_reg_range(0x12, 0x12), + regmap_reg_range(0x22, 0x22), + regmap_reg_range(0x32, 0x32), + regmap_reg_range(0x41, 0x41), + regmap_reg_range(0x51, 0x51), + regmap_reg_range(0x61, 0x61), + regmap_reg_range(0x71, 0x71), + regmap_reg_range(0x81, 0x81), + regmap_reg_range(0xA8, 0xA8), + regmap_reg_range(0xAA, 0xAA), + regmap_reg_range(0xB0, 0xB0), + regmap_reg_range(0xC1, 0xC1), +}; + +static const struct regmap_access_table act8600_write_ranges_table = { + .yes_ranges = act8600_reg_ranges, + .n_yes_ranges = ARRAY_SIZE(act8600_reg_ranges), + .no_ranges = act8600_reg_ro_ranges, + .n_no_ranges = ARRAY_SIZE(act8600_reg_ro_ranges), +}; + +static const struct regmap_access_table act8600_read_ranges_table = { + .yes_ranges = act8600_reg_ranges, + .n_yes_ranges = ARRAY_SIZE(act8600_reg_ranges), +}; + +static const struct regmap_access_table act8600_volatile_ranges_table = { + .yes_ranges = act8600_reg_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(act8600_reg_volatile_ranges), +}; + +static const struct regmap_config act8600_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xFF, + .wr_table = &act8600_write_ranges_table, + .rd_table = &act8600_read_ranges_table, + .volatile_table = &act8600_volatile_ranges_table, +}; + static const struct regmap_config act8865_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -319,7 +387,6 @@ static struct of_regulator_match act8600_matches[] = { }; static int act8865_pdata_from_dt(struct device *dev, - struct device_node **of_node, struct act8865_platform_data *pdata, unsigned long type) { @@ -370,7 +437,7 @@ static int act8865_pdata_from_dt(struct device *dev, regulator->id = i; regulator->name = matches[i].name; regulator->init_data = matches[i].init_data; - of_node[i] = matches[i].of_node; + regulator->of_node = matches[i].of_node; regulator++; } @@ -378,7 +445,6 @@ static int act8865_pdata_from_dt(struct device *dev, } #else static inline int act8865_pdata_from_dt(struct device *dev, - struct device_node **of_node, struct act8865_platform_data *pdata, unsigned long type) { @@ -386,8 +452,8 @@ static inline int act8865_pdata_from_dt(struct device *dev, } #endif -static struct regulator_init_data -*act8865_get_init_data(int id, struct act8865_platform_data *pdata) +static struct act8865_regulator_data *act8865_get_regulator_data( + int id, struct act8865_platform_data *pdata) { int i; @@ -396,7 +462,7 @@ static struct regulator_init_data for (i = 0; i < pdata->num_regulators; i++) { if (pdata->regulators[i].id == id) - return pdata->regulators[i].init_data; + return &pdata->regulators[i]; } return NULL; @@ -418,9 +484,9 @@ static int act8865_pmic_probe(struct i2c_client *client, const struct regulator_desc *regulators; struct act8865_platform_data pdata_of, *pdata; struct device *dev = &client->dev; - struct device_node **of_node; int i, ret, num_regulators; struct act8865 *act8865; + const struct regmap_config *regmap_config; unsigned long type; int off_reg, off_mask; int voltage_select = 0; @@ -447,12 +513,14 @@ static int act8865_pmic_probe(struct i2c_client *client, case ACT8600: regulators = act8600_regulators; num_regulators = ARRAY_SIZE(act8600_regulators); + regmap_config = &act8600_regmap_config; off_reg = -1; off_mask = -1; break; case ACT8846: regulators = act8846_regulators; num_regulators = ARRAY_SIZE(act8846_regulators); + regmap_config = &act8865_regmap_config; off_reg = ACT8846_GLB_OFF_CTRL; off_mask = ACT8846_OFF_SYSMASK; break; @@ -464,6 +532,7 @@ static int act8865_pmic_probe(struct i2c_client *client, regulators = act8865_regulators; num_regulators = ARRAY_SIZE(act8865_regulators); } + regmap_config = &act8865_regmap_config; off_reg = ACT8865_SYS_CTRL; off_mask = ACT8865_MSTROFF; break; @@ -472,34 +541,22 @@ static int act8865_pmic_probe(struct i2c_client *client, return -EINVAL; } - of_node = devm_kzalloc(dev, sizeof(struct device_node *) * - num_regulators, GFP_KERNEL); - if (!of_node) - return -ENOMEM; - if (dev->of_node && !pdata) { - ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, type); + ret = act8865_pdata_from_dt(dev, &pdata_of, type); if (ret < 0) return ret; pdata = &pdata_of; } - if (pdata->num_regulators > num_regulators) { - dev_err(dev, "too many regulators: %d\n", - pdata->num_regulators); - return -EINVAL; - } - act8865 = devm_kzalloc(dev, sizeof(struct act8865), GFP_KERNEL); if (!act8865) return -ENOMEM; - act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); + act8865->regmap = devm_regmap_init_i2c(client, regmap_config); if (IS_ERR(act8865->regmap)) { ret = PTR_ERR(act8865->regmap); - dev_err(&client->dev, "Failed to allocate register map: %d\n", - ret); + dev_err(dev, "Failed to allocate register map: %d\n", ret); return ret; } @@ -518,15 +575,20 @@ static int act8865_pmic_probe(struct i2c_client *client, for (i = 0; i < num_regulators; i++) { const struct regulator_desc *desc = ®ulators[i]; struct regulator_config config = { }; + struct act8865_regulator_data *rdata; struct regulator_dev *rdev; config.dev = dev; - config.init_data = act8865_get_init_data(desc->id, pdata); - config.of_node = of_node[i]; config.driver_data = act8865; config.regmap = act8865->regmap; - rdev = devm_regulator_register(&client->dev, desc, &config); + rdata = act8865_get_regulator_data(desc->id, pdata); + if (rdata) { + config.init_data = rdata->init_data; + config.of_node = rdata->of_node; + } + + rdev = devm_regulator_register(dev, desc, &config); if (IS_ERR(rdev)) { dev_err(dev, "failed to register %s\n", desc->name); return PTR_ERR(rdev); @@ -534,7 +596,6 @@ static int act8865_pmic_probe(struct i2c_client *client, } i2c_set_clientdata(client, act8865); - devm_kfree(dev, of_node); return 0; } diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 8b046eec6ae0..66337e12719b 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -372,7 +372,7 @@ static int as3722_ldo_set_current_limit(struct regulator_dev *rdev, AS3722_LDO_ILIMIT_MASK, reg); } -static struct regulator_ops as3722_ldo0_ops = { +static const struct regulator_ops as3722_ldo0_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -383,7 +383,7 @@ static struct regulator_ops as3722_ldo0_ops = { .set_current_limit = as3722_ldo_set_current_limit, }; -static struct regulator_ops as3722_ldo0_extcntrl_ops = { +static const struct regulator_ops as3722_ldo0_extcntrl_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -415,7 +415,7 @@ static int as3722_ldo3_get_current_limit(struct regulator_dev *rdev) return 150000; } -static struct regulator_ops as3722_ldo3_ops = { +static const struct regulator_ops as3722_ldo3_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -425,20 +425,45 @@ static struct regulator_ops as3722_ldo3_ops = { .get_current_limit = as3722_ldo3_get_current_limit, }; -static struct regulator_ops as3722_ldo3_extcntrl_ops = { +static const struct regulator_ops as3722_ldo3_extcntrl_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_current_limit = as3722_ldo3_get_current_limit, }; +static const struct regulator_ops as3722_ldo6_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .get_current_limit = as3722_ldo_get_current_limit, + .set_current_limit = as3722_ldo_set_current_limit, + .get_bypass = regulator_get_bypass_regmap, + .set_bypass = regulator_set_bypass_regmap, +}; + +static const struct regulator_ops as3722_ldo6_extcntrl_ops = { + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .get_current_limit = as3722_ldo_get_current_limit, + .set_current_limit = as3722_ldo_set_current_limit, + .get_bypass = regulator_get_bypass_regmap, + .set_bypass = regulator_set_bypass_regmap, +}; + 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), }; -static struct regulator_ops as3722_ldo_ops = { +static const struct regulator_ops as3722_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -450,7 +475,7 @@ static struct regulator_ops as3722_ldo_ops = { .set_current_limit = as3722_ldo_set_current_limit, }; -static struct regulator_ops as3722_ldo_extcntrl_ops = { +static const struct regulator_ops as3722_ldo_extcntrl_ops = { .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -616,7 +641,7 @@ static const struct regulator_linear_range as3722_sd2345_ranges[] = { REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000), }; -static struct regulator_ops as3722_sd016_ops = { +static const struct regulator_ops as3722_sd016_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -630,7 +655,7 @@ static struct regulator_ops as3722_sd016_ops = { .set_mode = as3722_sd_set_mode, }; -static struct regulator_ops as3722_sd016_extcntrl_ops = { +static const struct regulator_ops as3722_sd016_extcntrl_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -641,7 +666,7 @@ static struct regulator_ops as3722_sd016_extcntrl_ops = { .set_mode = as3722_sd_set_mode, }; -static struct regulator_ops as3722_sd2345_ops = { +static const struct regulator_ops as3722_sd2345_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -653,7 +678,7 @@ static struct regulator_ops as3722_sd2345_ops = { .set_mode = as3722_sd_set_mode, }; -static struct regulator_ops as3722_sd2345_extcntrl_ops = { +static const struct regulator_ops as3722_sd2345_extcntrl_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -760,7 +785,7 @@ static int as3722_regulator_probe(struct platform_device *pdev) struct as3722_regulator_config_data *reg_config; struct regulator_dev *rdev; struct regulator_config config = { }; - struct regulator_ops *ops; + const struct regulator_ops *ops; int id; int ret; @@ -829,6 +854,24 @@ static int as3722_regulator_probe(struct platform_device *pdev) } } break; + case AS3722_REGULATOR_ID_LDO6: + if (reg_config->ext_control) + ops = &as3722_ldo6_extcntrl_ops; + else + ops = &as3722_ldo6_ops; + as3722_regs->desc[id].enable_time = 500; + as3722_regs->desc[id].bypass_reg = + AS3722_LDO6_VOLTAGE_REG; + as3722_regs->desc[id].bypass_mask = + AS3722_LDO_VSEL_MASK; + as3722_regs->desc[id].bypass_val_on = + AS3722_LDO6_VSEL_BYPASS; + as3722_regs->desc[id].bypass_val_off = + AS3722_LDO6_VSEL_BYPASS; + as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges; + as3722_regs->desc[id].n_linear_ranges = + ARRAY_SIZE(as3722_ldo_ranges); + break; case AS3722_REGULATOR_ID_SD0: case AS3722_REGULATOR_ID_SD1: case AS3722_REGULATOR_ID_SD6: diff --git a/include/linux/mfd/as3722.h b/include/linux/mfd/as3722.h index 8d43e9f2a842..51e6f9414575 100644 --- a/include/linux/mfd/as3722.h +++ b/include/linux/mfd/as3722.h @@ -196,6 +196,7 @@ #define AS3722_LDO3_VSEL_MIN 0x01 #define AS3722_LDO3_VSEL_MAX 0x2D #define AS3722_LDO3_NUM_VOLT 0x2D +#define AS3722_LDO6_VSEL_BYPASS 0x3F #define AS3722_LDO_VSEL_MASK 0x7F #define AS3722_LDO_VSEL_MIN 0x01 #define AS3722_LDO_VSEL_MAX 0x7F diff --git a/include/linux/regulator/act8865.h b/include/linux/regulator/act8865.h index 2eb386017fa5..113d861a1e4c 100644 --- a/include/linux/regulator/act8865.h +++ b/include/linux/regulator/act8865.h @@ -69,11 +69,13 @@ enum { * @id: regulator id * @name: regulator name * @init_data: regulator init data + * @of_node: device tree node (optional) */ struct act8865_regulator_data { int id; const char *name; struct regulator_init_data *init_data; + struct device_node *of_node; }; /**