Commit 24ee65e4 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'regulator/topic/s5m8767',...

Merge remote-tracking branches 'regulator/topic/s5m8767', 'regulator/topic/st-pwm', 'regulator/topic/ti-abb', 'regulator/topic/tps51632', 'regulator/topic/tps62360', 'regulator/topic/tps6507x', 'regulator/topic/tps65090' and 'regulator/topic/tps65217' into regulator-next
...@@ -69,13 +69,16 @@ sub-node should be of the format as listed below. ...@@ -69,13 +69,16 @@ sub-node should be of the format as listed below.
}; };
}; };
The above regulator entries are defined in regulator bindings documentation The above regulator entries are defined in regulator bindings documentation
except op_mode description. except these properties:
- op_mode: describes the different operating modes of the LDO's with - op_mode: describes the different operating modes of the LDO's with
power mode change in SOC. The different possible values are, power mode change in SOC. The different possible values are,
0 - always off mode 0 - always off mode
1 - on in normal mode 1 - on in normal mode
2 - low power mode 2 - low power mode
3 - suspend mode 3 - suspend mode
- s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one
GPIO controlling this regulator (enable/disable); This is
valid only for buck9.
The following are the names of the regulators that the s5m8767 pmic block The following are the names of the regulators that the s5m8767 pmic block
supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
...@@ -148,5 +151,13 @@ Example: ...@@ -148,5 +151,13 @@ Example:
regulator-always-on; regulator-always-on;
regulator-boot-on; regulator-boot-on;
}; };
vemmc_reg: BUCK9 {
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
op_mode = <3>; /* Standby Mode */
s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>;
};
}; };
}; };
...@@ -4,10 +4,14 @@ Required Properties: ...@@ -4,10 +4,14 @@ Required Properties:
- compatible: Should be one of: - compatible: Should be one of:
- "ti,abb-v1" for older SoCs like OMAP3 - "ti,abb-v1" for older SoCs like OMAP3
- "ti,abb-v2" for newer SoCs like OMAP4, OMAP5 - "ti,abb-v2" for newer SoCs like OMAP4, OMAP5
- "ti,abb-v3" for a generic definition where setup and control registers are
provided (example: DRA7)
- reg: Address and length of the register set for the device. It contains - reg: Address and length of the register set for the device. It contains
the information of registers in the same order as described by reg-names the information of registers in the same order as described by reg-names
- reg-names: Should contain the reg names - reg-names: Should contain the reg names
- "base-address" - contains base address of ABB module - "base-address" - contains base address of ABB module (ti,abb-v1,ti,abb-v2)
- "control-address" - contains control register address of ABB module (ti,abb-v3)
- "setup-address" - contains setup register address of ABB module (ti,abb-v3)
- "int-address" - contains address of interrupt register for ABB module - "int-address" - contains address of interrupt register for ABB module
(also see Optional properties) (also see Optional properties)
- #address-cell: should be 0 - #address-cell: should be 0
......
...@@ -448,6 +448,12 @@ config REGULATOR_S5M8767 ...@@ -448,6 +448,12 @@ config REGULATOR_S5M8767
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
supports DVS mode with 8bits of output voltage control. supports DVS mode with 8bits of output voltage control.
config REGULATOR_ST_PWM
tristate "STMicroelectronics PWM voltage regulator"
depends on ARCH_STI
help
This driver supports ST's PWM controlled voltage regulators.
config REGULATOR_TI_ABB config REGULATOR_TI_ABB
tristate "TI Adaptive Body Bias on-chip LDO" tristate "TI Adaptive Body Bias on-chip LDO"
depends on ARCH_OMAP depends on ARCH_OMAP
......
...@@ -61,6 +61,7 @@ obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o ...@@ -61,6 +61,7 @@ obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
......
...@@ -11,11 +11,8 @@ ...@@ -11,11 +11,8 @@
* *
*/ */
#include <linux/bug.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
...@@ -170,12 +167,11 @@ static unsigned int s5m8767_opmode_reg[][4] = { ...@@ -170,12 +167,11 @@ static unsigned int s5m8767_opmode_reg[][4] = {
{0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
}; };
static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id,
int *enable_ctrl) int *reg, int *enable_ctrl)
{ {
int i, reg_id = rdev_get_id(rdev); int i;
unsigned int mode; unsigned int mode;
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
switch (reg_id) { switch (reg_id) {
case S5M8767_LDO1 ... S5M8767_LDO2: case S5M8767_LDO1 ... S5M8767_LDO2:
...@@ -214,53 +210,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, ...@@ -214,53 +210,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
return 0; return 0;
} }
static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg;
int enable_ctrl;
unsigned int val;
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret == -EINVAL)
return 1;
else if (ret)
return ret;
ret = regmap_read(s5m8767->iodev->regmap_pmic, reg, &val);
if (ret)
return ret;
return (val & S5M8767_ENCTRL_MASK) == enable_ctrl;
}
static int s5m8767_reg_enable(struct regulator_dev *rdev)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg;
int enable_ctrl;
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret)
return ret;
return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg,
S5M8767_ENCTRL_MASK, enable_ctrl);
}
static int s5m8767_reg_disable(struct regulator_dev *rdev)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg, enable_ctrl;
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret)
return ret;
return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg,
S5M8767_ENCTRL_MASK, ~S5M8767_ENCTRL_MASK);
}
static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767)
{ {
int reg; int reg;
...@@ -410,9 +359,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, ...@@ -410,9 +359,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
static struct regulator_ops s5m8767_ops = { static struct regulator_ops s5m8767_ops = {
.list_voltage = regulator_list_voltage_linear, .list_voltage = regulator_list_voltage_linear,
.is_enabled = s5m8767_reg_is_enabled, .is_enabled = regulator_is_enabled_regmap,
.enable = s5m8767_reg_enable, .enable = regulator_enable_regmap,
.disable = s5m8767_reg_disable, .disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = s5m8767_set_voltage_sel, .set_voltage_sel = s5m8767_set_voltage_sel,
.set_voltage_time_sel = s5m8767_set_voltage_time_sel, .set_voltage_time_sel = s5m8767_set_voltage_time_sel,
...@@ -420,9 +369,9 @@ static struct regulator_ops s5m8767_ops = { ...@@ -420,9 +369,9 @@ static struct regulator_ops s5m8767_ops = {
static struct regulator_ops s5m8767_buck78_ops = { static struct regulator_ops s5m8767_buck78_ops = {
.list_voltage = regulator_list_voltage_linear, .list_voltage = regulator_list_voltage_linear,
.is_enabled = s5m8767_reg_is_enabled, .is_enabled = regulator_is_enabled_regmap,
.enable = s5m8767_reg_enable, .enable = regulator_enable_regmap,
.disable = s5m8767_reg_disable, .disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap,
}; };
...@@ -483,6 +432,66 @@ static struct regulator_desc regulators[] = { ...@@ -483,6 +432,66 @@ static struct regulator_desc regulators[] = {
s5m8767_regulator_desc(BUCK9), s5m8767_regulator_desc(BUCK9),
}; };
/*
* Enable GPIO control over BUCK9 in regulator_config for that regulator.
*/
static void s5m8767_regulator_config_ext_control(struct s5m8767_info *s5m8767,
struct sec_regulator_data *rdata,
struct regulator_config *config)
{
int i, mode = 0;
if (rdata->id != S5M8767_BUCK9)
return;
/* Check if opmode for regulator matches S5M8767_ENCTRL_USE_GPIO */
for (i = 0; i < s5m8767->num_regulators; i++) {
const struct sec_opmode_data *opmode = &s5m8767->opmode[i];
if (opmode->id == rdata->id) {
mode = s5m8767_opmode_reg[rdata->id][opmode->mode];
break;
}
}
if (mode != S5M8767_ENCTRL_USE_GPIO) {
dev_warn(s5m8767->dev,
"ext-control for %s: mismatched op_mode (%x), ignoring\n",
rdata->reg_node->name, mode);
return;
}
if (!gpio_is_valid(rdata->ext_control_gpio)) {
dev_warn(s5m8767->dev,
"ext-control for %s: GPIO not valid, ignoring\n",
rdata->reg_node->name);
return;
}
config->ena_gpio = rdata->ext_control_gpio;
config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
}
/*
* Turn on GPIO control over BUCK9.
*/
static int s5m8767_enable_ext_control(struct s5m8767_info *s5m8767,
struct regulator_dev *rdev)
{
int id = rdev_get_id(rdev);
int ret, reg, enable_ctrl;
if (id != S5M8767_BUCK9)
return -EINVAL;
ret = s5m8767_get_register(s5m8767, id, &reg, &enable_ctrl);
if (ret)
return ret;
return regmap_update_bits(s5m8767->iodev->regmap_pmic,
reg, S5M8767_ENCTRL_MASK,
S5M8767_ENCTRL_USE_GPIO << S5M8767_ENCTRL_SHIFT);
}
#ifdef CONFIG_OF #ifdef CONFIG_OF
static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev,
struct sec_platform_data *pdata, struct sec_platform_data *pdata,
...@@ -520,6 +529,16 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev, ...@@ -520,6 +529,16 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev,
return 0; return 0;
} }
static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev,
struct sec_regulator_data *rdata,
struct device_node *reg_np)
{
rdata->ext_control_gpio = of_get_named_gpio(reg_np,
"s5m8767,pmic-ext-control-gpios", 0);
if (!gpio_is_valid(rdata->ext_control_gpio))
rdata->ext_control_gpio = 0;
}
static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
struct sec_platform_data *pdata) struct sec_platform_data *pdata)
{ {
...@@ -546,19 +565,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, ...@@ -546,19 +565,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
pdata->num_regulators, GFP_KERNEL); pdata->num_regulators, GFP_KERNEL);
if (!rdata) { if (!rdata)
dev_err(iodev->dev,
"could not allocate memory for regulator data\n");
return -ENOMEM; return -ENOMEM;
}
rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) *
pdata->num_regulators, GFP_KERNEL); pdata->num_regulators, GFP_KERNEL);
if (!rmode) { if (!rmode)
dev_err(iodev->dev,
"could not allocate memory for regulator mode\n");
return -ENOMEM; return -ENOMEM;
}
pdata->regulators = rdata; pdata->regulators = rdata;
pdata->opmode = rmode; pdata->opmode = rmode;
...@@ -574,6 +587,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, ...@@ -574,6 +587,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
continue; continue;
} }
s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np);
rdata->id = i; rdata->id = i;
rdata->initdata = of_get_regulator_init_data( rdata->initdata = of_get_regulator_init_data(
&pdev->dev, reg_np); &pdev->dev, reg_np);
...@@ -922,6 +937,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) ...@@ -922,6 +937,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
const struct sec_voltage_desc *desc; const struct sec_voltage_desc *desc;
int id = pdata->regulators[i].id; int id = pdata->regulators[i].id;
int enable_reg, enable_val;
desc = reg_voltage_map[id]; desc = reg_voltage_map[id];
if (desc) { if (desc) {
...@@ -935,6 +951,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) ...@@ -935,6 +951,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
regulators[id].vsel_mask = 0x3f; regulators[id].vsel_mask = 0x3f;
else else
regulators[id].vsel_mask = 0xff; regulators[id].vsel_mask = 0xff;
s5m8767_get_register(s5m8767, id, &enable_reg,
&enable_val);
regulators[id].enable_reg = enable_reg;
regulators[id].enable_mask = S5M8767_ENCTRL_MASK;
regulators[id].enable_val = enable_val;
} }
config.dev = s5m8767->dev; config.dev = s5m8767->dev;
...@@ -942,6 +964,9 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) ...@@ -942,6 +964,9 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
config.driver_data = s5m8767; config.driver_data = s5m8767;
config.regmap = iodev->regmap_pmic; config.regmap = iodev->regmap_pmic;
config.of_node = pdata->regulators[i].reg_node; config.of_node = pdata->regulators[i].reg_node;
if (pdata->regulators[i].ext_control_gpio)
s5m8767_regulator_config_ext_control(s5m8767,
&pdata->regulators[i], &config);
rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id], rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id],
&config); &config);
...@@ -951,6 +976,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) ...@@ -951,6 +976,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
id); id);
return ret; return ret;
} }
if (pdata->regulators[i].ext_control_gpio) {
ret = s5m8767_enable_ext_control(s5m8767, rdev[i]);
if (ret < 0) {
dev_err(s5m8767->dev,
"failed to enable gpio control over %s: %d\n",
rdev[i]->desc->name, ret);
return ret;
}
}
} }
return 0; return 0;
......
/*
* Regulator driver for ST's PWM Regulators
*
* Copyright (C) 2014 - STMicroelectronics Inc.
*
* Author: Lee Jones <lee.jones@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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pwm.h>
#define ST_PWM_REG_PERIOD 8448
struct st_pwm_regulator_pdata {
const struct regulator_desc *desc;
struct st_pwm_voltages *duty_cycle_table;
};
struct st_pwm_regulator_data {
const struct st_pwm_regulator_pdata *pdata;
struct pwm_device *pwm;
bool enabled;
int state;
};
struct st_pwm_voltages {
unsigned int uV;
unsigned int dutycycle;
};
static int st_pwm_regulator_get_voltage_sel(struct regulator_dev *dev)
{
struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
return drvdata->state;
}
static int st_pwm_regulator_set_voltage_sel(struct regulator_dev *dev,
unsigned selector)
{
struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
int dutycycle;
int ret;
dutycycle = (ST_PWM_REG_PERIOD / 100) *
drvdata->pdata->duty_cycle_table[selector].dutycycle;
ret = pwm_config(drvdata->pwm, dutycycle, ST_PWM_REG_PERIOD);
if (ret) {
dev_err(&dev->dev, "Failed to configure PWM\n");
return ret;
}
drvdata->state = selector;
if (!drvdata->enabled) {
ret = pwm_enable(drvdata->pwm);
if (ret) {
dev_err(&dev->dev, "Failed to enable PWM\n");
return ret;
}
drvdata->enabled = true;
}
return 0;
}
static int st_pwm_regulator_list_voltage(struct regulator_dev *dev,
unsigned selector)
{
struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
if (selector >= dev->desc->n_voltages)
return -EINVAL;
return drvdata->pdata->duty_cycle_table[selector].uV;
}
static struct regulator_ops st_pwm_regulator_voltage_ops = {
.set_voltage_sel = st_pwm_regulator_set_voltage_sel,
.get_voltage_sel = st_pwm_regulator_get_voltage_sel,
.list_voltage = st_pwm_regulator_list_voltage,
.map_voltage = regulator_map_voltage_iterate,
};
static struct st_pwm_voltages b2105_duty_cycle_table[] = {
{ .uV = 1114000, .dutycycle = 0, },
{ .uV = 1095000, .dutycycle = 10, },
{ .uV = 1076000, .dutycycle = 20, },
{ .uV = 1056000, .dutycycle = 30, },
{ .uV = 1036000, .dutycycle = 40, },
{ .uV = 1016000, .dutycycle = 50, },
/* WARNING: Values above 50% duty-cycle cause boot failures. */
};
static const struct regulator_desc b2105_desc = {
.name = "b2105-pwm-regulator",
.ops = &st_pwm_regulator_voltage_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = ARRAY_SIZE(b2105_duty_cycle_table),
.supply_name = "pwm",
};
static const struct st_pwm_regulator_pdata b2105_info = {
.desc = &b2105_desc,
.duty_cycle_table = b2105_duty_cycle_table,
};
static struct of_device_id st_pwm_of_match[] = {
{ .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, },
{ },
};
MODULE_DEVICE_TABLE(of, st_pwm_of_match);
static int st_pwm_regulator_probe(struct platform_device *pdev)
{
struct st_pwm_regulator_data *drvdata;
struct regulator_dev *regulator;
struct regulator_config config = { };
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_match;
if (!np) {
dev_err(&pdev->dev, "Device Tree node missing\n");
return -EINVAL;
}
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
of_match = of_match_device(st_pwm_of_match, &pdev->dev);
if (!of_match) {
dev_err(&pdev->dev, "failed to match of device\n");
return -ENODEV;
}
drvdata->pdata = of_match->data;
config.init_data = of_get_regulator_init_data(&pdev->dev, np);
if (!config.init_data)
return -ENOMEM;
config.of_node = np;
config.dev = &pdev->dev;
config.driver_data = drvdata;
drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(drvdata->pwm)) {
dev_err(&pdev->dev, "Failed to get PWM\n");
return PTR_ERR(drvdata->pwm);
}
regulator = devm_regulator_register(&pdev->dev,
drvdata->pdata->desc, &config);
if (IS_ERR(regulator)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
drvdata->pdata->desc->name);
return PTR_ERR(regulator);
}
return 0;
}
static struct platform_driver st_pwm_regulator_driver = {
.driver = {
.name = "st-pwm-regulator",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(st_pwm_of_match),
},
.probe = st_pwm_regulator_probe,
};
module_platform_driver(st_pwm_regulator_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>");
MODULE_DESCRIPTION("ST PWM Regulator Driver");
MODULE_ALIAS("platform:st_pwm-regulator");
...@@ -54,8 +54,8 @@ struct ti_abb_info { ...@@ -54,8 +54,8 @@ struct ti_abb_info {
/** /**
* struct ti_abb_reg - Register description for ABB block * struct ti_abb_reg - Register description for ABB block
* @setup_reg: setup register offset from base * @setup_off: setup register offset from base
* @control_reg: control register offset from base * @control_off: control register offset from base
* @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask
* @fbb_sel_mask: setup register- FBB sel mask * @fbb_sel_mask: setup register- FBB sel mask
* @rbb_sel_mask: setup register- RBB sel mask * @rbb_sel_mask: setup register- RBB sel mask
...@@ -64,8 +64,8 @@ struct ti_abb_info { ...@@ -64,8 +64,8 @@ struct ti_abb_info {
* @opp_sel_mask: control register - mask for mode to operate * @opp_sel_mask: control register - mask for mode to operate
*/ */
struct ti_abb_reg { struct ti_abb_reg {
u32 setup_reg; u32 setup_off;
u32 control_reg; u32 control_off;
/* Setup register fields */ /* Setup register fields */
u32 sr2_wtcnt_value_mask; u32 sr2_wtcnt_value_mask;
...@@ -83,6 +83,8 @@ struct ti_abb_reg { ...@@ -83,6 +83,8 @@ struct ti_abb_reg {
* @rdesc: regulator descriptor * @rdesc: regulator descriptor
* @clk: clock(usually sysclk) supplying ABB block * @clk: clock(usually sysclk) supplying ABB block
* @base: base address of ABB block * @base: base address of ABB block
* @setup_reg: setup register of ABB block
* @control_reg: control register of ABB block
* @int_base: interrupt register base address * @int_base: interrupt register base address
* @efuse_base: (optional) efuse base address for ABB modes * @efuse_base: (optional) efuse base address for ABB modes
* @ldo_base: (optional) LDOVBB vset override base address * @ldo_base: (optional) LDOVBB vset override base address
...@@ -99,6 +101,8 @@ struct ti_abb { ...@@ -99,6 +101,8 @@ struct ti_abb {
struct regulator_desc rdesc; struct regulator_desc rdesc;
struct clk *clk; struct clk *clk;
void __iomem *base; void __iomem *base;
void __iomem *setup_reg;
void __iomem *control_reg;
void __iomem *int_base; void __iomem *int_base;
void __iomem *efuse_base; void __iomem *efuse_base;
void __iomem *ldo_base; void __iomem *ldo_base;
...@@ -118,20 +122,18 @@ struct ti_abb { ...@@ -118,20 +122,18 @@ struct ti_abb {
* ti_abb_rmw() - handy wrapper to set specific register bits * ti_abb_rmw() - handy wrapper to set specific register bits
* @mask: mask for register field * @mask: mask for register field
* @value: value shifted to mask location and written * @value: value shifted to mask location and written
* @offset: offset of register * @reg: register address
* @base: base address
* *
* Return: final register value (may be unused) * Return: final register value (may be unused)
*/ */
static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset, static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg)
void __iomem *base)
{ {
u32 val; u32 val;
val = readl(base + offset); val = readl(reg);
val &= ~mask; val &= ~mask;
val |= (value << __ffs(mask)) & mask; val |= (value << __ffs(mask)) & mask;
writel(val, base + offset); writel(val, reg);
return val; return val;
} }
...@@ -263,21 +265,19 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, ...@@ -263,21 +265,19 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb,
if (ret) if (ret)
goto out; goto out;
ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg, ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg);
abb->base);
switch (info->opp_sel) { switch (info->opp_sel) {
case TI_ABB_SLOW_OPP: case TI_ABB_SLOW_OPP:
ti_abb_rmw(regs->rbb_sel_mask, 1, regs->setup_reg, abb->base); ti_abb_rmw(regs->rbb_sel_mask, 1, abb->setup_reg);
break; break;
case TI_ABB_FAST_OPP: case TI_ABB_FAST_OPP:
ti_abb_rmw(regs->fbb_sel_mask, 1, regs->setup_reg, abb->base); ti_abb_rmw(regs->fbb_sel_mask, 1, abb->setup_reg);
break; break;
} }
/* program next state of ABB ldo */ /* program next state of ABB ldo */
ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg, ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg);
abb->base);
/* /*
* program LDO VBB vset override if needed for !bypass mode * program LDO VBB vset override if needed for !bypass mode
...@@ -288,7 +288,7 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, ...@@ -288,7 +288,7 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb,
ti_abb_program_ldovbb(dev, abb, info); ti_abb_program_ldovbb(dev, abb, info);
/* Initiate ABB ldo change */ /* Initiate ABB ldo change */
ti_abb_rmw(regs->opp_change_mask, 1, regs->control_reg, abb->base); ti_abb_rmw(regs->opp_change_mask, 1, abb->control_reg);
/* Wait for ABB LDO to complete transition to new Bias setting */ /* Wait for ABB LDO to complete transition to new Bias setting */
ret = ti_abb_wait_txdone(dev, abb); ret = ti_abb_wait_txdone(dev, abb);
...@@ -490,8 +490,7 @@ static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb) ...@@ -490,8 +490,7 @@ static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb)
dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__,
clk_get_rate(abb->clk), sr2_wt_cnt_val); clk_get_rate(abb->clk), sr2_wt_cnt_val);
ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg, ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg);
abb->base);
return 0; return 0;
} }
...@@ -508,32 +507,24 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, ...@@ -508,32 +507,24 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
struct regulator_init_data *rinit_data) struct regulator_init_data *rinit_data)
{ {
struct ti_abb_info *info; struct ti_abb_info *info;
const struct property *prop;
const __be32 *abb_info;
const u32 num_values = 6; const u32 num_values = 6;
char *pname = "ti,abb_info"; char *pname = "ti,abb_info";
u32 num_entries, i; u32 i;
unsigned int *volt_table; unsigned int *volt_table;
int min_uV = INT_MAX, max_uV = 0; int num_entries, min_uV = INT_MAX, max_uV = 0;
struct regulation_constraints *c = &rinit_data->constraints; struct regulation_constraints *c = &rinit_data->constraints;
prop = of_find_property(dev->of_node, pname, NULL);
if (!prop) {
dev_err(dev, "No '%s' property?\n", pname);
return -ENODEV;
}
if (!prop->value) {
dev_err(dev, "Empty '%s' property?\n", pname);
return -ENODATA;
}
/* /*
* Each abb_info is a set of n-tuple, where n is num_values, consisting * Each abb_info is a set of n-tuple, where n is num_values, consisting
* of voltage and a set of detection logic for ABB information for that * of voltage and a set of detection logic for ABB information for that
* voltage to apply. * voltage to apply.
*/ */
num_entries = prop->length / sizeof(u32); num_entries = of_property_count_u32_elems(dev->of_node, pname);
if (num_entries < 0) {
dev_err(dev, "No '%s' property?\n", pname);
return num_entries;
}
if (!num_entries || (num_entries % num_values)) { if (!num_entries || (num_entries % num_values)) {
dev_err(dev, "All '%s' list entries need %d vals\n", pname, dev_err(dev, "All '%s' list entries need %d vals\n", pname,
num_values); num_values);
...@@ -542,38 +533,38 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, ...@@ -542,38 +533,38 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
num_entries /= num_values; num_entries /= num_values;
info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL);
if (!info) { if (!info)
dev_err(dev, "Can't allocate info table for '%s' property\n",
pname);
return -ENOMEM; return -ENOMEM;
}
abb->info = info; abb->info = info;
volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries,
GFP_KERNEL); GFP_KERNEL);
if (!volt_table) { if (!volt_table)
dev_err(dev, "Can't allocate voltage table for '%s' property\n",
pname);
return -ENOMEM; return -ENOMEM;
}
abb->rdesc.n_voltages = num_entries; abb->rdesc.n_voltages = num_entries;
abb->rdesc.volt_table = volt_table; abb->rdesc.volt_table = volt_table;
/* We do not know where the OPP voltage is at the moment */ /* We do not know where the OPP voltage is at the moment */
abb->current_info_idx = -EINVAL; abb->current_info_idx = -EINVAL;
abb_info = prop->value;
for (i = 0; i < num_entries; i++, info++, volt_table++) { for (i = 0; i < num_entries; i++, info++, volt_table++) {
u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; u32 efuse_offset, rbb_mask, fbb_mask, vset_mask;
u32 efuse_val; u32 efuse_val;
/* NOTE: num_values should equal to entries picked up here */ /* NOTE: num_values should equal to entries picked up here */
*volt_table = be32_to_cpup(abb_info++); of_property_read_u32_index(dev->of_node, pname, i * num_values,
info->opp_sel = be32_to_cpup(abb_info++); volt_table);
efuse_offset = be32_to_cpup(abb_info++); of_property_read_u32_index(dev->of_node, pname,
rbb_mask = be32_to_cpup(abb_info++); i * num_values + 1, &info->opp_sel);
fbb_mask = be32_to_cpup(abb_info++); of_property_read_u32_index(dev->of_node, pname,
vset_mask = be32_to_cpup(abb_info++); i * num_values + 2, &efuse_offset);
of_property_read_u32_index(dev->of_node, pname,
i * num_values + 3, &rbb_mask);
of_property_read_u32_index(dev->of_node, pname,
i * num_values + 4, &fbb_mask);
of_property_read_u32_index(dev->of_node, pname,
i * num_values + 5, &vset_mask);
dev_dbg(dev, dev_dbg(dev,
"[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n",
...@@ -648,8 +639,8 @@ static struct regulator_ops ti_abb_reg_ops = { ...@@ -648,8 +639,8 @@ static struct regulator_ops ti_abb_reg_ops = {
/* Default ABB block offsets, IF this changes in future, create new one */ /* Default ABB block offsets, IF this changes in future, create new one */
static const struct ti_abb_reg abb_regs_v1 = { static const struct ti_abb_reg abb_regs_v1 = {
/* WARNING: registers are wrongly documented in TRM */ /* WARNING: registers are wrongly documented in TRM */
.setup_reg = 0x04, .setup_off = 0x04,
.control_reg = 0x00, .control_off = 0x00,
.sr2_wtcnt_value_mask = (0xff << 8), .sr2_wtcnt_value_mask = (0xff << 8),
.fbb_sel_mask = (0x01 << 2), .fbb_sel_mask = (0x01 << 2),
...@@ -661,8 +652,8 @@ static const struct ti_abb_reg abb_regs_v1 = { ...@@ -661,8 +652,8 @@ static const struct ti_abb_reg abb_regs_v1 = {
}; };
static const struct ti_abb_reg abb_regs_v2 = { static const struct ti_abb_reg abb_regs_v2 = {
.setup_reg = 0x00, .setup_off = 0x00,
.control_reg = 0x04, .control_off = 0x04,
.sr2_wtcnt_value_mask = (0xff << 8), .sr2_wtcnt_value_mask = (0xff << 8),
.fbb_sel_mask = (0x01 << 2), .fbb_sel_mask = (0x01 << 2),
...@@ -673,9 +664,20 @@ static const struct ti_abb_reg abb_regs_v2 = { ...@@ -673,9 +664,20 @@ static const struct ti_abb_reg abb_regs_v2 = {
.opp_sel_mask = (0x03 << 0), .opp_sel_mask = (0x03 << 0),
}; };
static const struct ti_abb_reg abb_regs_generic = {
.sr2_wtcnt_value_mask = (0xff << 8),
.fbb_sel_mask = (0x01 << 2),
.rbb_sel_mask = (0x01 << 1),
.sr2_en_mask = (0x01 << 0),
.opp_change_mask = (0x01 << 2),
.opp_sel_mask = (0x03 << 0),
};
static const struct of_device_id ti_abb_of_match[] = { static const struct of_device_id ti_abb_of_match[] = {
{.compatible = "ti,abb-v1", .data = &abb_regs_v1}, {.compatible = "ti,abb-v1", .data = &abb_regs_v1},
{.compatible = "ti,abb-v2", .data = &abb_regs_v2}, {.compatible = "ti,abb-v2", .data = &abb_regs_v2},
{.compatible = "ti,abb-v3", .data = &abb_regs_generic},
{ }, { },
}; };
...@@ -722,11 +724,29 @@ static int ti_abb_probe(struct platform_device *pdev) ...@@ -722,11 +724,29 @@ static int ti_abb_probe(struct platform_device *pdev)
abb->regs = match->data; abb->regs = match->data;
/* Map ABB resources */ /* Map ABB resources */
pname = "base-address"; if (abb->regs->setup_off || abb->regs->control_off) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); pname = "base-address";
abb->base = devm_ioremap_resource(dev, res); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
if (IS_ERR(abb->base)) abb->base = devm_ioremap_resource(dev, res);
return PTR_ERR(abb->base); if (IS_ERR(abb->base))
return PTR_ERR(abb->base);
abb->setup_reg = abb->base + abb->regs->setup_off;
abb->control_reg = abb->base + abb->regs->control_off;
} else {
pname = "control-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
abb->control_reg = devm_ioremap_resource(dev, res);
if (IS_ERR(abb->control_reg))
return PTR_ERR(abb->control_reg);
pname = "setup-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
abb->setup_reg = devm_ioremap_resource(dev, res);
if (IS_ERR(abb->setup_reg))
return PTR_ERR(abb->setup_reg);
}
pname = "int-address"; pname = "int-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
...@@ -860,7 +880,7 @@ static int ti_abb_probe(struct platform_device *pdev) ...@@ -860,7 +880,7 @@ static int ti_abb_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rdev); platform_set_drvdata(pdev, rdev);
/* Enable the ldo if not already done by bootloader */ /* Enable the ldo if not already done by bootloader */
ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base); ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg);
return 0; return 0;
} }
......
...@@ -227,10 +227,8 @@ static struct tps51632_regulator_platform_data * ...@@ -227,10 +227,8 @@ static struct tps51632_regulator_platform_data *
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) { if (!pdata)
dev_err(dev, "Memory alloc failed for platform data\n");
return NULL; return NULL;
}
pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
if (!pdata->reg_init_data) { if (!pdata->reg_init_data) {
...@@ -299,10 +297,8 @@ static int tps51632_probe(struct i2c_client *client, ...@@ -299,10 +297,8 @@ static int tps51632_probe(struct i2c_client *client,
} }
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps) { if (!tps)
dev_err(&client->dev, "Memory allocation failed\n");
return -ENOMEM; return -ENOMEM;
}
tps->dev = &client->dev; tps->dev = &client->dev;
tps->desc.name = client->name; tps->desc.name = client->name;
......
...@@ -299,10 +299,8 @@ static struct tps62360_regulator_platform_data * ...@@ -299,10 +299,8 @@ static struct tps62360_regulator_platform_data *
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) { if (!pdata)
dev_err(dev, "Memory alloc failed for platform data\n");
return NULL; return NULL;
}
pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
if (!pdata->reg_init_data) { if (!pdata->reg_init_data) {
...@@ -377,11 +375,8 @@ static int tps62360_probe(struct i2c_client *client, ...@@ -377,11 +375,8 @@ static int tps62360_probe(struct i2c_client *client,
} }
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps) { if (!tps)
dev_err(&client->dev, "%s(): Memory allocation failed\n",
__func__);
return -ENOMEM; return -ENOMEM;
}
tps->en_discharge = pdata->en_discharge; tps->en_discharge = pdata->en_discharge;
tps->en_internal_pulldn = pdata->en_internal_pulldn; tps->en_internal_pulldn = pdata->en_internal_pulldn;
......
...@@ -359,7 +359,6 @@ static struct regulator_ops tps6507x_pmic_ops = { ...@@ -359,7 +359,6 @@ static struct regulator_ops tps6507x_pmic_ops = {
.map_voltage = regulator_map_voltage_ascend, .map_voltage = regulator_map_voltage_ascend,
}; };
#ifdef CONFIG_OF
static struct of_regulator_match tps6507x_matches[] = { static struct of_regulator_match tps6507x_matches[] = {
{ .name = "VDCDC1"}, { .name = "VDCDC1"},
{ .name = "VDCDC2"}, { .name = "VDCDC2"},
...@@ -381,12 +380,10 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( ...@@ -381,12 +380,10 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board),
GFP_KERNEL); GFP_KERNEL);
if (!tps_board) { if (!tps_board)
dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");
return NULL; return NULL;
}
regulators = of_find_node_by_name(np, "regulators"); regulators = of_get_child_by_name(np, "regulators");
if (!regulators) { if (!regulators) {
dev_err(&pdev->dev, "regulator node not found\n"); dev_err(&pdev->dev, "regulator node not found\n");
return NULL; return NULL;
...@@ -396,6 +393,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( ...@@ -396,6 +393,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
matches = tps6507x_matches; matches = tps6507x_matches;
ret = of_regulator_match(&pdev->dev, regulators, matches, count); ret = of_regulator_match(&pdev->dev, regulators, matches, count);
of_node_put(regulators);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
ret); ret);
...@@ -406,10 +404,8 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( ...@@ -406,10 +404,8 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data)
* TPS6507X_NUM_REGULATOR), GFP_KERNEL); * TPS6507X_NUM_REGULATOR), GFP_KERNEL);
if (!reg_data) { if (!reg_data)
dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n");
return NULL; return NULL;
}
tps_board->tps6507x_pmic_init_data = reg_data; tps_board->tps6507x_pmic_init_data = reg_data;
...@@ -424,15 +420,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( ...@@ -424,15 +420,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
return tps_board; return tps_board;
} }
#else
static inline struct tps6507x_board *tps6507x_parse_dt_reg_data(
struct platform_device *pdev,
struct of_regulator_match **tps6507x_reg_matches)
{
*tps6507x_reg_matches = NULL;
return NULL;
}
#endif
static int tps6507x_pmic_probe(struct platform_device *pdev) static int tps6507x_pmic_probe(struct platform_device *pdev)
{ {
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
...@@ -453,9 +441,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) ...@@ -453,9 +441,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
*/ */
tps_board = dev_get_platdata(tps6507x_dev->dev); tps_board = dev_get_platdata(tps6507x_dev->dev);
if (!tps_board && tps6507x_dev->dev->of_node) if (IS_ENABLED(CONFIG_OF) && !tps_board &&
tps6507x_dev->dev->of_node)
tps_board = tps6507x_parse_dt_reg_data(pdev, tps_board = tps6507x_parse_dt_reg_data(pdev,
&tps6507x_reg_matches); &tps6507x_reg_matches);
if (!tps_board) if (!tps_board)
return -EINVAL; return -EINVAL;
...@@ -481,7 +470,7 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) ...@@ -481,7 +470,7 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
tps->info[i] = info; tps->info[i] = info;
if (init_data->driver_data) { if (init_data->driver_data) {
struct tps6507x_reg_platform_data *data = struct tps6507x_reg_platform_data *data =
init_data->driver_data; init_data->driver_data;
tps->info[i]->defdcdc_default = data->defdcdc_default; tps->info[i]->defdcdc_default = data->defdcdc_default;
} }
......
...@@ -168,17 +168,13 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( ...@@ -168,17 +168,13 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata), tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata),
GFP_KERNEL); GFP_KERNEL);
if (!tps65090_pdata) { if (!tps65090_pdata)
dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX *
sizeof(*reg_pdata), GFP_KERNEL); sizeof(*reg_pdata), GFP_KERNEL);
if (!reg_pdata) { if (!reg_pdata)
dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
regulators = of_get_child_by_name(np, "regulators"); regulators = of_get_child_by_name(np, "regulators");
if (!regulators) { if (!regulators) {
...@@ -188,6 +184,7 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( ...@@ -188,6 +184,7 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches, ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches,
ARRAY_SIZE(tps65090_matches)); ARRAY_SIZE(tps65090_matches));
of_node_put(regulators);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Error parsing regulator init data: %d\n", ret); "Error parsing regulator init data: %d\n", ret);
...@@ -252,10 +249,8 @@ static int tps65090_regulator_probe(struct platform_device *pdev) ...@@ -252,10 +249,8 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic),
GFP_KERNEL); GFP_KERNEL);
if (!pmic) { if (!pmic)
dev_err(&pdev->dev, "mem alloc for pmic failed\n");
return -ENOMEM; return -ENOMEM;
}
for (num = 0; num < TPS65090_REGULATOR_MAX; num++) { for (num = 0; num < TPS65090_REGULATOR_MAX; num++) {
tps_pdata = tps65090_pdata->reg_pdata[num]; tps_pdata = tps65090_pdata->reg_pdata[num];
......
...@@ -187,7 +187,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) ...@@ -187,7 +187,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
struct device_node *regs; struct device_node *regs;
int i, count; int i, count;
regs = of_find_node_by_name(node, "regulators"); regs = of_get_child_by_name(node, "regulators");
if (!regs) if (!regs)
return NULL; return NULL;
...@@ -202,7 +202,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) ...@@ -202,7 +202,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
return NULL; return NULL;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (!reg_matches[i].init_data || !reg_matches[i].of_node) if (!reg_matches[i].of_node)
continue; continue;
pdata->tps65217_init_data[i] = reg_matches[i].init_data; pdata->tps65217_init_data[i] = reg_matches[i].init_data;
...@@ -222,7 +222,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) ...@@ -222,7 +222,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
{ {
struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
struct tps65217_board *pdata = dev_get_platdata(tps->dev); struct tps65217_board *pdata = dev_get_platdata(tps->dev);
struct regulator_init_data *reg_data;
struct regulator_dev *rdev; struct regulator_dev *rdev;
struct regulator_config config = { }; struct regulator_config config = { };
int i; int i;
...@@ -243,19 +242,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev) ...@@ -243,19 +242,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tps); platform_set_drvdata(pdev, tps);
for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { for (i = 0; i < TPS65217_NUM_REGULATOR; i++) {
reg_data = pdata->tps65217_init_data[i];
/*
* Regulator API handles empty constraints but not NULL
* constraints
*/
if (!reg_data)
continue;
/* Register the regulators */ /* Register the regulators */
config.dev = tps->dev; config.dev = tps->dev;
config.init_data = reg_data; config.init_data = pdata->tps65217_init_data[i];
config.driver_data = tps; config.driver_data = tps;
config.regmap = tps->regmap; config.regmap = tps->regmap;
if (tps->dev->of_node) if (tps->dev->of_node)
......
...@@ -126,7 +126,8 @@ struct sec_platform_data { ...@@ -126,7 +126,8 @@ struct sec_platform_data {
struct sec_regulator_data { struct sec_regulator_data {
int id; int id;
struct regulator_init_data *initdata; struct regulator_init_data *initdata;
struct device_node *reg_node; struct device_node *reg_node;
int ext_control_gpio;
}; };
/* /*
......
...@@ -183,9 +183,16 @@ enum s5m8767_regulators { ...@@ -183,9 +183,16 @@ enum s5m8767_regulators {
S5M8767_REG_MAX, S5M8767_REG_MAX,
}; };
/* LDO_EN/BUCK_EN field in registers */
#define S5M8767_ENCTRL_SHIFT 6 #define S5M8767_ENCTRL_SHIFT 6
#define S5M8767_ENCTRL_MASK (0x3 << S5M8767_ENCTRL_SHIFT) #define S5M8767_ENCTRL_MASK (0x3 << S5M8767_ENCTRL_SHIFT)
/*
* LDO_EN/BUCK_EN register value for controlling this Buck or LDO
* by GPIO (PWREN, BUCKEN).
*/
#define S5M8767_ENCTRL_USE_GPIO 0x1
/* /*
* Values for BUCK_RAMP field in DVS_RAMP register, matching raw values * Values for BUCK_RAMP field in DVS_RAMP register, matching raw values
* in mV/us. * in mV/us.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment