Commit 30d46827 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull regulator updates from Mark Brown:
 "This has not been a busy release for the regulator framework, though
  we do have the first parts of some ongoing work from Bjorn Andersson
  to allow us to support more complex modern systems with dynamic
  configuration of regulators in suspend and idle states.

   - Support for device-specific properties on regulator nodes when
     using simplified DT parsing in the core from Krzysztof Kozlowski.

   - Restructuring of the load tracking code, intended to support future
     improvements in this area for more complex system designs.

   - New drivers for Maxim MAX77843 and Mediatek MT6397.

   - Lots of smaller fixes and improvements"

* tag 'regulator-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (29 commits)
  regulator: max77843: Add max77843 regulator driver
  regulator: Fix build breakage on !REGULATOR
  regulator: Build sysfs entries with static attribute groups
  regulator: qcom-rpm: Make it possible to specify supply
  regulator: core: Consolidate drms update handling
  regulator: qcom-rpm: signedness bug in probe()
  regulator: da9211: Add gpio control for enable/disable of buck
  regulator: qcom_rpm: Don't update vreg->uV/mV if rpm_reg_write fails
  regulator: lp872x: Remove **regulators from struct lp872x
  regulator: da9211: fix unmatched of_node
  regulator: Update documentation after renaming function argument
  regulator: axp20x: Migrate to regulator core's simplified DT parsing code
  regulator: axp20x: Fill regulators_node and of_match descriptor fields
  regulator: pfuze100-regulator: add pfuze3000 support
  regulator: max77686: Document gpio properties
  regulator: Allow parsing custom properties when using simplified DT parsing
  regulator: max77686: Add GPIO control
  regulator: Copy config passed during registration
  regulator: tps65023: Constify struct regmap_config and regulator_ops
  regulator: max8649: Constify struct regmap_config and regulator_ops
  ...
parents b0c1936c dd7c2e72
......@@ -39,6 +39,12 @@ to get matched with their hardware counterparts as follow:
-BUCKn : 1-4.
Use standard regulator bindings for it ('regulator-off-in-suspend').
LDO20, LDO21, LDO22, BUCK8 and BUCK9 can be configured to GPIO enable
control. To turn this feature on this property must be added to the regulator
sub-node:
- maxim,ena-gpios : one GPIO specifier enable control (the gpio
flags are actually ignored and always
ACTIVE_HIGH is used)
Example:
......@@ -65,4 +71,12 @@ Example:
regulator-always-on;
regulator-boot-on;
};
buck9_reg {
regulator-compatible = "BUCK9";
regulator-name = "CAM_ISP_CORE_1.2V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1200000>;
maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
};
}
......@@ -11,6 +11,7 @@ Required properties:
BUCKA and BUCKB.
Optional properties:
- enable-gpios: platform gpio for control of BUCKA/BUCKB.
- Any optional property defined in regulator.txt
Example 1) DA9211
......@@ -27,6 +28,7 @@ Example 1) DA9211
regulator-max-microvolt = <1570000>;
regulator-min-microamp = <2000000>;
regulator-max-microamp = <5000000>;
enable-gpios = <&gpio 27 0>;
};
BUCKB {
regulator-name = "VBUCKB";
......@@ -34,11 +36,12 @@ Example 1) DA9211
regulator-max-microvolt = <1570000>;
regulator-min-microamp = <2000000>;
regulator-max-microamp = <5000000>;
enable-gpios = <&gpio 17 0>;
};
};
};
Example 2) DA92113
Example 2) DA9213
pmic: da9213@68 {
compatible = "dlg,da9213";
reg = <0x68>;
......@@ -51,6 +54,7 @@ Example 2) DA92113
regulator-max-microvolt = <1570000>;
regulator-min-microamp = <3000000>;
regulator-max-microamp = <6000000>;
enable-gpios = <&gpio 27 0>;
};
BUCKB {
regulator-name = "VBUCKB";
......@@ -58,6 +62,7 @@ Example 2) DA92113
regulator-max-microvolt = <1570000>;
regulator-min-microamp = <3000000>;
regulator-max-microamp = <6000000>;
enable-gpios = <&gpio 17 0>;
};
};
};
......@@ -2,7 +2,7 @@ Intersil ISL9305/ISL9305H voltage regulator
Required properties:
- compatible: "isl,isl9305" or "isl,isl9305h"
- compatible: "isil,isl9305" or "isil,isl9305h"
- reg: I2C slave address, usually 0x68.
- regulators: A node that houses a sub-node for each regulator within the
device. Each sub-node is identified using the node's name, with valid
......@@ -19,7 +19,7 @@ Optional properties:
Example
pmic: isl9305@68 {
compatible = "isl,isl9305";
compatible = "isil,isl9305";
reg = <0x68>;
VINDCD1-supply = <&system_power>;
......
Mediatek MT6397 Regulator Driver
Required properties:
- compatible: "mediatek,mt6397-regulator"
- mt6397regulator: List of regulators provided by this controller. It is named
according to its regulator type, buck_<name> and ldo_<name>.
The definition for each of these nodes is defined using the standard binding
for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
The valid names for regulators are::
BUCK:
buck_vpca15, buck_vpca7, buck_vsramca15, buck_vsramca7, buck_vcore, buck_vgpu,
buck_vdrm, buck_vio18
LDO:
ldo_vtcxo, ldo_va28, ldo_vcama, ldo_vio28, ldo_vusb, ldo_vmc, ldo_vmch,
ldo_vemc3v3, ldo_vgp1, ldo_vgp2, ldo_vgp3, ldo_vgp4, ldo_vgp5, ldo_vgp6,
ldo_vibr
Example:
pmic {
compatible = "mediatek,mt6397";
mt6397regulator: mt6397regulator {
compatible = "mediatek,mt6397-regulator";
mt6397_vpca15_reg: buck_vpca15 {
regulator-compatible = "buck_vpca15";
regulator-name = "vpca15";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <200>;
};
mt6397_vpca7_reg: buck_vpca7 {
regulator-compatible = "buck_vpca7";
regulator-name = "vpca7";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <115>;
};
mt6397_vsramca15_reg: buck_vsramca15 {
regulator-compatible = "buck_vsramca15";
regulator-name = "vsramca15";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <115>;
};
mt6397_vsramca7_reg: buck_vsramca7 {
regulator-compatible = "buck_vsramca7";
regulator-name = "vsramca7";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <115>;
};
mt6397_vcore_reg: buck_vcore {
regulator-compatible = "buck_vcore";
regulator-name = "vcore";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <115>;
};
mt6397_vgpu_reg: buck_vgpu {
regulator-compatible = "buck_vgpu";
regulator-name = "vgpu";
regulator-min-microvolt = < 700000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <115>;
};
mt6397_vdrm_reg: buck_vdrm {
regulator-compatible = "buck_vdrm";
regulator-name = "vdrm";
regulator-min-microvolt = < 800000>;
regulator-max-microvolt = <1400000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <500>;
};
mt6397_vio18_reg: buck_vio18 {
regulator-compatible = "buck_vio18";
regulator-name = "vio18";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2120000>;
regulator-ramp-delay = <12500>;
regulator-enable-ramp-delay = <500>;
};
mt6397_vtcxo_reg: ldo_vtcxo {
regulator-compatible = "ldo_vtcxo";
regulator-name = "vtcxo";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <90>;
};
mt6397_va28_reg: ldo_va28 {
regulator-compatible = "ldo_va28";
regulator-name = "va28";
/* fixed output 2.8 V */
regulator-enable-ramp-delay = <218>;
};
mt6397_vcama_reg: ldo_vcama {
regulator-compatible = "ldo_vcama";
regulator-name = "vcama";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vio28_reg: ldo_vio28 {
regulator-compatible = "ldo_vio28";
regulator-name = "vio28";
/* fixed output 2.8 V */
regulator-enable-ramp-delay = <240>;
};
mt6397_usb_reg: ldo_vusb {
regulator-compatible = "ldo_vusb";
regulator-name = "vusb";
/* fixed output 3.3 V */
regulator-enable-ramp-delay = <218>;
};
mt6397_vmc_reg: ldo_vmc {
regulator-compatible = "ldo_vmc";
regulator-name = "vmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vmch_reg: ldo_vmch {
regulator-compatible = "ldo_vmch";
regulator-name = "vmch";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vemc_3v3_reg: ldo_vemc3v3 {
regulator-compatible = "ldo_vemc3v3";
regulator-name = "vemc_3v3";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vgp1_reg: ldo_vgp1 {
regulator-compatible = "ldo_vgp1";
regulator-name = "vcamd";
regulator-min-microvolt = <1220000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <240>;
};
mt6397_vgp2_reg: ldo_vgp2 {
egulator-compatible = "ldo_vgp2";
regulator-name = "vcamio";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vgp3_reg: ldo_vgp3 {
regulator-compatible = "ldo_vgp3";
regulator-name = "vcamaf";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vgp4_reg: ldo_vgp4 {
regulator-compatible = "ldo_vgp4";
regulator-name = "vgp4";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vgp5_reg: ldo_vgp5 {
regulator-compatible = "ldo_vgp5";
regulator-name = "vgp5";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3000000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vgp6_reg: ldo_vgp6 {
regulator-compatible = "ldo_vgp6";
regulator-name = "vgp6";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
mt6397_vibr_reg: ldo_vibr {
regulator-compatible = "ldo_vibr";
regulator-name = "vibr";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
};
};
PFUZE100 family of regulators
Required properties:
- compatible: "fsl,pfuze100" or "fsl,pfuze200"
- compatible: "fsl,pfuze100", "fsl,pfuze200", "fsl,pfuze3000"
- reg: I2C slave address
Required child node:
......@@ -14,6 +14,8 @@ Required child node:
sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6
--PFUZE200
sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6
--PFUZE3000
sw1a,sw1b,sw2,sw3,swbst,vsnvs,vrefddr,vldo1,vldo2,vccsd,v33,vldo3,vldo4
Each regulator is defined using the standard binding for regulators.
......@@ -205,3 +207,93 @@ Example 2: PFUZE200
};
};
};
Example 3: PFUZE3000
pmic: pfuze3000@08 {
compatible = "fsl,pfuze3000";
reg = <0x08>;
regulators {
sw1a_reg: sw1a {
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1475000>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <6250>;
};
/* use sw1c_reg to align with pfuze100/pfuze200 */
sw1c_reg: sw1b {
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1475000>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <6250>;
};
sw2_reg: sw2 {
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
sw3a_reg: sw3 {
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1650000>;
regulator-boot-on;
regulator-always-on;
};
swbst_reg: swbst {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5150000>;
};
snvs_reg: vsnvs {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3000000>;
regulator-boot-on;
regulator-always-on;
};
vref_reg: vrefddr {
regulator-boot-on;
regulator-always-on;
};
vgen1_reg: vldo1 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
vgen2_reg: vldo2 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1550000>;
};
vgen3_reg: vccsd {
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
vgen4_reg: v33 {
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <3300000>;
};
vgen5_reg: vldo3 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
vgen6_reg: vldo4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
};
};
......@@ -414,6 +414,14 @@ config REGULATOR_MAX77802
Exynos5420/Exynos5800 SoCs to control various voltages.
It includes support for control of voltage and ramp speed.
config REGULATOR_MAX77843
tristate "Maxim 77843 regulator"
depends on MFD_MAX77843
help
This driver controls a Maxim 77843 regulator.
The regulator include two 'SAFEOUT' for USB(Universal Serial Bus)
This is suitable for Exynos5433 SoC chips.
config REGULATOR_MC13XXX_CORE
tristate
......@@ -433,6 +441,15 @@ config REGULATOR_MC13892
Say y here to support the regulators found on the Freescale MC13892
PMIC.
config REGULATOR_MT6397
tristate "MediaTek MT6397 PMIC"
depends on MFD_MT6397
help
Say y here to select this option to enable the power regulator of
MediaTek MT6397 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS
......
......@@ -55,9 +55,11 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
......
......@@ -32,11 +32,13 @@
#define AXP20X_FREQ_DCDC_MASK 0x0f
#define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
_emask, _enable_val, _disable_val) \
#define AXP20X_DESC_IO(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \
_ereg, _emask, _enable_val, _disable_val) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
......@@ -52,11 +54,13 @@
.ops = &axp20x_ops, \
}
#define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
_emask) \
#define AXP20X_DESC(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \
_ereg, _emask) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
......@@ -70,10 +74,12 @@
.ops = &axp20x_ops, \
}
#define AXP20X_DESC_FIXED(_id, _supply, _volt) \
#define AXP20X_DESC_FIXED(_id, _match, _supply, _volt) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = 1, \
......@@ -82,10 +88,13 @@
.ops = &axp20x_ops_fixed \
}
#define AXP20X_DESC_TABLE(_id, _supply, _table, _vreg, _vmask, _ereg, _emask) \
#define AXP20X_DESC_TABLE(_id, _match, _supply, _table, _vreg, _vmask, _ereg, \
_emask) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = ARRAY_SIZE(_table), \
......@@ -127,36 +136,20 @@ static struct regulator_ops axp20x_ops = {
};
static const struct regulator_desc axp20x_regulators[] = {
AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f,
AXP20X_PWR_OUT_CTRL, 0x10),
AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f,
AXP20X_PWR_OUT_CTRL, 0x02),
AXP20X_DESC_FIXED(LDO1, "acin", 1300),
AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0,
AXP20X_PWR_OUT_CTRL, 0x04),
AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f,
AXP20X_PWR_OUT_CTRL, 0x40),
AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f,
AXP20X_PWR_OUT_CTRL, 0x08),
AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0,
AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED,
AXP20X_IO_DISABLED),
};
#define AXP_MATCH(_name, _id) \
[AXP20X_##_id] = { \
.name = #_name, \
.driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \
}
static struct of_regulator_match axp20x_matches[] = {
AXP_MATCH(dcdc2, DCDC2),
AXP_MATCH(dcdc3, DCDC3),
AXP_MATCH(ldo1, LDO1),
AXP_MATCH(ldo2, LDO2),
AXP_MATCH(ldo3, LDO3),
AXP_MATCH(ldo4, LDO4),
AXP_MATCH(ldo5, LDO5),
AXP20X_DESC(DCDC2, "dcdc2", "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT,
0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
AXP20X_DESC(DCDC3, "dcdc3", "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT,
0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
AXP20X_DESC_FIXED(LDO1, "ldo1", "acin", 1300),
AXP20X_DESC(LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
AXP20X_DESC(LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT,
0x7f, AXP20X_PWR_OUT_CTRL, 0x40),
AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data,
AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08),
AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07,
AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
};
static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
......@@ -193,13 +186,6 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
if (!regulators) {
dev_warn(&pdev->dev, "regulators node not found\n");
} else {
ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches,
ARRAY_SIZE(axp20x_matches));
if (ret < 0) {
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
return ret;
}
dcdcfreq = 1500;
of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
......@@ -233,23 +219,17 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
{
struct regulator_dev *rdev;
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct regulator_init_data *init_data;
struct regulator_config config = {
.dev = pdev->dev.parent,
.regmap = axp20x->regmap,
};
int ret, i;
u32 workmode;
ret = axp20x_regulator_parse_dt(pdev);
if (ret)
return ret;
/* This only sets the dcdc freq. Ignore any errors */
axp20x_regulator_parse_dt(pdev);
for (i = 0; i < AXP20X_REG_ID_MAX; i++) {
init_data = axp20x_matches[i].init_data;
config.dev = pdev->dev.parent;
config.init_data = init_data;
config.regmap = axp20x->regmap;
config.of_node = axp20x_matches[i].of_node;
rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
&config);
if (IS_ERR(rdev)) {
......@@ -259,7 +239,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
return PTR_ERR(rdev);
}
ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode",
ret = of_property_read_u32(rdev->dev.of_node,
"x-powers,dcdc-workmode",
&workmode);
if (!ret) {
if (axp20x_set_dcdc_workmode(rdev, i, workmode))
......
This diff is collapsed.
......@@ -24,6 +24,7 @@
#include <linux/regmap.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/da9211.h>
#include "da9211-regulator.h"
......@@ -276,7 +277,10 @@ static struct da9211_pdata *da9211_parse_regulators_dt(
continue;
pdata->init_data[n] = da9211_matches[i].init_data;
pdata->reg_node[n] = da9211_matches[i].of_node;
pdata->gpio_ren[n] =
of_get_named_gpio(da9211_matches[i].of_node,
"enable-gpios", 0);
n++;
}
......@@ -364,7 +368,15 @@ static int da9211_regulator_init(struct da9211 *chip)
config.dev = chip->dev;
config.driver_data = chip;
config.regmap = chip->regmap;
config.of_node = chip->dev->of_node;
config.of_node = chip->pdata->reg_node[i];
if (gpio_is_valid(chip->pdata->gpio_ren[i])) {
config.ena_gpio = chip->pdata->gpio_ren[i];
config.ena_gpio_initialized = true;
} else {
config.ena_gpio = -EINVAL;
config.ena_gpio_initialized = false;
}
chip->rdev[i] = devm_regulator_register(chip->dev,
&da9211_regulators[i], &config);
......
......@@ -147,7 +147,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
static int slew_rates[] = {
static const int slew_rates[] = {
64000,
32000,
16000,
......@@ -296,7 +296,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
return PTR_ERR_OR_ZERO(di->rdev);
}
static struct regmap_config fan53555_regmap_config = {
static const struct regmap_config fan53555_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
......
......@@ -38,11 +38,13 @@ struct regulator {
#ifdef CONFIG_OF
struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
struct regulator_config *config,
struct device_node **node);
#else
static inline struct regulator_init_data *
regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
struct regulator_config *config,
struct device_node **node)
{
return NULL;
......
......@@ -177,8 +177,10 @@ static int isl9305_i2c_probe(struct i2c_client *i2c,
#ifdef CONFIG_OF
static const struct of_device_id isl9305_dt_ids[] = {
{ .compatible = "isl,isl9305" },
{ .compatible = "isl,isl9305h" },
{ .compatible = "isl,isl9305" }, /* for backward compat., don't use */
{ .compatible = "isil,isl9305" },
{ .compatible = "isl,isl9305h" }, /* for backward compat., don't use */
{ .compatible = "isil,isl9305h" },
{},
};
#endif
......
......@@ -106,7 +106,6 @@ struct lp872x {
struct device *dev;
enum lp872x_id chipid;
struct lp872x_platform_data *pdata;
struct regulator_dev **regulators;
int num_regulators;
enum lp872x_dvs_state dvs_pin;
int dvs_gpio;
......@@ -801,8 +800,6 @@ static int lp872x_regulator_register(struct lp872x *lp)
dev_err(lp->dev, "regulator register err");
return PTR_ERR(rdev);
}
*(lp->regulators + i) = rdev;
}
return 0;
......@@ -906,7 +903,7 @@ static struct lp872x_platform_data
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
int ret, size, num_regulators;
int ret;
const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS,
......@@ -918,38 +915,27 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
goto err_mem;
num_regulators = lp872x_num_regulators[id->driver_data];
size = sizeof(struct regulator_dev *) * num_regulators;
return -ENOMEM;
lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL);
if (!lp->regulators)
goto err_mem;
lp->num_regulators = lp872x_num_regulators[id->driver_data];
lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config);
if (IS_ERR(lp->regmap)) {
ret = PTR_ERR(lp->regmap);
dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
goto err_dev;
return ret;
}
lp->dev = &cl->dev;
lp->pdata = dev_get_platdata(&cl->dev);
lp->chipid = id->driver_data;
lp->num_regulators = num_regulators;
i2c_set_clientdata(cl, lp);
ret = lp872x_config(lp);
if (ret)
goto err_dev;
return ret;
return lp872x_regulator_register(lp);
err_mem:
return -ENOMEM;
err_dev:
return ret;
}
static const struct of_device_id lp872x_dt_ids[] = {
......
......@@ -103,6 +103,8 @@ static struct regulator_ops max14577_charger_ops = {
static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_SAFEOUT] = {
.name = "SAFEOUT",
.of_match = of_match_ptr("SAFEOUT"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
......@@ -114,6 +116,8 @@ static const struct regulator_desc max14577_supported_regulators[] = {
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
......@@ -137,6 +141,8 @@ static struct regulator_ops max77836_ldo_ops = {
static const struct regulator_desc max77836_supported_regulators[] = {
[MAX14577_SAFEOUT] = {
.name = "SAFEOUT",
.of_match = of_match_ptr("SAFEOUT"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
......@@ -148,6 +154,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
......@@ -157,6 +165,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
},
[MAX77836_LDO1] = {
.name = "LDO1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO1,
.ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE,
......@@ -171,6 +181,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
},
[MAX77836_LDO2] = {
.name = "LDO2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO2,
.ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE,
......@@ -198,43 +210,6 @@ static struct of_regulator_match max77836_regulator_matches[] = {
{ .name = "LDO2", },
};
static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev,
enum maxim_device_type dev_type)
{
int ret;
struct device_node *np;
struct of_regulator_match *regulator_matches;
unsigned int regulator_matches_size;
np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
if (!np) {
dev_err(&pdev->dev, "Failed to get child OF node for regulators\n");
return -EINVAL;
}
switch (dev_type) {
case MAXIM_DEVICE_TYPE_MAX77836:
regulator_matches = max77836_regulator_matches;
regulator_matches_size = ARRAY_SIZE(max77836_regulator_matches);
break;
case MAXIM_DEVICE_TYPE_MAX14577:
default:
regulator_matches = max14577_regulator_matches;
regulator_matches_size = ARRAY_SIZE(max14577_regulator_matches);
}
ret = of_regulator_match(&pdev->dev, np, regulator_matches,
regulator_matches_size);
if (ret < 0)
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
else
ret = 0;
of_node_put(np);
return ret;
}
static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type)
{
......@@ -261,11 +236,6 @@ static inline struct device_node *match_of_node(int index,
}
}
#else /* CONFIG_OF */
static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev,
enum maxim_device_type dev_type)
{
return 0;
}
static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type)
{
......@@ -308,16 +278,12 @@ static int max14577_regulator_probe(struct platform_device *pdev)
{
struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev);
int i, ret;
int i, ret = 0;
struct regulator_config config = {};
const struct regulator_desc *supported_regulators;
unsigned int supported_regulators_size;
enum maxim_device_type dev_type = max14577->dev_type;
ret = max14577_regulator_dt_parse_pdata(pdev, dev_type);
if (ret)
return ret;
switch (dev_type) {
case MAXIM_DEVICE_TYPE_MAX77836:
supported_regulators = max77836_supported_regulators;
......@@ -329,7 +295,7 @@ static int max14577_regulator_probe(struct platform_device *pdev)
supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators);
}
config.dev = &pdev->dev;
config.dev = max14577->dev;
config.driver_data = max14577;
for (i = 0; i < supported_regulators_size; i++) {
......
......@@ -26,6 +26,7 @@
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
......@@ -45,6 +46,11 @@
#define MAX77686_DVS_MINUV 600000
#define MAX77686_DVS_UVSTEP 12500
/*
* Value for configuring buck[89] and LDO{20,21,22} as GPIO control.
* It is the same as 'off' for other regulators.
*/
#define MAX77686_GPIO_CONTROL 0x0
/*
* Values used for configuring LDOs and bucks.
* Forcing low power mode: LDO1, 3-5, 9, 13, 17-26
......@@ -82,6 +88,8 @@ enum max77686_ramp_rate {
};
struct max77686_data {
u64 gpio_enabled:MAX77686_REGULATORS;
/* Array indexed by regulator id */
unsigned int opmode[MAX77686_REGULATORS];
};
......@@ -100,6 +108,26 @@ static unsigned int max77686_get_opmode_shift(int id)
}
}
/*
* When regulator is configured for GPIO control then it
* replaces "normal" mode. Any change from low power mode to normal
* should actually change to GPIO control.
* Map normal mode to proper value for such regulators.
*/
static unsigned int max77686_map_normal_mode(struct max77686_data *max77686,
int id)
{
switch (id) {
case MAX77686_BUCK8:
case MAX77686_BUCK9:
case MAX77686_LDO20 ... MAX77686_LDO22:
if (max77686->gpio_enabled & (1 << id))
return MAX77686_GPIO_CONTROL;
}
return MAX77686_NORMAL;
}
/* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */
static int max77686_set_suspend_disable(struct regulator_dev *rdev)
{
......@@ -136,7 +164,7 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev,
val = MAX77686_LDO_LOWPOWER_PWRREQ;
break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
val = MAX77686_NORMAL;
val = max77686_map_normal_mode(max77686, id);
break;
default:
pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
......@@ -160,7 +188,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
{
unsigned int val;
struct max77686_data *max77686 = rdev_get_drvdata(rdev);
int ret;
int ret, id = rdev_get_id(rdev);
switch (mode) {
case REGULATOR_MODE_STANDBY: /* switch off */
......@@ -170,7 +198,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
val = MAX77686_LDO_LOWPOWER_PWRREQ;
break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
val = MAX77686_NORMAL;
val = max77686_map_normal_mode(max77686, id);
break;
default:
pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
......@@ -184,7 +212,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
if (ret)
return ret;
max77686->opmode[rdev_get_id(rdev)] = val;
max77686->opmode[id] = val;
return 0;
}
......@@ -197,7 +225,7 @@ static int max77686_enable(struct regulator_dev *rdev)
shift = max77686_get_opmode_shift(id);
if (max77686->opmode[id] == MAX77686_OFF_PWRREQ)
max77686->opmode[id] = MAX77686_NORMAL;
max77686->opmode[id] = max77686_map_normal_mode(max77686, id);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
......@@ -229,6 +257,36 @@ static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
MAX77686_RAMP_RATE_MASK, ramp_value << 6);
}
static int max77686_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct max77686_data *max77686 = config->driver_data;
switch (desc->id) {
case MAX77686_BUCK8:
case MAX77686_BUCK9:
case MAX77686_LDO20 ... MAX77686_LDO22:
config->ena_gpio = of_get_named_gpio(np,
"maxim,ena-gpios", 0);
config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
config->ena_gpio_initialized = true;
break;
default:
return 0;
}
if (gpio_is_valid(config->ena_gpio)) {
max77686->gpio_enabled |= (1 << desc->id);
return regmap_update_bits(config->regmap, desc->enable_reg,
desc->enable_mask,
MAX77686_GPIO_CONTROL);
}
return 0;
}
static struct regulator_ops max77686_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
......@@ -283,6 +341,7 @@ static struct regulator_ops max77686_buck_dvs_ops = {
.name = "LDO"#num, \
.of_match = of_match_ptr("LDO"#num), \
.regulators_node = of_match_ptr("voltage-regulators"), \
.of_parse_cb = max77686_of_parse_cb, \
.id = MAX77686_LDO##num, \
.ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \
......@@ -355,6 +414,7 @@ static struct regulator_ops max77686_buck_dvs_ops = {
.name = "BUCK"#num, \
.of_match = of_match_ptr("BUCK"#num), \
.regulators_node = of_match_ptr("voltage-regulators"), \
.of_parse_cb = max77686_of_parse_cb, \
.id = MAX77686_BUCK##num, \
.ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \
......
/*
* max77843.c - Regulator driver for the Maxim MAX77843
*
* Copyright (C) 2015 Samsung Electronics
* Author: Jaewon Kim <jaewon02.kim@samsung.com>
* Author: Beomho Seo <beomho.seo@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/max77843-private.h>
#include <linux/regulator/of_regulator.h>
enum max77843_regulator_type {
MAX77843_SAFEOUT1 = 0,
MAX77843_SAFEOUT2,
MAX77843_CHARGER,
MAX77843_NUM,
};
static const unsigned int max77843_safeout_voltage_table[] = {
4850000,
4900000,
4950000,
3300000,
};
static int max77843_reg_is_enabled(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev->regmap;
int ret;
unsigned int reg;
ret = regmap_read(regmap, rdev->desc->enable_reg, &reg);
if (ret) {
dev_err(&rdev->dev, "Fialed to read charger register\n");
return ret;
}
return (reg & rdev->desc->enable_mask) == rdev->desc->enable_mask;
}
static int max77843_reg_get_current_limit(struct regulator_dev *rdev)
{
struct regmap *regmap = rdev->regmap;
unsigned int chg_min_uA = rdev->constraints->min_uA;
unsigned int chg_max_uA = rdev->constraints->max_uA;
unsigned int val;
int ret;
unsigned int reg, sel;
ret = regmap_read(regmap, MAX77843_CHG_REG_CHG_CNFG_02, &reg);
if (ret) {
dev_err(&rdev->dev, "Failed to read charger register\n");
return ret;
}
sel = reg & MAX77843_CHG_FAST_CHG_CURRENT_MASK;
if (sel < 0x03)
sel = 0;
else
sel -= 2;
val = chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel;
if (val > chg_max_uA)
return -EINVAL;
return val;
}
static int max77843_reg_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct regmap *regmap = rdev->regmap;
unsigned int chg_min_uA = rdev->constraints->min_uA;
int sel = 0;
while (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel < min_uA)
sel++;
if (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel > max_uA)
return -EINVAL;
sel += 2;
return regmap_write(regmap, MAX77843_CHG_REG_CHG_CNFG_02, sel);
}
static struct regulator_ops max77843_charger_ops = {
.is_enabled = max77843_reg_is_enabled,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_current_limit = max77843_reg_get_current_limit,
.set_current_limit = max77843_reg_set_current_limit,
};
static struct regulator_ops max77843_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_table,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_desc max77843_supported_regulators[] = {
[MAX77843_SAFEOUT1] = {
.name = "SAFEOUT1",
.id = MAX77843_SAFEOUT1,
.ops = &max77843_regulator_ops,
.of_match = of_match_ptr("SAFEOUT1"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table),
.volt_table = max77843_safeout_voltage_table,
.enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
.enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT1,
.vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
.vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT1_MASK,
},
[MAX77843_SAFEOUT2] = {
.name = "SAFEOUT2",
.id = MAX77843_SAFEOUT2,
.ops = &max77843_regulator_ops,
.of_match = of_match_ptr("SAFEOUT2"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table),
.volt_table = max77843_safeout_voltage_table,
.enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
.enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT2,
.vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
.vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT2_MASK,
},
[MAX77843_CHARGER] = {
.name = "CHARGER",
.id = MAX77843_CHARGER,
.ops = &max77843_charger_ops,
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
.enable_mask = MAX77843_CHG_MASK,
},
};
static struct regmap *max77843_get_regmap(struct max77843 *max77843, int reg_id)
{
switch (reg_id) {
case MAX77843_SAFEOUT1:
case MAX77843_SAFEOUT2:
return max77843->regmap;
case MAX77843_CHARGER:
return max77843->regmap_chg;
default:
return max77843->regmap;
}
}
static int max77843_regulator_probe(struct platform_device *pdev)
{
struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = {};
int i;
config.dev = max77843->dev;
config.driver_data = max77843;
for (i = 0; i < ARRAY_SIZE(max77843_supported_regulators); i++) {
struct regulator_dev *regulator;
config.regmap = max77843_get_regmap(max77843,
max77843_supported_regulators[i].id);
regulator = devm_regulator_register(&pdev->dev,
&max77843_supported_regulators[i], &config);
if (IS_ERR(regulator)) {
dev_err(&pdev->dev,
"Failed to regiser regulator-%d\n", i);
return PTR_ERR(regulator);
}
}
return 0;
}
static const struct platform_device_id max77843_regulator_id[] = {
{ "max77843-regulator", },
{ /* sentinel */ },
};
static struct platform_driver max77843_regulator_driver = {
.driver = {
.name = "max77843-regulator",
},
.probe = max77843_regulator_probe,
.id_table = max77843_regulator_id,
};
static int __init max77843_regulator_init(void)
{
return platform_driver_register(&max77843_regulator_driver);
}
subsys_initcall(max77843_regulator_init);
static void __exit max77843_regulator_exit(void)
{
platform_driver_unregister(&max77843_regulator_driver);
}
module_exit(max77843_regulator_exit);
MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
MODULE_DESCRIPTION("Maxim MAX77843 regulator driver");
MODULE_LICENSE("GPL");
......@@ -115,7 +115,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
static struct regulator_ops max8649_dcdc_ops = {
static const struct regulator_ops max8649_dcdc_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
......@@ -143,7 +143,7 @@ static struct regulator_desc dcdc_desc = {
.enable_is_inverted = true,
};
static struct regmap_config max8649_regmap_config = {
static const struct regmap_config max8649_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
......
This diff is collapsed.
......@@ -270,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match);
struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
struct regulator_config *config,
struct device_node **node)
{
struct device_node *search, *child;
......@@ -307,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
break;
}
if (desc->of_parse_cb) {
if (desc->of_parse_cb(child, desc, config)) {
dev_err(dev,
"driver callback failed to parse DT for regulator %s\n",
child->name);
init_data = NULL;
break;
}
}
of_node_get(child);
*node = child;
break;
......
......@@ -56,7 +56,7 @@
#define PFUZE100_VGEN5VOL 0x70
#define PFUZE100_VGEN6VOL 0x71
enum chips { PFUZE100, PFUZE200 };
enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 };
struct pfuze_regulator {
struct regulator_desc desc;
......@@ -80,9 +80,18 @@ static const int pfuze100_vsnvs[] = {
1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000,
};
static const int pfuze3000_sw2lo[] = {
1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000,
};
static const int pfuze3000_sw2hi[] = {
2500000, 2800000, 2850000, 3000000, 3100000, 3150000, 3200000, 3300000,
};
static const struct i2c_device_id pfuze_device_id[] = {
{.name = "pfuze100", .driver_data = PFUZE100},
{.name = "pfuze200", .driver_data = PFUZE200},
{.name = "pfuze3000", .driver_data = PFUZE3000},
{ }
};
MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
......@@ -90,6 +99,7 @@ MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
static const struct of_device_id pfuze_dt_ids[] = {
{ .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
{ .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
{ .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000},
{ }
};
MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
......@@ -219,6 +229,60 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
.stby_mask = 0x20, \
}
#define PFUZE3000_VCC_REG(_chip, _name, base, min, max, step) { \
.desc = { \
.name = #_name, \
.n_voltages = ((max) - (min)) / (step) + 1, \
.ops = &pfuze100_ldo_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.min_uV = (min), \
.uV_step = (step), \
.vsel_reg = (base), \
.vsel_mask = 0x3, \
.enable_reg = (base), \
.enable_mask = 0x10, \
}, \
.stby_reg = (base), \
.stby_mask = 0x20, \
}
#define PFUZE3000_SW2_REG(_chip, _name, base, min, max, step) { \
.desc = { \
.name = #_name,\
.n_voltages = ((max) - (min)) / (step) + 1, \
.ops = &pfuze100_sw_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.min_uV = (min), \
.uV_step = (step), \
.vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
.vsel_mask = 0x7, \
}, \
.stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
.stby_mask = 0x7, \
}
#define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \
.desc = { \
.name = #_name,\
.n_voltages = ((max) - (min)) / (step) + 1, \
.ops = &pfuze100_sw_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.min_uV = (min), \
.uV_step = (step), \
.vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
.vsel_mask = 0xf, \
}, \
.stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
.stby_mask = 0xf, \
}
/* PFUZE100 */
static struct pfuze_regulator pfuze100_regulators[] = {
PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
......@@ -254,6 +318,22 @@ static struct pfuze_regulator pfuze200_regulators[] = {
PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
};
static struct pfuze_regulator pfuze3000_regulators[] = {
PFUZE100_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 700000, 1475000, 25000),
PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000),
PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo),
PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000),
PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst),
PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
PFUZE100_FIXED_REG(PFUZE3000, VREFDDR, PFUZE100_VREFDDRCON, 750000),
PFUZE100_VGEN_REG(PFUZE3000, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000),
PFUZE100_VGEN_REG(PFUZE3000, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
PFUZE3000_VCC_REG(PFUZE3000, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000),
PFUZE3000_VCC_REG(PFUZE3000, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000),
PFUZE100_VGEN_REG(PFUZE3000, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
};
static struct pfuze_regulator *pfuze_regulators;
#ifdef CONFIG_OF
......@@ -294,6 +374,24 @@ static struct of_regulator_match pfuze200_matches[] = {
{ .name = "vgen6", },
};
/* PFUZE3000 */
static struct of_regulator_match pfuze3000_matches[] = {
{ .name = "sw1a", },
{ .name = "sw1b", },
{ .name = "sw2", },
{ .name = "sw3", },
{ .name = "swbst", },
{ .name = "vsnvs", },
{ .name = "vrefddr", },
{ .name = "vldo1", },
{ .name = "vldo2", },
{ .name = "vccsd", },
{ .name = "v33", },
{ .name = "vldo3", },
{ .name = "vldo4", },
};
static struct of_regulator_match *pfuze_matches;
static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
......@@ -313,6 +411,11 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
}
switch (chip->chip_id) {
case PFUZE3000:
pfuze_matches = pfuze3000_matches;
ret = of_regulator_match(dev, parent, pfuze3000_matches,
ARRAY_SIZE(pfuze3000_matches));
break;
case PFUZE200:
pfuze_matches = pfuze200_matches;
ret = of_regulator_match(dev, parent, pfuze200_matches,
......@@ -378,7 +481,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
* as ID=8 in PFUZE100
*/
dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
} else if ((value & 0x0f) != pfuze_chip->chip_id) {
} else if ((value & 0x0f) != pfuze_chip->chip_id &&
(value & 0xf0) >> 4 != pfuze_chip->chip_id) {
/* device id NOT match with your setting */
dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
return -ENODEV;
......@@ -417,7 +521,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
int i, ret;
const struct of_device_id *match;
u32 regulator_num;
u32 sw_check_start, sw_check_end;
u32 sw_check_start, sw_check_end, sw_hi = 0x40;
pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip),
GFP_KERNEL);
......@@ -458,13 +562,19 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
/* use the right regulators after identify the right device */
switch (pfuze_chip->chip_id) {
case PFUZE3000:
pfuze_regulators = pfuze3000_regulators;
regulator_num = ARRAY_SIZE(pfuze3000_regulators);
sw_check_start = PFUZE3000_SW2;
sw_check_end = PFUZE3000_SW2;
sw_hi = 1 << 3;
break;
case PFUZE200:
pfuze_regulators = pfuze200_regulators;
regulator_num = ARRAY_SIZE(pfuze200_regulators);
sw_check_start = PFUZE200_SW2;
sw_check_end = PFUZE200_SW3B;
break;
case PFUZE100:
default:
pfuze_regulators = pfuze100_regulators;
......@@ -474,7 +584,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
break;
}
dev_info(&client->dev, "pfuze%s found.\n",
(pfuze_chip->chip_id == PFUZE100) ? "100" : "200");
(pfuze_chip->chip_id == PFUZE100) ? "100" :
((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000"));
memcpy(pfuze_chip->regulator_descs, pfuze_regulators,
sizeof(pfuze_chip->regulator_descs));
......@@ -498,10 +609,15 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
/* SW2~SW4 high bit check and modify the voltage value table */
if (i >= sw_check_start && i <= sw_check_end) {
regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
if (val & 0x40) {
desc->min_uV = 800000;
desc->uV_step = 50000;
desc->n_voltages = 51;
if (val & sw_hi) {
if (pfuze_chip->chip_id == PFUZE3000) {
desc->volt_table = pfuze3000_sw2hi;
desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi);
} else {
desc->min_uV = 800000;
desc->uV_step = 50000;
desc->n_voltages = 51;
}
}
}
......
......@@ -227,9 +227,11 @@ static int rpm_reg_set_mV_sel(struct regulator_dev *rdev,
return uV;
mutex_lock(&vreg->lock);
vreg->uV = uV;
if (vreg->is_enabled)
ret = rpm_reg_write(vreg, req, vreg->uV / 1000);
ret = rpm_reg_write(vreg, req, uV / 1000);
if (!ret)
vreg->uV = uV;
mutex_unlock(&vreg->lock);
return ret;
......@@ -252,9 +254,11 @@ static int rpm_reg_set_uV_sel(struct regulator_dev *rdev,
return uV;
mutex_lock(&vreg->lock);
vreg->uV = uV;
if (vreg->is_enabled)
ret = rpm_reg_write(vreg, req, vreg->uV);
ret = rpm_reg_write(vreg, req, uV);
if (!ret)
vreg->uV = uV;
mutex_unlock(&vreg->lock);
return ret;
......@@ -674,6 +678,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
vreg->desc.owner = THIS_MODULE;
vreg->desc.type = REGULATOR_VOLTAGE;
vreg->desc.name = pdev->dev.of_node->name;
vreg->desc.supply_name = "vin";
vreg->rpm = dev_get_drvdata(pdev->dev.parent);
if (!vreg->rpm) {
......@@ -768,7 +773,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
break;
}
if (force_mode < 0) {
if (force_mode == -1) {
dev_err(&pdev->dev, "invalid force mode\n");
return -EINVAL;
}
......
......@@ -97,7 +97,7 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
RK808_RAMP_RATE_MASK, ramp_value);
}
int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
......@@ -112,7 +112,7 @@ int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
sel);
}
int rk808_set_suspend_enable(struct regulator_dev *rdev)
static int rk808_set_suspend_enable(struct regulator_dev *rdev)
{
unsigned int reg;
......@@ -123,7 +123,7 @@ int rk808_set_suspend_enable(struct regulator_dev *rdev)
0);
}
int rk808_set_suspend_disable(struct regulator_dev *rdev)
static int rk808_set_suspend_disable(struct regulator_dev *rdev)
{
unsigned int reg;
......
......@@ -36,6 +36,8 @@ static struct regulator_ops rt5033_buck_ops = {
static const struct regulator_desc rt5033_supported_regulators[] = {
[RT5033_BUCK] = {
.name = "BUCK",
.of_match = of_match_ptr("BUCK"),
.regulators_node = of_match_ptr("regulators"),
.id = RT5033_BUCK,
.ops = &rt5033_buck_ops,
.type = REGULATOR_VOLTAGE,
......@@ -50,6 +52,8 @@ static const struct regulator_desc rt5033_supported_regulators[] = {
},
[RT5033_LDO] = {
.name = "LDO",
.of_match = of_match_ptr("LDO"),
.regulators_node = of_match_ptr("regulators"),
.id = RT5033_LDO,
.ops = &rt5033_buck_ops,
.type = REGULATOR_VOLTAGE,
......@@ -64,6 +68,8 @@ static const struct regulator_desc rt5033_supported_regulators[] = {
},
[RT5033_SAFE_LDO] = {
.name = "SAFE_LDO",
.of_match = of_match_ptr("SAFE_LDO"),
.regulators_node = of_match_ptr("regulators"),
.id = RT5033_SAFE_LDO,
.ops = &rt5033_safe_ldo_ops,
.type = REGULATOR_VOLTAGE,
......@@ -81,7 +87,7 @@ static int rt5033_regulator_probe(struct platform_device *pdev)
int ret, i;
struct regulator_config config = {};
config.dev = &pdev->dev;
config.dev = rt5033->dev;
config.driver_data = rt5033;
for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) {
......
......@@ -173,7 +173,7 @@ static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
}
/* Operations permitted on VDCDCx */
static struct regulator_ops tps65023_dcdc_ops = {
static const struct regulator_ops tps65023_dcdc_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
......@@ -184,7 +184,7 @@ static struct regulator_ops tps65023_dcdc_ops = {
};
/* Operations permitted on LDOx */
static struct regulator_ops tps65023_ldo_ops = {
static const struct regulator_ops tps65023_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
......@@ -194,7 +194,7 @@ static struct regulator_ops tps65023_ldo_ops = {
.map_voltage = regulator_map_voltage_ascend,
};
static struct regmap_config tps65023_regmap_config = {
static const struct regmap_config tps65023_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
......
......@@ -32,6 +32,8 @@ struct da9211_pdata {
* 2 : 2 phase 2 buck
*/
int num_buck;
int gpio_ren[DA9211_MAX_REGULATORS];
struct device_node *reg_node[DA9211_MAX_REGULATORS];
struct regulator_init_data *init_data[DA9211_MAX_REGULATORS];
};
#endif
......@@ -21,6 +21,7 @@
struct regmap;
struct regulator_dev;
struct regulator_config;
struct regulator_init_data;
struct regulator_enable_gpio;
......@@ -205,6 +206,15 @@ enum regulator_type {
* @supply_name: Identifying the regulator supply
* @of_match: Name used to identify regulator in DT.
* @regulators_node: Name of node containing regulator definitions in DT.
* @of_parse_cb: Optional callback called only if of_match is present.
* Will be called for each regulator parsed from DT, during
* init_data parsing.
* The regulator_config passed as argument to the callback will
* be a copy of config passed to regulator_register, valid only
* for this particular call. Callback may freely change the
* config but it cannot store it for later usage.
* Callback should return 0 on success or negative ERRNO
* indicating failure.
* @id: Numerical identifier for the regulator.
* @ops: Regulator operations table.
* @irq: Interrupt number for the regulator.
......@@ -251,6 +261,9 @@ struct regulator_desc {
const char *supply_name;
const char *of_match;
const char *regulators_node;
int (*of_parse_cb)(struct device_node *,
const struct regulator_desc *,
struct regulator_config *);
int id;
bool continuous_voltage_range;
unsigned n_voltages;
......
......@@ -191,15 +191,22 @@ struct regulator_init_data {
void *driver_data; /* core does not touch this */
};
int regulator_suspend_prepare(suspend_state_t state);
int regulator_suspend_finish(void);
#ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void);
int regulator_suspend_prepare(suspend_state_t state);
int regulator_suspend_finish(void);
#else
static inline void regulator_has_full_constraints(void)
{
}
static inline int regulator_suspend_prepare(suspend_state_t state)
{
return 0;
}
static inline int regulator_suspend_finish(void)
{
return 0;
}
#endif
#endif
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Flora Fu <flora.fu@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LINUX_REGULATOR_MT6397_H
#define __LINUX_REGULATOR_MT6397_H
enum {
MT6397_ID_VPCA15 = 0,
MT6397_ID_VPCA7,
MT6397_ID_VSRAMCA15,
MT6397_ID_VSRAMCA7,
MT6397_ID_VCORE,
MT6397_ID_VGPU,
MT6397_ID_VDRM,
MT6397_ID_VIO18 = 7,
MT6397_ID_VTCXO,
MT6397_ID_VA28,
MT6397_ID_VCAMA,
MT6397_ID_VIO28,
MT6397_ID_VUSB,
MT6397_ID_VMC,
MT6397_ID_VMCH,
MT6397_ID_VEMC3V3,
MT6397_ID_VGP1,
MT6397_ID_VGP2,
MT6397_ID_VGP3,
MT6397_ID_VGP4,
MT6397_ID_VGP5,
MT6397_ID_VGP6,
MT6397_ID_VIBR,
MT6397_ID_RG_MAX,
};
#define MT6397_MAX_REGULATOR MT6397_ID_RG_MAX
#define MT6397_REGULATOR_ID97 0x97
#define MT6397_REGULATOR_ID91 0x91
#endif /* __LINUX_REGULATOR_MT6397_H */
......@@ -49,6 +49,20 @@
#define PFUZE200_VGEN5 11
#define PFUZE200_VGEN6 12
#define PFUZE3000_SW1A 0
#define PFUZE3000_SW1B 1
#define PFUZE3000_SW2 2
#define PFUZE3000_SW3 3
#define PFUZE3000_SWBST 4
#define PFUZE3000_VSNVS 5
#define PFUZE3000_VREFDDR 6
#define PFUZE3000_VLDO1 7
#define PFUZE3000_VLDO2 8
#define PFUZE3000_VCCSD 9
#define PFUZE3000_V33 10
#define PFUZE3000_VLDO3 11
#define PFUZE3000_VLDO4 12
struct regulator_init_data;
struct pfuze_regulator_platform_data {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment