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
This commit is contained in:
Родитель
7b836485d4
9c4c60554a
d8eb6fa7a9
8bad62cca3
ef4bcf88ea
33e63ba6c6
fe23ce0813
0ad91c69ab
94ee607c96
Коммит
24ee65e4a5
|
@ -69,13 +69,16 @@ sub-node should be of the format as listed below.
|
|||
};
|
||||
};
|
||||
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
|
||||
power mode change in SOC. The different possible values are,
|
||||
0 - always off mode
|
||||
1 - on in normal mode
|
||||
2 - low power 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
|
||||
supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
|
||||
|
@ -148,5 +151,13 @@ Example:
|
|||
regulator-always-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:
|
|||
- compatible: Should be one of:
|
||||
- "ti,abb-v1" for older SoCs like OMAP3
|
||||
- "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
|
||||
the information of registers in the same order as described by 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
|
||||
(also see Optional properties)
|
||||
- #address-cell: should be 0
|
||||
|
|
|
@ -448,6 +448,12 @@ config REGULATOR_S5M8767
|
|||
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
|
||||
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
|
||||
tristate "TI Adaptive Body Bias on-chip LDO"
|
||||
depends on ARCH_OMAP
|
||||
|
|
|
@ -61,6 +61,7 @@ obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
|
|||
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
|
||||
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.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_TI_ABB) += ti-abb-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
|
||||
|
|
|
@ -11,11 +11,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
@ -170,12 +167,11 @@ static unsigned int s5m8767_opmode_reg[][4] = {
|
|||
{0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
|
||||
};
|
||||
|
||||
static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
|
||||
int *enable_ctrl)
|
||||
static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id,
|
||||
int *reg, int *enable_ctrl)
|
||||
{
|
||||
int i, reg_id = rdev_get_id(rdev);
|
||||
int i;
|
||||
unsigned int mode;
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
|
||||
switch (reg_id) {
|
||||
case S5M8767_LDO1 ... S5M8767_LDO2:
|
||||
|
@ -214,53 +210,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
|
|||
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, ®, &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, ®, &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, ®, &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)
|
||||
{
|
||||
int reg;
|
||||
|
@ -410,9 +359,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
|||
|
||||
static struct regulator_ops s5m8767_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.is_enabled = s5m8767_reg_is_enabled,
|
||||
.enable = s5m8767_reg_enable,
|
||||
.disable = s5m8767_reg_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = s5m8767_set_voltage_sel,
|
||||
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
|
||||
|
@ -420,9 +369,9 @@ static struct regulator_ops s5m8767_ops = {
|
|||
|
||||
static struct regulator_ops s5m8767_buck78_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.is_enabled = s5m8767_reg_is_enabled,
|
||||
.enable = s5m8767_reg_enable,
|
||||
.disable = s5m8767_reg_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
@ -483,6 +432,66 @@ static struct regulator_desc regulators[] = {
|
|||
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, ®, &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
|
||||
static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev,
|
||||
struct sec_platform_data *pdata,
|
||||
|
@ -520,6 +529,16 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev,
|
|||
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,
|
||||
struct sec_platform_data *pdata)
|
||||
{
|
||||
|
@ -546,19 +565,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
|
|||
|
||||
rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
|
||||
pdata->num_regulators, GFP_KERNEL);
|
||||
if (!rdata) {
|
||||
dev_err(iodev->dev,
|
||||
"could not allocate memory for regulator data\n");
|
||||
if (!rdata)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) *
|
||||
pdata->num_regulators, GFP_KERNEL);
|
||||
if (!rmode) {
|
||||
dev_err(iodev->dev,
|
||||
"could not allocate memory for regulator mode\n");
|
||||
if (!rmode)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pdata->regulators = rdata;
|
||||
pdata->opmode = rmode;
|
||||
|
@ -574,6 +587,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
|
|||
continue;
|
||||
}
|
||||
|
||||
s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np);
|
||||
|
||||
rdata->id = i;
|
||||
rdata->initdata = of_get_regulator_init_data(
|
||||
&pdev->dev, reg_np);
|
||||
|
@ -922,6 +937,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
|
|||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
const struct sec_voltage_desc *desc;
|
||||
int id = pdata->regulators[i].id;
|
||||
int enable_reg, enable_val;
|
||||
|
||||
desc = reg_voltage_map[id];
|
||||
if (desc) {
|
||||
|
@ -935,6 +951,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
|
|||
regulators[id].vsel_mask = 0x3f;
|
||||
else
|
||||
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;
|
||||
|
@ -942,6 +964,9 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
|
|||
config.driver_data = s5m8767;
|
||||
config.regmap = iodev->regmap_pmic;
|
||||
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, ®ulators[id],
|
||||
&config);
|
||||
|
@ -951,6 +976,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
|
|||
id);
|
||||
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;
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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 {
|
|||
|
||||
/**
|
||||
* struct ti_abb_reg - Register description for ABB block
|
||||
* @setup_reg: setup register offset from base
|
||||
* @control_reg: control register offset from base
|
||||
* @setup_off: setup register offset from base
|
||||
* @control_off: control register offset from base
|
||||
* @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask
|
||||
* @fbb_sel_mask: setup register- FBB sel mask
|
||||
* @rbb_sel_mask: setup register- RBB sel mask
|
||||
|
@ -64,8 +64,8 @@ struct ti_abb_info {
|
|||
* @opp_sel_mask: control register - mask for mode to operate
|
||||
*/
|
||||
struct ti_abb_reg {
|
||||
u32 setup_reg;
|
||||
u32 control_reg;
|
||||
u32 setup_off;
|
||||
u32 control_off;
|
||||
|
||||
/* Setup register fields */
|
||||
u32 sr2_wtcnt_value_mask;
|
||||
|
@ -83,6 +83,8 @@ struct ti_abb_reg {
|
|||
* @rdesc: regulator descriptor
|
||||
* @clk: clock(usually sysclk) supplying 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
|
||||
* @efuse_base: (optional) efuse base address for ABB modes
|
||||
* @ldo_base: (optional) LDOVBB vset override base address
|
||||
|
@ -99,6 +101,8 @@ struct ti_abb {
|
|||
struct regulator_desc rdesc;
|
||||
struct clk *clk;
|
||||
void __iomem *base;
|
||||
void __iomem *setup_reg;
|
||||
void __iomem *control_reg;
|
||||
void __iomem *int_base;
|
||||
void __iomem *efuse_base;
|
||||
void __iomem *ldo_base;
|
||||
|
@ -118,20 +122,18 @@ struct ti_abb {
|
|||
* ti_abb_rmw() - handy wrapper to set specific register bits
|
||||
* @mask: mask for register field
|
||||
* @value: value shifted to mask location and written
|
||||
* @offset: offset of register
|
||||
* @base: base address
|
||||
* @reg: register address
|
||||
*
|
||||
* Return: final register value (may be unused)
|
||||
*/
|
||||
static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset,
|
||||
void __iomem *base)
|
||||
static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(base + offset);
|
||||
val = readl(reg);
|
||||
val &= ~mask;
|
||||
val |= (value << __ffs(mask)) & mask;
|
||||
writel(val, base + offset);
|
||||
writel(val, reg);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -263,21 +265,19 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg,
|
||||
abb->base);
|
||||
ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg);
|
||||
|
||||
switch (info->opp_sel) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* program next state of ABB ldo */
|
||||
ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg,
|
||||
abb->base);
|
||||
ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg);
|
||||
|
||||
/*
|
||||
* 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,
|
|||
ti_abb_program_ldovbb(dev, abb, info);
|
||||
|
||||
/* 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 */
|
||||
ret = ti_abb_wait_txdone(dev, 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__,
|
||||
clk_get_rate(abb->clk), sr2_wt_cnt_val);
|
||||
|
||||
ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg,
|
||||
abb->base);
|
||||
ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -508,32 +507,24 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
|
|||
struct regulator_init_data *rinit_data)
|
||||
{
|
||||
struct ti_abb_info *info;
|
||||
const struct property *prop;
|
||||
const __be32 *abb_info;
|
||||
const u32 num_values = 6;
|
||||
char *pname = "ti,abb_info";
|
||||
u32 num_entries, i;
|
||||
u32 i;
|
||||
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;
|
||||
|
||||
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
|
||||
* of voltage and a set of detection logic for ABB information for that
|
||||
* 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)) {
|
||||
dev_err(dev, "All '%s' list entries need %d vals\n", pname,
|
||||
num_values);
|
||||
|
@ -542,38 +533,38 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
|
|||
num_entries /= num_values;
|
||||
|
||||
info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL);
|
||||
if (!info) {
|
||||
dev_err(dev, "Can't allocate info table for '%s' property\n",
|
||||
pname);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
abb->info = info;
|
||||
|
||||
volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries,
|
||||
GFP_KERNEL);
|
||||
if (!volt_table) {
|
||||
dev_err(dev, "Can't allocate voltage table for '%s' property\n",
|
||||
pname);
|
||||
if (!volt_table)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
abb->rdesc.n_voltages = num_entries;
|
||||
abb->rdesc.volt_table = volt_table;
|
||||
/* We do not know where the OPP voltage is at the moment */
|
||||
abb->current_info_idx = -EINVAL;
|
||||
|
||||
abb_info = prop->value;
|
||||
for (i = 0; i < num_entries; i++, info++, volt_table++) {
|
||||
u32 efuse_offset, rbb_mask, fbb_mask, vset_mask;
|
||||
u32 efuse_val;
|
||||
|
||||
/* NOTE: num_values should equal to entries picked up here */
|
||||
*volt_table = be32_to_cpup(abb_info++);
|
||||
info->opp_sel = be32_to_cpup(abb_info++);
|
||||
efuse_offset = be32_to_cpup(abb_info++);
|
||||
rbb_mask = be32_to_cpup(abb_info++);
|
||||
fbb_mask = be32_to_cpup(abb_info++);
|
||||
vset_mask = be32_to_cpup(abb_info++);
|
||||
of_property_read_u32_index(dev->of_node, pname, i * num_values,
|
||||
volt_table);
|
||||
of_property_read_u32_index(dev->of_node, pname,
|
||||
i * num_values + 1, &info->opp_sel);
|
||||
of_property_read_u32_index(dev->of_node, pname,
|
||||
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,
|
||||
"[%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 = {
|
|||
/* Default ABB block offsets, IF this changes in future, create new one */
|
||||
static const struct ti_abb_reg abb_regs_v1 = {
|
||||
/* WARNING: registers are wrongly documented in TRM */
|
||||
.setup_reg = 0x04,
|
||||
.control_reg = 0x00,
|
||||
.setup_off = 0x04,
|
||||
.control_off = 0x00,
|
||||
|
||||
.sr2_wtcnt_value_mask = (0xff << 8),
|
||||
.fbb_sel_mask = (0x01 << 2),
|
||||
|
@ -661,8 +652,8 @@ static const struct ti_abb_reg abb_regs_v1 = {
|
|||
};
|
||||
|
||||
static const struct ti_abb_reg abb_regs_v2 = {
|
||||
.setup_reg = 0x00,
|
||||
.control_reg = 0x04,
|
||||
.setup_off = 0x00,
|
||||
.control_off = 0x04,
|
||||
|
||||
.sr2_wtcnt_value_mask = (0xff << 8),
|
||||
.fbb_sel_mask = (0x01 << 2),
|
||||
|
@ -673,9 +664,20 @@ static const struct ti_abb_reg abb_regs_v2 = {
|
|||
.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[] = {
|
||||
{.compatible = "ti,abb-v1", .data = &abb_regs_v1},
|
||||
{.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)
|
|||
abb->regs = match->data;
|
||||
|
||||
/* Map ABB resources */
|
||||
pname = "base-address";
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
|
||||
abb->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(abb->base))
|
||||
return PTR_ERR(abb->base);
|
||||
if (abb->regs->setup_off || abb->regs->control_off) {
|
||||
pname = "base-address";
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
|
||||
abb->base = devm_ioremap_resource(dev, res);
|
||||
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";
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
|
||||
|
@ -860,7 +880,7 @@ skip_opt:
|
|||
platform_set_drvdata(pdev, rdev);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -227,10 +227,8 @@ static struct tps51632_regulator_platform_data *
|
|||
struct device_node *np = dev->of_node;
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
dev_err(dev, "Memory alloc failed for platform data\n");
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
|
||||
if (!pdata->reg_init_data) {
|
||||
|
@ -299,10 +297,8 @@ static int tps51632_probe(struct i2c_client *client,
|
|||
}
|
||||
|
||||
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps) {
|
||||
dev_err(&client->dev, "Memory allocation failed\n");
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tps->dev = &client->dev;
|
||||
tps->desc.name = client->name;
|
||||
|
|
|
@ -299,10 +299,8 @@ static struct tps62360_regulator_platform_data *
|
|||
struct device_node *np = dev->of_node;
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
dev_err(dev, "Memory alloc failed for platform data\n");
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
|
||||
if (!pdata->reg_init_data) {
|
||||
|
@ -377,11 +375,8 @@ static int tps62360_probe(struct i2c_client *client,
|
|||
}
|
||||
|
||||
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps) {
|
||||
dev_err(&client->dev, "%s(): Memory allocation failed\n",
|
||||
__func__);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tps->en_discharge = pdata->en_discharge;
|
||||
tps->en_internal_pulldn = pdata->en_internal_pulldn;
|
||||
|
|
|
@ -359,7 +359,6 @@ static struct regulator_ops tps6507x_pmic_ops = {
|
|||
.map_voltage = regulator_map_voltage_ascend,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_regulator_match tps6507x_matches[] = {
|
||||
{ .name = "VDCDC1"},
|
||||
{ .name = "VDCDC2"},
|
||||
|
@ -381,12 +380,10 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
|
|||
|
||||
tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board),
|
||||
GFP_KERNEL);
|
||||
if (!tps_board) {
|
||||
dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");
|
||||
if (!tps_board)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
regulators = of_find_node_by_name(np, "regulators");
|
||||
regulators = of_get_child_by_name(np, "regulators");
|
||||
if (!regulators) {
|
||||
dev_err(&pdev->dev, "regulator node not found\n");
|
||||
return NULL;
|
||||
|
@ -396,6 +393,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
|
|||
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);
|
||||
|
@ -406,10 +404,8 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
|
|||
|
||||
reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data)
|
||||
* TPS6507X_NUM_REGULATOR), GFP_KERNEL);
|
||||
if (!reg_data) {
|
||||
dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n");
|
||||
if (!reg_data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tps_board->tps6507x_pmic_init_data = reg_data;
|
||||
|
||||
|
@ -424,15 +420,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data(
|
|||
|
||||
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)
|
||||
{
|
||||
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
|
@ -453,9 +441,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
|
|||
*/
|
||||
|
||||
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,
|
||||
&tps6507x_reg_matches);
|
||||
&tps6507x_reg_matches);
|
||||
if (!tps_board)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -481,7 +470,7 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
|
|||
tps->info[i] = info;
|
||||
if (init_data->driver_data) {
|
||||
struct tps6507x_reg_platform_data *data =
|
||||
init_data->driver_data;
|
||||
init_data->driver_data;
|
||||
tps->info[i]->defdcdc_default = data->defdcdc_default;
|
||||
}
|
||||
|
||||
|
|
|
@ -168,17 +168,13 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
|
|||
|
||||
tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata),
|
||||
GFP_KERNEL);
|
||||
if (!tps65090_pdata) {
|
||||
dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n");
|
||||
if (!tps65090_pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX *
|
||||
sizeof(*reg_pdata), GFP_KERNEL);
|
||||
if (!reg_pdata) {
|
||||
dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n");
|
||||
if (!reg_pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
regulators = of_get_child_by_name(np, "regulators");
|
||||
if (!regulators) {
|
||||
|
@ -188,6 +184,7 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
|
|||
|
||||
ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches,
|
||||
ARRAY_SIZE(tps65090_matches));
|
||||
of_node_put(regulators);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Error parsing regulator init data: %d\n", ret);
|
||||
|
@ -252,10 +249,8 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
|
|||
|
||||
pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic),
|
||||
GFP_KERNEL);
|
||||
if (!pmic) {
|
||||
dev_err(&pdev->dev, "mem alloc for pmic failed\n");
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (num = 0; num < TPS65090_REGULATOR_MAX; num++) {
|
||||
tps_pdata = tps65090_pdata->reg_pdata[num];
|
||||
|
|
|
@ -187,7 +187,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
|
|||
struct device_node *regs;
|
||||
int i, count;
|
||||
|
||||
regs = of_find_node_by_name(node, "regulators");
|
||||
regs = of_get_child_by_name(node, "regulators");
|
||||
if (!regs)
|
||||
return NULL;
|
||||
|
||||
|
@ -202,7 +202,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
|
|||
return NULL;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!reg_matches[i].init_data || !reg_matches[i].of_node)
|
||||
if (!reg_matches[i].of_node)
|
||||
continue;
|
||||
|
||||
pdata->tps65217_init_data[i] = reg_matches[i].init_data;
|
||||
|
@ -222,7 +222,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
|
||||
struct tps65217_board *pdata = dev_get_platdata(tps->dev);
|
||||
struct regulator_init_data *reg_data;
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_config config = { };
|
||||
int i;
|
||||
|
@ -243,19 +242,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, tps);
|
||||
|
||||
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 */
|
||||
config.dev = tps->dev;
|
||||
config.init_data = reg_data;
|
||||
config.init_data = pdata->tps65217_init_data[i];
|
||||
config.driver_data = tps;
|
||||
config.regmap = tps->regmap;
|
||||
if (tps->dev->of_node)
|
||||
|
|
|
@ -126,7 +126,8 @@ struct sec_platform_data {
|
|||
struct sec_regulator_data {
|
||||
int id;
|
||||
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 {
|
|||
S5M8767_REG_MAX,
|
||||
};
|
||||
|
||||
/* LDO_EN/BUCK_EN field in registers */
|
||||
#define S5M8767_ENCTRL_SHIFT 6
|
||||
#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
|
||||
* in mV/us.
|
||||
|
|
Загрузка…
Ссылка в новой задаче