summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-10-05 16:54:56 +0100
committerMark Brown <broonie@kernel.org>2020-10-05 16:54:56 +0100
commitc6e70a6fd5ceff381059e600156d78c1b94b7c60 (patch)
treecfbe62ca93677505433a4127632d4b8b74e5bb52 /drivers/regulator
parent549738f15da0e5a00275977623be199fbbf7df50 (diff)
parent184cdb8f6d391b379bb768b0c203600f5657176b (diff)
Merge remote-tracking branch 'regulator/for-5.10' into regulator-next
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/88pg86x.c2
-rw-r--r--drivers/regulator/Kconfig64
-rw-r--r--drivers/regulator/Makefile5
-rw-r--r--drivers/regulator/bd718x7-regulator.c422
-rw-r--r--drivers/regulator/bd9576-regulator.c337
-rw-r--r--drivers/regulator/core.c239
-rw-r--r--drivers/regulator/da9055-regulator.c2
-rw-r--r--drivers/regulator/da9062-regulator.c2
-rw-r--r--drivers/regulator/da9063-regulator.c2
-rw-r--r--drivers/regulator/da9210-regulator.c6
-rw-r--r--drivers/regulator/da9211-regulator.c18
-rw-r--r--drivers/regulator/dbx500-prcmu.c26
-rw-r--r--drivers/regulator/dummy.c4
-rw-r--r--drivers/regulator/fan53555.c2
-rw-r--r--drivers/regulator/fixed.c20
-rw-r--r--drivers/regulator/lochnagar-regulator.c1
-rw-r--r--drivers/regulator/lp8755.c88
-rw-r--r--drivers/regulator/ltc3589.c12
-rw-r--r--drivers/regulator/ltc3676.c12
-rw-r--r--drivers/regulator/max1586.c2
-rw-r--r--drivers/regulator/max77826-regulator.c2
-rw-r--r--drivers/regulator/mp886x.c109
-rw-r--r--drivers/regulator/mt6360-regulator.c459
-rw-r--r--drivers/regulator/pca9450-regulator.c6
-rw-r--r--drivers/regulator/pv88060-regulator.c10
-rw-r--r--drivers/regulator/pv88080-regulator.c10
-rw-r--r--drivers/regulator/pv88090-regulator.c10
-rw-r--r--drivers/regulator/pwm-regulator.c2
-rw-r--r--drivers/regulator/qcom-labibb-regulator.c8
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c2
-rw-r--r--drivers/regulator/qcom_smd-regulator.c167
-rw-r--r--drivers/regulator/qcom_spmi-regulator.c177
-rw-r--r--drivers/regulator/qcom_usb_vbus-regulator.c1
-rw-r--r--drivers/regulator/rpi-panel-attiny-regulator.c214
-rw-r--r--drivers/regulator/rt4801-regulator.c223
-rw-r--r--drivers/regulator/rtmv20-regulator.c397
-rw-r--r--drivers/regulator/s5m8767.c13
-rw-r--r--drivers/regulator/slg51000-regulator.c4
-rw-r--r--drivers/regulator/stm32-booster.c2
-rw-r--r--drivers/regulator/stm32-pwr.c2
-rw-r--r--drivers/regulator/stm32-vrefbuf.c2
-rw-r--r--drivers/regulator/stpmic1_regulator.c4
-rw-r--r--drivers/regulator/stw481x-vmmc.c4
-rw-r--r--drivers/regulator/sy8106a-regulator.c2
-rw-r--r--drivers/regulator/sy8827n.c2
-rw-r--r--drivers/regulator/ti-abb-regulator.c2
-rw-r--r--drivers/regulator/tps51632-regulator.c2
-rw-r--r--drivers/regulator/tps6105x-regulator.c2
-rw-r--r--drivers/regulator/tps62360-regulator.c2
-rw-r--r--drivers/regulator/tps65023-regulator.c2
-rw-r--r--drivers/regulator/tps65086-regulator.c4
-rw-r--r--drivers/regulator/tps65090-regulator.c8
-rw-r--r--drivers/regulator/tps6586x-regulator.c8
-rw-r--r--drivers/regulator/tps65910-regulator.c135
-rw-r--r--drivers/regulator/tps65912-regulator.c4
-rw-r--r--drivers/regulator/wm831x-dcdc.c4
-rw-r--r--drivers/regulator/wm831x-isink.c2
-rw-r--r--drivers/regulator/wm831x-ldo.c2
-rw-r--r--drivers/regulator/wm8350-regulator.c2
59 files changed, 2692 insertions, 585 deletions
diff --git a/drivers/regulator/88pg86x.c b/drivers/regulator/88pg86x.c
index 71cfa2c5de5e..e91d5885c5ef 100644
--- a/drivers/regulator/88pg86x.c
+++ b/drivers/regulator/88pg86x.c
@@ -84,7 +84,7 @@ static int pg86x_i2c_probe(struct i2c_client *i2c)
return 0;
}
-static const struct of_device_id pg86x_dt_ids [] = {
+static const struct of_device_id __maybe_unused pg86x_dt_ids[] = {
{ .compatible = "marvell,88pg867" },
{ .compatible = "marvell,88pg868" },
{ }
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7e18f0..020a00d6696b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -231,6 +231,16 @@ config REGULATOR_BD9571MWV
This driver can also be built as a module. If so, the module
will be called bd9571mwv-regulator.
+config REGULATOR_BD957XMUF
+ tristate "ROHM BD9576MUF and BD9573MUF Regulators"
+ depends on MFD_ROHM_BD957XMUF
+ help
+ This driver supports voltage regulators on ROHM BD9576MUF and
+ BD9573MUF PMICs.
+
+ This driver can also be built as a module. If so, the module
+ will be called bd9576-regulator.
+
config REGULATOR_CPCAP
tristate "Motorola CPCAP regulator"
depends on MFD_CPCAP
@@ -500,7 +510,7 @@ config REGULATOR_MAX1586
config REGULATOR_MAX77620
tristate "Maxim 77620/MAX20024 voltage regulator"
- depends on MFD_MAX77620
+ depends on MFD_MAX77620 || COMPILE_TEST
help
This driver controls Maxim MAX77620 voltage output regulator
via I2C bus. The provided regulator is suitable for Tegra
@@ -509,7 +519,7 @@ config REGULATOR_MAX77620
config REGULATOR_MAX77650
tristate "Maxim MAX77650/77651 regulator support"
- depends on MFD_MAX77650
+ depends on MFD_MAX77650 || COMPILE_TEST
help
Regulator driver for MAX77650/77651 PMIC from Maxim
Semiconductor. This device has a SIMO with three independent
@@ -532,7 +542,7 @@ config REGULATOR_MAX8660
config REGULATOR_MAX8907
tristate "Maxim 8907 voltage regulator"
- depends on MFD_MAX8907
+ depends on MFD_MAX8907 || COMPILE_TEST
help
This driver controls a Maxim 8907 voltage output regulator
via I2C bus. The provided regulator is suitable for Tegra
@@ -582,7 +592,7 @@ config REGULATOR_MAX8998
config REGULATOR_MAX77686
tristate "Maxim 77686 regulator"
- depends on MFD_MAX77686
+ depends on MFD_MAX77686 || COMPILE_TEST
help
This driver controls a Maxim 77686 regulator
via I2C bus. The provided regulator is suitable for
@@ -590,7 +600,7 @@ config REGULATOR_MAX77686
config REGULATOR_MAX77693
tristate "Maxim 77693/77843 regulator"
- depends on (MFD_MAX77693 || MFD_MAX77843)
+ depends on MFD_MAX77693 || MFD_MAX77843 || COMPILE_TEST
help
This driver controls a Maxim 77693/77843 regulators via I2C bus.
The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2'
@@ -599,7 +609,7 @@ config REGULATOR_MAX77693
config REGULATOR_MAX77802
tristate "Maxim 77802 regulator"
- depends on MFD_MAX77686
+ depends on MFD_MAX77686 || COMPILE_TEST
help
This driver controls a Maxim 77802 regulator
via I2C bus. The provided regulator is suitable for
@@ -711,6 +721,15 @@ config REGULATOR_MT6358
This driver supports the control of different power rails of device
through regulator interface.
+config REGULATOR_MT6360
+ tristate "MT6360 SubPMIC Regulator"
+ depends on MFD_MT6360
+ help
+ Say Y here to enable MT6360 regulator support.
+ This is support MT6360 PMIC/LDO part include
+ 2-channel buck with Thermal Shutdown and Overload Protection
+ 6-channel High PSRR and Low Dropout LDO.
+
config REGULATOR_MT6380
tristate "MediaTek MT6380 PMIC"
depends on MTK_PMIC_WRAP
@@ -864,6 +883,16 @@ config REGULATOR_QCOM_USB_VBUS
Say M here if you want to include support for enabling the VBUS output
as a module. The module will be named "qcom_usb_vbus_regulator".
+config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
+ tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator"
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on I2C
+ select REGMAP_I2C
+ help
+ This driver supports ATTINY regulator on the Raspberry Pi 7-inch
+ touchscreen unit. The regulator is used to enable power to the
+ TC358762, display and to control backlight.
+
config REGULATOR_RC5T583
tristate "RICOH RC5T583 Power regulators"
depends on MFD_RC5T583
@@ -894,6 +923,14 @@ config REGULATOR_RN5T618
config REGULATOR_ROHM
tristate
+config REGULATOR_RT4801
+ tristate "Richtek RT4801 Regulators"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ This adds support for voltage regulators in Richtek RT4801 Display Bias IC.
+ The device supports two regulators (DSVP/DSVN).
+
config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
@@ -902,16 +939,25 @@ config REGULATOR_RT5033
RT5033 PMIC. The device supports multiple regulators like
current source, LDO and Buck.
+config REGULATOR_RTMV20
+ tristate "RTMV20 Laser Diode Regulator"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ This driver adds support for the load switch current regulator on
+ the Richtek RTMV20. It can support the load current up to 6A and
+ integrate strobe/vsync/fsin signal to synchronize the IR camera.
+
config REGULATOR_S2MPA01
tristate "Samsung S2MPA01 voltage regulator"
- depends on MFD_SEC_CORE
+ depends on MFD_SEC_CORE || COMPILE_TEST
help
This driver controls Samsung S2MPA01 voltage output regulator
via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
config REGULATOR_S2MPS11
tristate "Samsung S2MPS11/13/14/15/S2MPU02 voltage regulator"
- depends on MFD_SEC_CORE
+ depends on MFD_SEC_CORE || COMPILE_TEST
help
This driver supports a Samsung S2MPS11/13/14/15/S2MPU02 voltage
output regulator via I2C bus. The chip is comprised of high efficient
@@ -920,7 +966,7 @@ config REGULATOR_S2MPS11
config REGULATOR_S5M8767
tristate "Samsung S5M8767A voltage regulator"
- depends on MFD_SEC_CORE
+ depends on MFD_SEC_CORE || COMPILE_TEST
help
This driver supports a Samsung S5M8767A voltage output regulator
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf526a8..6ebae516258e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
+obj-$(CONFIG_REGULATOR_BD957XMUF) += bd9576-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x-regulator.o
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
+obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
@@ -107,11 +109,14 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o
obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
+obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY) += rpi-panel-attiny-regulator.o
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o
+obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
+obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c
index 7b311389f925..0774467994fb 100644
--- a/drivers/regulator/bd718x7-regulator.c
+++ b/drivers/regulator/bd718x7-regulator.c
@@ -16,6 +16,39 @@
#include <linux/slab.h>
/*
+ * BD718(37/47/50) have two "enable control modes". ON/OFF can either be
+ * controlled by software - or by PMIC internal HW state machine. Whether
+ * regulator should be under SW or HW control can be defined from device-tree.
+ * Let's provide separate ops for regulators to use depending on the "enable
+ * control mode".
+ */
+#define BD718XX_HWOPNAME(swopname) swopname##_hwcontrol
+
+#define BD718XX_OPS(name, _list_voltage, _map_voltage, _set_voltage_sel, \
+ _get_voltage_sel, _set_voltage_time_sel, _set_ramp_delay) \
+static const struct regulator_ops name = { \
+ .enable = regulator_enable_regmap, \
+ .disable = regulator_disable_regmap, \
+ .is_enabled = regulator_is_enabled_regmap, \
+ .list_voltage = (_list_voltage), \
+ .map_voltage = (_map_voltage), \
+ .set_voltage_sel = (_set_voltage_sel), \
+ .get_voltage_sel = (_get_voltage_sel), \
+ .set_voltage_time_sel = (_set_voltage_time_sel), \
+ .set_ramp_delay = (_set_ramp_delay), \
+}; \
+ \
+static const struct regulator_ops BD718XX_HWOPNAME(name) = { \
+ .is_enabled = always_enabled_by_hwstate, \
+ .list_voltage = (_list_voltage), \
+ .map_voltage = (_map_voltage), \
+ .set_voltage_sel = (_set_voltage_sel), \
+ .get_voltage_sel = (_get_voltage_sel), \
+ .set_voltage_time_sel = (_set_voltage_time_sel), \
+ .set_ramp_delay = (_set_ramp_delay), \
+} \
+
+/*
* BUCK1/2/3/4
* BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
* 00: 10.00mV/usec 10mV 1uS
@@ -55,6 +88,38 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
BUCK_RAMPRATE_MASK, ramp_value << 6);
}
+/* These functions are used when regulators are under HW state machine control.
+ * We assume PMIC is in RUN state because SW running and able to query the
+ * status. Most of the regulators have fixed ON or OFF state at RUN/IDLE so for
+ * them we just return a constant. BD71837 BUCK3 and BUCK4 are exceptions as
+ * they support configuring the ON/OFF state for RUN.
+ *
+ * Note for next hacker - these PMICs have a register where the HW state can be
+ * read. If assuming RUN appears to be false in your use-case - you can
+ * implement state reading (although that is not going to be atomic) before
+ * returning the enable state.
+ */
+static int always_enabled_by_hwstate(struct regulator_dev *rdev)
+{
+ return 1;
+}
+
+static int never_enabled_by_hwstate(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static int bd71837_get_buck34_enable_hwctrl(struct regulator_dev *rdev)
+{
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
+ if (ret)
+ return ret;
+
+ return !!(BD718XX_BUCK_RUN_ON & val);
+}
/*
* On BD71837 (not on BD71847, BD71850, ...)
* Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
@@ -71,7 +136,7 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
unsigned int sel)
{
- if (regulator_is_enabled_regmap(rdev))
+ if (rdev->desc->ops->is_enabled(rdev))
return -EBUSY;
return regulator_set_voltage_sel_regmap(rdev, sel);
@@ -113,7 +178,7 @@ static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel,
int ret;
*mask = 0;
- if (regulator_is_enabled_regmap(rdev)) {
+ if (rdev->desc->ops->is_enabled(rdev)) {
int now, new;
now = rdev->desc->ops->get_voltage_sel(rdev);
@@ -195,133 +260,90 @@ static int bd718xx_set_voltage_sel_pickable_restricted(
static int bd71837_set_voltage_sel_pickable_restricted(
struct regulator_dev *rdev, unsigned int sel)
{
- if (regulator_is_enabled_regmap(rdev))
+ if (rdev->desc->ops->is_enabled(rdev))
return -EBUSY;
return regulator_set_voltage_sel_pickable_regmap(rdev, sel);
}
-static const struct regulator_ops bd718xx_pickable_range_ldo_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
+/*
+ * OPS common for BD71847 and BD71850
+ */
+BD718XX_OPS(bd718xx_pickable_range_ldo_ops,
+ regulator_list_voltage_pickable_linear_range, NULL,
+ bd718xx_set_voltage_sel_pickable_restricted,
+ regulator_get_voltage_sel_pickable_regmap, NULL, NULL);
+
+/* BD71847 and BD71850 LDO 5 is by default OFF at RUN state */
+static const struct regulator_ops bd718xx_ldo5_ops_hwstate = {
+ .is_enabled = never_enabled_by_hwstate,
.list_voltage = regulator_list_voltage_pickable_linear_range,
.set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
-
};
-static const struct regulator_ops bd71837_pickable_range_ldo_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_pickable_linear_range,
- .set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
-};
-
-static const struct regulator_ops bd718xx_pickable_range_buck_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_pickable_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
-
-static const struct regulator_ops bd71837_pickable_range_buck_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_pickable_linear_range,
- .set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
-
-static const struct regulator_ops bd71837_ldo_regulator_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .set_voltage_sel = bd71837_set_voltage_sel_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
-};
-
-static const struct regulator_ops bd718xx_ldo_regulator_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .set_voltage_sel = bd718xx_set_voltage_sel_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
-};
-
-static const struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_table,
- .set_voltage_sel = bd71837_set_voltage_sel_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
-};
-
-static const struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_table,
- .set_voltage_sel = bd718xx_set_voltage_sel_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
-};
+BD718XX_OPS(bd718xx_pickable_range_buck_ops,
+ regulator_list_voltage_pickable_linear_range, NULL,
+ regulator_set_voltage_sel_pickable_regmap,
+ regulator_get_voltage_sel_pickable_regmap,
+ regulator_set_voltage_time_sel, NULL);
-static const struct regulator_ops bd718xx_buck_regulator_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
+BD718XX_OPS(bd718xx_ldo_regulator_ops, regulator_list_voltage_linear_range,
+ NULL, bd718xx_set_voltage_sel_restricted,
+ regulator_get_voltage_sel_regmap, NULL, NULL);
-static const struct regulator_ops bd71837_buck_regulator_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .set_voltage_sel = bd71837_set_voltage_sel_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
+BD718XX_OPS(bd718xx_ldo_regulator_nolinear_ops, regulator_list_voltage_table,
+ NULL, bd718xx_set_voltage_sel_restricted,
+ regulator_get_voltage_sel_regmap, NULL, NULL);
-static const struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_ascend,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
+BD718XX_OPS(bd718xx_buck_regulator_ops, regulator_list_voltage_linear_range,
+ NULL, regulator_set_voltage_sel_regmap,
+ regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
+ NULL);
-static const struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_ascend,
- .set_voltage_sel = bd718xx_set_voltage_sel_restricted,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_time_sel = regulator_set_voltage_time_sel,
-};
+BD718XX_OPS(bd718xx_buck_regulator_nolinear_ops, regulator_list_voltage_table,
+ regulator_map_voltage_ascend, regulator_set_voltage_sel_regmap,
+ regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
+ NULL);
-static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
+/*
+ * OPS for BD71837
+ */
+BD718XX_OPS(bd71837_pickable_range_ldo_ops,
+ regulator_list_voltage_pickable_linear_range, NULL,
+ bd71837_set_voltage_sel_pickable_restricted,
+ regulator_get_voltage_sel_pickable_regmap, NULL, NULL);
+
+BD718XX_OPS(bd71837_pickable_range_buck_ops,
+ regulator_list_voltage_pickable_linear_range, NULL,
+ bd71837_set_voltage_sel_pickable_restricted,
+ regulator_get_voltage_sel_pickable_regmap,
+ regulator_set_voltage_time_sel, NULL);
+
+BD718XX_OPS(bd71837_ldo_regulator_ops, regulator_list_voltage_linear_range,
+ NULL, bd71837_set_voltage_sel_restricted,
+ regulator_get_voltage_sel_regmap, NULL, NULL);
+
+BD718XX_OPS(bd71837_ldo_regulator_nolinear_ops, regulator_list_voltage_table,
+ NULL, bd71837_set_voltage_sel_restricted,
+ regulator_get_voltage_sel_regmap, NULL, NULL);
+
+BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range,
+ NULL, bd71837_set_voltage_sel_restricted,
+ regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
+ NULL);
+
+BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table,
+ regulator_map_voltage_ascend, bd718xx_set_voltage_sel_restricted,
+ regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
+ NULL);
+/*
+ * BD71837 bucks 3 and 4 support defining their enable/disable state also
+ * when buck enable state is under HW state machine control. In that case the
+ * bit [2] in CTRL register is used to indicate if regulator should be ON.
+ */
+static const struct regulator_ops bd71837_buck34_ops_hwctrl = {
+ .is_enabled = bd71837_get_buck34_enable_hwctrl,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@@ -330,6 +352,14 @@ static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
};
/*
+ * OPS for all of the ICs - BD718(37/47/50)
+ */
+BD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range,
+ NULL, regulator_set_voltage_sel_regmap,
+ regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
+ bd718xx_buck1234_set_ramp_delay);
+
+/*
* BD71837 BUCK1/2/3/4
* BD71847 BUCK1/2
* 0.70 to 1.30V (10mV step)
@@ -543,14 +573,37 @@ static int buck_set_hw_dvs_levels(struct device_node *np,
return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
}
-static const struct bd718xx_regulator_data bd71847_regulators[] = {
+static const struct regulator_ops *bd71847_swcontrol_ops[] = {
+ &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops,
+ &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops,
+ &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops,
+ &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_nolinear_ops,
+ &bd718xx_ldo_regulator_ops, &bd718xx_ldo_regulator_ops,
+ &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops,
+};
+
+static const struct regulator_ops *bd71847_hwcontrol_ops[] = {
+ &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
+ &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
+ &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops),
+ &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops),
+ &BD718XX_HWOPNAME(bd718xx_buck_regulator_nolinear_ops),
+ &BD718XX_HWOPNAME(bd718xx_buck_regulator_ops),
+ &BD718XX_HWOPNAME(bd718xx_pickable_range_ldo_ops),
+ &BD718XX_HWOPNAME(bd718xx_ldo_regulator_nolinear_ops),
+ &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops),
+ &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops),
+ &bd718xx_ldo5_ops_hwstate,
+ &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops),
+};
+
+static struct bd718xx_regulator_data bd71847_regulators[] = {
{
.desc = {
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK1,
- .ops = &bd718xx_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_dvs_buck_volts,
@@ -585,7 +638,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK2,
- .ops = &bd718xx_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_dvs_buck_volts,
@@ -616,7 +668,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK3,
- .ops = &bd718xx_pickable_range_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71847_BUCK3_VOLTAGE_NUM,
.linear_ranges = bd71847_buck3_volts,
@@ -643,7 +694,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK4,
- .ops = &bd718xx_pickable_range_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71847_BUCK4_VOLTAGE_NUM,
.linear_ranges = bd71847_buck4_volts,
@@ -670,7 +720,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK5,
- .ops = &bd718xx_buck_regulator_nolinear_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
.n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
@@ -692,7 +741,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK6"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK6,
- .ops = &bd718xx_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_4th_nodvs_buck_volts,
@@ -716,7 +764,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO1,
- .ops = &bd718xx_pickable_range_ldo_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo1_volts,
@@ -742,7 +789,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO2,
- .ops = &bd718xx_ldo_regulator_nolinear_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &ldo_2_volts[0],
.vsel_reg = BD718XX_REG_LDO2_VOLT,
@@ -764,7 +810,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO3,
- .ops = &bd718xx_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo3_volts,
@@ -787,7 +832,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO4,
- .ops = &bd718xx_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo4_volts,
@@ -810,7 +854,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO5,
- .ops = &bd718xx_pickable_range_ldo_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71847_LDO5_VOLTAGE_NUM,
.linear_ranges = bd71847_ldo5_volts,
@@ -836,7 +879,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO6"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO6,
- .ops = &bd718xx_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo6_volts,
@@ -857,14 +899,41 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
},
};
-static const struct bd718xx_regulator_data bd71837_regulators[] = {
+static const struct regulator_ops *bd71837_swcontrol_ops[] = {
+ &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops,
+ &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops,
+ &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops,
+ &bd71837_buck_regulator_nolinear_ops, &bd71837_buck_regulator_ops,
+ &bd71837_pickable_range_ldo_ops, &bd71837_ldo_regulator_nolinear_ops,
+ &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops,
+ &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops,
+ &bd71837_ldo_regulator_ops,
+};
+
+static const struct regulator_ops *bd71837_hwcontrol_ops[] = {
+ &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
+ &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
+ &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl,
+ &BD718XX_HWOPNAME(bd71837_pickable_range_buck_ops),
+ &BD718XX_HWOPNAME(bd71837_buck_regulator_ops),
+ &BD718XX_HWOPNAME(bd71837_buck_regulator_nolinear_ops),
+ &BD718XX_HWOPNAME(bd71837_buck_regulator_ops),
+ &BD718XX_HWOPNAME(bd71837_pickable_range_ldo_ops),
+ &BD718XX_HWOPNAME(bd71837_ldo_regulator_nolinear_ops),
+ &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
+ &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
+ &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
+ &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
+ &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
+};
+
+static struct bd718xx_regulator_data bd71837_regulators[] = {
{
.desc = {
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK1,
- .ops = &bd718xx_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_dvs_buck_volts,
@@ -898,7 +967,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK2,
- .ops = &bd718xx_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_dvs_buck_volts,
@@ -929,7 +997,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK3,
- .ops = &bd718xx_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_dvs_buck_volts,
@@ -958,7 +1025,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK4,
- .ops = &bd718xx_dvs_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_dvs_buck_volts,
@@ -987,7 +1053,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK5,
- .ops = &bd71837_pickable_range_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
.linear_ranges = bd71837_buck5_volts,
@@ -1014,7 +1079,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK6"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK6,
- .ops = &bd71837_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
.linear_ranges = bd71837_buck6_volts,
@@ -1038,7 +1102,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK7"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK7,
- .ops = &bd71837_buck_regulator_nolinear_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
.n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
@@ -1060,7 +1123,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK8"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK8,
- .ops = &bd71837_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
.linear_ranges = bd718xx_4th_nodvs_buck_volts,
@@ -1084,7 +1146,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO1,
- .ops = &bd71837_pickable_range_ldo_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo1_volts,
@@ -1110,7 +1171,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO2,
- .ops = &bd71837_ldo_regulator_nolinear_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &ldo_2_volts[0],
.vsel_reg = BD718XX_REG_LDO2_VOLT,
@@ -1132,7 +1192,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO3,
- .ops = &bd71837_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo3_volts,
@@ -1155,7 +1214,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO4,
- .ops = &bd71837_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo4_volts,
@@ -1178,7 +1236,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO5,
- .ops = &bd71837_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71837_LDO5_VOLTAGE_NUM,
.linear_ranges = bd71837_ldo5_volts,
@@ -1205,7 +1262,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO6"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO6,
- .ops = &bd71837_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo6_volts,
@@ -1232,7 +1288,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO7"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO7,
- .ops = &bd71837_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71837_LDO7_VOLTAGE_NUM,
.linear_ranges = bd71837_ldo7_volts,
@@ -1251,15 +1306,57 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
},
};
+static void mark_hw_controlled(struct device *dev, struct device_node *np,
+ struct bd718xx_regulator_data *reg_data,
+ unsigned int num_reg_data, int *info)
+{
+ int i;
+
+ for (i = 1; i <= num_reg_data; i++) {
+ if (!of_node_name_eq(np, reg_data[i-1].desc.of_match))
+ continue;
+
+ *info |= 1 << (i - 1);
+ dev_dbg(dev, "regulator %d runlevel controlled\n", i);
+ return;
+ }
+ dev_warn(dev, "Bad regulator node\n");
+}
+
+static int get_hw_controlled_regulators(struct device *dev,
+ struct bd718xx_regulator_data *reg_data,
+ unsigned int num_reg_data, int *info)
+{
+ struct device_node *np;
+ struct device_node *nproot = dev->of_node;
+ const char *prop = "rohm,no-regulator-enable-control";
+
+ *info = 0;
+
+ nproot = of_get_child_by_name(nproot, "regulators");
+ if (!nproot) {
+ dev_err(dev, "failed to find regulators node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np)
+ if (of_property_read_bool(np, prop))
+ mark_hw_controlled(dev, np, reg_data, num_reg_data,
+ info);
+
+ of_node_put(nproot);
+ return 0;
+}
+
static int bd718xx_probe(struct platform_device *pdev)
{
struct bd718xx *mfd;
struct regulator_config config = { 0 };
- int i, j, err;
+ int i, j, err, omit_enable;
bool use_snvs;
- const struct bd718xx_regulator_data *reg_data;
+ struct bd718xx_regulator_data *reg_data;
unsigned int num_reg_data;
enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
+ const struct regulator_ops **swops, **hwops;
mfd = dev_get_drvdata(pdev->dev.parent);
if (!mfd) {
@@ -1272,10 +1369,14 @@ static int bd718xx_probe(struct platform_device *pdev)
case ROHM_CHIP_TYPE_BD71837:
reg_data = bd71837_regulators;
num_reg_data = ARRAY_SIZE(bd71837_regulators);
+ swops = &bd71837_swcontrol_ops[0];
+ hwops = &bd71837_hwcontrol_ops[0];
break;
case ROHM_CHIP_TYPE_BD71847:
reg_data = bd71847_regulators;
num_reg_data = ARRAY_SIZE(bd71847_regulators);
+ swops = &bd71847_swcontrol_ops[0];
+ hwops = &bd71847_hwcontrol_ops[0];
break;
default:
dev_err(&pdev->dev, "Unsupported chip type\n");
@@ -1319,17 +1420,35 @@ static int bd718xx_probe(struct platform_device *pdev)
}
}
+ config.dev = pdev->dev.parent;
+ config.regmap = mfd->chip.regmap;
+ /*
+ * There are cases when we want to leave the enable-control for
+ * the HW state machine and use this driver only for voltage control.
+ * One special case is when we use PMIC_STBY_REQ line from SoC to PMIC
+ * in order to set the system to SUSPEND state.
+ *
+ * If regulator is taken under SW control the regulator state will not
+ * be affected by PMIC state machine - Eg. regulator is likely to stay
+ * on even in SUSPEND
+ */
+ get_hw_controlled_regulators(pdev->dev.parent, reg_data, num_reg_data,
+ &omit_enable);
+
for (i = 0; i < num_reg_data; i++) {
- const struct regulator_desc *desc;
+ struct regulator_desc *desc;
struct regulator_dev *rdev;
- const struct bd718xx_regulator_data *r;
+ struct bd718xx_regulator_data *r;
+ int no_enable_control = omit_enable & (1 << i);
r = &reg_data[i];
desc = &r->desc;
- config.dev = pdev->dev.parent;
- config.regmap = mfd->chip.regmap;
+ if (no_enable_control)
+ desc->ops = hwops[i];
+ else
+ desc->ops = swops[i];
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
@@ -1356,8 +1475,9 @@ static int bd718xx_probe(struct platform_device *pdev)
* enable SW control for crucial regulators if snvs state is
* used
*/
- if (!use_snvs || !rdev->constraints->always_on ||
- !rdev->constraints->boot_on) {
+ if (!no_enable_control && (!use_snvs ||
+ !rdev->constraints->always_on ||
+ !rdev->constraints->boot_on)) {
err = regmap_update_bits(mfd->chip.regmap, r->init.reg,
r->init.mask, r->init.val);
if (err) {
diff --git a/drivers/regulator/bd9576-regulator.c b/drivers/regulator/bd9576-regulator.c
new file mode 100644
index 000000000000..a8b5832a5a1b
--- /dev/null
+++ b/drivers/regulator/bd9576-regulator.c
@@ -0,0 +1,337 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2020 ROHM Semiconductors
+// ROHM BD9576MUF/BD9573MUF regulator driver
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/rohm-bd957x.h>
+#include <linux/mfd/rohm-generic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+
+#define BD957X_VOUTS1_VOLT 3300000
+#define BD957X_VOUTS4_BASE_VOLT 1030000
+#define BD957X_VOUTS34_NUM_VOLT 32
+
+static int vout1_volt_table[] = {5000000, 4900000, 4800000, 4700000, 4600000,
+ 4500000, 4500000, 4500000, 5000000, 5100000,
+ 5200000, 5300000, 5400000, 5500000, 5500000,
+ 5500000};
+
+static int vout2_volt_table[] = {1800000, 1780000, 1760000, 1740000, 1720000,
+ 1700000, 1680000, 1660000, 1800000, 1820000,
+ 1840000, 1860000, 1880000, 1900000, 1920000,
+ 1940000};
+
+static int voutl1_volt_table[] = {2500000, 2540000, 2580000, 2620000, 2660000,
+ 2700000, 2740000, 2780000, 2500000, 2460000,
+ 2420000, 2380000, 2340000, 2300000, 2260000,
+ 2220000};
+
+struct bd957x_regulator_data {
+ struct regulator_desc desc;
+ int base_voltage;
+};
+
+static int bd957x_vout34_list_voltage(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ const struct regulator_desc *desc = rdev->desc;
+ int multiplier = selector & desc->vsel_mask & 0x7f;
+ int tune;
+
+ /* VOUT3 and 4 has 10mV step */
+ tune = multiplier * 10000;
+
+ if (!(selector & 0x80))
+ return desc->fixed_uV - tune;
+
+ return desc->fixed_uV + tune;
+}
+
+static int bd957x_list_voltage(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ const struct regulator_desc *desc = rdev->desc;
+ int index = selector & desc->vsel_mask & 0x7f;
+
+ if (!(selector & 0x80))
+ index += desc->n_voltages/2;
+
+ if (index >= desc->n_voltages)
+ return -EINVAL;
+
+ return desc->volt_table[index];
+}
+
+static const struct regulator_ops bd957x_vout34_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = bd957x_vout34_list_voltage,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static const struct regulator_ops bd957X_vouts1_regulator_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops bd957x_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = bd957x_list_voltage,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static struct bd957x_regulator_data bd9576_regulators[] = {
+ {
+ .desc = {
+ .name = "VD50",
+ .of_match = of_match_ptr("regulator-vd50"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD957X_VD50,
+ .type = REGULATOR_VOLTAGE,
+ .ops = &bd957x_ops,
+ .volt_table = &vout1_volt_table[0],
+ .n_voltages = ARRAY_SIZE(vout1_volt_table),
+ .vsel_reg = BD957X_REG_VOUT1_TUNE,
+ .vsel_mask = BD957X_MASK_VOUT1_TUNE,
+ .enable_reg = BD957X_REG_POW_TRIGGER1,
+ .enable_mask = BD957X_REGULATOR_EN_MASK,
+ .enable_val = BD957X_REGULATOR_DIS_VAL,
+ .enable_is_inverted = true,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "VD18",
+ .of_match = of_match_ptr("regulator-vd18"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD957X_VD18,
+ .type = REGULATOR_VOLTAGE,
+ .ops = &bd957x_ops,
+ .volt_table = &vout2_volt_table[0],
+ .n_voltages = ARRAY_SIZE(vout2_volt_table),
+ .vsel_reg = BD957X_REG_VOUT2_TUNE,
+ .vsel_mask = BD957X_MASK_VOUT2_TUNE,
+ .enable_reg = BD957X_REG_POW_TRIGGER2,
+ .enable_mask = BD957X_REGULATOR_EN_MASK,
+ .enable_val = BD957X_REGULATOR_DIS_VAL,
+ .enable_is_inverted = true,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "VDDDR",
+ .of_match = of_match_ptr("regulator-vdddr"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD957X_VDDDR,
+ .ops = &bd957x_vout34_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = BD957X_VOUTS34_NUM_VOLT,
+ .vsel_reg = BD957X_REG_VOUT3_TUNE,
+ .vsel_mask = BD957X_MASK_VOUT3_TUNE,
+ .enable_reg = BD957X_REG_POW_TRIGGER3,
+ .enable_mask = BD957X_REGULATOR_EN_MASK,
+ .enable_val = BD957X_REGULATOR_DIS_VAL,
+ .enable_is_inverted = true,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "VD10",
+ .of_match = of_match_ptr("regulator-vd10"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD957X_VD10,
+ .ops = &bd957x_vout34_ops,
+ .type = REGULATOR_VOLTAGE,
+ .fixed_uV = BD957X_VOUTS4_BASE_VOLT,
+ .n_voltages = BD957X_VOUTS34_NUM_VOLT,
+ .vsel_reg = BD957X_REG_VOUT4_TUNE,
+ .vsel_mask = BD957X_MASK_VOUT4_TUNE,
+ .enable_reg = BD957X_REG_POW_TRIGGER4,
+ .enable_mask = BD957X_REGULATOR_EN_MASK,
+ .enable_val = BD957X_REGULATOR_DIS_VAL,
+ .enable_is_inverted = true,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "VOUTL1",
+ .of_match = of_match_ptr("regulator-voutl1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD957X_VOUTL1,
+ .ops = &bd957x_ops,
+ .type = REGULATOR_VOLTAGE,
+ .volt_table = &voutl1_volt_table[0],
+ .n_voltages = ARRAY_SIZE(voutl1_volt_table),
+ .vsel_reg = BD957X_REG_VOUTL1_TUNE,
+ .vsel_mask = BD957X_MASK_VOUTL1_TUNE,
+ .enable_reg = BD957X_REG_POW_TRIGGERL1,
+ .enable_mask = BD957X_REGULATOR_EN_MASK,
+ .enable_val = BD957X_REGULATOR_DIS_VAL,
+ .enable_is_inverted = true,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "VOUTS1",
+ .of_match = of_match_ptr("regulator-vouts1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD957X_VOUTS1,
+ .ops = &bd957X_vouts1_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 1,
+ .fixed_uV = BD957X_VOUTS1_VOLT,
+ .enable_reg = BD957X_REG_POW_TRIGGERS1,
+ .enable_mask = BD957X_REGULATOR_EN_MASK,
+ .enable_val = BD957X_REGULATOR_DIS_VAL,
+ .enable_is_inverted = true,
+ .owner = THIS_MODULE,
+ },
+ },
+};
+
+static int bd957x_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+ struct regulator_config config = { 0 };
+ int i, err;
+ bool vout_mode, ddr_sel;
+ const struct bd957x_regulator_data *reg_data = &bd9576_regulators[0];
+ unsigned int num_reg_data = ARRAY_SIZE(bd9576_regulators);
+ enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
+
+ regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!regmap) {
+ dev_err(&pdev->dev, "No regmap\n");
+ return -EINVAL;
+ }
+ vout_mode = of_property_read_bool(pdev->dev.parent->of_node,
+ "rohm,vout1-en-low");
+ if (vout_mode) {
+ struct gpio_desc *en;
+
+ dev_dbg(&pdev->dev, "GPIO controlled mode\n");
+
+ /* VOUT1 enable state judged by VOUT1_EN pin */
+ /* See if we have GPIO defined */
+ en = devm_gpiod_get_from_of_node(&pdev->dev,
+ pdev->dev.parent->of_node,
+ "rohm,vout1-en-gpios", 0,
+ GPIOD_OUT_LOW, "vout1-en");
+ if (!IS_ERR(en)) {
+ /* VOUT1_OPS gpio ctrl */
+ /*
+ * Regulator core prioritizes the ena_gpio over
+ * enable/disable/is_enabled callbacks so no need to
+ * clear them. We can still use same ops
+ */
+ config.ena_gpiod = en;
+ } else {
+ /*
+ * In theory it is possible someone wants to set
+ * vout1-en LOW during OTP loading and set VOUT1 to be
+ * controlled by GPIO - but control the GPIO from some
+ * where else than this driver. For that to work we
+ * should unset the is_enabled callback here.
+ *
+ * I believe such case where rohm,vout1-en-low is set
+ * and vout1-en-gpios is not is likely to be a
+ * misconfiguration. So let's just err out for now.
+ */
+ dev_err(&pdev->dev,
+ "Failed to get VOUT1 control GPIO\n");
+ return PTR_ERR(en);
+ }
+ }
+
+ /*
+ * If more than one PMIC needs to be controlled by same processor then
+ * allocate the regulator data array here and use bd9576_regulators as
+ * template. At the moment I see no such use-case so I spare some
+ * bytes and use bd9576_regulators directly for non-constant configs
+ * like DDR voltage selection.
+ */
+ ddr_sel = of_property_read_bool(pdev->dev.parent->of_node,
+ "rohm,ddr-sel-low");
+ if (ddr_sel)
+ bd9576_regulators[2].desc.fixed_uV = 1350000;
+ else
+ bd9576_regulators[2].desc.fixed_uV = 1500000;
+
+ switch (chip) {
+ case ROHM_CHIP_TYPE_BD9576:
+ dev_dbg(&pdev->dev, "Found BD9576MUF\n");
+ break;
+ case ROHM_CHIP_TYPE_BD9573:
+ dev_dbg(&pdev->dev, "Found BD9573MUF\n");
+ break;
+ default:
+ dev_err(&pdev->dev, "Unsupported chip type\n");
+ err = -EINVAL;
+ goto err;
+ }
+
+ config.dev = pdev->dev.parent;
+ config.regmap = regmap;
+
+ for (i = 0; i < num_reg_data; i++) {
+
+ const struct regulator_desc *desc;
+ struct regulator_dev *rdev;
+ const struct bd957x_regulator_data *r;
+
+ r = &reg_data[i];
+ desc = &r->desc;
+
+ rdev = devm_regulator_register(&pdev->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev,
+ "failed to register %s regulator\n",
+ desc->name);
+ err = PTR_ERR(rdev);
+ goto err;
+ }
+ /*
+ * Clear the VOUT1 GPIO setting - rest of the regulators do not
+ * support GPIO control
+ */
+ config.ena_gpiod = NULL;
+ }
+
+err:
+ return err;
+}
+
+static const struct platform_device_id bd957x_pmic_id[] = {
+ { "bd9573-pmic", ROHM_CHIP_TYPE_BD9573 },
+ { "bd9576-pmic", ROHM_CHIP_TYPE_BD9576 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, bd957x_pmic_id);
+
+static struct platform_driver bd957x_regulator = {
+ .driver = {
+ .name = "bd957x-pmic",
+ },
+ .probe = bd957x_probe,
+ .id_table = bd957x_pmic_id,
+};
+
+module_platform_driver(bd957x_regulator);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("ROHM BD9576/BD9573 voltage regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bd957x-pmic");
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 7ff507ec875a..a4ffd71696da 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -190,11 +190,10 @@ static inline int regulator_lock_nested(struct regulator_dev *rdev,
* than the one, which initially locked the mutex, it will
* wait on mutex.
*/
-void regulator_lock(struct regulator_dev *rdev)
+static void regulator_lock(struct regulator_dev *rdev)
{
regulator_lock_nested(rdev, NULL);
}
-EXPORT_SYMBOL_GPL(regulator_lock);
/**
* regulator_unlock - unlock a single regulator
@@ -203,7 +202,7 @@ EXPORT_SYMBOL_GPL(regulator_lock);
* This function unlocks the mutex when the
* reference counter reaches 0.
*/
-void regulator_unlock(struct regulator_dev *rdev)
+static void regulator_unlock(struct regulator_dev *rdev)
{
mutex_lock(&regulator_nesting_mutex);
@@ -216,7 +215,6 @@ void regulator_unlock(struct regulator_dev *rdev)
mutex_unlock(&regulator_nesting_mutex);
}
-EXPORT_SYMBOL_GPL(regulator_unlock);
static bool regulator_supply_is_couple(struct regulator_dev *rdev)
{
@@ -409,11 +407,11 @@ err_node_put:
static struct device_node *of_get_regulator(struct device *dev, const char *supply)
{
struct device_node *regnode = NULL;
- char prop_name[32]; /* 32 is max size of property name */
+ char prop_name[64]; /* 64 is max size of property name */
dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
- snprintf(prop_name, 32, "%s-supply", supply);
+ snprintf(prop_name, 64, "%s-supply", supply);
regnode = of_parse_phandle(dev->of_node, prop_name, 0);
if (!regnode) {
@@ -568,6 +566,30 @@ regulator_get_suspend_state(struct regulator_dev *rdev, suspend_state_t state)
}
}
+static const struct regulator_state *
+regulator_get_suspend_state_check(struct regulator_dev *rdev, suspend_state_t state)
+{
+ const struct regulator_state *rstate;
+
+ rstate = regulator_get_suspend_state(rdev, state);
+ if (rstate == NULL)
+ return NULL;
+
+ /* If we have no suspend mode configuration don't set anything;
+ * only warn if the driver implements set_suspend_voltage or
+ * set_suspend_mode callback.
+ */
+ if (rstate->enabled != ENABLE_IN_SUSPEND &&
+ rstate->enabled != DISABLE_IN_SUSPEND) {
+ if (rdev->desc->ops->set_suspend_voltage ||
+ rdev->desc->ops->set_suspend_mode)
+ rdev_warn(rdev, "No configuration\n");
+ return NULL;
+ }
+
+ return rstate;
+}
+
static ssize_t regulator_uV_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -945,7 +967,8 @@ static int drms_uA_update(struct regulator_dev *rdev)
/* set the optimum mode for our new total regulator load */
err = rdev->desc->ops->set_load(rdev, current_uA);
if (err < 0)
- rdev_err(rdev, "failed to set load %d\n", current_uA);
+ rdev_err(rdev, "failed to set load %d: %pe\n",
+ current_uA, ERR_PTR(err));
} else {
/* get output voltage */
output_uV = regulator_get_voltage_rdev(rdev);
@@ -972,40 +995,24 @@ static int drms_uA_update(struct regulator_dev *rdev)
/* check the new mode is allowed */
err = regulator_mode_constrain(rdev, &mode);
if (err < 0) {
- rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
- current_uA, input_uV, output_uV);
+ rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV: %pe\n",
+ current_uA, input_uV, output_uV, ERR_PTR(err));
return err;
}
err = rdev->desc->ops->set_mode(rdev, mode);
if (err < 0)
- rdev_err(rdev, "failed to set optimum mode %x\n", mode);
+ rdev_err(rdev, "failed to set optimum mode %x: %pe\n",
+ mode, ERR_PTR(err));
}
return err;
}
-static int suspend_set_state(struct regulator_dev *rdev,
- suspend_state_t state)
+static int __suspend_set_state(struct regulator_dev *rdev,
+ const struct regulator_state *rstate)
{
int ret = 0;
- struct regulator_state *rstate;
-
- rstate = regulator_get_suspend_state(rdev, state);
- if (rstate == NULL)
- return 0;
-
- /* If we have no suspend mode configuration don't set anything;
- * only warn if the driver implements set_suspend_voltage or
- * set_suspend_mode callback.
- */
- if (rstate->enabled != ENABLE_IN_SUSPEND &&
- rstate->enabled != DISABLE_IN_SUSPEND) {
- if (rdev->desc->ops->set_suspend_voltage ||
- rdev->desc->ops->set_suspend_mode)
- rdev_warn(rdev, "No configuration\n");
- return 0;
- }
if (rstate->enabled == ENABLE_IN_SUSPEND &&
rdev->desc->ops->set_suspend_enable)
@@ -1017,14 +1024,14 @@ static int suspend_set_state(struct regulator_dev *rdev,
ret = 0;
if (ret < 0) {
- rdev_err(rdev, "failed to enabled/disable\n");
+ rdev_err(rdev, "failed to enabled/disable: %pe\n", ERR_PTR(ret));
return ret;
}
if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) {
ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV);
if (ret < 0) {
- rdev_err(rdev, "failed to set voltage\n");
+ rdev_err(rdev, "failed to set voltage: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1032,7 +1039,7 @@ static int suspend_set_state(struct regulator_dev *rdev,
if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) {
ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode);
if (ret < 0) {
- rdev_err(rdev, "failed to set mode\n");
+ rdev_err(rdev, "failed to set mode: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1040,7 +1047,20 @@ static int suspend_set_state(struct regulator_dev *rdev,
return ret;
}
-static void print_constraints(struct regulator_dev *rdev)
+static int suspend_set_initial_state(struct regulator_dev *rdev)
+{
+ const struct regulator_state *rstate;
+
+ rstate = regulator_get_suspend_state_check(rdev,
+ rdev->constraints->initial_state);
+ if (!rstate)
+ return 0;
+
+ return __suspend_set_state(rdev, rstate);
+}
+
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+static void print_constraints_debug(struct regulator_dev *rdev)
{
struct regulation_constraints *constraints = rdev->constraints;
char buf[160] = "";
@@ -1097,12 +1117,27 @@ static void print_constraints(struct regulator_dev *rdev)
if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
count += scnprintf(buf + count, len - count, "idle ");
if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
- count += scnprintf(buf + count, len - count, "standby");
+ count += scnprintf(buf + count, len - count, "standby ");
if (!count)
- scnprintf(buf, len, "no parameters");
+ count = scnprintf(buf, len, "no parameters");
+ else
+ --count;
+
+ count += scnprintf(buf + count, len - count, ", %s",
+ _regulator_is_enabled(rdev) ? "enabled" : "disabled");
rdev_dbg(rdev, "%s\n", buf);
+}
+#else /* !DEBUG && !CONFIG_DYNAMIC_DEBUG */
+static inline void print_constraints_debug(struct regulator_dev *rdev) {}
+#endif /* !DEBUG && !CONFIG_DYNAMIC_DEBUG */
+
+static void print_constraints(struct regulator_dev *rdev)
+{
+ struct regulation_constraints *constraints = rdev->constraints;
+
+ print_constraints_debug(rdev);
if ((constraints->min_uV != constraints->max_uV) &&
!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE))
@@ -1135,8 +1170,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
if (current_uV < 0) {
rdev_err(rdev,
- "failed to get the current voltage(%d)\n",
- current_uV);
+ "failed to get the current voltage: %pe\n",
+ ERR_PTR(current_uV));
return current_uV;
}
@@ -1165,8 +1200,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
rdev, target_min, target_max);
if (ret < 0) {
rdev_err(rdev,
- "failed to apply %d-%duV constraint(%d)\n",
- target_min, target_max, ret);
+ "failed to apply %d-%duV constraint: %pe\n",
+ target_min, target_max, ERR_PTR(ret));
return ret;
}
}
@@ -1315,16 +1350,16 @@ static int set_machine_constraints(struct regulator_dev *rdev,
ret = ops->set_input_current_limit(rdev,
rdev->constraints->ilim_uA);
if (ret < 0) {
- rdev_err(rdev, "failed to set input limit\n");
+ rdev_err(rdev, "failed to set input limit: %pe\n", ERR_PTR(ret));
return ret;
}
}
/* do we need to setup our suspend state */
if (rdev->constraints->initial_state) {
- ret = suspend_set_state(rdev, rdev->constraints->initial_state);
+ ret = suspend_set_initial_state(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to set suspend state\n");
+ rdev_err(rdev, "failed to set suspend state: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1337,7 +1372,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
if (ret < 0) {
- rdev_err(rdev, "failed to set initial mode: %d\n", ret);
+ rdev_err(rdev, "failed to set initial mode: %pe\n", ERR_PTR(ret));
return ret;
}
} else if (rdev->constraints->system_load) {
@@ -1352,7 +1387,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
&& ops->set_ramp_delay) {
ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay);
if (ret < 0) {
- rdev_err(rdev, "failed to set ramp_delay\n");
+ rdev_err(rdev, "failed to set ramp_delay: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1360,7 +1395,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
if (rdev->constraints->pull_down && ops->set_pull_down) {
ret = ops->set_pull_down(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to set pull down\n");
+ rdev_err(rdev, "failed to set pull down: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1368,7 +1403,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
if (rdev->constraints->soft_start && ops->set_soft_start) {
ret = ops->set_soft_start(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to set soft start\n");
+ rdev_err(rdev, "failed to set soft start: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1377,7 +1412,8 @@ static int set_machine_constraints(struct regulator_dev *rdev,
&& ops->set_over_current_protection) {
ret = ops->set_over_current_protection(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to set over current protection\n");
+ rdev_err(rdev, "failed to set over current protection: %pe\n",
+ ERR_PTR(ret));
return ret;
}
}
@@ -1388,7 +1424,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
ret = ops->set_active_discharge(rdev, ad_state);
if (ret < 0) {
- rdev_err(rdev, "failed to set active discharge\n");
+ rdev_err(rdev, "failed to set active discharge: %pe\n", ERR_PTR(ret));
return ret;
}
}
@@ -1408,7 +1444,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
ret = _regulator_do_enable(rdev);
if (ret < 0 && ret != -EINVAL) {
- rdev_err(rdev, "failed to enable\n");
+ rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -1632,8 +1668,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
supply_name);
if (err) {
- rdev_dbg(rdev, "could not add device link %s err %d\n",
- dev->kobj.name, err);
+ rdev_dbg(rdev, "could not add device link %s: %pe\n",
+ dev->kobj.name, ERR_PTR(err));
/* non-fatal */
}
}
@@ -2421,7 +2457,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
if (ret >= 0) {
delay = ret;
} else {
- rdev_warn(rdev, "enable_time() failed: %d\n", ret);
+ rdev_warn(rdev, "enable_time() failed: %pe\n", ERR_PTR(ret));
delay = 0;
}
@@ -2610,7 +2646,7 @@ static int _regulator_enable(struct regulator *regulator)
_notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE,
NULL);
} else if (ret < 0) {
- rdev_err(rdev, "is_enabled() failed: %d\n", ret);
+ rdev_err(rdev, "is_enabled() failed: %pe\n", ERR_PTR(ret));
goto err_consumer_disable;
}
/* Fallthrough on positive return values - already enabled */
@@ -2712,7 +2748,7 @@ static int _regulator_disable(struct regulator *regulator)
ret = _regulator_do_disable(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to disable\n");
+ rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret));
_notifier_call_chain(rdev,
REGULATOR_EVENT_ABORT_DISABLE,
NULL);
@@ -2779,7 +2815,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
ret = _regulator_do_disable(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to force disable\n");
+ rdev_err(rdev, "failed to force disable: %pe\n", ERR_PTR(ret));
_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
REGULATOR_EVENT_ABORT_DISABLE, NULL);
return ret;
@@ -2858,7 +2894,8 @@ static void regulator_disable_work(struct work_struct *work)
for (i = 0; i < count; i++) {
ret = _regulator_disable(regulator);
if (ret != 0)
- rdev_err(rdev, "Deferred disable failed: %d\n", ret);
+ rdev_err(rdev, "Deferred disable failed: %pe\n",
+ ERR_PTR(ret));
}
}
WARN_ON(!total_count);
@@ -3051,7 +3088,7 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator,
*vsel_reg = rdev->desc->vsel_reg;
*vsel_mask = rdev->desc->vsel_mask;
- return 0;
+ return 0;
}
EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register);
@@ -3383,7 +3420,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
}
if (delay < 0) {
- rdev_warn(rdev, "failed to get delay: %d\n", delay);
+ rdev_warn(rdev, "failed to get delay: %pe\n", ERR_PTR(delay));
delay = 0;
}
@@ -3535,8 +3572,8 @@ int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
ret = regulator_set_voltage_unlocked(rdev->supply,
best_supply_uV, INT_MAX, state);
if (ret) {
- dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
- ret);
+ dev_err(&rdev->dev, "Failed to increase supply voltage: %pe\n",
+ ERR_PTR(ret));
goto out;
}
}
@@ -3553,8 +3590,8 @@ int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
ret = regulator_set_voltage_unlocked(rdev->supply,
best_supply_uV, INT_MAX, state);
if (ret)
- dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",
- ret);
+ dev_warn(&rdev->dev, "Failed to decrease supply voltage: %pe\n",
+ ERR_PTR(ret));
/* No need to fail here */
ret = 0;
}
@@ -4540,8 +4577,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
err:
if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to get supply '%s': %d\n",
- consumers[i].supply, ret);
+ dev_err(dev, "Failed to get supply '%s': %pe\n",
+ consumers[i].supply, ERR_PTR(ret));
else
dev_dbg(dev, "Failed to get supply '%s', deferring\n",
consumers[i].supply);
@@ -4599,8 +4636,8 @@ int regulator_bulk_enable(int num_consumers,
err:
for (i = 0; i < num_consumers; i++) {
if (consumers[i].ret < 0)
- pr_err("Failed to enable %s: %d\n", consumers[i].supply,
- consumers[i].ret);
+ pr_err("Failed to enable %s: %pe\n", consumers[i].supply,
+ ERR_PTR(consumers[i].ret));
else
regulator_disable(consumers[i].consumer);
}
@@ -4636,12 +4673,12 @@ int regulator_bulk_disable(int num_consumers,
return 0;
err:
- pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
+ pr_err("Failed to disable %s: %pe\n", consumers[i].supply, ERR_PTR(ret));
for (++i; i < num_consumers; ++i) {
r = regulator_enable(consumers[i].consumer);
if (r != 0)
- pr_err("Failed to re-enable %s: %d\n",
- consumers[i].supply, r);
+ pr_err("Failed to re-enable %s: %pe\n",
+ consumers[i].supply, ERR_PTR(r));
}
return ret;
@@ -4709,14 +4746,11 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
* @data: callback-specific data.
*
* Called by regulator drivers to notify clients a regulator event has
- * occurred. We also notify regulator clients downstream.
- * Note lock must be held by caller.
+ * occurred.
*/
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
- lockdep_assert_held_once(&rdev->mutex.base);
-
_notifier_call_chain(rdev, event, data);
return NOTIFY_DONE;
@@ -5023,8 +5057,8 @@ static void regulator_remove_coupling(struct regulator_dev *rdev)
if (coupler && coupler->detach_regulator) {
err = coupler->detach_regulator(coupler, rdev);
if (err)
- rdev_err(rdev, "failed to detach from coupler: %d\n",
- err);
+ rdev_err(rdev, "failed to detach from coupler: %pe\n",
+ ERR_PTR(err));
}
kfree(rdev->coupling_desc.coupled_rdevs);
@@ -5033,20 +5067,20 @@ static void regulator_remove_coupling(struct regulator_dev *rdev)
static int regulator_init_coupling(struct regulator_dev *rdev)
{
+ struct regulator_dev **coupled;
int err, n_phandles;
- size_t alloc_size;
if (!IS_ENABLED(CONFIG_OF))
n_phandles = 0;
else
n_phandles = of_get_n_coupled(rdev);
- alloc_size = sizeof(*rdev) * (n_phandles + 1);
-
- rdev->coupling_desc.coupled_rdevs = kzalloc(alloc_size, GFP_KERNEL);
- if (!rdev->coupling_desc.coupled_rdevs)
+ coupled = kcalloc(n_phandles + 1, sizeof(*coupled), GFP_KERNEL);
+ if (!coupled)
return -ENOMEM;
+ rdev->coupling_desc.coupled_rdevs = coupled;
+
/*
* Every regulator should always have coupling descriptor filled with
* at least pointer to itself.
@@ -5068,7 +5102,7 @@ static int regulator_init_coupling(struct regulator_dev *rdev)
if (IS_ERR(rdev->coupling_desc.coupler)) {
err = PTR_ERR(rdev->coupling_desc.coupler);
- rdev_err(rdev, "failed to get coupler: %d\n", err);
+ rdev_err(rdev, "failed to get coupler: %pe\n", ERR_PTR(err));
return err;
}
@@ -5231,8 +5265,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (config->ena_gpiod) {
ret = regulator_ena_gpio_request(rdev, config);
if (ret != 0) {
- rdev_err(rdev, "Failed to request enable GPIO: %d\n",
- ret);
+ rdev_err(rdev, "Failed to request enable GPIO: %pe\n",
+ ERR_PTR(ret));
goto clean;
}
/* The regulator core took over the GPIO descriptor */
@@ -5256,15 +5290,20 @@ regulator_register(const struct regulator_desc *regulator_desc,
else if (regulator_desc->supply_name)
rdev->supply_name = regulator_desc->supply_name;
- /*
- * Attempt to resolve the regulator supply, if specified,
- * but don't return an error if we fail because we will try
- * to resolve it again later as more regulators are added.
- */
- if (regulator_resolve_supply(rdev))
- rdev_dbg(rdev, "unable to resolve supply\n");
-
ret = set_machine_constraints(rdev, constraints);
+ if (ret == -EPROBE_DEFER) {
+ /* Regulator might be in bypass mode and so needs its supply
+ * to set the constraints */
+ /* FIXME: this currently triggers a chicken-and-egg problem
+ * when creating -SUPPLY symlink in sysfs to a regulator
+ * that is just being created */
+ ret = regulator_resolve_supply(rdev);
+ if (!ret)
+ ret = set_machine_constraints(rdev, constraints);
+ else
+ rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
+ ERR_PTR(ret));
+ }
if (ret < 0)
goto wash;
@@ -5375,9 +5414,14 @@ static int regulator_suspend(struct device *dev)
struct regulator_dev *rdev = dev_to_rdev(dev);
suspend_state_t state = pm_suspend_target_state;
int ret;
+ const struct regulator_state *rstate;
+
+ rstate = regulator_get_suspend_state_check(rdev, state);
+ if (!rstate)
+ return 0;
regulator_lock(rdev);
- ret = suspend_set_state(rdev, state);
+ ret = __suspend_set_state(rdev, rstate);
regulator_unlock(rdev);
return ret;
@@ -5394,11 +5438,14 @@ static int regulator_resume(struct device *dev)
if (rstate == NULL)
return 0;
+ /* Avoid grabbing the lock if we don't need to */
+ if (!rdev->desc->ops->resume)
+ return 0;
+
regulator_lock(rdev);
- if (rdev->desc->ops->resume &&
- (rstate->enabled == ENABLE_IN_SUSPEND ||
- rstate->enabled == DISABLE_IN_SUSPEND))
+ if (rstate->enabled == ENABLE_IN_SUSPEND ||
+ rstate->enabled == DISABLE_IN_SUSPEND)
ret = rdev->desc->ops->resume(rdev);
regulator_unlock(rdev);
@@ -5809,7 +5856,7 @@ static int regulator_late_cleanup(struct device *dev, void *data)
rdev_info(rdev, "disabling\n");
ret = _regulator_do_disable(rdev);
if (ret != 0)
- rdev_err(rdev, "couldn't disable: %d\n", ret);
+ rdev_err(rdev, "couldn't disable: %pe\n", ERR_PTR(ret));
} else {
/* The intention is that in future we will
* assume that full constraints are provided
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c
index c025ccb1a30a..73ff5fc7d8d7 100644
--- a/drivers/regulator/da9055-regulator.c
+++ b/drivers/regulator/da9055-regulator.c
@@ -485,10 +485,8 @@ static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data)
{
struct da9055_regulator *regulator = data;
- regulator_lock(regulator->rdev);
regulator_notifier_call_chain(regulator->rdev,
REGULATOR_EVENT_OVER_CURRENT, NULL);
- regulator_unlock(regulator->rdev);
return IRQ_HANDLED;
}
diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index d8112f56e94e..1a6324001027 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -907,10 +907,8 @@ static irqreturn_t da9062_ldo_lim_event(int irq, void *data)
continue;
if (BIT(regl->info->oc_event.lsb) & bits) {
- regulator_lock(regl->rdev);
regulator_notifier_call_chain(regl->rdev,
REGULATOR_EVENT_OVER_CURRENT, NULL);
- regulator_unlock(regl->rdev);
handled = IRQ_HANDLED;
}
}
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c
index fe65b5acaf28..cf7d5341750e 100644
--- a/drivers/regulator/da9063-regulator.c
+++ b/drivers/regulator/da9063-regulator.c
@@ -574,10 +574,8 @@ static irqreturn_t da9063_ldo_lim_event(int irq, void *data)
continue;
if (BIT(regl->info->oc_event.lsb) & bits) {
- regulator_lock(regl->rdev);
regulator_notifier_call_chain(regl->rdev,
REGULATOR_EVENT_OVER_CURRENT, NULL);
- regulator_unlock(regl->rdev);
}
}
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index 0cdeb6186529..7493af0b5c04 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -77,8 +77,6 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
if (error < 0)
goto error_i2c;
- regulator_lock(chip->rdev);
-
if (val & DA9210_E_OVCURR) {
regulator_notifier_call_chain(chip->rdev,
REGULATOR_EVENT_OVER_CURRENT,
@@ -103,8 +101,6 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
handled |= DA9210_E_VMAX;
}
- regulator_unlock(chip->rdev);
-
if (handled) {
/* Clear handled events */
error = regmap_write(chip->regmap, DA9210_REG_EVENT_B, handled);
@@ -125,7 +121,7 @@ error_i2c:
* I2C driver interface functions
*/
-static const struct of_device_id da9210_dt_ids[] = {
+static const struct of_device_id __maybe_unused da9210_dt_ids[] = {
{ .compatible = "dlg,da9210", },
{ }
};
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index 297b3aa7c753..e01b32d1fa17 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -51,10 +51,24 @@ static const struct regmap_range_cfg da9211_regmap_range[] = {
},
};
+static bool da9211_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case DA9211_REG_STATUS_A:
+ case DA9211_REG_STATUS_B:
+ case DA9211_REG_EVENT_A:
+ case DA9211_REG_EVENT_B:
+ return true;
+ }
+ return false;
+}
+
static const struct regmap_config da9211_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 5 * 128,
+ .volatile_reg = da9211_volatile_reg,
+ .cache_type = REGCACHE_RBTREE,
.ranges = da9211_regmap_range,
.num_ranges = ARRAY_SIZE(da9211_regmap_range),
};
@@ -332,10 +346,8 @@ static irqreturn_t da9211_irq_handler(int irq, void *data)
goto error_i2c;
if (reg_val & DA9211_E_OV_CURR_A) {
- regulator_lock(chip->rdev[0]);
regulator_notifier_call_chain(chip->rdev[0],
REGULATOR_EVENT_OVER_CURRENT, NULL);
- regulator_unlock(chip->rdev[0]);
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
DA9211_E_OV_CURR_A);
@@ -346,10 +358,8 @@ static irqreturn_t da9211_irq_handler(int irq, void *data)
}
if (reg_val & DA9211_E_OV_CURR_B) {
- regulator_lock(chip->rdev[1]);
regulator_notifier_call_chain(chip->rdev[1],
REGULATOR_EVENT_OVER_CURRENT, NULL);
- regulator_unlock(chip->rdev[1]);
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
DA9211_E_OV_CURR_B);
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c
index c3ad6aa6b5d3..8b70bfe88019 100644
--- a/drivers/regulator/dbx500-prcmu.c
+++ b/drivers/regulator/dbx500-prcmu.c
@@ -67,8 +67,6 @@ static int power_state_active_get(void)
static struct ux500_regulator_debug {
struct dentry *dir;
- struct dentry *status_file;
- struct dentry *power_state_cnt_file;
struct dbx500_regulator_info *regulator_array;
int num_regulators;
u8 *state_before_suspend;
@@ -117,22 +115,14 @@ ux500_regulator_debug_init(struct platform_device *pdev,
{
/* create directory */
rdebug.dir = debugfs_create_dir("ux500-regulator", NULL);
- if (!rdebug.dir)
- goto exit_no_debugfs;
/* create "status" file */
- rdebug.status_file = debugfs_create_file("status",
- S_IRUGO, rdebug.dir, &pdev->dev,
- &ux500_regulator_status_fops);
- if (!rdebug.status_file)
- goto exit_destroy_dir;
+ debugfs_create_file("status", S_IRUGO, rdebug.dir, &pdev->dev,
+ &ux500_regulator_status_fops);
/* create "power-state-count" file */
- rdebug.power_state_cnt_file = debugfs_create_file("power-state-count",
- S_IRUGO, rdebug.dir, &pdev->dev,
- &ux500_regulator_power_state_cnt_fops);
- if (!rdebug.power_state_cnt_file)
- goto exit_destroy_status;
+ debugfs_create_file("power-state-count", S_IRUGO, rdebug.dir,
+ &pdev->dev, &ux500_regulator_power_state_cnt_fops);
rdebug.regulator_array = regulator_info;
rdebug.num_regulators = num_regulators;
@@ -150,13 +140,7 @@ ux500_regulator_debug_init(struct platform_device *pdev,
exit_free:
kfree(rdebug.state_before_suspend);
exit_destroy_power_state:
- debugfs_remove(rdebug.power_state_cnt_file);
-exit_destroy_status:
- debugfs_remove(rdebug.status_file);
-exit_destroy_dir:
- debugfs_remove(rdebug.dir);
-exit_no_debugfs:
- dev_err(&pdev->dev, "failed to create debugfs entries.\n");
+ debugfs_remove_recursive(rdebug.dir);
return -ENOMEM;
}
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c
index 74de6983c61a..d8059f596391 100644
--- a/drivers/regulator/dummy.c
+++ b/drivers/regulator/dummy.c
@@ -21,13 +21,13 @@
struct regulator_dev *dummy_regulator_rdev;
-static struct regulator_init_data dummy_initdata = {
+static const struct regulator_init_data dummy_initdata = {
.constraints = {
.always_on = 1,
},
};
-static struct regulator_ops dummy_ops;
+static const struct regulator_ops dummy_ops;
static const struct regulator_desc dummy_desc = {
.name = "regulator-dummy",
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
index 00c83492f774..aa426183b6a1 100644
--- a/drivers/regulator/fan53555.c
+++ b/drivers/regulator/fan53555.c
@@ -436,7 +436,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
return pdata;
}
-static const struct of_device_id fan53555_dt_ids[] = {
+static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
{
.compatible = "fcs,fan53526",
.data = (void *)FAN53526_VENDOR_FAIRCHILD,
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 142a70a89153..3de7709bdcd4 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -41,14 +41,6 @@ struct fixed_dev_type {
bool has_enable_clock;
};
-static const struct fixed_dev_type fixed_voltage_data = {
- .has_enable_clock = false,
-};
-
-static const struct fixed_dev_type fixed_clkenable_data = {
- .has_enable_clock = true,
-};
-
static int reg_clock_enable(struct regulator_dev *rdev)
{
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
@@ -131,10 +123,10 @@ of_get_fixed_voltage_config(struct device *dev,
return config;
}
-static struct regulator_ops fixed_voltage_ops = {
+static const struct regulator_ops fixed_voltage_ops = {
};
-static struct regulator_ops fixed_voltage_clkenabled_ops = {
+static const struct regulator_ops fixed_voltage_clkenabled_ops = {
.enable = reg_clock_enable,
.disable = reg_clock_disable,
.is_enabled = reg_clock_is_enabled,
@@ -260,6 +252,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
}
#if defined(CONFIG_OF)
+static const struct fixed_dev_type fixed_voltage_data = {
+ .has_enable_clock = false,
+};
+
+static const struct fixed_dev_type fixed_clkenable_data = {
+ .has_enable_clock = true,
+};
+
static const struct of_device_id fixed_of_match[] = {
{
.compatible = "regulator-fixed",
diff --git a/drivers/regulator/lochnagar-regulator.c b/drivers/regulator/lochnagar-regulator.c
index 5ea3e4141684..cb71fa5f43c3 100644
--- a/drivers/regulator/lochnagar-regulator.c
+++ b/drivers/regulator/lochnagar-regulator.c
@@ -98,6 +98,7 @@ static const struct regulator_ops lochnagar_vddcore_ops = {
};
static const struct linear_range lochnagar_vddcore_ranges[] = {
+ REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0),
REGULATOR_LINEAR_RANGE(600000, 0x8, 0x41, 12500),
};
diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c
index 4291df077c39..13c535711265 100644
--- a/drivers/regulator/lp8755.c
+++ b/drivers/regulator/lp8755.c
@@ -49,53 +49,15 @@ struct lp8755_chip {
struct regulator_dev *rdev[LP8755_BUCK_MAX];
};
-/**
- *lp8755_read : read a single register value from lp8755.
- *@pchip : device to read from
- *@reg : register to read from
- *@val : pointer to store read value
- */
-static int lp8755_read(struct lp8755_chip *pchip, unsigned int reg,
- unsigned int *val)
-{
- return regmap_read(pchip->regmap, reg, val);
-}
-
-/**
- *lp8755_write : write a single register value to lp8755.
- *@pchip : device to write to
- *@reg : register to write to
- *@val : value to be written
- */
-static int lp8755_write(struct lp8755_chip *pchip, unsigned int reg,
- unsigned int val)
-{
- return regmap_write(pchip->regmap, reg, val);
-}
-
-/**
- *lp8755_update_bits : set the values of bit fields in lp8755 register.
- *@pchip : device to read from
- *@reg : register to update
- *@mask : bitmask to be changed
- *@val : value for bitmask
- */
-static int lp8755_update_bits(struct lp8755_chip *pchip, unsigned int reg,
- unsigned int mask, unsigned int val)
-{
- return regmap_update_bits(pchip->regmap, reg, mask, val);
-}
-
static int lp8755_buck_enable_time(struct regulator_dev *rdev)
{
int ret;
unsigned int regval;
enum lp8755_bucks id = rdev_get_id(rdev);
- struct lp8755_chip *pchip = rdev_get_drvdata(rdev);
- ret = lp8755_read(pchip, 0x12 + id, &regval);
+ ret = regmap_read(rdev->regmap, 0x12 + id, &regval);
if (ret < 0) {
- dev_err(pchip->dev, "i2c access error %s\n", __func__);
+ dev_err(&rdev->dev, "i2c access error %s\n", __func__);
return ret;
}
return (regval & 0xff) * 100;
@@ -115,17 +77,17 @@ static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
break;
case REGULATOR_MODE_NORMAL:
/* enable automatic pwm/pfm mode */
- ret = lp8755_update_bits(pchip, 0x08 + id, 0x20, 0x00);
+ ret = regmap_update_bits(rdev->regmap, 0x08 + id, 0x20, 0x00);
if (ret < 0)
goto err_i2c;
break;
case REGULATOR_MODE_IDLE:
/* enable automatic pwm/pfm/lppfm mode */
- ret = lp8755_update_bits(pchip, 0x08 + id, 0x20, 0x20);
+ ret = regmap_update_bits(rdev->regmap, 0x08 + id, 0x20, 0x20);
if (ret < 0)
goto err_i2c;
- ret = lp8755_update_bits(pchip, 0x10, 0x01, 0x01);
+ ret = regmap_update_bits(rdev->regmap, 0x10, 0x01, 0x01);
if (ret < 0)
goto err_i2c;
break;
@@ -135,12 +97,12 @@ static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
regbval = (0x01 << id);
}
- ret = lp8755_update_bits(pchip, 0x06, 0x01 << id, regbval);
+ ret = regmap_update_bits(rdev->regmap, 0x06, 0x01 << id, regbval);
if (ret < 0)
goto err_i2c;
return ret;
err_i2c:
- dev_err(pchip->dev, "i2c access error %s\n", __func__);
+ dev_err(&rdev->dev, "i2c access error %s\n", __func__);
return ret;
}
@@ -149,9 +111,8 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev)
int ret;
unsigned int regval;
enum lp8755_bucks id = rdev_get_id(rdev);
- struct lp8755_chip *pchip = rdev_get_drvdata(rdev);
- ret = lp8755_read(pchip, 0x06, &regval);
+ ret = regmap_read(rdev->regmap, 0x06, &regval);
if (ret < 0)
goto err_i2c;
@@ -159,7 +120,7 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev)
if (regval & (0x01 << id))
return REGULATOR_MODE_FAST;
- ret = lp8755_read(pchip, 0x08 + id, &regval);
+ ret = regmap_read(rdev->regmap, 0x08 + id, &regval);
if (ret < 0)
goto err_i2c;
@@ -171,7 +132,7 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
err_i2c:
- dev_err(pchip->dev, "i2c access error %s\n", __func__);
+ dev_err(&rdev->dev, "i2c access error %s\n", __func__);
return 0;
}
@@ -180,7 +141,6 @@ static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp)
int ret;
unsigned int regval = 0x00;
enum lp8755_bucks id = rdev_get_id(rdev);
- struct lp8755_chip *pchip = rdev_get_drvdata(rdev);
/* uV/us */
switch (ramp) {
@@ -209,17 +169,17 @@ static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp)
regval = 0x00;
break;
default:
- dev_err(pchip->dev,
+ dev_err(&rdev->dev,
"Not supported ramp value %d %s\n", ramp, __func__);
return -EINVAL;
}
- ret = lp8755_update_bits(pchip, 0x07 + id, 0x07, regval);
+ ret = regmap_update_bits(rdev->regmap, 0x07 + id, 0x07, regval);
if (ret < 0)
goto err_i2c;
return ret;
err_i2c:
- dev_err(pchip->dev, "i2c access error %s\n", __func__);
+ dev_err(&rdev->dev, "i2c access error %s\n", __func__);
return ret;
}
@@ -278,7 +238,7 @@ static int lp8755_init_data(struct lp8755_chip *pchip)
struct lp8755_platform_data *pdata = pchip->pdata;
/* read back muti-phase configuration */
- ret = lp8755_read(pchip, 0x3D, &regval);
+ ret = regmap_read(pchip->regmap, 0x3D, &regval);
if (ret < 0)
goto out_i2c_error;
pchip->mphase = regval & 0x0F;
@@ -356,11 +316,11 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
struct lp8755_chip *pchip = data;
/* read flag0 register */
- ret = lp8755_read(pchip, 0x0D, &flag0);
+ ret = regmap_read(pchip->regmap, 0x0D, &flag0);
if (ret < 0)
goto err_i2c;
/* clear flag register to pull up int. pin */
- ret = lp8755_write(pchip, 0x0D, 0x00);
+ ret = regmap_write(pchip->regmap, 0x0D, 0x00);
if (ret < 0)
goto err_i2c;
@@ -369,19 +329,17 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
if ((flag0 & (0x4 << icnt))
&& (pchip->irqmask & (0x04 << icnt))
&& (pchip->rdev[icnt] != NULL)) {
- regulator_lock(pchip->rdev[icnt]);
regulator_notifier_call_chain(pchip->rdev[icnt],
LP8755_EVENT_PWR_FAULT,
NULL);
- regulator_unlock(pchip->rdev[icnt]);
}
/* read flag1 register */
- ret = lp8755_read(pchip, 0x0E, &flag1);
+ ret = regmap_read(pchip->regmap, 0x0E, &flag1);
if (ret < 0)
goto err_i2c;
/* clear flag register to pull up int. pin */
- ret = lp8755_write(pchip, 0x0E, 0x00);
+ ret = regmap_write(pchip->regmap, 0x0E, 0x00);
if (ret < 0)
goto err_i2c;
@@ -389,22 +347,18 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
if ((flag1 & 0x01) && (pchip->irqmask & 0x01))
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
if (pchip->rdev[icnt] != NULL) {
- regulator_lock(pchip->rdev[icnt]);
regulator_notifier_call_chain(pchip->rdev[icnt],
LP8755_EVENT_OCP,
NULL);
- regulator_unlock(pchip->rdev[icnt]);
}
/* send OVP event to all regulator devices */
if ((flag1 & 0x02) && (pchip->irqmask & 0x02))
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
if (pchip->rdev[icnt] != NULL) {
- regulator_lock(pchip->rdev[icnt]);
regulator_notifier_call_chain(pchip->rdev[icnt],
LP8755_EVENT_OVP,
NULL);
- regulator_unlock(pchip->rdev[icnt]);
}
return IRQ_HANDLED;
@@ -423,7 +377,7 @@ static int lp8755_int_config(struct lp8755_chip *pchip)
return 0;
}
- ret = lp8755_read(pchip, 0x0F, &regval);
+ ret = regmap_read(pchip->regmap, 0x0F, &regval);
if (ret < 0) {
dev_err(pchip->dev, "i2c access error %s\n", __func__);
return ret;
@@ -502,7 +456,7 @@ static int lp8755_probe(struct i2c_client *client,
err:
/* output disable */
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
- lp8755_write(pchip, icnt, 0x00);
+ regmap_write(pchip->regmap, icnt, 0x00);
return ret;
}
@@ -513,7 +467,7 @@ static int lp8755_remove(struct i2c_client *client)
struct lp8755_chip *pchip = i2c_get_clientdata(client);
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
- lp8755_write(pchip, icnt, 0x00);
+ regmap_write(pchip->regmap, icnt, 0x00);
return 0;
}
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 9a037fdc5fc5..38f7ccb63b52 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -357,22 +357,16 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id)
if (irqstat & LTC3589_IRQSTAT_THERMAL_WARN) {
event = REGULATOR_EVENT_OVER_TEMP;
- for (i = 0; i < LTC3589_NUM_REGULATORS; i++) {
- regulator_lock(ltc3589->regulators[i]);
+ for (i = 0; i < LTC3589_NUM_REGULATORS; i++)
regulator_notifier_call_chain(ltc3589->regulators[i],
event, NULL);
- regulator_unlock(ltc3589->regulators[i]);
- }
}
if (irqstat & LTC3589_IRQSTAT_UNDERVOLT_WARN) {
event = REGULATOR_EVENT_UNDER_VOLTAGE;
- for (i = 0; i < LTC3589_NUM_REGULATORS; i++) {
- regulator_lock(ltc3589->regulators[i]);
+ for (i = 0; i < LTC3589_NUM_REGULATORS; i++)
regulator_notifier_call_chain(ltc3589->regulators[i],
event, NULL);
- regulator_unlock(ltc3589->regulators[i]);
- }
}
/* Clear warning condition */
@@ -457,7 +451,7 @@ static const struct i2c_device_id ltc3589_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);
-static const struct of_device_id ltc3589_of_match[] = {
+static const struct of_device_id __maybe_unused ltc3589_of_match[] = {
{
.compatible = "lltc,ltc3589",
.data = (void *)LTC3589,
diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c
index 093b3e4a6303..eb3d6bed6d54 100644
--- a/drivers/regulator/ltc3676.c
+++ b/drivers/regulator/ltc3676.c
@@ -276,23 +276,17 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id)
if (irqstat & LTC3676_IRQSTAT_THERMAL_WARN) {
dev_warn(dev, "Over-temperature Warning\n");
event = REGULATOR_EVENT_OVER_TEMP;
- for (i = 0; i < LTC3676_NUM_REGULATORS; i++) {
- regulator_lock(ltc3676->regulators[i]);
+ for (i = 0; i < LTC3676_NUM_REGULATORS; i++)
regulator_notifier_call_chain(ltc3676->regulators[i],
event, NULL);
- regulator_unlock(ltc3676->regulators[i]);
- }
}
if (irqstat & LTC3676_IRQSTAT_UNDERVOLT_WARN) {
dev_info(dev, "Undervoltage Warning\n");
event = REGULATOR_EVENT_UNDER_VOLTAGE;
- for (i = 0; i < LTC3676_NUM_REGULATORS; i++) {
- regulator_lock(ltc3676->regulators[i]);
+ for (i = 0; i < LTC3676_NUM_REGULATORS; i++)
regulator_notifier_call_chain(ltc3676->regulators[i],
event, NULL);
- regulator_unlock(ltc3676->regulators[i]);
- }
}
/* Clear warning condition */
@@ -368,7 +362,7 @@ 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[] = {
+static const struct of_device_id __maybe_unused ltc3676_of_match[] = {
{ .compatible = "lltc,ltc3676" },
{ },
};
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index f8941025780b..d4958394e608 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -201,7 +201,7 @@ static int of_get_max1586_platform_data(struct device *dev,
return 0;
}
-static const struct of_device_id max1586_of_match[] = {
+static const struct of_device_id __maybe_unused max1586_of_match[] = {
{ .compatible = "maxim,max1586", },
{},
};
diff --git a/drivers/regulator/max77826-regulator.c b/drivers/regulator/max77826-regulator.c
index 502ab6afc814..f9e2e884ff54 100644
--- a/drivers/regulator/max77826-regulator.c
+++ b/drivers/regulator/max77826-regulator.c
@@ -274,7 +274,7 @@ static int max77826_i2c_probe(struct i2c_client *client)
return max77826_read_device_id(regmap, dev);
}
-static const struct of_device_id max77826_of_match[] = {
+static const struct of_device_id __maybe_unused max77826_of_match[] = {
{ .compatible = "maxim,max77826" },
{ /* sentinel */ }
};
diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c
index d3d475f717f4..a84fd74081de 100644
--- a/drivers/regulator/mp886x.c
+++ b/drivers/regulator/mp886x.c
@@ -18,18 +18,70 @@
#define MP886X_V_BOOT (1 << 7)
#define MP886X_SYSCNTLREG1 0x01
#define MP886X_MODE (1 << 0)
+#define MP886X_SLEW_SHIFT 3
+#define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT)
#define MP886X_GO (1 << 6)
#define MP886X_EN (1 << 7)
+#define MP8869_SYSCNTLREG2 0x02
+
+struct mp886x_cfg_info {
+ const struct regulator_ops *rops;
+ const int slew_rates[8];
+ const int switch_freq[4];
+ const u8 fs_reg;
+ const u8 fs_shift;
+};
struct mp886x_device_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_init_data *regulator;
struct gpio_desc *en_gpio;
+ const struct mp886x_cfg_info *ci;
u32 r[2];
unsigned int sel;
};
+static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp)
+{
+ struct mp886x_device_info *di = rdev_get_drvdata(rdev);
+ const struct mp886x_cfg_info *ci = di->ci;
+ int reg = -1, i;
+
+ for (i = 0; i < ARRAY_SIZE(ci->slew_rates); i++) {
+ if (ramp <= ci->slew_rates[i])
+ reg = i;
+ else
+ break;
+ }
+
+ if (reg < 0) {
+ dev_err(di->dev, "unsupported ramp value %d\n", ramp);
+ return -EINVAL;
+ }
+
+ return regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
+ MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT);
+}
+
+static void mp886x_set_switch_freq(struct mp886x_device_info *di,
+ struct regmap *regmap,
+ u32 freq)
+{
+ const struct mp886x_cfg_info *ci = di->ci;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) {
+ if (freq == ci->switch_freq[i]) {
+ regmap_update_bits(regmap, ci->fs_reg,
+ 0x3 << ci->fs_shift, i << ci->fs_shift);
+ return;
+ }
+ }
+
+ dev_err(di->dev, "invalid frequency %d\n", freq);
+}
+
static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
switch (mode) {
@@ -117,6 +169,29 @@ static const struct regulator_ops mp8869_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp886x_set_mode,
.get_mode = mp886x_get_mode,
+ .set_ramp_delay = mp886x_set_ramp,
+};
+
+static const struct mp886x_cfg_info mp8869_ci = {
+ .rops = &mp8869_regulator_ops,
+ .slew_rates = {
+ 40000,
+ 30000,
+ 20000,
+ 10000,
+ 5000,
+ 2500,
+ 1250,
+ 625,
+ },
+ .switch_freq = {
+ 500000,
+ 750000,
+ 1000000,
+ 1250000,
+ },
+ .fs_reg = MP8869_SYSCNTLREG2,
+ .fs_shift = 4,
};
static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
@@ -173,6 +248,29 @@ static const struct regulator_ops mp8867_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp886x_set_mode,
.get_mode = mp886x_get_mode,
+ .set_ramp_delay = mp886x_set_ramp,
+};
+
+static const struct mp886x_cfg_info mp8867_ci = {
+ .rops = &mp8867_regulator_ops,
+ .slew_rates = {
+ 64000,
+ 32000,
+ 16000,
+ 8000,
+ 4000,
+ 2000,
+ 1000,
+ 500,
+ },
+ .switch_freq = {
+ 500000,
+ 750000,
+ 1000000,
+ 1500000,
+ },
+ .fs_reg = MP886X_SYSCNTLREG1,
+ .fs_shift = 1,
};
static int mp886x_regulator_register(struct mp886x_device_info *di,
@@ -183,7 +281,7 @@ static int mp886x_regulator_register(struct mp886x_device_info *di,
rdesc->name = "mp886x-reg";
rdesc->supply_name = "vin";
- rdesc->ops = of_device_get_match_data(di->dev);
+ rdesc->ops = di->ci->rops;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->n_voltages = 128;
rdesc->enable_reg = MP886X_SYSCNTLREG1;
@@ -213,6 +311,7 @@ static int mp886x_i2c_probe(struct i2c_client *client)
struct mp886x_device_info *di;
struct regulator_config config = { };
struct regmap *regmap;
+ u32 freq;
int ret;
di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL);
@@ -234,6 +333,7 @@ static int mp886x_i2c_probe(struct i2c_client *client)
if (IS_ERR(di->en_gpio))
return PTR_ERR(di->en_gpio);
+ di->ci = of_device_get_match_data(dev);
di->dev = dev;
regmap = devm_regmap_init_i2c(client, &mp886x_regmap_config);
@@ -249,6 +349,9 @@ static int mp886x_i2c_probe(struct i2c_client *client)
config.driver_data = di;
config.of_node = np;
+ if (!of_property_read_u32(np, "mps,switch-frequency-hz", &freq))
+ mp886x_set_switch_freq(di, regmap, freq);
+
ret = mp886x_regulator_register(di, &config);
if (ret < 0)
dev_err(dev, "Failed to register regulator!\n");
@@ -258,11 +361,11 @@ static int mp886x_i2c_probe(struct i2c_client *client)
static const struct of_device_id mp886x_dt_ids[] = {
{
.compatible = "mps,mp8867",
- .data = &mp8867_regulator_ops
+ .data = &mp8867_ci
},
{
.compatible = "mps,mp8869",
- .data = &mp8869_regulator_ops
+ .data = &mp8869_ci
},
{ }
};
diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c
new file mode 100644
index 000000000000..15308ee29c13
--- /dev/null
+++ b/drivers/regulator/mt6360-regulator.c
@@ -0,0 +1,459 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 MediaTek Inc.
+//
+// Author: Gene Chen <gene_chen@richtek.com>
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+
+enum {
+ MT6360_REGULATOR_BUCK1 = 0,
+ MT6360_REGULATOR_BUCK2,
+ MT6360_REGULATOR_LDO6,
+ MT6360_REGULATOR_LDO7,
+ MT6360_REGULATOR_LDO1,
+ MT6360_REGULATOR_LDO2,
+ MT6360_REGULATOR_LDO3,
+ MT6360_REGULATOR_LDO5,
+ MT6360_REGULATOR_MAX,
+};
+
+struct mt6360_irq_mapping {
+ const char *name;
+ irq_handler_t handler;
+};
+
+struct mt6360_regulator_desc {
+ const struct regulator_desc desc;
+ unsigned int mode_reg;
+ unsigned int mode_mask;
+ unsigned int state_reg;
+ unsigned int state_mask;
+ const struct mt6360_irq_mapping *irq_tables;
+ int irq_table_size;
+};
+
+struct mt6360_regulator_data {
+ struct device *dev;
+ struct regmap *regmap;
+};
+
+static irqreturn_t mt6360_pgb_event_handler(int irq, void *data)
+{
+ struct regulator_dev *rdev = data;
+
+ regulator_notifier_call_chain(rdev, REGULATOR_EVENT_FAIL, NULL);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mt6360_oc_event_handler(int irq, void *data)
+{
+ struct regulator_dev *rdev = data;
+
+ regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mt6360_ov_event_handler(int irq, void *data)
+{
+ struct regulator_dev *rdev = data;
+
+ regulator_notifier_call_chain(rdev, REGULATOR_EVENT_REGULATION_OUT, NULL);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mt6360_uv_event_handler(int irq, void *data)
+{
+ struct regulator_dev *rdev = data;
+
+ regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, NULL);
+ return IRQ_HANDLED;
+}
+
+static const struct mt6360_irq_mapping buck1_irq_tbls[] = {
+ { "buck1_pgb_evt", mt6360_pgb_event_handler },
+ { "buck1_oc_evt", mt6360_oc_event_handler },
+ { "buck1_ov_evt", mt6360_ov_event_handler },
+ { "buck1_uv_evt", mt6360_uv_event_handler },
+};
+
+static const struct mt6360_irq_mapping buck2_irq_tbls[] = {
+ { "buck2_pgb_evt", mt6360_pgb_event_handler },
+ { "buck2_oc_evt", mt6360_oc_event_handler },
+ { "buck2_ov_evt", mt6360_ov_event_handler },
+ { "buck2_uv_evt", mt6360_uv_event_handler },
+};
+
+static const struct mt6360_irq_mapping ldo6_irq_tbls[] = {
+ { "ldo6_pgb_evt", mt6360_pgb_event_handler },
+ { "ldo6_oc_evt", mt6360_oc_event_handler },
+};
+
+static const struct mt6360_irq_mapping ldo7_irq_tbls[] = {
+ { "ldo7_pgb_evt", mt6360_pgb_event_handler },
+ { "ldo7_oc_evt", mt6360_oc_event_handler },
+};
+
+static const struct mt6360_irq_mapping ldo1_irq_tbls[] = {
+ { "ldo1_pgb_evt", mt6360_pgb_event_handler },
+ { "ldo1_oc_evt", mt6360_oc_event_handler },
+};
+
+static const struct mt6360_irq_mapping ldo2_irq_tbls[] = {
+ { "ldo2_pgb_evt", mt6360_pgb_event_handler },
+ { "ldo2_oc_evt", mt6360_oc_event_handler },
+};
+
+static const struct mt6360_irq_mapping ldo3_irq_tbls[] = {
+ { "ldo3_pgb_evt", mt6360_pgb_event_handler },
+ { "ldo3_oc_evt", mt6360_oc_event_handler },
+};
+
+static const struct mt6360_irq_mapping ldo5_irq_tbls[] = {
+ { "ldo5_pgb_evt", mt6360_pgb_event_handler },
+ { "ldo5_oc_evt", mt6360_oc_event_handler },
+};
+
+static const struct linear_range buck_vout_ranges[] = {
+ REGULATOR_LINEAR_RANGE(300000, 0x00, 0xc7, 5000),
+ REGULATOR_LINEAR_RANGE(1300000, 0xc8, 0xff, 0),
+};
+
+static const struct linear_range ldo_vout_ranges1[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0x00, 0x09, 10000),
+ REGULATOR_LINEAR_RANGE(600000, 0x0a, 0x10, 0),
+ REGULATOR_LINEAR_RANGE(610000, 0x11, 0x19, 10000),
+ REGULATOR_LINEAR_RANGE(700000, 0x1a, 0x20, 0),
+ REGULATOR_LINEAR_RANGE(710000, 0x21, 0x29, 10000),
+ REGULATOR_LINEAR_RANGE(800000, 0x2a, 0x30, 0),
+ REGULATOR_LINEAR_RANGE(810000, 0x31, 0x39, 10000),
+ REGULATOR_LINEAR_RANGE(900000, 0x3a, 0x40, 0),
+ REGULATOR_LINEAR_RANGE(910000, 0x41, 0x49, 10000),
+ REGULATOR_LINEAR_RANGE(1000000, 0x4a, 0x50, 0),
+ REGULATOR_LINEAR_RANGE(1010000, 0x51, 0x59, 10000),
+ REGULATOR_LINEAR_RANGE(1100000, 0x5a, 0x60, 0),
+ REGULATOR_LINEAR_RANGE(1110000, 0x61, 0x69, 10000),
+ REGULATOR_LINEAR_RANGE(1200000, 0x6a, 0x70, 0),
+ REGULATOR_LINEAR_RANGE(1210000, 0x71, 0x79, 10000),
+ REGULATOR_LINEAR_RANGE(1300000, 0x7a, 0x80, 0),
+ REGULATOR_LINEAR_RANGE(1310000, 0x81, 0x89, 10000),
+ REGULATOR_LINEAR_RANGE(1400000, 0x8a, 0x90, 0),
+ REGULATOR_LINEAR_RANGE(1410000, 0x91, 0x99, 10000),
+ REGULATOR_LINEAR_RANGE(1500000, 0x9a, 0xa0, 0),
+ REGULATOR_LINEAR_RANGE(1510000, 0xa1, 0xa9, 10000),
+ REGULATOR_LINEAR_RANGE(1600000, 0xaa, 0xb0, 0),
+ REGULATOR_LINEAR_RANGE(1610000, 0xb1, 0xb9, 10000),
+ REGULATOR_LINEAR_RANGE(1700000, 0xba, 0xc0, 0),
+ REGULATOR_LINEAR_RANGE(1710000, 0xc1, 0xc9, 10000),
+ REGULATOR_LINEAR_RANGE(1800000, 0xca, 0xd0, 0),
+ REGULATOR_LINEAR_RANGE(1810000, 0xd1, 0xd9, 10000),
+ REGULATOR_LINEAR_RANGE(1900000, 0xda, 0xe0, 0),
+ REGULATOR_LINEAR_RANGE(1910000, 0xe1, 0xe9, 10000),
+ REGULATOR_LINEAR_RANGE(2000000, 0xea, 0xf0, 0),
+ REGULATOR_LINEAR_RANGE(2010000, 0xf1, 0xf9, 10000),
+ REGULATOR_LINEAR_RANGE(2100000, 0xfa, 0xff, 0),
+};
+
+static const struct linear_range ldo_vout_ranges2[] = {
+ REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x09, 10000),
+ REGULATOR_LINEAR_RANGE(1300000, 0x0a, 0x10, 0),
+ REGULATOR_LINEAR_RANGE(1310000, 0x11, 0x19, 10000),
+ REGULATOR_LINEAR_RANGE(1400000, 0x1a, 0x1f, 0),
+ REGULATOR_LINEAR_RANGE(1500000, 0x20, 0x29, 10000),
+ REGULATOR_LINEAR_RANGE(1600000, 0x2a, 0x2f, 0),
+ REGULATOR_LINEAR_RANGE(1700000, 0x30, 0x39, 10000),
+ REGULATOR_LINEAR_RANGE(1800000, 0x3a, 0x40, 0),
+ REGULATOR_LINEAR_RANGE(1810000, 0x41, 0x49, 10000),
+ REGULATOR_LINEAR_RANGE(1900000, 0x4a, 0x4f, 0),
+ REGULATOR_LINEAR_RANGE(2000000, 0x50, 0x59, 10000),
+ REGULATOR_LINEAR_RANGE(2100000, 0x5a, 0x60, 0),
+ REGULATOR_LINEAR_RANGE(2110000, 0x61, 0x69, 10000),
+ REGULATOR_LINEAR_RANGE(2200000, 0x6a, 0x6f, 0),
+ REGULATOR_LINEAR_RANGE(2500000, 0x70, 0x79, 10000),
+ REGULATOR_LINEAR_RANGE(2600000, 0x7a, 0x7f, 0),
+ REGULATOR_LINEAR_RANGE(2700000, 0x80, 0x89, 10000),
+ REGULATOR_LINEAR_RANGE(2800000, 0x8a, 0x90, 0),
+ REGULATOR_LINEAR_RANGE(2810000, 0x91, 0x99, 10000),
+ REGULATOR_LINEAR_RANGE(2900000, 0x9a, 0xa0, 0),
+ REGULATOR_LINEAR_RANGE(2910000, 0xa1, 0xa9, 10000),
+ REGULATOR_LINEAR_RANGE(3000000, 0xaa, 0xb0, 0),
+ REGULATOR_LINEAR_RANGE(3010000, 0xb1, 0xb9, 10000),
+ REGULATOR_LINEAR_RANGE(3100000, 0xba, 0xc0, 0),
+ REGULATOR_LINEAR_RANGE(3110000, 0xc1, 0xc9, 10000),
+ REGULATOR_LINEAR_RANGE(3200000, 0xca, 0xcf, 0),
+ REGULATOR_LINEAR_RANGE(3300000, 0xd0, 0xd9, 10000),
+ REGULATOR_LINEAR_RANGE(3400000, 0xda, 0xe0, 0),
+ REGULATOR_LINEAR_RANGE(3410000, 0xe1, 0xe9, 10000),
+ REGULATOR_LINEAR_RANGE(3500000, 0xea, 0xf0, 0),
+ REGULATOR_LINEAR_RANGE(3510000, 0xf1, 0xf9, 10000),
+ REGULATOR_LINEAR_RANGE(3600000, 0xfa, 0xff, 0),
+};
+
+static const struct linear_range ldo_vout_ranges3[] = {
+ REGULATOR_LINEAR_RANGE(2700000, 0x00, 0x09, 10000),
+ REGULATOR_LINEAR_RANGE(2800000, 0x0a, 0x10, 0),
+ REGULATOR_LINEAR_RANGE(2810000, 0x11, 0x19, 10000),
+ REGULATOR_LINEAR_RANGE(2900000, 0x1a, 0x20, 0),
+ REGULATOR_LINEAR_RANGE(2910000, 0x21, 0x29, 10000),
+ REGULATOR_LINEAR_RANGE(3000000, 0x2a, 0x30, 0),
+ REGULATOR_LINEAR_RANGE(3010000, 0x31, 0x39, 10000),
+ REGULATOR_LINEAR_RANGE(3100000, 0x3a, 0x40, 0),
+ REGULATOR_LINEAR_RANGE(3110000, 0x41, 0x49, 10000),
+ REGULATOR_LINEAR_RANGE(3200000, 0x4a, 0x4f, 0),
+ REGULATOR_LINEAR_RANGE(3300000, 0x50, 0x59, 10000),
+ REGULATOR_LINEAR_RANGE(3400000, 0x5a, 0x60, 0),
+ REGULATOR_LINEAR_RANGE(3410000, 0x61, 0x69, 10000),
+ REGULATOR_LINEAR_RANGE(3500000, 0x6a, 0x70, 0),
+ REGULATOR_LINEAR_RANGE(3510000, 0x71, 0x79, 10000),
+ REGULATOR_LINEAR_RANGE(3600000, 0x7a, 0x7f, 0),
+};
+
+static int mt6360_regulator_set_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+{
+ const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc;
+ struct regmap *regmap = rdev_get_regmap(rdev);
+ int shift = ffs(rdesc->mode_mask) - 1;
+ unsigned int val;
+ int ret;
+
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ val = MT6360_OPMODE_NORMAL;
+ break;
+ case REGULATOR_MODE_STANDBY:
+ val = MT6360_OPMODE_ULP;
+ break;
+ case REGULATOR_MODE_IDLE:
+ val = MT6360_OPMODE_LP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = regmap_update_bits(regmap, rdesc->mode_reg, rdesc->mode_mask, val << shift);
+ if (ret) {
+ dev_err(&rdev->dev, "%s: fail (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static unsigned int mt6360_regulator_get_mode(struct regulator_dev *rdev)
+{
+ const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc;
+ struct regmap *regmap = rdev_get_regmap(rdev);
+ int shift = ffs(rdesc->mode_mask) - 1;
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(regmap, rdesc->mode_reg, &val);
+ if (ret)
+ return ret;
+
+ val &= rdesc->mode_mask;
+ val >>= shift;
+
+ switch (val) {
+ case MT6360_OPMODE_LP:
+ return REGULATOR_MODE_IDLE;
+ case MT6360_OPMODE_ULP:
+ return REGULATOR_MODE_STANDBY;
+ case MT6360_OPMODE_NORMAL:
+ return REGULATOR_MODE_NORMAL;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mt6360_regulator_get_status(struct regulator_dev *rdev)
+{
+ const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc;
+ struct regmap *regmap = rdev_get_regmap(rdev);
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(regmap, rdesc->state_reg, &val);
+ if (ret)
+ return ret;
+
+ if (val & rdesc->state_mask)
+ return REGULATOR_STATUS_ON;
+
+ return REGULATOR_STATUS_OFF;
+}
+
+static const struct regulator_ops mt6360_regulator_ops = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_mode = mt6360_regulator_set_mode,
+ .get_mode = mt6360_regulator_get_mode,
+ .get_status = mt6360_regulator_get_status,
+};
+
+static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
+{
+ switch (hw_mode) {
+ case MT6360_OPMODE_NORMAL:
+ return REGULATOR_MODE_NORMAL;
+ case MT6360_OPMODE_LP:
+ return REGULATOR_MODE_IDLE;
+ case MT6360_OPMODE_ULP:
+ return REGULATOR_MODE_STANDBY;
+ default:
+ return REGULATOR_MODE_INVALID;
+ }
+}
+
+#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg, vmask, \
+ mreg, mmask, streg, stmask, vranges, \
+ vcnts, offon_delay, irq_tbls) \
+{ \
+ .desc = { \
+ .name = #_name, \
+ .supply_name = #_sname, \
+ .id = MT6360_REGULATOR_##_name, \
+ .of_match = of_match_ptr(#_name), \
+ .regulators_node = of_match_ptr("regulator"), \
+ .of_map_mode = mt6360_regulator_of_map_mode, \
+ .owner = THIS_MODULE, \
+ .ops = &mt6360_regulator_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .vsel_reg = vreg, \
+ .vsel_mask = vmask, \
+ .enable_reg = ereg, \
+ .enable_mask = emask, \
+ .linear_ranges = vranges, \
+ .n_linear_ranges = ARRAY_SIZE(vranges), \
+ .n_voltages = vcnts, \
+ .off_on_delay = offon_delay, \
+ }, \
+ .mode_reg = mreg, \
+ .mode_mask = mmask, \
+ .state_reg = streg, \
+ .state_mask = stmask, \
+ .irq_tables = irq_tbls, \
+ .irq_table_size = ARRAY_SIZE(irq_tbls), \
+}
+
+static const struct mt6360_regulator_desc mt6360_regulator_descs[] = {
+ MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
+ buck_vout_ranges, 256, 0, buck1_irq_tbls),
+ MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
+ buck_vout_ranges, 256, 0, buck2_irq_tbls),
+ MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
+ ldo_vout_ranges1, 256, 0, ldo6_irq_tbls),
+ MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
+ ldo_vout_ranges1, 256, 0, ldo7_irq_tbls),
+ MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
+ ldo_vout_ranges2, 256, 0, ldo1_irq_tbls),
+ MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
+ ldo_vout_ranges2, 256, 0, ldo2_irq_tbls),
+ MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
+ ldo_vout_ranges2, 256, 100, ldo3_irq_tbls),
+ MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
+ ldo_vout_ranges3, 128, 100, ldo5_irq_tbls),
+};
+
+static int mt6360_regulator_irq_register(struct platform_device *pdev,
+ struct regulator_dev *rdev,
+ const struct mt6360_irq_mapping *tbls,
+ int tbl_size)
+{
+ int i, irq, ret;
+
+ for (i = 0; i < tbl_size; i++) {
+ const struct mt6360_irq_mapping *irq_desc = tbls + i;
+
+ irq = platform_get_irq_byname(pdev, irq_desc->name);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Fail to get %s irq\n", irq_desc->name);
+ return irq;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, irq_desc->handler, 0,
+ irq_desc->name, rdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to request %s irq\n", irq_desc->name);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int mt6360_regulator_probe(struct platform_device *pdev)
+{
+ struct mt6360_regulator_data *mrd;
+ struct regulator_config config = {};
+ int i, ret;
+
+ mrd = devm_kzalloc(&pdev->dev, sizeof(*mrd), GFP_KERNEL);
+ if (!mrd)
+ return -ENOMEM;
+
+ mrd->dev = &pdev->dev;
+
+ mrd->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!mrd->regmap) {
+ dev_err(&pdev->dev, "Failed to get parent regmap\n");
+ return -ENODEV;
+ }
+
+ config.dev = pdev->dev.parent;
+ config.driver_data = mrd;
+ config.regmap = mrd->regmap;
+
+ for (i = 0; i < ARRAY_SIZE(mt6360_regulator_descs); i++) {
+ const struct mt6360_regulator_desc *rdesc = mt6360_regulator_descs + i;
+ struct regulator_dev *rdev;
+
+ rdev = devm_regulator_register(&pdev->dev, &rdesc->desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "Failed to register %d regulator\n", i);
+ return PTR_ERR(rdev);
+ }
+
+ ret = mt6360_regulator_irq_register(pdev, rdev, rdesc->irq_tables,
+ rdesc->irq_table_size);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register %d regulator irqs\n", i);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id mt6360_regulator_id_table[] = {
+ { "mt6360-regulator", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, mt6360_regulator_id_table);
+
+static struct platform_driver mt6360_regulator_driver = {
+ .driver = {
+ .name = "mt6360-regulator",
+ },
+ .probe = mt6360_regulator_probe,
+ .id_table = mt6360_regulator_id_table,
+};
+module_platform_driver(mt6360_regulator_driver);
+
+MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>");
+MODULE_DESCRIPTION("MT6360 Regulator Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index eb5822bf53e0..cb29421d745a 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -90,7 +90,7 @@ static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev,
BUCK1_RAMP_MASK, ramp_value << 6);
}
-static struct regulator_ops pca9450_dvs_buck_regulator_ops = {
+static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@@ -101,7 +101,7 @@ static struct regulator_ops pca9450_dvs_buck_regulator_ops = {
.set_ramp_delay = pca9450_dvs_set_ramp_delay,
};
-static struct regulator_ops pca9450_buck_regulator_ops = {
+static const struct regulator_ops pca9450_buck_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@@ -111,7 +111,7 @@ static struct regulator_ops pca9450_buck_regulator_ops = {
.set_voltage_time_sel = regulator_set_voltage_time_sel,
};
-static struct regulator_ops pca9450_ldo_regulator_ops = {
+static const struct regulator_ops pca9450_ldo_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c
index 787ced918372..48238846f45c 100644
--- a/drivers/regulator/pv88060-regulator.c
+++ b/drivers/regulator/pv88060-regulator.c
@@ -233,13 +233,10 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data)
if (reg_val & PV88060_E_VDD_FLT) {
for (i = 0; i < PV88060_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_lock(chip->rdev[i]);
+ if (chip->rdev[i] != NULL)
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
- regulator_unlock(chip->rdev[i]);
- }
}
err = regmap_write(chip->regmap, PV88060_REG_EVENT_A,
@@ -252,13 +249,10 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data)
if (reg_val & PV88060_E_OVER_TEMP) {
for (i = 0; i < PV88060_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_lock(chip->rdev[i]);
+ if (chip->rdev[i] != NULL)
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
- regulator_unlock(chip->rdev[i]);
- }
}
err = regmap_write(chip->regmap, PV88060_REG_EVENT_A,
diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c
index a444f68af1a8..2a74cc05acfe 100644
--- a/drivers/regulator/pv88080-regulator.c
+++ b/drivers/regulator/pv88080-regulator.c
@@ -334,13 +334,10 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
if (reg_val & PV88080_E_VDD_FLT) {
for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_lock(chip->rdev[i]);
+ if (chip->rdev[i] != NULL)
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
- regulator_unlock(chip->rdev[i]);
- }
}
err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
@@ -353,13 +350,10 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data)
if (reg_val & PV88080_E_OVER_TEMP) {
for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_lock(chip->rdev[i]);
+ if (chip->rdev[i] != NULL)
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
- regulator_unlock(chip->rdev[i]);
- }
}
err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c
index 784729ec2182..a80176bdf8ec 100644
--- a/drivers/regulator/pv88090-regulator.c
+++ b/drivers/regulator/pv88090-regulator.c
@@ -226,13 +226,10 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data)
if (reg_val & PV88090_E_VDD_FLT) {
for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_lock(chip->rdev[i]);
+ if (chip->rdev[i] != NULL)
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
- regulator_unlock(chip->rdev[i]);
- }
}
err = regmap_write(chip->regmap, PV88090_REG_EVENT_A,
@@ -245,13 +242,10 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data)
if (reg_val & PV88090_E_OVER_TEMP) {
for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
- if (chip->rdev[i] != NULL) {
- regulator_lock(chip->rdev[i]);
+ if (chip->rdev[i] != NULL)
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP,
NULL);
- regulator_unlock(chip->rdev[i]);
- }
}
err = regmap_write(chip->regmap, PV88090_REG_EVENT_A,
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index 990bd50771d8..7629476d94ae 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -390,7 +390,7 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id pwm_of_match[] = {
+static const struct of_device_id __maybe_unused pwm_of_match[] = {
{ .compatible = "pwm-regulator" },
{ },
};
diff --git a/drivers/regulator/qcom-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c
index 8c7dd1928380..8ccf572394a2 100644
--- a/drivers/regulator/qcom-labibb-regulator.c
+++ b/drivers/regulator/qcom-labibb-regulator.c
@@ -44,16 +44,16 @@ struct labibb_regulator_data {
const char *name;
u8 type;
u16 base;
- struct regulator_desc *desc;
+ const struct regulator_desc *desc;
};
-static struct regulator_ops qcom_labibb_ops = {
+static const struct regulator_ops qcom_labibb_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
-static struct regulator_desc pmi8998_lab_desc = {
+static const struct regulator_desc pmi8998_lab_desc = {
.enable_mask = LAB_ENABLE_CTL_MASK,
.enable_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),
.enable_val = LABIBB_CONTROL_ENABLE,
@@ -65,7 +65,7 @@ static struct regulator_desc pmi8998_lab_desc = {
.ops = &qcom_labibb_ops,
};
-static struct regulator_desc pmi8998_ibb_desc = {
+static const struct regulator_desc pmi8998_ibb_desc = {
.enable_mask = IBB_ENABLE_CTL_MASK,
.enable_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),
.enable_val = LABIBB_CONTROL_ENABLE,
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
index 08dcc614efa7..d488325499a9 100644
--- a/drivers/regulator/qcom-rpmh-regulator.c
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -967,7 +967,7 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id rpmh_regulator_match_table[] = {
+static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
{
.compatible = "qcom,pm8005-rpmh-regulators",
.data = pm8005_vreg_data,
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
index a87b56bc29fa..bb944ee5fe3b 100644
--- a/drivers/regulator/qcom_smd-regulator.c
+++ b/drivers/regulator/qcom_smd-regulator.c
@@ -403,6 +403,24 @@ static const struct regulator_desc pm8950_pldo = {
.ops = &rpm_smps_ldo_ops,
};
+static const struct regulator_desc pm8953_lnldo = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(1380000, 8, 15, 120000),
+ REGULATOR_LINEAR_RANGE(690000, 0, 7, 60000),
+ },
+ .n_linear_ranges = 2,
+ .n_voltages = 16,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm8953_ult_nldo = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 94,
+ .ops = &rpm_smps_ldo_ops,
+};
static const struct regulator_desc pm8994_hfsmps = {
.linear_ranges = (struct linear_range[]) {
@@ -541,6 +559,69 @@ static const struct regulator_desc pmi8998_bob = {
.ops = &rpm_bob_ops,
};
+static const struct regulator_desc pm660_ftsmps = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(355000, 0, 199, 5000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 200,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm660_hfsmps = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(320000, 0, 216, 8000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 217,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm660_ht_nldo = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(312000, 0, 124, 8000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 125,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm660_ht_lvpldo = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 63,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm660_nldo660 = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 124,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm660_pldo660 = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 256,
+ .ops = &rpm_smps_ldo_ops,
+};
+
+static const struct regulator_desc pm660l_bob = {
+ .linear_ranges = (struct linear_range[]) {
+ REGULATOR_LINEAR_RANGE(1800000, 0, 84, 32000),
+ },
+ .n_linear_ranges = 1,
+ .n_voltages = 85,
+ .ops = &rpm_bob_ops,
+};
+
static const struct regulator_desc pms405_hfsmps3 = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
@@ -791,6 +872,41 @@ static const struct rpm_regulator_data rpm_pm8950_regulators[] = {
{}
};
+static const struct rpm_regulator_data rpm_pm8953_regulators[] = {
+ { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8998_hfsmps, "vdd_s1" },
+ { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8998_hfsmps, "vdd_s2" },
+ { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8998_hfsmps, "vdd_s3" },
+ { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8998_hfsmps, "vdd_s4" },
+ { "s5", QCOM_SMD_RPM_SMPA, 5, &pm8950_ftsmps2p5, "vdd_s5" },
+ { "s6", QCOM_SMD_RPM_SMPA, 6, &pm8950_ftsmps2p5, "vdd_s6" },
+ { "s7", QCOM_SMD_RPM_SMPA, 7, &pm8998_hfsmps, "vdd_s7" },
+
+ { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8953_ult_nldo, "vdd_l1" },
+ { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8953_ult_nldo, "vdd_l2_l3" },
+ { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8953_ult_nldo, "vdd_l2_l3" },
+ { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" },
+ { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" },
+ { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" },
+ { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" },
+ { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" },
+ { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" },
+ { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" },
+ { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" },
+ { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" },
+ { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" },
+ { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" },
+ { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" },
+ { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" },
+ { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" },
+ { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" },
+ { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8953_ult_nldo, "vdd_l4_l5_l6_l7_l16_l19" },
+ { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8953_lnldo, "vdd_l20" },
+ { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8953_lnldo, "vdd_l21" },
+ { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" },
+ { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8953_ult_nldo, "vdd_l23" },
+ {}
+};
+
static const struct rpm_regulator_data rpm_pm8994_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8994_ftsmps, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8994_ftsmps, "vdd_s2" },
@@ -902,6 +1018,54 @@ static const struct rpm_regulator_data rpm_pmi8998_regulators[] = {
{}
};
+static const struct rpm_regulator_data rpm_pm660_regulators[] = {
+ { "s1", QCOM_SMD_RPM_SMPA, 1, &pm660_ftsmps, "vdd_s1" },
+ { "s2", QCOM_SMD_RPM_SMPA, 2, &pm660_ftsmps, "vdd_s2" },
+ { "s3", QCOM_SMD_RPM_SMPA, 3, &pm660_ftsmps, "vdd_s3" },
+ { "s4", QCOM_SMD_RPM_SMPA, 4, &pm660_hfsmps, "vdd_s4" },
+ { "s5", QCOM_SMD_RPM_SMPA, 5, &pm660_hfsmps, "vdd_s5" },
+ { "s6", QCOM_SMD_RPM_SMPA, 6, &pm660_hfsmps, "vdd_s6" },
+ { "l1", QCOM_SMD_RPM_LDOA, 1, &pm660_nldo660, "vdd_l1_l6_l7" },
+ { "l2", QCOM_SMD_RPM_LDOA, 2, &pm660_ht_nldo, "vdd_l2_l3" },
+ { "l3", QCOM_SMD_RPM_LDOA, 3, &pm660_nldo660, "vdd_l2_l3" },
+ /* l4 is unaccessible on PM660 */
+ { "l5", QCOM_SMD_RPM_LDOA, 5, &pm660_ht_nldo, "vdd_l5" },
+ { "l6", QCOM_SMD_RPM_LDOA, 6, &pm660_ht_nldo, "vdd_l1_l6_l7" },
+ { "l7", QCOM_SMD_RPM_LDOA, 7, &pm660_ht_nldo, "vdd_l1_l6_l7" },
+ { "l8", QCOM_SMD_RPM_LDOA, 8, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l9", QCOM_SMD_RPM_LDOA, 9, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l10", QCOM_SMD_RPM_LDOA, 10, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l11", QCOM_SMD_RPM_LDOA, 11, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l12", QCOM_SMD_RPM_LDOA, 12, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l13", QCOM_SMD_RPM_LDOA, 13, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l14", QCOM_SMD_RPM_LDOA, 14, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" },
+ { "l15", QCOM_SMD_RPM_LDOA, 15, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" },
+ { "l16", QCOM_SMD_RPM_LDOA, 16, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" },
+ { "l17", QCOM_SMD_RPM_LDOA, 17, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" },
+ { "l18", QCOM_SMD_RPM_LDOA, 18, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" },
+ { "l19", QCOM_SMD_RPM_LDOA, 19, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" },
+ { }
+};
+
+static const struct rpm_regulator_data rpm_pm660l_regulators[] = {
+ { "s1", QCOM_SMD_RPM_SMPB, 1, &pm660_ftsmps, "vdd_s1" },
+ { "s2", QCOM_SMD_RPM_SMPB, 2, &pm660_ftsmps, "vdd_s2" },
+ { "s3", QCOM_SMD_RPM_RWCX, 0, &pm660_ftsmps, "vdd_s3_s4" },
+ { "s5", QCOM_SMD_RPM_RWMX, 0, &pm660_ftsmps, "vdd_s5" },
+ { "l1", QCOM_SMD_RPM_LDOB, 1, &pm660_nldo660, "vdd_l1_l9_l10" },
+ { "l2", QCOM_SMD_RPM_LDOB, 2, &pm660_pldo660, "vdd_l2" },
+ { "l3", QCOM_SMD_RPM_LDOB, 3, &pm660_pldo660, "vdd_l3_l5_l7_l8" },
+ { "l4", QCOM_SMD_RPM_LDOB, 4, &pm660_pldo660, "vdd_l4_l6" },
+ { "l5", QCOM_SMD_RPM_LDOB, 5, &pm660_pldo660, "vdd_l3_l5_l7_l8" },
+ { "l6", QCOM_SMD_RPM_LDOB, 6, &pm660_pldo660, "vdd_l4_l6" },
+ { "l7", QCOM_SMD_RPM_LDOB, 7, &pm660_pldo660, "vdd_l3_l5_l7_l8" },
+ { "l8", QCOM_SMD_RPM_LDOB, 8, &pm660_pldo660, "vdd_l3_l5_l7_l8" },
+ { "l9", QCOM_SMD_RPM_RWLC, 0, &pm660_ht_nldo, "vdd_l1_l9_l10" },
+ { "l10", QCOM_SMD_RPM_RWLM, 0, &pm660_ht_nldo, "vdd_l1_l9_l10" },
+ { "bob", QCOM_SMD_RPM_BOBB, 1, &pm660l_bob, "vdd_bob", },
+ { }
+};
+
static const struct rpm_regulator_data rpm_pms405_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pms405_hfsmps3, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pms405_hfsmps3, "vdd_s2" },
@@ -930,8 +1094,11 @@ static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
{ .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
{ .compatible = "qcom,rpm-pm8950-regulators", .data = &rpm_pm8950_regulators },
+ { .compatible = "qcom,rpm-pm8953-regulators", .data = &rpm_pm8953_regulators },
{ .compatible = "qcom,rpm-pm8994-regulators", .data = &rpm_pm8994_regulators },
{ .compatible = "qcom,rpm-pm8998-regulators", .data = &rpm_pm8998_regulators },
+ { .compatible = "qcom,rpm-pm660-regulators", .data = &rpm_pm660_regulators },
+ { .compatible = "qcom,rpm-pm660l-regulators", .data = &rpm_pm660l_regulators },
{ .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators },
{ .compatible = "qcom,rpm-pmi8994-regulators", .data = &rpm_pmi8994_regulators },
{ .compatible = "qcom,rpm-pmi8998-regulators", .data = &rpm_pmi8998_regulators },
diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c
index 5ee7c5305d95..e62e1d72d943 100644
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -135,6 +135,18 @@ enum spmi_regulator_subtype {
SPMI_REGULATOR_SUBTYPE_LV_P600 = 0x2b,
SPMI_REGULATOR_SUBTYPE_LV_P1200 = 0x2c,
SPMI_REGULATOR_SUBTYPE_LV_P450 = 0x2d,
+ SPMI_REGULATOR_SUBTYPE_HT_N300_ST = 0x30,
+ SPMI_REGULATOR_SUBTYPE_HT_N600_ST = 0x31,
+ SPMI_REGULATOR_SUBTYPE_HT_N1200_ST = 0x32,
+ SPMI_REGULATOR_SUBTYPE_HT_LVP150 = 0x3b,
+ SPMI_REGULATOR_SUBTYPE_HT_LVP300 = 0x3c,
+ SPMI_REGULATOR_SUBTYPE_L660_N300_ST = 0x42,
+ SPMI_REGULATOR_SUBTYPE_L660_N600_ST = 0x43,
+ SPMI_REGULATOR_SUBTYPE_L660_P50 = 0x46,
+ SPMI_REGULATOR_SUBTYPE_L660_P150 = 0x47,
+ SPMI_REGULATOR_SUBTYPE_L660_P600 = 0x49,
+ SPMI_REGULATOR_SUBTYPE_L660_LVP150 = 0x4d,
+ SPMI_REGULATOR_SUBTYPE_L660_LVP600 = 0x4f,
SPMI_REGULATOR_SUBTYPE_LV100 = 0x01,
SPMI_REGULATOR_SUBTYPE_LV300 = 0x02,
SPMI_REGULATOR_SUBTYPE_MV300 = 0x08,
@@ -511,6 +523,22 @@ static struct spmi_voltage_range ult_pldo_ranges[] = {
SPMI_VOLTAGE_RANGE(0, 1750000, 1750000, 3337500, 3337500, 12500),
};
+static struct spmi_voltage_range pldo660_ranges[] = {
+ SPMI_VOLTAGE_RANGE(0, 1504000, 1504000, 3544000, 3544000, 8000),
+};
+
+static struct spmi_voltage_range nldo660_ranges[] = {
+ SPMI_VOLTAGE_RANGE(0, 320000, 320000, 1304000, 1304000, 8000),
+};
+
+static struct spmi_voltage_range ht_lvpldo_ranges[] = {
+ SPMI_VOLTAGE_RANGE(0, 1504000, 1504000, 2000000, 2000000, 8000),
+};
+
+static struct spmi_voltage_range ht_nldo_ranges[] = {
+ SPMI_VOLTAGE_RANGE(0, 312000, 312000, 1304000, 1304000, 8000),
+};
+
static struct spmi_voltage_range hfs430_ranges[] = {
SPMI_VOLTAGE_RANGE(0, 320000, 320000, 2040000, 2040000, 8000),
};
@@ -530,6 +558,10 @@ static DEFINE_SPMI_SET_POINTS(ult_lo_smps);
static DEFINE_SPMI_SET_POINTS(ult_ho_smps);
static DEFINE_SPMI_SET_POINTS(ult_nldo);
static DEFINE_SPMI_SET_POINTS(ult_pldo);
+static DEFINE_SPMI_SET_POINTS(pldo660);
+static DEFINE_SPMI_SET_POINTS(nldo660);
+static DEFINE_SPMI_SET_POINTS(ht_lvpldo);
+static DEFINE_SPMI_SET_POINTS(ht_nldo);
static DEFINE_SPMI_SET_POINTS(hfs430);
static inline int spmi_vreg_read(struct spmi_regulator *vreg, u16 addr, u8 *buf,
@@ -1443,6 +1475,30 @@ static const struct spmi_regulator_mapping supported_regulators[] = {
SPMI_VREG(LDO, LV_P300, 0, INF, LDO, ldo, pldo, 10000),
SPMI_VREG(LDO, LV_P600, 0, INF, LDO, ldo, pldo, 10000),
SPMI_VREG(LDO, LV_P1200, 0, INF, LDO, ldo, pldo, 10000),
+ SPMI_VREG(LDO, HT_N300_ST, 0, INF, FTSMPS426, ftsmps426,
+ ht_nldo, 30000),
+ SPMI_VREG(LDO, HT_N600_ST, 0, INF, FTSMPS426, ftsmps426,
+ ht_nldo, 30000),
+ SPMI_VREG(LDO, HT_N1200_ST, 0, INF, FTSMPS426, ftsmps426,
+ ht_nldo, 30000),
+ SPMI_VREG(LDO, HT_LVP150, 0, INF, FTSMPS426, ftsmps426,
+ ht_lvpldo, 10000),
+ SPMI_VREG(LDO, HT_LVP300, 0, INF, FTSMPS426, ftsmps426,
+ ht_lvpldo, 10000),
+ SPMI_VREG(LDO, L660_N300_ST, 0, INF, FTSMPS426, ftsmps426,
+ nldo660, 10000),
+ SPMI_VREG(LDO, L660_N600_ST, 0, INF, FTSMPS426, ftsmps426,
+ nldo660, 10000),
+ SPMI_VREG(LDO, L660_P50, 0, INF, FTSMPS426, ftsmps426,
+ pldo660, 10000),
+ SPMI_VREG(LDO, L660_P150, 0, INF, FTSMPS426, ftsmps426,
+ pldo660, 10000),
+ SPMI_VREG(LDO, L660_P600, 0, INF, FTSMPS426, ftsmps426,
+ pldo660, 10000),
+ SPMI_VREG(LDO, L660_LVP150, 0, INF, FTSMPS426, ftsmps426,
+ ht_lvpldo, 10000),
+ SPMI_VREG(LDO, L660_LVP600, 0, INF, FTSMPS426, ftsmps426,
+ ht_lvpldo, 10000),
SPMI_VREG_VS(LV100, 0, INF),
SPMI_VREG_VS(LV300, 0, INF),
SPMI_VREG_VS(MV300, 0, INF),
@@ -1633,45 +1689,43 @@ static int spmi_regulator_init_registers(struct spmi_regulator *vreg,
return ret;
/* Set up enable pin control. */
- if ((type == SPMI_REGULATOR_LOGICAL_TYPE_SMPS
- || type == SPMI_REGULATOR_LOGICAL_TYPE_LDO
- || type == SPMI_REGULATOR_LOGICAL_TYPE_VS)
- && !(data->pin_ctrl_enable
- & SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT)) {
- ctrl_reg[SPMI_COMMON_IDX_ENABLE] &=
- ~SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK;
- ctrl_reg[SPMI_COMMON_IDX_ENABLE] |=
- data->pin_ctrl_enable & SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK;
+ if (!(data->pin_ctrl_enable & SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT)) {
+ switch (type) {
+ case SPMI_REGULATOR_LOGICAL_TYPE_SMPS:
+ case SPMI_REGULATOR_LOGICAL_TYPE_LDO:
+ case SPMI_REGULATOR_LOGICAL_TYPE_VS:
+ ctrl_reg[SPMI_COMMON_IDX_ENABLE] &=
+ ~SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK;
+ ctrl_reg[SPMI_COMMON_IDX_ENABLE] |=
+ data->pin_ctrl_enable & SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK;
+ break;
+ default:
+ break;
+ }
}
/* Set up mode pin control. */
- if ((type == SPMI_REGULATOR_LOGICAL_TYPE_SMPS
- || type == SPMI_REGULATOR_LOGICAL_TYPE_LDO)
- && !(data->pin_ctrl_hpm
- & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) {
- ctrl_reg[SPMI_COMMON_IDX_MODE] &=
- ~SPMI_COMMON_MODE_FOLLOW_ALL_MASK;
- ctrl_reg[SPMI_COMMON_IDX_MODE] |=
- data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_ALL_MASK;
- }
-
- if (type == SPMI_REGULATOR_LOGICAL_TYPE_VS
- && !(data->pin_ctrl_hpm & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) {
- ctrl_reg[SPMI_COMMON_IDX_MODE] &=
- ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK;
- ctrl_reg[SPMI_COMMON_IDX_MODE] |=
- data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK;
- }
-
- if ((type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS
- || type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS
- || type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_LDO)
- && !(data->pin_ctrl_hpm
- & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) {
- ctrl_reg[SPMI_COMMON_IDX_MODE] &=
- ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK;
- ctrl_reg[SPMI_COMMON_IDX_MODE] |=
- data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK;
+ if (!(data->pin_ctrl_hpm & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) {
+ switch (type) {
+ case SPMI_REGULATOR_LOGICAL_TYPE_SMPS:
+ case SPMI_REGULATOR_LOGICAL_TYPE_LDO:
+ ctrl_reg[SPMI_COMMON_IDX_MODE] &=
+ ~SPMI_COMMON_MODE_FOLLOW_ALL_MASK;
+ ctrl_reg[SPMI_COMMON_IDX_MODE] |=
+ data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_ALL_MASK;
+ break;
+ case SPMI_REGULATOR_LOGICAL_TYPE_VS:
+ case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS:
+ case SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS:
+ case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LDO:
+ ctrl_reg[SPMI_COMMON_IDX_MODE] &=
+ ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK;
+ ctrl_reg[SPMI_COMMON_IDX_MODE] |=
+ data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK;
+ break;
+ default:
+ break;
+ }
}
/* Write back any control register values that were modified. */
@@ -1960,6 +2014,55 @@ static const struct spmi_regulator_data pmi8994_regulators[] = {
{ }
};
+static const struct spmi_regulator_data pm660_regulators[] = {
+ { "s1", 0x1400, "vdd_s1", },
+ { "s2", 0x1700, "vdd_s2", },
+ { "s3", 0x1a00, "vdd_s3", },
+ { "s4", 0x1d00, "vdd_s3", },
+ { "s5", 0x2000, "vdd_s5", },
+ { "s6", 0x2300, "vdd_s6", },
+ { "l1", 0x4000, "vdd_l1_l6_l7", },
+ { "l2", 0x4100, "vdd_l2_l3", },
+ { "l3", 0x4200, "vdd_l2_l3", },
+ /* l4 is unaccessible on PM660 */
+ { "l5", 0x4400, "vdd_l5", },
+ { "l6", 0x4500, "vdd_l1_l6_l7", },
+ { "l7", 0x4600, "vdd_l1_l6_l7", },
+ { "l8", 0x4700, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l9", 0x4800, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l10", 0x4900, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l11", 0x4a00, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l12", 0x4b00, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l13", 0x4c00, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l14", 0x4d00, "vdd_l8_l9_l10_l11_l12_l13_l14", },
+ { "l15", 0x4e00, "vdd_l15_l16_l17_l18_l19", },
+ { "l16", 0x4f00, "vdd_l15_l16_l17_l18_l19", },
+ { "l17", 0x5000, "vdd_l15_l16_l17_l18_l19", },
+ { "l18", 0x5100, "vdd_l15_l16_l17_l18_l19", },
+ { "l19", 0x5200, "vdd_l15_l16_l17_l18_l19", },
+ { }
+};
+
+static const struct spmi_regulator_data pm660l_regulators[] = {
+ { "s1", 0x1400, "vdd_s1", },
+ { "s2", 0x1700, "vdd_s2", },
+ { "s3", 0x1a00, "vdd_s3", },
+ { "s4", 0x1d00, "vdd_s4", },
+ { "s5", 0x2000, "vdd_s5", },
+ { "l1", 0x4000, "vdd_l1_l9_l10", },
+ { "l2", 0x4100, "vdd_l2", },
+ { "l3", 0x4200, "vdd_l3_l5_l7_l8", },
+ { "l4", 0x4300, "vdd_l4_l6", },
+ { "l5", 0x4400, "vdd_l3_l5_l7_l8", },
+ { "l6", 0x4500, "vdd_l4_l6", },
+ { "l7", 0x4600, "vdd_l3_l5_l7_l8", },
+ { "l8", 0x4700, "vdd_l3_l5_l7_l8", },
+ { "l9", 0x4800, "vdd_l1_l9_l10", },
+ { "l10", 0x4900, "vdd_l1_l9_l10", },
+ { }
+};
+
+
static const struct spmi_regulator_data pm8004_regulators[] = {
{ "s2", 0x1700, "vdd_s2", },
{ "s5", 0x2000, "vdd_s5", },
@@ -1988,6 +2091,8 @@ static const struct of_device_id qcom_spmi_regulator_match[] = {
{ .compatible = "qcom,pm8950-regulators", .data = &pm8950_regulators },
{ .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
{ .compatible = "qcom,pmi8994-regulators", .data = &pmi8994_regulators },
+ { .compatible = "qcom,pm660-regulators", .data = &pm660_regulators },
+ { .compatible = "qcom,pm660l-regulators", .data = &pm660l_regulators },
{ .compatible = "qcom,pms405-regulators", .data = &pms405_regulators },
{ }
};
diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c
index 8ba947f3585f..457788b50572 100644
--- a/drivers/regulator/qcom_usb_vbus-regulator.c
+++ b/drivers/regulator/qcom_usb_vbus-regulator.c
@@ -63,6 +63,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
qcom_usb_vbus_rdesc.enable_mask = OTG_EN;
config.dev = dev;
config.init_data = init_data;
+ config.of_node = dev->of_node;
config.regmap = regmap;
rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config);
diff --git a/drivers/regulator/rpi-panel-attiny-regulator.c b/drivers/regulator/rpi-panel-attiny-regulator.c
new file mode 100644
index 000000000000..ee46bfbf5eee
--- /dev/null
+++ b/drivers/regulator/rpi-panel-attiny-regulator.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Marek Vasut <marex@denx.de>
+ *
+ * Based on rpi_touchscreen.c by Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+
+/* I2C registers of the Atmel microcontroller. */
+#define REG_ID 0x80
+#define REG_PORTA 0x81
+#define REG_PORTA_HF BIT(2)
+#define REG_PORTA_VF BIT(3)
+#define REG_PORTB 0x82
+#define REG_POWERON 0x85
+#define REG_PWM 0x86
+
+static const struct regmap_config attiny_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_PWM,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int attiny_lcd_power_enable(struct regulator_dev *rdev)
+{
+ unsigned int data;
+
+ regmap_write(rdev->regmap, REG_POWERON, 1);
+ /* Wait for nPWRDWN to go low to indicate poweron is done. */
+ regmap_read_poll_timeout(rdev->regmap, REG_PORTB, data,
+ data & BIT(0), 10, 1000000);
+
+ /* Default to the same orientation as the closed source
+ * firmware used for the panel. Runtime rotation
+ * configuration will be supported using VC4's plane
+ * orientation bits.
+ */
+ regmap_write(rdev->regmap, REG_PORTA, BIT(2));
+
+ return 0;
+}
+
+static int attiny_lcd_power_disable(struct regulator_dev *rdev)
+{
+ regmap_write(rdev->regmap, REG_PWM, 0);
+ regmap_write(rdev->regmap, REG_POWERON, 0);
+ udelay(1);
+ return 0;
+}
+
+static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev)
+{
+ unsigned int data;
+ int ret;
+
+ ret = regmap_read(rdev->regmap, REG_POWERON, &data);
+ if (ret < 0)
+ return ret;
+
+ if (!(data & BIT(0)))
+ return 0;
+
+ ret = regmap_read(rdev->regmap, REG_PORTB, &data);
+ if (ret < 0)
+ return ret;
+
+ return data & BIT(0);
+}
+
+static const struct regulator_init_data attiny_regulator_default = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static const struct regulator_ops attiny_regulator_ops = {
+ .enable = attiny_lcd_power_enable,
+ .disable = attiny_lcd_power_disable,
+ .is_enabled = attiny_lcd_power_is_enabled,
+};
+
+static const struct regulator_desc attiny_regulator = {
+ .name = "tc358762-power",
+ .ops = &attiny_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+};
+
+static int attiny_update_status(struct backlight_device *bl)
+{
+ struct regmap *regmap = bl_get_data(bl);
+ int brightness = bl->props.brightness;
+
+ if (bl->props.power != FB_BLANK_UNBLANK ||
+ bl->props.fb_blank != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ return regmap_write(regmap, REG_PWM, brightness);
+}
+
+static int attiny_get_brightness(struct backlight_device *bl)
+{
+ struct regmap *regmap = bl_get_data(bl);
+ int ret, brightness;
+
+ ret = regmap_read(regmap, REG_PWM, &brightness);
+ if (ret)
+ return ret;
+
+ return brightness;
+}
+
+static const struct backlight_ops attiny_bl = {
+ .update_status = attiny_update_status,
+ .get_brightness = attiny_get_brightness,
+};
+
+/*
+ * I2C driver interface functions
+ */
+static int attiny_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct backlight_properties props = { };
+ struct regulator_config config = { };
+ struct backlight_device *bl;
+ struct regulator_dev *rdev;
+ struct regmap *regmap;
+ unsigned int data;
+ int ret;
+
+ regmap = devm_regmap_init_i2c(i2c, &attiny_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = regmap_read(regmap, REG_ID, &data);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret);
+ return ret;
+ }
+
+ switch (data) {
+ case 0xde: /* ver 1 */
+ case 0xc3: /* ver 2 */
+ break;
+ default:
+ dev_err(&i2c->dev, "Unknown Atmel firmware revision: 0x%02x\n", data);
+ return -ENODEV;
+ }
+
+ regmap_write(regmap, REG_POWERON, 0);
+ mdelay(1);
+
+ config.dev = &i2c->dev;
+ config.regmap = regmap;
+ config.of_node = i2c->dev.of_node;
+ config.init_data = &attiny_regulator_default;
+
+ rdev = devm_regulator_register(&i2c->dev, &attiny_regulator, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&i2c->dev, "Failed to register ATTINY regulator\n");
+ return PTR_ERR(rdev);
+ }
+
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = 0xff;
+ bl = devm_backlight_device_register(&i2c->dev,
+ "7inch-touchscreen-panel-bl",
+ &i2c->dev, regmap, &attiny_bl,
+ &props);
+ if (IS_ERR(bl))
+ return PTR_ERR(bl);
+
+ bl->props.brightness = 0xff;
+
+ return 0;
+}
+
+static const struct of_device_id attiny_dt_ids[] = {
+ { .compatible = "raspberrypi,7inch-touchscreen-panel-regulator" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, attiny_dt_ids);
+
+static struct i2c_driver attiny_regulator_driver = {
+ .driver = {
+ .name = "rpi_touchscreen_attiny",
+ .of_match_table = of_match_ptr(attiny_dt_ids),
+ },
+ .probe = attiny_i2c_probe,
+};
+
+module_i2c_driver(attiny_regulator_driver);
+
+MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
+MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch touchscreen");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/rt4801-regulator.c b/drivers/regulator/rt4801-regulator.c
new file mode 100644
index 000000000000..2055a9cb13ba
--- /dev/null
+++ b/drivers/regulator/rt4801-regulator.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+#define RT4801_REG_VOP 0x00
+#define RT4801_REG_VON 0x01
+#define RT4801_REG_APPS 0x03
+
+#define VOUT_MASK 0x1F
+
+#define MIN_UV 4000000
+#define STEP_UV 100000
+#define MAX_UV 6000000
+#define N_VOLTAGES ((MAX_UV - MIN_UV) / STEP_UV + 1)
+
+#define DSV_OUT_POS 0
+#define DSV_OUT_NEG 1
+#define DSV_OUT_MAX 2
+
+#define DSVP_ENABLE BIT(0)
+#define DSVN_ENABLE BIT(1)
+#define DSVALL_ENABLE (DSVP_ENABLE | DSVN_ENABLE)
+
+struct rt4801_priv {
+ struct device *dev;
+ struct gpio_descs *enable_gpios;
+ unsigned int enable_flag;
+ unsigned int volt_sel[DSV_OUT_MAX];
+};
+
+static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
+{
+ struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev), ret;
+
+ if (priv->enable_flag & BIT(id)) {
+ ret = regulator_set_voltage_sel_regmap(rdev, selector);
+ if (ret)
+ return ret;
+ }
+
+ priv->volt_sel[id] = selector;
+ return 0;
+}
+
+static int rt4801_get_voltage_sel(struct regulator_dev *rdev)
+{
+ struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+
+ if (priv->enable_flag & BIT(id))
+ return regulator_get_voltage_sel_regmap(rdev);
+
+ return priv->volt_sel[id];
+}
+
+static int rt4801_enable(struct regulator_dev *rdev)
+{
+ struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+ struct gpio_descs *gpios = priv->enable_gpios;
+ int id = rdev_get_id(rdev), ret;
+
+ if (gpios->ndescs <= id) {
+ dev_warn(&rdev->dev, "no dedicated gpio can control\n");
+ goto bypass_gpio;
+ }
+
+ gpiod_set_value(gpios->desc[id], 1);
+
+bypass_gpio:
+ ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, priv->volt_sel[id]);
+ if (ret)
+ return ret;
+
+ priv->enable_flag |= BIT(id);
+ return 0;
+}
+
+static int rt4801_disable(struct regulator_dev *rdev)
+{
+ struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+ struct gpio_descs *gpios = priv->enable_gpios;
+ int id = rdev_get_id(rdev);
+
+ if (gpios->ndescs <= id) {
+ dev_warn(&rdev->dev, "no dedicated gpio can control\n");
+ goto bypass_gpio;
+ }
+
+ gpiod_set_value(gpios->desc[id], 0);
+
+bypass_gpio:
+ priv->enable_flag &= ~BIT(id);
+ return 0;
+}
+
+static int rt4801_is_enabled(struct regulator_dev *rdev)
+{
+ struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+
+ return !!(priv->enable_flag & BIT(id));
+}
+
+static const struct regulator_ops rt4801_regulator_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .set_voltage_sel = rt4801_set_voltage_sel,
+ .get_voltage_sel = rt4801_get_voltage_sel,
+ .enable = rt4801_enable,
+ .disable = rt4801_disable,
+ .is_enabled = rt4801_is_enabled,
+};
+
+static const struct regulator_desc rt4801_regulator_descs[] = {
+ {
+ .name = "DSVP",
+ .ops = &rt4801_regulator_ops,
+ .of_match = of_match_ptr("DSVP"),
+ .type = REGULATOR_VOLTAGE,
+ .id = DSV_OUT_POS,
+ .min_uV = MIN_UV,
+ .uV_step = STEP_UV,
+ .n_voltages = N_VOLTAGES,
+ .owner = THIS_MODULE,
+ .vsel_reg = RT4801_REG_VOP,
+ .vsel_mask = VOUT_MASK,
+ },
+ {
+ .name = "DSVN",
+ .ops = &rt4801_regulator_ops,
+ .of_match = of_match_ptr("DSVN"),
+ .type = REGULATOR_VOLTAGE,
+ .id = DSV_OUT_NEG,
+ .min_uV = MIN_UV,
+ .uV_step = STEP_UV,
+ .n_voltages = N_VOLTAGES,
+ .owner = THIS_MODULE,
+ .vsel_reg = RT4801_REG_VON,
+ .vsel_mask = VOUT_MASK,
+ },
+};
+
+static const struct regmap_config rt4801_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = RT4801_REG_APPS,
+};
+
+static int rt4801_probe(struct i2c_client *i2c)
+{
+ struct rt4801_priv *priv;
+ struct regmap *regmap;
+ int i;
+
+ priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &i2c->dev;
+ /* bootloader will on, driver only reconfigure enable to all output high */
+ priv->enable_flag = DSVALL_ENABLE;
+
+ regmap = devm_regmap_init_i2c(i2c, &rt4801_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&i2c->dev, "Failed to init regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ priv->enable_gpios = devm_gpiod_get_array_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->enable_gpios)) {
+ dev_err(&i2c->dev, "Failed to get gpios\n");
+ return PTR_ERR(priv->enable_gpios);
+ }
+
+ for (i = 0; i < DSV_OUT_MAX; i++) {
+ const struct regulator_desc *desc = rt4801_regulator_descs + i;
+ struct regulator_config config = { .dev = &i2c->dev, .driver_data = priv,
+ .regmap = regmap, };
+ struct regulator_dev *rdev;
+ unsigned int val;
+ int ret;
+
+ /* initialize volt_sel variable */
+ ret = regmap_read(regmap, desc->vsel_reg, &val);
+ if (ret)
+ return ret;
+
+ priv->volt_sel[i] = val & desc->vsel_mask;
+
+ rdev = devm_regulator_register(&i2c->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&i2c->dev, "Failed to register [%d] regulator\n", i);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id __maybe_unused rt4801_of_id[] = {
+ { .compatible = "richtek,rt4801", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rt4801_of_id);
+
+static struct i2c_driver rt4801_driver = {
+ .driver = {
+ .name = "rt4801",
+ .of_match_table = of_match_ptr(rt4801_of_id),
+ },
+ .probe_new = rt4801_probe,
+};
+module_i2c_driver(rt4801_driver);
+
+MODULE_AUTHOR("ChiYuan Hwang <cy_huang@richtek.com>");
+MODULE_DESCRIPTION("Richtek RT4801 Display Bias Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c
new file mode 100644
index 000000000000..852fb2596ffd
--- /dev/null
+++ b/drivers/regulator/rtmv20-regulator.c
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+#define RTMV20_REG_DEVINFO 0x00
+#define RTMV20_REG_PULSEDELAY 0x01
+#define RTMV20_REG_PULSEWIDTH 0x03
+#define RTMV20_REG_LDCTRL1 0x05
+#define RTMV20_REG_ESPULSEWIDTH 0x06
+#define RTMV20_REG_ESLDCTRL1 0x08
+#define RTMV20_REG_LBP 0x0A
+#define RTMV20_REG_LDCTRL2 0x0B
+#define RTMV20_REG_FSIN1CTRL1 0x0D
+#define RTMV20_REG_FSIN1CTRL3 0x0F
+#define RTMV20_REG_FSIN2CTRL1 0x10
+#define RTMV20_REG_FSIN2CTRL3 0x12
+#define RTMV20_REG_ENCTRL 0x13
+#define RTMV20_REG_STRBVSYNDLYL 0x29
+#define RTMV20_REG_LDIRQ 0x30
+#define RTMV20_REG_LDSTAT 0x40
+#define RTMV20_REG_LDMASK 0x50
+
+#define RTMV20_VID_MASK GENMASK(7, 4)
+#define RICHTEK_VID 0x80
+#define RTMV20_LDCURR_MASK GENMASK(7, 0)
+#define RTMV20_DELAY_MASK GENMASK(9, 0)
+#define RTMV20_WIDTH_MASK GENMASK(13, 0)
+#define RTMV20_WIDTH2_MASK GENMASK(7, 0)
+#define RTMV20_LBPLVL_MASK GENMASK(3, 0)
+#define RTMV20_LBPEN_MASK BIT(7)
+#define RTMV20_STROBEPOL_MASK BIT(1)
+#define RTMV20_VSYNPOL_MASK BIT(1)
+#define RTMV20_FSINEN_MASK BIT(7)
+#define RTMV20_ESEN_MASK BIT(6)
+#define RTMV20_FSINOUT_MASK BIT(2)
+#define LDENABLE_MASK (BIT(3) | BIT(0))
+
+#define OTPEVT_MASK BIT(4)
+#define SHORTEVT_MASK BIT(3)
+#define OPENEVT_MASK BIT(2)
+#define LBPEVT_MASK BIT(1)
+#define OCPEVT_MASK BIT(0)
+#define FAILEVT_MASK (SHORTEVT_MASK | OPENEVT_MASK | LBPEVT_MASK)
+
+#define RTMV20_LSW_MINUA 0
+#define RTMV20_LSW_MAXUA 6000000
+#define RTMV20_LSW_STEPUA 30000
+
+#define RTMV20_LSW_DEFAULTUA 3000000
+
+#define RTMV20_I2CRDY_TIMEUS 200
+#define RTMV20_CSRDY_TIMEUS 2000
+
+struct rtmv20_priv {
+ struct device *dev;
+ struct regmap *regmap;
+ struct gpio_desc *enable_gpio;
+ struct regulator_dev *rdev;
+};
+
+static int rtmv20_lsw_enable(struct regulator_dev *rdev)
+{
+ struct rtmv20_priv *priv = rdev_get_drvdata(rdev);
+ int ret;
+
+ gpiod_set_value(priv->enable_gpio, 1);
+
+ /* Wait for I2C can be accessed */
+ usleep_range(RTMV20_I2CRDY_TIMEUS, RTMV20_I2CRDY_TIMEUS + 100);
+
+ /* HW re-enable, disable cache only and sync regcache here */
+ regcache_cache_only(priv->regmap, false);
+ ret = regcache_sync(priv->regmap);
+ if (ret)
+ return ret;
+
+ return regulator_enable_regmap(rdev);
+}
+
+static int rtmv20_lsw_disable(struct regulator_dev *rdev)
+{
+ struct rtmv20_priv *priv = rdev_get_drvdata(rdev);
+ int ret;
+
+ ret = regulator_disable_regmap(rdev);
+ if (ret)
+ return ret;
+
+ /* Mark the regcache as dirty and cache only before HW disabled */
+ regcache_cache_only(priv->regmap, true);
+ regcache_mark_dirty(priv->regmap);
+
+ gpiod_set_value(priv->enable_gpio, 0);
+
+ return 0;
+}
+
+static const struct regulator_ops rtmv20_regulator_ops = {
+ .set_current_limit = regulator_set_current_limit_regmap,
+ .get_current_limit = regulator_get_current_limit_regmap,
+ .enable = rtmv20_lsw_enable,
+ .disable = rtmv20_lsw_disable,
+ .is_enabled = regulator_is_enabled_regmap,
+};
+
+static const struct regulator_desc rtmv20_lsw_desc = {
+ .name = "rtmv20,lsw",
+ .of_match = of_match_ptr("lsw"),
+ .type = REGULATOR_CURRENT,
+ .owner = THIS_MODULE,
+ .ops = &rtmv20_regulator_ops,
+ .csel_reg = RTMV20_REG_LDCTRL1,
+ .csel_mask = RTMV20_LDCURR_MASK,
+ .enable_reg = RTMV20_REG_ENCTRL,
+ .enable_mask = LDENABLE_MASK,
+ .enable_time = RTMV20_CSRDY_TIMEUS,
+};
+
+static irqreturn_t rtmv20_irq_handler(int irq, void *data)
+{
+ struct rtmv20_priv *priv = data;
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(priv->regmap, RTMV20_REG_LDIRQ, &val);
+ if (ret) {
+ dev_err(priv->dev, "Failed to get irq flags\n");
+ return IRQ_NONE;
+ }
+
+ if (val & OTPEVT_MASK)
+ regulator_notifier_call_chain(priv->rdev, REGULATOR_EVENT_OVER_TEMP, NULL);
+
+ if (val & OCPEVT_MASK)
+ regulator_notifier_call_chain(priv->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL);
+
+ if (val & FAILEVT_MASK)
+ regulator_notifier_call_chain(priv->rdev, REGULATOR_EVENT_FAIL, NULL);
+
+ return IRQ_HANDLED;
+}
+
+static u32 clamp_to_selector(u32 val, u32 min, u32 max, u32 step)
+{
+ u32 retval = clamp_val(val, min, max);
+
+ return (retval - min) / step;
+}
+
+static int rtmv20_properties_init(struct rtmv20_priv *priv)
+{
+ const struct {
+ const char *name;
+ u32 def;
+ u32 min;
+ u32 max;
+ u32 step;
+ u32 addr;
+ u32 mask;
+ } props[] = {
+ { "richtek,ld-pulse-delay-us", 0, 0, 100000, 100, RTMV20_REG_PULSEDELAY,
+ RTMV20_DELAY_MASK },
+ { "richtek,ld-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_PULSEWIDTH,
+ RTMV20_WIDTH_MASK },
+ { "richtek,fsin1-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN1CTRL1,
+ RTMV20_DELAY_MASK },
+ { "richtek,fsin1-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN1CTRL3,
+ RTMV20_WIDTH2_MASK },
+ { "richtek,fsin2-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN2CTRL1,
+ RTMV20_DELAY_MASK },
+ { "richtek,fsin2-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN2CTRL3,
+ RTMV20_WIDTH2_MASK },
+ { "richtek,es-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_ESPULSEWIDTH,
+ RTMV20_WIDTH_MASK },
+ { "richtek,es-ld-current-microamp", 3000000, 0, 6000000, 30000,
+ RTMV20_REG_ESLDCTRL1, RTMV20_LDCURR_MASK },
+ { "richtek,lbp-level-microvolt", 2700000, 2400000, 3700000, 100000, RTMV20_REG_LBP,
+ RTMV20_LBPLVL_MASK },
+ { "richtek,lbp-enable", 0, 0, 1, 1, RTMV20_REG_LBP, RTMV20_LBPEN_MASK },
+ { "richtek,strobe-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2,
+ RTMV20_STROBEPOL_MASK },
+ { "richtek,vsync-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2,
+ RTMV20_VSYNPOL_MASK },
+ { "richtek,fsin-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINEN_MASK },
+ { "richtek,fsin-output", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINOUT_MASK },
+ { "richtek,es-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_ESEN_MASK },
+ };
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(props); i++) {
+ __be16 bval16;
+ u16 val16;
+ u32 temp;
+ int significant_bit = fls(props[i].mask);
+ int shift = ffs(props[i].mask) - 1;
+
+ if (props[i].max > 1) {
+ ret = device_property_read_u32(priv->dev, props[i].name, &temp);
+ if (ret)
+ temp = props[i].def;
+ } else
+ temp = device_property_read_bool(priv->dev, props[i].name);
+
+ temp = clamp_to_selector(temp, props[i].min, props[i].max, props[i].step);
+
+ /* If significant bit is over 8, two byte access, others one */
+ if (significant_bit > 8) {
+ ret = regmap_raw_read(priv->regmap, props[i].addr, &bval16, sizeof(bval16));
+ if (ret)
+ return ret;
+
+ val16 = be16_to_cpu(bval16);
+ val16 &= ~props[i].mask;
+ val16 |= (temp << shift);
+ bval16 = cpu_to_be16(val16);
+
+ ret = regmap_raw_write(priv->regmap, props[i].addr, &bval16,
+ sizeof(bval16));
+ } else {
+ ret = regmap_update_bits(priv->regmap, props[i].addr, props[i].mask,
+ temp << shift);
+ }
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rtmv20_check_chip_exist(struct rtmv20_priv *priv)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(priv->regmap, RTMV20_REG_DEVINFO, &val);
+ if (ret)
+ return ret;
+
+ if ((val & RTMV20_VID_MASK) != RICHTEK_VID)
+ return -ENODEV;
+
+ return 0;
+}
+
+static bool rtmv20_is_accessible_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case RTMV20_REG_DEVINFO ... RTMV20_REG_STRBVSYNDLYL:
+ case RTMV20_REG_LDIRQ:
+ case RTMV20_REG_LDSTAT:
+ case RTMV20_REG_LDMASK:
+ return true;
+ }
+ return false;
+}
+
+static bool rtmv20_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ if (reg == RTMV20_REG_LDIRQ || reg == RTMV20_REG_LDSTAT)
+ return true;
+ return false;
+}
+
+static const struct regmap_config rtmv20_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_RBTREE,
+ .max_register = RTMV20_REG_LDMASK,
+
+ .writeable_reg = rtmv20_is_accessible_reg,
+ .readable_reg = rtmv20_is_accessible_reg,
+ .volatile_reg = rtmv20_is_volatile_reg,
+};
+
+static int rtmv20_probe(struct i2c_client *i2c)
+{
+ struct rtmv20_priv *priv;
+ struct regulator_config config = {};
+ int ret;
+
+ priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &i2c->dev;
+
+ /* Before regmap register, configure HW enable to make I2C accessible */
+ priv->enable_gpio = devm_gpiod_get(&i2c->dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->enable_gpio)) {
+ dev_err(&i2c->dev, "Failed to get enable gpio\n");
+ return PTR_ERR(priv->enable_gpio);
+ }
+
+ /* Wait for I2C can be accessed */
+ usleep_range(RTMV20_I2CRDY_TIMEUS, RTMV20_I2CRDY_TIMEUS + 100);
+
+ priv->regmap = devm_regmap_init_i2c(i2c, &rtmv20_regmap_config);
+ if (IS_ERR(priv->regmap)) {
+ dev_err(&i2c->dev, "Failed to allocate register map\n");
+ return PTR_ERR(priv->regmap);
+ }
+
+ ret = rtmv20_check_chip_exist(priv);
+ if (ret) {
+ dev_err(&i2c->dev, "Chip vendor info is not matched\n");
+ return ret;
+ }
+
+ ret = rtmv20_properties_init(priv);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to init properties\n");
+ return ret;
+ }
+
+ /*
+ * keep in shutdown mode to minimize the current consumption
+ * and also mark regcache as dirty
+ */
+ regcache_cache_only(priv->regmap, true);
+ regcache_mark_dirty(priv->regmap);
+ gpiod_set_value(priv->enable_gpio, 0);
+
+ config.dev = &i2c->dev;
+ config.regmap = priv->regmap;
+ config.driver_data = priv;
+ priv->rdev = devm_regulator_register(&i2c->dev, &rtmv20_lsw_desc, &config);
+ if (IS_ERR(priv->rdev)) {
+ dev_err(&i2c->dev, "Failed to register regulator\n");
+ return PTR_ERR(priv->rdev);
+ }
+
+ /* Unmask all events before IRQ registered */
+ ret = regmap_write(priv->regmap, RTMV20_REG_LDMASK, 0);
+ if (ret)
+ return ret;
+
+ return devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, rtmv20_irq_handler,
+ IRQF_ONESHOT, dev_name(&i2c->dev), priv);
+}
+
+static int __maybe_unused rtmv20_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+
+ /*
+ * When system suspend, disable irq to prevent interrupt trigger
+ * during I2C bus suspend
+ */
+ disable_irq(i2c->irq);
+ if (device_may_wakeup(dev))
+ enable_irq_wake(i2c->irq);
+
+ return 0;
+}
+
+static int __maybe_unused rtmv20_resume(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+
+ /* Enable irq after I2C bus already resume */
+ enable_irq(i2c->irq);
+ if (device_may_wakeup(dev))
+ disable_irq_wake(i2c->irq);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(rtmv20_pm, rtmv20_suspend, rtmv20_resume);
+
+static const struct of_device_id __maybe_unused rtmv20_of_id[] = {
+ { .compatible = "richtek,rtmv20", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, rtmv20_of_id);
+
+static struct i2c_driver rtmv20_driver = {
+ .driver = {
+ .name = "rtmv20",
+ .of_match_table = of_match_ptr(rtmv20_of_id),
+ .pm = &rtmv20_pm,
+ },
+ .probe_new = rtmv20_probe,
+};
+module_i2c_driver(rtmv20_driver);
+
+MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
+MODULE_DESCRIPTION("Richtek RTMV20 Regulator Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index 4abd3ed31f60..3fa472127e9a 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -1000,18 +1000,7 @@ static struct platform_driver s5m8767_pmic_driver = {
.probe = s5m8767_pmic_probe,
.id_table = s5m8767_pmic_id,
};
-
-static int __init s5m8767_pmic_init(void)
-{
- return platform_driver_register(&s5m8767_pmic_driver);
-}
-subsys_initcall(s5m8767_pmic_init);
-
-static void __exit s5m8767_pmic_exit(void)
-{
- platform_driver_unregister(&s5m8767_pmic_driver);
-}
-module_exit(s5m8767_pmic_exit);
+module_platform_driver(s5m8767_pmic_driver);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c
index 87b020d0b958..75a941fb3c2b 100644
--- a/drivers/regulator/slg51000-regulator.c
+++ b/drivers/regulator/slg51000-regulator.c
@@ -386,10 +386,8 @@ static irqreturn_t slg51000_irq_handler(int irq, void *data)
for (i = 0; i < SLG51000_MAX_REGULATORS; i++) {
if (!(evt[i][R2] & SLG51000_IRQ_ILIM_FLAG_MASK) &&
(evt[i][R0] & SLG51000_EVT_ILIM_FLAG_MASK)) {
- regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_CURRENT, NULL);
- regulator_unlock(chip->rdev[i]);
if (evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK)
dev_warn(chip->dev,
@@ -403,10 +401,8 @@ static irqreturn_t slg51000_irq_handler(int irq, void *data)
for (i = 0; i < SLG51000_MAX_REGULATORS; i++) {
if (!(evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK) &&
(evt[i][R1] & SLG51000_STA_VOUT_OK_FLAG_MASK)) {
- regulator_lock(chip->rdev[i]);
regulator_notifier_call_chain(chip->rdev[i],
REGULATOR_EVENT_OVER_TEMP, NULL);
- regulator_unlock(chip->rdev[i]);
}
}
handled = IRQ_HANDLED;
diff --git a/drivers/regulator/stm32-booster.c b/drivers/regulator/stm32-booster.c
index 03f162ffd144..3136ea8a35d5 100644
--- a/drivers/regulator/stm32-booster.c
+++ b/drivers/regulator/stm32-booster.c
@@ -101,7 +101,7 @@ static int stm32_booster_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id stm32_booster_of_match[] = {
+static const struct of_device_id __maybe_unused stm32_booster_of_match[] = {
{
.compatible = "st,stm32h7-booster",
.data = (void *)&stm32h7_booster_desc
diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c
index e0e627b0106e..2a42acb7c24e 100644
--- a/drivers/regulator/stm32-pwr.c
+++ b/drivers/regulator/stm32-pwr.c
@@ -166,7 +166,7 @@ static int stm32_pwr_regulator_probe(struct platform_device *pdev)
return ret;
}
-static const struct of_device_id stm32_pwr_of_match[] = {
+static const struct of_device_id __maybe_unused stm32_pwr_of_match[] = {
{ .compatible = "st,stm32mp1,pwr-reg", },
{},
};
diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c
index 992bc18101ef..161622ea7259 100644
--- a/drivers/regulator/stm32-vrefbuf.c
+++ b/drivers/regulator/stm32-vrefbuf.c
@@ -284,7 +284,7 @@ static const struct dev_pm_ops stm32_vrefbuf_pm_ops = {
NULL)
};
-static const struct of_device_id stm32_vrefbuf_of_match[] = {
+static const struct of_device_id __maybe_unused stm32_vrefbuf_of_match[] = {
{ .compatible = "st,stm32-vrefbuf", },
{},
};
diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c
index 73e0ab2baeaa..cf10fdb72e32 100644
--- a/drivers/regulator/stpmic1_regulator.c
+++ b/drivers/regulator/stpmic1_regulator.c
@@ -505,15 +505,11 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
- regulator_lock(rdev);
-
/* Send an overcurrent notification */
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_OVER_CURRENT,
NULL);
- regulator_unlock(rdev);
-
return IRQ_HANDLED;
}
diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c
index 6dc2316daad3..127ab43add49 100644
--- a/drivers/regulator/stw481x-vmmc.c
+++ b/drivers/regulator/stw481x-vmmc.c
@@ -27,7 +27,7 @@ static const unsigned int stw481x_vmmc_voltages[] = {
3300000,
};
-static struct regulator_ops stw481x_vmmc_ops = {
+static const struct regulator_ops stw481x_vmmc_ops = {
.list_voltage = regulator_list_voltage_table,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -36,7 +36,7 @@ static struct regulator_ops stw481x_vmmc_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
-static struct regulator_desc vmmc_regulator = {
+static const struct regulator_desc vmmc_regulator = {
.name = "VMMC",
.id = 0,
.ops = &stw481x_vmmc_ops,
diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c
index 2222e739e62b..c119f85259a5 100644
--- a/drivers/regulator/sy8106a-regulator.c
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -123,7 +123,7 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c)
return 0;
}
-static const struct of_device_id sy8106a_i2c_of_match[] = {
+static const struct of_device_id __maybe_unused sy8106a_i2c_of_match[] = {
{ .compatible = "silergy,sy8106a" },
{ },
};
diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c
index b207217f74d8..52e8c17afe24 100644
--- a/drivers/regulator/sy8827n.c
+++ b/drivers/regulator/sy8827n.c
@@ -156,6 +156,7 @@ static int sy8827n_i2c_probe(struct i2c_client *client)
return ret;
}
+#ifdef CONFIG_OF
static const struct of_device_id sy8827n_dt_ids[] = {
{
.compatible = "silergy,sy8827n",
@@ -163,6 +164,7 @@ static const struct of_device_id sy8827n_dt_ids[] = {
{ }
};
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
+#endif
static const struct i2c_device_id sy8827n_id[] = {
{ "sy8827n", },
diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c
index af9abcd9c166..3e60bff76194 100644
--- a/drivers/regulator/ti-abb-regulator.c
+++ b/drivers/regulator/ti-abb-regulator.c
@@ -619,7 +619,7 @@ check_abb:
return 0;
}
-static struct regulator_ops ti_abb_reg_ops = {
+static const struct regulator_ops ti_abb_reg_ops = {
.list_voltage = regulator_list_voltage_table,
.set_voltage_sel = ti_abb_set_voltage_sel,
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c
index c139890c1514..a15e415e61d5 100644
--- a/drivers/regulator/tps51632-regulator.c
+++ b/drivers/regulator/tps51632-regulator.c
@@ -108,7 +108,7 @@ static int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev,
return ret;
}
-static struct regulator_ops tps51632_dcdc_ops = {
+static const struct regulator_ops tps51632_dcdc_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
index f8939af0bd2c..a6469fe05635 100644
--- a/drivers/regulator/tps6105x-regulator.c
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -26,7 +26,7 @@ static const unsigned int tps6105x_voltages[] = {
5000000, /* There is an additional 5V */
};
-static struct regulator_ops tps6105x_regulator_ops = {
+static const struct regulator_ops tps6105x_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
index f6a6d36a6533..315cd5daf480 100644
--- a/drivers/regulator/tps62360-regulator.c
+++ b/drivers/regulator/tps62360-regulator.c
@@ -233,7 +233,7 @@ static unsigned int tps62360_get_mode(struct regulator_dev *rdev)
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}
-static struct regulator_ops tps62360_dcdc_ops = {
+static const struct regulator_ops tps62360_dcdc_ops = {
.get_voltage_sel = tps62360_dcdc_get_voltage_sel,
.set_voltage_sel = tps62360_dcdc_set_voltage_sel,
.list_voltage = regulator_list_voltage_linear,
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 795d459ff3cf..f25806531c7e 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -316,7 +316,7 @@ static int tps_65023_probe(struct i2c_client *client,
return 0;
}
-static const struct of_device_id tps65023_of_match[] = {
+static const struct of_device_id __maybe_unused tps65023_of_match[] = {
{ .compatible = "ti,tps65020", .data = &tps65020_drv_data},
{ .compatible = "ti,tps65021", .data = &tps65021_drv_data},
{ .compatible = "ti,tps65023", .data = &tps65023_drv_data},
diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c
index 23528475a962..070c956216b0 100644
--- a/drivers/regulator/tps65086-regulator.c
+++ b/drivers/regulator/tps65086-regulator.c
@@ -101,7 +101,7 @@ static const struct linear_range tps65086_ldoa23_ranges[] = {
};
/* Operations permitted on regulators */
-static struct regulator_ops reg_ops = {
+static const struct regulator_ops reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@@ -112,7 +112,7 @@ static struct regulator_ops reg_ops = {
};
/* Operations permitted on load switches */
-static struct regulator_ops switch_ops = {
+static const struct regulator_ops switch_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c
index f0b660e9f15f..1d2e04f452d4 100644
--- a/drivers/regulator/tps65090-regulator.c
+++ b/drivers/regulator/tps65090-regulator.c
@@ -47,7 +47,7 @@ struct tps65090_regulator {
int overcurrent_wait;
};
-static struct regulator_ops tps65090_ext_control_ops = {
+static const struct regulator_ops tps65090_ext_control_ops = {
};
/**
@@ -167,19 +167,19 @@ err:
return ret;
}
-static struct regulator_ops tps65090_reg_control_ops = {
+static const struct regulator_ops tps65090_reg_control_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
-static struct regulator_ops tps65090_fet_control_ops = {
+static const struct regulator_ops tps65090_fet_control_ops = {
.enable = tps65090_fet_enable,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
-static struct regulator_ops tps65090_ldo_ops = {
+static const struct regulator_ops tps65090_ldo_ops = {
};
#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index 09e994e1f9a9..18bf4b885b08 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -60,7 +60,7 @@ struct tps6586x_regulator {
int enable_reg[2];
};
-static struct regulator_ops tps6586x_rw_regulator_ops = {
+static const struct regulator_ops tps6586x_rw_regulator_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@@ -71,7 +71,7 @@ static struct regulator_ops tps6586x_rw_regulator_ops = {
.disable = regulator_disable_regmap,
};
-static struct regulator_ops tps6586x_rw_linear_regulator_ops = {
+static const struct regulator_ops tps6586x_rw_linear_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
@@ -81,7 +81,7 @@ static struct regulator_ops tps6586x_rw_linear_regulator_ops = {
.disable = regulator_disable_regmap,
};
-static struct regulator_ops tps6586x_ro_regulator_ops = {
+static const struct regulator_ops tps6586x_ro_regulator_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@@ -91,7 +91,7 @@ static struct regulator_ops tps6586x_ro_regulator_ops = {
.disable = regulator_disable_regmap,
};
-static struct regulator_ops tps6586x_sys_regulator_ops = {
+static const struct regulator_ops tps6586x_sys_regulator_ops = {
};
static const unsigned int tps6586x_ldo0_voltages[] = {
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 4eb5b19d2344..1d5b0a1b86f7 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -390,8 +390,8 @@ static int tps65911_get_ctrl_register(int id)
static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
- struct tps65910 *mfd = pmic->mfd;
- int reg, value, id = rdev_get_id(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
+ int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
@@ -399,14 +399,14 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
switch (mode) {
case REGULATOR_MODE_NORMAL:
- return tps65910_reg_update_bits(pmic->mfd, reg,
- LDO_ST_MODE_BIT | LDO_ST_ON_BIT,
- LDO_ST_ON_BIT);
+ return regmap_update_bits(regmap, reg,
+ LDO_ST_MODE_BIT | LDO_ST_ON_BIT,
+ LDO_ST_ON_BIT);
case REGULATOR_MODE_IDLE:
- value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
- return tps65910_reg_set_bits(mfd, reg, value);
+ return regmap_set_bits(regmap, reg,
+ LDO_ST_ON_BIT | LDO_ST_MODE_BIT);
case REGULATOR_MODE_STANDBY:
- return tps65910_reg_clear_bits(mfd, reg, LDO_ST_ON_BIT);
+ return regmap_clear_bits(regmap, reg, LDO_ST_ON_BIT);
}
return -EINVAL;
@@ -415,13 +415,14 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
static unsigned int tps65910_get_mode(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int ret, reg, value, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
- ret = tps65910_reg_read(pmic->mfd, reg, &value);
+ ret = regmap_read(regmap, reg, &value);
if (ret < 0)
return ret;
@@ -435,20 +436,20 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev)
static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
{
- struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int ret, id = rdev_get_id(dev);
int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
switch (id) {
case TPS65910_REG_VDD1:
- ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_OP, &opvsel);
+ ret = regmap_read(regmap, TPS65910_VDD1_OP, &opvsel);
if (ret < 0)
return ret;
- ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1, &mult);
+ ret = regmap_read(regmap, TPS65910_VDD1, &mult);
if (ret < 0)
return ret;
mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
- ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_SR, &srvsel);
+ ret = regmap_read(regmap, TPS65910_VDD1_SR, &srvsel);
if (ret < 0)
return ret;
sr = opvsel & VDD1_OP_CMD_MASK;
@@ -457,14 +458,14 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
vselmax = 75;
break;
case TPS65910_REG_VDD2:
- ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_OP, &opvsel);
+ ret = regmap_read(regmap, TPS65910_VDD2_OP, &opvsel);
if (ret < 0)
return ret;
- ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2, &mult);
+ ret = regmap_read(regmap, TPS65910_VDD2, &mult);
if (ret < 0)
return ret;
mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
- ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_SR, &srvsel);
+ ret = regmap_read(regmap, TPS65910_VDD2_SR, &srvsel);
if (ret < 0)
return ret;
sr = opvsel & VDD2_OP_CMD_MASK;
@@ -473,12 +474,10 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
vselmax = 75;
break;
case TPS65911_REG_VDDCTRL:
- ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_OP,
- &opvsel);
+ ret = regmap_read(regmap, TPS65911_VDDCTRL_OP, &opvsel);
if (ret < 0)
return ret;
- ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_SR,
- &srvsel);
+ ret = regmap_read(regmap, TPS65911_VDDCTRL_SR, &srvsel);
if (ret < 0)
return ret;
sr = opvsel & VDDCTRL_OP_CMD_MASK;
@@ -514,13 +513,14 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
static int tps65910_get_voltage_sel(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int ret, reg, value, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
- ret = tps65910_reg_read(pmic->mfd, reg, &value);
+ ret = regmap_read(regmap, reg, &value);
if (ret < 0)
return ret;
@@ -556,12 +556,13 @@ static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
static int tps65911_get_voltage_sel(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int ret, id = rdev_get_id(dev);
unsigned int value, reg;
reg = pmic->get_ctrl_reg(id);
- ret = tps65910_reg_read(pmic->mfd, reg, &value);
+ ret = regmap_read(regmap, reg, &value);
if (ret < 0)
return ret;
@@ -594,7 +595,7 @@ static int tps65911_get_voltage_sel(struct regulator_dev *dev)
static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
unsigned selector)
{
- struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int id = rdev_get_id(dev), vsel;
int dcdc_mult = 0;
@@ -605,10 +606,9 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
dcdc_mult--;
vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
- tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD1,
- VDD1_VGAIN_SEL_MASK,
- dcdc_mult << VDD1_VGAIN_SEL_SHIFT);
- tps65910_reg_write(pmic->mfd, TPS65910_VDD1_OP, vsel);
+ regmap_update_bits(regmap, TPS65910_VDD1, VDD1_VGAIN_SEL_MASK,
+ dcdc_mult << VDD1_VGAIN_SEL_SHIFT);
+ regmap_write(regmap, TPS65910_VDD1_OP, vsel);
break;
case TPS65910_REG_VDD2:
dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
@@ -616,14 +616,14 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
dcdc_mult--;
vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
- tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD2,
- VDD1_VGAIN_SEL_MASK,
- dcdc_mult << VDD2_VGAIN_SEL_SHIFT);
- tps65910_reg_write(pmic->mfd, TPS65910_VDD2_OP, vsel);
+ regmap_update_bits(regmap, TPS65910_VDD2, VDD1_VGAIN_SEL_MASK,
+ dcdc_mult << VDD2_VGAIN_SEL_SHIFT);
+ regmap_write(regmap, TPS65910_VDD2_OP, vsel);
break;
case TPS65911_REG_VDDCTRL:
vsel = selector + 3;
- tps65910_reg_write(pmic->mfd, TPS65911_VDDCTRL_OP, vsel);
+ regmap_write(regmap, TPS65911_VDDCTRL_OP, vsel);
+ break;
}
return 0;
@@ -633,6 +633,7 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev,
unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
@@ -649,11 +650,11 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev,
case TPS65910_REG_VAUX2:
case TPS65910_REG_VAUX33:
case TPS65910_REG_VMMC:
- return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
- selector << LDO_SEL_SHIFT);
+ return regmap_update_bits(regmap, reg, LDO_SEL_MASK,
+ selector << LDO_SEL_SHIFT);
case TPS65910_REG_VBB:
- return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
- selector << BBCH_BBSEL_SHIFT);
+ return regmap_update_bits(regmap, reg, BBCH_BBSEL_MASK,
+ selector << BBCH_BBSEL_SHIFT);
}
return -EINVAL;
@@ -663,6 +664,7 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev,
unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+ struct regmap *regmap = rdev_get_regmap(dev);
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
@@ -673,21 +675,21 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev,
case TPS65911_REG_LDO1:
case TPS65911_REG_LDO2:
case TPS65911_REG_LDO4:
- return tps65910_reg_update_bits(pmic->mfd, reg, LDO1_SEL_MASK,
- selector << LDO_SEL_SHIFT);
+ return regmap_update_bits(regmap, reg, LDO1_SEL_MASK,
+ selector << LDO_SEL_SHIFT);
case TPS65911_REG_LDO3:
case TPS65911_REG_LDO5:
case TPS65911_REG_LDO6:
case TPS65911_REG_LDO7:
case TPS65911_REG_LDO8:
- return tps65910_reg_update_bits(pmic->mfd, reg, LDO3_SEL_MASK,
- selector << LDO_SEL_SHIFT);
+ return regmap_update_bits(regmap, reg, LDO3_SEL_MASK,
+ selector << LDO_SEL_SHIFT);
case TPS65910_REG_VIO:
- return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
- selector << LDO_SEL_SHIFT);
+ return regmap_update_bits(regmap, reg, LDO_SEL_MASK,
+ selector << LDO_SEL_SHIFT);
case TPS65910_REG_VBB:
- return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
- selector << BBCH_BBSEL_SHIFT);
+ return regmap_update_bits(regmap, reg, BBCH_BBSEL_MASK,
+ selector << BBCH_BBSEL_SHIFT);
}
return -EINVAL;
@@ -757,7 +759,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
}
/* Regulator ops (except VRTC) */
-static struct regulator_ops tps65910_ops_dcdc = {
+static const struct regulator_ops tps65910_ops_dcdc = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -770,7 +772,7 @@ static struct regulator_ops tps65910_ops_dcdc = {
.map_voltage = regulator_map_voltage_ascend,
};
-static struct regulator_ops tps65910_ops_vdd3 = {
+static const struct regulator_ops tps65910_ops_vdd3 = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -781,7 +783,7 @@ static struct regulator_ops tps65910_ops_vdd3 = {
.map_voltage = regulator_map_voltage_ascend,
};
-static struct regulator_ops tps65910_ops_vbb = {
+static const struct regulator_ops tps65910_ops_vbb = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -793,7 +795,7 @@ static struct regulator_ops tps65910_ops_vbb = {
.map_voltage = regulator_map_voltage_iterate,
};
-static struct regulator_ops tps65910_ops = {
+static const struct regulator_ops tps65910_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -805,7 +807,7 @@ static struct regulator_ops tps65910_ops = {
.map_voltage = regulator_map_voltage_ascend,
};
-static struct regulator_ops tps65911_ops = {
+static const struct regulator_ops tps65911_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -850,10 +852,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
/* External EN1 control */
if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1)
- ret = tps65910_reg_set_bits(mfd,
+ ret = regmap_set_bits(mfd->regmap,
TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
else
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
if (ret < 0) {
dev_err(mfd->dev,
@@ -863,10 +865,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
/* External EN2 control */
if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2)
- ret = tps65910_reg_set_bits(mfd,
+ ret = regmap_set_bits(mfd->regmap,
TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
else
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
if (ret < 0) {
dev_err(mfd->dev,
@@ -878,10 +880,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
if ((tps65910_chip_id(mfd) == TPS65910) &&
(id >= TPS65910_REG_VDIG1)) {
if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
- ret = tps65910_reg_set_bits(mfd,
+ ret = regmap_set_bits(mfd->regmap,
TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
else
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
if (ret < 0) {
dev_err(mfd->dev,
@@ -893,10 +895,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
/* Return if no external control is selected */
if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) {
/* Clear all sleep controls */
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
if (!ret)
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
if (ret < 0)
dev_err(mfd->dev,
@@ -917,39 +919,38 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
int sr_reg_add = pmic->get_ctrl_reg(id) + 2;
int opvsel, srvsel;
- ret = tps65910_reg_read(pmic->mfd, op_reg_add, &opvsel);
+ ret = regmap_read(mfd->regmap, op_reg_add, &opvsel);
if (ret < 0)
return ret;
- ret = tps65910_reg_read(pmic->mfd, sr_reg_add, &srvsel);
+ ret = regmap_read(mfd->regmap, sr_reg_add, &srvsel);
if (ret < 0)
return ret;
if (opvsel & VDD1_OP_CMD_MASK) {
u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
- ret = tps65910_reg_write(pmic->mfd, op_reg_add,
- reg_val);
+ ret = regmap_write(mfd->regmap, op_reg_add, reg_val);
if (ret < 0) {
dev_err(mfd->dev,
"Error in configuring op register\n");
return ret;
}
}
- ret = tps65910_reg_write(pmic->mfd, sr_reg_add, 0);
+ ret = regmap_write(mfd->regmap, sr_reg_add, 0);
if (ret < 0) {
dev_err(mfd->dev, "Error in setting sr register\n");
return ret;
}
}
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
if (!ret) {
if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
- ret = tps65910_reg_set_bits(mfd,
+ ret = regmap_set_bits(mfd->regmap,
TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
else
- ret = tps65910_reg_clear_bits(mfd,
+ ret = regmap_clear_bits(mfd->regmap,
TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
}
if (ret < 0)
@@ -1097,7 +1098,7 @@ static int tps65910_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pmic);
/* Give control of all register to control port */
- err = tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL,
+ err = regmap_set_bits(pmic->mfd->regmap, TPS65910_DEVCTRL,
DEVCTRL_SR_CTL_I2C_SEL_MASK);
if (err < 0)
return err;
@@ -1113,7 +1114,7 @@ static int tps65910_probe(struct platform_device *pdev)
* voltage level can go higher than expected or crash
* Workaround: use no synchronization of DCDC clocks
*/
- tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL,
+ regmap_clear_bits(pmic->mfd->regmap, TPS65910_DCDCCTRL,
DCDCCTRL_DCDCCKSYNC_MASK);
break;
case TPS65911:
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
index 63d6bbd4969b..b52d4f2874b7 100644
--- a/drivers/regulator/tps65912-regulator.c
+++ b/drivers/regulator/tps65912-regulator.c
@@ -57,7 +57,7 @@ static const struct linear_range tps65912_ldo_ranges[] = {
};
/* Operations permitted on DCDCx */
-static struct regulator_ops tps65912_ops_dcdc = {
+static const struct regulator_ops tps65912_ops_dcdc = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -67,7 +67,7 @@ static struct regulator_ops tps65912_ops_dcdc = {
};
/* Operations permitted on LDOx */
-static struct regulator_ops tps65912_ops_ldo = {
+static const struct regulator_ops tps65912_ops_ldo = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index ad2203d11a88..e43ed4d93f71 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -178,11 +178,9 @@ static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
{
struct wm831x_dcdc *dcdc = data;
- regulator_lock(dcdc->regulator);
regulator_notifier_call_chain(dcdc->regulator,
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
- regulator_unlock(dcdc->regulator);
return IRQ_HANDLED;
}
@@ -191,11 +189,9 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
{
struct wm831x_dcdc *dcdc = data;
- regulator_lock(dcdc->regulator);
regulator_notifier_call_chain(dcdc->regulator,
REGULATOR_EVENT_OVER_CURRENT,
NULL);
- regulator_unlock(dcdc->regulator);
return IRQ_HANDLED;
}
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index ff3d2bf50410..eade3ae3e333 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -99,11 +99,9 @@ static irqreturn_t wm831x_isink_irq(int irq, void *data)
{
struct wm831x_isink *isink = data;
- regulator_lock(isink->regulator);
regulator_notifier_call_chain(isink->regulator,
REGULATOR_EVENT_OVER_CURRENT,
NULL);
- regulator_unlock(isink->regulator);
return IRQ_HANDLED;
}
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 7b6cf4810cb7..e091b189ecc0 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -46,11 +46,9 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
{
struct wm831x_ldo *ldo = data;
- regulator_lock(ldo->regulator);
regulator_notifier_call_chain(ldo->regulator,
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
- regulator_unlock(ldo->regulator);
return IRQ_HANDLED;
}
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 2e7bfdf7c87b..6579bfdb0c26 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1089,7 +1089,6 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
- regulator_lock(rdev);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT,
@@ -1098,7 +1097,6 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
- regulator_unlock(rdev);
return IRQ_HANDLED;
}