Commit f94784bd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regulator-v3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "The main thing this time around is support for suspend mode
  configuration from DT which will enable some very useful power savings
  on systems where we can't rely on the bootloader configuration.  We
  still don't really support dynamic configuration of this at runtime,
  that may come later if there is any demand.

  Summary:
   - Support for specifying the target regulation mode and voltage
     during system suspend via DT, enabling power savings in that mode.
   - Reduce the default verbosity of the logging on boot, improving boot
     times especially for systems with very large numbers of regulators.
   - Lots of cleanups and fixes for Maxim PMIC drivers.
   - New driver for Richtek RT5033"

* tag 'regulator-v3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (62 commits)
  regulator: core: Fix regualtor_ena_gpio_free not to access pin after freeing
  regulator: sky81452: Modify Device Tree structure
  regulator: sky81452: Modify Device Tree structure
  dt-bindings: Update documentation for "system-power-controller" and fix misspellings
  of: Rename "poweroff-source" property to "system-power-controller"
  regulator: max77686: Remove support for board files
  regulator: max77802: Remove support for board files
  regulator: max77802: Fill regulator modes translation callback
  regulator: max77802: Document binding for regulator operating modes
  regulator: of: Add support for parsing initial and suspend modes
  regulator: of: Pass the regulator description in the match table
  regulator: of: Add regulator desc param to of_get_regulator_init_data()
  regulator: Add mode mapping function to struct regulator_desc
  regulator: Document binding for initial and suspend modes
  regulator: core: Add PRE_DISABLE notification
  regulator: gpio: fix parsing of gpio list
  regulator: rpm: add support for RPM-controller SMB208
  regulator: da9063: Do not transform local IRQ to virtual
  regulator: sky81452: Modify dependent Kconfig symbol
  regulator: rt5033: Add RT5033 Regulator device driver
  ...
parents de740386 176488fb
* Generic system power control capability
Power-management integrated circuits or miscellaneous hardware components are
sometimes able to control the system power. The device driver associated with these
components might need to define this capability, which tells the kernel that
it can be used to switch off the system. The corresponding device must have the
standard property "system-power-controller" in its device node. This property
marks the device as able to control the system power. In order to test if this
property is found programmatically, use the helper function
"of_device_is_system_power_controller" from of.h .
Example:
act8846: act8846@5 {
compatible = "active-semi,act8846";
status = "okay";
system-power-controller;
}
......@@ -5,6 +5,10 @@ Required properties:
- compatible: "active-semi,act8846" or "active-semi,act8865"
- reg: I2C slave address
Optional properties:
- system-power-controller: Telling whether or not this pmic is controlling
the system power. See Documentation/devicetree/bindings/power/power-controller.txt .
Any standard regulator properties can be used to configure the single regulator.
The valid names for regulators are:
......
......@@ -25,6 +25,29 @@ with their hardware counterparts as follow. The valid names are:
example: LDO1, LDO2, LDO35.
-BUCKn : for BUCKs, where n can lie in range 1 to 10.
example: BUCK1, BUCK5, BUCK10.
The max77802 regulator supports two different operating modes: Normal and Low
Power Mode. Some regulators support the modes to be changed at startup or by
the consumers during normal operation while others only support to change the
mode during system suspend. The standard regulator suspend states binding can
be used to configure the regulator operating mode.
The regulators that support the standard "regulator-initial-mode" property,
changing their mode during normal operation are: LDOs 1, 3, 20 and 21.
The possible values for "regulator-initial-mode" and "regulator-mode" are:
1: Normal regulator voltage output mode.
3: Low Power which reduces the quiescent current down to only 1uA
The list of valid modes are defined in the dt-bindings/clock/maxim,max77802.h
header and can be included by device tree source files.
The standard "regulator-mode" property can only be used for regulators that
support changing their mode to Low Power Mode during suspend. These regulators
are: BUCKs 2-4 and LDOs 1-35. Also, it only takes effect if the regulator has
been enabled for the given suspend state using "regulator-on-in-suspend" and
has not been disabled for that state using "regulator-off-in-suspend".
Example:
max77802@09 {
......@@ -36,11 +59,23 @@ Example:
#size-cells = <0>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "vdd_1v0";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
regulator-initial-mode = <MAX77802_OPMODE_LP>;
};
ldo11_reg: LDO11 {
regulator-name = "vdd_ldo11";
regulator-min-microvolt = <1900000>;
regulator-max-microvolt = <1900000>;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <MAX77802_OPMODE_LP>;
};
};
buck1_reg: BUCK1 {
......
......@@ -19,6 +19,24 @@ Optional properties:
design requires. This property describes the total system ramp time
required due to the combination of internal ramping of the regulator itself,
and board design issues such as trace capacitance and load on the supply.
- regulator-state-mem sub-root node for Suspend-to-RAM mode
: suspend to memory, the device goes to sleep, but all data stored in memory,
only some external interrupt can wake the device.
- regulator-state-disk sub-root node for Suspend-to-DISK mode
: suspend to disk, this state operates similarly to Suspend-to-RAM,
but includes a final step of writing memory contents to disk.
- regulator-state-[mem/disk] node has following common properties:
- regulator-on-in-suspend: regulator should be on in suspend state.
- regulator-off-in-suspend: regulator should be off in suspend state.
- regulator-suspend-microvolt: regulator should be set to this voltage
in suspend.
- regulator-mode: operating mode in the given suspend state.
The set of possible operating modes depends on the capabilities of
every hardware so the valid modes are documented on each regulator
device tree binding document.
- regulator-initial-mode: initial operating mode. The set of possible operating
modes depends on the capabilities of every hardware so each device binding
documentation explains which values the regulator supports.
Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple
......@@ -34,6 +52,10 @@ Example:
regulator-max-microvolt = <2500000>;
regulator-always-on;
vin-supply = <&vin>;
regulator-state-mem {
regulator-on-in-suspend;
};
};
Regulator Consumers:
......
SKY81452 voltage regulator
Required properties:
- regulator node named lout.
- any required generic properties defined in regulator.txt
Optional properties:
......@@ -9,8 +10,9 @@ Optional properties:
Example:
regulator {
/* generic regulator properties */
regulator-name = "touch_en";
regulator-min-microvolt = <4500000>;
regulator-max-microvolt = <8000000>;
lout {
regulator-name = "sky81452-lout";
regulator-min-microvolt = <4500000>;
regulator-max-microvolt = <8000000>;
};
};
......@@ -330,7 +330,8 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev,
for_each_child_of_node(nproot, np) {
if (!of_node_cmp(np->name, info->desc.name)) {
config->init_data =
of_get_regulator_init_data(&pdev->dev, np);
of_get_regulator_init_data(&pdev->dev, np,
&info->desc);
config->of_node = np;
break;
}
......
......@@ -521,6 +521,14 @@ config REGULATOR_RN5T618
help
Say y here to support the regulators found on Ricoh RN5T618 PMIC.
config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
help
This adds support for voltage and current regulators in Richtek
RT5033 PMIC. The device supports multiple regulators like
current source, LDO and Buck.
config REGULATOR_S2MPA01
tristate "Samsung S2MPA01 voltage regulator"
depends on MFD_SEC_CORE
......@@ -547,7 +555,7 @@ config REGULATOR_S5M8767
config REGULATOR_SKY81452
tristate "Skyworks Solutions SKY81452 voltage regulator"
depends on SKY81452
depends on MFD_SKY81452
help
This driver supports Skyworks SKY81452 voltage output regulator
via I2C bus. SKY81452 has one voltage linear regulator can be
......
......@@ -69,6 +69,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
......
......@@ -61,6 +61,8 @@
#define ACT8846_REG12_VSET 0xa0
#define ACT8846_REG12_CTRL 0xa1
#define ACT8846_REG13_CTRL 0xb1
#define ACT8846_GLB_OFF_CTRL 0xc3
#define ACT8846_OFF_SYSMASK 0x18
/*
* ACT8865 Global Register Map.
......@@ -84,6 +86,7 @@
#define ACT8865_LDO3_CTRL 0x61
#define ACT8865_LDO4_VSET 0x64
#define ACT8865_LDO4_CTRL 0x65
#define ACT8865_MSTROFF 0x20
/*
* Field Definitions.
......@@ -98,6 +101,8 @@
struct act8865 {
struct regmap *regmap;
int off_reg;
int off_mask;
};
static const struct regmap_config act8865_regmap_config = {
......@@ -275,6 +280,16 @@ static struct regulator_init_data
return NULL;
}
static struct i2c_client *act8865_i2c_client;
static void act8865_power_off(void)
{
struct act8865 *act8865;
act8865 = i2c_get_clientdata(act8865_i2c_client);
regmap_write(act8865->regmap, act8865->off_reg, act8865->off_mask);
while (1);
}
static int act8865_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
{
......@@ -285,6 +300,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
int i, ret, num_regulators;
struct act8865 *act8865;
unsigned long type;
int off_reg, off_mask;
pdata = dev_get_platdata(dev);
......@@ -304,10 +320,14 @@ static int act8865_pmic_probe(struct i2c_client *client,
case ACT8846:
regulators = act8846_regulators;
num_regulators = ARRAY_SIZE(act8846_regulators);
off_reg = ACT8846_GLB_OFF_CTRL;
off_mask = ACT8846_OFF_SYSMASK;
break;
case ACT8865:
regulators = act8865_regulators;
num_regulators = ARRAY_SIZE(act8865_regulators);
off_reg = ACT8865_SYS_CTRL;
off_mask = ACT8865_MSTROFF;
break;
default:
dev_err(dev, "invalid device id %lu\n", type);
......@@ -345,6 +365,17 @@ static int act8865_pmic_probe(struct i2c_client *client,
return ret;
}
if (of_device_is_system_power_controller(dev->of_node)) {
if (!pm_power_off) {
act8865_i2c_client = client;
act8865->off_reg = off_reg;
act8865->off_mask = off_mask;
pm_power_off = act8865_power_off;
} else {
dev_err(dev, "Failed to set poweroff capability, already defined\n");
}
}
/* Finally register devices */
for (i = 0; i < num_regulators; i++) {
const struct regulator_desc *desc = &regulators[i];
......
......@@ -189,17 +189,18 @@ static int anatop_regulator_probe(struct platform_device *pdev)
int ret = 0;
u32 val;
initdata = of_get_regulator_init_data(dev, np);
sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
if (!sreg)
return -ENOMEM;
sreg->initdata = initdata;
sreg->name = of_get_property(np, "regulator-name", NULL);
rdesc = &sreg->rdesc;
rdesc->name = sreg->name;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->owner = THIS_MODULE;
initdata = of_get_regulator_init_data(dev, np, rdesc);
sreg->initdata = initdata;
anatop_np = of_get_parent(np);
if (!anatop_np)
return -ENODEV;
......@@ -283,6 +284,19 @@ static int anatop_regulator_probe(struct platform_device *pdev)
sreg->sel = 0;
sreg->bypass = true;
}
/*
* In case vddpu was disabled by the bootloader, we need to set
* a sane default until imx6-cpufreq was probed and changes the
* voltage to the correct value. In this case we set 1.25V.
*/
if (!sreg->sel && !strcmp(sreg->name, "vddpu"))
sreg->sel = 22;
if (!sreg->sel) {
dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
return -EINVAL;
}
} else {
rdesc->ops = &anatop_rops;
}
......
......@@ -179,7 +179,8 @@ static const struct regulator_init_data arizona_ldo1_default = {
};
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
struct regulator_config *config)
struct regulator_config *config,
const struct regulator_desc *desc)
{
struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_ldo1 *ldo1 = config->driver_data;
......@@ -194,7 +195,8 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
if (init_node) {
config->of_node = init_node;
init_data = of_get_regulator_init_data(arizona->dev, init_node);
init_data = of_get_regulator_init_data(arizona->dev, init_node,
desc);
if (init_data) {
init_data->consumer_supplies = &ldo1->supply;
......@@ -257,9 +259,11 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_OF)) {
if (!dev_get_platdata(arizona->dev)) {
ret = arizona_ldo1_of_get_pdata(arizona, &config);
ret = arizona_ldo1_of_get_pdata(arizona, &config, desc);
if (ret < 0)
return ret;
config.ena_gpio_initialized = true;
}
}
......
......@@ -198,7 +198,8 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
};
static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
struct regulator_config *config)
struct regulator_config *config,
const struct regulator_desc *desc)
{
struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_micsupp *micsupp = config->driver_data;
......@@ -210,7 +211,7 @@ static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
if (np) {
config->of_node = np;
init_data = of_get_regulator_init_data(arizona->dev, np);
init_data = of_get_regulator_init_data(arizona->dev, np, desc);
if (init_data) {
init_data->consumer_supplies = &micsupp->supply;
......@@ -264,7 +265,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_OF)) {
if (!dev_get_platdata(arizona->dev)) {
ret = arizona_micsupp_of_get_pdata(arizona, &config);
ret = arizona_micsupp_of_get_pdata(arizona, &config,
desc);
if (ret < 0)
return ret;
}
......
......@@ -828,7 +828,7 @@ static void print_constraints(struct regulator_dev *rdev)
if (!count)
sprintf(buf, "no parameters");
rdev_info(rdev, "%s\n", buf);
rdev_dbg(rdev, "%s\n", buf);
if ((constraints->min_uV != constraints->max_uV) &&
!(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
......@@ -1713,6 +1713,8 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
gpiod_put(pin->gpiod);
list_del(&pin->list);
kfree(pin);
rdev->ena_pin = NULL;
return;
} else {
pin->request_count--;
}
......@@ -1976,9 +1978,18 @@ static int _regulator_disable(struct regulator_dev *rdev)
/* we are last user */
if (_regulator_can_change_status(rdev)) {
ret = _notifier_call_chain(rdev,
REGULATOR_EVENT_PRE_DISABLE,
NULL);
if (ret & NOTIFY_STOP_MASK)
return -EINVAL;
ret = _regulator_do_disable(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to disable\n");
_notifier_call_chain(rdev,
REGULATOR_EVENT_ABORT_DISABLE,
NULL);
return ret;
}
_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
......@@ -2035,9 +2046,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
{
int ret = 0;
ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
REGULATOR_EVENT_PRE_DISABLE, NULL);
if (ret & NOTIFY_STOP_MASK)
return -EINVAL;
ret = _regulator_do_disable(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to force disable\n");
_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
REGULATOR_EVENT_ABORT_DISABLE, NULL);
return ret;
}
......@@ -3650,7 +3668,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
dev_set_drvdata(&rdev->dev, rdev);
if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
if ((config->ena_gpio || config->ena_gpio_initialized) &&
gpio_is_valid(config->ena_gpio)) {
ret = regulator_ena_gpio_request(rdev, config);
if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
......
......@@ -436,7 +436,8 @@ static int da9052_regulator_probe(struct platform_device *pdev)
if (!of_node_cmp(np->name,
regulator->info->reg_desc.name)) {
config.init_data = of_get_regulator_init_data(
&pdev->dev, np);
&pdev->dev, np,
&regulator->info->reg_desc);
config.of_node = np;
break;
}
......
......@@ -867,17 +867,14 @@ static int da9063_regulator_probe(struct platform_device *pdev)
return irq;
}
regulators->irq_ldo_lim = regmap_irq_get_virq(da9063->regmap_irq, irq);
if (regulators->irq_ldo_lim >= 0) {
ret = request_threaded_irq(regulators->irq_ldo_lim,
NULL, da9063_ldo_lim_event,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"LDO_LIM", regulators);
if (ret) {
dev_err(&pdev->dev,
"Failed to request LDO_LIM IRQ.\n");
regulators->irq_ldo_lim = -ENXIO;
}
ret = request_threaded_irq(irq,
NULL, da9063_ldo_lim_event,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"LDO_LIM", regulators);
if (ret) {
dev_err(&pdev->dev,
"Failed to request LDO_LIM IRQ.\n");
regulators->irq_ldo_lim = -ENXIO;
}
return 0;
......
......@@ -147,7 +147,7 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
config.dev = &i2c->dev;
config.init_data = pdata ? &pdata->da9210_constraints :
of_get_regulator_init_data(dev, dev->of_node);
of_get_regulator_init_data(dev, dev->of_node, &da9210_reg);
config.driver_data = chip;
config.regmap = chip->regmap;
config.of_node = dev->of_node;
......
......@@ -33,7 +33,7 @@ static struct regulator_init_data dummy_initdata = {
static struct regulator_ops dummy_ops;
static struct regulator_desc dummy_desc = {
static const struct regulator_desc dummy_desc = {
.name = "regulator-dummy",
.id = -1,
.type = REGULATOR_VOLTAGE,
......
......@@ -302,7 +302,8 @@ static struct regmap_config fan53555_regmap_config = {
};
static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
struct device_node *np)
struct device_node *np,
const struct regulator_desc *desc)
{
struct fan53555_platform_data *pdata;
int ret;
......@@ -312,7 +313,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
if (!pdata)
return NULL;
pdata->regulator = of_get_regulator_init_data(dev, np);
pdata->regulator = of_get_regulator_init_data(dev, np, desc);
ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
&tmp);
......@@ -347,20 +348,20 @@ static int fan53555_regulator_probe(struct i2c_client *client,
unsigned int val;
int ret;
di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
GFP_KERNEL);
if (!di)
return -ENOMEM;
pdata = dev_get_platdata(&client->dev);
if (!pdata)
pdata = fan53555_parse_dt(&client->dev, np);
pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
if (!pdata || !pdata->regulator) {
dev_err(&client->dev, "Platform data not found!\n");
return -ENODEV;
}
di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
GFP_KERNEL);
if (!di)
return -ENOMEM;
di->regulator = pdata->regulator;
if (client->dev.of_node) {
const struct of_device_id *match;
......
......@@ -40,13 +40,15 @@ struct fixed_voltage_data {
/**
* of_get_fixed_voltage_config - extract fixed_voltage_config structure info
* @dev: device requesting for fixed_voltage_config
* @desc: regulator description
*
* Populates fixed_voltage_config structure by extracting data from device
* tree node, returns a pointer to the populated structure of NULL if memory
* alloc fails.
*/
static struct fixed_voltage_config *
of_get_fixed_voltage_config(struct device *dev)
of_get_fixed_voltage_config(struct device *dev,
const struct regulator_desc *desc)
{
struct fixed_voltage_config *config;
struct device_node *np = dev->of_node;
......@@ -57,7 +59,7 @@ of_get_fixed_voltage_config(struct device *dev)
if (!config)
return ERR_PTR(-ENOMEM);
config->init_data = of_get_regulator_init_data(dev, dev->of_node);
config->init_data = of_get_regulator_init_data(dev, dev->of_node, desc);
if (!config->init_data)
return ERR_PTR(-EINVAL);
......@@ -112,8 +114,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
struct regulator_config cfg = { };
int ret;
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
if (pdev->dev.of_node) {
config = of_get_fixed_voltage_config(&pdev->dev);
config = of_get_fixed_voltage_config(&pdev->dev,
&drvdata->desc);
if (IS_ERR(config))
return PTR_ERR(config);
} else {
......@@ -123,11 +131,6 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
if (!config)
return -ENOMEM;
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->desc.name = devm_kstrdup(&pdev->dev,
config->supply_name,
GFP_KERNEL);
......@@ -157,8 +160,11 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->desc.fixed_uV = config->microvolts;
if (config->gpio >= 0)
if (gpio_is_valid(config->gpio)) {
cfg.ena_gpio = config->gpio;
if (pdev->dev.of_node)
cfg.ena_gpio_initialized = true;
}
cfg.ena_gpio_invert = !config->enable_high;
if (config->enabled_at_boot) {
if (config->enable_high)
......
......@@ -133,7 +133,8 @@ static struct regulator_ops gpio_regulator_voltage_ops = {
};
static struct gpio_regulator_config *
of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
const struct regulator_desc *desc)
{
struct gpio_regulator_config *config;
const char *regtype;
......@@ -146,7 +147,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
if (!config)
return ERR_PTR(-ENOMEM);
config->init_data = of_get_regulator_init_data(dev, np);
config->init_data = of_get_regulator_init_data(dev, np, desc);
if (!config->init_data)
return ERR_PTR(-EINVAL);
......@@ -162,34 +163,41 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
/* Fetch GPIOs. */
config->nr_gpios = of_gpio_count(np);
config->gpios = devm_kzalloc(dev,
sizeof(struct gpio) * config->nr_gpios,
GFP_KERNEL);
if (!config->gpios)
return ERR_PTR(-ENOMEM);
proplen = of_property_count_u32_elems(np, "gpios-states");
/* optional property */
if (proplen < 0)
proplen = 0;
if (proplen > 0 && proplen != config->nr_gpios) {
dev_warn(dev, "gpios <-> gpios-states mismatch\n");
proplen = 0;
}
/* Fetch GPIOs. - optional property*/
ret = of_gpio_count(np);
if ((ret < 0) && (ret != -ENOENT))
return ERR_PTR(ret);
if (ret > 0) {
config->nr_gpios = ret;
config->gpios = devm_kzalloc(dev,
sizeof(struct gpio) * config->nr_gpios,
GFP_KERNEL);
if (!config->gpios)
return ERR_PTR(-ENOMEM);
proplen = of_property_count_u32_elems(np, "gpios-states");
/* optional property */
if (proplen < 0)
proplen = 0;
if (proplen > 0 && proplen != config->nr_gpios) {
dev_warn(dev, "gpios <-> gpios-states mismatch\n");
proplen = 0;
}
for (i = 0; i < config->nr_gpios; i++) {
gpio = of_get_named_gpio(np, "gpios", i);
if (gpio < 0)
break;
config->gpios[i].gpio = gpio;
if (proplen > 0) {
of_property_read_u32_index(np, "gpios-states", i, &ret);
if (ret)
config->gpios[i].flags = GPIOF_OUT_INIT_HIGH;
for (i = 0; i < config->nr_gpios; i++) {
gpio = of_get_named_gpio(np, "gpios", i);
if (gpio < 0)
break;
config->gpios[i].gpio = gpio;
if (proplen > 0) {
of_property_read_u32_index(np, "gpios-states",
i, &ret);
if (ret)
config->gpios[i].flags =
GPIOF_OUT_INIT_HIGH;
}
}
}
......@@ -243,17 +251,18 @@ static int gpio_regulator_probe(struct platform_device *pdev)
struct regulator_config cfg = { };
int ptr, ret, state;
if (np) {
config = of_get_gpio_regulator_config(&pdev->dev, np);
if (IS_ERR(config))
return PTR_ERR(config);
}
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
GFP_KERNEL);
if (drvdata == NULL)
return -ENOMEM;
if (np) {
config = of_get_gpio_regulator_config(&pdev->dev, np,
&drvdata->desc);
if (IS_ERR(config))
return PTR_ERR(config);
}
drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
if (drvdata->desc.name == NULL) {
dev_err(&pdev->dev, "Failed to allocate supply name\n");
......@@ -261,13 +270,23 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err;
}
drvdata->gpios = kmemdup(config->gpios,
config->nr_gpios * sizeof(struct gpio),
GFP_KERNEL);
if (drvdata->gpios == NULL) {
dev_err(&pdev->dev, "Failed to allocate gpio data\n");
ret = -ENOMEM;
goto err_name;
if (config->nr_gpios != 0) {
drvdata->gpios = kmemdup(config->gpios,
config->nr_gpios * sizeof(struct gpio),
GFP_KERNEL);
if (drvdata->gpios == NULL) {
dev_err(&pdev->dev, "Failed to allocate gpio data\n");
ret = -ENOMEM;
goto err_name;
}
drvdata->nr_gpios = config->nr_gpios;
ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
if (ret) {
dev_err(&pdev->dev,
"Could not obtain regulator setting GPIOs: %d\n", ret);
goto err_memstate;
}
}
drvdata->states = kmemdup(config->states,
......@@ -301,14 +320,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err_memgpio;
}
drvdata->nr_gpios = config->nr_gpios;
ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
if (ret) {
dev_err(&pdev->dev,
"Could not obtain regulator setting GPIOs: %d\n", ret);
goto err_memstate;
}
/* build initial state from gpio init data. */
state = 0;
for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) {
......@@ -322,8 +333,10 @@ static int gpio_regulator_probe(struct platform_device *pdev)
cfg.driver_data = drvdata;
cfg.of_node = np;
if (config->enable_gpio >= 0)
if (gpio_is_valid(config->enable_gpio)) {
cfg.ena_gpio = config->enable_gpio;
cfg.ena_gpio_initialized = true;
}
cfg.ena_gpio_invert = !config->enable_high;
if (config->enabled_at_boot) {
if (config->enable_high)
......
This diff is collapsed.
......@@ -139,7 +139,7 @@ static struct regulator_ops max77693_charger_ops = {
.enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \
}
static struct regulator_desc regulators[] = {
static const struct regulator_desc regulators[] = {
regulator_desc_esafeout(1),
regulator_desc_esafeout(2),
{
......
This diff is collapsed.
......@@ -174,7 +174,7 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed))
dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n");
pd->reg_data = of_get_regulator_init_data(dev, np);
pd->reg_data = of_get_regulator_init_data(dev, np, &regulator);
if (!pd->reg_data) {
dev_err(dev, "Failed to parse regulator init data\n");
return NULL;
......@@ -225,6 +225,8 @@ static int max8952_pmic_probe(struct i2c_client *client,
config.of_node = client->dev.of_node;
config.ena_gpio = pdata->gpio_en;
if (client->dev.of_node)
config.ena_gpio_initialized = true;
if (pdata->reg_data->constraints.boot_on)
config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
......
......@@ -458,7 +458,8 @@ static int max8973_probe(struct i2c_client *client,
config.dev = &client->dev;
config.init_data = pdata ? pdata->reg_init_data :
of_get_regulator_init_data(&client->dev, client->dev.of_node);
of_get_regulator_init_data(&client->dev, client->dev.of_node,
&max->desc);
config.driver_data = max;
config.of_node = client->dev.of_node;
config.regmap = max->regmap;
......
......@@ -953,7 +953,8 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
rdata->id = i;
rdata->initdata = of_get_regulator_init_data(&pdev->dev,
reg_np);
reg_np,
&regulators[i]);
rdata->reg_node = reg_np;
rdata++;
}
......
......@@ -686,8 +686,9 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
continue;
rdata->id = regulators[i].id;
rdata->initdata = of_get_regulator_init_data(
iodev->dev, reg_np);
rdata->initdata = of_get_regulator_init_data(iodev->dev,
reg_np,
&regulators[i]);
rdata->reg_node = reg_np;
++rdata;
}
......
......@@ -194,7 +194,8 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
regulators[i].desc.name)) {
p->id = i;
p->init_data = of_get_regulator_init_data(
&pdev->dev, child);
&pdev->dev, child,
&regulators[i].desc);
p->node = child;
p++;
......
......@@ -19,12 +19,20 @@
#include "internal.h"
static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
[PM_SUSPEND_MEM] = "regulator-state-mem",
[PM_SUSPEND_MAX] = "regulator-state-disk",
};
static void of_get_regulation_constraints(struct device_node *np,
struct regulator_init_data **init_data)
struct regulator_init_data **init_data,
const struct regulator_desc *desc)
{
const __be32 *min_uV, *max_uV;
struct regulation_constraints *constraints = &(*init_data)->constraints;
int ret;
struct regulator_state *suspend_state;
struct device_node *suspend_np;
int ret, i;
u32 pval;
constraints->name = of_get_property(np, "regulator-name", NULL);
......@@ -73,18 +81,84 @@ static void of_get_regulation_constraints(struct device_node *np,
ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
if (!ret)
constraints->enable_time = pval;
if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) {
if (desc && desc->of_map_mode) {
ret = desc->of_map_mode(pval);
if (ret == -EINVAL)
pr_err("%s: invalid mode %u\n", np->name, pval);
else
constraints->initial_mode = ret;
} else {
pr_warn("%s: mapping for mode %d not defined\n",
np->name, pval);
}
}
for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
switch (i) {
case PM_SUSPEND_MEM:
suspend_state = &constraints->state_mem;
break;
case PM_SUSPEND_MAX:
suspend_state = &constraints->state_disk;
break;
case PM_SUSPEND_ON:
case PM_SUSPEND_FREEZE:
case PM_SUSPEND_STANDBY:
default:
continue;
};
suspend_np = of_get_child_by_name(np, regulator_states[i]);
if (!suspend_np || !suspend_state)
continue;
if (!of_property_read_u32(suspend_np, "regulator-mode",
&pval)) {
if (desc && desc->of_map_mode) {
ret = desc->of_map_mode(pval);
if (ret == -EINVAL)
pr_err("%s: invalid mode %u\n",
np->name, pval);
else
suspend_state->mode = ret;
} else {
pr_warn("%s: mapping for mode %d not defined\n",
np->name, pval);
}
}
if (of_property_read_bool(suspend_np,
"regulator-on-in-suspend"))
suspend_state->enabled = true;
else if (of_property_read_bool(suspend_np,
"regulator-off-in-suspend"))
suspend_state->disabled = true;
if (!of_property_read_u32(suspend_np,
"regulator-suspend-microvolt", &pval))
suspend_state->uV = pval;
of_node_put(suspend_np);
suspend_state = NULL;
suspend_np = NULL;
}
}
/**
* of_get_regulator_init_data - extract regulator_init_data structure info
* @dev: device requesting for regulator_init_data
* @node: regulator device node
* @desc: regulator description
*
* Populates regulator_init_data structure by extracting data from device
* tree node, returns a pointer to the populated struture or NULL if memory
* alloc fails.
*/
struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
struct device_node *node)
struct device_node *node,
const struct regulator_desc *desc)
{
struct regulator_init_data *init_data;
......@@ -95,7 +169,7 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
if (!init_data)
return NULL; /* Out of memory? */
of_get_regulation_constraints(node, &init_data);
of_get_regulation_constraints(node, &init_data, desc);
return init_data;
}
EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
......@@ -176,7 +250,8 @@ int of_regulator_match(struct device *dev, struct device_node *node,
continue;
match->init_data =
of_get_regulator_init_data(dev, child);
of_get_regulator_init_data(dev, child,
match->desc);
if (!match->init_data) {
dev_err(dev,
"failed to parse DT for regulator %s\n",
......@@ -224,7 +299,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
if (strcmp(desc->of_match, name))
continue;
init_data = of_get_regulator_init_data(dev, child);
init_data = of_get_regulator_init_data(dev, child, desc);
if (!init_data) {
dev_err(dev,
"failed to parse DT for regulator %s\n",
......
......@@ -149,7 +149,8 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return ret;
}
config.init_data = of_get_regulator_init_data(&pdev->dev, np);
config.init_data = of_get_regulator_init_data(&pdev->dev, np,
&drvdata->desc);
if (!config.init_data)
return -ENOMEM;
......
......@@ -183,6 +183,13 @@ static const struct regulator_linear_range ftsmps_ranges[] = {
REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000),
};
static const struct regulator_linear_range smb208_ranges[] = {
REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500),
REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500),
REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000),
REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000),
};
static const struct regulator_linear_range ncp_ranges[] = {
REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000),
};
......@@ -559,6 +566,16 @@ static const struct qcom_rpm_reg pm8921_switch = {
.parts = &rpm8960_switch_parts,
};
static const struct qcom_rpm_reg smb208_smps = {
.desc.linear_ranges = smb208_ranges,
.desc.n_linear_ranges = ARRAY_SIZE(smb208_ranges),
.desc.n_voltages = 235,
.desc.ops = &uV_ops,
.parts = &rpm8960_smps_parts,
.supports_force_mode_auto = false,
.supports_force_mode_bypass = false,
};
static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo },
{ .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo },
......@@ -578,6 +595,8 @@ static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps },
{ .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp },
{ .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch },
{ .compatible = "qcom,rpm-smb208", .data = &smb208_smps },
{ }
};
MODULE_DEVICE_TABLE(of, rpm_of_match);
......@@ -643,10 +662,6 @@ static int rpm_reg_probe(struct platform_device *pdev)
match = of_match_device(rpm_of_match, &pdev->dev);
template = match->data;
initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
if (!initdata)
return -EINVAL;
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
if (!vreg) {
dev_err(&pdev->dev, "failed to allocate vreg\n");
......@@ -666,6 +681,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENODEV;
}
initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&vreg->desc);
if (!initdata)
return -EINVAL;
key = "reg";
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
if (ret) {
......
......@@ -36,6 +36,12 @@
#define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET)
#define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET)
/* Offset from XXX_ON_VSEL to XXX_SLP_VSEL */
#define RK808_SLP_REG_OFFSET 1
/* Offset from XXX_EN_REG to SLEEP_SET_OFF_XXX */
#define RK808_SLP_SET_OFF_REG_OFFSET 2
static const int rk808_buck_config_regs[] = {
RK808_BUCK1_CONFIG_REG,
RK808_BUCK2_CONFIG_REG,
......@@ -91,6 +97,43 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
RK808_RAMP_RATE_MASK, ramp_value);
}
int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
if (sel < 0)
return -EINVAL;
reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
return regmap_update_bits(rdev->regmap, reg,
rdev->desc->vsel_mask,
sel);
}
int rk808_set_suspend_enable(struct regulator_dev *rdev)
{
unsigned int reg;
reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
return regmap_update_bits(rdev->regmap, reg,
rdev->desc->enable_mask,
0);
}
int rk808_set_suspend_disable(struct regulator_dev *rdev)
{
unsigned int reg;
reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
return regmap_update_bits(rdev->regmap, reg,
rdev->desc->enable_mask,
rdev->desc->enable_mask);
}
static struct regulator_ops rk808_buck1_2_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
......@@ -100,6 +143,9 @@ static struct regulator_ops rk808_buck1_2_ops = {
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_ramp_delay = rk808_set_ramp_delay,
.set_suspend_voltage = rk808_set_suspend_voltage,
.set_suspend_enable = rk808_set_suspend_enable,
.set_suspend_disable = rk808_set_suspend_disable,
};
static struct regulator_ops rk808_reg_ops = {
......@@ -110,12 +156,17 @@ static struct regulator_ops rk808_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_suspend_voltage = rk808_set_suspend_voltage,
.set_suspend_enable = rk808_set_suspend_enable,
.set_suspend_disable = rk808_set_suspend_disable,
};
static struct regulator_ops rk808_switch_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_suspend_enable = rk808_set_suspend_enable,
.set_suspend_disable = rk808_set_suspend_disable,
};
static const struct regulator_desc rk808_reg[] = {
......
......@@ -31,6 +31,8 @@ static struct regulator_ops rn5t618_reg_ops = {
#define REG(rid, ereg, emask, vreg, vmask, min, max, step) \
[RN5T618_##rid] = { \
.name = #rid, \
.of_match = of_match_ptr(#rid), \
.regulators_node = of_match_ptr("regulators"), \
.id = RN5T618_##rid, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
......@@ -60,60 +62,15 @@ static struct regulator_desc rn5t618_regulators[] = {
REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
};
static struct of_regulator_match rn5t618_matches[] = {
[RN5T618_DCDC1] = { .name = "DCDC1" },
[RN5T618_DCDC2] = { .name = "DCDC2" },
[RN5T618_DCDC3] = { .name = "DCDC3" },
[RN5T618_LDO1] = { .name = "LDO1" },
[RN5T618_LDO2] = { .name = "LDO2" },
[RN5T618_LDO3] = { .name = "LDO3" },
[RN5T618_LDO4] = { .name = "LDO4" },
[RN5T618_LDO5] = { .name = "LDO5" },
[RN5T618_LDORTC1] = { .name = "LDORTC1" },
[RN5T618_LDORTC2] = { .name = "LDORTC2" },
};
static int rn5t618_regulator_parse_dt(struct platform_device *pdev)
{
struct device_node *np, *regulators;
int ret;
np = of_node_get(pdev->dev.parent->of_node);
if (!np)
return 0;
regulators = of_get_child_by_name(np, "regulators");
if (!regulators) {
dev_err(&pdev->dev, "regulators node not found\n");
return -EINVAL;
}
ret = of_regulator_match(&pdev->dev, regulators, rn5t618_matches,
ARRAY_SIZE(rn5t618_matches));
of_node_put(regulators);
if (ret < 0) {
dev_err(&pdev->dev, "error parsing regulator init data: %d\n",
ret);
}
return 0;
}
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;
int ret, i;
ret = rn5t618_regulator_parse_dt(pdev);
if (ret)
return ret;
int i;
for (i = 0; i < RN5T618_REG_NUM; i++) {
config.dev = &pdev->dev;
config.init_data = rn5t618_matches[i].init_data;
config.of_node = rn5t618_matches[i].of_node;
config.dev = pdev->dev.parent;
config.regmap = rn5t618->regmap;
rdev = devm_regulator_register(&pdev->dev,
......
/*
* Regulator driver for the Richtek RT5033
*
* Copyright (C) 2014 Samsung Electronics, Co., Ltd.
* Author: Beomho Seo <beomho.seo@samsung.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 bythe Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/mfd/rt5033.h>
#include <linux/mfd/rt5033-private.h>
#include <linux/regulator/of_regulator.h>
static struct regulator_ops rt5033_safe_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops rt5033_buck_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_desc rt5033_supported_regulators[] = {
[RT5033_BUCK] = {
.name = "BUCK",
.id = RT5033_BUCK,
.ops = &rt5033_buck_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM,
.min_uV = RT5033_REGULATOR_BUCK_VOLTAGE_MIN,
.uV_step = RT5033_REGULATOR_BUCK_VOLTAGE_STEP,
.enable_reg = RT5033_REG_CTRL,
.enable_mask = RT5033_CTRL_EN_BUCK_MASK,
.vsel_reg = RT5033_REG_BUCK_CTRL,
.vsel_mask = RT5033_BUCK_CTRL_MASK,
},
[RT5033_LDO] = {
.name = "LDO",
.id = RT5033_LDO,
.ops = &rt5033_buck_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM,
.min_uV = RT5033_REGULATOR_LDO_VOLTAGE_MIN,
.uV_step = RT5033_REGULATOR_LDO_VOLTAGE_STEP,
.enable_reg = RT5033_REG_CTRL,
.enable_mask = RT5033_CTRL_EN_LDO_MASK,
.vsel_reg = RT5033_REG_LDO_CTRL,
.vsel_mask = RT5033_LDO_CTRL_MASK,
},
[RT5033_SAFE_LDO] = {
.name = "SAFE_LDO",
.id = RT5033_SAFE_LDO,
.ops = &rt5033_safe_ldo_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = 1,
.min_uV = RT5033_REGULATOR_SAFE_LDO_VOLTAGE,
.enable_reg = RT5033_REG_CTRL,
.enable_mask = RT5033_CTRL_EN_SAFE_LDO_MASK,
},
};
static int rt5033_regulator_probe(struct platform_device *pdev)
{
struct rt5033_dev *rt5033 = dev_get_drvdata(pdev->dev.parent);
int ret, i;
struct regulator_config config = {};
config.dev = &pdev->dev;
config.driver_data = rt5033;
for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) {
struct regulator_dev *regulator;
config.regmap = rt5033->regmap;
regulator = devm_regulator_register(&pdev->dev,
&rt5033_supported_regulators[i], &config);
if (IS_ERR(regulator)) {
ret = PTR_ERR(regulator);
dev_err(&pdev->dev,
"Regulator init failed %d: with error: %d\n",
i, ret);
return ret;
}
}
return 0;
}
static const struct platform_device_id rt5033_regulator_id[] = {
{ "rt5033-regulator", },
{ }
};
MODULE_DEVICE_TABLE(platform, rt5033_regulator_id);
static struct platform_driver rt5033_regulator_driver = {
.driver = {
.name = "rt5033-regulator",
},
.probe = rt5033_regulator_probe,
.id_table = rt5033_regulator_id,
};
module_platform_driver(rt5033_regulator_driver);
MODULE_DESCRIPTION("Richtek RT5033 Regulator driver");
MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
MODULE_LICENSE("GPL");
......@@ -298,7 +298,7 @@ static struct regulator_ops s2mpa01_buck_ops = {
.enable_mask = S2MPA01_ENABLE_MASK \
}
static struct regulator_desc regulators[] = {
static const struct regulator_desc regulators[] = {
regulator_desc_ldo(1, STEP_25_MV),
regulator_desc_ldo(2, STEP_50_MV),
regulator_desc_ldo(3, STEP_50_MV),
......
......@@ -940,7 +940,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
return -EINVAL;
};
s2mps11->ext_control_gpio = devm_kzalloc(&pdev->dev,
s2mps11->ext_control_gpio = devm_kmalloc(&pdev->dev,
sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num,
GFP_KERNEL);
if (!s2mps11->ext_control_gpio)
......@@ -981,6 +981,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
config.regmap = iodev->regmap_pmic;
config.driver_data = s2mps11;
config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
config.ena_gpio_initialized = true;
for (i = 0; i < s2mps11->rdev_num; i++) {
struct regulator_dev *regulator;
......
......@@ -581,7 +581,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
rdata->id = i;
rdata->initdata = of_get_regulator_init_data(
&pdev->dev, reg_np);
&pdev->dev, reg_np,
&regulators[i]);
rdata->reg_node = reg_np;
rdata++;
rmode->id = i;
......@@ -950,6 +951,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
config.of_node = pdata->regulators[i].reg_node;
config.ena_gpio = -EINVAL;
config.ena_gpio_flags = 0;
config.ena_gpio_initialized = true;
if (gpio_is_valid(pdata->regulators[i].ext_control_gpio))
s5m8767_regulator_config_ext_control(s5m8767,
&pdata->regulators[i], &config);
......
......@@ -5,9 +5,8 @@
* 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 as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
* 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
......@@ -52,6 +51,8 @@ static const struct regulator_linear_range sky81452_reg_ranges[] = {
static const struct regulator_desc sky81452_reg = {
.name = "LOUT",
.of_match = of_match_ptr("lout"),
.regulators_node = of_match_ptr("regulator"),
.ops = &sky81452_reg_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
......@@ -64,30 +65,6 @@ static const struct regulator_desc sky81452_reg = {
.enable_mask = SKY81452_LEN,
};
#ifdef CONFIG_OF
static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev)
{
struct regulator_init_data *init_data;
struct device_node *np;
np = of_get_child_by_name(dev->parent->of_node, "regulator");
if (unlikely(!np)) {
dev_err(dev, "regulator node not found");
return NULL;
}
init_data = of_get_regulator_init_data(dev, np);
of_node_put(np);
return init_data;
}
#else
static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev)
{
return ERR_PTR(-EINVAL);
}
#endif
static int sky81452_reg_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
......@@ -95,20 +72,16 @@ static int sky81452_reg_probe(struct platform_device *pdev)
struct regulator_config config = { };
struct regulator_dev *rdev;
if (!init_data) {
init_data = sky81452_reg_parse_dt(dev);
if (IS_ERR(init_data))
return PTR_ERR(init_data);
}
config.dev = dev;
config.dev = dev->parent;
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = dev_get_drvdata(dev->parent);
rdev = devm_regulator_register(dev, &sky81452_reg, &config);
if (IS_ERR(rdev))
if (IS_ERR(rdev)) {
dev_err(dev, "failed to register. err=%ld\n", PTR_ERR(rdev));
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
......@@ -126,5 +99,4 @@ module_platform_driver(sky81452_reg_driver);
MODULE_DESCRIPTION("Skyworks SKY81452 Regulator driver");
MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");
......@@ -72,7 +72,8 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
config.regmap = stw481x->map;
config.of_node = pdev->dev.of_node;
config.init_data = of_get_regulator_init_data(&pdev->dev,
pdev->dev.of_node);
pdev->dev.of_node,
&vmmc_regulator);
stw481x->vmmc_regulator = devm_regulator_register(&pdev->dev,
&vmmc_regulator, &config);
......
......@@ -837,7 +837,8 @@ static int ti_abb_probe(struct platform_device *pdev)
return -EINVAL;
}
initdata = of_get_regulator_init_data(dev, pdev->dev.of_node);
initdata = of_get_regulator_init_data(dev, pdev->dev.of_node,
&abb->rdesc);
if (!initdata) {
dev_err(dev, "%s: Unable to alloc regulator init data\n",
__func__);
......
......@@ -221,7 +221,8 @@ static const struct of_device_id tps51632_of_match[] = {
MODULE_DEVICE_TABLE(of, tps51632_of_match);
static struct tps51632_regulator_platform_data *
of_get_tps51632_platform_data(struct device *dev)
of_get_tps51632_platform_data(struct device *dev,
const struct regulator_desc *desc)
{
struct tps51632_regulator_platform_data *pdata;
struct device_node *np = dev->of_node;
......@@ -230,7 +231,8 @@ static struct tps51632_regulator_platform_data *
if (!pdata)
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,
desc);
if (!pdata->reg_init_data) {
dev_err(dev, "Not able to get OF regulator init data\n");
return NULL;
......@@ -248,7 +250,8 @@ static struct tps51632_regulator_platform_data *
}
#else
static struct tps51632_regulator_platform_data *
of_get_tps51632_platform_data(struct device *dev)
of_get_tps51632_platform_data(struct device *dev,
const struct regulator_desc *desc)
{
return NULL;
}
......@@ -273,9 +276,25 @@ static int tps51632_probe(struct i2c_client *client,
}
}
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
tps->dev = &client->dev;
tps->desc.name = client->name;
tps->desc.id = 0;
tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
tps->desc.min_uV = TPS51632_MIN_VOLTAGE;
tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV;
tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
tps->desc.ops = &tps51632_dcdc_ops;
tps->desc.type = REGULATOR_VOLTAGE;
tps->desc.owner = THIS_MODULE;
pdata = dev_get_platdata(&client->dev);
if (!pdata && client->dev.of_node)
pdata = of_get_tps51632_platform_data(&client->dev);
pdata = of_get_tps51632_platform_data(&client->dev, &tps->desc);
if (!pdata) {
dev_err(&client->dev, "No Platform data\n");
return -EINVAL;
......@@ -296,22 +315,6 @@ static int tps51632_probe(struct i2c_client *client,
}
}
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
tps->dev = &client->dev;
tps->desc.name = client->name;
tps->desc.id = 0;
tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
tps->desc.min_uV = TPS51632_MIN_VOLTAGE;
tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV;
tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
tps->desc.ops = &tps51632_dcdc_ops;
tps->desc.type = REGULATOR_VOLTAGE;
tps->desc.owner = THIS_MODULE;
if (pdata->enable_pwm_dvfs)
tps->desc.vsel_reg = TPS51632_VOLTAGE_BASE_REG;
else
......
......@@ -293,7 +293,8 @@ static const struct regmap_config tps62360_regmap_config = {
};
static struct tps62360_regulator_platform_data *
of_get_tps62360_platform_data(struct device *dev)
of_get_tps62360_platform_data(struct device *dev,
const struct regulator_desc *desc)
{
struct tps62360_regulator_platform_data *pdata;
struct device_node *np = dev->of_node;
......@@ -302,7 +303,8 @@ static struct tps62360_regulator_platform_data *
if (!pdata)
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,
desc);
if (!pdata->reg_init_data) {
dev_err(dev, "Not able to get OF regulator init data\n");
return NULL;
......@@ -350,6 +352,17 @@ static int tps62360_probe(struct i2c_client *client,
pdata = dev_get_platdata(&client->dev);
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
tps->desc.name = client->name;
tps->desc.id = 0;
tps->desc.ops = &tps62360_dcdc_ops;
tps->desc.type = REGULATOR_VOLTAGE;
tps->desc.owner = THIS_MODULE;
tps->desc.uV_step = 10000;
if (client->dev.of_node) {
const struct of_device_id *match;
match = of_match_device(of_match_ptr(tps62360_of_match),
......@@ -360,7 +373,8 @@ static int tps62360_probe(struct i2c_client *client,
}
chip_id = (int)(long)match->data;
if (!pdata)
pdata = of_get_tps62360_platform_data(&client->dev);
pdata = of_get_tps62360_platform_data(&client->dev,
&tps->desc);
} else if (id) {
chip_id = id->driver_data;
} else {
......@@ -374,10 +388,6 @@ static int tps62360_probe(struct i2c_client *client,
return -EIO;
}
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
tps->en_discharge = pdata->en_discharge;
tps->en_internal_pulldn = pdata->en_internal_pulldn;
tps->vsel0_gpio = pdata->vsel0_gpio;
......@@ -401,13 +411,6 @@ static int tps62360_probe(struct i2c_client *client,
return -ENODEV;
}
tps->desc.name = client->name;
tps->desc.id = 0;
tps->desc.ops = &tps62360_dcdc_ops;
tps->desc.type = REGULATOR_VOLTAGE;
tps->desc.owner = THIS_MODULE;
tps->desc.uV_step = 10000;
tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config);
if (IS_ERR(tps->regmap)) {
ret = PTR_ERR(tps->regmap);
......
......@@ -312,7 +312,11 @@ static void tps65090_configure_regulator_config(
gpio_flag = GPIOF_OUT_INIT_HIGH;
config->ena_gpio = tps_pdata->gpio;
config->ena_gpio_initialized = true;
config->ena_gpio_flags = gpio_flag;
} else {
config->ena_gpio = -EINVAL;
config->ena_gpio_initialized = false;
}
}
......
......@@ -231,7 +231,8 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
template = match->data;
id = template->id;
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&regulators[id]);
platform_set_drvdata(pdev, tps);
......
......@@ -1104,7 +1104,8 @@ static int twlreg_probe(struct platform_device *pdev)
template = match->data;
id = template->desc.id;
initdata = of_get_regulator_init_data(&pdev->dev,
pdev->dev.of_node);
pdev->dev.of_node,
&template->desc);
drvdata = NULL;
} else {
id = pdev->id;
......
......@@ -74,7 +74,8 @@ static int vexpress_regulator_probe(struct platform_device *pdev)
reg->desc.owner = THIS_MODULE;
reg->desc.continuous_voltage_range = true;
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&reg->desc);
if (!init_data)
return -EINVAL;
......
......@@ -145,10 +145,12 @@ static int wm8994_ldo_probe(struct platform_device *pdev)
config.driver_data = ldo;
config.regmap = wm8994->regmap;
config.init_data = &ldo->init_data;
if (pdata)
if (pdata) {
config.ena_gpio = pdata->ldo[id].enable;
else if (wm8994->dev->of_node)
} else if (wm8994->dev->of_node) {
config.ena_gpio = wm8994->pdata.ldo[id].enable;
config.ena_gpio_initialized = true;
}
/* Use default constraints if none set up */
if (!pdata || !pdata->ldo[id].init_data || wm8994->dev->of_node) {
......
/*
* Copyright (C) 2014 Google, Inc
*
* 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.
*
* Device Tree binding constants for the Maxim 77802 PMIC regulators
*/
#ifndef _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H
#define _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H
/* Regulator operating modes */
#define MAX77802_OPMODE_LP 1
#define MAX77802_OPMODE_NORMAL 3
#endif /* _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H */
......@@ -131,13 +131,6 @@ enum max77686_opmode {
MAX77686_OPMODE_STANDBY,
};
enum max77802_opmode {
MAX77802_OPMODE_OFF,
MAX77802_OPMODE_STANDBY,
MAX77802_OPMODE_LP,
MAX77802_OPMODE_NORMAL,
};
struct max77686_opmode_data {
int id;
int mode;
......
......@@ -923,14 +923,14 @@ static inline int of_changeset_update_property(struct of_changeset *ocs,
extern int of_resolve_phandles(struct device_node *tree);
/**
* of_system_has_poweroff_source - Tells if poweroff-source is found for device_node
* of_device_is_system_power_controller - Tells if system-power-controller is found for device_node
* @np: Pointer to the given device_node
*
* return true if present false otherwise
*/
static inline bool of_system_has_poweroff_source(const struct device_node *np)
static inline bool of_device_is_system_power_controller(const struct device_node *np)
{
return of_property_read_bool(np, "poweroff-source");
return of_property_read_bool(np, "system-power-controller");
}
#endif /* _LINUX_OF_H */
......@@ -101,6 +101,8 @@ struct regmap;
* Data passed is "struct pre_voltage_change_data"
* ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason.
* Data passed is old voltage cast to (void *).
* PRE_DISABLE Regulator is about to be disabled
* ABORT_DISABLE Regulator disable failed for some reason
*
* NOTE: These events can be OR'ed together when passed into handler.
*/
......@@ -115,6 +117,8 @@ struct regmap;
#define REGULATOR_EVENT_DISABLE 0x80
#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
#define REGULATOR_EVENT_PRE_DISABLE 0x400
#define REGULATOR_EVENT_ABORT_DISABLE 0x800
/**
* struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event
......@@ -284,7 +288,7 @@ devm_regulator_get(struct device *dev, const char *id)
static inline struct regulator *__must_check
regulator_get_exclusive(struct device *dev, const char *id)
{
return NULL;
return ERR_PTR(-ENODEV);
}
static inline struct regulator *__must_check
......
......@@ -243,6 +243,8 @@ enum regulator_type {
*
* @enable_time: Time taken for initial enable of regulator (in uS).
* @off_on_delay: guard time (in uS), before re-enabling a regulator
*
* @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode
*/
struct regulator_desc {
const char *name;
......@@ -285,6 +287,8 @@ struct regulator_desc {
unsigned int enable_time;
unsigned int off_on_delay;
unsigned int (*of_map_mode)(unsigned int mode);
};
/**
......@@ -301,6 +305,9 @@ struct regulator_desc {
* NULL).
* @regmap: regmap to use for core regmap helpers if dev_get_regulator() is
* insufficient.
* @ena_gpio_initialized: GPIO controlling regulator enable was properly
* initialized, meaning that >= 0 is a valid gpio
* identifier and < 0 is a non existent gpio.
* @ena_gpio: GPIO controlling regulator enable.
* @ena_gpio_invert: Sense for GPIO enable control.
* @ena_gpio_flags: Flags to use when calling gpio_request_one()
......@@ -312,6 +319,7 @@ struct regulator_config {
struct device_node *of_node;
struct regmap *regmap;
bool ena_gpio_initialized;
int ena_gpio;
unsigned int ena_gpio_invert:1;
unsigned int ena_gpio_flags;
......
......@@ -6,24 +6,29 @@
#ifndef __LINUX_OF_REG_H
#define __LINUX_OF_REG_H
struct regulator_desc;
struct of_regulator_match {
const char *name;
void *driver_data;
struct regulator_init_data *init_data;
struct device_node *of_node;
const struct regulator_desc *desc;
};
#if defined(CONFIG_OF)
extern struct regulator_init_data
*of_get_regulator_init_data(struct device *dev,
struct device_node *node);
struct device_node *node,
const struct regulator_desc *desc);
extern int of_regulator_match(struct device *dev, struct device_node *node,
struct of_regulator_match *matches,
unsigned int num_matches);
#else
static inline struct regulator_init_data
*of_get_regulator_init_data(struct device *dev,
struct device_node *node)
struct device_node *node,
const struct regulator_desc *desc)
{
return NULL;
}
......
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