mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
Merge branch 'regulator-5.2' into regulator-next
This commit is contained in:
commit
e2a23affe6
@ -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
|
||||
|
@ -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>;
|
||||
};
|
||||
};
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 = ®ulators[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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 = ®s[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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
®ulator->info->reg_desc);
|
||||
config.of_node = np;
|
||||
break;
|
||||
}
|
||||
}
|
||||
of_node_put(nproot);
|
||||
#endif
|
||||
}
|
||||
|
||||
regulator->rdev = devm_regulator_register(&pdev->dev,
|
||||
®ulator->info->reg_desc,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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__
|
||||
|
@ -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);
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 = <c3589_ ## _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 = <c3589->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 = <c3589_ ## _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 = <c3589->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, <c3589_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 = <c3589->regulator_descs[i];
|
||||
struct regulator_desc *desc = &rdesc->desc;
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_desc *desc = <c3589->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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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__
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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 = ®s[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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
®ulators[i], &config);
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
186
drivers/regulator/stm32-pwr.c
Normal file
186
drivers/regulator/stm32-pwr.c
Normal 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");
|
@ -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, ®);
|
||||
error = regmap_read(regmap, SY8106A_REG_VOUT1_SEL, ®);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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(®_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;
|
||||
|
@ -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),
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
®->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, ®->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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user