regulator: Updates for v4.12
Quite a lot going on with the regulator API for this release, much more in the core than in the drivers for a change: - Fixes for voltage change propagation through dumb power switches. - A notification when regulators are enabled. - A new settling time property for regulators where the time taken to move to a new voltage is not related to the size of the change. - Some reorganization of the Arizona drivers in preparation for sharing the code with the next generation devices they've been integrated with. - Support for newer Freescale chips in the Anatop regulator. - A new driver for voltage controlled regulators to cope with some exciting ChromeOS hardware designs. - Support for Rohm BD9571MWV-M and TI TPS65132. -----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAlkJ72cTHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0KfMB/9zutY/L8UyJ40ZOIn4mgfUiWuzTrMP lFWlHyRtt0gz6pHlZtaslDUMpp95R/BchE3fNfvmi1VHAAL8yt+edlMniPmVLG+M 09CSr27n0Vk8uk8DIpZNzzPc/Rxp0tfa59/+e01yV69s3x/j0yoFXGxHPbco2zT/ EVSYgQf5yXgAu4qG/htLm0AEQyHvfnMiGvd2Z3xU+kE1BOv617ATmYBdvkZLOKDO f7QqVK/POkVmDDh3p+qOUYa1+su6icpe3O2bYeWc/x50gxXx+ouxdtmqLSpPoWZz ox+1S1Mv32UC5q9NMF2lz1o0SK8VNLVVTQHr9x57IbXCyIBl84e+6JES =6YOx -----END PGP SIGNATURE----- Merge tag 'regulator-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator Pull regulator updates from Mark Brown: "Quite a lot going on with the regulator API for this release, much more in the core than in the drivers for a change: - Fixes for voltage change propagation through dumb power switches. - A notification when regulators are enabled. - A new settling time property for regulators where the time taken to move to a new voltage is not related to the size of the change. - Some reorganization of the Arizona drivers in preparation for sharing the code with the next generation devices they've been integrated with. - Support for newer Freescale chips in the Anatop regulator. - A new driver for voltage controlled regulators to cope with some exciting ChromeOS hardware designs. - Support for Rohm BD9571MWV-M and TI TPS65132" * tag 'regulator-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (51 commits) regulator: Add ROHM BD9571MWV-M PMIC regulator driver regulator: arizona-ldo1: Factor out generic initialization regulator: arizona-ldo1: Make arizona_ldo1 independent of struct arizona regulator: arizona-ldo1: Move pdata into a separate structure regulator: arizona-micsupp: Factor out generic initialization regulator: arizona-micsupp: Make arizona_micsupp independent of struct arizona regulator: arizona-micsupp: Move pdata into a separate structure regulator: arizona: Split KConfig options for LDO1 and MICSUPP regulators regulator: anatop: make regulator name property required regulator: tps65023: Fix inverted core enable logic. regulator: anatop: make sure regulator name is properly defined regulator: core: Allow dummy regulators for supplies regulator: core: Only propagate voltage changes to if it can change voltages regulator: vctrl: Fix out of bounds array access for vctrl->vtable regulator: tps65132: fix platform_no_drv_owner.cocci warnings regulator: tps65132: Fix off-by-one for .max_register setting regulator: anatop: set default voltage selector for pcie regulator: tps65132: add device-tree binding regulator: tps65132: add regulator driver for TI TPS65132 regulator: anatop: remove unneeded name field of struct anatop_regulator ...
This commit is contained in:
commit
a90f0e9ebb
@ -2,6 +2,7 @@ Anatop Voltage regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "fsl,anatop-regulator"
|
||||
- regulator-name: A string used as a descriptive name for regulator outputs
|
||||
- anatop-reg-offset: Anatop MFD register offset
|
||||
- anatop-vol-bit-shift: Bit shift for the register
|
||||
- anatop-vol-bit-width: Number of bits used in the register
|
||||
|
@ -8,8 +8,8 @@ Required property:
|
||||
|
||||
Optional properties:
|
||||
LM3632 has external enable pins for two LDOs.
|
||||
- ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin.
|
||||
- ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin.
|
||||
- enable-gpios: Two GPIO specifiers for Vpos and Vneg control pins.
|
||||
The first entry is Vpos, the second is Vneg enable pin.
|
||||
|
||||
Child nodes:
|
||||
LM3631
|
||||
@ -30,5 +30,79 @@ Child nodes:
|
||||
|
||||
Examples: Please refer to ti-lmu dt-bindings [2].
|
||||
|
||||
lm3631@29 {
|
||||
compatible = "ti,lm3631";
|
||||
reg = <0x29>;
|
||||
|
||||
regulators {
|
||||
compatible = "ti,lm363x-regulator";
|
||||
|
||||
vboost {
|
||||
regulator-name = "lcd_boost";
|
||||
regulator-min-microvolt = <4500000>;
|
||||
regulator-max-microvolt = <6350000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vcont {
|
||||
regulator-name = "lcd_vcont";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
voref {
|
||||
regulator-name = "lcd_voref";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
};
|
||||
|
||||
vpos {
|
||||
regulator-name = "lcd_vpos";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vneg {
|
||||
regulator-name = "lcd_vneg";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
lm3632@11 {
|
||||
compatible = "ti,lm3632";
|
||||
reg = <0x11>;
|
||||
|
||||
regulators {
|
||||
compatible = "ti,lm363x-regulator";
|
||||
|
||||
/* GPIO1_16 for Vpos, GPIO1_28 is for Vneg */
|
||||
enable-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>,
|
||||
<&gpio1 28 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
vboost {
|
||||
regulator-name = "lcd_boost";
|
||||
regulator-min-microvolt = <4500000>;
|
||||
regulator-max-microvolt = <6400000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
vpos {
|
||||
regulator-name = "lcd_vpos";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
};
|
||||
|
||||
vneg {
|
||||
regulator-name = "lcd_vneg";
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <6000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
[1] ../regulator/regulator.txt
|
||||
[2] ../mfd/ti-lmu.txt
|
||||
|
@ -13,7 +13,7 @@ Required child node:
|
||||
--PFUZE100
|
||||
sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6
|
||||
--PFUZE200
|
||||
sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6
|
||||
sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6,coin
|
||||
--PFUZE3000
|
||||
sw1a,sw1b,sw2,sw3,swbst,vsnvs,vrefddr,vldo1,vldo2,vccsd,v33,vldo3,vldo4
|
||||
|
||||
@ -205,6 +205,12 @@ Example 2: PFUZE200
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
coin_reg: coin {
|
||||
regulator-min-microvolt = <2500000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,9 @@ 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-settling-time-us: Settling time, in microseconds, for voltage
|
||||
change if regulator have the constant time for any level voltage change.
|
||||
This is useful when regulator have exponential voltage change.
|
||||
- regulator-soft-start: Enable soft start so that voltage ramps slowly
|
||||
- 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,
|
||||
|
@ -0,0 +1,46 @@
|
||||
TPS65132 regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,tps65132"
|
||||
- reg: I2C slave address
|
||||
|
||||
Optional Subnode:
|
||||
Device supports two regulators OUTP and OUTN. A sub node within the
|
||||
device node describe the properties of these regulators. The sub-node
|
||||
names must be as follows:
|
||||
-For regulator outp, the sub node name should be "outp".
|
||||
-For regulator outn, the sub node name should be "outn".
|
||||
|
||||
-enable-gpios:(active high, output) Regulators are controlled by the input pins.
|
||||
If it is connected to GPIO through host system then provide the
|
||||
gpio number as per gpio.txt.
|
||||
-active-discharge-gpios: (active high, output) Some configurations use delay mechanisms
|
||||
on the enable pin, to keep the regulator enabled for some time after
|
||||
the enable signal goes low. This GPIO is used to actively discharge
|
||||
the delay mechanism. Requires specification of ti,active-discharge-time-us
|
||||
-ti,active-discharge-time-us: how long the active discharge gpio should be
|
||||
asserted for during active discharge, in microseconds.
|
||||
|
||||
Each regulator is defined using the standard binding for regulators.
|
||||
|
||||
Example:
|
||||
|
||||
tps65132@3e {
|
||||
compatible = "ti,tps65132";
|
||||
reg = <0x3e>;
|
||||
|
||||
outp {
|
||||
regulator-name = "outp";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
enable-gpios = <&gpio 23 0>;
|
||||
};
|
||||
|
||||
outn {
|
||||
regulator-name = "outn";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-active-discharge = <0>;
|
||||
enable-gpios = <&gpio 40 0>;
|
||||
};
|
||||
};
|
49
Documentation/devicetree/bindings/regulator/vctrl.txt
Normal file
49
Documentation/devicetree/bindings/regulator/vctrl.txt
Normal file
@ -0,0 +1,49 @@
|
||||
Bindings for Voltage controlled regulators
|
||||
==========================================
|
||||
|
||||
Required properties:
|
||||
--------------------
|
||||
- compatible : must be "vctrl-regulator".
|
||||
- regulator-min-microvolt : smallest voltage consumers may set
|
||||
- regulator-max-microvolt : largest voltage consumers may set
|
||||
- ctrl-supply : The regulator supplying the control voltage.
|
||||
- ctrl-voltage-range : an array of two integer values describing the range
|
||||
(min/max) of the control voltage. The values specify
|
||||
the control voltage needed to generate the corresponding
|
||||
regulator-min/max-microvolt output voltage.
|
||||
|
||||
Optional properties:
|
||||
--------------------
|
||||
- ovp-threshold-percent : overvoltage protection (OVP) threshold of the
|
||||
regulator in percent. Some regulators have an OVP
|
||||
circuitry which shuts down the regulator when the
|
||||
actual output voltage deviates beyond a certain
|
||||
margin from the expected value for a given control
|
||||
voltage. On larger voltage decreases this can occur
|
||||
undesiredly since the output voltage does not adjust
|
||||
inmediately to changes in the control voltage. To
|
||||
avoid this situation the vctrl driver breaks down
|
||||
larger voltage decreases into multiple steps, where
|
||||
each step is within the OVP threshold.
|
||||
- min-slew-down-rate : Describes how slowly the regulator voltage will decay
|
||||
down in the worst case (lightest expected load).
|
||||
Specified in uV / us (like main regulator ramp rate).
|
||||
This value is required when ovp-threshold-percent is
|
||||
specified.
|
||||
|
||||
Example:
|
||||
|
||||
vctrl-reg {
|
||||
compatible = "vctrl-regulator";
|
||||
regulator-name = "vctrl_reg";
|
||||
|
||||
ctrl-supply = <&ctrl_reg>;
|
||||
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
|
||||
ctrl-voltage-range = <200000 500000>;
|
||||
|
||||
min-slew-down-rate = <225>;
|
||||
ovp-threshold-percent = <16>;
|
||||
};
|
@ -13756,12 +13756,14 @@ F: drivers/mfd/cs47l24*
|
||||
F: drivers/power/supply/wm83*.c
|
||||
F: drivers/rtc/rtc-wm83*.c
|
||||
F: drivers/regulator/wm8*.c
|
||||
F: drivers/regulator/arizona*
|
||||
F: drivers/video/backlight/wm83*_bl.c
|
||||
F: drivers/watchdog/wm83*_wdt.c
|
||||
F: include/linux/mfd/arizona/
|
||||
F: include/linux/mfd/wm831x/
|
||||
F: include/linux/mfd/wm8350/
|
||||
F: include/linux/mfd/wm8400*
|
||||
F: include/linux/regulator/arizona*
|
||||
F: include/linux/wm97xx.h
|
||||
F: include/sound/wm????.h
|
||||
F: sound/soc/codecs/arizona.?
|
||||
|
@ -209,7 +209,9 @@ static const struct i2c_board_info wm1277_devs[] = {
|
||||
};
|
||||
|
||||
static struct arizona_pdata wm5102_reva_pdata = {
|
||||
.ldoena = S3C64XX_GPN(7),
|
||||
.ldo1 = {
|
||||
.ldoena = S3C64XX_GPN(7),
|
||||
},
|
||||
.gpio_base = CODEC_GPIO_BASE,
|
||||
.irq_flags = IRQF_TRIGGER_HIGH,
|
||||
.micd_pol_gpio = CODEC_GPIO_BASE + 4,
|
||||
@ -239,7 +241,9 @@ static struct spi_board_info wm5102_reva_spi_devs[] = {
|
||||
};
|
||||
|
||||
static struct arizona_pdata wm5102_pdata = {
|
||||
.ldoena = S3C64XX_GPN(7),
|
||||
.ldo1 = {
|
||||
.ldoena = S3C64XX_GPN(7),
|
||||
},
|
||||
.gpio_base = CODEC_GPIO_BASE,
|
||||
.irq_flags = IRQF_TRIGGER_HIGH,
|
||||
.micd_pol_gpio = CODEC_GPIO_BASE + 2,
|
||||
|
@ -125,12 +125,20 @@ config REGULATOR_AB8500
|
||||
This driver supports the regulators found on the ST-Ericsson mixed
|
||||
signal AB8500 PMIC
|
||||
|
||||
config REGULATOR_ARIZONA
|
||||
tristate "Wolfson Arizona class devices"
|
||||
config REGULATOR_ARIZONA_LDO1
|
||||
tristate "Wolfson Arizona class devices LDO1"
|
||||
depends on MFD_ARIZONA
|
||||
depends on SND_SOC
|
||||
help
|
||||
Support for the regulators found on Wolfson Arizona class
|
||||
Support for the LDO1 regulators found on Wolfson Arizona class
|
||||
devices.
|
||||
|
||||
config REGULATOR_ARIZONA_MICSUPP
|
||||
tristate "Wolfson Arizona class devices MICSUPP"
|
||||
depends on MFD_ARIZONA
|
||||
depends on SND_SOC
|
||||
help
|
||||
Support for the MICSUPP regulators found on Wolfson Arizona class
|
||||
devices.
|
||||
|
||||
config REGULATOR_AS3711
|
||||
@ -163,6 +171,17 @@ config REGULATOR_BCM590XX
|
||||
BCM590xx PMUs. This will enable support for the software
|
||||
controllable LDO/Switching regulators.
|
||||
|
||||
config REGULATOR_BD9571MWV
|
||||
tristate "ROHM BD9571MWV Regulators"
|
||||
depends on MFD_BD9571MWV
|
||||
help
|
||||
This driver provides support for the voltage regulators on the
|
||||
ROHM BD9571MWV PMIC. This will enable support for the software
|
||||
controllable regulator and voltage sampling units.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called bd9571mwv-regulator.
|
||||
|
||||
config REGULATOR_CPCAP
|
||||
tristate "Motorola CPCAP regulator"
|
||||
depends on MFD_CPCAP
|
||||
@ -788,6 +807,14 @@ config REGULATOR_TPS65090
|
||||
This driver provides support for the voltage regulators on the
|
||||
TI TPS65090 PMIC.
|
||||
|
||||
config REGULATOR_TPS65132
|
||||
tristate "TI TPS65132 Dual Output Power regulators"
|
||||
depends on I2C && GPIOLIB
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports TPS65132 single inductor - dual output
|
||||
power supply specifcally designed for display panels.
|
||||
|
||||
config REGULATOR_TPS65217
|
||||
tristate "TI TPS65217 Power regulators"
|
||||
depends on MFD_TPS65217
|
||||
@ -850,6 +877,13 @@ config REGULATOR_TWL4030
|
||||
This driver supports the voltage regulators provided by
|
||||
this family of companion chips.
|
||||
|
||||
config REGULATOR_VCTRL
|
||||
tristate "Voltage controlled regulators"
|
||||
depends on OF
|
||||
help
|
||||
This driver provides support for voltage regulators whose output
|
||||
voltage is controlled by the voltage of another regulator.
|
||||
|
||||
config REGULATOR_VEXPRESS
|
||||
tristate "Versatile Express regulators"
|
||||
depends on VEXPRESS_CONFIG
|
||||
|
@ -19,11 +19,13 @@ obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
|
||||
obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
|
||||
obj-$(CONFIG_REGULATOR_ARIZONA_LDO1) += arizona-ldo1.o
|
||||
obj-$(CONFIG_REGULATOR_ARIZONA_MICSUPP) += arizona-micsupp.o
|
||||
obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
||||
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
|
||||
@ -105,7 +107,9 @@ obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
|
||||
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
|
||||
|
@ -39,7 +39,6 @@
|
||||
#define LDO_FET_FULL_ON 0x1f
|
||||
|
||||
struct anatop_regulator {
|
||||
const char *name;
|
||||
u32 control_reg;
|
||||
struct regmap *anatop;
|
||||
int vol_bit_shift;
|
||||
@ -193,13 +192,21 @@ static int anatop_regulator_probe(struct platform_device *pdev)
|
||||
sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
|
||||
if (!sreg)
|
||||
return -ENOMEM;
|
||||
sreg->name = of_get_property(np, "regulator-name", NULL);
|
||||
|
||||
rdesc = &sreg->rdesc;
|
||||
rdesc->name = sreg->name;
|
||||
rdesc->type = REGULATOR_VOLTAGE;
|
||||
rdesc->owner = THIS_MODULE;
|
||||
|
||||
of_property_read_string(np, "regulator-name", &rdesc->name);
|
||||
if (!rdesc->name) {
|
||||
dev_err(dev, "failed to get a regulator-name\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
initdata = of_get_regulator_init_data(dev, np, rdesc);
|
||||
if (!initdata)
|
||||
return -ENOMEM;
|
||||
|
||||
initdata->supply_regulator = "vin";
|
||||
sreg->initdata = initdata;
|
||||
|
||||
@ -293,9 +300,13 @@ static int anatop_regulator_probe(struct platform_device *pdev)
|
||||
* 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"))
|
||||
if (!sreg->sel && !strcmp(rdesc->name, "vddpu"))
|
||||
sreg->sel = 22;
|
||||
|
||||
/* set the default voltage of the pcie phy to be 1.100v */
|
||||
if (!sreg->sel && !strcmp(rdesc->name, "vddpcie"))
|
||||
sreg->sel = 0x10;
|
||||
|
||||
if (!sreg->bypass && !sreg->sel) {
|
||||
dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
|
||||
return -EINVAL;
|
||||
|
@ -25,13 +25,15 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/regulator/arizona-ldo1.h>
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
#include <linux/mfd/arizona/pdata.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
struct arizona_ldo1 {
|
||||
struct regulator_dev *regulator;
|
||||
struct arizona *arizona;
|
||||
struct regmap *regmap;
|
||||
|
||||
struct regulator_consumer_supply supply;
|
||||
struct regulator_init_data init_data;
|
||||
@ -65,7 +67,7 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned sel)
|
||||
{
|
||||
struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
|
||||
struct regmap *regmap = ldo->arizona->regmap;
|
||||
struct regmap *regmap = ldo->regmap;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
@ -91,7 +93,7 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
|
||||
static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
|
||||
struct regmap *regmap = ldo->arizona->regmap;
|
||||
struct regmap *regmap = ldo->regmap;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
@ -186,19 +188,19 @@ static const struct regulator_init_data arizona_ldo1_wm5110 = {
|
||||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
|
||||
static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
|
||||
struct regulator_config *config,
|
||||
const struct regulator_desc *desc)
|
||||
const struct regulator_desc *desc,
|
||||
bool *external_dcvdd)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
struct arizona_ldo1 *ldo1 = config->driver_data;
|
||||
struct device_node *np = arizona->dev->of_node;
|
||||
struct device_node *np = config->dev->of_node;
|
||||
struct device_node *init_node, *dcvdd_node;
|
||||
struct regulator_init_data *init_data;
|
||||
|
||||
pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0);
|
||||
if (pdata->ldoena < 0) {
|
||||
dev_warn(arizona->dev,
|
||||
dev_warn(config->dev,
|
||||
"LDOENA GPIO property missing/malformed: %d\n",
|
||||
pdata->ldoena);
|
||||
pdata->ldoena = 0;
|
||||
@ -212,20 +214,19 @@ 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(config->dev, init_node,
|
||||
desc);
|
||||
|
||||
if (init_data) {
|
||||
init_data->consumer_supplies = &ldo1->supply;
|
||||
init_data->num_consumer_supplies = 1;
|
||||
|
||||
if (dcvdd_node && dcvdd_node != init_node)
|
||||
arizona->external_dcvdd = true;
|
||||
*external_dcvdd = true;
|
||||
|
||||
pdata->ldo1 = init_data;
|
||||
pdata->init_data = init_data;
|
||||
}
|
||||
} else if (dcvdd_node) {
|
||||
arizona->external_dcvdd = true;
|
||||
*external_dcvdd = true;
|
||||
}
|
||||
|
||||
of_node_put(dcvdd_node);
|
||||
@ -233,21 +234,79 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arizona_ldo1_common_init(struct platform_device *pdev,
|
||||
struct arizona_ldo1 *ldo1,
|
||||
const struct regulator_desc *desc,
|
||||
struct arizona_ldo1_pdata *pdata,
|
||||
bool *external_dcvdd)
|
||||
{
|
||||
struct device *parent_dev = pdev->dev.parent;
|
||||
struct regulator_config config = { };
|
||||
int ret;
|
||||
|
||||
*external_dcvdd = false;
|
||||
|
||||
ldo1->supply.supply = "DCVDD";
|
||||
ldo1->init_data.consumer_supplies = &ldo1->supply;
|
||||
ldo1->supply.dev_name = dev_name(parent_dev);
|
||||
|
||||
config.dev = parent_dev;
|
||||
config.driver_data = ldo1;
|
||||
config.regmap = ldo1->regmap;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF)) {
|
||||
if (!dev_get_platdata(parent_dev)) {
|
||||
ret = arizona_ldo1_of_get_pdata(pdata,
|
||||
&config, desc,
|
||||
external_dcvdd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
config.ena_gpio = pdata->ldoena;
|
||||
|
||||
if (pdata->init_data)
|
||||
config.init_data = pdata->init_data;
|
||||
else
|
||||
config.init_data = &ldo1->init_data;
|
||||
|
||||
/*
|
||||
* LDO1 can only be used to supply DCVDD so if it has no
|
||||
* consumers then DCVDD is supplied externally.
|
||||
*/
|
||||
if (config.init_data->num_consumer_supplies == 0)
|
||||
*external_dcvdd = true;
|
||||
|
||||
ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
|
||||
|
||||
of_node_put(config.of_node);
|
||||
|
||||
if (IS_ERR(ldo1->regulator)) {
|
||||
ret = PTR_ERR(ldo1->regulator);
|
||||
dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ldo1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
const struct regulator_desc *desc;
|
||||
struct regulator_config config = { };
|
||||
struct arizona_ldo1 *ldo1;
|
||||
const struct regulator_desc *desc;
|
||||
bool external_dcvdd;
|
||||
int ret;
|
||||
|
||||
arizona->external_dcvdd = false;
|
||||
|
||||
ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
|
||||
if (!ldo1)
|
||||
return -ENOMEM;
|
||||
|
||||
ldo1->arizona = arizona;
|
||||
ldo1->regmap = arizona->regmap;
|
||||
|
||||
/*
|
||||
* Since the chip usually supplies itself we provide some
|
||||
@ -273,50 +332,13 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
|
||||
ldo1->init_data.consumer_supplies = &ldo1->supply;
|
||||
ldo1->supply.supply = "DCVDD";
|
||||
ldo1->supply.dev_name = dev_name(arizona->dev);
|
||||
ret = arizona_ldo1_common_init(pdev, ldo1, desc,
|
||||
&arizona->pdata.ldo1,
|
||||
&external_dcvdd);
|
||||
if (ret == 0)
|
||||
arizona->external_dcvdd = external_dcvdd;
|
||||
|
||||
config.dev = arizona->dev;
|
||||
config.driver_data = ldo1;
|
||||
config.regmap = arizona->regmap;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF)) {
|
||||
if (!dev_get_platdata(arizona->dev)) {
|
||||
ret = arizona_ldo1_of_get_pdata(arizona, &config, desc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
config.ena_gpio = arizona->pdata.ldoena;
|
||||
|
||||
if (arizona->pdata.ldo1)
|
||||
config.init_data = arizona->pdata.ldo1;
|
||||
else
|
||||
config.init_data = &ldo1->init_data;
|
||||
|
||||
/*
|
||||
* LDO1 can only be used to supply DCVDD so if it has no
|
||||
* consumers then DCVDD is supplied externally.
|
||||
*/
|
||||
if (config.init_data->num_consumer_supplies == 0)
|
||||
arizona->external_dcvdd = true;
|
||||
|
||||
ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
|
||||
|
||||
of_node_put(config.of_node);
|
||||
|
||||
if (IS_ERR(ldo1->regulator)) {
|
||||
ret = PTR_ERR(ldo1->regulator);
|
||||
dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ldo1);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver arizona_ldo1_driver = {
|
||||
|
@ -30,9 +30,14 @@
|
||||
#include <linux/mfd/arizona/pdata.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
#include <linux/regulator/arizona-micsupp.h>
|
||||
|
||||
struct arizona_micsupp {
|
||||
struct regulator_dev *regulator;
|
||||
struct arizona *arizona;
|
||||
struct regmap *regmap;
|
||||
struct snd_soc_dapm_context **dapm;
|
||||
unsigned int enable_reg;
|
||||
struct device *dev;
|
||||
|
||||
struct regulator_consumer_supply supply;
|
||||
struct regulator_init_data init_data;
|
||||
@ -44,21 +49,22 @@ 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 snd_soc_component *component = snd_soc_dapm_to_component(dapm);
|
||||
struct arizona *arizona = micsupp->arizona;
|
||||
struct regmap *regmap = arizona->regmap;
|
||||
unsigned int reg;
|
||||
struct snd_soc_dapm_context *dapm = *micsupp->dapm;
|
||||
struct snd_soc_component *component;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, ®);
|
||||
ret = regmap_read(micsupp->regmap, micsupp->enable_reg, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to read CP state: %d\n", ret);
|
||||
dev_err(micsupp->dev,
|
||||
"Failed to read CP state: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dapm) {
|
||||
if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
|
||||
component = snd_soc_dapm_to_component(dapm);
|
||||
|
||||
if ((val & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
|
||||
ARIZONA_CPMIC_ENA)
|
||||
snd_soc_component_force_enable_pin(component,
|
||||
"MICSUPP");
|
||||
@ -199,47 +205,100 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
|
||||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
|
||||
static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata,
|
||||
struct regulator_config *config,
|
||||
const struct regulator_desc *desc)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
struct arizona_micsupp *micsupp = config->driver_data;
|
||||
struct device_node *np;
|
||||
struct regulator_init_data *init_data;
|
||||
|
||||
np = of_get_child_by_name(arizona->dev->of_node, "micvdd");
|
||||
np = of_get_child_by_name(config->dev->of_node, "micvdd");
|
||||
|
||||
if (np) {
|
||||
config->of_node = np;
|
||||
|
||||
init_data = of_get_regulator_init_data(arizona->dev, np, desc);
|
||||
init_data = of_get_regulator_init_data(config->dev, np, desc);
|
||||
|
||||
if (init_data) {
|
||||
init_data->consumer_supplies = &micsupp->supply;
|
||||
init_data->num_consumer_supplies = 1;
|
||||
|
||||
pdata->micvdd = init_data;
|
||||
pdata->init_data = init_data;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arizona_micsupp_common_init(struct platform_device *pdev,
|
||||
struct arizona_micsupp *micsupp,
|
||||
const struct regulator_desc *desc,
|
||||
struct arizona_micsupp_pdata *pdata)
|
||||
{
|
||||
struct regulator_config config = { };
|
||||
int ret;
|
||||
|
||||
INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
|
||||
|
||||
micsupp->init_data.consumer_supplies = &micsupp->supply;
|
||||
micsupp->supply.supply = "MICVDD";
|
||||
micsupp->supply.dev_name = dev_name(micsupp->dev);
|
||||
micsupp->enable_reg = desc->enable_reg;
|
||||
|
||||
config.dev = micsupp->dev;
|
||||
config.driver_data = micsupp;
|
||||
config.regmap = micsupp->regmap;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF)) {
|
||||
if (!dev_get_platdata(micsupp->dev)) {
|
||||
ret = arizona_micsupp_of_get_pdata(pdata, &config,
|
||||
desc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdata->init_data)
|
||||
config.init_data = pdata->init_data;
|
||||
else
|
||||
config.init_data = &micsupp->init_data;
|
||||
|
||||
/* Default to regulated mode */
|
||||
regmap_update_bits(micsupp->regmap, micsupp->enable_reg,
|
||||
ARIZONA_CPMIC_BYPASS, 0);
|
||||
|
||||
micsupp->regulator = devm_regulator_register(&pdev->dev,
|
||||
desc,
|
||||
&config);
|
||||
|
||||
of_node_put(config.of_node);
|
||||
|
||||
if (IS_ERR(micsupp->regulator)) {
|
||||
ret = PTR_ERR(micsupp->regulator);
|
||||
dev_err(micsupp->dev, "Failed to register mic supply: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, micsupp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
const struct regulator_desc *desc;
|
||||
struct regulator_config config = { };
|
||||
struct arizona_micsupp *micsupp;
|
||||
int ret;
|
||||
|
||||
micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
|
||||
if (!micsupp)
|
||||
return -ENOMEM;
|
||||
|
||||
micsupp->arizona = arizona;
|
||||
INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
|
||||
micsupp->regmap = arizona->regmap;
|
||||
micsupp->dapm = &arizona->dapm;
|
||||
micsupp->dev = arizona->dev;
|
||||
|
||||
/*
|
||||
* Since the chip usually supplies itself we provide some
|
||||
@ -258,48 +317,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
|
||||
micsupp->init_data.consumer_supplies = &micsupp->supply;
|
||||
micsupp->supply.supply = "MICVDD";
|
||||
micsupp->supply.dev_name = dev_name(arizona->dev);
|
||||
|
||||
config.dev = arizona->dev;
|
||||
config.driver_data = micsupp;
|
||||
config.regmap = arizona->regmap;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF)) {
|
||||
if (!dev_get_platdata(arizona->dev)) {
|
||||
ret = arizona_micsupp_of_get_pdata(arizona, &config,
|
||||
desc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (arizona->pdata.micvdd)
|
||||
config.init_data = arizona->pdata.micvdd;
|
||||
else
|
||||
config.init_data = &micsupp->init_data;
|
||||
|
||||
/* Default to regulated mode until the API supports bypass */
|
||||
regmap_update_bits(arizona->regmap, ARIZONA_MIC_CHARGE_PUMP_1,
|
||||
ARIZONA_CPMIC_BYPASS, 0);
|
||||
|
||||
micsupp->regulator = devm_regulator_register(&pdev->dev,
|
||||
desc,
|
||||
&config);
|
||||
|
||||
of_node_put(config.of_node);
|
||||
|
||||
if (IS_ERR(micsupp->regulator)) {
|
||||
ret = PTR_ERR(micsupp->regulator);
|
||||
dev_err(arizona->dev, "Failed to register mic supply: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, micsupp);
|
||||
|
||||
return 0;
|
||||
return arizona_micsupp_common_init(pdev, micsupp, desc,
|
||||
&arizona->pdata.micvdd);
|
||||
}
|
||||
|
||||
static struct platform_driver arizona_micsupp_driver = {
|
||||
|
178
drivers/regulator/bd9571mwv-regulator.c
Normal file
178
drivers/regulator/bd9571mwv-regulator.c
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* ROHM BD9571MWV-M regulator driver
|
||||
*
|
||||
* Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether expressed or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License version 2 for more details.
|
||||
*
|
||||
* Based on the TPS65086 driver
|
||||
*
|
||||
* NOTE: VD09 is missing
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
||||
#include <linux/mfd/bd9571mwv.h>
|
||||
|
||||
enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS };
|
||||
|
||||
#define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\
|
||||
{ \
|
||||
.name = _name, \
|
||||
.of_match = of_match_ptr(_of), \
|
||||
.regulators_node = "regulators", \
|
||||
.id = _id, \
|
||||
.ops = &_ops, \
|
||||
.n_voltages = _nv, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.vsel_reg = _vr, \
|
||||
.vsel_mask = _vm, \
|
||||
.min_uV = _min, \
|
||||
.uV_step = _step, \
|
||||
.linear_min_sel = _lmin, \
|
||||
}
|
||||
|
||||
int bd9571mwv_avs_get_moni_state(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, BD9571MWV_AVS_SET_MONI, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return val & BD9571MWV_AVS_SET_MONI_MASK;
|
||||
}
|
||||
|
||||
int bd9571mwv_avs_set_voltage_sel_regmap(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bd9571mwv_avs_get_moni_state(rdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return regmap_write_bits(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret),
|
||||
rdev->desc->vsel_mask, sel);
|
||||
}
|
||||
|
||||
int bd9571mwv_avs_get_voltage_sel_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = bd9571mwv_avs_get_moni_state(rdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
val &= rdev->desc->vsel_mask;
|
||||
val >>= ffs(rdev->desc->vsel_mask) - 1;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
return regmap_write_bits(rdev->regmap, BD9571MWV_DVFS_SETVID,
|
||||
rdev->desc->vsel_mask, sel);
|
||||
}
|
||||
|
||||
/* Operations permitted on AVS voltage regulator */
|
||||
static struct regulator_ops avs_ops = {
|
||||
.set_voltage_sel = bd9571mwv_avs_set_voltage_sel_regmap,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = bd9571mwv_avs_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
/* Operations permitted on voltage regulators */
|
||||
static struct regulator_ops reg_ops = {
|
||||
.set_voltage_sel = bd9571mwv_reg_set_voltage_sel_regmap,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
/* Operations permitted on voltage monitors */
|
||||
static struct regulator_ops vid_ops = {
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f,
|
||||
0x80, 600000, 10000, 0x3c),
|
||||
BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf,
|
||||
16, 1625000, 25000, 0),
|
||||
BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf,
|
||||
16, 2150000, 50000, 0),
|
||||
BD9571MWV_REG("VD33", "vd33", VD33, vid_ops, BD9571MWV_VD33_VID, 0xf,
|
||||
11, 2800000, 100000, 0),
|
||||
BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops,
|
||||
BD9571MWV_DVFS_MONIVDAC, 0x7f,
|
||||
0x80, 600000, 10000, 0x3c),
|
||||
};
|
||||
|
||||
static int bd9571mwv_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bd9571mwv *bd = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
int i;
|
||||
|
||||
platform_set_drvdata(pdev, bd);
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.dev->of_node = bd->dev->of_node;
|
||||
config.driver_data = bd;
|
||||
config.regmap = bd->regmap;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
|
||||
rdev = devm_regulator_register(&pdev->dev, ®ulators[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(bd->dev, "failed to register %s regulator\n",
|
||||
pdev->name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id bd9571mwv_regulator_id_table[] = {
|
||||
{ "bd9571mwv-regulator", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table);
|
||||
|
||||
static struct platform_driver bd9571mwv_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "bd9571mwv-regulator",
|
||||
},
|
||||
.probe = bd9571mwv_regulator_probe,
|
||||
.id_table = bd9571mwv_regulator_id_table,
|
||||
};
|
||||
module_platform_driver(bd9571mwv_regulator_driver);
|
||||
|
||||
MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
|
||||
MODULE_DESCRIPTION("BD9571MWV Regulator driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1326,8 +1326,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
regulator->dev = dev;
|
||||
|
||||
/* Add a link to the device sysfs entry */
|
||||
size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
|
||||
dev->kobj.name, supply_name);
|
||||
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
|
||||
dev->kobj.name, supply_name);
|
||||
if (size >= REG_STR_SIZE)
|
||||
goto overflow_err;
|
||||
|
||||
@ -1343,7 +1343,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
/* non-fatal */
|
||||
}
|
||||
} else {
|
||||
regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
|
||||
regulator->supply_name = kstrdup_const(supply_name, GFP_KERNEL);
|
||||
if (regulator->supply_name == NULL)
|
||||
goto overflow_err;
|
||||
}
|
||||
@ -1451,8 +1451,6 @@ static struct regulator_dev *regulator_lookup_by_name(const char *name)
|
||||
* regulator_dev_lookup - lookup a regulator device.
|
||||
* @dev: device for regulator "consumer".
|
||||
* @supply: Supply name or regulator ID.
|
||||
* @ret: 0 on success, -ENODEV if lookup fails permanently, -EPROBE_DEFER if
|
||||
* lookup could succeed in the future.
|
||||
*
|
||||
* If successful, returns a struct regulator_dev that corresponds to the name
|
||||
* @supply and with the embedded struct device refcount incremented by one.
|
||||
@ -1534,14 +1532,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
|
||||
if (IS_ERR(r)) {
|
||||
ret = PTR_ERR(r);
|
||||
|
||||
if (ret == -ENODEV) {
|
||||
/*
|
||||
* No supply was specified for this regulator and
|
||||
* there will never be one.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Did the lookup explicitly defer for us? */
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
@ -1799,7 +1789,7 @@ static void _regulator_put(struct regulator *regulator)
|
||||
put_device(&rdev->dev);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
||||
kfree(regulator->supply_name);
|
||||
kfree_const(regulator->supply_name);
|
||||
kfree(regulator);
|
||||
|
||||
module_put(rdev->owner);
|
||||
@ -2182,6 +2172,8 @@ static int _regulator_enable(struct regulator_dev *rdev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
_notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE,
|
||||
NULL);
|
||||
} else if (ret < 0) {
|
||||
rdev_err(rdev, "is_enabled() failed: %d\n", ret);
|
||||
return ret;
|
||||
@ -2486,7 +2478,7 @@ static int _regulator_list_voltage(struct regulator *regulator,
|
||||
ret = ops->list_voltage(rdev, selector);
|
||||
if (lock)
|
||||
mutex_unlock(&rdev->mutex);
|
||||
} else if (rdev->supply) {
|
||||
} else if (rdev->is_switch && rdev->supply) {
|
||||
ret = _regulator_list_voltage(rdev->supply, selector, lock);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
@ -2544,7 +2536,7 @@ int regulator_count_voltages(struct regulator *regulator)
|
||||
if (rdev->desc->n_voltages)
|
||||
return rdev->desc->n_voltages;
|
||||
|
||||
if (!rdev->supply)
|
||||
if (!rdev->is_switch || !rdev->supply)
|
||||
return -EINVAL;
|
||||
|
||||
return regulator_count_voltages(rdev->supply);
|
||||
@ -2773,6 +2765,8 @@ static int _regulator_set_voltage_time(struct regulator_dev *rdev,
|
||||
ramp_delay = rdev->constraints->ramp_delay;
|
||||
else if (rdev->desc->ramp_delay)
|
||||
ramp_delay = rdev->desc->ramp_delay;
|
||||
else if (rdev->constraints->settling_time)
|
||||
return rdev->constraints->settling_time;
|
||||
|
||||
if (ramp_delay == 0) {
|
||||
rdev_dbg(rdev, "ramp_delay not set\n");
|
||||
@ -2941,8 +2935,10 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
|
||||
if (ret < 0)
|
||||
goto out2;
|
||||
|
||||
if (rdev->supply && (rdev->desc->min_dropout_uV ||
|
||||
!rdev->desc->ops->get_voltage)) {
|
||||
if (rdev->supply &&
|
||||
regulator_ops_is_valid(rdev->supply->rdev,
|
||||
REGULATOR_CHANGE_VOLTAGE) &&
|
||||
(rdev->desc->min_dropout_uV || !rdev->desc->ops->get_voltage)) {
|
||||
int current_supply_uV;
|
||||
int selector;
|
||||
|
||||
@ -4099,6 +4095,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
}
|
||||
|
||||
if (!rdev->desc->ops->get_voltage &&
|
||||
!rdev->desc->ops->list_voltage &&
|
||||
!rdev->desc->fixed_uV)
|
||||
rdev->is_switch = true;
|
||||
|
||||
ret = device_register(&rdev->dev);
|
||||
if (ret != 0) {
|
||||
put_device(&rdev->dev);
|
||||
|
@ -445,6 +445,42 @@ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
|
||||
|
||||
/**
|
||||
* regulator_set_soft_start_regmap - Default set_soft_start() using regmap
|
||||
*
|
||||
* @rdev: device to operate on.
|
||||
*/
|
||||
int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = rdev->desc->soft_start_val_on;
|
||||
if (!val)
|
||||
val = rdev->desc->soft_start_mask;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,
|
||||
rdev->desc->soft_start_mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
|
||||
|
||||
/**
|
||||
* regulator_set_pull_down_regmap - Default set_pull_down() using regmap
|
||||
*
|
||||
* @rdev: device to operate on.
|
||||
*/
|
||||
int regulator_set_pull_down_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = rdev->desc->pull_down_val_on;
|
||||
if (!val)
|
||||
val = rdev->desc->pull_down_mask;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,
|
||||
rdev->desc->pull_down_mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);
|
||||
|
||||
/**
|
||||
* regulator_get_bypass_regmap - Default get_bypass() using regmap
|
||||
*
|
||||
|
@ -214,7 +214,14 @@ static int hi655x_regulator_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id hi655x_regulator_table[] = {
|
||||
{ .name = "hi655x-regulator" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, hi655x_regulator_table);
|
||||
|
||||
static struct platform_driver hi655x_regulator_driver = {
|
||||
.id_table = hi655x_regulator_table,
|
||||
.driver = {
|
||||
.name = "hi655x-regulator",
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ struct regulator {
|
||||
int uA_load;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
char *supply_name;
|
||||
const char *supply_name;
|
||||
struct device_attribute dev_attr;
|
||||
struct regulator_dev *rdev;
|
||||
struct dentry *debugfs;
|
||||
|
@ -227,9 +227,9 @@ static int lm363x_regulator_of_get_enable_gpio(struct device_node *np, int id)
|
||||
*/
|
||||
switch (id) {
|
||||
case LM3632_LDO_POS:
|
||||
return of_get_named_gpio(np, "ti,lcm-en1-gpio", 0);
|
||||
return of_get_named_gpio(np, "enable-gpios", 0);
|
||||
case LM3632_LDO_NEG:
|
||||
return of_get_named_gpio(np, "ti,lcm-en2-gpio", 0);
|
||||
return of_get_named_gpio(np, "enable-gpios", 1);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
@ -470,7 +471,11 @@ static int ltc3589_probe(struct i2c_client *client,
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, ltc3589);
|
||||
ltc3589->variant = id->driver_data;
|
||||
if (client->dev.of_node)
|
||||
ltc3589->variant = (enum ltc3589_variant)
|
||||
of_device_get_match_data(&client->dev);
|
||||
else
|
||||
ltc3589->variant = id->driver_data;
|
||||
ltc3589->dev = dev;
|
||||
|
||||
descs = ltc3589->regulator_descs;
|
||||
@ -542,9 +547,27 @@ static struct i2c_device_id ltc3589_i2c_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);
|
||||
|
||||
static const struct of_device_id ltc3589_of_match[] = {
|
||||
{
|
||||
.compatible = "lltc,ltc3589",
|
||||
.data = (void *)LTC3589,
|
||||
},
|
||||
{
|
||||
.compatible = "lltc,ltc3589-1",
|
||||
.data = (void *)LTC3589_1,
|
||||
},
|
||||
{
|
||||
.compatible = "lltc,ltc3589-2",
|
||||
.data = (void *)LTC3589_2,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ltc3589_of_match);
|
||||
|
||||
static struct i2c_driver ltc3589_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(ltc3589_of_match),
|
||||
},
|
||||
.probe = ltc3589_probe,
|
||||
.id_table = ltc3589_i2c_id,
|
||||
|
@ -406,9 +406,16 @@ static const struct i2c_device_id ltc3676_i2c_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ltc3676_i2c_id);
|
||||
|
||||
static const struct of_device_id ltc3676_of_match[] = {
|
||||
{ .compatible = "lltc,ltc3676" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ltc3676_of_match);
|
||||
|
||||
static struct i2c_driver ltc3676_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(ltc3676_of_match),
|
||||
},
|
||||
.probe = ltc3676_regulator_probe,
|
||||
.id_table = ltc3676_i2c_id,
|
||||
|
@ -126,14 +126,14 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev,
|
||||
* The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back
|
||||
* the set up value.
|
||||
*/
|
||||
static struct regulator_ops max1586_v3_ops = {
|
||||
static const struct regulator_ops max1586_v3_ops = {
|
||||
.get_voltage_sel = max1586_v3_get_voltage_sel,
|
||||
.set_voltage_sel = max1586_v3_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_ops max1586_v6_ops = {
|
||||
static const struct regulator_ops max1586_v6_ops = {
|
||||
.get_voltage_sel = max1586_v6_get_voltage_sel,
|
||||
.set_voltage_sel = max1586_v6_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
|
@ -150,7 +150,7 @@ static const struct regulator_ops max77693_safeout_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops max77693_charger_ops = {
|
||||
static const struct regulator_ops max77693_charger_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
|
@ -194,7 +194,7 @@ static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev,
|
||||
return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0);
|
||||
}
|
||||
|
||||
static struct regulator_ops max8660_ldo5_ops = {
|
||||
static const struct regulator_ops max8660_ldo5_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.set_voltage_sel = max8660_ldo5_set_voltage_sel,
|
||||
@ -252,7 +252,7 @@ static int max8660_ldo67_set_voltage_sel(struct regulator_dev *rdev,
|
||||
selector << 4);
|
||||
}
|
||||
|
||||
static struct regulator_ops max8660_ldo67_ops = {
|
||||
static const struct regulator_ops max8660_ldo67_ops = {
|
||||
.is_enabled = max8660_ldo67_is_enabled,
|
||||
.enable = max8660_ldo67_enable,
|
||||
.disable = max8660_ldo67_disable,
|
||||
|
@ -86,6 +86,10 @@ static void of_get_regulation_constraints(struct device_node *np,
|
||||
constraints->ramp_disable = true;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "regulator-settling-time-us", &pval);
|
||||
if (!ret)
|
||||
constraints->settling_time = pval;
|
||||
|
||||
ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
|
||||
if (!ret)
|
||||
constraints->enable_time = pval;
|
||||
|
@ -40,6 +40,7 @@
|
||||
#define PFUZE100_REVID 0x3
|
||||
#define PFUZE100_FABID 0x4
|
||||
|
||||
#define PFUZE100_COINVOL 0x1a
|
||||
#define PFUZE100_SW1ABVOL 0x20
|
||||
#define PFUZE100_SW1CVOL 0x2e
|
||||
#define PFUZE100_SW2VOL 0x35
|
||||
@ -81,6 +82,10 @@ static const int pfuze100_vsnvs[] = {
|
||||
1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000,
|
||||
};
|
||||
|
||||
static const int pfuze100_coin[] = {
|
||||
2500000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
|
||||
};
|
||||
|
||||
static const int pfuze3000_sw2lo[] = {
|
||||
1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000,
|
||||
};
|
||||
@ -230,6 +235,23 @@ static const struct regulator_ops pfuze100_swb_regulator_ops = {
|
||||
.stby_mask = 0x20, \
|
||||
}
|
||||
|
||||
#define PFUZE100_COIN_REG(_chip, _name, base, mask, voltages) \
|
||||
[_chip ## _ ## _name] = { \
|
||||
.desc = { \
|
||||
.name = #_name, \
|
||||
.n_voltages = ARRAY_SIZE(voltages), \
|
||||
.ops = &pfuze100_swb_regulator_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = _chip ## _ ## _name, \
|
||||
.owner = THIS_MODULE, \
|
||||
.volt_table = voltages, \
|
||||
.vsel_reg = (base), \
|
||||
.vsel_mask = (mask), \
|
||||
.enable_reg = (base), \
|
||||
.enable_mask = 0x8, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define PFUZE3000_VCC_REG(_chip, _name, base, min, max, step) { \
|
||||
.desc = { \
|
||||
.name = #_name, \
|
||||
@ -317,6 +339,7 @@ static struct pfuze_regulator pfuze200_regulators[] = {
|
||||
PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
|
||||
PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
|
||||
PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
|
||||
PFUZE100_COIN_REG(PFUZE200, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin),
|
||||
};
|
||||
|
||||
static struct pfuze_regulator pfuze3000_regulators[] = {
|
||||
@ -371,6 +394,7 @@ static struct of_regulator_match pfuze200_matches[] = {
|
||||
{ .name = "vgen4", },
|
||||
{ .name = "vgen5", },
|
||||
{ .name = "vgen6", },
|
||||
{ .name = "coin", },
|
||||
};
|
||||
|
||||
/* PFUZE3000 */
|
||||
|
@ -519,7 +519,7 @@ static const struct regulator_desc rk818_reg[] = {
|
||||
RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
|
||||
BIT(0), 400),
|
||||
RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
|
||||
RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
|
||||
RK818_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
|
||||
BIT(1), 400),
|
||||
{
|
||||
.name = "LDO_REG3",
|
||||
|
@ -213,7 +213,7 @@ ramp_disable:
|
||||
1 << enable_shift, 0);
|
||||
}
|
||||
|
||||
static struct regulator_ops s2mpa01_ldo_ops = {
|
||||
static const struct regulator_ops s2mpa01_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -224,7 +224,7 @@ static struct regulator_ops s2mpa01_ldo_ops = {
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops s2mpa01_buck_ops = {
|
||||
static const struct regulator_ops s2mpa01_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -359,11 +359,11 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
|
||||
if (iodev->dev->of_node) {
|
||||
reg_np = of_get_child_by_name(iodev->dev->of_node,
|
||||
"regulators");
|
||||
if (!reg_np) {
|
||||
dev_err(&pdev->dev,
|
||||
"could not find regulators sub-node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!reg_np) {
|
||||
dev_err(&pdev->dev,
|
||||
"could not find regulators sub-node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_regulator_match(&pdev->dev, reg_np, rdata,
|
||||
S2MPA01_REGULATOR_MAX);
|
||||
|
@ -238,7 +238,7 @@ ramp_disable:
|
||||
1 << enable_shift, 0);
|
||||
}
|
||||
|
||||
static struct regulator_ops s2mps11_ldo_ops = {
|
||||
static const struct regulator_ops s2mps11_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -249,7 +249,7 @@ static struct regulator_ops s2mps11_ldo_ops = {
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops s2mps11_buck_ops = {
|
||||
static const struct regulator_ops s2mps11_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -392,7 +392,7 @@ static const struct regulator_desc s2mps11_regulators[] = {
|
||||
regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV),
|
||||
};
|
||||
|
||||
static struct regulator_ops s2mps14_reg_ops;
|
||||
static const struct regulator_ops s2mps14_reg_ops;
|
||||
|
||||
#define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \
|
||||
.name = "LDO"#num, \
|
||||
@ -599,7 +599,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
|
||||
rdev->desc->enable_mask, state);
|
||||
}
|
||||
|
||||
static struct regulator_ops s2mps14_reg_ops = {
|
||||
static const struct regulator_ops s2mps14_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -681,7 +681,7 @@ static const struct regulator_desc s2mps14_regulators[] = {
|
||||
S2MPS14_BUCK1235_START_SEL),
|
||||
};
|
||||
|
||||
static struct regulator_ops s2mps15_reg_ldo_ops = {
|
||||
static const struct regulator_ops s2mps15_reg_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -691,7 +691,7 @@ static struct regulator_ops s2mps15_reg_ldo_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops s2mps15_reg_buck_ops = {
|
||||
static const struct regulator_ops s2mps15_reg_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -886,7 +886,7 @@ static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||
ramp_val << ramp_shift);
|
||||
}
|
||||
|
||||
static struct regulator_ops s2mpu02_ldo_ops = {
|
||||
static const struct regulator_ops s2mpu02_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -898,7 +898,7 @@ static struct regulator_ops s2mpu02_ldo_ops = {
|
||||
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops s2mpu02_buck_ops = {
|
||||
static const struct regulator_ops s2mpu02_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
|
@ -357,7 +357,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct regulator_ops s5m8767_ops = {
|
||||
static const struct regulator_ops s5m8767_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
@ -367,7 +367,7 @@ static struct regulator_ops s5m8767_ops = {
|
||||
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops s5m8767_buck78_ops = {
|
||||
static const struct regulator_ops s5m8767_buck78_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
|
@ -311,8 +311,7 @@ static int tps_65023_probe(struct i2c_client *client,
|
||||
|
||||
/* Enable setting output voltage by I2C */
|
||||
regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
|
||||
TPS65023_REG_CTRL2_CORE_ADJ,
|
||||
TPS65023_REG_CTRL2_CORE_ADJ);
|
||||
TPS65023_REG_CTRL2_CORE_ADJ, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
284
drivers/regulator/tps65132-regulator.c
Normal file
284
drivers/regulator/tps65132-regulator.c
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* TI TPS65132 Regulator driver
|
||||
*
|
||||
* Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author: Venkat Reddy Talla <vreddytalla@nvidia.com>
|
||||
* Laxman Dewangan <ldewangan@nvidia.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
|
||||
* whether express or implied; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#define TPS65132_REG_VPOS 0x00
|
||||
#define TPS65132_REG_VNEG 0x01
|
||||
#define TPS65132_REG_APPS_DISP_DISN 0x03
|
||||
#define TPS65132_REG_CONTROL 0x0FF
|
||||
|
||||
#define TPS65132_VOUT_MASK 0x1F
|
||||
#define TPS65132_VOUT_N_VOLTAGE 0x15
|
||||
#define TPS65132_VOUT_VMIN 4000000
|
||||
#define TPS65132_VOUT_VMAX 6000000
|
||||
#define TPS65132_VOUT_STEP 100000
|
||||
|
||||
#define TPS65132_REG_APPS_DIS_VPOS BIT(0)
|
||||
#define TPS65132_REG_APPS_DIS_VNEG BIT(1)
|
||||
|
||||
#define TPS65132_REGULATOR_ID_VPOS 0
|
||||
#define TPS65132_REGULATOR_ID_VNEG 1
|
||||
#define TPS65132_MAX_REGULATORS 2
|
||||
|
||||
#define TPS65132_ACT_DIS_TIME_SLACK 1000
|
||||
|
||||
struct tps65132_reg_pdata {
|
||||
struct gpio_desc *en_gpiod;
|
||||
struct gpio_desc *act_dis_gpiod;
|
||||
unsigned int act_dis_time_us;
|
||||
int ena_gpio_state;
|
||||
};
|
||||
|
||||
struct tps65132_regulator {
|
||||
struct device *dev;
|
||||
struct regmap *rmap;
|
||||
struct regulator_desc *rdesc[TPS65132_MAX_REGULATORS];
|
||||
struct tps65132_reg_pdata reg_pdata[TPS65132_MAX_REGULATORS];
|
||||
struct regulator_dev *rdev[TPS65132_MAX_REGULATORS];
|
||||
};
|
||||
|
||||
static int tps65132_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
|
||||
int ret;
|
||||
|
||||
if (!IS_ERR(rpdata->en_gpiod)) {
|
||||
gpiod_set_value_cansleep(rpdata->en_gpiod, 1);
|
||||
rpdata->ena_gpio_state = 1;
|
||||
}
|
||||
|
||||
/* Hardware automatically enable discharge bit in enable */
|
||||
if (rdev->constraints->active_discharge ==
|
||||
REGULATOR_ACTIVE_DISCHARGE_DISABLE) {
|
||||
ret = regulator_set_active_discharge_regmap(rdev, false);
|
||||
if (ret < 0) {
|
||||
dev_err(tps->dev, "Failed to disable active discharge: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65132_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
|
||||
|
||||
if (!IS_ERR(rpdata->en_gpiod)) {
|
||||
gpiod_set_value_cansleep(rpdata->en_gpiod, 0);
|
||||
rpdata->ena_gpio_state = 0;
|
||||
}
|
||||
|
||||
if (!IS_ERR(rpdata->act_dis_gpiod)) {
|
||||
gpiod_set_value_cansleep(rpdata->act_dis_gpiod, 1);
|
||||
usleep_range(rpdata->act_dis_time_us, rpdata->act_dis_time_us +
|
||||
TPS65132_ACT_DIS_TIME_SLACK);
|
||||
gpiod_set_value_cansleep(rpdata->act_dis_gpiod, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65132_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
|
||||
int id = rdev_get_id(rdev);
|
||||
struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
|
||||
|
||||
if (!IS_ERR(rpdata->en_gpiod))
|
||||
return rpdata->ena_gpio_state;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct regulator_ops tps65132_regulator_ops = {
|
||||
.enable = tps65132_regulator_enable,
|
||||
.disable = tps65132_regulator_disable,
|
||||
.is_enabled = tps65132_regulator_is_enabled,
|
||||
.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,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
static int tps65132_of_parse_cb(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
struct tps65132_regulator *tps = config->driver_data;
|
||||
struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[desc->id];
|
||||
int ret;
|
||||
|
||||
rpdata->en_gpiod = devm_fwnode_get_index_gpiod_from_child(tps->dev,
|
||||
"enable", 0, &np->fwnode, 0, "enable");
|
||||
if (IS_ERR(rpdata->en_gpiod)) {
|
||||
ret = PTR_ERR(rpdata->en_gpiod);
|
||||
|
||||
/* Ignore the error other than probe defer */
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rpdata->act_dis_gpiod = devm_fwnode_get_index_gpiod_from_child(
|
||||
tps->dev, "active-discharge", 0,
|
||||
&np->fwnode, 0, "active-discharge");
|
||||
if (IS_ERR(rpdata->act_dis_gpiod)) {
|
||||
ret = PTR_ERR(rpdata->act_dis_gpiod);
|
||||
|
||||
/* Ignore the error other than probe defer */
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "ti,active-discharge-time-us",
|
||||
&rpdata->act_dis_time_us);
|
||||
if (ret < 0) {
|
||||
dev_err(tps->dev, "Failed to read active discharge time:%d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TPS65132_REGULATOR_DESC(_id, _name) \
|
||||
[TPS65132_REGULATOR_ID_##_id] = { \
|
||||
.name = "tps65132-"#_name, \
|
||||
.supply_name = "vin", \
|
||||
.id = TPS65132_REGULATOR_ID_##_id, \
|
||||
.of_match = of_match_ptr(#_name), \
|
||||
.of_parse_cb = tps65132_of_parse_cb, \
|
||||
.ops = &tps65132_regulator_ops, \
|
||||
.n_voltages = TPS65132_VOUT_N_VOLTAGE, \
|
||||
.min_uV = TPS65132_VOUT_VMIN, \
|
||||
.uV_step = TPS65132_VOUT_STEP, \
|
||||
.enable_time = 500, \
|
||||
.vsel_mask = TPS65132_VOUT_MASK, \
|
||||
.vsel_reg = TPS65132_REG_##_id, \
|
||||
.active_discharge_off = 0, \
|
||||
.active_discharge_on = TPS65132_REG_APPS_DIS_##_id, \
|
||||
.active_discharge_mask = TPS65132_REG_APPS_DIS_##_id, \
|
||||
.active_discharge_reg = TPS65132_REG_APPS_DISP_DISN, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
static struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = {
|
||||
TPS65132_REGULATOR_DESC(VPOS, outp),
|
||||
TPS65132_REGULATOR_DESC(VNEG, outn),
|
||||
};
|
||||
|
||||
static const struct regmap_range tps65132_no_reg_ranges[] = {
|
||||
regmap_reg_range(TPS65132_REG_APPS_DISP_DISN + 1,
|
||||
TPS65132_REG_CONTROL - 1),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tps65132_no_reg_table = {
|
||||
.no_ranges = tps65132_no_reg_ranges,
|
||||
.n_no_ranges = ARRAY_SIZE(tps65132_no_reg_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config tps65132_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = TPS65132_REG_CONTROL,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.rd_table = &tps65132_no_reg_table,
|
||||
.wr_table = &tps65132_no_reg_table,
|
||||
};
|
||||
|
||||
static int tps65132_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *client_id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct tps65132_regulator *tps;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
int ret;
|
||||
|
||||
tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
|
||||
tps->rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config);
|
||||
if (IS_ERR(tps->rmap)) {
|
||||
ret = PTR_ERR(tps->rmap);
|
||||
dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, tps);
|
||||
tps->dev = dev;
|
||||
|
||||
for (id = 0; id < TPS65132_MAX_REGULATORS; ++id) {
|
||||
tps->rdesc[id] = &tps_regs_desc[id];
|
||||
|
||||
config.regmap = tps->rmap;
|
||||
config.dev = dev;
|
||||
config.driver_data = tps;
|
||||
|
||||
tps->rdev[id] = devm_regulator_register(dev,
|
||||
tps->rdesc[id], &config);
|
||||
if (IS_ERR(tps->rdev[id])) {
|
||||
ret = PTR_ERR(tps->rdev[id]);
|
||||
dev_err(dev, "regulator %s register failed: %d\n",
|
||||
tps->rdesc[id]->name, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps65132_id[] = {
|
||||
{.name = "tps65132",},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tps65132_id);
|
||||
|
||||
static struct i2c_driver tps65132_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tps65132",
|
||||
},
|
||||
.probe = tps65132_probe,
|
||||
.id_table = tps65132_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(tps65132_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("tps65132 regulator driver");
|
||||
MODULE_AUTHOR("Venkat Reddy Talla <vreddytalla@nvidia.com>");
|
||||
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -456,8 +456,6 @@ static int twl6030smps_map_voltage(struct regulator_dev *rdev, int min_uV,
|
||||
vsel = 60;
|
||||
else if ((min_uV > 1350000) && (min_uV <= 1500000))
|
||||
vsel = 59;
|
||||
else if ((min_uV > 1300000) && (min_uV <= 1350000))
|
||||
vsel = 58;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
546
drivers/regulator/vctrl-regulator.c
Normal file
546
drivers/regulator/vctrl-regulator.c
Normal file
@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Driver for voltage controller regulators
|
||||
*
|
||||
* Copyright (C) 2017 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
struct vctrl_voltage_range {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
};
|
||||
|
||||
struct vctrl_voltage_ranges {
|
||||
struct vctrl_voltage_range ctrl;
|
||||
struct vctrl_voltage_range out;
|
||||
};
|
||||
|
||||
struct vctrl_voltage_table {
|
||||
int ctrl;
|
||||
int out;
|
||||
int ovp_min_sel;
|
||||
};
|
||||
|
||||
struct vctrl_data {
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_desc desc;
|
||||
struct regulator *ctrl_reg;
|
||||
bool enabled;
|
||||
unsigned int min_slew_down_rate;
|
||||
unsigned int ovp_threshold;
|
||||
struct vctrl_voltage_ranges vrange;
|
||||
struct vctrl_voltage_table *vtable;
|
||||
unsigned int sel;
|
||||
};
|
||||
|
||||
static int vctrl_calc_ctrl_voltage(struct vctrl_data *vctrl, int out_uV)
|
||||
{
|
||||
struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
|
||||
struct vctrl_voltage_range *out = &vctrl->vrange.out;
|
||||
|
||||
return ctrl->min_uV +
|
||||
DIV_ROUND_CLOSEST_ULL((s64)(out_uV - out->min_uV) *
|
||||
(ctrl->max_uV - ctrl->min_uV),
|
||||
out->max_uV - out->min_uV);
|
||||
}
|
||||
|
||||
static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
|
||||
{
|
||||
struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
|
||||
struct vctrl_voltage_range *out = &vctrl->vrange.out;
|
||||
|
||||
if (ctrl_uV < 0) {
|
||||
pr_err("vctrl: failed to get control voltage\n");
|
||||
return ctrl_uV;
|
||||
}
|
||||
|
||||
if (ctrl_uV < ctrl->min_uV)
|
||||
return out->min_uV;
|
||||
|
||||
if (ctrl_uV > ctrl->max_uV)
|
||||
return out->max_uV;
|
||||
|
||||
return out->min_uV +
|
||||
DIV_ROUND_CLOSEST_ULL((s64)(ctrl_uV - ctrl->min_uV) *
|
||||
(out->max_uV - out->min_uV),
|
||||
ctrl->max_uV - ctrl->min_uV);
|
||||
}
|
||||
|
||||
static int vctrl_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
|
||||
|
||||
return vctrl_calc_output_voltage(vctrl, ctrl_uV);
|
||||
}
|
||||
|
||||
static int vctrl_set_voltage(struct regulator_dev *rdev,
|
||||
int req_min_uV, int req_max_uV,
|
||||
unsigned int *selector)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
struct regulator *ctrl_reg = vctrl->ctrl_reg;
|
||||
int orig_ctrl_uV = regulator_get_voltage(ctrl_reg);
|
||||
int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
|
||||
int ret;
|
||||
|
||||
if (req_min_uV >= uV || !vctrl->ovp_threshold)
|
||||
/* voltage rising or no OVP */
|
||||
return regulator_set_voltage(
|
||||
ctrl_reg,
|
||||
vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
|
||||
vctrl_calc_ctrl_voltage(vctrl, req_max_uV));
|
||||
|
||||
while (uV > req_min_uV) {
|
||||
int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
|
||||
int next_uV;
|
||||
int next_ctrl_uV;
|
||||
int delay;
|
||||
|
||||
/* Make sure no infinite loop even in crazy cases */
|
||||
if (max_drop_uV == 0)
|
||||
max_drop_uV = 1;
|
||||
|
||||
next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
|
||||
next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
|
||||
|
||||
ret = regulator_set_voltage(ctrl_reg,
|
||||
next_ctrl_uV,
|
||||
next_ctrl_uV);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
delay = DIV_ROUND_UP(uV - next_uV, vctrl->min_slew_down_rate);
|
||||
usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
|
||||
|
||||
uV = next_uV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
/* Try to go back to original voltage */
|
||||
regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vctrl_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
|
||||
return vctrl->sel;
|
||||
}
|
||||
|
||||
static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
struct regulator *ctrl_reg = vctrl->ctrl_reg;
|
||||
unsigned int orig_sel = vctrl->sel;
|
||||
int ret;
|
||||
|
||||
if (selector >= rdev->desc->n_voltages)
|
||||
return -EINVAL;
|
||||
|
||||
if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
|
||||
/* voltage rising or no OVP */
|
||||
ret = regulator_set_voltage(ctrl_reg,
|
||||
vctrl->vtable[selector].ctrl,
|
||||
vctrl->vtable[selector].ctrl);
|
||||
if (!ret)
|
||||
vctrl->sel = selector;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (vctrl->sel != selector) {
|
||||
unsigned int next_sel;
|
||||
int delay;
|
||||
|
||||
if (selector >= vctrl->vtable[vctrl->sel].ovp_min_sel)
|
||||
next_sel = selector;
|
||||
else
|
||||
next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
|
||||
|
||||
ret = regulator_set_voltage(ctrl_reg,
|
||||
vctrl->vtable[next_sel].ctrl,
|
||||
vctrl->vtable[next_sel].ctrl);
|
||||
if (ret) {
|
||||
dev_err(&rdev->dev,
|
||||
"failed to set control voltage to %duV\n",
|
||||
vctrl->vtable[next_sel].ctrl);
|
||||
goto err;
|
||||
}
|
||||
vctrl->sel = next_sel;
|
||||
|
||||
delay = DIV_ROUND_UP(vctrl->vtable[vctrl->sel].out -
|
||||
vctrl->vtable[next_sel].out,
|
||||
vctrl->min_slew_down_rate);
|
||||
usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (vctrl->sel != orig_sel) {
|
||||
/* Try to go back to original voltage */
|
||||
if (!regulator_set_voltage(ctrl_reg,
|
||||
vctrl->vtable[orig_sel].ctrl,
|
||||
vctrl->vtable[orig_sel].ctrl))
|
||||
vctrl->sel = orig_sel;
|
||||
else
|
||||
dev_warn(&rdev->dev,
|
||||
"failed to restore original voltage\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vctrl_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
|
||||
if (selector >= rdev->desc->n_voltages)
|
||||
return -EINVAL;
|
||||
|
||||
return vctrl->vtable[selector].out;
|
||||
}
|
||||
|
||||
static int vctrl_parse_dt(struct platform_device *pdev,
|
||||
struct vctrl_data *vctrl)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
u32 pval;
|
||||
u32 vrange_ctrl[2];
|
||||
|
||||
vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl");
|
||||
if (IS_ERR(vctrl->ctrl_reg))
|
||||
return PTR_ERR(vctrl->ctrl_reg);
|
||||
|
||||
ret = of_property_read_u32(np, "ovp-threshold-percent", &pval);
|
||||
if (!ret) {
|
||||
vctrl->ovp_threshold = pval;
|
||||
if (vctrl->ovp_threshold > 100) {
|
||||
dev_err(&pdev->dev,
|
||||
"ovp-threshold-percent (%u) > 100\n",
|
||||
vctrl->ovp_threshold);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "min-slew-down-rate", &pval);
|
||||
if (!ret) {
|
||||
vctrl->min_slew_down_rate = pval;
|
||||
|
||||
/* We use the value as int and as divider; sanity check */
|
||||
if (vctrl->min_slew_down_rate == 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"min-slew-down-rate must not be 0\n");
|
||||
return -EINVAL;
|
||||
} else if (vctrl->min_slew_down_rate > INT_MAX) {
|
||||
dev_err(&pdev->dev, "min-slew-down-rate (%u) too big\n",
|
||||
vctrl->min_slew_down_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vctrl->ovp_threshold && !vctrl->min_slew_down_rate) {
|
||||
dev_err(&pdev->dev,
|
||||
"ovp-threshold-percent requires min-slew-down-rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "regulator-min-microvolt", &pval);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to read regulator-min-microvolt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
vctrl->vrange.out.min_uV = pval;
|
||||
|
||||
ret = of_property_read_u32(np, "regulator-max-microvolt", &pval);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to read regulator-max-microvolt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
vctrl->vrange.out.max_uV = pval;
|
||||
|
||||
ret = of_property_read_u32_array(np, "ctrl-voltage-range", vrange_ctrl,
|
||||
2);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to read ctrl-voltage-range: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vrange_ctrl[0] >= vrange_ctrl[1]) {
|
||||
dev_err(&pdev->dev, "ctrl-voltage-range is invalid: %d-%d\n",
|
||||
vrange_ctrl[0], vrange_ctrl[1]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vctrl->vrange.ctrl.min_uV = vrange_ctrl[0];
|
||||
vctrl->vrange.ctrl.max_uV = vrange_ctrl[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vctrl_cmp_ctrl_uV(const void *a, const void *b)
|
||||
{
|
||||
const struct vctrl_voltage_table *at = a;
|
||||
const struct vctrl_voltage_table *bt = b;
|
||||
|
||||
return at->ctrl - bt->ctrl;
|
||||
}
|
||||
|
||||
static int vctrl_init_vtable(struct platform_device *pdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = platform_get_drvdata(pdev);
|
||||
struct regulator_desc *rdesc = &vctrl->desc;
|
||||
struct regulator *ctrl_reg = vctrl->ctrl_reg;
|
||||
struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl;
|
||||
int n_voltages;
|
||||
int ctrl_uV;
|
||||
int i, idx_vt;
|
||||
|
||||
n_voltages = regulator_count_voltages(ctrl_reg);
|
||||
|
||||
rdesc->n_voltages = n_voltages;
|
||||
|
||||
/* determine number of steps within the range of the vctrl regulator */
|
||||
for (i = 0; i < n_voltages; i++) {
|
||||
ctrl_uV = regulator_list_voltage(ctrl_reg, i);
|
||||
|
||||
if (ctrl_uV < vrange_ctrl->min_uV ||
|
||||
ctrl_uV > vrange_ctrl->max_uV) {
|
||||
rdesc->n_voltages--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rdesc->n_voltages == 0) {
|
||||
dev_err(&pdev->dev, "invalid configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vctrl->vtable = devm_kcalloc(&pdev->dev, rdesc->n_voltages,
|
||||
sizeof(struct vctrl_voltage_table),
|
||||
GFP_KERNEL);
|
||||
if (!vctrl->vtable)
|
||||
return -ENOMEM;
|
||||
|
||||
/* create mapping control <=> output voltage */
|
||||
for (i = 0, idx_vt = 0; i < n_voltages; i++) {
|
||||
ctrl_uV = regulator_list_voltage(ctrl_reg, i);
|
||||
|
||||
if (ctrl_uV < vrange_ctrl->min_uV ||
|
||||
ctrl_uV > vrange_ctrl->max_uV)
|
||||
continue;
|
||||
|
||||
vctrl->vtable[idx_vt].ctrl = ctrl_uV;
|
||||
vctrl->vtable[idx_vt].out =
|
||||
vctrl_calc_output_voltage(vctrl, ctrl_uV);
|
||||
idx_vt++;
|
||||
}
|
||||
|
||||
/* we rely on the table to be ordered by ascending voltage */
|
||||
sort(vctrl->vtable, rdesc->n_voltages,
|
||||
sizeof(struct vctrl_voltage_table), vctrl_cmp_ctrl_uV,
|
||||
NULL);
|
||||
|
||||
/* pre-calculate OVP-safe downward transitions */
|
||||
for (i = rdesc->n_voltages - 1; i > 0; i--) {
|
||||
int j;
|
||||
int ovp_min_uV = (vctrl->vtable[i].out *
|
||||
(100 - vctrl->ovp_threshold)) / 100;
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
if (vctrl->vtable[j].out >= ovp_min_uV) {
|
||||
vctrl->vtable[i].ovp_min_sel = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == i) {
|
||||
dev_warn(&pdev->dev, "switching down from %duV may cause OVP shutdown\n",
|
||||
vctrl->vtable[i].out);
|
||||
/* use next lowest voltage */
|
||||
vctrl->vtable[i].ovp_min_sel = i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vctrl_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
int ret = regulator_enable(vctrl->ctrl_reg);
|
||||
|
||||
if (!ret)
|
||||
vctrl->enabled = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vctrl_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
int ret = regulator_disable(vctrl->ctrl_reg);
|
||||
|
||||
if (!ret)
|
||||
vctrl->enabled = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vctrl_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
|
||||
|
||||
return vctrl->enabled;
|
||||
}
|
||||
|
||||
static const struct regulator_ops vctrl_ops_cont = {
|
||||
.enable = vctrl_enable,
|
||||
.disable = vctrl_disable,
|
||||
.is_enabled = vctrl_is_enabled,
|
||||
.get_voltage = vctrl_get_voltage,
|
||||
.set_voltage = vctrl_set_voltage,
|
||||
};
|
||||
|
||||
static const struct regulator_ops vctrl_ops_non_cont = {
|
||||
.enable = vctrl_enable,
|
||||
.disable = vctrl_disable,
|
||||
.is_enabled = vctrl_is_enabled,
|
||||
.set_voltage_sel = vctrl_set_voltage_sel,
|
||||
.get_voltage_sel = vctrl_get_voltage_sel,
|
||||
.list_voltage = vctrl_list_voltage,
|
||||
.map_voltage = regulator_map_voltage_iterate,
|
||||
};
|
||||
|
||||
static int vctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct vctrl_data *vctrl;
|
||||
const struct regulator_init_data *init_data;
|
||||
struct regulator_desc *rdesc;
|
||||
struct regulator_config cfg = { };
|
||||
struct vctrl_voltage_range *vrange_ctrl;
|
||||
int ctrl_uV;
|
||||
int ret;
|
||||
|
||||
vctrl = devm_kzalloc(&pdev->dev, sizeof(struct vctrl_data),
|
||||
GFP_KERNEL);
|
||||
if (!vctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, vctrl);
|
||||
|
||||
ret = vctrl_parse_dt(pdev, vctrl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
vrange_ctrl = &vctrl->vrange.ctrl;
|
||||
|
||||
rdesc = &vctrl->desc;
|
||||
rdesc->name = "vctrl";
|
||||
rdesc->type = REGULATOR_VOLTAGE;
|
||||
rdesc->owner = THIS_MODULE;
|
||||
|
||||
if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) ||
|
||||
(regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) {
|
||||
rdesc->continuous_voltage_range = true;
|
||||
rdesc->ops = &vctrl_ops_cont;
|
||||
} else {
|
||||
rdesc->ops = &vctrl_ops_non_cont;
|
||||
}
|
||||
|
||||
init_data = of_get_regulator_init_data(&pdev->dev, np, rdesc);
|
||||
if (!init_data)
|
||||
return -ENOMEM;
|
||||
|
||||
cfg.of_node = np;
|
||||
cfg.dev = &pdev->dev;
|
||||
cfg.driver_data = vctrl;
|
||||
cfg.init_data = init_data;
|
||||
|
||||
if (!rdesc->continuous_voltage_range) {
|
||||
ret = vctrl_init_vtable(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
|
||||
if (ctrl_uV < 0) {
|
||||
dev_err(&pdev->dev, "failed to get control voltage\n");
|
||||
return ctrl_uV;
|
||||
}
|
||||
|
||||
/* determine current voltage selector from control voltage */
|
||||
if (ctrl_uV < vrange_ctrl->min_uV) {
|
||||
vctrl->sel = 0;
|
||||
} else if (ctrl_uV > vrange_ctrl->max_uV) {
|
||||
vctrl->sel = rdesc->n_voltages - 1;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rdesc->n_voltages; i++) {
|
||||
if (ctrl_uV == vctrl->vtable[i].ctrl) {
|
||||
vctrl->sel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg);
|
||||
if (IS_ERR(vctrl->rdev)) {
|
||||
ret = PTR_ERR(vctrl->rdev);
|
||||
dev_err(&pdev->dev, "failed to register regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id vctrl_of_match[] = {
|
||||
{ .compatible = "vctrl-regulator", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, vctrl_of_match);
|
||||
|
||||
static struct platform_driver vctrl_driver = {
|
||||
.probe = vctrl_probe,
|
||||
.driver = {
|
||||
.name = "vctrl-regulator",
|
||||
.of_match_table = of_match_ptr(vctrl_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(vctrl_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Voltage Controlled Regulator Driver");
|
||||
MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -12,6 +12,8 @@
|
||||
#define _ARIZONA_PDATA_H
|
||||
|
||||
#include <dt-bindings/mfd/arizona.h>
|
||||
#include <linux/regulator/arizona-ldo1.h>
|
||||
#include <linux/regulator/arizona-micsupp.h>
|
||||
|
||||
#define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */
|
||||
#define ARIZONA_GPN_DIR_SHIFT 15 /* GPN_DIR */
|
||||
@ -76,13 +78,12 @@ struct arizona_micd_range {
|
||||
|
||||
struct arizona_pdata {
|
||||
int reset; /** GPIO controlling /RESET, if any */
|
||||
int ldoena; /** GPIO controlling LODENA, if any */
|
||||
|
||||
/** Regulator configuration for MICVDD */
|
||||
struct regulator_init_data *micvdd;
|
||||
struct arizona_micsupp_pdata micvdd;
|
||||
|
||||
/** Regulator configuration for LDO1 */
|
||||
struct regulator_init_data *ldo1;
|
||||
struct arizona_ldo1_pdata ldo1;
|
||||
|
||||
/** If a direct 32kHz clock is provided on an MCLK specify it here */
|
||||
int clk32k_src;
|
||||
|
@ -24,7 +24,7 @@
|
||||
struct regulator_init_data;
|
||||
|
||||
struct isl9305_pdata {
|
||||
struct regulator_init_data *init_data[ISL9305_MAX_REGULATOR];
|
||||
struct regulator_init_data *init_data[ISL9305_MAX_REGULATOR + 1];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
24
include/linux/regulator/arizona-ldo1.h
Normal file
24
include/linux/regulator/arizona-ldo1.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Platform data for Arizona LDO1 regulator
|
||||
*
|
||||
* Copyright 2017 Cirrus Logic
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ARIZONA_LDO1_H
|
||||
#define ARIZONA_LDO1_H
|
||||
|
||||
struct regulator_init_data;
|
||||
|
||||
struct arizona_ldo1_pdata {
|
||||
/** GPIO controlling LDOENA, if any */
|
||||
int ldoena;
|
||||
|
||||
/** Regulator configuration for LDO1 */
|
||||
const struct regulator_init_data *init_data;
|
||||
};
|
||||
|
||||
#endif
|
21
include/linux/regulator/arizona-micsupp.h
Normal file
21
include/linux/regulator/arizona-micsupp.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Platform data for Arizona micsupp regulator
|
||||
*
|
||||
* Copyright 2017 Cirrus Logic
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ARIZONA_MICSUPP_H
|
||||
#define ARIZONA_MICSUPP_H
|
||||
|
||||
struct regulator_init_data;
|
||||
|
||||
struct arizona_micsupp_pdata {
|
||||
/** Regulator configuration for micsupp */
|
||||
const struct regulator_init_data *init_data;
|
||||
};
|
||||
|
||||
#endif
|
@ -119,6 +119,7 @@ struct regmap;
|
||||
#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
|
||||
#define REGULATOR_EVENT_PRE_DISABLE 0x400
|
||||
#define REGULATOR_EVENT_ABORT_DISABLE 0x800
|
||||
#define REGULATOR_EVENT_ENABLE 0x1000
|
||||
|
||||
/*
|
||||
* Regulator errors that can be queried using regulator_get_error_flags
|
||||
|
@ -292,6 +292,14 @@ enum regulator_type {
|
||||
* set_active_discharge
|
||||
* @active_discharge_reg: Register for control when using regmap
|
||||
* set_active_discharge
|
||||
* @soft_start_reg: Register for control when using regmap set_soft_start
|
||||
* @soft_start_mask: Mask for control when using regmap set_soft_start
|
||||
* @soft_start_val_on: Enabling value for control when using regmap
|
||||
* set_soft_start
|
||||
* @pull_down_reg: Register for control when using regmap set_pull_down
|
||||
* @pull_down_mask: Mask for control when using regmap set_pull_down
|
||||
* @pull_down_val_on: Enabling value for control when using regmap
|
||||
* set_pull_down
|
||||
*
|
||||
* @enable_time: Time taken for initial enable of regulator (in uS).
|
||||
* @off_on_delay: guard time (in uS), before re-enabling a regulator
|
||||
@ -345,6 +353,12 @@ struct regulator_desc {
|
||||
unsigned int active_discharge_off;
|
||||
unsigned int active_discharge_mask;
|
||||
unsigned int active_discharge_reg;
|
||||
unsigned int soft_start_reg;
|
||||
unsigned int soft_start_mask;
|
||||
unsigned int soft_start_val_on;
|
||||
unsigned int pull_down_reg;
|
||||
unsigned int pull_down_mask;
|
||||
unsigned int pull_down_val_on;
|
||||
|
||||
unsigned int enable_time;
|
||||
|
||||
@ -429,6 +443,8 @@ struct regulator_dev {
|
||||
struct regulator_enable_gpio *ena_pin;
|
||||
unsigned int ena_gpio_state:1;
|
||||
|
||||
unsigned int is_switch:1;
|
||||
|
||||
/* time when this regulator was disabled last time */
|
||||
unsigned long last_off_jiffy;
|
||||
};
|
||||
@ -476,6 +492,8 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int new_selector);
|
||||
int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable);
|
||||
int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable);
|
||||
int regulator_set_soft_start_regmap(struct regulator_dev *rdev);
|
||||
int regulator_set_pull_down_regmap(struct regulator_dev *rdev);
|
||||
|
||||
int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
|
||||
bool enable);
|
||||
|
@ -108,6 +108,8 @@ struct regulator_state {
|
||||
* @initial_state: Suspend state to set by default.
|
||||
* @initial_mode: Mode to set at startup.
|
||||
* @ramp_delay: Time to settle down after voltage change (unit: uV/us)
|
||||
* @settling_time: Time to settle down after voltage change when voltage
|
||||
* change is non-linear (unit: microseconds).
|
||||
* @active_discharge: Enable/disable active discharge. The enum
|
||||
* regulator_active_discharge values are used for
|
||||
* initialisation.
|
||||
@ -149,6 +151,7 @@ struct regulation_constraints {
|
||||
unsigned int initial_mode;
|
||||
|
||||
unsigned int ramp_delay;
|
||||
unsigned int settling_time;
|
||||
unsigned int enable_time;
|
||||
|
||||
unsigned int active_discharge;
|
||||
|
@ -48,6 +48,7 @@
|
||||
#define PFUZE200_VGEN4 10
|
||||
#define PFUZE200_VGEN5 11
|
||||
#define PFUZE200_VGEN6 12
|
||||
#define PFUZE200_COIN 13
|
||||
|
||||
#define PFUZE3000_SW1A 0
|
||||
#define PFUZE3000_SW1B 1
|
||||
|
Loading…
Reference in New Issue
Block a user