mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge tag 'regulator-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown:
"A fairly quiet release for the regulator API, the bulk of the changes
being lots of small cleanups and API updates contributed by Axel Lin
with just a small set of larger changes:
- New driver for LP8755
- DT support for S5M8767, TPS51632, TPS6507x and TPS65090
- Support for writing a "commit changes" bit in the regmap helper
functions."
* tag 'regulator-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (60 commits)
regulator: Fix memory garbage dev_err printout.
regulator: max77686: Reuse rdev_get_id() function.
regulator: tps51632: Use regulator_[get|set]_voltage_sel_regmap
regulator: as3711: Fix checking if no platform initialization data
regulator: s5m8767: Prevent possible NULL pointer dereference
regulator: s5m8767: Fix dev argument for devm_kzalloc and of_get_regulator_init_data
regulator: core: Optimize _regulator_do_set_voltage if voltage does not change
regulator: max8998: Let regulator core handle the case selector == old_selector
regulator: s5m8767: Use of_get_child_count()
regulator: anatop: improve precision of delay time
regulator: show state for GPIO-controlled regulators
regulator: s5m8767: Fix build in non-DT case
regulator: add device tree support for s5m8767
regulator: palmas: Remove a redundant setting for warm_reset
regulator: mc13xxx: Use of_get_child_count()
regulator: max8997: Use of_get_child_count()
regulator: tps65090: Fix using wrong dev argument for calling of_regulator_match
regulators: anatop: add set_voltage_time_sel interface
regulator: Add missing of_node_put()
regulator: tps6507x: Fix using wrong dev argument for calling of_regulator_match
...
This commit is contained in:
91
Documentation/devicetree/bindings/mfd/tps6507x.txt
Executable file
91
Documentation/devicetree/bindings/mfd/tps6507x.txt
Executable file
@@ -0,0 +1,91 @@
|
||||
TPS6507x Power Management Integrated Circuit
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,tps6507x"
|
||||
- reg: I2C slave address
|
||||
- regulators: This is the list of child nodes that specify the regulator
|
||||
initialization data for defined regulators. Not all regulators for the
|
||||
given device need to be present. The definition for each of these nodes
|
||||
is defined using the standard binding for regulators found at
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
The regulator is matched with the regulator-compatible.
|
||||
|
||||
The valid regulator-compatible values are:
|
||||
tps6507x: vdcdc1, vdcdc2, vdcdc3, vldo1, vldo2
|
||||
- xxx-supply: Input voltage supply regulator.
|
||||
These entries are required if regulators are enabled for a device.
|
||||
Missing of these properties can cause the regulator registration
|
||||
fails.
|
||||
If some of input supply is powered through battery or always-on
|
||||
supply then also it is require to have these parameters with proper
|
||||
node handle of always on power supply.
|
||||
tps6507x:
|
||||
vindcdc1_2-supply: VDCDC1 and VDCDC2 input.
|
||||
vindcdc3-supply : VDCDC3 input.
|
||||
vldo1_2-supply : VLDO1 and VLDO2 input.
|
||||
|
||||
Regulator Optional properties:
|
||||
- defdcdc_default: It's property of DCDC2 and DCDC3 regulators.
|
||||
0: If defdcdc pin of DCDC2/DCDC3 is pulled to GND.
|
||||
1: If defdcdc pin of DCDC2/DCDC3 is driven HIGH.
|
||||
If this property is not defined, it defaults to 0 (not enabled).
|
||||
|
||||
Example:
|
||||
|
||||
pmu: tps6507x@48 {
|
||||
compatible = "ti,tps6507x";
|
||||
reg = <0x48>;
|
||||
|
||||
vindcdc1_2-supply = <&vbat>;
|
||||
vindcdc3-supply = <...>;
|
||||
vinldo1_2-supply = <...>;
|
||||
|
||||
regulators {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
vdcdc1_reg: regulator@0 {
|
||||
regulator-compatible = "VDCDC1";
|
||||
reg = <0>;
|
||||
regulator-min-microvolt = <3150000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
vdcdc2_reg: regulator@1 {
|
||||
regulator-compatible = "VDCDC2";
|
||||
reg = <1>;
|
||||
regulator-min-microvolt = <1710000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
defdcdc_default = <1>;
|
||||
};
|
||||
vdcdc3_reg: regulator@2 {
|
||||
regulator-compatible = "VDCDC3";
|
||||
reg = <2>;
|
||||
regulator-min-microvolt = <950000>
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
defdcdc_default = <1>;
|
||||
};
|
||||
ldo1_reg: regulator@3 {
|
||||
regulator-compatible = "LDO1";
|
||||
reg = <3>;
|
||||
regulator-min-microvolt = <1710000>;
|
||||
regulator-max-microvolt = <1890000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
ldo2_reg: regulator@4 {
|
||||
regulator-compatible = "LDO2";
|
||||
reg = <4>;
|
||||
regulator-min-microvolt = <1140000>;
|
||||
regulator-max-microvolt = <1320000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
@@ -9,6 +9,11 @@ Required properties:
|
||||
- anatop-min-voltage: Minimum voltage of this regulator
|
||||
- anatop-max-voltage: Maximum voltage of this regulator
|
||||
|
||||
Optional properties:
|
||||
- anatop-delay-reg-offset: Anatop MFD step time register offset
|
||||
- anatop-delay-bit-shift: Bit shift for the step time register
|
||||
- anatop-delay-bit-width: Number of bits used in the step time register
|
||||
|
||||
Any property defined as part of the core regulator
|
||||
binding, defined in regulator.txt, can also be used.
|
||||
|
||||
@@ -23,6 +28,9 @@ Example:
|
||||
anatop-reg-offset = <0x140>;
|
||||
anatop-vol-bit-shift = <9>;
|
||||
anatop-vol-bit-width = <5>;
|
||||
anatop-delay-reg-offset = <0x170>;
|
||||
anatop-delay-bit-shift = <24>;
|
||||
anatop-delay-bit-width = <2>;
|
||||
anatop-min-bit-val = <1>;
|
||||
anatop-min-voltage = <725000>;
|
||||
anatop-max-voltage = <1300000>;
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
* Samsung S5M8767 Voltage and Current Regulator
|
||||
|
||||
The Samsung S5M8767 is a multi-function device which includes volatage and
|
||||
current regulators, rtc, charger controller and other sub-blocks. It is
|
||||
interfaced to the host controller using a i2c interface. Each sub-block is
|
||||
addressed by the host system using different i2c slave address. This document
|
||||
describes the bindings for 'pmic' sub-block of s5m8767.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "samsung,s5m8767-pmic".
|
||||
- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
|
||||
|
||||
- s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
|
||||
units for buck2 when changing voltage using gpio dvs. Refer to [1] below
|
||||
for additional information.
|
||||
|
||||
- s5m8767,pmic-buck3-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
|
||||
units for buck3 when changing voltage using gpio dvs. Refer to [1] below
|
||||
for additional information.
|
||||
|
||||
- s5m8767,pmic-buck4-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
|
||||
units for buck4 when changing voltage using gpio dvs. Refer to [1] below
|
||||
for additional information.
|
||||
|
||||
- s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used
|
||||
for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines.
|
||||
|
||||
[1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
|
||||
property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage'
|
||||
property should specify atleast one voltage level (which would be a
|
||||
safe operating voltage).
|
||||
|
||||
If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
|
||||
property is specified, then all the eight voltage values for the
|
||||
's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified.
|
||||
|
||||
Optional properties:
|
||||
- interrupt-parent: Specifies the phandle of the interrupt controller to which
|
||||
the interrupts from s5m8767 are delivered to.
|
||||
- interrupts: Interrupt specifiers for two interrupt sources.
|
||||
- First interrupt specifier is for 'irq1' interrupt.
|
||||
- Second interrupt specifier is for 'alert' interrupt.
|
||||
- s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
|
||||
- s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs.
|
||||
- s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs.
|
||||
|
||||
Additional properties required if either of the optional properties are used:
|
||||
|
||||
- s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from
|
||||
the possible 8 options selectable by the dvs gpios. The value of this
|
||||
property should be between 0 and 7. If not specified or if out of range, the
|
||||
default value of this property is set to 0.
|
||||
|
||||
- s5m8767,pmic-buck-dvs-gpios: GPIO specifiers for three host gpio's used
|
||||
for dvs. The format of the gpio specifier depends in the gpio controller.
|
||||
|
||||
Regulators: The regulators of s5m8767 that have to be instantiated should be
|
||||
included in a sub-node named 'regulators'. Regulator nodes included in this
|
||||
sub-node should be of the format as listed below.
|
||||
|
||||
regulator_name {
|
||||
ldo1_reg: LDO1 {
|
||||
regulator-name = "VDD_ALIVE_1.0V";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
op_mode = <1>; /* Normal Mode */
|
||||
};
|
||||
};
|
||||
The above regulator entries are defined in regulator bindings documentation
|
||||
except op_mode description.
|
||||
- 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
|
||||
|
||||
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
|
||||
as per the datasheet of s5m8767.
|
||||
|
||||
- LDOn
|
||||
- valid values for n are 1 to 28
|
||||
- Example: LDO0, LD01, LDO28
|
||||
- BUCKn
|
||||
- valid values for n are 1 to 9.
|
||||
- Example: BUCK1, BUCK2, BUCK9
|
||||
|
||||
The bindings inside the regulator nodes use the standard regulator bindings
|
||||
which are documented elsewhere.
|
||||
|
||||
Example:
|
||||
|
||||
s5m8767_pmic@66 {
|
||||
compatible = "samsung,s5m8767-pmic";
|
||||
reg = <0x66>;
|
||||
|
||||
s5m8767,pmic-buck2-uses-gpio-dvs;
|
||||
s5m8767,pmic-buck3-uses-gpio-dvs;
|
||||
s5m8767,pmic-buck4-uses-gpio-dvs;
|
||||
|
||||
s5m8767,pmic-buck-default-dvs-idx = <0>;
|
||||
|
||||
s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 1 0 0>, /* DVS1 */
|
||||
<&gpx0 1 1 0 0>, /* DVS2 */
|
||||
<&gpx0 2 1 0 0>; /* DVS3 */
|
||||
|
||||
s5m8767,pmic-buck-ds-gpios = <&gpx2 3 1 0 0>, /* SET1 */
|
||||
<&gpx2 4 1 0 0>, /* SET2 */
|
||||
<&gpx2 5 1 0 0>; /* SET3 */
|
||||
|
||||
s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>,
|
||||
<1250000>, <1200000>,
|
||||
<1150000>, <1100000>,
|
||||
<1000000>, <950000>;
|
||||
|
||||
s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
|
||||
<1100000>, <1100000>,
|
||||
<1000000>, <1000000>,
|
||||
<1000000>, <1000000>;
|
||||
|
||||
s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
|
||||
<1200000>, <1200000>,
|
||||
<1200000>, <1200000>,
|
||||
<1200000>, <1200000>;
|
||||
|
||||
regulators {
|
||||
ldo1_reg: LDO1 {
|
||||
regulator-name = "VDD_ABB_3.3V";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
op_mode = <1>; /* Normal Mode */
|
||||
};
|
||||
|
||||
ldo2_reg: LDO2 {
|
||||
regulator-name = "VDD_ALIVE_1.1V";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
buck1_reg: BUCK1 {
|
||||
regulator-name = "VDD_MIF_1.2V";
|
||||
regulator-min-microvolt = <950000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
TPS51632 Voltage regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "ti,tps51632"
|
||||
- reg: I2C slave address
|
||||
|
||||
Optional properties:
|
||||
- ti,enable-pwm-dvfs: Enable the DVFS voltage control through the PWM interface.
|
||||
- ti,dvfs-step-20mV: The 20mV step voltage when PWM DVFS enabled. Missing this
|
||||
will set 10mV step voltage in PWM DVFS mode. In normal mode, the voltage
|
||||
step is 10mV as per datasheet.
|
||||
|
||||
Any property defined as part of the core regulator binding, defined in
|
||||
regulator.txt, can also be used.
|
||||
|
||||
Example:
|
||||
|
||||
tps51632 {
|
||||
compatible = "ti,tps51632";
|
||||
reg = <0x43>;
|
||||
regulator-name = "tps51632-vout";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-boot-on;
|
||||
ti,enable-pwm-dvfs;
|
||||
ti,dvfs-step-20mV;
|
||||
};
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/mutex.h>
|
||||
@@ -60,6 +61,15 @@ static struct mfd_cell s2mps11_devs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_device_id sec_dt_match[] = {
|
||||
{ .compatible = "samsung,s5m8767-pmic",
|
||||
.data = (void *)S5M8767X,
|
||||
},
|
||||
{},
|
||||
};
|
||||
#endif
|
||||
|
||||
int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest)
|
||||
{
|
||||
return regmap_read(sec_pmic->regmap, reg, dest);
|
||||
@@ -95,6 +105,57 @@ static struct regmap_config sec_regmap_config = {
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/*
|
||||
* Only the common platform data elements for s5m8767 are parsed here from the
|
||||
* device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
|
||||
* others have to parse their own platform data elements from device tree.
|
||||
*
|
||||
* The s5m8767 platform data structure is instantiated here and the drivers for
|
||||
* the sub-modules need not instantiate another instance while parsing their
|
||||
* platform data.
|
||||
*/
|
||||
static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
|
||||
struct device *dev)
|
||||
{
|
||||
struct sec_platform_data *pd;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd) {
|
||||
dev_err(dev, "could not allocate memory for pdata\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* ToDo: the 'wakeup' member in the platform data is more of a linux
|
||||
* specfic information. Hence, there is no binding for that yet and
|
||||
* not parsed here.
|
||||
*/
|
||||
|
||||
return pd;
|
||||
}
|
||||
#else
|
||||
static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
|
||||
struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int sec_i2c_get_driver_data(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
#ifdef CONFIG_OF
|
||||
if (i2c->dev.of_node) {
|
||||
const struct of_device_id *match;
|
||||
match = of_match_node(sec_dt_match, i2c->dev.of_node);
|
||||
return (int)match->data;
|
||||
}
|
||||
#endif
|
||||
return (int)id->driver_data;
|
||||
}
|
||||
|
||||
static int sec_pmic_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
@@ -111,13 +172,22 @@ static int sec_pmic_probe(struct i2c_client *i2c,
|
||||
sec_pmic->dev = &i2c->dev;
|
||||
sec_pmic->i2c = i2c;
|
||||
sec_pmic->irq = i2c->irq;
|
||||
sec_pmic->type = id->driver_data;
|
||||
sec_pmic->type = sec_i2c_get_driver_data(i2c, id);
|
||||
|
||||
if (sec_pmic->dev->of_node) {
|
||||
pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
|
||||
if (IS_ERR(pdata)) {
|
||||
ret = PTR_ERR(pdata);
|
||||
return ret;
|
||||
}
|
||||
pdata->device_type = sec_pmic->type;
|
||||
}
|
||||
if (pdata) {
|
||||
sec_pmic->device_type = pdata->device_type;
|
||||
sec_pmic->ono = pdata->ono;
|
||||
sec_pmic->irq_base = pdata->irq_base;
|
||||
sec_pmic->wakeup = pdata->wakeup;
|
||||
sec_pmic->pdata = pdata;
|
||||
}
|
||||
|
||||
sec_pmic->regmap = devm_regmap_init_i2c(i2c, &sec_regmap_config);
|
||||
@@ -192,6 +262,7 @@ static struct i2c_driver sec_pmic_driver = {
|
||||
.driver = {
|
||||
.name = "sec_pmic",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(sec_dt_match),
|
||||
},
|
||||
.probe = sec_pmic_probe,
|
||||
.remove = sec_pmic_remove,
|
||||
|
||||
@@ -30,8 +30,6 @@ struct pm8607_regulator_info {
|
||||
unsigned int *vol_table;
|
||||
unsigned int *vol_suspend;
|
||||
|
||||
int update_reg;
|
||||
int update_bit;
|
||||
int slope_double;
|
||||
};
|
||||
|
||||
@@ -222,29 +220,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
uint8_t val;
|
||||
int ret;
|
||||
|
||||
val = (uint8_t)(selector << (ffs(rdev->desc->vsel_mask) - 1));
|
||||
|
||||
ret = pm860x_set_bits(info->i2c, rdev->desc->vsel_reg,
|
||||
rdev->desc->vsel_mask, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
switch (info->desc.id) {
|
||||
case PM8607_ID_BUCK1:
|
||||
case PM8607_ID_BUCK3:
|
||||
ret = pm860x_set_bits(info->i2c, info->update_reg,
|
||||
1 << info->update_bit,
|
||||
1 << info->update_bit);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pm8606_preg_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
@@ -276,7 +251,7 @@ static int pm8606_preg_is_enabled(struct regulator_dev *rdev)
|
||||
|
||||
static struct regulator_ops pm8607_regulator_ops = {
|
||||
.list_voltage = pm8607_list_voltage,
|
||||
.set_voltage_sel = pm8607_set_voltage_sel,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@@ -313,11 +288,11 @@ static struct regulator_ops pm8606_preg_ops = {
|
||||
.n_voltages = ARRAY_SIZE(vreg##_table), \
|
||||
.vsel_reg = PM8607_##vreg, \
|
||||
.vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \
|
||||
.apply_reg = PM8607_##ureg, \
|
||||
.apply_bit = (ubit), \
|
||||
.enable_reg = PM8607_##ereg, \
|
||||
.enable_mask = 1 << (ebit), \
|
||||
}, \
|
||||
.update_reg = PM8607_##ureg, \
|
||||
.update_bit = (ubit), \
|
||||
.slope_double = (0), \
|
||||
.vol_table = (unsigned int *)&vreg##_table, \
|
||||
.vol_suspend = (unsigned int *)&vreg##_suspend_table, \
|
||||
@@ -343,9 +318,9 @@ static struct regulator_ops pm8606_preg_ops = {
|
||||
}
|
||||
|
||||
static struct pm8607_regulator_info pm8607_regulator_info[] = {
|
||||
PM8607_DVC(BUCK1, GO, 0, SUPPLIES_EN11, 0),
|
||||
PM8607_DVC(BUCK2, GO, 1, SUPPLIES_EN11, 1),
|
||||
PM8607_DVC(BUCK3, GO, 2, SUPPLIES_EN11, 2),
|
||||
PM8607_DVC(BUCK1, GO, BIT(0), SUPPLIES_EN11, 0),
|
||||
PM8607_DVC(BUCK2, GO, BIT(1), SUPPLIES_EN11, 1),
|
||||
PM8607_DVC(BUCK3, GO, BIT(2), SUPPLIES_EN11, 2),
|
||||
|
||||
PM8607_LDO(1, LDO1, 0, SUPPLIES_EN11, 3),
|
||||
PM8607_LDO(2, LDO2, 0, SUPPLIES_EN11, 4),
|
||||
@@ -372,7 +347,7 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
struct device_node *nproot, *np;
|
||||
nproot = pdev->dev.parent->of_node;
|
||||
nproot = of_node_get(pdev->dev.parent->of_node);
|
||||
if (!nproot)
|
||||
return -ENODEV;
|
||||
nproot = of_find_node_by_name(nproot, "regulators");
|
||||
@@ -388,6 +363,7 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev,
|
||||
break;
|
||||
}
|
||||
}
|
||||
of_node_put(nproot);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -91,6 +91,7 @@ config REGULATOR_AAT2870
|
||||
config REGULATOR_ARIZONA
|
||||
tristate "Wolfson Arizona class devices"
|
||||
depends on MFD_ARIZONA
|
||||
depends on SND_SOC
|
||||
help
|
||||
Support for the regulators found on Wolfson Arizona class
|
||||
devices.
|
||||
@@ -277,6 +278,15 @@ config REGULATOR_LP872X
|
||||
help
|
||||
This driver supports LP8720/LP8725 PMIC
|
||||
|
||||
config REGULATOR_LP8755
|
||||
tristate "TI LP8755 High Performance PMU driver"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports LP8755 High Performance PMU driver. This
|
||||
chip contains six step-down DC/DC converters which can support
|
||||
9 mode multiphase configuration.
|
||||
|
||||
config REGULATOR_LP8788
|
||||
bool "TI LP8788 Power Regulators"
|
||||
depends on MFD_LP8788
|
||||
|
||||
@@ -30,6 +30,7 @@ obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
|
||||
obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o
|
||||
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o
|
||||
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
|
||||
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
|
||||
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
|
||||
|
||||
@@ -31,12 +31,18 @@
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
#define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */
|
||||
#define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
|
||||
|
||||
struct anatop_regulator {
|
||||
const char *name;
|
||||
u32 control_reg;
|
||||
struct regmap *anatop;
|
||||
int vol_bit_shift;
|
||||
int vol_bit_width;
|
||||
u32 delay_reg;
|
||||
int delay_bit_shift;
|
||||
int delay_bit_width;
|
||||
int min_bit_val;
|
||||
int min_voltage;
|
||||
int max_voltage;
|
||||
@@ -55,6 +61,32 @@ static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg,
|
||||
return regulator_set_voltage_sel_regmap(reg, selector);
|
||||
}
|
||||
|
||||
static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg,
|
||||
unsigned int old_sel,
|
||||
unsigned int new_sel)
|
||||
{
|
||||
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
|
||||
/* check whether need to care about LDO ramp up speed */
|
||||
if (anatop_reg->delay_bit_width && new_sel > old_sel) {
|
||||
/*
|
||||
* the delay for LDO ramp up time is
|
||||
* based on the register setting, we need
|
||||
* to calculate how many steps LDO need to
|
||||
* ramp up, and how much delay needed. (us)
|
||||
*/
|
||||
regmap_read(anatop_reg->anatop, anatop_reg->delay_reg, &val);
|
||||
val = (val >> anatop_reg->delay_bit_shift) &
|
||||
((1 << anatop_reg->delay_bit_width) - 1);
|
||||
ret = (new_sel - old_sel) * (LDO_RAMP_UP_UNIT_IN_CYCLES <<
|
||||
val) / LDO_RAMP_UP_FREQ_IN_MHZ + 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
|
||||
{
|
||||
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
||||
@@ -67,6 +99,7 @@ static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
|
||||
|
||||
static struct regulator_ops anatop_rops = {
|
||||
.set_voltage_sel = anatop_regmap_set_voltage_sel,
|
||||
.set_voltage_time_sel = anatop_regmap_set_voltage_time_sel,
|
||||
.get_voltage_sel = anatop_regmap_get_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
@@ -143,6 +176,14 @@ static int anatop_regulator_probe(struct platform_device *pdev)
|
||||
goto anatop_probe_end;
|
||||
}
|
||||
|
||||
/* read LDO ramp up setting, only for core reg */
|
||||
of_property_read_u32(np, "anatop-delay-reg-offset",
|
||||
&sreg->delay_reg);
|
||||
of_property_read_u32(np, "anatop-delay-bit-width",
|
||||
&sreg->delay_bit_width);
|
||||
of_property_read_u32(np, "anatop-delay-bit-shift",
|
||||
&sreg->delay_bit_shift);
|
||||
|
||||
rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1
|
||||
+ sreg->min_bit_val;
|
||||
rdesc->min_uV = sreg->min_voltage;
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
#include <linux/mfd/arizona/pdata.h>
|
||||
@@ -34,6 +36,8 @@ struct arizona_micsupp {
|
||||
|
||||
struct regulator_consumer_supply supply;
|
||||
struct regulator_init_data init_data;
|
||||
|
||||
struct work_struct check_cp_work;
|
||||
};
|
||||
|
||||
static int arizona_micsupp_list_voltage(struct regulator_dev *rdev,
|
||||
@@ -72,9 +76,73 @@ static int arizona_micsupp_map_voltage(struct regulator_dev *rdev,
|
||||
return selector;
|
||||
}
|
||||
|
||||
static void arizona_micsupp_check_cp(struct work_struct *work)
|
||||
{
|
||||
struct arizona_micsupp *micsupp =
|
||||
container_of(work, struct arizona_micsupp, check_cp_work);
|
||||
struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm;
|
||||
struct arizona *arizona = micsupp->arizona;
|
||||
struct regmap *regmap = arizona->regmap;
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, ®);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to read CP state: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dapm) {
|
||||
if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
|
||||
ARIZONA_CPMIC_ENA)
|
||||
snd_soc_dapm_force_enable_pin(dapm, "MICSUPP");
|
||||
else
|
||||
snd_soc_dapm_disable_pin(dapm, "MICSUPP");
|
||||
|
||||
snd_soc_dapm_sync(dapm);
|
||||
}
|
||||
}
|
||||
|
||||
static int arizona_micsupp_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct arizona_micsupp *micsupp = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_enable_regmap(rdev);
|
||||
|
||||
if (ret == 0)
|
||||
schedule_work(&micsupp->check_cp_work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arizona_micsupp_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct arizona_micsupp *micsupp = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_disable_regmap(rdev);
|
||||
if (ret == 0)
|
||||
schedule_work(&micsupp->check_cp_work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arizona_micsupp_set_bypass(struct regulator_dev *rdev, bool ena)
|
||||
{
|
||||
struct arizona_micsupp *micsupp = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_set_bypass_regmap(rdev, ena);
|
||||
if (ret == 0)
|
||||
schedule_work(&micsupp->check_cp_work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct regulator_ops arizona_micsupp_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable = arizona_micsupp_enable,
|
||||
.disable = arizona_micsupp_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
|
||||
.list_voltage = arizona_micsupp_list_voltage,
|
||||
@@ -84,7 +152,7 @@ static struct regulator_ops arizona_micsupp_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
.set_bypass = arizona_micsupp_set_bypass,
|
||||
};
|
||||
|
||||
static const struct regulator_desc arizona_micsupp = {
|
||||
@@ -109,7 +177,8 @@ static const struct regulator_desc arizona_micsupp = {
|
||||
static const struct regulator_init_data arizona_micsupp_default = {
|
||||
.constraints = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS |
|
||||
REGULATOR_CHANGE_VOLTAGE,
|
||||
REGULATOR_CHANGE_VOLTAGE |
|
||||
REGULATOR_CHANGE_BYPASS,
|
||||
.min_uV = 1700000,
|
||||
.max_uV = 3300000,
|
||||
},
|
||||
@@ -131,6 +200,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
micsupp->arizona = arizona;
|
||||
INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
|
||||
|
||||
/*
|
||||
* Since the chip usually supplies itself we provide some
|
||||
|
||||
@@ -303,7 +303,7 @@ static int as3711_regulator_probe(struct platform_device *pdev)
|
||||
reg_data = pdata ? pdata->init_data[id] : NULL;
|
||||
|
||||
/* No need to register if there is no regulator data */
|
||||
if (!ri->desc.name)
|
||||
if (!reg_data)
|
||||
continue;
|
||||
|
||||
reg = ®s[id];
|
||||
|
||||
@@ -200,8 +200,8 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
if (*min_uV > *max_uV) {
|
||||
dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n",
|
||||
regulator->min_uV, regulator->max_uV);
|
||||
rdev_err(rdev, "Restricting voltage, %u-%uuV\n",
|
||||
*min_uV, *max_uV);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2080,10 +2080,20 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
|
||||
*/
|
||||
int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sel <<= ffs(rdev->desc->vsel_mask) - 1;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
|
||||
ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
|
||||
rdev->desc->vsel_mask, sel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rdev->desc->apply_bit)
|
||||
ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
|
||||
rdev->desc->apply_bit,
|
||||
rdev->desc->apply_bit);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
|
||||
|
||||
@@ -2229,8 +2239,11 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
||||
best_val = rdev->desc->ops->list_voltage(rdev, ret);
|
||||
if (min_uV <= best_val && max_uV >= best_val) {
|
||||
selector = ret;
|
||||
ret = rdev->desc->ops->set_voltage_sel(rdev,
|
||||
ret);
|
||||
if (old_selector == selector)
|
||||
ret = 0;
|
||||
else
|
||||
ret = rdev->desc->ops->set_voltage_sel(
|
||||
rdev, ret);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -2241,7 +2254,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
||||
|
||||
/* Call set_voltage_time_sel if successfully obtained old_selector */
|
||||
if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 &&
|
||||
rdev->desc->ops->set_voltage_time_sel) {
|
||||
old_selector != selector && rdev->desc->ops->set_voltage_time_sel) {
|
||||
|
||||
delay = rdev->desc->ops->set_voltage_time_sel(rdev,
|
||||
old_selector, selector);
|
||||
@@ -2294,6 +2307,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
|
||||
{
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret = 0;
|
||||
int old_min_uV, old_max_uV;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
|
||||
@@ -2315,18 +2329,29 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
|
||||
ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* restore original values in case of error */
|
||||
old_min_uV = regulator->min_uV;
|
||||
old_max_uV = regulator->max_uV;
|
||||
regulator->min_uV = min_uV;
|
||||
regulator->max_uV = max_uV;
|
||||
|
||||
ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
goto out2;
|
||||
|
||||
ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
|
||||
|
||||
if (ret < 0)
|
||||
goto out2;
|
||||
|
||||
out:
|
||||
mutex_unlock(&rdev->mutex);
|
||||
return ret;
|
||||
out2:
|
||||
regulator->min_uV = old_min_uV;
|
||||
regulator->max_uV = old_max_uV;
|
||||
mutex_unlock(&rdev->mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_voltage);
|
||||
|
||||
@@ -3208,7 +3233,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
if (ops->is_enabled) {
|
||||
if (rdev->ena_gpio || ops->is_enabled) {
|
||||
status = device_create_file(dev, &dev_attr_state);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
@@ -70,7 +70,6 @@ struct da9052_regulator_info {
|
||||
int step_uV;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
unsigned char activate_bit;
|
||||
};
|
||||
|
||||
struct da9052_regulator {
|
||||
@@ -210,36 +209,6 @@ static int da9052_map_voltage(struct regulator_dev *rdev,
|
||||
return sel;
|
||||
}
|
||||
|
||||
static int da9052_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9052_regulator_info *info = regulator->info;
|
||||
int id = rdev_get_id(rdev);
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_update(regulator->da9052, rdev->desc->vsel_reg,
|
||||
rdev->desc->vsel_mask, selector);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Some LDOs and DCDCs are DVC controlled which requires enabling of
|
||||
* the activate bit to implment the changes on the output.
|
||||
*/
|
||||
switch (id) {
|
||||
case DA9052_ID_BUCK1:
|
||||
case DA9052_ID_BUCK2:
|
||||
case DA9052_ID_BUCK3:
|
||||
case DA9052_ID_LDO2:
|
||||
case DA9052_ID_LDO3:
|
||||
ret = da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
|
||||
info->activate_bit, info->activate_bit);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct regulator_ops da9052_dcdc_ops = {
|
||||
.get_current_limit = da9052_dcdc_get_current_limit,
|
||||
.set_current_limit = da9052_dcdc_set_current_limit,
|
||||
@@ -247,7 +216,7 @@ static struct regulator_ops da9052_dcdc_ops = {
|
||||
.list_voltage = da9052_list_voltage,
|
||||
.map_voltage = da9052_map_voltage,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = da9052_regulator_set_voltage_sel,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@@ -257,7 +226,7 @@ static struct regulator_ops da9052_ldo_ops = {
|
||||
.list_voltage = da9052_list_voltage,
|
||||
.map_voltage = da9052_map_voltage,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = da9052_regulator_set_voltage_sel,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@@ -274,13 +243,14 @@ static struct regulator_ops da9052_ldo_ops = {
|
||||
.owner = THIS_MODULE,\
|
||||
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.vsel_mask = (1 << (sbits)) - 1,\
|
||||
.apply_reg = DA9052_SUPPLY_REG, \
|
||||
.apply_bit = (abits), \
|
||||
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.enable_mask = 1 << (ebits),\
|
||||
},\
|
||||
.min_uV = (min) * 1000,\
|
||||
.max_uV = (max) * 1000,\
|
||||
.step_uV = (step) * 1000,\
|
||||
.activate_bit = (abits),\
|
||||
}
|
||||
|
||||
#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
|
||||
@@ -294,13 +264,14 @@ static struct regulator_ops da9052_ldo_ops = {
|
||||
.owner = THIS_MODULE,\
|
||||
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.vsel_mask = (1 << (sbits)) - 1,\
|
||||
.apply_reg = DA9052_SUPPLY_REG, \
|
||||
.apply_bit = (abits), \
|
||||
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
|
||||
.enable_mask = 1 << (ebits),\
|
||||
},\
|
||||
.min_uV = (min) * 1000,\
|
||||
.max_uV = (max) * 1000,\
|
||||
.step_uV = (step) * 1000,\
|
||||
.activate_bit = (abits),\
|
||||
}
|
||||
|
||||
static struct da9052_regulator_info da9052_regulator_info[] = {
|
||||
@@ -395,9 +366,9 @@ static int da9052_regulator_probe(struct platform_device *pdev)
|
||||
config.init_data = pdata->regulators[pdev->id];
|
||||
} else {
|
||||
#ifdef CONFIG_OF
|
||||
struct device_node *nproot = da9052->dev->of_node;
|
||||
struct device_node *np;
|
||||
struct device_node *nproot, *np;
|
||||
|
||||
nproot = of_node_get(da9052->dev->of_node);
|
||||
if (!nproot)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -414,6 +385,7 @@ static int da9052_regulator_probe(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
of_node_put(nproot);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ struct da9055_volt_reg {
|
||||
int reg_b;
|
||||
int sl_shift;
|
||||
int v_mask;
|
||||
int v_shift;
|
||||
};
|
||||
|
||||
struct da9055_mode_reg {
|
||||
@@ -388,7 +387,6 @@ static struct regulator_ops da9055_ldo_ops = {
|
||||
.reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
|
||||
.sl_shift = 7,\
|
||||
.v_mask = (1 << (vbits)) - 1,\
|
||||
.v_shift = (vbits),\
|
||||
},\
|
||||
}
|
||||
|
||||
@@ -417,7 +415,6 @@ static struct regulator_ops da9055_ldo_ops = {
|
||||
.reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
|
||||
.sl_shift = 7,\
|
||||
.v_mask = (1 << (vbits)) - 1,\
|
||||
.v_shift = (vbits),\
|
||||
},\
|
||||
.mode = {\
|
||||
.reg = DA9055_REG_BCORE_MODE,\
|
||||
|
||||
@@ -132,7 +132,7 @@ static struct regulator_ops gpio_regulator_voltage_ops = {
|
||||
.list_voltage = gpio_regulator_list_voltage,
|
||||
};
|
||||
|
||||
struct gpio_regulator_config *
|
||||
static struct gpio_regulator_config *
|
||||
of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
|
||||
{
|
||||
struct gpio_regulator_config *config;
|
||||
@@ -163,10 +163,7 @@ 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. */
|
||||
for (i = 0; ; i++)
|
||||
if (of_get_named_gpio(np, "gpios", i) < 0)
|
||||
break;
|
||||
config->nr_gpios = i;
|
||||
config->nr_gpios = of_gpio_count(np);
|
||||
|
||||
config->gpios = devm_kzalloc(dev,
|
||||
sizeof(struct gpio) * config->nr_gpios,
|
||||
|
||||
@@ -73,8 +73,6 @@ static const unsigned int buck_voltage_map[] = {
|
||||
};
|
||||
|
||||
#define BUCK_TARGET_VOL_MASK 0x3f
|
||||
#define BUCK_TARGET_VOL_MIN_IDX 0x01
|
||||
#define BUCK_TARGET_VOL_MAX_IDX 0x19
|
||||
|
||||
#define LP3971_BUCK_RAMP_REG(x) (buck_base_addr[x]+2)
|
||||
|
||||
@@ -140,7 +138,7 @@ static int lp3971_ldo_disable(struct regulator_dev *dev)
|
||||
return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
|
||||
}
|
||||
|
||||
static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
|
||||
static int lp3971_ldo_get_voltage_sel(struct regulator_dev *dev)
|
||||
{
|
||||
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
|
||||
int ldo = rdev_get_id(dev) - LP3971_LDO1;
|
||||
@@ -149,7 +147,7 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
|
||||
reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
|
||||
val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
|
||||
|
||||
return dev->desc->volt_table[val];
|
||||
return val;
|
||||
}
|
||||
|
||||
static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
@@ -168,7 +166,7 @@ static struct regulator_ops lp3971_ldo_ops = {
|
||||
.is_enabled = lp3971_ldo_is_enabled,
|
||||
.enable = lp3971_ldo_enable,
|
||||
.disable = lp3971_ldo_disable,
|
||||
.get_voltage = lp3971_ldo_get_voltage,
|
||||
.get_voltage_sel = lp3971_ldo_get_voltage_sel,
|
||||
.set_voltage_sel = lp3971_ldo_set_voltage_sel,
|
||||
};
|
||||
|
||||
@@ -201,24 +199,16 @@ static int lp3971_dcdc_disable(struct regulator_dev *dev)
|
||||
return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
|
||||
}
|
||||
|
||||
static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
|
||||
static int lp3971_dcdc_get_voltage_sel(struct regulator_dev *dev)
|
||||
{
|
||||
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
|
||||
int buck = rdev_get_id(dev) - LP3971_DCDC1;
|
||||
u16 reg;
|
||||
int val;
|
||||
|
||||
reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
|
||||
reg &= BUCK_TARGET_VOL_MASK;
|
||||
|
||||
if (reg <= BUCK_TARGET_VOL_MAX_IDX)
|
||||
val = buck_voltage_map[reg];
|
||||
else {
|
||||
val = 0;
|
||||
dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
|
||||
}
|
||||
|
||||
return val;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
@@ -249,7 +239,7 @@ static struct regulator_ops lp3971_dcdc_ops = {
|
||||
.is_enabled = lp3971_dcdc_is_enabled,
|
||||
.enable = lp3971_dcdc_enable,
|
||||
.disable = lp3971_dcdc_disable,
|
||||
.get_voltage = lp3971_dcdc_get_voltage,
|
||||
.get_voltage_sel = lp3971_dcdc_get_voltage_sel,
|
||||
.set_voltage_sel = lp3971_dcdc_set_voltage_sel,
|
||||
};
|
||||
|
||||
|
||||
@@ -165,8 +165,6 @@ static const int buck_base_addr[] = {
|
||||
#define LP3972_BUCK_VOL_ENABLE_REG(x) (buck_vol_enable_addr[x])
|
||||
#define LP3972_BUCK_VOL1_REG(x) (buck_base_addr[x])
|
||||
#define LP3972_BUCK_VOL_MASK 0x1f
|
||||
#define LP3972_BUCK_VOL_MIN_IDX(x) ((x) ? 0x01 : 0x00)
|
||||
#define LP3972_BUCK_VOL_MAX_IDX(x) ((x) ? 0x19 : 0x1f)
|
||||
|
||||
static int lp3972_i2c_read(struct i2c_client *i2c, char reg, int count,
|
||||
u16 *dest)
|
||||
@@ -257,7 +255,7 @@ static int lp3972_ldo_disable(struct regulator_dev *dev)
|
||||
mask, 0);
|
||||
}
|
||||
|
||||
static int lp3972_ldo_get_voltage(struct regulator_dev *dev)
|
||||
static int lp3972_ldo_get_voltage_sel(struct regulator_dev *dev)
|
||||
{
|
||||
struct lp3972 *lp3972 = rdev_get_drvdata(dev);
|
||||
int ldo = rdev_get_id(dev) - LP3972_LDO1;
|
||||
@@ -267,7 +265,7 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev)
|
||||
reg = lp3972_reg_read(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo));
|
||||
val = (reg >> LP3972_LDO_VOL_CONTR_SHIFT(ldo)) & mask;
|
||||
|
||||
return dev->desc->volt_table[val];
|
||||
return val;
|
||||
}
|
||||
|
||||
static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
@@ -314,7 +312,7 @@ static struct regulator_ops lp3972_ldo_ops = {
|
||||
.is_enabled = lp3972_ldo_is_enabled,
|
||||
.enable = lp3972_ldo_enable,
|
||||
.disable = lp3972_ldo_disable,
|
||||
.get_voltage = lp3972_ldo_get_voltage,
|
||||
.get_voltage_sel = lp3972_ldo_get_voltage_sel,
|
||||
.set_voltage_sel = lp3972_ldo_set_voltage_sel,
|
||||
};
|
||||
|
||||
@@ -353,24 +351,16 @@ static int lp3972_dcdc_disable(struct regulator_dev *dev)
|
||||
return val;
|
||||
}
|
||||
|
||||
static int lp3972_dcdc_get_voltage(struct regulator_dev *dev)
|
||||
static int lp3972_dcdc_get_voltage_sel(struct regulator_dev *dev)
|
||||
{
|
||||
struct lp3972 *lp3972 = rdev_get_drvdata(dev);
|
||||
int buck = rdev_get_id(dev) - LP3972_DCDC1;
|
||||
u16 reg;
|
||||
int val;
|
||||
|
||||
reg = lp3972_reg_read(lp3972, LP3972_BUCK_VOL1_REG(buck));
|
||||
reg &= LP3972_BUCK_VOL_MASK;
|
||||
if (reg <= LP3972_BUCK_VOL_MAX_IDX(buck))
|
||||
val = dev->desc->volt_table[reg];
|
||||
else {
|
||||
val = 0;
|
||||
dev_warn(&dev->dev, "chip reported incorrect voltage value."
|
||||
" reg = %d\n", reg);
|
||||
}
|
||||
|
||||
return val;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
@@ -402,7 +392,7 @@ static struct regulator_ops lp3972_dcdc_ops = {
|
||||
.is_enabled = lp3972_dcdc_is_enabled,
|
||||
.enable = lp3972_dcdc_enable,
|
||||
.disable = lp3972_dcdc_disable,
|
||||
.get_voltage = lp3972_dcdc_get_voltage,
|
||||
.get_voltage_sel = lp3972_dcdc_get_voltage_sel,
|
||||
.set_voltage_sel = lp3972_dcdc_set_voltage_sel,
|
||||
};
|
||||
|
||||
|
||||
@@ -181,20 +181,6 @@ static inline int lp872x_update_bits(struct lp872x *lp, u8 addr,
|
||||
return regmap_update_bits(lp->regmap, addr, mask, data);
|
||||
}
|
||||
|
||||
static int _rdev_to_offset(struct regulator_dev *rdev)
|
||||
{
|
||||
enum lp872x_regulator_id id = rdev_get_id(rdev);
|
||||
|
||||
switch (id) {
|
||||
case LP8720_ID_LDO1 ... LP8720_ID_BUCK:
|
||||
return id;
|
||||
case LP8725_ID_LDO1 ... LP8725_ID_BUCK2:
|
||||
return id - LP8725_ID_BASE;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int lp872x_get_timestep_usec(struct lp872x *lp)
|
||||
{
|
||||
enum lp872x_id chip = lp->chipid;
|
||||
@@ -234,28 +220,20 @@ static int lp872x_get_timestep_usec(struct lp872x *lp)
|
||||
static int lp872x_regulator_enable_time(struct regulator_dev *rdev)
|
||||
{
|
||||
struct lp872x *lp = rdev_get_drvdata(rdev);
|
||||
enum lp872x_regulator_id regulator = rdev_get_id(rdev);
|
||||
enum lp872x_regulator_id rid = rdev_get_id(rdev);
|
||||
int time_step_us = lp872x_get_timestep_usec(lp);
|
||||
int ret, offset;
|
||||
int ret;
|
||||
u8 addr, val;
|
||||
|
||||
if (time_step_us < 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (regulator) {
|
||||
case LP8720_ID_LDO1 ... LP8720_ID_LDO5:
|
||||
case LP8725_ID_LDO1 ... LP8725_ID_LILO2:
|
||||
offset = _rdev_to_offset(rdev);
|
||||
if (offset < 0)
|
||||
return -EINVAL;
|
||||
|
||||
addr = LP872X_LDO1_VOUT + offset;
|
||||
switch (rid) {
|
||||
case LP8720_ID_LDO1 ... LP8720_ID_BUCK:
|
||||
addr = LP872X_LDO1_VOUT + rid;
|
||||
break;
|
||||
case LP8720_ID_BUCK:
|
||||
addr = LP8720_BUCK_VOUT1;
|
||||
break;
|
||||
case LP8725_ID_BUCK1:
|
||||
addr = LP8725_BUCK1_VOUT1;
|
||||
case LP8725_ID_LDO1 ... LP8725_ID_BUCK1:
|
||||
addr = LP872X_LDO1_VOUT + rid - LP8725_ID_BASE;
|
||||
break;
|
||||
case LP8725_ID_BUCK2:
|
||||
addr = LP8725_BUCK2_VOUT1;
|
||||
|
||||
566
drivers/regulator/lp8755.c
Normal file
566
drivers/regulator/lp8755.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -103,16 +103,6 @@ static const int lp8788_buck_vtbl[] = {
|
||||
1950000, 2000000,
|
||||
};
|
||||
|
||||
static const u8 buck1_vout_addr[] = {
|
||||
LP8788_BUCK1_VOUT0, LP8788_BUCK1_VOUT1,
|
||||
LP8788_BUCK1_VOUT2, LP8788_BUCK1_VOUT3,
|
||||
};
|
||||
|
||||
static const u8 buck2_vout_addr[] = {
|
||||
LP8788_BUCK2_VOUT0, LP8788_BUCK2_VOUT1,
|
||||
LP8788_BUCK2_VOUT2, LP8788_BUCK2_VOUT3,
|
||||
};
|
||||
|
||||
static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
|
||||
{
|
||||
struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs;
|
||||
@@ -235,7 +225,7 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
|
||||
lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
|
||||
idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
|
||||
}
|
||||
addr = buck1_vout_addr[idx];
|
||||
addr = LP8788_BUCK1_VOUT0 + idx;
|
||||
break;
|
||||
case BUCK2:
|
||||
if (mode == EXTPIN) {
|
||||
@@ -258,7 +248,7 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
|
||||
lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
|
||||
idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S;
|
||||
}
|
||||
addr = buck2_vout_addr[idx];
|
||||
addr = LP8788_BUCK2_VOUT0 + idx;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
@@ -429,7 +419,8 @@ static struct regulator_desc lp8788_buck_desc[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int lp8788_dvs_gpio_request(struct lp8788_buck *buck,
|
||||
static int lp8788_dvs_gpio_request(struct platform_device *pdev,
|
||||
struct lp8788_buck *buck,
|
||||
enum lp8788_buck_id id)
|
||||
{
|
||||
struct lp8788_platform_data *pdata = buck->lp->pdata;
|
||||
@@ -440,7 +431,7 @@ static int lp8788_dvs_gpio_request(struct lp8788_buck *buck,
|
||||
switch (id) {
|
||||
case BUCK1:
|
||||
gpio = pdata->buck1_dvs->gpio;
|
||||
ret = devm_gpio_request_one(buck->lp->dev, gpio, DVS_LOW,
|
||||
ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW,
|
||||
b1_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -448,9 +439,9 @@ static int lp8788_dvs_gpio_request(struct lp8788_buck *buck,
|
||||
buck->dvs = pdata->buck1_dvs;
|
||||
break;
|
||||
case BUCK2:
|
||||
for (i = 0 ; i < LP8788_NUM_BUCK2_DVS ; i++) {
|
||||
for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) {
|
||||
gpio = pdata->buck2_dvs->gpio[i];
|
||||
ret = devm_gpio_request_one(buck->lp->dev, gpio,
|
||||
ret = devm_gpio_request_one(&pdev->dev, gpio,
|
||||
DVS_LOW, b2_name[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -464,7 +455,8 @@ static int lp8788_dvs_gpio_request(struct lp8788_buck *buck,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
|
||||
static int lp8788_init_dvs(struct platform_device *pdev,
|
||||
struct lp8788_buck *buck, enum lp8788_buck_id id)
|
||||
{
|
||||
struct lp8788_platform_data *pdata = buck->lp->pdata;
|
||||
u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
|
||||
@@ -472,7 +464,7 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
|
||||
u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
|
||||
|
||||
/* no dvs for buck3, 4 */
|
||||
if (id == BUCK3 || id == BUCK4)
|
||||
if (id > BUCK2)
|
||||
return 0;
|
||||
|
||||
/* no dvs platform data, then dvs will be selected by I2C registers */
|
||||
@@ -483,7 +475,7 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
|
||||
(id == BUCK2 && !pdata->buck2_dvs))
|
||||
goto set_default_dvs_mode;
|
||||
|
||||
if (lp8788_dvs_gpio_request(buck, id))
|
||||
if (lp8788_dvs_gpio_request(pdev, buck, id))
|
||||
goto set_default_dvs_mode;
|
||||
|
||||
return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
|
||||
@@ -503,17 +495,20 @@ static int lp8788_buck_probe(struct platform_device *pdev)
|
||||
struct regulator_dev *rdev;
|
||||
int ret;
|
||||
|
||||
buck = devm_kzalloc(lp->dev, sizeof(struct lp8788_buck), GFP_KERNEL);
|
||||
if (id >= LP8788_NUM_BUCKS)
|
||||
return -EINVAL;
|
||||
|
||||
buck = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_buck), GFP_KERNEL);
|
||||
if (!buck)
|
||||
return -ENOMEM;
|
||||
|
||||
buck->lp = lp;
|
||||
|
||||
ret = lp8788_init_dvs(buck, id);
|
||||
ret = lp8788_init_dvs(pdev, buck, id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cfg.dev = lp->dev;
|
||||
cfg.dev = pdev->dev.parent;
|
||||
cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL;
|
||||
cfg.driver_data = buck;
|
||||
cfg.regmap = lp->regmap;
|
||||
@@ -521,7 +516,7 @@ static int lp8788_buck_probe(struct platform_device *pdev)
|
||||
rdev = regulator_register(&lp8788_buck_desc[id], &cfg);
|
||||
if (IS_ERR(rdev)) {
|
||||
ret = PTR_ERR(rdev);
|
||||
dev_err(lp->dev, "BUCK%d regulator register err = %d\n",
|
||||
dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n",
|
||||
id + 1, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user