1
0
Fork 0

Merge branch 'regulator-5.2' into regulator-next

hifive-unleashed-5.2
Mark Brown 2019-05-06 22:52:14 +09:00
commit e2a23affe6
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
89 changed files with 1334 additions and 2781 deletions

View File

@ -4,16 +4,30 @@ Required properties:
- compatible : Must be "regulator-gpio".
- regulator-name : Defined in regulator.txt as optional, but required
here.
- states : Selection of available voltages and GPIO configs.
if there are no states, then use a fixed regulator
- gpios : Array of one or more GPIO pins used to select the
regulator voltage/current listed in "states".
- states : Selection of available voltages/currents provided by
this regulator and matching GPIO configurations to
achieve them. If there are no states in the "states"
array, use a fixed regulator instead.
Optional properties:
- enable-gpio : GPIO to use to enable/disable the regulator.
- gpios : GPIO group used to control voltage.
- gpios-states : gpios pin's initial states array. 0: LOW, 1: HIGH.
defualt is LOW if nothing is specified.
- enable-gpios : GPIO used to enable/disable the regulator.
Warning, the GPIO phandle flags are ignored and the
GPIO polarity is controlled solely by the presence
of "enable-active-high" DT property. This is due to
compatibility with old DTs.
- enable-active-high : Polarity of "enable-gpio" GPIO is active HIGH.
Default is active LOW.
- gpios-states : On operating systems, that don't support reading back
gpio values in output mode (most notably linux), this
array provides the state of GPIO pins set when
requesting them from the gpio controller. Systems,
that are capable of preserving state when requesting
the lines, are free to ignore this property.
0: LOW, 1: HIGH. Default is LOW if nothing else
is specified.
- startup-delay-us : Startup time in microseconds.
- enable-active-high : Polarity of GPIO is active high (default is low).
- regulator-type : Specifies what is being regulated, must be either
"voltage" or "current", defaults to voltage.
@ -30,7 +44,7 @@ Example:
regulator-max-microvolt = <2600000>;
regulator-boot-on;
enable-gpio = <&gpio0 23 0x4>;
enable-gpios = <&gpio0 23 0x4>;
gpios = <&gpio0 24 0x4
&gpio0 25 0x4>;
states = <1800000 0x3

View File

@ -0,0 +1,43 @@
STM32MP1 PWR Regulators
-----------------------
Available Regulators in STM32MP1 PWR block are:
- reg11 for regulator 1V1
- reg18 for regulator 1V8
- usb33 for the swtich USB3V3
Required properties:
- compatible: Must be "st,stm32mp1,pwr-reg"
- list of child nodes that specify the regulator reg11, reg18 or usb33
initialization data for defined regulators. The definition for each of
these nodes is defined using the standard binding for regulators found at
Documentation/devicetree/bindings/regulator/regulator.txt.
- vdd-supply: phandle to the parent supply/regulator node for vdd input
- vdd_3v3_usbfs-supply: phandle to the parent supply/regulator node for usb33
Example:
pwr_regulators: pwr@50001000 {
compatible = "st,stm32mp1,pwr-reg";
reg = <0x50001000 0x10>;
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
reg11: reg11 {
regulator-name = "reg11";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
};
reg18: reg18 {
regulator-name = "reg18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
usb33: usb33 {
regulator-name = "usb33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
};

View File

@ -34,7 +34,7 @@
/* Current settings - values are 2*2^(reg_val/4) microamps. These are
* exported since they are used by multiple drivers.
*/
int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
const unsigned int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
2,
2,
3,

View File

@ -35,12 +35,6 @@ static bool wm8400_volatile(struct device *dev, unsigned int reg)
}
}
int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data)
{
return regmap_bulk_read(wm8400->regmap, reg, data, count);
}
EXPORT_SYMBOL_GPL(wm8400_block_read);
static int wm8400_register_codec(struct wm8400 *wm8400)
{
const struct mfd_cell cell = {

View File

@ -77,11 +77,6 @@ struct pm800_regulator_info {
int max_ua;
};
struct pm800_regulators {
struct pm80x_chip *chip;
struct regmap *map;
};
/*
* vreg - the buck regs string.
* ereg - the string for the enable register.
@ -235,7 +230,6 @@ static int pm800_regulator_probe(struct platform_device *pdev)
{
struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent);
struct pm800_regulators *pm800_data;
struct regulator_config config = { };
struct regulator_init_data *init_data;
int i, ret;
@ -252,18 +246,8 @@ static int pm800_regulator_probe(struct platform_device *pdev)
return -EINVAL;
}
pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data),
GFP_KERNEL);
if (!pm800_data)
return -ENOMEM;
pm800_data->map = chip->subchip->regmap_power;
pm800_data->chip = chip;
platform_set_drvdata(pdev, pm800_data);
config.dev = chip->dev;
config.regmap = pm800_data->map;
config.regmap = chip->subchip->regmap_power;
for (i = 0; i < PM800_ID_RG_MAX; i++) {
struct regulator_dev *regulator;

View File

@ -235,6 +235,8 @@ static const struct regulator_ops pm8606_preg_ops = {
{ \
.desc = { \
.name = "PREG", \
.of_match = of_match_ptr("PREG"), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &pm8606_preg_ops, \
.type = REGULATOR_CURRENT, \
.id = PM8606_ID_PREG, \
@ -249,6 +251,8 @@ static const struct regulator_ops pm8606_preg_ops = {
{ \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(#vreg), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &pm8607_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = PM8607_ID_##vreg, \
@ -270,6 +274,8 @@ static const struct regulator_ops pm8606_preg_ops = {
{ \
.desc = { \
.name = "LDO" #_id, \
.of_match = of_match_ptr("LDO" #_id), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &pm8607_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = PM8607_ID_LDO##_id, \
@ -309,36 +315,6 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = {
PM8606_PREG(PREREGULATORB, 5),
};
#ifdef CONFIG_OF
static int pm8607_regulator_dt_init(struct platform_device *pdev,
struct pm8607_regulator_info *info,
struct regulator_config *config)
{
struct device_node *nproot, *np;
nproot = pdev->dev.parent->of_node;
if (!nproot)
return -ENODEV;
nproot = of_get_child_by_name(nproot, "regulators");
if (!nproot) {
dev_err(&pdev->dev, "failed to find regulators node\n");
return -ENODEV;
}
for_each_child_of_node(nproot, np) {
if (of_node_name_eq(np, info->desc.name)) {
config->init_data =
of_get_regulator_init_data(&pdev->dev, np,
&info->desc);
config->of_node = np;
break;
}
}
of_node_put(nproot);
return 0;
}
#else
#define pm8607_regulator_dt_init(x, y, z) (-1)
#endif
static int pm8607_regulator_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@ -373,12 +349,11 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
if ((i == PM8607_ID_BUCK3) && chip->buck3_double)
info->slope_double = 1;
config.dev = &pdev->dev;
config.dev = chip->dev;
config.driver_data = info;
if (pm8607_regulator_dt_init(pdev, info, &config))
if (pdata)
config.init_data = pdata;
if (pdata)
config.init_data = pdata;
if (chip->id == CHIP_PM8607)
config.regmap = chip->regmap;

View File

@ -223,6 +223,7 @@ config REGULATOR_CPCAP
config REGULATOR_DA903X
tristate "Dialog Semiconductor DA9030/DA9034 regulators"
depends on PMIC_DA903X
depends on !CC_IS_CLANG # https://bugs.llvm.org/show_bug.cgi?id=38789
help
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
@ -839,6 +840,13 @@ config REGULATOR_STM32_VREFBUF
This driver can also be built as a module. If so, the module
will be called stm32-vrefbuf.
config REGULATOR_STM32_PWR
bool "STMicroelectronics STM32 PWR"
depends on ARCH_STM32 || COMPILE_TEST
help
This driver supports internal regulators (1V1, 1V8, 3V3) in the
STMicroelectronics STM32 chips.
config REGULATOR_STPMIC1
tristate "STMicroelectronics STPMIC1 PMIC Regulators"
depends on MFD_STPMIC1
@ -1010,7 +1018,8 @@ config REGULATOR_TWL4030
config REGULATOR_UNIPHIER
tristate "UniPhier regulator driver"
depends on ARCH_UNIPHIER || COMPILE_TEST
depends on OF && MFD_SYSCON
depends on OF
select REGMAP_MMIO
default ARCH_UNIPHIER
help
Support for regulators implemented on Socionext UniPhier SoCs.

View File

@ -105,6 +105,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o

View File

@ -48,7 +48,6 @@
* @regreg: regulator register number in the AB3100
*/
struct ab3100_regulator {
struct regulator_dev *rdev;
struct device *dev;
struct ab3100_platform_data *plfdata;
u8 regreg;
@ -354,14 +353,13 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
return 0;
}
static struct regulator_ops regulator_ops_fixed = {
.list_voltage = regulator_list_voltage_linear,
static const struct regulator_ops regulator_ops_fixed = {
.enable = ab3100_enable_regulator,
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
};
static struct regulator_ops regulator_ops_variable = {
static const struct regulator_ops regulator_ops_variable = {
.enable = ab3100_enable_regulator,
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
@ -370,7 +368,7 @@ static struct regulator_ops regulator_ops_variable = {
.list_voltage = regulator_list_voltage_table,
};
static struct regulator_ops regulator_ops_variable_sleepable = {
static const struct regulator_ops regulator_ops_variable_sleepable = {
.enable = ab3100_enable_regulator,
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
@ -386,14 +384,14 @@ static struct regulator_ops regulator_ops_variable_sleepable = {
* is an on/off switch plain an simple. The external
* voltage is defined in the board set-up if any.
*/
static struct regulator_ops regulator_ops_external = {
static const struct regulator_ops regulator_ops_external = {
.enable = ab3100_enable_regulator,
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_voltage_regulator_external,
};
static struct regulator_desc
static const struct regulator_desc
ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
{
.name = "LDO_A",
@ -402,7 +400,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
.n_voltages = 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = LDO_A_VOLTAGE,
.fixed_uV = LDO_A_VOLTAGE,
.enable_time = 200,
},
{
@ -412,7 +410,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
.n_voltages = 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = LDO_C_VOLTAGE,
.fixed_uV = LDO_C_VOLTAGE,
.enable_time = 200,
},
{
@ -422,7 +420,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
.n_voltages = 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = LDO_D_VOLTAGE,
.fixed_uV = LDO_D_VOLTAGE,
.enable_time = 200,
},
{
@ -500,7 +498,7 @@ static int ab3100_regulator_register(struct platform_device *pdev,
struct device_node *np,
unsigned long id)
{
struct regulator_desc *desc;
const struct regulator_desc *desc;
struct ab3100_regulator *reg;
struct regulator_dev *rdev;
struct regulator_config config = { };
@ -545,8 +543,6 @@ static int ab3100_regulator_register(struct platform_device *pdev,
return err;
}
/* Then set a pointer back to the registered regulator */
reg->rdev = rdev;
return 0;
}
@ -609,18 +605,6 @@ static const u8 ab3100_reg_initvals[] = {
LDO_D_SETTING,
};
static int ab3100_regulators_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];
reg->rdev = NULL;
}
return 0;
}
static int
ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
{
@ -647,10 +631,8 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
pdev, NULL, ab3100_regulator_matches[i].init_data,
ab3100_regulator_matches[i].of_node,
(unsigned long)ab3100_regulator_matches[i].driver_data);
if (err) {
ab3100_regulators_remove(pdev);
if (err)
return err;
}
}
return 0;
@ -705,14 +687,12 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
/* Register the regulators */
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct regulator_desc *desc = &ab3100_regulator_desc[i];
const struct regulator_desc *desc = &ab3100_regulator_desc[i];
err = ab3100_regulator_register(pdev, plfdata, NULL, NULL,
desc->id);
if (err) {
ab3100_regulators_remove(pdev);
if (err)
return err;
}
}
return 0;
@ -723,7 +703,6 @@ static struct platform_driver ab3100_regulators_driver = {
.name = "ab3100-regulators",
},
.probe = ab3100_regulators_probe,
.remove = ab3100_regulators_remove,
};
static __init int ab3100_regulators_init(void)

View File

@ -479,7 +479,6 @@ static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = {
* struct ab8500_ext_regulator_info - ab8500 regulator information
* @dev: device pointer
* @desc: regulator description
* @rdev: regulator device
* @cfg: regulator configuration (extension of regulator FW configuration)
* @update_bank: bank to control on/off
* @update_reg: register to control on/off
@ -495,7 +494,6 @@ static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = {
struct ab8500_ext_regulator_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_dev *rdev;
struct ab8500_ext_regulator_cfg *cfg;
u8 update_bank;
u8 update_reg;
@ -530,7 +528,7 @@ static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
info->update_bank, info->update_reg,
info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(info->rdev),
dev_err(rdev_get_dev(rdev),
"couldn't set enable bits for regulator\n");
return ret;
}
@ -566,7 +564,7 @@ static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
info->update_bank, info->update_reg,
info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(info->rdev),
dev_err(rdev_get_dev(rdev),
"couldn't set disable bits for regulator\n");
return ret;
}
@ -720,7 +718,7 @@ static int ab8500_ext_list_voltage(struct regulator_dev *rdev,
return -EINVAL;
}
static struct regulator_ops ab8500_ext_regulator_ops = {
static const struct regulator_ops ab8500_ext_regulator_ops = {
.enable = ab8500_ext_regulator_enable,
.disable = ab8500_ext_regulator_disable,
.is_enabled = ab8500_ext_regulator_is_enabled,
@ -735,6 +733,7 @@ static struct ab8500_ext_regulator_info
[AB8500_EXT_SUPPLY1] = {
.desc = {
.name = "VEXTSUPPLY1",
.of_match = of_match_ptr("ab8500_ext1"),
.ops = &ab8500_ext_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_EXT_SUPPLY1,
@ -752,6 +751,7 @@ static struct ab8500_ext_regulator_info
[AB8500_EXT_SUPPLY2] = {
.desc = {
.name = "VEXTSUPPLY2",
.of_match = of_match_ptr("ab8500_ext2"),
.ops = &ab8500_ext_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_EXT_SUPPLY2,
@ -769,6 +769,7 @@ static struct ab8500_ext_regulator_info
[AB8500_EXT_SUPPLY3] = {
.desc = {
.name = "VEXTSUPPLY3",
.of_match = of_match_ptr("ab8500_ext3"),
.ops = &ab8500_ext_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_EXT_SUPPLY3,
@ -785,30 +786,13 @@ static struct ab8500_ext_regulator_info
},
};
static struct of_regulator_match ab8500_ext_regulator_match[] = {
{ .name = "ab8500_ext1", .driver_data = (void *) AB8500_EXT_SUPPLY1, },
{ .name = "ab8500_ext2", .driver_data = (void *) AB8500_EXT_SUPPLY2, },
{ .name = "ab8500_ext3", .driver_data = (void *) AB8500_EXT_SUPPLY3, },
};
static int ab8500_ext_regulator_probe(struct platform_device *pdev)
{
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct ab8500_regulator_platform_data *pdata = &ab8500_regulator_plat_data;
struct device_node *np = pdev->dev.of_node;
struct regulator_config config = { };
int i, err;
if (np) {
err = of_regulator_match(&pdev->dev, np,
ab8500_ext_regulator_match,
ARRAY_SIZE(ab8500_ext_regulator_match));
if (err < 0) {
dev_err(&pdev->dev,
"Error parsing regulator init data: %d\n", err);
return err;
}
}
struct regulator_dev *rdev;
int i;
if (!ab8500) {
dev_err(&pdev->dev, "null mfd parent\n");
@ -844,23 +828,18 @@ static int ab8500_ext_regulator_probe(struct platform_device *pdev)
config.dev = &pdev->dev;
config.driver_data = info;
config.of_node = ab8500_ext_regulator_match[i].of_node;
config.init_data = (np) ?
ab8500_ext_regulator_match[i].init_data :
&pdata->ext_regulator[i];
config.init_data = &pdata->ext_regulator[i];
/* register regulator with framework */
info->rdev = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev);
rdev = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
return err;
return PTR_ERR(rdev);
}
dev_dbg(rdev_get_dev(info->rdev),
"%s-probed\n", info->desc.name);
dev_dbg(&pdev->dev, "%s-probed\n", info->desc.name);
}
return 0;

View File

@ -44,7 +44,6 @@ struct ab8500_shared_mode {
* struct ab8500_regulator_info - ab8500 regulator information
* @dev: device pointer
* @desc: regulator description
* @regulator_dev: regulator device
* @shared_mode: used when mode is shared between two regulators
* @load_lp_uA: maximum load in idle (low power) mode
* @update_bank: bank to control on/off
@ -65,7 +64,6 @@ struct ab8500_shared_mode {
struct ab8500_regulator_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_dev *regulator;
struct ab8500_shared_mode *shared_mode;
int load_lp_uA;
u8 update_bank;
@ -510,7 +508,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
return ret;
}
static struct regulator_ops ab8500_regulator_volt_mode_ops = {
static const struct regulator_ops ab8500_regulator_volt_mode_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
@ -522,7 +520,7 @@ static struct regulator_ops ab8500_regulator_volt_mode_ops = {
.list_voltage = regulator_list_voltage_table,
};
static struct regulator_ops ab8500_regulator_volt_ops = {
static const struct regulator_ops ab8500_regulator_volt_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
@ -531,7 +529,7 @@ static struct regulator_ops ab8500_regulator_volt_ops = {
.list_voltage = regulator_list_voltage_table,
};
static struct regulator_ops ab8500_regulator_mode_ops = {
static const struct regulator_ops ab8500_regulator_mode_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
@ -541,14 +539,14 @@ static struct regulator_ops ab8500_regulator_mode_ops = {
.list_voltage = regulator_list_voltage_table,
};
static struct regulator_ops ab8500_regulator_ops = {
static const struct regulator_ops ab8500_regulator_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
.list_voltage = regulator_list_voltage_table,
};
static struct regulator_ops ab8500_regulator_anamic_mode_ops = {
static const struct regulator_ops ab8500_regulator_anamic_mode_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
@ -1600,6 +1598,7 @@ static int ab8500_regulator_register(struct platform_device *pdev,
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct ab8500_regulator_info *info = NULL;
struct regulator_config config = { };
struct regulator_dev *rdev;
/* assign per-regulator data */
info = &abx500_regulator.info[id];
@ -1621,12 +1620,11 @@ static int ab8500_regulator_register(struct platform_device *pdev,
}
/* register regulator with framework */
info->regulator = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(info->regulator)) {
rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
return PTR_ERR(info->regulator);
return PTR_ERR(rdev);
}
return 0;

View File

@ -226,7 +226,7 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0),
};
static struct regulator_ops act8865_ops = {
static const struct regulator_ops act8865_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -236,7 +236,7 @@ static struct regulator_ops act8865_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_ops act8865_ldo_ops = {
static const struct regulator_ops act8865_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -245,6 +245,8 @@ static struct regulator_ops act8865_ldo_ops = {
#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \
[_family##_ID_##_id] = { \
.name = _name, \
.of_match = of_match_ptr(_name), \
.regulators_node = of_match_ptr("regulators"), \
.supply_name = _supply, \
.id = _family##_ID_##_id, \
.type = REGULATOR_VOLTAGE, \
@ -265,6 +267,8 @@ static const struct regulator_desc act8600_regulators[] = {
ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET, "vp3"),
{
.name = "SUDCDC_REG4",
.of_match = of_match_ptr("SUDCDC_REG4"),
.regulators_node = of_match_ptr("regulators"),
.id = ACT8600_ID_SUDCDC4,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
@ -283,6 +287,8 @@ static const struct regulator_desc act8600_regulators[] = {
ACT88xx_REG("LDO8", ACT8600, LDO8, VSET, "inl"),
{
.name = "LDO_REG9",
.of_match = of_match_ptr("LDO_REG9"),
.regulators_node = of_match_ptr("regulators"),
.id = ACT8600_ID_LDO9,
.ops = &act8865_ldo_ops,
.type = REGULATOR_VOLTAGE,
@ -294,6 +300,8 @@ static const struct regulator_desc act8600_regulators[] = {
},
{
.name = "LDO_REG10",
.of_match = of_match_ptr("LDO_REG10"),
.regulators_node = of_match_ptr("regulators"),
.id = ACT8600_ID_LDO10,
.ops = &act8865_ldo_ops,
.type = REGULATOR_VOLTAGE,
@ -348,110 +356,6 @@ static const struct of_device_id act8865_dt_ids[] = {
{ }
};
MODULE_DEVICE_TABLE(of, act8865_dt_ids);
static struct of_regulator_match act8846_matches[] = {
[ACT8846_ID_REG1] = { .name = "REG1" },
[ACT8846_ID_REG2] = { .name = "REG2" },
[ACT8846_ID_REG3] = { .name = "REG3" },
[ACT8846_ID_REG4] = { .name = "REG4" },
[ACT8846_ID_REG5] = { .name = "REG5" },
[ACT8846_ID_REG6] = { .name = "REG6" },
[ACT8846_ID_REG7] = { .name = "REG7" },
[ACT8846_ID_REG8] = { .name = "REG8" },
[ACT8846_ID_REG9] = { .name = "REG9" },
[ACT8846_ID_REG10] = { .name = "REG10" },
[ACT8846_ID_REG11] = { .name = "REG11" },
[ACT8846_ID_REG12] = { .name = "REG12" },
};
static struct of_regulator_match act8865_matches[] = {
[ACT8865_ID_DCDC1] = { .name = "DCDC_REG1"},
[ACT8865_ID_DCDC2] = { .name = "DCDC_REG2"},
[ACT8865_ID_DCDC3] = { .name = "DCDC_REG3"},
[ACT8865_ID_LDO1] = { .name = "LDO_REG1"},
[ACT8865_ID_LDO2] = { .name = "LDO_REG2"},
[ACT8865_ID_LDO3] = { .name = "LDO_REG3"},
[ACT8865_ID_LDO4] = { .name = "LDO_REG4"},
};
static struct of_regulator_match act8600_matches[] = {
[ACT8600_ID_DCDC1] = { .name = "DCDC_REG1"},
[ACT8600_ID_DCDC2] = { .name = "DCDC_REG2"},
[ACT8600_ID_DCDC3] = { .name = "DCDC_REG3"},
[ACT8600_ID_SUDCDC4] = { .name = "SUDCDC_REG4"},
[ACT8600_ID_LDO5] = { .name = "LDO_REG5"},
[ACT8600_ID_LDO6] = { .name = "LDO_REG6"},
[ACT8600_ID_LDO7] = { .name = "LDO_REG7"},
[ACT8600_ID_LDO8] = { .name = "LDO_REG8"},
[ACT8600_ID_LDO9] = { .name = "LDO_REG9"},
[ACT8600_ID_LDO10] = { .name = "LDO_REG10"},
};
static int act8865_pdata_from_dt(struct device *dev,
struct act8865_platform_data *pdata,
unsigned long type)
{
int matched, i, num_matches;
struct device_node *np;
struct act8865_regulator_data *regulator;
struct of_regulator_match *matches;
switch (type) {
case ACT8600:
matches = act8600_matches;
num_matches = ARRAY_SIZE(act8600_matches);
break;
case ACT8846:
matches = act8846_matches;
num_matches = ARRAY_SIZE(act8846_matches);
break;
case ACT8865:
matches = act8865_matches;
num_matches = ARRAY_SIZE(act8865_matches);
break;
default:
dev_err(dev, "invalid device id %lu\n", type);
return -EINVAL;
}
np = of_get_child_by_name(dev->of_node, "regulators");
if (!np) {
dev_err(dev, "missing 'regulators' subnode in DT\n");
return -EINVAL;
}
matched = of_regulator_match(dev, np, matches, num_matches);
of_node_put(np);
if (matched <= 0)
return matched;
pdata->regulators = devm_kcalloc(dev,
num_matches,
sizeof(struct act8865_regulator_data),
GFP_KERNEL);
if (!pdata->regulators)
return -ENOMEM;
pdata->num_regulators = num_matches;
regulator = pdata->regulators;
for (i = 0; i < num_matches; i++) {
regulator->id = i;
regulator->name = matches[i].name;
regulator->init_data = matches[i].init_data;
regulator->of_node = matches[i].of_node;
regulator++;
}
return 0;
}
#else
static inline int act8865_pdata_from_dt(struct device *dev,
struct act8865_platform_data *pdata,
unsigned long type)
{
return 0;
}
#endif
static struct act8865_regulator_data *act8865_get_regulator_data(
@ -459,9 +363,6 @@ static struct act8865_regulator_data *act8865_get_regulator_data(
{
int i;
if (!pdata)
return NULL;
for (i = 0; i < pdata->num_regulators; i++) {
if (pdata->regulators[i].id == id)
return &pdata->regulators[i];
@ -484,7 +385,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
{
const struct regulator_desc *regulators;
struct act8865_platform_data pdata_of, *pdata;
struct act8865_platform_data *pdata = NULL;
struct device *dev = &client->dev;
int i, ret, num_regulators;
struct act8865 *act8865;
@ -493,9 +394,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
int off_reg, off_mask;
int voltage_select = 0;
pdata = dev_get_platdata(dev);
if (dev->of_node && !pdata) {
if (dev->of_node) {
const struct of_device_id *id;
id = of_match_device(of_match_ptr(act8865_dt_ids), dev);
@ -509,6 +408,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
NULL);
} else {
type = i2c_id->driver_data;
pdata = dev_get_platdata(dev);
}
switch (type) {
@ -543,14 +443,6 @@ static int act8865_pmic_probe(struct i2c_client *client,
return -EINVAL;
}
if (dev->of_node && !pdata) {
ret = act8865_pdata_from_dt(dev, &pdata_of, type);
if (ret < 0)
return ret;
pdata = &pdata_of;
}
act8865 = devm_kzalloc(dev, sizeof(struct act8865), GFP_KERNEL);
if (!act8865)
return -ENOMEM;
@ -577,17 +469,20 @@ static int act8865_pmic_probe(struct i2c_client *client,
for (i = 0; i < num_regulators; i++) {
const struct regulator_desc *desc = &regulators[i];
struct regulator_config config = { };
struct act8865_regulator_data *rdata;
struct regulator_dev *rdev;
config.dev = dev;
config.driver_data = act8865;
config.regmap = act8865->regmap;
rdata = act8865_get_regulator_data(desc->id, pdata);
if (rdata) {
config.init_data = rdata->init_data;
config.of_node = rdata->of_node;
if (pdata) {
struct act8865_regulator_data *rdata;
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);

View File

@ -23,18 +23,10 @@
#define LDO_FET_FULL_ON 0x1f
struct anatop_regulator {
u32 control_reg;
struct regmap *anatop;
int vol_bit_shift;
int vol_bit_width;
u32 delay_reg;
int delay_bit_shift;
int delay_bit_width;
int min_bit_val;
int min_voltage;
int max_voltage;
struct regulator_desc rdesc;
struct regulator_init_data *initdata;
bool bypass;
int sel;
};
@ -55,7 +47,7 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg,
* to calculate how many steps LDO need to
* ramp up, and how much delay needed. (us)
*/
regmap_read(anatop_reg->anatop, anatop_reg->delay_reg, &val);
regmap_read(reg->regmap, anatop_reg->delay_reg, &val);
val = (val >> anatop_reg->delay_bit_shift) &
((1 << anatop_reg->delay_bit_width) - 1);
ret = (new_sel - old_sel) * (LDO_RAMP_UP_UNIT_IN_CYCLES <<
@ -170,6 +162,13 @@ static int anatop_regulator_probe(struct platform_device *pdev)
struct anatop_regulator *sreg;
struct regulator_init_data *initdata;
struct regulator_config config = { };
struct regmap *regmap;
u32 control_reg;
u32 vol_bit_shift;
u32 vol_bit_width;
u32 min_bit_val;
u32 min_voltage;
u32 max_voltage;
int ret = 0;
u32 val;
@ -192,48 +191,41 @@ static int anatop_regulator_probe(struct platform_device *pdev)
return -ENOMEM;
initdata->supply_regulator = "vin";
sreg->initdata = initdata;
anatop_np = of_get_parent(np);
if (!anatop_np)
return -ENODEV;
sreg->anatop = syscon_node_to_regmap(anatop_np);
regmap = syscon_node_to_regmap(anatop_np);
of_node_put(anatop_np);
if (IS_ERR(sreg->anatop))
return PTR_ERR(sreg->anatop);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
ret = of_property_read_u32(np, "anatop-reg-offset",
&sreg->control_reg);
ret = of_property_read_u32(np, "anatop-reg-offset", &control_reg);
if (ret) {
dev_err(dev, "no anatop-reg-offset property set\n");
return ret;
}
ret = of_property_read_u32(np, "anatop-vol-bit-width",
&sreg->vol_bit_width);
ret = of_property_read_u32(np, "anatop-vol-bit-width", &vol_bit_width);
if (ret) {
dev_err(dev, "no anatop-vol-bit-width property set\n");
return ret;
}
ret = of_property_read_u32(np, "anatop-vol-bit-shift",
&sreg->vol_bit_shift);
ret = of_property_read_u32(np, "anatop-vol-bit-shift", &vol_bit_shift);
if (ret) {
dev_err(dev, "no anatop-vol-bit-shift property set\n");
return ret;
}
ret = of_property_read_u32(np, "anatop-min-bit-val",
&sreg->min_bit_val);
ret = of_property_read_u32(np, "anatop-min-bit-val", &min_bit_val);
if (ret) {
dev_err(dev, "no anatop-min-bit-val property set\n");
return ret;
}
ret = of_property_read_u32(np, "anatop-min-voltage",
&sreg->min_voltage);
ret = of_property_read_u32(np, "anatop-min-voltage", &min_voltage);
if (ret) {
dev_err(dev, "no anatop-min-voltage property set\n");
return ret;
}
ret = of_property_read_u32(np, "anatop-max-voltage",
&sreg->max_voltage);
ret = of_property_read_u32(np, "anatop-max-voltage", &max_voltage);
if (ret) {
dev_err(dev, "no anatop-max-voltage property set\n");
return ret;
@ -247,24 +239,23 @@ static int anatop_regulator_probe(struct platform_device *pdev)
of_property_read_u32(np, "anatop-delay-bit-shift",
&sreg->delay_bit_shift);
rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1
+ sreg->min_bit_val;
rdesc->min_uV = sreg->min_voltage;
rdesc->n_voltages = (max_voltage - min_voltage) / 25000 + 1
+ min_bit_val;
rdesc->min_uV = min_voltage;
rdesc->uV_step = 25000;
rdesc->linear_min_sel = sreg->min_bit_val;
rdesc->vsel_reg = sreg->control_reg;
rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) <<
sreg->vol_bit_shift;
rdesc->linear_min_sel = min_bit_val;
rdesc->vsel_reg = control_reg;
rdesc->vsel_mask = ((1 << vol_bit_width) - 1) << vol_bit_shift;
rdesc->min_dropout_uV = 125000;
config.dev = &pdev->dev;
config.init_data = initdata;
config.driver_data = sreg;
config.of_node = pdev->dev.of_node;
config.regmap = sreg->anatop;
config.regmap = regmap;
/* Only core regulators have the ramp up delay configuration. */
if (sreg->control_reg && sreg->delay_bit_width) {
if (control_reg && sreg->delay_bit_width) {
rdesc->ops = &anatop_core_rops;
ret = regmap_read(config.regmap, rdesc->vsel_reg, &val);
@ -273,7 +264,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
return ret;
}
sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift;
sreg->sel = (val & rdesc->vsel_mask) >> vol_bit_shift;
if (sreg->sel == LDO_FET_FULL_ON) {
sreg->sel = 0;
sreg->bypass = true;
@ -306,7 +297,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
anatop_rops.disable = regulator_disable_regmap;
anatop_rops.is_enabled = regulator_is_enabled_regmap;
rdesc->enable_reg = sreg->control_reg;
rdesc->enable_reg = control_reg;
rdesc->enable_mask = BIT(enable_bit);
}
}

View File

@ -1,15 +1,10 @@
/*
* arizona-ldo1.c -- LDO1 supply for Arizona devices
*
* Copyright 2012 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// arizona-ldo1.c -- LDO1 supply for Arizona devices
//
// Copyright 2012 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/module.h>
#include <linux/moduleparam.h>

View File

@ -1,15 +1,10 @@
/*
* arizona-micsupp.c -- Microphone supply for Arizona devices
*
* Copyright 2012 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// arizona-micsupp.c -- Microphone supply for Arizona devices
//
// Copyright 2012 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/module.h>
#include <linux/moduleparam.h>

View File

@ -17,14 +17,6 @@
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
struct as3711_regulator_info {
struct regulator_desc desc;
};
struct as3711_regulator {
struct as3711_regulator_info *reg_info;
};
/*
* The regulator API supports 4 modes of operataion: FAST, NORMAL, IDLE and
* STANDBY. We map them in the following way to AS3711 SD1-4 DCDC modes:
@ -129,7 +121,6 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = {
#define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _sfx) \
[AS3711_REGULATOR_ ## _id] = { \
.desc = { \
.name = "as3711-regulator-" # _id, \
.id = AS3711_REGULATOR_ ## _id, \
.n_voltages = (_vmask + 1), \
@ -142,10 +133,9 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = {
.enable_mask = BIT(_en_bit), \
.linear_ranges = as3711_ ## _sfx ## _ranges, \
.n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \
}, \
}
static struct as3711_regulator_info as3711_reg_info[] = {
static const struct regulator_desc as3711_reg_desc[] = {
AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, sd),
AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, sd),
AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, sd),
@ -161,7 +151,7 @@ static struct as3711_regulator_info as3711_reg_info[] = {
/* StepUp output voltage depends on supplying regulator */
};
#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info)
#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_desc)
static struct of_regulator_match
as3711_regulator_matches[AS3711_REGULATOR_NUM] = {
@ -215,11 +205,8 @@ static int as3711_regulator_probe(struct platform_device *pdev)
struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev);
struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = {.dev = &pdev->dev,};
struct as3711_regulator *reg = NULL;
struct as3711_regulator *regs;
struct device_node *of_node[AS3711_REGULATOR_NUM] = {};
struct regulator_dev *rdev;
struct as3711_regulator_info *ri;
int ret;
int id;
@ -236,30 +223,20 @@ static int as3711_regulator_probe(struct platform_device *pdev)
}
}
regs = devm_kcalloc(&pdev->dev,
AS3711_REGULATOR_NUM,
sizeof(struct as3711_regulator),
GFP_KERNEL);
if (!regs)
return -ENOMEM;
for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) {
reg = &regs[id];
reg->reg_info = ri;
for (id = 0; id < AS3711_REGULATOR_NUM; id++) {
config.init_data = pdata->init_data[id];
config.driver_data = reg;
config.regmap = as3711->regmap;
config.of_node = of_node[id];
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &as3711_reg_desc[id],
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name);
as3711_reg_desc[id].name);
return PTR_ERR(rdev);
}
}
platform_set_drvdata(pdev, regs);
return 0;
}

View File

@ -81,7 +81,6 @@ struct as3722_regulator_config_data {
struct as3722_regulators {
struct device *dev;
struct as3722 *as3722;
struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX];
struct regulator_desc desc[AS3722_REGULATOR_ID_MAX];
struct as3722_regulator_config_data
reg_config_data[AS3722_REGULATOR_ID_MAX];
@ -314,63 +313,10 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
},
};
static const int as3722_ldo_current[] = { 150000, 300000 };
static const int as3722_sd016_current[] = { 2500000, 3000000, 3500000 };
static int as3722_current_to_index(int min_uA, int max_uA,
const int *curr_table, int n_currents)
{
int i;
for (i = n_currents - 1; i >= 0; i--) {
if ((min_uA <= curr_table[i]) && (curr_table[i] <= max_uA))
return i;
}
return -EINVAL;
}
static int as3722_ldo_get_current_limit(struct regulator_dev *rdev)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
u32 val;
int ret;
ret = as3722_read(as3722, as3722_reg_lookup[id].vsel_reg, &val);
if (ret < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
as3722_reg_lookup[id].vsel_reg, ret);
return ret;
}
if (val & AS3722_LDO_ILIMIT_MASK)
return 300000;
return 150000;
}
static int as3722_ldo_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
int ret;
u32 reg = 0;
ret = as3722_current_to_index(min_uA, max_uA, as3722_ldo_current,
ARRAY_SIZE(as3722_ldo_current));
if (ret < 0) {
dev_err(as3722_regs->dev,
"Current range min:max = %d:%d does not support\n",
min_uA, max_uA);
return ret;
}
if (ret)
reg = AS3722_LDO_ILIMIT_BIT;
return as3722_update_bits(as3722, as3722_reg_lookup[id].vsel_reg,
AS3722_LDO_ILIMIT_MASK, reg);
}
static const unsigned int as3722_ldo_current[] = { 150000, 300000 };
static const unsigned int as3722_sd016_current[] = {
2500000, 3000000, 3500000
};
static const struct regulator_ops as3722_ldo0_ops = {
.is_enabled = regulator_is_enabled_regmap,
@ -379,16 +325,16 @@ static const struct regulator_ops as3722_ldo0_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_ldo_get_current_limit,
.set_current_limit = as3722_ldo_set_current_limit,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
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,
.get_current_limit = as3722_ldo_get_current_limit,
.set_current_limit = as3722_ldo_set_current_limit,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg,
@ -440,8 +386,8 @@ static const struct regulator_ops as3722_ldo6_ops = {
.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_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
.get_bypass = regulator_get_bypass_regmap,
.set_bypass = regulator_set_bypass_regmap,
};
@ -451,8 +397,8 @@ static const struct regulator_ops as3722_ldo6_extcntrl_ops = {
.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_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
.get_bypass = regulator_get_bypass_regmap,
.set_bypass = regulator_set_bypass_regmap,
};
@ -471,8 +417,8 @@ static const struct regulator_ops as3722_ldo_ops = {
.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_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
static const struct regulator_ops as3722_ldo_extcntrl_ops = {
@ -480,8 +426,8 @@ static const struct regulator_ops as3722_ldo_extcntrl_ops = {
.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_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev)
@ -539,85 +485,6 @@ static int as3722_sd_set_mode(struct regulator_dev *rdev,
return ret;
}
static int as3722_sd016_get_current_limit(struct regulator_dev *rdev)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
u32 val, reg;
int mask;
int ret;
switch (id) {
case AS3722_REGULATOR_ID_SD0:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD1:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD6:
reg = AS3722_OVCURRENT_DEB_REG;
mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
break;
default:
return -EINVAL;
}
ret = as3722_read(as3722, reg, &val);
if (ret < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
reg, ret);
return ret;
}
val &= mask;
val >>= ffs(mask) - 1;
if (val == 3)
return -EINVAL;
return as3722_sd016_current[val];
}
static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
int ret;
int val;
int mask;
u32 reg;
ret = as3722_current_to_index(min_uA, max_uA, as3722_sd016_current,
ARRAY_SIZE(as3722_sd016_current));
if (ret < 0) {
dev_err(as3722_regs->dev,
"Current range min:max = %d:%d does not support\n",
min_uA, max_uA);
return ret;
}
switch (id) {
case AS3722_REGULATOR_ID_SD0:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD1:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD6:
reg = AS3722_OVCURRENT_DEB_REG;
mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
break;
default:
return -EINVAL;
}
ret <<= ffs(mask) - 1;
val = ret & mask;
return as3722_update_bits(as3722, reg, mask, val);
}
static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
{
int err;
@ -649,8 +516,8 @@ static const struct regulator_ops as3722_sd016_ops = {
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_sd016_get_current_limit,
.set_current_limit = as3722_sd016_set_current_limit,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
.get_mode = as3722_sd_get_mode,
.set_mode = as3722_sd_set_mode,
};
@ -660,8 +527,8 @@ static const struct regulator_ops as3722_sd016_extcntrl_ops = {
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_sd016_get_current_limit,
.set_current_limit = as3722_sd016_set_current_limit,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
.get_mode = as3722_sd_get_mode,
.set_mode = as3722_sd_set_mode,
};
@ -807,42 +674,45 @@ static int as3722_regulator_probe(struct platform_device *pdev)
config.regmap = as3722->regmap;
for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) {
struct regulator_desc *desc;
desc = &as3722_regs->desc[id];
reg_config = &as3722_regs->reg_config_data[id];
as3722_regs->desc[id].name = as3722_reg_lookup[id].name;
as3722_regs->desc[id].supply_name = as3722_reg_lookup[id].sname;
as3722_regs->desc[id].id = as3722_reg_lookup[id].regulator_id;
as3722_regs->desc[id].n_voltages =
as3722_reg_lookup[id].n_voltages;
as3722_regs->desc[id].type = REGULATOR_VOLTAGE;
as3722_regs->desc[id].owner = THIS_MODULE;
as3722_regs->desc[id].enable_reg =
as3722_reg_lookup[id].enable_reg;
as3722_regs->desc[id].enable_mask =
as3722_reg_lookup[id].enable_mask;
as3722_regs->desc[id].vsel_reg = as3722_reg_lookup[id].vsel_reg;
as3722_regs->desc[id].vsel_mask =
as3722_reg_lookup[id].vsel_mask;
desc->name = as3722_reg_lookup[id].name;
desc->supply_name = as3722_reg_lookup[id].sname;
desc->id = as3722_reg_lookup[id].regulator_id;
desc->n_voltages = as3722_reg_lookup[id].n_voltages;
desc->type = REGULATOR_VOLTAGE;
desc->owner = THIS_MODULE;
desc->enable_reg = as3722_reg_lookup[id].enable_reg;
desc->enable_mask = as3722_reg_lookup[id].enable_mask;
desc->vsel_reg = as3722_reg_lookup[id].vsel_reg;
desc->vsel_mask = as3722_reg_lookup[id].vsel_mask;
switch (id) {
case AS3722_REGULATOR_ID_LDO0:
if (reg_config->ext_control)
ops = &as3722_ldo0_extcntrl_ops;
else
ops = &as3722_ldo0_ops;
as3722_regs->desc[id].min_uV = 825000;
as3722_regs->desc[id].uV_step = 25000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500;
desc->min_uV = 825000;
desc->uV_step = 25000;
desc->linear_min_sel = 1;
desc->enable_time = 500;
desc->curr_table = as3722_ldo_current;
desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
break;
case AS3722_REGULATOR_ID_LDO3:
if (reg_config->ext_control)
ops = &as3722_ldo3_extcntrl_ops;
else
ops = &as3722_ldo3_ops;
as3722_regs->desc[id].min_uV = 620000;
as3722_regs->desc[id].uV_step = 20000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500;
desc->min_uV = 620000;
desc->uV_step = 20000;
desc->linear_min_sel = 1;
desc->enable_time = 500;
if (reg_config->enable_tracking) {
ret = as3722_ldo3_set_tracking_mode(as3722_regs,
id, AS3722_LDO3_MODE_PMOS_TRACKING);
@ -859,18 +729,17 @@ static int as3722_regulator_probe(struct platform_device *pdev)
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);
desc->enable_time = 500;
desc->bypass_reg = AS3722_LDO6_VOLTAGE_REG;
desc->bypass_mask = AS3722_LDO_VSEL_MASK;
desc->bypass_val_on = AS3722_LDO6_VSEL_BYPASS;
desc->bypass_val_off = AS3722_LDO6_VSEL_BYPASS;
desc->linear_ranges = as3722_ldo_ranges;
desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges);
desc->curr_table = as3722_ldo_current;
desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
break;
case AS3722_REGULATOR_ID_SD0:
case AS3722_REGULATOR_ID_SD1:
@ -889,9 +758,25 @@ static int as3722_regulator_probe(struct platform_device *pdev)
AS3722_SD0_VSEL_MAX + 1;
as3722_regs->desc[id].min_uV = 610000;
}
as3722_regs->desc[id].uV_step = 10000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 600;
desc->uV_step = 10000;
desc->linear_min_sel = 1;
desc->enable_time = 600;
desc->curr_table = as3722_sd016_current;
desc->n_current_limits =
ARRAY_SIZE(as3722_sd016_current);
if (id == AS3722_REGULATOR_ID_SD0) {
desc->csel_reg = AS3722_OVCURRENT_REG;
desc->csel_mask =
AS3722_OVCURRENT_SD0_TRIP_MASK;
} else if (id == AS3722_REGULATOR_ID_SD1) {
desc->csel_reg = AS3722_OVCURRENT_REG;
desc->csel_mask =
AS3722_OVCURRENT_SD1_TRIP_MASK;
} else if (id == AS3722_REGULATOR_ID_SD6) {
desc->csel_reg = AS3722_OVCURRENT_DEB_REG;
desc->csel_mask =
AS3722_OVCURRENT_SD6_TRIP_MASK;
}
break;
case AS3722_REGULATOR_ID_SD2:
case AS3722_REGULATOR_ID_SD3:
@ -901,9 +786,8 @@ static int as3722_regulator_probe(struct platform_device *pdev)
ops = &as3722_sd2345_extcntrl_ops;
else
ops = &as3722_sd2345_ops;
as3722_regs->desc[id].linear_ranges =
as3722_sd2345_ranges;
as3722_regs->desc[id].n_linear_ranges =
desc->linear_ranges = as3722_sd2345_ranges;
desc->n_linear_ranges =
ARRAY_SIZE(as3722_sd2345_ranges);
break;
default:
@ -911,17 +795,19 @@ static int as3722_regulator_probe(struct platform_device *pdev)
ops = &as3722_ldo_extcntrl_ops;
else
ops = &as3722_ldo_ops;
as3722_regs->desc[id].enable_time = 500;
as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
as3722_regs->desc[id].n_linear_ranges =
ARRAY_SIZE(as3722_ldo_ranges);
desc->enable_time = 500;
desc->linear_ranges = as3722_ldo_ranges;
desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges);
desc->curr_table = as3722_ldo_current;
desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
break;
}
as3722_regs->desc[id].ops = ops;
desc->ops = ops;
config.init_data = reg_config->reg_init;
config.of_node = as3722_regulator_matches[id].of_node;
rdev = devm_regulator_register(&pdev->dev,
&as3722_regs->desc[id], &config);
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "regulator %d register failed %d\n",
@ -929,7 +815,6 @@ static int as3722_regulator_probe(struct platform_device *pdev)
return ret;
}
as3722_regs->rdevs[id] = rdev;
if (reg_config->ext_control) {
ret = regulator_enable_regmap(rdev);
if (ret < 0) {

View File

@ -367,16 +367,14 @@ static const int axp209_dcdc2_ldo3_slew_rates[] = {
static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
{
struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
const struct regulator_desc *desc;
int id = rdev_get_id(rdev);
u8 reg, mask, enable, cfg = 0xff;
const int *slew_rates;
int rate_count = 0;
desc = rdev->desc;
switch (axp20x->variant) {
case AXP209_ID:
if (desc->id == AXP20X_DCDC2) {
if (id == AXP20X_DCDC2) {
slew_rates = axp209_dcdc2_ldo3_slew_rates;
rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates);
reg = AXP20X_DCDC2_LDO3_V_RAMP;
@ -388,7 +386,7 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
break;
}
if (desc->id == AXP20X_LDO3) {
if (id == AXP20X_LDO3) {
slew_rates = axp209_dcdc2_ldo3_slew_rates;
rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates);
reg = AXP20X_DCDC2_LDO3_V_RAMP;
@ -435,16 +433,11 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
static int axp20x_regulator_enable_regmap(struct regulator_dev *rdev)
{
struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
const struct regulator_desc *desc;
if (!rdev)
return -EINVAL;
desc = rdev->desc;
int id = rdev_get_id(rdev);
switch (axp20x->variant) {
case AXP209_ID:
if ((desc->id == AXP20X_LDO3) &&
if ((id == AXP20X_LDO3) &&
rdev->constraints && rdev->constraints->soft_start) {
int v_out;
int ret;
@ -1028,7 +1021,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
* (See include/linux/mfd/axp20x.h)
*/
reg = AXP803_DCDC_FREQ_CTRL;
/* Fall through to the check below.*/
/* Fall through - to the check below.*/
case AXP806_ID:
/*
* AXP806 also have DCDC work frequency setting register at a
@ -1119,12 +1112,12 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
break;
case AXP806_ID:
reg = AXP806_DCDC_MODE_CTRL2;
/*
* AXP806 DCDC regulator IDs have the same range as AXP22X.
* Fall through to the check below.
* (See include/linux/mfd/axp20x.h)
*/
reg = AXP806_DCDC_MODE_CTRL2;
/* Fall through - to the check below. */
case AXP221_ID:
case AXP223_ID:
case AXP809_ID:

View File

@ -103,10 +103,6 @@
((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
#define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS)
struct bcm590xx_board {
struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS];
};
/* LDO group A: supported voltages in microvolts */
static const unsigned int ldo_a_table[] = {
1200000, 1800000, 2500000, 2700000, 2800000,
@ -280,105 +276,15 @@ static const struct regulator_ops bcm590xx_ops_vbus = {
.disable = regulator_disable_regmap,
};
#define BCM590XX_MATCH(_name, _id) \
{ \
.name = #_name, \
.driver_data = (void *)&bcm590xx_regs[BCM590XX_REG_##_id], \
}
static struct of_regulator_match bcm590xx_matches[] = {
BCM590XX_MATCH(rfldo, RFLDO),
BCM590XX_MATCH(camldo1, CAMLDO1),
BCM590XX_MATCH(camldo2, CAMLDO2),
BCM590XX_MATCH(simldo1, SIMLDO1),
BCM590XX_MATCH(simldo2, SIMLDO2),
BCM590XX_MATCH(sdldo, SDLDO),
BCM590XX_MATCH(sdxldo, SDXLDO),
BCM590XX_MATCH(mmcldo1, MMCLDO1),
BCM590XX_MATCH(mmcldo2, MMCLDO2),
BCM590XX_MATCH(audldo, AUDLDO),
BCM590XX_MATCH(micldo, MICLDO),
BCM590XX_MATCH(usbldo, USBLDO),
BCM590XX_MATCH(vibldo, VIBLDO),
BCM590XX_MATCH(csr, CSR),
BCM590XX_MATCH(iosr1, IOSR1),
BCM590XX_MATCH(iosr2, IOSR2),
BCM590XX_MATCH(msr, MSR),
BCM590XX_MATCH(sdsr1, SDSR1),
BCM590XX_MATCH(sdsr2, SDSR2),
BCM590XX_MATCH(vsr, VSR),
BCM590XX_MATCH(gpldo1, GPLDO1),
BCM590XX_MATCH(gpldo2, GPLDO2),
BCM590XX_MATCH(gpldo3, GPLDO3),
BCM590XX_MATCH(gpldo4, GPLDO4),
BCM590XX_MATCH(gpldo5, GPLDO5),
BCM590XX_MATCH(gpldo6, GPLDO6),
BCM590XX_MATCH(vbus, VBUS),
};
static struct bcm590xx_board *bcm590xx_parse_dt_reg_data(
struct platform_device *pdev,
struct of_regulator_match **bcm590xx_reg_matches)
{
struct bcm590xx_board *data;
struct device_node *np = pdev->dev.parent->of_node;
struct device_node *regulators;
struct of_regulator_match *matches = bcm590xx_matches;
int count = ARRAY_SIZE(bcm590xx_matches);
int idx = 0;
int ret;
if (!np) {
dev_err(&pdev->dev, "of node not found\n");
return NULL;
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return NULL;
np = of_node_get(np);
regulators = of_get_child_by_name(np, "regulators");
if (!regulators) {
dev_warn(&pdev->dev, "regulator node not found\n");
return NULL;
}
ret = of_regulator_match(&pdev->dev, regulators, matches, count);
of_node_put(regulators);
if (ret < 0) {
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
ret);
return NULL;
}
*bcm590xx_reg_matches = matches;
for (idx = 0; idx < count; idx++) {
if (!matches[idx].init_data || !matches[idx].of_node)
continue;
data->bcm590xx_pmu_init_data[idx] = matches[idx].init_data;
}
return data;
}
static int bcm590xx_probe(struct platform_device *pdev)
{
struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent);
struct bcm590xx_board *pmu_data = NULL;
struct bcm590xx_reg *pmu;
struct regulator_config config = { };
struct bcm590xx_info *info;
struct regulator_init_data *reg_data;
struct regulator_dev *rdev;
struct of_regulator_match *bcm590xx_reg_matches = NULL;
int i;
pmu_data = bcm590xx_parse_dt_reg_data(pdev,
&bcm590xx_reg_matches);
pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
if (!pmu)
return -ENOMEM;
@ -397,13 +303,10 @@ static int bcm590xx_probe(struct platform_device *pdev)
info = bcm590xx_regs;
for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) {
if (pmu_data)
reg_data = pmu_data->bcm590xx_pmu_init_data[i];
else
reg_data = NULL;
/* Register the regulators */
pmu->desc[i].name = info->name;
pmu->desc[i].of_match = of_match_ptr(info->name);
pmu->desc[i].regulators_node = of_match_ptr("regulators");
pmu->desc[i].supply_name = info->vin_name;
pmu->desc[i].id = i;
pmu->desc[i].volt_table = info->volt_table;
@ -433,16 +336,12 @@ static int bcm590xx_probe(struct platform_device *pdev)
pmu->desc[i].owner = THIS_MODULE;
config.dev = bcm590xx->dev;
config.init_data = reg_data;
config.driver_data = pmu;
if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
config.regmap = bcm590xx->regmap_sec;
else
config.regmap = bcm590xx->regmap_pri;
if (bcm590xx_reg_matches)
config.of_node = bcm590xx_reg_matches[i].of_node;
rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i],
&config);
if (IS_ERR(rdev)) {

View File

@ -27,8 +27,8 @@
static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
int ramp_delay)
{
int id = rdev->desc->id;
unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
int id = rdev_get_id(rdev);
unsigned int ramp_value;
dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1,
ramp_delay);

View File

@ -1339,9 +1339,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
* We'll only apply the initial system load if an
* initial mode wasn't specified.
*/
regulator_lock(rdev);
drms_uA_update(rdev);
regulator_unlock(rdev);
}
if ((rdev->constraints->ramp_delay || rdev->constraints->ramp_disable)
@ -3005,7 +3003,7 @@ EXPORT_SYMBOL_GPL(regulator_get_linear_step);
* @min_uV: Minimum required voltage in uV.
* @max_uV: Maximum required voltage in uV.
*
* Returns a boolean or a negative error code.
* Returns a boolean.
*/
int regulator_is_supported_voltage(struct regulator *regulator,
int min_uV, int max_uV)
@ -3029,7 +3027,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
ret = regulator_count_voltages(regulator);
if (ret < 0)
return ret;
return 0;
voltages = ret;
for (i = 0; i < voltages; i++) {
@ -4345,8 +4343,6 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n",
consumers[i].supply, ret);
consumers[i].consumer = NULL;
goto err;
}
@ -4355,6 +4351,13 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
return 0;
err:
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get supply '%s': %d\n",
consumers[i].supply, ret);
else
dev_dbg(dev, "Failed to get supply '%s', deferring\n",
consumers[i].supply);
while (--i >= 0)
regulator_put(consumers[i].consumer);

View File

@ -505,17 +505,12 @@ MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table);
static int cpcap_regulator_probe(struct platform_device *pdev)
{
struct cpcap_ddata *ddata;
const struct of_device_id *match;
const struct cpcap_regulator *match_data;
struct regulator_config config;
struct regulator_init_data init_data;
int i;
match = of_match_device(of_match_ptr(cpcap_regulator_id_table),
&pdev->dev);
if (!match)
return -EINVAL;
if (!match->data) {
match_data = of_device_get_match_data(&pdev->dev);
if (!match_data) {
dev_err(&pdev->dev, "no configuration data found\n");
return -ENODEV;
@ -530,14 +525,12 @@ static int cpcap_regulator_probe(struct platform_device *pdev)
return -ENODEV;
ddata->dev = &pdev->dev;
ddata->soc = match->data;
ddata->soc = match_data;
platform_set_drvdata(pdev, ddata);
memset(&config, 0, sizeof(config));
memset(&init_data, 0, sizeof(init_data));
config.dev = &pdev->dev;
config.regmap = ddata->reg;
config.init_data = &init_data;
for (i = 0; i < CPCAP_NR_REGULATORS; i++) {
const struct cpcap_regulator *regulator = &ddata->soc[i];

View File

@ -1,13 +1,9 @@
/*
* Regulators driver for Dialog Semiconductor DA903x
*
* Copyright (C) 2006-2008 Marvell International Ltd.
* Copyright (C) 2008 Compulab Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Regulators driver for Dialog Semiconductor DA903x
//
// Copyright (C) 2006-2008 Marvell International Ltd.
// Copyright (C) 2008 Compulab Ltd.
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -1,16 +1,10 @@
/*
* da9052-regulator.c: Regulator driver for DA9052
*
* Copyright(c) 2011 Dialog Semiconductor Ltd.
*
* Author: David Dajun Chen <dchen@diasemi.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
// SPDX-License-Identifier: GPL-2.0+
//
// da9052-regulator.c: Regulator driver for DA9052
//
// Copyright(c) 2011 Dialog Semiconductor Ltd.
//
// Author: David Dajun Chen <dchen@diasemi.com>
#include <linux/module.h>
#include <linux/moduleparam.h>
@ -19,10 +13,8 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/regulator/of_regulator.h>
#endif
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>
@ -294,6 +286,8 @@ static const struct regulator_ops da9052_ldo_ops = {
{\
.reg_desc = {\
.name = #_name,\
.of_match = of_match_ptr(#_name),\
.regulators_node = of_match_ptr("regulators"),\
.ops = &da9052_ldo_ops,\
.type = REGULATOR_VOLTAGE,\
.id = DA9052_ID_##_id,\
@ -314,6 +308,8 @@ static const struct regulator_ops da9052_ldo_ops = {
{\
.reg_desc = {\
.name = #_name,\
.of_match = of_match_ptr(#_name),\
.regulators_node = of_match_ptr("regulators"),\
.ops = &da9052_dcdc_ops,\
.type = REGULATOR_VOLTAGE,\
.id = DA9052_ID_##_id,\
@ -417,36 +413,11 @@ static int da9052_regulator_probe(struct platform_device *pdev)
return -EINVAL;
}
config.dev = &pdev->dev;
config.dev = da9052->dev;
config.driver_data = regulator;
config.regmap = da9052->regmap;
if (pdata) {
if (pdata)
config.init_data = pdata->regulators[cell->id];
} else {
#ifdef CONFIG_OF
struct device_node *nproot = da9052->dev->of_node;
struct device_node *np;
if (!nproot)
return -ENODEV;
nproot = of_get_child_by_name(nproot, "regulators");
if (!nproot)
return -ENODEV;
for_each_child_of_node(nproot, np) {
if (of_node_name_eq(np,
regulator->info->reg_desc.name)) {
config.init_data = of_get_regulator_init_data(
&pdev->dev, np,
&regulator->info->reg_desc);
config.of_node = np;
break;
}
}
of_node_put(nproot);
#endif
}
regulator->rdev = devm_regulator_register(&pdev->dev,
&regulator->info->reg_desc,

View File

@ -1,16 +1,10 @@
/*
* Regulator driver for DA9055 PMIC
*
* Copyright(c) 2012 Dialog Semiconductor Ltd.
*
* Author: David Dajun Chen <dchen@diasemi.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Regulator driver for DA9055 PMIC
//
// Copyright(c) 2012 Dialog Semiconductor Ltd.
//
// Author: David Dajun Chen <dchen@diasemi.com>
#include <linux/module.h>
#include <linux/init.h>
@ -338,6 +332,8 @@ static const struct regulator_ops da9055_ldo_ops = {
{\
.reg_desc = {\
.name = #_id,\
.of_match = of_match_ptr(#_id),\
.regulators_node = of_match_ptr("regulators"),\
.ops = &da9055_ldo_ops,\
.type = REGULATOR_VOLTAGE,\
.id = DA9055_ID_##_id,\
@ -366,6 +362,8 @@ static const struct regulator_ops da9055_ldo_ops = {
{\
.reg_desc = {\
.name = #_id,\
.of_match = of_match_ptr(#_id),\
.regulators_node = of_match_ptr("regulators"),\
.ops = &da9055_buck_ops,\
.type = REGULATOR_VOLTAGE,\
.id = DA9055_ID_##_id,\
@ -487,8 +485,10 @@ static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data)
{
struct da9055_regulator *regulator = data;
regulator_lock(regulator->rdev);
regulator_notifier_call_chain(regulator->rdev,
REGULATOR_EVENT_OVER_CURRENT, NULL);
regulator_unlock(regulator->rdev);
return IRQ_HANDLED;
}
@ -507,59 +507,6 @@ static inline struct da9055_regulator_info *find_regulator_info(int id)
return NULL;
}
#ifdef CONFIG_OF
static struct of_regulator_match da9055_reg_matches[] = {
{ .name = "BUCK1", },
{ .name = "BUCK2", },
{ .name = "LDO1", },
{ .name = "LDO2", },
{ .name = "LDO3", },
{ .name = "LDO4", },
{ .name = "LDO5", },
{ .name = "LDO6", },
};
static int da9055_regulator_dt_init(struct platform_device *pdev,
struct da9055_regulator *regulator,
struct regulator_config *config,
int regid)
{
struct device_node *nproot, *np;
int ret;
nproot = of_node_get(pdev->dev.parent->of_node);
if (!nproot)
return -ENODEV;
np = of_get_child_by_name(nproot, "regulators");
if (!np)
return -ENODEV;
ret = of_regulator_match(&pdev->dev, np, &da9055_reg_matches[regid], 1);
of_node_put(nproot);
if (ret < 0) {
dev_err(&pdev->dev, "Error matching regulator: %d\n", ret);
return ret;
}
config->init_data = da9055_reg_matches[regid].init_data;
config->of_node = da9055_reg_matches[regid].of_node;
if (!config->of_node)
return -ENODEV;
return 0;
}
#else
static inline int da9055_regulator_dt_init(struct platform_device *pdev,
struct da9055_regulator *regulator,
struct regulator_config *config,
int regid)
{
return -ENODEV;
}
#endif /* CONFIG_OF */
static int da9055_regulator_probe(struct platform_device *pdev)
{
struct regulator_config config = { };
@ -580,18 +527,12 @@ static int da9055_regulator_probe(struct platform_device *pdev)
}
regulator->da9055 = da9055;
config.dev = &pdev->dev;
config.dev = da9055->dev;
config.driver_data = regulator;
config.regmap = da9055->regmap;
if (pdata) {
if (pdata)
config.init_data = pdata->regulators[pdev->id];
} else {
ret = da9055_regulator_dt_init(pdev, regulator, &config,
pdev->id);
if (ret < 0)
return ret;
}
ret = da9055_gpio_init(regulator, &config, pdata, pdev->id);
if (ret < 0)

View File

@ -1,17 +1,8 @@
/*
* Regulator device driver for DA9061 and DA9062.
* Copyright (C) 2015-2017 Dialog Semiconductor
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Regulator device driver for DA9061 and DA9062.
// Copyright (C) 2015-2017 Dialog Semiconductor
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@ -53,16 +44,12 @@ enum {
/* Regulator capabilities and registers description */
struct da9062_regulator_info {
struct regulator_desc desc;
/* Current limiting */
unsigned int n_current_limits;
const int *current_limits;
/* Main register fields */
struct reg_field mode;
struct reg_field suspend;
struct reg_field sleep;
struct reg_field suspend_sleep;
unsigned int suspend_vsel_reg;
struct reg_field ilimit;
/* Event detection bit */
struct reg_field oc_event;
};
@ -78,7 +65,6 @@ struct da9062_regulator {
struct regmap_field *suspend;
struct regmap_field *sleep;
struct regmap_field *suspend_sleep;
struct regmap_field *ilimit;
};
/* Encapsulates all information for the regulators driver */
@ -104,7 +90,7 @@ enum {
* - DA9062_ID_[BUCK1|BUCK2|BUCK4]
* Entry indexes corresponds to register values.
*/
static const int da9062_buck_a_limits[] = {
static const unsigned int da9062_buck_a_limits[] = {
500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000,
1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000
};
@ -114,44 +100,11 @@ static const int da9062_buck_a_limits[] = {
* - DA9062_ID_BUCK3
* Entry indexes corresponds to register values.
*/
static const int da9062_buck_b_limits[] = {
static const unsigned int da9062_buck_b_limits[] = {
1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000,
2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000
};
static int da9062_set_current_limit(struct regulator_dev *rdev,
int min_ua, int max_ua)
{
struct da9062_regulator *regl = rdev_get_drvdata(rdev);
const struct da9062_regulator_info *rinfo = regl->info;
int n, tval;
for (n = rinfo->n_current_limits - 1; n >= 0; n--) {
tval = rinfo->current_limits[n];
if (tval >= min_ua && tval <= max_ua)
return regmap_field_write(regl->ilimit, n);
}
return -EINVAL;
}
static int da9062_get_current_limit(struct regulator_dev *rdev)
{
struct da9062_regulator *regl = rdev_get_drvdata(rdev);
const struct da9062_regulator_info *rinfo = regl->info;
unsigned int sel;
int ret;
ret = regmap_field_read(regl->ilimit, &sel);
if (ret < 0)
return ret;
if (sel >= rinfo->n_current_limits)
sel = rinfo->n_current_limits - 1;
return rinfo->current_limits[sel];
}
static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode)
{
struct da9062_regulator *regl = rdev_get_drvdata(rdev);
@ -395,8 +348,8 @@ static const struct regulator_ops da9062_buck_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
.set_current_limit = da9062_set_current_limit,
.get_current_limit = da9062_get_current_limit,
.set_current_limit = regulator_set_current_limit_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_mode = da9062_buck_set_mode,
.get_mode = da9062_buck_get_mode,
.get_status = da9062_buck_get_status,
@ -433,8 +386,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
.desc.min_uV = (300) * 1000,
.desc.uV_step = (10) * 1000,
.desc.n_voltages = ((1570) - (300))/(10) + 1,
.current_limits = da9062_buck_a_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.curr_table = da9062_buck_a_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_C,
.desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK1_CONT,
.desc.enable_mask = DA9062AA_BUCK1_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK1_A,
@ -457,10 +412,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C,
__builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1),
},
{
.desc.id = DA9061_ID_BUCK2,
@ -471,8 +422,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
.desc.min_uV = (800) * 1000,
.desc.uV_step = (20) * 1000,
.desc.n_voltages = ((3340) - (800))/(20) + 1,
.current_limits = da9062_buck_b_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits),
.desc.curr_table = da9062_buck_b_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_A,
.desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK3_CONT,
.desc.enable_mask = DA9062AA_BUCK3_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK3_A,
@ -495,10 +448,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A,
__builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1),
},
{
.desc.id = DA9061_ID_BUCK3,
@ -509,8 +458,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
.desc.min_uV = (530) * 1000,
.desc.uV_step = (10) * 1000,
.desc.n_voltages = ((1800) - (530))/(10) + 1,
.current_limits = da9062_buck_a_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.curr_table = da9062_buck_a_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_B,
.desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK4_CONT,
.desc.enable_mask = DA9062AA_BUCK4_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK4_A,
@ -533,10 +484,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B,
__builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1),
},
{
.desc.id = DA9061_ID_LDO1,
@ -679,8 +626,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
.desc.min_uV = (300) * 1000,
.desc.uV_step = (10) * 1000,
.desc.n_voltages = ((1570) - (300))/(10) + 1,
.current_limits = da9062_buck_a_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.curr_table = da9062_buck_a_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_C,
.desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK1_CONT,
.desc.enable_mask = DA9062AA_BUCK1_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK1_A,
@ -703,10 +652,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C,
__builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1),
},
{
.desc.id = DA9062_ID_BUCK2,
@ -717,8 +662,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
.desc.min_uV = (300) * 1000,
.desc.uV_step = (10) * 1000,
.desc.n_voltages = ((1570) - (300))/(10) + 1,
.current_limits = da9062_buck_a_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.curr_table = da9062_buck_a_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_C,
.desc.csel_mask = DA9062AA_BUCK2_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK2_CONT,
.desc.enable_mask = DA9062AA_BUCK2_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK2_A,
@ -741,10 +688,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C,
__builtin_ffs((int)DA9062AA_BUCK2_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK2_ILIM_MASK)) - 1),
},
{
.desc.id = DA9062_ID_BUCK3,
@ -755,8 +698,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
.desc.min_uV = (800) * 1000,
.desc.uV_step = (20) * 1000,
.desc.n_voltages = ((3340) - (800))/(20) + 1,
.current_limits = da9062_buck_b_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits),
.desc.curr_table = da9062_buck_b_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_A,
.desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK3_CONT,
.desc.enable_mask = DA9062AA_BUCK3_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK3_A,
@ -779,10 +724,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A,
__builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1),
},
{
.desc.id = DA9062_ID_BUCK4,
@ -793,8 +734,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
.desc.min_uV = (530) * 1000,
.desc.uV_step = (10) * 1000,
.desc.n_voltages = ((1800) - (530))/(10) + 1,
.current_limits = da9062_buck_a_limits,
.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.curr_table = da9062_buck_a_limits,
.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
.desc.csel_reg = DA9062AA_BUCK_ILIM_B,
.desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK,
.desc.enable_reg = DA9062AA_BUCK4_CONT,
.desc.enable_mask = DA9062AA_BUCK4_EN_MASK,
.desc.vsel_reg = DA9062AA_VBUCK4_A,
@ -817,10 +760,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
.ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B,
__builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1,
sizeof(unsigned int) * 8 -
__builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1),
},
{
.desc.id = DA9062_ID_LDO1,
@ -974,8 +913,10 @@ static irqreturn_t da9062_ldo_lim_event(int irq, void *data)
continue;
if (BIT(regl->info->oc_event.lsb) & bits) {
regulator_lock(regl->rdev);
regulator_notifier_call_chain(regl->rdev,
REGULATOR_EVENT_OVER_CURRENT, NULL);
regulator_unlock(regl->rdev);
handled = IRQ_HANDLED;
}
}
@ -1063,15 +1004,6 @@ static int da9062_regulator_probe(struct platform_device *pdev)
return PTR_ERR(regl->suspend_sleep);
}
if (regl->info->ilimit.reg) {
regl->ilimit = devm_regmap_field_alloc(
&pdev->dev,
chip->regmap,
regl->info->ilimit);
if (IS_ERR(regl->ilimit))
return PTR_ERR(regl->ilimit);
}
/* Register regulator */
memset(&config, 0, sizeof(config));
config.dev = chip->dev;

View File

@ -1,18 +1,12 @@
// SPDX-License-Identifier: GPL-2.0+
//
// Regulator driver for DA9063 PMIC series
//
// Copyright 2012 Dialog Semiconductors Ltd.
// Copyright 2013 Philipp Zabel, Pengutronix
//
// Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
/*
* Regulator driver for DA9063 PMIC series
*
* Copyright 2012 Dialog Semiconductors Ltd.
* Copyright 2013 Philipp Zabel, Pengutronix
*
* Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@ -38,17 +32,12 @@
struct da9063_regulator_info {
struct regulator_desc desc;
/* Current limiting */
unsigned n_current_limits;
const int *current_limits;
/* DA9063 main register fields */
struct reg_field mode; /* buck mode of operation */
struct reg_field suspend;
struct reg_field sleep;
struct reg_field suspend_sleep;
unsigned int suspend_vsel_reg;
struct reg_field ilimit;
/* DA9063 event detection bit */
struct reg_field oc_event;
@ -73,15 +62,18 @@ struct da9063_regulator_info {
.suspend_vsel_reg = DA9063_REG_V##regl_name##_B
/* Macros for voltage DC/DC converters (BUCKs) */
#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array) \
#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array, \
creg, cmask) \
.desc.id = chip##_ID_##regl_name, \
.desc.name = __stringify(chip##_##regl_name), \
.desc.ops = &da9063_buck_ops, \
.desc.min_uV = (min_mV) * 1000, \
.desc.uV_step = (step_mV) * 1000, \
.desc.n_voltages = ((max_mV) - (min_mV))/(step_mV) + 1, \
.current_limits = limits_array, \
.n_current_limits = ARRAY_SIZE(limits_array)
.desc.csel_reg = (creg), \
.desc.csel_mask = (cmask), \
.desc.curr_table = limits_array, \
.desc.n_current_limits = ARRAY_SIZE(limits_array)
#define DA9063_BUCK_COMMON_FIELDS(regl_name) \
.desc.enable_reg = DA9063_REG_##regl_name##_CONT, \
@ -112,7 +104,6 @@ struct da9063_regulator {
struct regmap_field *suspend;
struct regmap_field *sleep;
struct regmap_field *suspend_sleep;
struct regmap_field *ilimit;
};
/* Encapsulates all information for the regulators driver */
@ -134,65 +125,32 @@ enum {
/* Current limits array (in uA) for BCORE1, BCORE2, BPRO.
Entry indexes corresponds to register values. */
static const int da9063_buck_a_limits[] = {
static const unsigned int da9063_buck_a_limits[] = {
500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000,
1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000
};
/* Current limits array (in uA) for BMEM, BIO, BPERI.
Entry indexes corresponds to register values. */
static const int da9063_buck_b_limits[] = {
static const unsigned int da9063_buck_b_limits[] = {
1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000,
2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000
};
/* Current limits array (in uA) for merged BCORE1 and BCORE2.
Entry indexes corresponds to register values. */
static const int da9063_bcores_merged_limits[] = {
static const unsigned int da9063_bcores_merged_limits[] = {
1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2200000, 2400000,
2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000
};
/* Current limits array (in uA) for merged BMEM and BIO.
Entry indexes corresponds to register values. */
static const int da9063_bmem_bio_merged_limits[] = {
static const unsigned int da9063_bmem_bio_merged_limits[] = {
3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000,
4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000
};
static int da9063_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct da9063_regulator *regl = rdev_get_drvdata(rdev);
const struct da9063_regulator_info *rinfo = regl->info;
int n, tval;
for (n = rinfo->n_current_limits - 1; n >= 0; n--) {
tval = rinfo->current_limits[n];
if (tval >= min_uA && tval <= max_uA)
return regmap_field_write(regl->ilimit, n);
}
return -EINVAL;
}
static int da9063_get_current_limit(struct regulator_dev *rdev)
{
struct da9063_regulator *regl = rdev_get_drvdata(rdev);
const struct da9063_regulator_info *rinfo = regl->info;
unsigned int sel;
int ret;
ret = regmap_field_read(regl->ilimit, &sel);
if (ret < 0)
return ret;
if (sel >= rinfo->n_current_limits)
sel = rinfo->n_current_limits - 1;
return rinfo->current_limits[sel];
}
static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned mode)
{
struct da9063_regulator *regl = rdev_get_drvdata(rdev);
@ -434,8 +392,8 @@ static const struct regulator_ops da9063_buck_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
.set_current_limit = da9063_set_current_limit,
.get_current_limit = da9063_get_current_limit,
.set_current_limit = regulator_set_current_limit_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_mode = da9063_buck_set_mode,
.get_mode = da9063_buck_get_mode,
.get_status = da9063_buck_get_status,
@ -465,69 +423,61 @@ static const struct regulator_ops da9063_ldo_ops = {
static const struct da9063_regulator_info da9063_regulator_info[] = {
{
DA9063_BUCK(DA9063, BCORE1, 300, 10, 1570,
da9063_buck_a_limits),
da9063_buck_a_limits,
DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK),
DA9063_BUCK_COMMON_FIELDS(BCORE1),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C,
DA9063_BCORE1_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BCORE2, 300, 10, 1570,
da9063_buck_a_limits),
da9063_buck_a_limits,
DA9063_REG_BUCK_ILIM_C, DA9063_BCORE2_ILIM_MASK),
DA9063_BUCK_COMMON_FIELDS(BCORE2),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE2_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C,
DA9063_BCORE2_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BPRO, 530, 10, 1800,
da9063_buck_a_limits),
da9063_buck_a_limits,
DA9063_REG_BUCK_ILIM_B, DA9063_BPRO_ILIM_MASK),
DA9063_BUCK_COMMON_FIELDS(BPRO),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPRO_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_B,
DA9063_BPRO_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BMEM, 800, 20, 3340,
da9063_buck_b_limits),
da9063_buck_b_limits,
DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK),
DA9063_BUCK_COMMON_FIELDS(BMEM),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A,
DA9063_BMEM_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BIO, 800, 20, 3340,
da9063_buck_b_limits),
da9063_buck_b_limits,
DA9063_REG_BUCK_ILIM_A, DA9063_BIO_ILIM_MASK),
DA9063_BUCK_COMMON_FIELDS(BIO),
.suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VBIO_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A,
DA9063_BIO_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BPERI, 800, 20, 3340,
da9063_buck_b_limits),
da9063_buck_b_limits,
DA9063_REG_BUCK_ILIM_B, DA9063_BPERI_ILIM_MASK),
DA9063_BUCK_COMMON_FIELDS(BPERI),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPERI_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_B,
DA9063_BPERI_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BCORES_MERGED, 300, 10, 1570,
da9063_bcores_merged_limits),
da9063_bcores_merged_limits,
DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK),
/* BCORES_MERGED uses the same register fields as BCORE1 */
DA9063_BUCK_COMMON_FIELDS(BCORE1),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C,
DA9063_BCORE1_ILIM_MASK),
},
{
DA9063_BUCK(DA9063, BMEM_BIO_MERGED, 800, 20, 3340,
da9063_bmem_bio_merged_limits),
da9063_bmem_bio_merged_limits,
DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK),
/* BMEM_BIO_MERGED uses the same register fields as BMEM */
DA9063_BUCK_COMMON_FIELDS(BMEM),
.suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL),
.ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A,
DA9063_BMEM_ILIM_MASK),
},
{
DA9063_LDO(DA9063, LDO3, 900, 20, 3440),
@ -615,9 +565,12 @@ static irqreturn_t da9063_ldo_lim_event(int irq, void *data)
if (regl->info->oc_event.reg != DA9063_REG_STATUS_D)
continue;
if (BIT(regl->info->oc_event.lsb) & bits)
if (BIT(regl->info->oc_event.lsb) & bits) {
regulator_lock(regl->rdev);
regulator_notifier_call_chain(regl->rdev,
REGULATOR_EVENT_OVER_CURRENT, NULL);
regulator_unlock(regl->rdev);
}
}
return IRQ_HANDLED;
@ -861,13 +814,6 @@ static int da9063_regulator_probe(struct platform_device *pdev)
return PTR_ERR(regl->suspend_sleep);
}
if (regl->info->ilimit.reg) {
regl->ilimit = devm_regmap_field_alloc(&pdev->dev,
da9063->regmap, regl->info->ilimit);
if (IS_ERR(regl->ilimit))
return PTR_ERR(regl->ilimit);
}
/* Register regulator */
memset(&config, 0, sizeof(config));
config.dev = &pdev->dev;

View File

@ -1,22 +1,7 @@
/*
* da9210-regulator.c - Regulator device driver for DA9210
* Copyright (C) 2013 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// da9210-regulator.c - Regulator device driver for DA9210
// Copyright (C) 2013 Dialog Semiconductor Ltd.
#include <linux/err.h>
#include <linux/i2c.h>

View File

@ -1,22 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* da9210-regulator.h - Regulator definitions for DA9210
* Copyright (C) 2013 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __DA9210_REGISTERS_H__

View File

@ -1,18 +1,8 @@
/*
* da9211-regulator.c - Regulator device driver for DA9211/DA9212
* /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225
* Copyright (C) 2015 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// da9211-regulator.c - Regulator device driver for DA9211/DA9212
// /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225
// Copyright (C) 2015 Dialog Semiconductor Ltd.
#include <linux/err.h>
#include <linux/i2c.h>
@ -322,8 +312,10 @@ static irqreturn_t da9211_irq_handler(int irq, void *data)
goto error_i2c;
if (reg_val & DA9211_E_OV_CURR_A) {
regulator_lock(chip->rdev[0]);
regulator_notifier_call_chain(chip->rdev[0],
REGULATOR_EVENT_OVER_CURRENT, NULL);
regulator_unlock(chip->rdev[0]);
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
DA9211_E_OV_CURR_A);
@ -334,8 +326,10 @@ static irqreturn_t da9211_irq_handler(int irq, void *data)
}
if (reg_val & DA9211_E_OV_CURR_B) {
regulator_lock(chip->rdev[1]);
regulator_notifier_call_chain(chip->rdev[1],
REGULATOR_EVENT_OVER_CURRENT, NULL);
regulator_unlock(chip->rdev[1]);
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
DA9211_E_OV_CURR_B);

View File

@ -1,17 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* da9211-regulator.h - Regulator definitions for DA9211/DA9212
* /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225
* Copyright (C) 2015 Dialog Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DA9211_REGISTERS_H__

View File

@ -75,7 +75,7 @@ static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
}
/* db8500 regulator operations */
static struct regulator_ops db8500_regulator_ops = {
static const struct regulator_ops db8500_regulator_ops = {
.enable = db8500_regulator_enable,
.disable = db8500_regulator_disable,
.is_enabled = db8500_regulator_is_enabled,
@ -200,7 +200,7 @@ static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
return info->is_enabled;
}
static struct regulator_ops db8500_regulator_switch_ops = {
static const struct regulator_ops db8500_regulator_switch_ops = {
.enable = db8500_regulator_switch_enable,
.disable = db8500_regulator_switch_disable,
.is_enabled = db8500_regulator_switch_is_enabled,
@ -214,6 +214,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VAPE] = {
.desc = {
.name = "db8500-vape",
.of_match = of_match_ptr("db8500_vape"),
.id = DB8500_REGULATOR_VAPE,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -223,6 +224,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VARM] = {
.desc = {
.name = "db8500-varm",
.of_match = of_match_ptr("db8500_varm"),
.id = DB8500_REGULATOR_VARM,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -232,6 +234,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VMODEM] = {
.desc = {
.name = "db8500-vmodem",
.of_match = of_match_ptr("db8500_vmodem"),
.id = DB8500_REGULATOR_VMODEM,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -241,6 +244,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VPLL] = {
.desc = {
.name = "db8500-vpll",
.of_match = of_match_ptr("db8500_vpll"),
.id = DB8500_REGULATOR_VPLL,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -250,6 +254,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VSMPS1] = {
.desc = {
.name = "db8500-vsmps1",
.of_match = of_match_ptr("db8500_vsmps1"),
.id = DB8500_REGULATOR_VSMPS1,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -259,6 +264,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VSMPS2] = {
.desc = {
.name = "db8500-vsmps2",
.of_match = of_match_ptr("db8500_vsmps2"),
.id = DB8500_REGULATOR_VSMPS2,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -271,6 +277,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VSMPS3] = {
.desc = {
.name = "db8500-vsmps3",
.of_match = of_match_ptr("db8500_vsmps3"),
.id = DB8500_REGULATOR_VSMPS3,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -280,6 +287,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_VRF1] = {
.desc = {
.name = "db8500-vrf1",
.of_match = of_match_ptr("db8500_vrf1"),
.id = DB8500_REGULATOR_VRF1,
.ops = &db8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -289,6 +297,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
.desc = {
.name = "db8500-sva-mmdsp",
.of_match = of_match_ptr("db8500_sva_mmdsp"),
.id = DB8500_REGULATOR_SWITCH_SVAMMDSP,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -299,6 +308,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
.desc = {
.name = "db8500-sva-mmdsp-ret",
.of_match = of_match_ptr("db8500_sva_mmdsp_ret"),
.id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -310,6 +320,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
.desc = {
.name = "db8500-sva-pipe",
.of_match = of_match_ptr("db8500_sva_pipe"),
.id = DB8500_REGULATOR_SWITCH_SVAPIPE,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -320,6 +331,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
.desc = {
.name = "db8500-sia-mmdsp",
.of_match = of_match_ptr("db8500_sia_mmdsp"),
.id = DB8500_REGULATOR_SWITCH_SIAMMDSP,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -330,6 +342,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
.desc = {
.name = "db8500-sia-mmdsp-ret",
.of_match = of_match_ptr("db8500_sia_mmdsp_ret"),
.id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -341,6 +354,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
.desc = {
.name = "db8500-sia-pipe",
.of_match = of_match_ptr("db8500_sia_pipe"),
.id = DB8500_REGULATOR_SWITCH_SIAPIPE,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -351,6 +365,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_SGA] = {
.desc = {
.name = "db8500-sga",
.of_match = of_match_ptr("db8500_sga"),
.id = DB8500_REGULATOR_SWITCH_SGA,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -361,6 +376,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
.desc = {
.name = "db8500-b2r2-mcde",
.of_match = of_match_ptr("db8500_b2r2_mcde"),
.id = DB8500_REGULATOR_SWITCH_B2R2_MCDE,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -371,6 +387,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_ESRAM12] = {
.desc = {
.name = "db8500-esram12",
.of_match = of_match_ptr("db8500_esram12"),
.id = DB8500_REGULATOR_SWITCH_ESRAM12,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -382,6 +399,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
.desc = {
.name = "db8500-esram12-ret",
.of_match = of_match_ptr("db8500_esram12_ret"),
.id = DB8500_REGULATOR_SWITCH_ESRAM12RET,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -393,6 +411,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_ESRAM34] = {
.desc = {
.name = "db8500-esram34",
.of_match = of_match_ptr("db8500_esram34"),
.id = DB8500_REGULATOR_SWITCH_ESRAM34,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -404,6 +423,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
.desc = {
.name = "db8500-esram34-ret",
.of_match = of_match_ptr("db8500_esram34_ret"),
.id = DB8500_REGULATOR_SWITCH_ESRAM34RET,
.ops = &db8500_regulator_switch_ops,
.type = REGULATOR_VOLTAGE,
@ -414,113 +434,38 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
},
};
static int db8500_regulator_register(struct platform_device *pdev,
struct regulator_init_data *init_data,
int id,
struct device_node *np)
{
struct dbx500_regulator_info *info;
struct regulator_config config = { };
int err;
/* assign per-regulator data */
info = &dbx500_regulator_info[id];
info->dev = &pdev->dev;
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = info;
config.of_node = np;
/* register with the regulator framework */
info->rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev);
dev_err(&pdev->dev, "failed to register %s: err %i\n",
info->desc.name, err);
return err;
}
dev_dbg(rdev_get_dev(info->rdev),
"regulator-%s-probed\n", info->desc.name);
return 0;
}
static struct of_regulator_match db8500_regulator_matches[] = {
{ .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, },
{ .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, },
{ .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, },
{ .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, },
{ .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, },
{ .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, },
{ .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, },
{ .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, },
{ .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, },
{ .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, },
{ .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, },
{ .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, },
{ .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, },
{ .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, },
{ .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, },
{ .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, },
{ .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, },
{ .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, },
{ .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, },
{ .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, },
};
static int
db8500_regulator_of_probe(struct platform_device *pdev,
struct device_node *np)
{
int i, err;
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
err = db8500_regulator_register(
pdev, db8500_regulator_matches[i].init_data,
i, db8500_regulator_matches[i].of_node);
if (err)
return err;
}
return 0;
}
static int db8500_regulator_probe(struct platform_device *pdev)
{
struct regulator_init_data *db8500_init_data =
dev_get_platdata(&pdev->dev);
struct device_node *np = pdev->dev.of_node;
int i, err;
struct regulator_init_data *db8500_init_data;
struct dbx500_regulator_info *info;
struct regulator_config config = { };
struct regulator_dev *rdev;
int err, i;
/* register all regulators */
if (np) {
err = of_regulator_match(&pdev->dev, np,
db8500_regulator_matches,
ARRAY_SIZE(db8500_regulator_matches));
if (err < 0) {
dev_err(&pdev->dev,
"Error parsing regulator init data: %d\n", err);
db8500_init_data = dev_get_platdata(&pdev->dev);
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
/* assign per-regulator data */
info = &dbx500_regulator_info[i];
config.driver_data = info;
config.dev = &pdev->dev;
if (db8500_init_data)
config.init_data = &db8500_init_data[i];
rdev = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(rdev)) {
err = PTR_ERR(rdev);
dev_err(&pdev->dev, "failed to register %s: err %i\n",
info->desc.name, err);
return err;
}
err = db8500_regulator_of_probe(pdev, np);
if (err)
return err;
} else {
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
err = db8500_regulator_register(pdev,
&db8500_init_data[i],
i, NULL);
if (err)
return err;
}
dev_dbg(&pdev->dev, "regulator-%s-probed\n", info->desc.name);
}
err = ux500_regulator_debug_init(pdev,
dbx500_regulator_info,
ARRAY_SIZE(dbx500_regulator_info));
ux500_regulator_debug_init(pdev, dbx500_regulator_info,
ARRAY_SIZE(dbx500_regulator_info));
return 0;
}

View File

@ -15,18 +15,14 @@
/**
* struct dbx500_regulator_info - dbx500 regulator information
* @dev: device pointer
* @desc: regulator description
* @rdev: regulator device pointer
* @is_enabled: status of the regulator
* @epod_id: id for EPOD (power domain)
* @is_ramret: RAM retention switch for EPOD (power domain)
*
*/
struct dbx500_regulator_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_dev *rdev;
bool is_enabled;
u16 epod_id;
bool is_ramret;

View File

@ -1,17 +1,13 @@
/*
* FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
*
* Supported Part Numbers:
* FAN53555UC00X/01X/03X/04X/05X
*
* Copyright (c) 2012 Marvell Technology Ltd.
* Yunfan Zhang <yfzhang@marvell.com>
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
// SPDX-License-Identifier: GPL-2.0
//
// FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
//
// Supported Part Numbers:
// FAN53555UC00X/01X/03X/04X/05X
//
// Copyright (c) 2012 Marvell Technology Ltd.
// Yunfan Zhang <yfzhang@marvell.com>
#include <linux/module.h>
#include <linux/param.h>
#include <linux/err.h>
@ -91,10 +87,8 @@ enum {
struct fan53555_device_info {
enum fan53555_vendor vendor;
struct regmap *regmap;
struct device *dev;
struct regulator_desc desc;
struct regulator_dev *rdev;
struct regulator_init_data *regulator;
/* IC Type and Rev */
int chip_id;
@ -106,8 +100,6 @@ struct fan53555_device_info {
unsigned int vsel_min;
unsigned int vsel_step;
unsigned int vsel_count;
/* Voltage slew rate limiting */
unsigned int slew_rate;
/* Mode */
unsigned int mode_reg;
unsigned int mode_mask;
@ -125,7 +117,7 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
ret = regulator_map_voltage_linear(rdev, uV, uV);
if (ret < 0)
return ret;
ret = regmap_update_bits(di->regmap, di->sleep_reg,
ret = regmap_update_bits(rdev->regmap, di->sleep_reg,
di->desc.vsel_mask, ret);
if (ret < 0)
return ret;
@ -140,7 +132,7 @@ static int fan53555_set_suspend_enable(struct regulator_dev *rdev)
{
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
return regmap_update_bits(di->regmap, di->sleep_reg,
return regmap_update_bits(rdev->regmap, di->sleep_reg,
VSEL_BUCK_EN, VSEL_BUCK_EN);
}
@ -148,7 +140,7 @@ static int fan53555_set_suspend_disable(struct regulator_dev *rdev)
{
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
return regmap_update_bits(di->regmap, di->sleep_reg,
return regmap_update_bits(rdev->regmap, di->sleep_reg,
VSEL_BUCK_EN, 0);
}
@ -158,11 +150,11 @@ static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
switch (mode) {
case REGULATOR_MODE_FAST:
regmap_update_bits(di->regmap, di->mode_reg,
regmap_update_bits(rdev->regmap, di->mode_reg,
di->mode_mask, di->mode_mask);
break;
case REGULATOR_MODE_NORMAL:
regmap_update_bits(di->regmap, di->vol_reg, di->mode_mask, 0);
regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0);
break;
default:
return -EINVAL;
@ -176,7 +168,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
unsigned int val;
int ret = 0;
ret = regmap_read(di->regmap, di->mode_reg, &val);
ret = regmap_read(rdev->regmap, di->mode_reg, &val);
if (ret < 0)
return ret;
if (val & di->mode_mask)
@ -213,7 +205,7 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
return -EINVAL;
}
return regmap_update_bits(di->regmap, FAN53555_CONTROL,
return regmap_update_bits(rdev->regmap, FAN53555_CONTROL,
CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
}
@ -396,6 +388,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
struct regulator_config *config)
{
struct regulator_desc *rdesc = &di->desc;
struct regulator_dev *rdev;
rdesc->name = "fan53555-reg";
rdesc->supply_name = "vin";
@ -410,8 +403,8 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
rdesc->vsel_mask = di->vsel_count - 1;
rdesc->owner = THIS_MODULE;
di->rdev = devm_regulator_register(di->dev, &di->desc, config);
return PTR_ERR_OR_ZERO(di->rdev);
rdev = devm_regulator_register(di->dev, &di->desc, config);
return PTR_ERR_OR_ZERO(rdev);
}
static const struct regmap_config fan53555_regmap_config = {
@ -466,6 +459,7 @@ static int fan53555_regulator_probe(struct i2c_client *client,
struct fan53555_device_info *di;
struct fan53555_platform_data *pdata;
struct regulator_config config = { };
struct regmap *regmap;
unsigned int val;
int ret;
@ -502,22 +496,22 @@ static int fan53555_regulator_probe(struct i2c_client *client,
di->vendor = id->driver_data;
}
di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
if (IS_ERR(di->regmap)) {
regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Failed to allocate regmap!\n");
return PTR_ERR(di->regmap);
return PTR_ERR(regmap);
}
di->dev = &client->dev;
i2c_set_clientdata(client, di);
/* Get chip ID */
ret = regmap_read(di->regmap, FAN53555_ID1, &val);
ret = regmap_read(regmap, FAN53555_ID1, &val);
if (ret < 0) {
dev_err(&client->dev, "Failed to get chip ID!\n");
return ret;
}
di->chip_id = val & DIE_ID;
/* Get chip revision */
ret = regmap_read(di->regmap, FAN53555_ID2, &val);
ret = regmap_read(regmap, FAN53555_ID2, &val);
if (ret < 0) {
dev_err(&client->dev, "Failed to get chip Rev!\n");
return ret;
@ -534,7 +528,7 @@ static int fan53555_regulator_probe(struct i2c_client *client,
/* Register regulator */
config.dev = di->dev;
config.init_data = di->regulator;
config.regmap = di->regmap;
config.regmap = regmap;
config.driver_data = di;
config.of_node = np;

View File

@ -36,7 +36,6 @@
struct gpio_regulator_data {
struct regulator_desc desc;
struct regulator_dev *dev;
struct gpio_desc **gpiods;
int nr_gpios;
@ -125,7 +124,7 @@ static int gpio_regulator_set_current_limit(struct regulator_dev *dev,
return 0;
}
static struct regulator_ops gpio_regulator_voltage_ops = {
static const struct regulator_ops gpio_regulator_voltage_ops = {
.get_voltage = gpio_regulator_get_value,
.set_voltage = gpio_regulator_set_voltage,
.list_voltage = gpio_regulator_list_voltage,
@ -221,7 +220,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
return config;
}
static struct regulator_ops gpio_regulator_current_ops = {
static const struct regulator_ops gpio_regulator_current_ops = {
.get_current_limit = gpio_regulator_get_value,
.set_current_limit = gpio_regulator_set_current_limit,
};
@ -233,6 +232,7 @@ static int gpio_regulator_probe(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct gpio_regulator_data *drvdata;
struct regulator_config cfg = { };
struct regulator_dev *rdev;
enum gpiod_flags gflags;
int ptr, ret, state, i;
@ -326,9 +326,9 @@ static int gpio_regulator_probe(struct platform_device *pdev)
if (IS_ERR(cfg.ena_gpiod))
return PTR_ERR(cfg.ena_gpiod);
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev);
rdev = devm_regulator_register(dev, &drvdata->desc, &cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "Failed to register regulator: %d\n", ret);
return ret;
}
@ -338,15 +338,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
return 0;
}
static int gpio_regulator_remove(struct platform_device *pdev)
{
struct gpio_regulator_data *drvdata = platform_get_drvdata(pdev);
regulator_unregister(drvdata->dev);
return 0;
}
#if defined(CONFIG_OF)
static const struct of_device_id regulator_gpio_of_match[] = {
{ .compatible = "regulator-gpio", },
@ -357,7 +348,6 @@ MODULE_DEVICE_TABLE(of, regulator_gpio_of_match);
static struct platform_driver gpio_regulator_driver = {
.probe = gpio_regulator_probe,
.remove = gpio_regulator_remove,
.driver = {
.name = "gpio-regulator",
.of_match_table = of_match_ptr(regulator_gpio_of_match),

View File

@ -1,17 +1,13 @@
/*
* Device driver for regulators in Hi6421 IC
*
* Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
* http://www.hisilicon.com
* Copyright (c) <2013-2014> Linaro Ltd.
* http://www.linaro.org
*
* Author: Guodong Xu <guodong.xu@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Device driver for regulators in Hi6421 IC
//
// Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
// http://www.hisilicon.com
// Copyright (c) <2013-2014> Linaro Ltd.
// http://www.linaro.org
//
// Author: Guodong Xu <guodong.xu@linaro.org>
#include <linux/slab.h>
#include <linux/device.h>
@ -78,43 +74,6 @@ enum hi6421_regulator_id {
HI6421_NUM_REGULATORS,
};
#define HI6421_REGULATOR_OF_MATCH(_name, id) \
{ \
.name = #_name, \
.driver_data = (void *) HI6421_##id, \
}
static struct of_regulator_match hi6421_regulator_match[] = {
HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0),
HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1),
HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2),
HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3),
HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4),
HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5),
HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6),
HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7),
HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8),
HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9),
HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10),
HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11),
HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12),
HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13),
HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14),
HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15),
HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16),
HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17),
HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18),
HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19),
HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20),
HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO),
HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0),
HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1),
HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2),
HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3),
HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4),
HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5),
};
/* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */
static const unsigned int ldo_0_voltages[] = {
1500000, 1800000, 2400000, 2500000,
@ -157,6 +116,7 @@ static const struct regulator_ops hi6421_buck345_ops;
#define HI6421_LDO_ENABLE_TIME (350)
/*
* _id - LDO id name string
* _match - of match name string
* v_table - voltage table
* vreg - voltage select register
* vmask - voltage select mask
@ -166,11 +126,13 @@ static const struct regulator_ops hi6421_buck345_ops;
* ecomask - eco mode mask
* ecoamp - eco mode load uppler limit in uA
*/
#define HI6421_LDO(_id, v_table, vreg, vmask, ereg, emask, \
#define HI6421_LDO(_id, _match, v_table, vreg, vmask, ereg, emask, \
odelay, ecomask, ecoamp) \
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &hi6421_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -191,6 +153,7 @@ static const struct regulator_ops hi6421_buck345_ops;
/* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step
*
* _id - LDO id name string
* _match - of match name string
* _min_uV - minimum voltage supported in uV
* n_volt - number of votages available
* vstep - voltage increase in each linear step in uV
@ -202,11 +165,13 @@ static const struct regulator_ops hi6421_buck345_ops;
* ecomask - eco mode mask
* ecoamp - eco mode load uppler limit in uA
*/
#define HI6421_LDO_LINEAR(_id, _min_uV, n_volt, vstep, vreg, vmask, \
#define HI6421_LDO_LINEAR(_id, _match, _min_uV, n_volt, vstep, vreg, vmask,\
ereg, emask, odelay, ecomask, ecoamp) \
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &hi6421_ldo_linear_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -228,6 +193,7 @@ static const struct regulator_ops hi6421_buck345_ops;
/* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges
*
* _id - LDO id name string
* _match - of match name string
* n_volt - number of votages available
* volt_ranges - array of regulator_linear_range
* vstep - voltage increase in each linear step in uV
@ -239,11 +205,13 @@ static const struct regulator_ops hi6421_buck345_ops;
* ecomask - eco mode mask
* ecoamp - eco mode load uppler limit in uA
*/
#define HI6421_LDO_LINEAR_RANGE(_id, n_volt, volt_ranges, vreg, vmask, \
#define HI6421_LDO_LINEAR_RANGE(_id, _match, n_volt, volt_ranges, vreg, vmask,\
ereg, emask, odelay, ecomask, ecoamp) \
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &hi6421_ldo_linear_range_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -265,6 +233,7 @@ static const struct regulator_ops hi6421_buck345_ops;
/* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step
*
* _id - BUCK0/1/2 id name string
* _match - of match name string
* vreg - voltage select register
* vmask - voltage select mask
* ereg - enable register
@ -273,11 +242,13 @@ static const struct regulator_ops hi6421_buck345_ops;
* etime - enable time
* odelay - off/on delay time in uS
*/
#define HI6421_BUCK012(_id, vreg, vmask, ereg, emask, sleepmask, \
#define HI6421_BUCK012(_id, _match, vreg, vmask, ereg, emask, sleepmask,\
etime, odelay) \
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &hi6421_buck012_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -299,6 +270,7 @@ static const struct regulator_ops hi6421_buck345_ops;
* that it supports SLEEP mode, so has different .ops.
*
* _id - LDO id name string
* _match - of match name string
* v_table - voltage table
* vreg - voltage select register
* vmask - voltage select mask
@ -307,11 +279,13 @@ static const struct regulator_ops hi6421_buck345_ops;
* odelay - off/on delay time in uS
* sleepmask - mask of sleep mode
*/
#define HI6421_BUCK345(_id, v_table, vreg, vmask, ereg, emask, \
#define HI6421_BUCK345(_id, _match, v_table, vreg, vmask, ereg, emask, \
odelay, sleepmask) \
[HI6421_##_id] = { \
.desc = { \
.name = #_id, \
.of_match = of_match_ptr(#_match), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &hi6421_buck345_ops, \
.type = REGULATOR_VOLTAGE, \
.id = HI6421_##_id, \
@ -331,59 +305,63 @@ static const struct regulator_ops hi6421_buck345_ops;
/* HI6421 regulator information */
static struct hi6421_regulator_info
hi6421_regulator_info[HI6421_NUM_REGULATORS] = {
HI6421_LDO(LDO0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10,
HI6421_LDO(LDO0, hi6421_vout0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10,
10000, 0x20, 8000),
HI6421_LDO_LINEAR(LDO1, 1700000, 4, 100000, 0x21, 0x03, 0x21, 0x10,
10000, 0x20, 5000),
HI6421_LDO_LINEAR(LDO2, 1050000, 8, 50000, 0x22, 0x07, 0x22, 0x10,
20000, 0x20, 8000),
HI6421_LDO_LINEAR(LDO3, 1050000, 8, 50000, 0x23, 0x07, 0x23, 0x10,
20000, 0x20, 8000),
HI6421_LDO(LDO4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10,
HI6421_LDO_LINEAR(LDO1, hi6421_vout1, 1700000, 4, 100000, 0x21, 0x03,
0x21, 0x10, 10000, 0x20, 5000),
HI6421_LDO_LINEAR(LDO2, hi6421_vout2, 1050000, 8, 50000, 0x22, 0x07,
0x22, 0x10, 20000, 0x20, 8000),
HI6421_LDO_LINEAR(LDO3, hi6421_vout3, 1050000, 8, 50000, 0x23, 0x07,
0x23, 0x10, 20000, 0x20, 8000),
HI6421_LDO(LDO4, hi6421_vout4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10,
20000, 0x20, 8000),
HI6421_LDO(LDO5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10,
HI6421_LDO(LDO5, hi6421_vout5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10,
20000, 0x20, 8000),
HI6421_LDO(LDO6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10,
HI6421_LDO(LDO6, hi6421_vout6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10,
20000, 0x20, 8000),
HI6421_LDO(LDO7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10,
HI6421_LDO(LDO7, hi6421_vout7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10,
20000, 0x20, 5000),
HI6421_LDO(LDO8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10,
HI6421_LDO(LDO8, hi6421_vout8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10,
20000, 0x20, 8000),
HI6421_LDO(LDO9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10,
HI6421_LDO(LDO9, hi6421_vout9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10,
HI6421_LDO(LDO10, hi6421_vout10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10,
HI6421_LDO(LDO11, hi6421_vout11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10,
HI6421_LDO(LDO12, hi6421_vout12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10,
HI6421_LDO(LDO13, hi6421_vout13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10,
HI6421_LDO(LDO14, hi6421_vout14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10,
HI6421_LDO(LDO15, hi6421_vout15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10,
HI6421_LDO(LDO16, hi6421_vout16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10,
HI6421_LDO(LDO17, hi6421_vout17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10,
HI6421_LDO(LDO18, hi6421_vout18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10,
HI6421_LDO(LDO19, hi6421_vout19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10,
40000, 0x20, 8000),
HI6421_LDO(LDO20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10,
HI6421_LDO(LDO20, hi6421_vout20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10,
40000, 0x20, 8000),
HI6421_LDO_LINEAR_RANGE(LDOAUDIO, 8, ldo_audio_volt_range, 0x36,
0x70, 0x36, 0x01, 40000, 0x02, 5000),
HI6421_BUCK012(BUCK0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, 20000),
HI6421_BUCK012(BUCK1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, 20000),
HI6421_BUCK012(BUCK2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, 100),
HI6421_BUCK345(BUCK3, buck_3_voltages, 0x13, 0x07, 0x12, 0x01,
20000, 0x10),
HI6421_BUCK345(BUCK4, buck_4_voltages, 0x15, 0x07, 0x14, 0x01,
20000, 0x10),
HI6421_BUCK345(BUCK5, buck_5_voltages, 0x17, 0x07, 0x16, 0x01,
20000, 0x10),
HI6421_LDO_LINEAR_RANGE(LDOAUDIO, hi6421_vout_audio, 8,
ldo_audio_volt_range, 0x36, 0x70, 0x36, 0x01,
40000, 0x02, 5000),
HI6421_BUCK012(BUCK0, hi6421_buck0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400,
20000),
HI6421_BUCK012(BUCK1, hi6421_buck1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400,
20000),
HI6421_BUCK012(BUCK2, hi6421_buck2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350,
100),
HI6421_BUCK345(BUCK3, hi6421_buck3, buck_3_voltages, 0x13, 0x07, 0x12,
0x01, 20000, 0x10),
HI6421_BUCK345(BUCK4, hi6421_buck4, buck_4_voltages, 0x15, 0x07, 0x14,
0x01, 20000, 0x10),
HI6421_BUCK345(BUCK5, hi6421_buck5, buck_5_voltages, 0x17, 0x07, 0x16,
0x01, 20000, 0x10),
};
static int hi6421_regulator_enable(struct regulator_dev *rdev)
@ -552,42 +530,14 @@ static const struct regulator_ops hi6421_buck345_ops = {
.set_mode = hi6421_regulator_buck_set_mode,
};
static int hi6421_regulator_register(struct platform_device *pdev,
struct regmap *rmap,
struct regulator_init_data *init_data,
int id, struct device_node *np)
{
struct hi6421_regulator_info *info = NULL;
struct regulator_config config = { };
struct regulator_dev *rdev;
/* assign per-regulator data */
info = &hi6421_regulator_info[id];
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = info;
config.regmap = rmap;
config.of_node = np;
/* register regulator with framework */
rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
return PTR_ERR(rdev);
}
return 0;
}
static int hi6421_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np;
struct hi6421_pmic *pmic;
struct hi6421_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
struct hi6421_regulator_pdata *pdata;
int i, ret = 0;
struct hi6421_regulator_info *info;
struct regulator_config config = { };
struct regulator_dev *rdev;
int i;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@ -595,27 +545,21 @@ static int hi6421_regulator_probe(struct platform_device *pdev)
mutex_init(&pdata->lock);
platform_set_drvdata(pdev, pdata);
np = of_get_child_by_name(dev->parent->of_node, "regulators");
if (!np)
return -ENODEV;
ret = of_regulator_match(dev, np,
hi6421_regulator_match,
ARRAY_SIZE(hi6421_regulator_match));
of_node_put(np);
if (ret < 0) {
dev_err(dev, "Error parsing regulator init data: %d\n", ret);
return ret;
}
pmic = dev_get_drvdata(dev->parent);
for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) {
ret = hi6421_regulator_register(pdev, pmic->regmap,
hi6421_regulator_match[i].init_data, i,
hi6421_regulator_match[i].of_node);
if (ret)
return ret;
/* assign per-regulator data */
info = &hi6421_regulator_info[i];
config.dev = pdev->dev.parent;
config.driver_data = info;
config.regmap = pmic->regmap;
rdev = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
return PTR_ERR(rdev);
}
}
return 0;

View File

@ -1,18 +1,14 @@
/*
* Device driver for regulators in Hi6421V530 IC
*
* Copyright (c) <2017> HiSilicon Technologies Co., Ltd.
* http://www.hisilicon.com
* Copyright (c) <2017> Linaro Ltd.
* http://www.linaro.org
*
* Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com>
* Guodong Xu <guodong.xu@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Device driver for regulators in Hi6421V530 IC
//
// Copyright (c) <2017> HiSilicon Technologies Co., Ltd.
// http://www.hisilicon.com
// Copyright (c) <2017> Linaro Ltd.
// http://www.linaro.org
//
// Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com>
// Guodong Xu <guodong.xu@linaro.org>
#include <linux/mfd/hi6421-pmic.h>
#include <linux/module.h>

View File

@ -1,16 +1,12 @@
/*
* Device driver for regulators in Hi655x IC
*
* Copyright (c) 2016 Hisilicon.
*
* Authors:
* Chen Feng <puck.chen@hisilicon.com>
* Fei Wang <w.f@huawei.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Device driver for regulators in Hi655x IC
//
// Copyright (c) 2016 Hisilicon.
//
// Authors:
// Chen Feng <puck.chen@hisilicon.com>
// Fei Wang <w.f@huawei.com>
#include <linux/bitops.h>
#include <linux/device.h>
@ -28,7 +24,6 @@
struct hi655x_regulator {
unsigned int disable_reg;
unsigned int status_reg;
unsigned int ctrl_mask;
struct regulator_desc rdesc;
};
@ -77,22 +72,18 @@ enum hi655x_regulator_id {
static int hi655x_is_enabled(struct regulator_dev *rdev)
{
unsigned int value = 0;
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
regmap_read(rdev->regmap, regulator->status_reg, &value);
return (value & BIT(regulator->ctrl_mask));
return (value & rdev->desc->enable_mask);
}
static int hi655x_disable(struct regulator_dev *rdev)
{
int ret = 0;
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
ret = regmap_write(rdev->regmap, regulator->disable_reg,
BIT(regulator->ctrl_mask));
return ret;
return regmap_write(rdev->regmap, regulator->disable_reg,
rdev->desc->enable_mask);
}
static const struct regulator_ops hi655x_regulator_ops = {
@ -132,7 +123,6 @@ static const struct regulator_ops hi655x_ldo_linear_ops = {
}, \
.disable_reg = HI655X_BUS_ADDR(dreg), \
.status_reg = HI655X_BUS_ADDR(sreg), \
.ctrl_mask = cmask, \
}
#define HI655X_LDO_LINEAR(_ID, vreg, vmask, ereg, dreg, \
@ -155,10 +145,9 @@ static const struct regulator_ops hi655x_ldo_linear_ops = {
}, \
.disable_reg = HI655X_BUS_ADDR(dreg), \
.status_reg = HI655X_BUS_ADDR(sreg), \
.ctrl_mask = cmask, \
}
static struct hi655x_regulator regulators[] = {
static const struct hi655x_regulator regulators[] = {
HI655X_LDO_LINEAR(LDO2, 0x72, 0x07, 0x29, 0x2a, 0x2b, 0x01,
2500000, 8, 100000),
HI655X_LDO(LDO7, 0x78, 0x07, 0x29, 0x2a, 0x2b, 0x06, ldo7_voltages),

View File

@ -48,7 +48,7 @@ static const int ldo_cont_enable_time[] = {
static int lm363x_regulator_enable_time(struct regulator_dev *rdev)
{
enum lm363x_regulator_id id = rdev_get_id(rdev);
u8 val, addr, mask;
unsigned int val, addr, mask;
switch (id) {
case LM3631_LDO_CONT:
@ -71,7 +71,7 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev)
return 0;
}
if (regmap_read(rdev->regmap, addr, (unsigned int *)&val))
if (regmap_read(rdev->regmap, addr, &val))
return -EINVAL;
val = (val & mask) >> LM3631_ENTIME_SHIFT;
@ -82,13 +82,13 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev)
return ENABLE_TIME_USEC * val;
}
static struct regulator_ops lm363x_boost_voltage_table_ops = {
static const struct regulator_ops lm363x_boost_voltage_table_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static struct regulator_ops lm363x_regulator_voltage_table_ops = {
static const struct regulator_ops lm363x_regulator_voltage_table_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,

View File

@ -372,10 +372,13 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
if ((flag0 & (0x4 << icnt))
&& (pchip->irqmask & (0x04 << icnt))
&& (pchip->rdev[icnt] != NULL))
&& (pchip->rdev[icnt] != NULL)) {
regulator_lock(pchip->rdev[icnt]);
regulator_notifier_call_chain(pchip->rdev[icnt],
LP8755_EVENT_PWR_FAULT,
NULL);
regulator_unlock(pchip->rdev[icnt]);
}
/* read flag1 register */
ret = lp8755_read(pchip, 0x0E, &flag1);
@ -389,18 +392,24 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
/* send OCP event to all regulator devices */
if ((flag1 & 0x01) && (pchip->irqmask & 0x01))
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
if (pchip->rdev[icnt] != NULL)
if (pchip->rdev[icnt] != NULL) {
regulator_lock(pchip->rdev[icnt]);
regulator_notifier_call_chain(pchip->rdev[icnt],
LP8755_EVENT_OCP,
NULL);
regulator_unlock(pchip->rdev[icnt]);
}
/* send OVP event to all regulator devices */
if ((flag1 & 0x02) && (pchip->irqmask & 0x02))
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
if (pchip->rdev[icnt] != NULL)
if (pchip->rdev[icnt] != NULL) {
regulator_lock(pchip->rdev[icnt]);
regulator_notifier_call_chain(pchip->rdev[icnt],
LP8755_EVENT_OVP,
NULL);
regulator_unlock(pchip->rdev[icnt]);
}
return IRQ_HANDLED;
err_i2c:

View File

@ -34,6 +34,10 @@
.ramp_delay = _delay, \
.linear_ranges = _lr, \
.n_linear_ranges = ARRAY_SIZE(_lr), \
.curr_table = lp87565_buck_uA, \
.n_current_limits = ARRAY_SIZE(lp87565_buck_uA),\
.csel_reg = (_cr), \
.csel_mask = LP87565_BUCK_CTRL_2_ILIM, \
}, \
.ctrl2_reg = _cr, \
}
@ -102,44 +106,7 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
return 0;
}
static int lp87565_buck_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
int id = rdev_get_id(rdev);
struct lp87565 *lp87565 = rdev_get_drvdata(rdev);
int i;
for (i = ARRAY_SIZE(lp87565_buck_uA) - 1; i >= 0; i--) {
if (lp87565_buck_uA[i] >= min_uA &&
lp87565_buck_uA[i] <= max_uA)
return regmap_update_bits(lp87565->regmap,
regulators[id].ctrl2_reg,
LP87565_BUCK_CTRL_2_ILIM,
i << __ffs(LP87565_BUCK_CTRL_2_ILIM));
}
return -EINVAL;
}
static int lp87565_buck_get_current_limit(struct regulator_dev *rdev)
{
int id = rdev_get_id(rdev);
struct lp87565 *lp87565 = rdev_get_drvdata(rdev);
int ret;
unsigned int val;
ret = regmap_read(lp87565->regmap, regulators[id].ctrl2_reg, &val);
if (ret)
return ret;
val = (val & LP87565_BUCK_CTRL_2_ILIM) >>
__ffs(LP87565_BUCK_CTRL_2_ILIM);
return (val < ARRAY_SIZE(lp87565_buck_uA)) ?
lp87565_buck_uA[val] : -EINVAL;
}
/* Operations permitted on BUCK0, BUCK1 */
/* Operations permitted on BUCKs */
static const struct regulator_ops lp87565_buck_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
@ -150,8 +117,8 @@ static const struct regulator_ops lp87565_buck_ops = {
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = lp87565_buck_set_ramp_delay,
.set_current_limit = lp87565_buck_set_current_limit,
.get_current_limit = lp87565_buck_get_current_limit,
.set_current_limit = regulator_set_current_limit_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
};
static const struct lp87565_regulator regulators[] = {
@ -193,7 +160,7 @@ static int lp87565_regulator_probe(struct platform_device *pdev)
struct lp87565 *lp87565 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct regulator_dev *rdev;
int i, min_idx = LP87565_BUCK_1, max_idx = LP87565_BUCK_3;
int i, min_idx = LP87565_BUCK_0, max_idx = LP87565_BUCK_3;
platform_set_drvdata(pdev, lp87565);

View File

@ -1,21 +1,9 @@
/*
* Linear Technology LTC3589,LTC3589-1 regulator support
*
* Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
// SPDX-License-Identifier: GPL-2.0
//
// Linear Technology LTC3589,LTC3589-1 regulator support
//
// Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@ -84,19 +72,11 @@ enum ltc3589_reg {
LTC3589_NUM_REGULATORS,
};
struct ltc3589_regulator {
struct regulator_desc desc;
/* External feedback voltage divider */
unsigned int r1;
unsigned int r2;
};
struct ltc3589 {
struct regmap *regmap;
struct device *dev;
enum ltc3589_variant variant;
struct ltc3589_regulator regulator_descs[LTC3589_NUM_REGULATORS];
struct regulator_desc regulator_descs[LTC3589_NUM_REGULATORS];
struct regulator_dev *regulators[LTC3589_NUM_REGULATORS];
};
@ -196,132 +176,91 @@ static const struct regulator_ops ltc3589_table_regulator_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2)
{
uint64_t tmp;
#define LTC3589_REG(_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit) \
[LTC3589_ ## _name] = { \
.desc = { \
.name = #_name, \
.n_voltages = (dtv_mask) + 1, \
.min_uV = (go_bit) ? 362500 : 0, \
.uV_step = (go_bit) ? 12500 : 0, \
.ramp_delay = (go_bit) ? 1750 : 0, \
.fixed_uV = (dtv_mask) ? 0 : 800000, \
.ops = &ltc3589_ ## _ops ## _regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = LTC3589_ ## _name, \
.owner = THIS_MODULE, \
.vsel_reg = (dtv1_reg), \
.vsel_mask = (dtv_mask), \
.apply_reg = (go_bit) ? LTC3589_VCCR : 0, \
.apply_bit = (go_bit), \
.enable_reg = (en_bit) ? LTC3589_OVEN : 0, \
.enable_mask = (en_bit), \
}, \
if (uV == 0)
return 0;
tmp = (uint64_t)uV * r1;
do_div(tmp, r2);
return uV + (unsigned int)tmp;
}
static int ltc3589_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct ltc3589 *ltc3589 = config->driver_data;
struct regulator_desc *rdesc = &ltc3589->regulator_descs[desc->id];
u32 r[2];
int ret;
/* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */
if (desc->id >= LTC3589_LDO3)
return 0;
ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", r, 2);
if (ret) {
dev_err(ltc3589->dev, "Failed to parse voltage divider: %d\n",
ret);
return ret;
}
#define LTC3589_LINEAR_REG(_name, _dtv1) \
LTC3589_REG(_name, linear, LTC3589_OVEN_ ## _name, \
if (!r[0] || !r[1])
return 0;
rdesc->min_uV = ltc3589_scale(desc->min_uV, r[0], r[1]);
rdesc->uV_step = ltc3589_scale(desc->uV_step, r[0], r[1]);
rdesc->fixed_uV = ltc3589_scale(desc->fixed_uV, r[0], r[1]);
return 0;
}
#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit)\
[LTC3589_ ## _name] = { \
.name = #_name, \
.of_match = of_match_ptr(#_of_name), \
.regulators_node = of_match_ptr("regulators"), \
.of_parse_cb = ltc3589_of_parse_cb, \
.n_voltages = (dtv_mask) + 1, \
.min_uV = (go_bit) ? 362500 : 0, \
.uV_step = (go_bit) ? 12500 : 0, \
.ramp_delay = (go_bit) ? 1750 : 0, \
.fixed_uV = (dtv_mask) ? 0 : 800000, \
.ops = &ltc3589_ ## _ops ## _regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = LTC3589_ ## _name, \
.owner = THIS_MODULE, \
.vsel_reg = (dtv1_reg), \
.vsel_mask = (dtv_mask), \
.apply_reg = (go_bit) ? LTC3589_VCCR : 0, \
.apply_bit = (go_bit), \
.enable_reg = (en_bit) ? LTC3589_OVEN : 0, \
.enable_mask = (en_bit), \
}
#define LTC3589_LINEAR_REG(_name, _of_name, _dtv1) \
LTC3589_REG(_name, _of_name, linear, LTC3589_OVEN_ ## _name, \
LTC3589_ ## _dtv1, 0x1f, \
LTC3589_VCCR_ ## _name ## _GO)
#define LTC3589_FIXED_REG(_name) \
LTC3589_REG(_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0)
#define LTC3589_FIXED_REG(_name, _of_name) \
LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0)
static struct ltc3589_regulator ltc3589_regulators[LTC3589_NUM_REGULATORS] = {
LTC3589_LINEAR_REG(SW1, B1DTV1),
LTC3589_LINEAR_REG(SW2, B2DTV1),
LTC3589_LINEAR_REG(SW3, B3DTV1),
LTC3589_FIXED_REG(BB_OUT),
LTC3589_REG(LDO1, fixed_standby, 0, 0, 0, 0),
LTC3589_LINEAR_REG(LDO2, L2DTV1),
LTC3589_FIXED_REG(LDO3),
LTC3589_REG(LDO4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60, 0),
static const struct regulator_desc ltc3589_regulators[] = {
LTC3589_LINEAR_REG(SW1, sw1, B1DTV1),
LTC3589_LINEAR_REG(SW2, sw2, B2DTV1),
LTC3589_LINEAR_REG(SW3, sw3, B3DTV1),
LTC3589_FIXED_REG(BB_OUT, bb-out),
LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0),
LTC3589_LINEAR_REG(LDO2, ldo2, L2DTV1),
LTC3589_FIXED_REG(LDO3, ldo3),
LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2,
0x60, 0),
};
#ifdef CONFIG_OF
static struct of_regulator_match ltc3589_matches[LTC3589_NUM_REGULATORS] = {
{ .name = "sw1", },
{ .name = "sw2", },
{ .name = "sw3", },
{ .name = "bb-out", },
{ .name = "ldo1", }, /* standby */
{ .name = "ldo2", },
{ .name = "ldo3", },
{ .name = "ldo4", },
};
static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589)
{
struct device *dev = ltc3589->dev;
struct device_node *node;
int i, ret;
node = of_get_child_by_name(dev->of_node, "regulators");
if (!node) {
dev_err(dev, "regulators node not found\n");
return -EINVAL;
}
ret = of_regulator_match(dev, node, ltc3589_matches,
ARRAY_SIZE(ltc3589_matches));
of_node_put(node);
if (ret < 0) {
dev_err(dev, "Error parsing regulator init data: %d\n", ret);
return ret;
}
if (ret != LTC3589_NUM_REGULATORS) {
dev_err(dev, "Only %d regulators described in device tree\n",
ret);
return -EINVAL;
}
/* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */
for (i = 0; i < LTC3589_LDO3; i++) {
struct ltc3589_regulator *desc = &ltc3589->regulator_descs[i];
struct device_node *np = ltc3589_matches[i].of_node;
u32 vdiv[2];
ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider",
vdiv, 2);
if (ret) {
dev_err(dev, "Failed to parse voltage divider: %d\n",
ret);
return ret;
}
desc->r1 = vdiv[0];
desc->r2 = vdiv[1];
}
return 0;
}
static inline struct regulator_init_data *match_init_data(int index)
{
return ltc3589_matches[index].init_data;
}
static inline struct device_node *match_of_node(int index)
{
return ltc3589_matches[index].of_node;
}
#else
static inline int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589)
{
return 0;
}
static inline struct regulator_init_data *match_init_data(int index)
{
return NULL;
}
static inline struct device_node *match_of_node(int index)
{
return NULL;
}
#endif
static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@ -409,7 +348,6 @@ static const struct regmap_config ltc3589_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
static irqreturn_t ltc3589_isr(int irq, void *dev_id)
{
struct ltc3589 *ltc3589 = dev_id;
@ -419,16 +357,22 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id)
if (irqstat & LTC3589_IRQSTAT_THERMAL_WARN) {
event = REGULATOR_EVENT_OVER_TEMP;
for (i = 0; i < LTC3589_NUM_REGULATORS; i++)
for (i = 0; i < LTC3589_NUM_REGULATORS; i++) {
regulator_lock(ltc3589->regulators[i]);
regulator_notifier_call_chain(ltc3589->regulators[i],
event, NULL);
regulator_unlock(ltc3589->regulators[i]);
}
}
if (irqstat & LTC3589_IRQSTAT_UNDERVOLT_WARN) {
event = REGULATOR_EVENT_UNDER_VOLTAGE;
for (i = 0; i < LTC3589_NUM_REGULATORS; i++)
for (i = 0; i < LTC3589_NUM_REGULATORS; i++) {
regulator_lock(ltc3589->regulators[i]);
regulator_notifier_call_chain(ltc3589->regulators[i],
event, NULL);
regulator_unlock(ltc3589->regulators[i]);
}
}
/* Clear warning condition */
@ -437,33 +381,11 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2)
{
uint64_t tmp;
if (uV == 0)
return 0;
tmp = (uint64_t)uV * r1;
do_div(tmp, r2);
return uV + (unsigned int)tmp;
}
static void ltc3589_apply_fb_voltage_divider(struct ltc3589_regulator *rdesc)
{
struct regulator_desc *desc = &rdesc->desc;
if (!rdesc->r1 || !rdesc->r2)
return;
desc->min_uV = ltc3589_scale(desc->min_uV, rdesc->r1, rdesc->r2);
desc->uV_step = ltc3589_scale(desc->uV_step, rdesc->r1, rdesc->r2);
desc->fixed_uV = ltc3589_scale(desc->fixed_uV, rdesc->r1, rdesc->r2);
}
static int ltc3589_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct ltc3589_regulator *descs;
struct regulator_desc *descs;
struct ltc3589 *ltc3589;
int i, ret;
@ -482,11 +404,11 @@ static int ltc3589_probe(struct i2c_client *client,
descs = ltc3589->regulator_descs;
memcpy(descs, ltc3589_regulators, sizeof(ltc3589_regulators));
if (ltc3589->variant == LTC3589) {
descs[LTC3589_LDO3].desc.fixed_uV = 1800000;
descs[LTC3589_LDO4].desc.volt_table = ltc3589_ldo4;
descs[LTC3589_LDO3].fixed_uV = 1800000;
descs[LTC3589_LDO4].volt_table = ltc3589_ldo4;
} else {
descs[LTC3589_LDO3].desc.fixed_uV = 2800000;
descs[LTC3589_LDO4].desc.volt_table = ltc3589_12_ldo4;
descs[LTC3589_LDO3].fixed_uV = 2800000;
descs[LTC3589_LDO4].volt_table = ltc3589_12_ldo4;
}
ltc3589->regmap = devm_regmap_init_i2c(client, &ltc3589_regmap_config);
@ -496,25 +418,12 @@ static int ltc3589_probe(struct i2c_client *client,
return ret;
}
ret = ltc3589_parse_regulators_dt(ltc3589);
if (ret)
return ret;
for (i = 0; i < LTC3589_NUM_REGULATORS; i++) {
struct ltc3589_regulator *rdesc = &ltc3589->regulator_descs[i];
struct regulator_desc *desc = &rdesc->desc;
struct regulator_init_data *init_data;
struct regulator_desc *desc = &ltc3589->regulator_descs[i];
struct regulator_config config = { };
init_data = match_init_data(i);
if (i < LTC3589_LDO3)
ltc3589_apply_fb_voltage_divider(rdesc);
config.dev = dev;
config.init_data = init_data;
config.driver_data = ltc3589;
config.of_node = match_of_node(i);
ltc3589->regulators[i] = devm_regulator_register(dev, desc,
&config);

View File

@ -285,17 +285,23 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id)
if (irqstat & LTC3676_IRQSTAT_THERMAL_WARN) {
dev_warn(dev, "Over-temperature Warning\n");
event = REGULATOR_EVENT_OVER_TEMP;
for (i = 0; i < LTC3676_NUM_REGULATORS; i++)
for (i = 0; i < LTC3676_NUM_REGULATORS; i++) {
regulator_lock(ltc3676->regulators[i]);
regulator_notifier_call_chain(ltc3676->regulators[i],
event, NULL);
regulator_unlock(ltc3676->regulators[i]);
}
}
if (irqstat & LTC3676_IRQSTAT_UNDERVOLT_WARN) {
dev_info(dev, "Undervoltage Warning\n");
event = REGULATOR_EVENT_UNDER_VOLTAGE;
for (i = 0; i < LTC3676_NUM_REGULATORS; i++)
for (i = 0; i < LTC3676_NUM_REGULATORS; i++) {
regulator_lock(ltc3676->regulators[i]);
regulator_notifier_call_chain(ltc3676->regulators[i],
event, NULL);
regulator_unlock(ltc3676->regulators[i]);
}
}
/* Clear warning condition */

View File

@ -155,58 +155,6 @@ static const struct regulator_desc max77836_supported_regulators[] = {
[MAX77836_LDO2] = MAX77836_LDO_REG(2),
};
#ifdef CONFIG_OF
static struct of_regulator_match max14577_regulator_matches[] = {
{ .name = "SAFEOUT", },
{ .name = "CHARGER", },
};
static struct of_regulator_match max77836_regulator_matches[] = {
{ .name = "SAFEOUT", },
{ .name = "CHARGER", },
{ .name = "LDO1", },
{ .name = "LDO2", },
};
static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type)
{
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,
enum maxim_device_type dev_type)
{
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 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,
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.
@ -265,9 +213,6 @@ static int max14577_regulator_probe(struct platform_device *pdev)
if (pdata && pdata->regulators) {
config.init_data = pdata->regulators[i].initdata;
config.of_node = pdata->regulators[i].of_node;
} else {
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);

View File

@ -41,7 +41,7 @@ struct max77650_regulator_desc {
unsigned int regB;
};
static const u32 max77651_sbb1_regulator_volt_table[] = {
static const unsigned int max77651_sbb1_regulator_volt_table[] = {
2400000, 3200000, 4000000, 4800000,
2450000, 3250000, 4050000, 4850000,
2500000, 3300000, 4100000, 4900000,

View File

@ -159,6 +159,8 @@ static const struct regulator_ops max8925_regulator_ldo_ops = {
{ \
.desc = { \
.name = "SDV" #_id, \
.of_match = of_match_ptr("SDV" #_id), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &max8925_regulator_sdv_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MAX8925_ID_SD##_id, \
@ -175,6 +177,8 @@ static const struct regulator_ops max8925_regulator_ldo_ops = {
{ \
.desc = { \
.name = "LDO" #_id, \
.of_match = of_match_ptr("LDO" #_id), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &max8925_regulator_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MAX8925_ID_LDO##_id, \
@ -187,34 +191,6 @@ static const struct regulator_ops max8925_regulator_ldo_ops = {
.enable_reg = MAX8925_LDOCTL##_id, \
}
#ifdef CONFIG_OF
static struct of_regulator_match max8925_regulator_matches[] = {
{ .name = "SDV1",},
{ .name = "SDV2",},
{ .name = "SDV3",},
{ .name = "LDO1",},
{ .name = "LDO2",},
{ .name = "LDO3",},
{ .name = "LDO4",},
{ .name = "LDO5",},
{ .name = "LDO6",},
{ .name = "LDO7",},
{ .name = "LDO8",},
{ .name = "LDO9",},
{ .name = "LDO10",},
{ .name = "LDO11",},
{ .name = "LDO12",},
{ .name = "LDO13",},
{ .name = "LDO14",},
{ .name = "LDO15",},
{ .name = "LDO16",},
{ .name = "LDO17",},
{ .name = "LDO18",},
{ .name = "LDO19",},
{ .name = "LDO20",},
};
#endif
static struct max8925_regulator_info max8925_regulator_info[] = {
MAX8925_SDV(1, 637.5, 1425, 12.5),
MAX8925_SDV(2, 650, 2225, 25),
@ -242,37 +218,6 @@ static struct max8925_regulator_info max8925_regulator_info[] = {
MAX8925_LDO(20, 750, 3900, 50),
};
#ifdef CONFIG_OF
static int max8925_regulator_dt_init(struct platform_device *pdev,
struct regulator_config *config,
int ridx)
{
struct device_node *nproot, *np;
int rcount;
nproot = pdev->dev.parent->of_node;
if (!nproot)
return -ENODEV;
np = of_get_child_by_name(nproot, "regulators");
if (!np) {
dev_err(&pdev->dev, "failed to find regulators node\n");
return -ENODEV;
}
rcount = of_regulator_match(&pdev->dev, np,
&max8925_regulator_matches[ridx], 1);
of_node_put(np);
if (rcount < 0)
return rcount;
config->init_data = max8925_regulator_matches[ridx].init_data;
config->of_node = max8925_regulator_matches[ridx].of_node;
return 0;
}
#else
#define max8925_regulator_dt_init(x, y, z) (-1)
#endif
static int max8925_regulator_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
@ -281,7 +226,7 @@ static int max8925_regulator_probe(struct platform_device *pdev)
struct max8925_regulator_info *ri;
struct resource *res;
struct regulator_dev *rdev;
int i, regulator_idx;
int i;
res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (!res) {
@ -290,10 +235,8 @@ static int max8925_regulator_probe(struct platform_device *pdev)
}
for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
ri = &max8925_regulator_info[i];
if (ri->vol_reg == res->start) {
regulator_idx = i;
if (ri->vol_reg == res->start)
break;
}
}
if (i == ARRAY_SIZE(max8925_regulator_info)) {
@ -303,12 +246,11 @@ static int max8925_regulator_probe(struct platform_device *pdev)
}
ri->i2c = chip->i2c;
config.dev = &pdev->dev;
config.dev = chip->dev;
config.driver_data = ri;
if (max8925_regulator_dt_init(pdev, &config, regulator_idx))
if (pdata)
config.init_data = pdata;
if (pdata)
config.init_data = pdata;
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
if (IS_ERR(rdev)) {

View File

@ -33,72 +33,6 @@ struct max8998_data {
unsigned int buck2_idx;
};
struct voltage_map_desc {
int min;
int max;
int step;
};
/* Voltage maps in uV*/
static const struct voltage_map_desc ldo23_voltage_map_desc = {
.min = 800000, .step = 50000, .max = 1300000,
};
static const struct voltage_map_desc ldo456711_voltage_map_desc = {
.min = 1600000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc ldo8_voltage_map_desc = {
.min = 3000000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc ldo9_voltage_map_desc = {
.min = 2800000, .step = 100000, .max = 3100000,
};
static const struct voltage_map_desc ldo10_voltage_map_desc = {
.min = 950000, .step = 50000, .max = 1300000,
};
static const struct voltage_map_desc ldo1213_voltage_map_desc = {
.min = 800000, .step = 100000, .max = 3300000,
};
static const struct voltage_map_desc ldo1415_voltage_map_desc = {
.min = 1200000, .step = 100000, .max = 3300000,
};
static const struct voltage_map_desc ldo1617_voltage_map_desc = {
.min = 1600000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc buck12_voltage_map_desc = {
.min = 750000, .step = 25000, .max = 1525000,
};
static const struct voltage_map_desc buck3_voltage_map_desc = {
.min = 1600000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc buck4_voltage_map_desc = {
.min = 800000, .step = 100000, .max = 2300000,
};
static const struct voltage_map_desc *ldo_voltage_map[] = {
NULL,
NULL,
&ldo23_voltage_map_desc, /* LDO2 */
&ldo23_voltage_map_desc, /* LDO3 */
&ldo456711_voltage_map_desc, /* LDO4 */
&ldo456711_voltage_map_desc, /* LDO5 */
&ldo456711_voltage_map_desc, /* LDO6 */
&ldo456711_voltage_map_desc, /* LDO7 */
&ldo8_voltage_map_desc, /* LDO8 */
&ldo9_voltage_map_desc, /* LDO9 */
&ldo10_voltage_map_desc, /* LDO10 */
&ldo456711_voltage_map_desc, /* LDO11 */
&ldo1213_voltage_map_desc, /* LDO12 */
&ldo1213_voltage_map_desc, /* LDO13 */
&ldo1415_voltage_map_desc, /* LDO14 */
&ldo1415_voltage_map_desc, /* LDO15 */
&ldo1617_voltage_map_desc, /* LDO16 */
&ldo1617_voltage_map_desc, /* LDO17 */
&buck12_voltage_map_desc, /* BUCK1 */
&buck12_voltage_map_desc, /* BUCK2 */
&buck3_voltage_map_desc, /* BUCK3 */
&buck4_voltage_map_desc, /* BUCK4 */
};
static int max8998_get_enable_register(struct regulator_dev *rdev,
int *reg, int *shift)
{
@ -400,7 +334,6 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8998->iodev->i2c;
const struct voltage_map_desc *desc;
int buck = rdev_get_id(rdev);
u8 val = 0;
int difference, ret;
@ -408,8 +341,6 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4)
return -EINVAL;
desc = ldo_voltage_map[buck];
/* Voltage stabilization */
ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
if (ret)
@ -420,14 +351,14 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP))
return 0;
difference = (new_selector - old_selector) * desc->step / 1000;
difference = (new_selector - old_selector) * rdev->desc->uV_step / 1000;
if (difference > 0)
return DIV_ROUND_UP(difference, (val & 0x0f) + 1);
return 0;
}
static struct regulator_ops max8998_ldo_ops = {
static const struct regulator_ops max8998_ldo_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = max8998_ldo_is_enabled,
@ -437,7 +368,7 @@ static struct regulator_ops max8998_ldo_ops = {
.set_voltage_sel = max8998_set_voltage_ldo_sel,
};
static struct regulator_ops max8998_buck_ops = {
static const struct regulator_ops max8998_buck_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = max8998_ldo_is_enabled,
@ -448,164 +379,59 @@ static struct regulator_ops max8998_buck_ops = {
.set_voltage_time_sel = max8998_set_voltage_buck_time_sel,
};
static struct regulator_ops max8998_others_ops = {
static const struct regulator_ops max8998_others_ops = {
.is_enabled = max8998_ldo_is_enabled,
.enable = max8998_ldo_enable,
.disable = max8998_ldo_disable,
};
static struct regulator_desc regulators[] = {
{
.name = "LDO2",
.id = MAX8998_LDO2,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO3",
.id = MAX8998_LDO3,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO4",
.id = MAX8998_LDO4,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO5",
.id = MAX8998_LDO5,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO6",
.id = MAX8998_LDO6,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO7",
.id = MAX8998_LDO7,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO8",
.id = MAX8998_LDO8,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO9",
.id = MAX8998_LDO9,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO10",
.id = MAX8998_LDO10,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO11",
.id = MAX8998_LDO11,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO12",
.id = MAX8998_LDO12,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO13",
.id = MAX8998_LDO13,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO14",
.id = MAX8998_LDO14,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO15",
.id = MAX8998_LDO15,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO16",
.id = MAX8998_LDO16,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO17",
.id = MAX8998_LDO17,
.ops = &max8998_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "BUCK1",
.id = MAX8998_BUCK1,
.ops = &max8998_buck_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "BUCK2",
.id = MAX8998_BUCK2,
.ops = &max8998_buck_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "BUCK3",
.id = MAX8998_BUCK3,
.ops = &max8998_buck_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "BUCK4",
.id = MAX8998_BUCK4,
.ops = &max8998_buck_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "EN32KHz-AP",
.id = MAX8998_EN32KHZ_AP,
.ops = &max8998_others_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "EN32KHz-CP",
.id = MAX8998_EN32KHZ_CP,
.ops = &max8998_others_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "ENVICHG",
.id = MAX8998_ENVICHG,
.ops = &max8998_others_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "ESAFEOUT1",
.id = MAX8998_ESAFEOUT1,
.ops = &max8998_others_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "ESAFEOUT2",
.id = MAX8998_ESAFEOUT2,
.ops = &max8998_others_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
#define MAX8998_LINEAR_REG(_name, _ops, _min, _step, _max) \
{ \
.name = #_name, \
.id = MAX8998_##_name, \
.ops = _ops, \
.min_uV = (_min), \
.uV_step = (_step), \
.n_voltages = ((_max) - (_min)) / (_step) + 1, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
#define MAX8998_OTHERS_REG(_name, _id) \
{ \
.name = #_name, \
.id = _id, \
.ops = &max8998_others_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
static const struct regulator_desc regulators[] = {
MAX8998_LINEAR_REG(LDO2, &max8998_ldo_ops, 800000, 50000, 1300000),
MAX8998_LINEAR_REG(LDO3, &max8998_ldo_ops, 800000, 50000, 1300000),
MAX8998_LINEAR_REG(LDO4, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO5, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO6, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO7, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO8, &max8998_ldo_ops, 3000000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO9, &max8998_ldo_ops, 2800000, 100000, 3100000),
MAX8998_LINEAR_REG(LDO10, &max8998_ldo_ops, 950000, 50000, 1300000),
MAX8998_LINEAR_REG(LDO11, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO12, &max8998_ldo_ops, 800000, 100000, 3300000),
MAX8998_LINEAR_REG(LDO13, &max8998_ldo_ops, 800000, 100000, 3300000),
MAX8998_LINEAR_REG(LDO14, &max8998_ldo_ops, 1200000, 100000, 3300000),
MAX8998_LINEAR_REG(LDO15, &max8998_ldo_ops, 1200000, 100000, 3300000),
MAX8998_LINEAR_REG(LDO16, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(LDO17, &max8998_ldo_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(BUCK1, &max8998_buck_ops, 750000, 25000, 1525000),
MAX8998_LINEAR_REG(BUCK2, &max8998_buck_ops, 750000, 25000, 1525000),
MAX8998_LINEAR_REG(BUCK3, &max8998_buck_ops, 1600000, 100000, 3600000),
MAX8998_LINEAR_REG(BUCK4, &max8998_buck_ops, 800000, 100000, 2300000),
MAX8998_OTHERS_REG(EN32KHz-AP, MAX8998_EN32KHZ_AP),
MAX8998_OTHERS_REG(EN32KHz-CP, MAX8998_EN32KHZ_CP),
MAX8998_OTHERS_REG(ENVICHG, MAX8998_ENVICHG),
MAX8998_OTHERS_REG(ESAFEOUT1, MAX8998_ESAFEOUT1),
MAX8998_OTHERS_REG(ESAFEOUT2, MAX8998_ESAFEOUT2),
};
static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev,
@ -796,9 +622,11 @@ static int max8998_pmic_probe(struct platform_device *pdev)
/* Set predefined values for BUCK1 registers */
for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
int index = MAX8998_BUCK1 - MAX8998_LDO2;
i = 0;
while (buck12_voltage_map_desc.min +
buck12_voltage_map_desc.step*i
while (regulators[index].min_uV +
regulators[index].uV_step * i
< pdata->buck1_voltage[v])
i++;
@ -824,9 +652,11 @@ static int max8998_pmic_probe(struct platform_device *pdev)
/* Set predefined values for BUCK2 registers */
for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
int index = MAX8998_BUCK2 - MAX8998_LDO2;
i = 0;
while (buck12_voltage_map_desc.min +
buck12_voltage_map_desc.step*i
while (regulators[index].min_uV +
regulators[index].uV_step * i
< pdata->buck2_voltage[v])
i++;
@ -839,18 +669,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
}
for (i = 0; i < pdata->num_regulators; i++) {
const struct voltage_map_desc *desc;
int id = pdata->regulators[i].id;
int index = id - MAX8998_LDO2;
desc = ldo_voltage_map[id];
if (desc && regulators[index].ops != &max8998_others_ops) {
int count = (desc->max - desc->min) / desc->step + 1;
regulators[index].n_voltages = count;
regulators[index].min_uV = desc->min;
regulators[index].uV_step = desc->step;
}
int index = pdata->regulators[i].id - MAX8998_LDO2;
config.dev = max8998->dev;
config.of_node = pdata->regulators[i].reg_node;
@ -867,7 +686,6 @@ static int max8998_pmic_probe(struct platform_device *pdev)
}
}
return 0;
}

View File

@ -119,8 +119,6 @@ enum {
* @lpm: LPM GPIO descriptor
*/
struct mcp16502 {
struct regulator_dev *rdev[NUM_REGULATORS];
struct regmap *rmap;
struct gpio_desc *lpm;
};
@ -179,13 +177,12 @@ static unsigned int mcp16502_get_mode(struct regulator_dev *rdev)
{
unsigned int val;
int ret, reg;
struct mcp16502 *mcp = rdev_get_drvdata(rdev);
reg = mcp16502_get_reg(rdev, MCP16502_OPMODE_ACTIVE);
if (reg < 0)
return reg;
ret = regmap_read(mcp->rmap, reg, &val);
ret = regmap_read(rdev->regmap, reg, &val);
if (ret)
return ret;
@ -211,7 +208,6 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode,
{
int val;
int reg;
struct mcp16502 *mcp = rdev_get_drvdata(rdev);
reg = mcp16502_get_reg(rdev, op_mode);
if (reg < 0)
@ -228,7 +224,7 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode,
return -EINVAL;
}
reg = regmap_update_bits(mcp->rmap, reg, MCP16502_MODE, val);
reg = regmap_update_bits(rdev->regmap, reg, MCP16502_MODE, val);
return reg;
}
@ -247,9 +243,8 @@ static int mcp16502_get_status(struct regulator_dev *rdev)
{
int ret;
unsigned int val;
struct mcp16502 *mcp = rdev_get_drvdata(rdev);
ret = regmap_read(mcp->rmap, MCP16502_STAT_BASE(rdev_get_id(rdev)),
ret = regmap_read(rdev->regmap, MCP16502_STAT_BASE(rdev_get_id(rdev)),
&val);
if (ret)
return ret;
@ -290,7 +285,6 @@ static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev)
*/
static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
struct mcp16502 *mcp = rdev_get_drvdata(rdev);
int sel = regulator_map_voltage_linear_range(rdev, uV, uV);
int reg = mcp16502_suspend_get_target_reg(rdev);
@ -300,7 +294,7 @@ static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV)
if (reg < 0)
return reg;
return regmap_update_bits(mcp->rmap, reg, MCP16502_VSEL, sel);
return regmap_update_bits(rdev->regmap, reg, MCP16502_VSEL, sel);
}
/*
@ -328,13 +322,12 @@ static int mcp16502_set_suspend_mode(struct regulator_dev *rdev,
*/
static int mcp16502_set_suspend_enable(struct regulator_dev *rdev)
{
struct mcp16502 *mcp = rdev_get_drvdata(rdev);
int reg = mcp16502_suspend_get_target_reg(rdev);
if (reg < 0)
return reg;
return regmap_update_bits(mcp->rmap, reg, MCP16502_EN, MCP16502_EN);
return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, MCP16502_EN);
}
/*
@ -342,13 +335,12 @@ static int mcp16502_set_suspend_enable(struct regulator_dev *rdev)
*/
static int mcp16502_set_suspend_disable(struct regulator_dev *rdev)
{
struct mcp16502 *mcp = rdev_get_drvdata(rdev);
int reg = mcp16502_suspend_get_target_reg(rdev);
if (reg < 0)
return reg;
return regmap_update_bits(mcp->rmap, reg, MCP16502_EN, 0);
return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, 0);
}
#endif /* CONFIG_SUSPEND */
@ -435,36 +427,15 @@ static const struct regmap_config mcp16502_regmap_config = {
.wr_table = &mcp16502_yes_reg_table,
};
/*
* set_up_regulators() - initialize all regulators
*/
static int setup_regulators(struct mcp16502 *mcp, struct device *dev,
struct regulator_config config)
{
int i;
for (i = 0; i < NUM_REGULATORS; i++) {
mcp->rdev[i] = devm_regulator_register(dev,
&mcp16502_desc[i],
&config);
if (IS_ERR(mcp->rdev[i])) {
dev_err(dev,
"failed to register %s regulator %ld\n",
mcp16502_desc[i].name, PTR_ERR(mcp->rdev[i]));
return PTR_ERR(mcp->rdev[i]);
}
}
return 0;
}
static int mcp16502_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
struct device *dev;
struct mcp16502 *mcp;
int ret = 0;
struct regmap *rmap;
int i, ret;
dev = &client->dev;
config.dev = dev;
@ -473,15 +444,15 @@ static int mcp16502_probe(struct i2c_client *client,
if (!mcp)
return -ENOMEM;
mcp->rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
if (IS_ERR(mcp->rmap)) {
ret = PTR_ERR(mcp->rmap);
rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
if (IS_ERR(rmap)) {
ret = PTR_ERR(rmap);
dev_err(dev, "regmap init failed: %d\n", ret);
return ret;
}
i2c_set_clientdata(client, mcp);
config.regmap = mcp->rmap;
config.regmap = rmap;
config.driver_data = mcp;
mcp->lpm = devm_gpiod_get(dev, "lpm", GPIOD_OUT_LOW);
@ -490,9 +461,15 @@ static int mcp16502_probe(struct i2c_client *client,
return PTR_ERR(mcp->lpm);
}
ret = setup_regulators(mcp, dev, config);
if (ret != 0)
return ret;
for (i = 0; i < NUM_REGULATORS; i++) {
rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(dev,
"failed to register %s regulator %ld\n",
mcp16502_desc[i].name, PTR_ERR(rdev));
return PTR_ERR(rdev);
}
}
mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);

View File

@ -1,16 +1,7 @@
/*
* Copyright (c) 2015 MediaTek Inc.
* Author: Henry Chen <henryc.chen@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2015 MediaTek Inc.
// Author: Henry Chen <henryc.chen@mediatek.com>
#include <linux/err.h>
#include <linux/gpio.h>

View File

@ -1,15 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2015 MediaTek Inc.
* Author: Henry Chen <henryc.chen@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MT6311_REGULATOR_H__

View File

@ -1,11 +1,7 @@
/*
* Copyright (c) 2016 MediaTek Inc.
* Author: Chen Zhong <chen.zhong@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2016 MediaTek Inc.
// Author: Chen Zhong <chen.zhong@mediatek.com>
#include <linux/module.h>
#include <linux/of.h>
@ -118,43 +114,43 @@ static const struct regulator_linear_range buck_volt_range3[] = {
REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
};
static const u32 ldo_volt_table1[] = {
static const unsigned int ldo_volt_table1[] = {
3300000, 3400000, 3500000, 3600000,
};
static const u32 ldo_volt_table2[] = {
static const unsigned int ldo_volt_table2[] = {
1500000, 1800000, 2500000, 2800000,
};
static const u32 ldo_volt_table3[] = {
static const unsigned int ldo_volt_table3[] = {
1800000, 3300000,
};
static const u32 ldo_volt_table4[] = {
static const unsigned int ldo_volt_table4[] = {
3000000, 3300000,
};
static const u32 ldo_volt_table5[] = {
static const unsigned int ldo_volt_table5[] = {
1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table6[] = {
static const unsigned int ldo_volt_table6[] = {
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
};
static const u32 ldo_volt_table7[] = {
static const unsigned int ldo_volt_table7[] = {
1200000, 1300000, 1500000, 1800000,
};
static const u32 ldo_volt_table8[] = {
static const unsigned int ldo_volt_table8[] = {
1800000, 3000000,
};
static const u32 ldo_volt_table9[] = {
static const unsigned int ldo_volt_table9[] = {
1200000, 1350000, 1500000, 1800000,
};
static const u32 ldo_volt_table10[] = {
static const unsigned int ldo_volt_table10[] = {
1200000, 1300000, 1500000, 1800000,
};

View File

@ -1,16 +1,7 @@
/*
* Copyright (c) 2017 MediaTek Inc.
* Author: Chenglin Xu <chenglin.xu@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2017 MediaTek Inc.
// Author: Chenglin Xu <chenglin.xu@mediatek.com>
#include <linux/module.h>
#include <linux/of.h>
@ -173,19 +164,19 @@ static const struct regulator_linear_range buck_volt_range3[] = {
REGULATOR_LINEAR_RANGE(1200000, 0, 0x3c, 25000),
};
static const u32 ldo_volt_table1[] = {
static const unsigned int ldo_volt_table1[] = {
1400000, 1350000, 1300000, 1250000, 1200000, 1150000, 1100000, 1050000,
};
static const u32 ldo_volt_table2[] = {
static const unsigned int ldo_volt_table2[] = {
2200000, 3300000,
};
static const u32 ldo_volt_table3[] = {
static const unsigned int ldo_volt_table3[] = {
1240000, 1390000, 1540000, 1840000,
};
static const u32 ldo_volt_table4[] = {
static const unsigned int ldo_volt_table4[] = {
2200000, 3300000,
};

View File

@ -1,16 +1,7 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Flora Fu <flora.fu@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2014 MediaTek Inc.
// Author: Flora Fu <flora.fu@mediatek.com>
#include <linux/module.h>
#include <linux/of.h>
@ -123,35 +114,35 @@ static const struct regulator_linear_range buck_volt_range3[] = {
REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000),
};
static const u32 ldo_volt_table1[] = {
static const unsigned int ldo_volt_table1[] = {
1500000, 1800000, 2500000, 2800000,
};
static const u32 ldo_volt_table2[] = {
static const unsigned int ldo_volt_table2[] = {
1800000, 3300000,
};
static const u32 ldo_volt_table3[] = {
static const unsigned int ldo_volt_table3[] = {
3000000, 3300000,
};
static const u32 ldo_volt_table4[] = {
static const unsigned int ldo_volt_table4[] = {
1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table5[] = {
static const unsigned int ldo_volt_table5[] = {
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table5_v2[] = {
static const unsigned int ldo_volt_table5_v2[] = {
1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table6[] = {
static const unsigned int ldo_volt_table6[] = {
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
};
static const u32 ldo_volt_table7[] = {
static const unsigned int ldo_volt_table7[] = {
1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000,
};

View File

@ -371,8 +371,9 @@ int of_regulator_match(struct device *dev, struct device_node *node,
}
EXPORT_SYMBOL_GPL(of_regulator_match);
struct device_node *regulator_of_get_init_node(struct device *dev,
const struct regulator_desc *desc)
static struct
device_node *regulator_of_get_init_node(struct device *dev,
const struct regulator_desc *desc)
{
struct device_node *search, *child;
const char *name;

View File

@ -991,9 +991,6 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic,
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[id] = rdev;
/* Initialise sleep/init values from platform data */
if (pdata) {
reg_init = pdata->reg_init[id];
@ -1101,9 +1098,6 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic,
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[id] = rdev;
/* Initialise sleep/init values from platform data */
if (pdata) {
reg_init = pdata->reg_init[id];
@ -1288,9 +1282,6 @@ static int palmas_smps_registration(struct palmas_pmic *pmic,
pdev_name);
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[id] = rdev;
}
return 0;
@ -1395,9 +1386,6 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic,
pdev_name);
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[id] = rdev;
}
return 0;

View File

@ -1,17 +1,7 @@
/*
* pv88060-regulator.c - Regulator device driver for PV88060
* Copyright (C) 2015 Powerventure Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// pv88060-regulator.c - Regulator device driver for PV88060
// Copyright (C) 2015 Powerventure Semiconductor Ltd.
#include <linux/err.h>
#include <linux/i2c.h>
@ -244,9 +234,11 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data)
if (reg_val & PV88060_E_VDD_FLT) {
for (i = 0; i < PV88060_MAX_REGULATORS; i++) {
if (chip->rdev[i] != NULL) {
regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
regulator_unlock(chip->rdev[i]);
}
}
@ -261,9 +253,11 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data)
if (reg_val & PV88060_E_OVER_TEMP) {
for (i = 0; i < PV88060_MAX_REGULATORS; i++) {
if (chip->rdev[i] != NULL) {
regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
regulator_unlock(chip->rdev[i]);
}
}

View File

@ -1,16 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* pv88060-regulator.h - Regulator definitions for PV88060
* Copyright (C) 2015 Powerventure Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PV88060_REGISTERS_H__

View File

@ -1,17 +1,7 @@
/*
* pv88080-regulator.c - Regulator device driver for PV88080
* Copyright (C) 2016 Powerventure Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// pv88080-regulator.c - Regulator device driver for PV88080
// Copyright (C) 2016 Powerventure Semiconductor Ltd.
#include <linux/err.h>
#include <linux/i2c.h>
@ -345,9 +335,11 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
if (reg_val & PV88080_E_VDD_FLT) {
for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
if (chip->rdev[i] != NULL) {
regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
regulator_unlock(chip->rdev[i]);
}
}
@ -362,9 +354,11 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
if (reg_val & PV88080_E_OVER_TEMP) {
for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
if (chip->rdev[i] != NULL) {
regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
regulator_unlock(chip->rdev[i]);
}
}

View File

@ -1,16 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* pv88080-regulator.h - Regulator definitions for PV88080
* Copyright (C) 2016 Powerventure Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PV88080_REGISTERS_H__

View File

@ -1,17 +1,7 @@
/*
* pv88090-regulator.c - Regulator device driver for PV88090
* Copyright (C) 2015 Powerventure Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// pv88090-regulator.c - Regulator device driver for PV88090
// Copyright (C) 2015 Powerventure Semiconductor Ltd.
#include <linux/err.h>
#include <linux/i2c.h>
@ -237,9 +227,11 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data)
if (reg_val & PV88090_E_VDD_FLT) {
for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
if (chip->rdev[i] != NULL) {
regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
regulator_unlock(chip->rdev[i]);
}
}
@ -254,9 +246,11 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data)
if (reg_val & PV88090_E_OVER_TEMP) {
for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
if (chip->rdev[i] != NULL) {
regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
regulator_unlock(chip->rdev[i]);
}
}

View File

@ -1,16 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* pv88090-regulator.h - Regulator definitions for PV88090
* Copyright (C) 2015 Powerventure Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PV88090_REGISTERS_H__

View File

@ -47,18 +47,13 @@ struct rc5t583_regulator_info {
struct regulator_desc desc;
};
struct rc5t583_regulator {
struct rc5t583_regulator_info *reg_info;
struct regulator_dev *rdev;
};
static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
{
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
struct rc5t583_regulator_info *reg_info = rdev_get_drvdata(rdev);
int vsel = regulator_get_voltage_sel_regmap(rdev);
int curr_uV = regulator_list_voltage_linear(rdev, vsel);
return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us);
return DIV_ROUND_UP(curr_uV, reg_info->enable_uv_per_us);
}
static const struct regulator_ops rc5t583_ops = {
@ -120,8 +115,6 @@ static int rc5t583_regulator_probe(struct platform_device *pdev)
struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
struct regulator_config config = { };
struct rc5t583_regulator *reg = NULL;
struct rc5t583_regulator *regs;
struct regulator_dev *rdev;
struct rc5t583_regulator_info *ri;
int ret;
@ -132,18 +125,8 @@ static int rc5t583_regulator_probe(struct platform_device *pdev)
return -ENODEV;
}
regs = devm_kcalloc(&pdev->dev,
RC5T583_REGULATOR_MAX,
sizeof(struct rc5t583_regulator),
GFP_KERNEL);
if (!regs)
return -ENOMEM;
for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
reg = &regs[id];
ri = &rc5t583_reg_info[id];
reg->reg_info = ri;
if (ri->deepsleep_id == RC5T583_DS_NONE)
goto skip_ext_pwr_config;
@ -163,7 +146,7 @@ static int rc5t583_regulator_probe(struct platform_device *pdev)
skip_ext_pwr_config:
config.dev = &pdev->dev;
config.init_data = pdata->reg_init_data[id];
config.driver_data = reg;
config.driver_data = ri;
config.regmap = rc5t583->regmap;
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
@ -172,9 +155,7 @@ skip_ext_pwr_config:
ri->desc.name);
return PTR_ERR(rdev);
}
reg->rdev = rdev;
}
platform_set_drvdata(pdev, regs);
return 0;
}

View File

@ -46,7 +46,7 @@ static const struct regulator_ops rn5t618_reg_ops = {
.vsel_mask = (vmask), \
}
static struct regulator_desc rn5t567_regulators[] = {
static const struct regulator_desc rn5t567_regulators[] = {
/* DCDC */
REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
@ -63,7 +63,7 @@ static struct regulator_desc rn5t567_regulators[] = {
REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
};
static struct regulator_desc rn5t618_regulators[] = {
static const struct regulator_desc rn5t618_regulators[] = {
/* DCDC */
REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
@ -79,7 +79,7 @@ static struct regulator_desc rn5t618_regulators[] = {
REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
};
static struct regulator_desc rc5t619_regulators[] = {
static const struct regulator_desc rc5t619_regulators[] = {
/* DCDC */
REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
@ -107,7 +107,7 @@ static int rn5t618_regulator_probe(struct platform_device *pdev)
struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct regulator_dev *rdev;
struct regulator_desc *regulators;
const struct regulator_desc *regulators;
int i;
int num_regulators = 0;

View File

@ -17,10 +17,7 @@
#include <linux/mfd/samsung/core.h>
#include <linux/mfd/samsung/s2mpa01.h>
#define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators)
struct s2mpa01_info {
struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX];
int ramp_delay24;
int ramp_delay3;
int ramp_delay5;
@ -232,6 +229,8 @@ static const struct regulator_ops s2mpa01_buck_ops = {
#define regulator_desc_ldo(num, step) { \
.name = "LDO"#num, \
.of_match = of_match_ptr("LDO"#num), \
.regulators_node = of_match_ptr("regulators"), \
.id = S2MPA01_LDO##num, \
.ops = &s2mpa01_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
@ -247,6 +246,8 @@ static const struct regulator_ops s2mpa01_buck_ops = {
#define regulator_desc_buck1_4(num) { \
.name = "BUCK"#num, \
.of_match = of_match_ptr("BUCK"#num), \
.regulators_node = of_match_ptr("regulators"), \
.id = S2MPA01_BUCK##num, \
.ops = &s2mpa01_buck_ops, \
.type = REGULATOR_VOLTAGE, \
@ -263,6 +264,8 @@ static const struct regulator_ops s2mpa01_buck_ops = {
#define regulator_desc_buck5 { \
.name = "BUCK5", \
.of_match = of_match_ptr("BUCK5"), \
.regulators_node = of_match_ptr("regulators"), \
.id = S2MPA01_BUCK5, \
.ops = &s2mpa01_buck_ops, \
.type = REGULATOR_VOLTAGE, \
@ -279,6 +282,8 @@ static const struct regulator_ops s2mpa01_buck_ops = {
#define regulator_desc_buck6_10(num, min, step) { \
.name = "BUCK"#num, \
.of_match = of_match_ptr("BUCK"#num), \
.regulators_node = of_match_ptr("regulators"), \
.id = S2MPA01_BUCK##num, \
.ops = &s2mpa01_buck_ops, \
.type = REGULATOR_VOLTAGE, \
@ -336,9 +341,7 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
{
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
struct device_node *reg_np = NULL;
struct regulator_config config = { };
struct of_regulator_match *rdata;
struct s2mpa01_info *s2mpa01;
int i;
@ -346,39 +349,15 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
if (!s2mpa01)
return -ENOMEM;
rdata = s2mpa01->rdata;
for (i = 0; i < S2MPA01_REGULATOR_CNT; i++)
rdata[i].name = regulators[i].name;
if (iodev->dev->of_node) {
reg_np = of_get_child_by_name(iodev->dev->of_node,
"regulators");
if (!reg_np) {
dev_err(&pdev->dev,
"could not find regulators sub-node\n");
return -EINVAL;
}
of_regulator_match(&pdev->dev, reg_np, rdata,
S2MPA01_REGULATOR_MAX);
of_node_put(reg_np);
}
platform_set_drvdata(pdev, s2mpa01);
config.dev = &pdev->dev;
config.dev = iodev->dev;
config.regmap = iodev->regmap_pmic;
config.driver_data = s2mpa01;
for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) {
struct regulator_dev *rdev;
if (pdata)
config.init_data = pdata->regulators[i].initdata;
else
config.init_data = rdata[i].init_data;
if (reg_np)
config.of_node = rdata[i].of_node;
rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);

View File

@ -146,7 +146,7 @@ static const struct regulator_ops sc2731_regu_linear_ops = {
.vsel_mask = vmask, \
}
static struct regulator_desc regulators[] = {
static const struct regulator_desc regulators[] = {
SC2731_REGU_LINEAR(BUCK_CPU0, SC2731_POWER_PD_SW,
SC2731_DCDC_CPU0_PD_MASK, SC2731_DCDC_CPU0_VOL,
SC2731_DCDC_CPU0_VOL_MASK, 3125, 400000, 1996875),

View File

@ -1,21 +1,9 @@
/*
* sky81452-regulator.c SKY81452 regulator driver
*
* Copyright 2014 Skyworks Solutions Inc.
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-2.0
//
// sky81452-regulator.c SKY81452 regulator driver
//
// Copyright 2014 Skyworks Solutions Inc.
// Author : Gyungoh Yoo <jack.yoo@skyworksinc.com>
#include <linux/module.h>
#include <linux/kernel.h>
@ -34,7 +22,7 @@
#define SKY81452_LEN 0x40
#define SKY81452_LOUT 0x1F
static struct regulator_ops sky81452_reg_ops = {
static const struct regulator_ops sky81452_reg_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap,

View File

@ -0,0 +1,186 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) STMicroelectronics 2019
// Authors: Gabriel Fernandez <gabriel.fernandez@st.com>
// Pascal Paillet <p.paillet@st.com>.
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
/*
* Registers description
*/
#define REG_PWR_CR3 0x0C
#define USB_3_3_EN BIT(24)
#define USB_3_3_RDY BIT(26)
#define REG_1_8_EN BIT(28)
#define REG_1_8_RDY BIT(29)
#define REG_1_1_EN BIT(30)
#define REG_1_1_RDY BIT(31)
/* list of supported regulators */
enum {
PWR_REG11,
PWR_REG18,
PWR_USB33,
STM32PWR_REG_NUM_REGS
};
static u32 ready_mask_table[STM32PWR_REG_NUM_REGS] = {
[PWR_REG11] = REG_1_1_RDY,
[PWR_REG18] = REG_1_8_RDY,
[PWR_USB33] = USB_3_3_RDY,
};
struct stm32_pwr_reg {
void __iomem *base;
u32 ready_mask;
};
static int stm32_pwr_reg_is_ready(struct regulator_dev *rdev)
{
struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
u32 val;
val = readl_relaxed(priv->base + REG_PWR_CR3);
return (val & priv->ready_mask);
}
static int stm32_pwr_reg_is_enabled(struct regulator_dev *rdev)
{
struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
u32 val;
val = readl_relaxed(priv->base + REG_PWR_CR3);
return (val & rdev->desc->enable_mask);
}
static int stm32_pwr_reg_enable(struct regulator_dev *rdev)
{
struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
int ret;
u32 val;
val = readl_relaxed(priv->base + REG_PWR_CR3);
val |= rdev->desc->enable_mask;
writel_relaxed(val, priv->base + REG_PWR_CR3);
/* use an arbitrary timeout of 20ms */
ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, val,
100, 20 * 1000);
if (ret)
dev_err(&rdev->dev, "regulator enable timed out!\n");
return ret;
}
static int stm32_pwr_reg_disable(struct regulator_dev *rdev)
{
struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
int ret;
u32 val;
val = readl_relaxed(priv->base + REG_PWR_CR3);
val &= ~rdev->desc->enable_mask;
writel_relaxed(val, priv->base + REG_PWR_CR3);
/* use an arbitrary timeout of 20ms */
ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val,
100, 20 * 1000);
if (ret)
dev_err(&rdev->dev, "regulator disable timed out!\n");
return ret;
}
static const struct regulator_ops stm32_pwr_reg_ops = {
.enable = stm32_pwr_reg_enable,
.disable = stm32_pwr_reg_disable,
.is_enabled = stm32_pwr_reg_is_enabled,
};
#define PWR_REG(_id, _name, _volt, _en, _supply) \
[_id] = { \
.id = _id, \
.name = _name, \
.of_match = of_match_ptr(_name), \
.n_voltages = 1, \
.type = REGULATOR_VOLTAGE, \
.fixed_uV = _volt, \
.ops = &stm32_pwr_reg_ops, \
.enable_mask = _en, \
.owner = THIS_MODULE, \
.supply_name = _supply, \
} \
static const struct regulator_desc stm32_pwr_desc[] = {
PWR_REG(PWR_REG11, "reg11", 1100000, REG_1_1_EN, "vdd"),
PWR_REG(PWR_REG18, "reg18", 1800000, REG_1_8_EN, "vdd"),
PWR_REG(PWR_USB33, "usb33", 3300000, USB_3_3_EN, "vdd_3v3_usbfs"),
};
static int stm32_pwr_regulator_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct stm32_pwr_reg *priv;
void __iomem *base;
struct regulator_dev *rdev;
struct regulator_config config = { };
int i, ret = 0;
base = of_iomap(np, 0);
if (!base) {
dev_err(&pdev->dev, "Unable to map IO memory\n");
return -ENOMEM;
}
config.dev = &pdev->dev;
for (i = 0; i < STM32PWR_REG_NUM_REGS; i++) {
priv = devm_kzalloc(&pdev->dev, sizeof(struct stm32_pwr_reg),
GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->base = base;
priv->ready_mask = ready_mask_table[i];
config.driver_data = priv;
rdev = devm_regulator_register(&pdev->dev,
&stm32_pwr_desc[i],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev,
"Failed to register regulator: %d\n", ret);
break;
}
}
return ret;
}
static const struct of_device_id stm32_pwr_of_match[] = {
{ .compatible = "st,stm32mp1,pwr-reg", },
{},
};
MODULE_DEVICE_TABLE(of, stm32_pwr_of_match);
static struct platform_driver stm32_pwr_driver = {
.probe = stm32_pwr_regulator_probe,
.driver = {
.name = "stm32-pwr-regulator",
.of_match_table = of_match_ptr(stm32_pwr_of_match),
},
};
module_platform_driver(stm32_pwr_driver);
MODULE_DESCRIPTION("STM32MP1 PWR voltage regulator driver");
MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
MODULE_LICENSE("GPL v2");

View File

@ -22,12 +22,6 @@
*/
#define SY8106A_GO_BIT BIT(7)
struct sy8106a {
struct regulator_dev *rdev;
struct regmap *regmap;
u32 fixed_voltage;
};
static const struct regmap_config sy8106a_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@ -70,36 +64,32 @@ static const struct regulator_desc sy8106a_reg = {
static int sy8106a_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct sy8106a *chip;
struct device *dev = &i2c->dev;
struct regulator_dev *rdev = NULL;
struct regulator_dev *rdev;
struct regulator_config config = { };
struct regmap *regmap;
unsigned int reg, vsel;
u32 fixed_voltage;
int error;
chip = devm_kzalloc(&i2c->dev, sizeof(struct sy8106a), GFP_KERNEL);
if (!chip)
return -ENOMEM;
error = of_property_read_u32(dev->of_node, "silergy,fixed-microvolt",
&chip->fixed_voltage);
&fixed_voltage);
if (error)
return error;
if (chip->fixed_voltage < SY8106A_MIN_MV * 1000 ||
chip->fixed_voltage > SY8106A_MAX_MV * 1000)
if (fixed_voltage < SY8106A_MIN_MV * 1000 ||
fixed_voltage > SY8106A_MAX_MV * 1000)
return -EINVAL;
chip->regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config);
if (IS_ERR(chip->regmap)) {
error = PTR_ERR(chip->regmap);
regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config);
if (IS_ERR(regmap)) {
error = PTR_ERR(regmap);
dev_err(dev, "Failed to allocate register map: %d\n", error);
return error;
}
config.dev = &i2c->dev;
config.regmap = chip->regmap;
config.driver_data = chip;
config.regmap = regmap;
config.of_node = dev->of_node;
config.init_data = of_get_regulator_init_data(dev, dev->of_node,
@ -109,15 +99,15 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
/* Ensure GO_BIT is enabled when probing */
error = regmap_read(chip->regmap, SY8106A_REG_VOUT1_SEL, &reg);
error = regmap_read(regmap, SY8106A_REG_VOUT1_SEL, &reg);
if (error)
return error;
if (!(reg & SY8106A_GO_BIT)) {
vsel = (chip->fixed_voltage / 1000 - SY8106A_MIN_MV) /
vsel = (fixed_voltage / 1000 - SY8106A_MIN_MV) /
SY8106A_STEP_MV;
error = regmap_write(chip->regmap, SY8106A_REG_VOUT1_SEL,
error = regmap_write(regmap, SY8106A_REG_VOUT1_SEL,
vsel | SY8106A_GO_BIT);
if (error)
return error;
@ -131,10 +121,6 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c,
return error;
}
chip->rdev = rdev;
i2c_set_clientdata(i2c, chip);
return 0;
}

View File

@ -115,7 +115,6 @@ static struct tps_info tps6507x_pmic_regs[] = {
struct tps6507x_pmic {
struct regulator_desc desc[TPS6507X_NUM_REGULATOR];
struct tps6507x_dev *mfd;
struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR];
struct tps_info *info[TPS6507X_NUM_REGULATOR];
struct mutex io_lock;
};
@ -349,7 +348,7 @@ static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev,
return tps6507x_pmic_reg_write(tps, reg, data);
}
static struct regulator_ops tps6507x_pmic_ops = {
static const struct regulator_ops tps6507x_pmic_ops = {
.is_enabled = tps6507x_pmic_is_enabled,
.enable = tps6507x_pmic_enable,
.disable = tps6507x_pmic_disable,
@ -359,66 +358,20 @@ static struct regulator_ops tps6507x_pmic_ops = {
.map_voltage = regulator_map_voltage_ascend,
};
static struct of_regulator_match tps6507x_matches[] = {
{ .name = "VDCDC1"},
{ .name = "VDCDC2"},
{ .name = "VDCDC3"},
{ .name = "LDO1"},
{ .name = "LDO2"},
};
static struct tps6507x_board *tps6507x_parse_dt_reg_data(
struct platform_device *pdev,
struct of_regulator_match **tps6507x_reg_matches)
static int tps6507x_pmic_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct tps6507x_board *tps_board;
struct device_node *np = pdev->dev.parent->of_node;
struct device_node *regulators;
struct of_regulator_match *matches;
struct regulator_init_data *reg_data;
int idx = 0, count, ret;
struct tps6507x_pmic *tps = config->driver_data;
struct tps_info *info = tps->info[desc->id];
u32 prop;
int ret;
tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board),
GFP_KERNEL);
if (!tps_board)
return NULL;
ret = of_property_read_u32(np, "ti,defdcdc_default", &prop);
if (!ret)
info->defdcdc_default = prop;
regulators = of_get_child_by_name(np, "regulators");
if (!regulators) {
dev_err(&pdev->dev, "regulator node not found\n");
return NULL;
}
count = ARRAY_SIZE(tps6507x_matches);
matches = tps6507x_matches;
ret = of_regulator_match(&pdev->dev, regulators, matches, count);
of_node_put(regulators);
if (ret < 0) {
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
ret);
return NULL;
}
*tps6507x_reg_matches = matches;
reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data)
* TPS6507X_NUM_REGULATOR), GFP_KERNEL);
if (!reg_data)
return NULL;
tps_board->tps6507x_pmic_init_data = reg_data;
for (idx = 0; idx < count; idx++) {
if (!matches[idx].init_data || !matches[idx].of_node)
continue;
memcpy(&reg_data[idx], matches[idx].init_data,
sizeof(struct regulator_init_data));
}
return tps_board;
return 0;
}
static int tps6507x_pmic_probe(struct platform_device *pdev)
@ -426,14 +379,11 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
struct tps_info *info = &tps6507x_pmic_regs[0];
struct regulator_config config = { };
struct regulator_init_data *init_data;
struct regulator_init_data *init_data = NULL;
struct regulator_dev *rdev;
struct tps6507x_pmic *tps;
struct tps6507x_board *tps_board;
struct of_regulator_match *tps6507x_reg_matches = NULL;
int i;
int error;
unsigned int prop;
/**
* tps_board points to pmic related constants
@ -441,20 +391,8 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
*/
tps_board = dev_get_platdata(tps6507x_dev->dev);
if (IS_ENABLED(CONFIG_OF) && !tps_board &&
tps6507x_dev->dev->of_node)
tps_board = tps6507x_parse_dt_reg_data(pdev,
&tps6507x_reg_matches);
if (!tps_board)
return -EINVAL;
/**
* init_data points to array of regulator_init structures
* coming from the board-evm file.
*/
init_data = tps_board->tps6507x_pmic_init_data;
if (!init_data)
return -EINVAL;
if (tps_board)
init_data = tps_board->tps6507x_pmic_init_data;
tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
@ -468,13 +406,16 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) {
/* Register the regulators */
tps->info[i] = info;
if (init_data->driver_data) {
if (init_data && init_data->driver_data) {
struct tps6507x_reg_platform_data *data =
init_data->driver_data;
tps->info[i]->defdcdc_default = data->defdcdc_default;
info->defdcdc_default = data->defdcdc_default;
}
tps->desc[i].name = info->name;
tps->desc[i].of_match = of_match_ptr(info->name);
tps->desc[i].regulators_node = of_match_ptr("regulators");
tps->desc[i].of_parse_cb = tps6507x_pmic_of_parse_cb;
tps->desc[i].id = i;
tps->desc[i].n_voltages = info->table_len;
tps->desc[i].volt_table = info->table;
@ -486,17 +427,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
config.init_data = init_data;
config.driver_data = tps;
if (tps6507x_reg_matches) {
error = of_property_read_u32(
tps6507x_reg_matches[i].of_node,
"ti,defdcdc_default", &prop);
if (!error)
tps->info[i]->defdcdc_default = prop;
config.of_node = tps6507x_reg_matches[i].of_node;
}
rdev = devm_regulator_register(&pdev->dev, &tps->desc[i],
&config);
if (IS_ERR(rdev)) {
@ -505,9 +435,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
pdev->name);
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
tps->rdev[i] = rdev;
}
tps6507x_dev->pmic = tps;

View File

@ -90,8 +90,8 @@ static const struct regulator_linear_range tps65086_buck345_25mv_ranges[] = {
static const struct regulator_linear_range tps65086_ldoa1_ranges[] = {
REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000),
REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xA, 100000),
REGULATOR_LINEAR_RANGE(2700000, 0xB, 0xD, 150000),
REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xB, 100000),
REGULATOR_LINEAR_RANGE(2850000, 0xC, 0xD, 150000),
REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0),
};

View File

@ -55,10 +55,7 @@ struct tps65132_reg_pdata {
struct tps65132_regulator {
struct device *dev;
struct regmap *rmap;
struct regulator_desc *rdesc[TPS65132_MAX_REGULATORS];
struct tps65132_reg_pdata reg_pdata[TPS65132_MAX_REGULATORS];
struct regulator_dev *rdev[TPS65132_MAX_REGULATORS];
};
static int tps65132_regulator_enable(struct regulator_dev *rdev)
@ -120,7 +117,7 @@ static int tps65132_regulator_is_enabled(struct regulator_dev *rdev)
return 1;
}
static struct regulator_ops tps65132_regulator_ops = {
static const struct regulator_ops tps65132_regulator_ops = {
.enable = tps65132_regulator_enable,
.disable = tps65132_regulator_disable,
.is_enabled = tps65132_regulator_is_enabled,
@ -196,7 +193,7 @@ static int tps65132_of_parse_cb(struct device_node *np,
.owner = THIS_MODULE, \
}
static struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = {
static const struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = {
TPS65132_REGULATOR_DESC(VPOS, outp),
TPS65132_REGULATOR_DESC(VNEG, outn),
};
@ -225,6 +222,8 @@ static int tps65132_probe(struct i2c_client *client,
{
struct device *dev = &client->dev;
struct tps65132_regulator *tps;
struct regulator_dev *rdev;
struct regmap *rmap;
struct regulator_config config = { };
int id;
int ret;
@ -233,9 +232,9 @@ static int tps65132_probe(struct i2c_client *client,
if (!tps)
return -ENOMEM;
tps->rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config);
if (IS_ERR(tps->rmap)) {
ret = PTR_ERR(tps->rmap);
rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config);
if (IS_ERR(rmap)) {
ret = PTR_ERR(rmap);
dev_err(dev, "regmap init failed: %d\n", ret);
return ret;
}
@ -244,18 +243,16 @@ static int tps65132_probe(struct i2c_client *client,
tps->dev = dev;
for (id = 0; id < TPS65132_MAX_REGULATORS; ++id) {
tps->rdesc[id] = &tps_regs_desc[id];
config.regmap = tps->rmap;
config.regmap = rmap;
config.dev = dev;
config.driver_data = tps;
tps->rdev[id] = devm_regulator_register(dev,
tps->rdesc[id], &config);
if (IS_ERR(tps->rdev[id])) {
ret = PTR_ERR(tps->rdev[id]);
rdev = devm_regulator_register(dev, &tps_regs_desc[id],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "regulator %s register failed: %d\n",
tps->rdesc[id]->name, ret);
tps_regs_desc[id].name, ret);
return ret;
}
}

View File

@ -58,8 +58,7 @@ static const unsigned int LDO1_VSEL_table[] = {
static const struct regulator_linear_range tps65217_uv1_ranges[] = {
REGULATOR_LINEAR_RANGE(900000, 0, 24, 25000),
REGULATOR_LINEAR_RANGE(1550000, 25, 30, 50000),
REGULATOR_LINEAR_RANGE(1850000, 31, 52, 50000),
REGULATOR_LINEAR_RANGE(1550000, 25, 52, 50000),
REGULATOR_LINEAR_RANGE(3000000, 53, 55, 100000),
REGULATOR_LINEAR_RANGE(3300000, 56, 63, 0),
};
@ -150,7 +149,7 @@ static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev)
}
/* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */
static struct regulator_ops tps65217_pmic_ops = {
static const struct regulator_ops tps65217_pmic_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = tps65217_pmic_enable,
.disable = tps65217_pmic_disable,
@ -163,7 +162,7 @@ static struct regulator_ops tps65217_pmic_ops = {
};
/* Operations permitted on LDO1 */
static struct regulator_ops tps65217_pmic_ldo1_ops = {
static const struct regulator_ops tps65217_pmic_ldo1_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = tps65217_pmic_enable,
.disable = tps65217_pmic_disable,

View File

@ -29,7 +29,8 @@
#include <linux/mfd/tps65218.h>
#define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
_em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \
_em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm, \
_ct, _ncl) \
{ \
.name = _name, \
.of_match = _of, \
@ -42,6 +43,8 @@
.vsel_mask = _vm, \
.csel_reg = _cr, \
.csel_mask = _cm, \
.curr_table = _ct, \
.n_current_limits = _ncl, \
.enable_reg = _er, \
.enable_mask = _em, \
.volt_table = NULL, \
@ -162,7 +165,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
}
/* Operations permitted on DCDC1, DCDC2 */
static struct regulator_ops tps65218_dcdc12_ops = {
static const struct regulator_ops tps65218_dcdc12_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = tps65218_pmic_enable,
.disable = tps65218_pmic_disable,
@ -176,7 +179,7 @@ static struct regulator_ops tps65218_dcdc12_ops = {
};
/* Operations permitted on DCDC3, DCDC4 and LDO1 */
static struct regulator_ops tps65218_ldo1_dcdc34_ops = {
static const struct regulator_ops tps65218_ldo1_dcdc34_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = tps65218_pmic_enable,
.disable = tps65218_pmic_disable,
@ -188,8 +191,7 @@ static struct regulator_ops tps65218_ldo1_dcdc34_ops = {
.set_suspend_disable = tps65218_pmic_set_suspend_disable,
};
static const int ls3_currents[] = { 100000, 200000, 500000, 1000000 };
static const unsigned int ls3_currents[] = { 100000, 200000, 500000, 1000000 };
static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev,
int lim_uA)
@ -229,33 +231,17 @@ static int tps65218_pmic_set_current_limit(struct regulator_dev *dev,
TPS65218_PROTECT_L1);
}
static int tps65218_pmic_get_current_limit(struct regulator_dev *dev)
{
int retval;
unsigned int index;
struct tps65218 *tps = rdev_get_drvdata(dev);
retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index);
if (retval < 0)
return retval;
index = (index & dev->desc->csel_mask) >>
__builtin_ctz(dev->desc->csel_mask);
return ls3_currents[index];
}
static struct regulator_ops tps65218_ls23_ops = {
static const struct regulator_ops tps65218_ls23_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = tps65218_pmic_enable,
.disable = tps65218_pmic_disable,
.set_input_current_limit = tps65218_pmic_set_input_current_lim,
.set_current_limit = tps65218_pmic_set_current_limit,
.get_current_limit = tps65218_pmic_get_current_limit,
.get_current_limit = regulator_get_current_limit_regmap,
};
/* Operations permitted on DCDC5, DCDC6 */
static struct regulator_ops tps65218_dcdc56_pmic_ops = {
static const struct regulator_ops tps65218_dcdc56_pmic_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = tps65218_pmic_enable,
.disable = tps65218_pmic_disable,
@ -270,53 +256,57 @@ static const struct regulator_desc regulators[] = {
TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges,
2, 4000, 0, TPS65218_REG_SEQ3,
TPS65218_SEQ3_DC1_SEQ_MASK),
TPS65218_SEQ3_DC1_SEQ_MASK, NULL, 0),
TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2,
REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64,
TPS65218_REG_CONTROL_DCDC2,
TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges,
2, 4000, 0, TPS65218_REG_SEQ3,
TPS65218_SEQ3_DC2_SEQ_MASK),
TPS65218_SEQ3_DC2_SEQ_MASK, NULL, 0),
TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3,
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REG_CONTROL_DCDC3,
TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2,
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK),
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK,
NULL, 0),
TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4,
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53,
TPS65218_REG_CONTROL_DCDC4,
TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2,
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK),
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK,
NULL, 0),
TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5,
REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1,
-1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0,
0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5,
TPS65218_SEQ5_DC5_SEQ_MASK),
TPS65218_SEQ5_DC5_SEQ_MASK, NULL, 0),
TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6,
REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1,
-1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0,
0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5,
TPS65218_SEQ5_DC6_SEQ_MASK),
TPS65218_SEQ5_DC6_SEQ_MASK, NULL, 0),
TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1,
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REG_CONTROL_LDO1,
TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges,
2, 0, 0, TPS65218_REG_SEQ6,
TPS65218_SEQ6_LDO1_SEQ_MASK),
TPS65218_SEQ6_LDO1_SEQ_MASK, NULL, 0),
TPS65218_REGULATOR("LS2", "regulator-ls2", TPS65218_LS_2,
REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0,
TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS2_EN,
TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS2ILIM_MASK,
NULL, 0, 0, 0, 0, 0),
NULL, 0, 0, 0, 0, 0, ls3_currents,
ARRAY_SIZE(ls3_currents)),
TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3,
REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0,
TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN,
TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK,
NULL, 0, 0, 0, 0, 0),
NULL, 0, 0, 0, 0, 0, ls3_currents,
ARRAY_SIZE(ls3_currents)),
};
static int tps65218_regulator_probe(struct platform_device *pdev)

View File

@ -137,7 +137,6 @@ struct tps6524x {
struct spi_device *spi;
struct mutex lock;
struct regulator_desc desc[N_REGULATORS];
struct regulator_dev *rdev[N_REGULATORS];
};
static int __read_reg(struct tps6524x *hw, int reg)
@ -565,7 +564,7 @@ static int is_supply_enabled(struct regulator_dev *rdev)
return read_field(hw, &info->enable);
}
static struct regulator_ops regulator_ops = {
static const struct regulator_ops regulator_ops = {
.is_enabled = is_supply_enabled,
.enable = enable_supply,
.disable = disable_supply,
@ -584,6 +583,7 @@ static int pmic_probe(struct spi_device *spi)
const struct supply_info *info = supply_info;
struct regulator_init_data *init_data;
struct regulator_config config = { };
struct regulator_dev *rdev;
int i;
init_data = dev_get_platdata(dev);
@ -616,10 +616,9 @@ static int pmic_probe(struct spi_device *spi)
config.init_data = init_data;
config.driver_data = hw;
hw->rdev[i] = devm_regulator_register(dev, &hw->desc[i],
&config);
if (IS_ERR(hw->rdev[i]))
return PTR_ERR(hw->rdev[i]);
rdev = devm_regulator_register(dev, &hw->desc[i], &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
}
return 0;

View File

@ -1,27 +1,13 @@
/*
* tps80031-regulator.c -- TI TPS80031 regulator driver.
*
* Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power
* Management with Power Path and Battery Charger.
*
* Copyright (c) 2012, NVIDIA Corporation.
*
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
* whether express or implied; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307, USA
*/
// SPDX-License-Identifier: GPL-2.0
//
// tps80031-regulator.c -- TI TPS80031 regulator driver.
//
// Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power
// Management with Power Path and Battery Charger.
//
// Copyright (c) 2012, NVIDIA Corporation.
//
// Author: Laxman Dewangan <ldewangan@nvidia.com>
#include <linux/delay.h>
#include <linux/err.h>
@ -85,7 +71,6 @@ struct tps80031_regulator_info {
struct tps80031_regulator {
struct device *dev;
struct regulator_dev *rdev;
struct tps80031_regulator_info *rinfo;
u8 device_flags;
@ -155,7 +140,7 @@ static int tps80031_reg_disable(struct regulator_dev *rdev)
}
/* DCDC voltages for the selector of 58 to 63 */
static int tps80031_dcdc_voltages[4][5] = {
static const int tps80031_dcdc_voltages[4][5] = {
{ 1350, 1500, 1800, 1900, 2100},
{ 1350, 1500, 1800, 1900, 2100},
{ 2084, 2315, 2778, 2932, 3241},
@ -378,7 +363,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
return ret;
}
static struct regulator_ops tps80031_dcdc_ops = {
static const struct regulator_ops tps80031_dcdc_ops = {
.list_voltage = tps80031_dcdc_list_voltage,
.set_voltage_sel = tps80031_dcdc_set_voltage_sel,
.get_voltage_sel = tps80031_dcdc_get_voltage_sel,
@ -387,7 +372,7 @@ static struct regulator_ops tps80031_dcdc_ops = {
.is_enabled = tps80031_reg_is_enabled,
};
static struct regulator_ops tps80031_ldo_ops = {
static const struct regulator_ops tps80031_ldo_ops = {
.list_voltage = tps80031_ldo_list_voltage,
.map_voltage = tps80031_ldo_map_voltage,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
@ -397,18 +382,18 @@ static struct regulator_ops tps80031_ldo_ops = {
.is_enabled = tps80031_reg_is_enabled,
};
static struct regulator_ops tps80031_vbus_sw_ops = {
static const struct regulator_ops tps80031_vbus_sw_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = tps80031_vbus_enable,
.disable = tps80031_vbus_disable,
.is_enabled = tps80031_vbus_is_enabled,
};
static struct regulator_ops tps80031_vbus_hw_ops = {
static const struct regulator_ops tps80031_vbus_hw_ops = {
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops tps80031_ext_reg_ops = {
static const struct regulator_ops tps80031_ext_reg_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = tps80031_reg_enable,
.disable = tps80031_reg_disable,
@ -736,7 +721,6 @@ static int tps80031_regulator_probe(struct platform_device *pdev)
ri->rinfo->desc.name);
return PTR_ERR(rdev);
}
ri->rdev = rdev;
}
platform_set_drvdata(pdev, pmic);

View File

@ -392,7 +392,7 @@ static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev)
return vsel;
}
static struct regulator_ops twl4030ldo_ops = {
static const struct regulator_ops twl4030ldo_ops = {
.list_voltage = twl4030ldo_list_voltage,
.set_voltage_sel = twl4030ldo_set_voltage_sel,
@ -430,14 +430,14 @@ static int twl4030smps_get_voltage(struct regulator_dev *rdev)
return vsel * 12500 + 600000;
}
static struct regulator_ops twl4030smps_ops = {
static const struct regulator_ops twl4030smps_ops = {
.set_voltage = twl4030smps_set_voltage,
.get_voltage = twl4030smps_get_voltage,
};
/*----------------------------------------------------------------------*/
static struct regulator_ops twl4030fixed_ops = {
static const struct regulator_ops twl4030fixed_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = twl4030reg_enable,

View File

@ -334,10 +334,8 @@ static int vctrl_init_vtable(struct platform_device *pdev)
ctrl_uV = regulator_list_voltage(ctrl_reg, i);
if (ctrl_uV < vrange_ctrl->min_uV ||
ctrl_uV > vrange_ctrl->max_uV) {
ctrl_uV > vrange_ctrl->max_uV)
rdesc->n_voltages--;
continue;
}
}
if (rdesc->n_voltages == 0) {

View File

@ -1,15 +1,6 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2012 ARM Limited
*/
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (C) 2012 ARM Limited
#define DRVNAME "vexpress-regulator"
#define pr_fmt(fmt) DRVNAME ": " fmt
@ -23,17 +14,10 @@
#include <linux/regulator/of_regulator.h>
#include <linux/vexpress.h>
struct vexpress_regulator {
struct regulator_desc desc;
struct regulator_dev *regdev;
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 = regmap_read(reg->regmap, 0, &uV);
unsigned int uV;
int err = regmap_read(regdev->regmap, 0, &uV);
return err ? err : uV;
}
@ -41,60 +25,58 @@ static int vexpress_regulator_get_voltage(struct regulator_dev *regdev)
static int vexpress_regulator_set_voltage(struct regulator_dev *regdev,
int min_uV, int max_uV, unsigned *selector)
{
struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
return regmap_write(reg->regmap, 0, min_uV);
return regmap_write(regdev->regmap, 0, min_uV);
}
static struct regulator_ops vexpress_regulator_ops_ro = {
static const struct regulator_ops vexpress_regulator_ops_ro = {
.get_voltage = vexpress_regulator_get_voltage,
};
static struct regulator_ops vexpress_regulator_ops = {
static const struct regulator_ops vexpress_regulator_ops = {
.get_voltage = vexpress_regulator_get_voltage,
.set_voltage = vexpress_regulator_set_voltage,
};
static int vexpress_regulator_probe(struct platform_device *pdev)
{
struct vexpress_regulator *reg;
struct regulator_desc *desc;
struct regulator_init_data *init_data;
struct regulator_config config = { };
struct regulator_dev *rdev;
struct regmap *regmap;
reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL);
if (!reg)
desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
reg->regmap = devm_regmap_init_vexpress_config(&pdev->dev);
if (IS_ERR(reg->regmap))
return PTR_ERR(reg->regmap);
regmap = devm_regmap_init_vexpress_config(&pdev->dev);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
reg->desc.name = dev_name(&pdev->dev);
reg->desc.type = REGULATOR_VOLTAGE;
reg->desc.owner = THIS_MODULE;
reg->desc.continuous_voltage_range = true;
desc->name = dev_name(&pdev->dev);
desc->type = REGULATOR_VOLTAGE;
desc->owner = THIS_MODULE;
desc->continuous_voltage_range = true;
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&reg->desc);
desc);
if (!init_data)
return -EINVAL;
init_data->constraints.apply_uV = 0;
if (init_data->constraints.min_uV && init_data->constraints.max_uV)
reg->desc.ops = &vexpress_regulator_ops;
desc->ops = &vexpress_regulator_ops;
else
reg->desc.ops = &vexpress_regulator_ops_ro;
desc->ops = &vexpress_regulator_ops_ro;
config.regmap = regmap;
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = reg;
config.of_node = pdev->dev.of_node;
reg->regdev = devm_regulator_register(&pdev->dev, &reg->desc, &config);
if (IS_ERR(reg->regdev))
return PTR_ERR(reg->regdev);
platform_set_drvdata(pdev, reg);
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
return 0;
}

View File

@ -1,15 +1,10 @@
/*
* wm831x-dcdc.c -- DC-DC buck convertor driver for the WM831x series
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// wm831x-dcdc.c -- DC-DC buck converter driver for the WM831x series
//
// Copyright 2009 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/module.h>
#include <linux/moduleparam.h>
@ -183,9 +178,11 @@ static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
{
struct wm831x_dcdc *dcdc = data;
regulator_lock(dcdc->regulator);
regulator_notifier_call_chain(dcdc->regulator,
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
regulator_unlock(dcdc->regulator);
return IRQ_HANDLED;
}
@ -194,9 +191,11 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
{
struct wm831x_dcdc *dcdc = data;
regulator_lock(dcdc->regulator);
regulator_notifier_call_chain(dcdc->regulator,
REGULATOR_EVENT_OVER_CURRENT,
NULL);
regulator_unlock(dcdc->regulator);
return IRQ_HANDLED;
}

View File

@ -1,15 +1,10 @@
/*
* wm831x-isink.c -- Current sink driver for the WM831x series
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// wm831x-isink.c -- Current sink driver for the WM831x series
//
// Copyright 2009 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/module.h>
#include <linux/moduleparam.h>
@ -92,57 +87,23 @@ static int wm831x_isink_is_enabled(struct regulator_dev *rdev)
return 0;
}
static int wm831x_isink_set_current(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct wm831x_isink *isink = rdev_get_drvdata(rdev);
struct wm831x *wm831x = isink->wm831x;
int ret, i;
for (i = 0; i < ARRAY_SIZE(wm831x_isinkv_values); i++) {
int val = wm831x_isinkv_values[i];
if (min_uA <= val && val <= max_uA) {
ret = wm831x_set_bits(wm831x, isink->reg,
WM831X_CS1_ISEL_MASK, i);
return ret;
}
}
return -EINVAL;
}
static int wm831x_isink_get_current(struct regulator_dev *rdev)
{
struct wm831x_isink *isink = rdev_get_drvdata(rdev);
struct wm831x *wm831x = isink->wm831x;
int ret;
ret = wm831x_reg_read(wm831x, isink->reg);
if (ret < 0)
return ret;
ret &= WM831X_CS1_ISEL_MASK;
if (ret > WM831X_ISINK_MAX_ISEL)
ret = WM831X_ISINK_MAX_ISEL;
return wm831x_isinkv_values[ret];
}
static const struct regulator_ops wm831x_isink_ops = {
.is_enabled = wm831x_isink_is_enabled,
.enable = wm831x_isink_enable,
.disable = wm831x_isink_disable,
.set_current_limit = wm831x_isink_set_current,
.get_current_limit = wm831x_isink_get_current,
.set_current_limit = regulator_set_current_limit_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
};
static irqreturn_t wm831x_isink_irq(int irq, void *data)
{
struct wm831x_isink *isink = data;
regulator_lock(isink->regulator);
regulator_notifier_call_chain(isink->regulator,
REGULATOR_EVENT_OVER_CURRENT,
NULL);
regulator_unlock(isink->regulator);
return IRQ_HANDLED;
}
@ -187,10 +148,15 @@ static int wm831x_isink_probe(struct platform_device *pdev)
isink->desc.ops = &wm831x_isink_ops;
isink->desc.type = REGULATOR_CURRENT;
isink->desc.owner = THIS_MODULE;
isink->desc.curr_table = wm831x_isinkv_values,
isink->desc.n_current_limits = ARRAY_SIZE(wm831x_isinkv_values),
isink->desc.csel_reg = isink->reg,
isink->desc.csel_mask = WM831X_CS1_ISEL_MASK,
config.dev = pdev->dev.parent;
config.init_data = pdata->isink[id];
config.driver_data = isink;
config.regmap = wm831x->regmap;
isink->regulator = devm_regulator_register(&pdev->dev, &isink->desc,
&config);

View File

@ -1,15 +1,10 @@
/*
* wm831x-ldo.c -- LDO driver for the WM831x series
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// wm831x-ldo.c -- LDO driver for the WM831x series
//
// Copyright 2009 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/module.h>
#include <linux/moduleparam.h>
@ -51,9 +46,11 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
{
struct wm831x_ldo *ldo = data;
regulator_lock(ldo->regulator);
regulator_notifier_call_chain(ldo->regulator,
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
regulator_unlock(ldo->regulator);
return IRQ_HANDLED;
}

View File

@ -1,16 +1,11 @@
/*
* wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC
*
* Copyright 2007, 2008 Wolfson Microelectronics PLC.
*
* Author: Liam Girdwood
* linux@wolfsonmicro.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC
//
// Copyright 2007, 2008 Wolfson Microelectronics PLC.
//
// Author: Liam Girdwood
// linux@wolfsonmicro.com
#include <linux/module.h>
#include <linux/moduleparam.h>
@ -28,7 +23,7 @@
#define WM8350_DCDC_MAX_VSEL 0x66
/* Microamps */
static const int isink_cur[] = {
static const unsigned int isink_cur[] = {
4,
5,
6,
@ -95,73 +90,6 @@ static const int isink_cur[] = {
223191
};
static int get_isink_val(int min_uA, int max_uA, u16 *setting)
{
int i;
for (i = 0; i < ARRAY_SIZE(isink_cur); i++) {
if (min_uA <= isink_cur[i] && max_uA >= isink_cur[i]) {
*setting = i;
return 0;
}
}
return -EINVAL;
}
static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA,
int max_uA)
{
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
int isink = rdev_get_id(rdev);
u16 val, setting;
int ret;
ret = get_isink_val(min_uA, max_uA, &setting);
if (ret != 0)
return ret;
switch (isink) {
case WM8350_ISINK_A:
val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) &
~WM8350_CS1_ISEL_MASK;
wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_A,
val | setting);
break;
case WM8350_ISINK_B:
val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) &
~WM8350_CS1_ISEL_MASK;
wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_B,
val | setting);
break;
default:
return -EINVAL;
}
return 0;
}
static int wm8350_isink_get_current(struct regulator_dev *rdev)
{
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
int isink = rdev_get_id(rdev);
u16 val;
switch (isink) {
case WM8350_ISINK_A:
val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) &
WM8350_CS1_ISEL_MASK;
break;
case WM8350_ISINK_B:
val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) &
WM8350_CS1_ISEL_MASK;
break;
default:
return 0;
}
return isink_cur[val];
}
/* turn on ISINK followed by DCDC */
static int wm8350_isink_enable(struct regulator_dev *rdev)
{
@ -982,8 +910,8 @@ static const struct regulator_ops wm8350_ldo_ops = {
};
static const struct regulator_ops wm8350_isink_ops = {
.set_current_limit = wm8350_isink_set_current,
.get_current_limit = wm8350_isink_get_current,
.set_current_limit = regulator_set_current_limit_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.enable = wm8350_isink_enable,
.disable = wm8350_isink_disable,
.is_enabled = wm8350_isink_is_enabled,
@ -1138,6 +1066,10 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.irq = WM8350_IRQ_CS1,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.curr_table = isink_cur,
.n_current_limits = ARRAY_SIZE(isink_cur),
.csel_reg = WM8350_CURRENT_SINK_DRIVER_A,
.csel_mask = WM8350_CS1_ISEL_MASK,
},
{
.name = "ISINKB",
@ -1146,6 +1078,10 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.irq = WM8350_IRQ_CS2,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.curr_table = isink_cur,
.n_current_limits = ARRAY_SIZE(isink_cur),
.csel_reg = WM8350_CURRENT_SINK_DRIVER_B,
.csel_mask = WM8350_CS2_ISEL_MASK,
},
};

View File

@ -1,16 +1,10 @@
/*
* Regulator support for WM8400
*
* Copyright 2008 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Regulator support for WM8400
//
// Copyright 2008 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/bug.h>
#include <linux/err.h>
@ -36,13 +30,12 @@ static const struct regulator_ops wm8400_ldo_ops = {
static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
struct regmap *rmap = rdev_get_regmap(dev);
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
u16 data[2];
int ret;
ret = wm8400_block_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 2,
data);
ret = regmap_bulk_read(rmap, WM8400_DCDC1_CONTROL_1 + offset, data, 2);
if (ret != 0)
return 0;
@ -63,36 +56,36 @@ static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev)
static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
struct regmap *rmap = rdev_get_regmap(dev);
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
int ret;
switch (mode) {
case REGULATOR_MODE_FAST:
/* Datasheet: active with force PWM */
ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset,
ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset,
WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM);
if (ret != 0)
return ret;
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
WM8400_DC1_ACTIVE);
case REGULATOR_MODE_NORMAL:
/* Datasheet: active */
ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset,
ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset,
WM8400_DC1_FRC_PWM, 0);
if (ret != 0)
return ret;
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
WM8400_DC1_ACTIVE);
case REGULATOR_MODE_IDLE:
/* Datasheet: standby */
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset,
WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0);
default:
return -EINVAL;
@ -195,7 +188,7 @@ static struct regulator_desc regulators[] = {
.id = WM8400_DCDC2,
.ops = &wm8400_dcdc_ops,
.enable_reg = WM8400_DCDC2_CONTROL_1,
.enable_mask = WM8400_DC1_ENA_MASK,
.enable_mask = WM8400_DC2_ENA_MASK,
.n_voltages = WM8400_DC2_VSEL_MASK + 1,
.vsel_reg = WM8400_DCDC2_CONTROL_1,
.vsel_mask = WM8400_DC2_VSEL_MASK,

View File

@ -1,15 +1,10 @@
/*
* wm8994-regulator.c -- Regulator driver for the WM8994
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// wm8994-regulator.c -- Regulator driver for the WM8994
//
// Copyright 2009 Wolfson Microelectronics PLC.
//
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
#include <linux/module.h>
#include <linux/moduleparam.h>

View File

@ -553,7 +553,6 @@ struct palmas_pmic {
struct palmas *palmas;
struct device *dev;
struct regulator_desc desc[PALMAS_NUM_REGS];
struct regulator_dev *rdev[PALMAS_NUM_REGS];
struct mutex mutex;
int smps123;

View File

@ -1213,6 +1213,6 @@
#define WM831X_LDO1_OK_WIDTH 1 /* LDO1_OK */
#define WM831X_ISINK_MAX_ISEL 55
extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1];
extern const unsigned int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1];
#endif

View File

@ -923,12 +923,4 @@ struct wm8400 {
#define WM8400_LINE_CMP_VTHD_SHIFT 0 /* LINE_CMP_VTHD - [3:0] */
#define WM8400_LINE_CMP_VTHD_WIDTH 4 /* LINE_CMP_VTHD - [3:0] */
int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data);
static inline int wm8400_set_bits(struct wm8400 *wm8400, u8 reg,
u16 mask, u16 val)
{
return regmap_update_bits(wm8400->regmap, reg, mask, val);
}
#endif

View File

@ -478,6 +478,11 @@ static inline int regulator_is_supported_voltage(struct regulator *regulator,
return 0;
}
static inline unsigned int regulator_get_linear_step(struct regulator *regulator)
{
return 0;
}
static inline int regulator_set_current_limit(struct regulator *regulator,
int min_uA, int max_uA)
{

View File

@ -1062,10 +1062,10 @@ static void anc_iir(struct snd_soc_component *component, unsigned int bnk,
snd_soc_component_update_bits(component, AB8500_ANCCONF1,
BIT(AB8500_ANCCONF1_ANCIIRINIT),
BIT(AB8500_ANCCONF1_ANCIIRINIT));
usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY*2);
snd_soc_component_update_bits(component, AB8500_ANCCONF1,
BIT(AB8500_ANCCONF1_ANCIIRINIT), 0);
usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY*2);
} else {
snd_soc_component_update_bits(component, AB8500_ANCCONF1,
BIT(AB8500_ANCCONF1_ANCIIRUPDATE),