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: ...@@ -39,6 +39,12 @@ to get matched with their hardware counterparts as follow:
-BUCKn : 1-4. -BUCKn : 1-4.
Use standard regulator bindings for it ('regulator-off-in-suspend'). 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: Example:
...@@ -65,4 +71,12 @@ Example: ...@@ -65,4 +71,12 @@ Example:
regulator-always-on; regulator-always-on;
regulator-boot-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: ...@@ -11,6 +11,7 @@ Required properties:
BUCKA and BUCKB. BUCKA and BUCKB.
Optional properties: Optional properties:
- enable-gpios: platform gpio for control of BUCKA/BUCKB.
- Any optional property defined in regulator.txt - Any optional property defined in regulator.txt
Example 1) DA9211 Example 1) DA9211
...@@ -27,6 +28,7 @@ Example 1) DA9211 ...@@ -27,6 +28,7 @@ Example 1) DA9211
regulator-max-microvolt = <1570000>; regulator-max-microvolt = <1570000>;
regulator-min-microamp = <2000000>; regulator-min-microamp = <2000000>;
regulator-max-microamp = <5000000>; regulator-max-microamp = <5000000>;
enable-gpios = <&gpio 27 0>;
}; };
BUCKB { BUCKB {
regulator-name = "VBUCKB"; regulator-name = "VBUCKB";
...@@ -34,11 +36,12 @@ Example 1) DA9211 ...@@ -34,11 +36,12 @@ Example 1) DA9211
regulator-max-microvolt = <1570000>; regulator-max-microvolt = <1570000>;
regulator-min-microamp = <2000000>; regulator-min-microamp = <2000000>;
regulator-max-microamp = <5000000>; regulator-max-microamp = <5000000>;
enable-gpios = <&gpio 17 0>;
}; };
}; };
}; };
Example 2) DA92113 Example 2) DA9213
pmic: da9213@68 { pmic: da9213@68 {
compatible = "dlg,da9213"; compatible = "dlg,da9213";
reg = <0x68>; reg = <0x68>;
...@@ -51,6 +54,7 @@ Example 2) DA92113 ...@@ -51,6 +54,7 @@ Example 2) DA92113
regulator-max-microvolt = <1570000>; regulator-max-microvolt = <1570000>;
regulator-min-microamp = <3000000>; regulator-min-microamp = <3000000>;
regulator-max-microamp = <6000000>; regulator-max-microamp = <6000000>;
enable-gpios = <&gpio 27 0>;
}; };
BUCKB { BUCKB {
regulator-name = "VBUCKB"; regulator-name = "VBUCKB";
...@@ -58,6 +62,7 @@ Example 2) DA92113 ...@@ -58,6 +62,7 @@ Example 2) DA92113
regulator-max-microvolt = <1570000>; regulator-max-microvolt = <1570000>;
regulator-min-microamp = <3000000>; regulator-min-microamp = <3000000>;
regulator-max-microamp = <6000000>; regulator-max-microamp = <6000000>;
enable-gpios = <&gpio 17 0>;
}; };
}; };
}; };
...@@ -2,7 +2,7 @@ Intersil ISL9305/ISL9305H voltage regulator ...@@ -2,7 +2,7 @@ Intersil ISL9305/ISL9305H voltage regulator
Required properties: Required properties:
- compatible: "isl,isl9305" or "isl,isl9305h" - compatible: "isil,isl9305" or "isil,isl9305h"
- reg: I2C slave address, usually 0x68. - reg: I2C slave address, usually 0x68.
- regulators: A node that houses a sub-node for each regulator within the - 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 device. Each sub-node is identified using the node's name, with valid
...@@ -19,7 +19,7 @@ Optional properties: ...@@ -19,7 +19,7 @@ Optional properties:
Example Example
pmic: isl9305@68 { pmic: isl9305@68 {
compatible = "isl,isl9305"; compatible = "isil,isl9305";
reg = <0x68>; reg = <0x68>;
VINDCD1-supply = <&system_power>; 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 PFUZE100 family of regulators
Required properties: Required properties:
- compatible: "fsl,pfuze100" or "fsl,pfuze200" - compatible: "fsl,pfuze100", "fsl,pfuze200", "fsl,pfuze3000"
- reg: I2C slave address - reg: I2C slave address
Required child node: Required child node:
...@@ -14,6 +14,8 @@ Required child node: ...@@ -14,6 +14,8 @@ Required child node:
sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6 sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6
--PFUZE200 --PFUZE200
sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6 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. Each regulator is defined using the standard binding for regulators.
...@@ -205,3 +207,93 @@ Example 2: PFUZE200 ...@@ -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 ...@@ -414,6 +414,14 @@ config REGULATOR_MAX77802
Exynos5420/Exynos5800 SoCs to control various voltages. Exynos5420/Exynos5800 SoCs to control various voltages.
It includes support for control of voltage and ramp speed. 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 config REGULATOR_MC13XXX_CORE
tristate tristate
...@@ -433,6 +441,15 @@ config REGULATOR_MC13892 ...@@ -433,6 +441,15 @@ config REGULATOR_MC13892
Say y here to support the regulators found on the Freescale MC13892 Say y here to support the regulators found on the Freescale MC13892
PMIC. 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 config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators" tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS depends on MFD_PALMAS
......
...@@ -55,9 +55,11 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o ...@@ -55,9 +55,11 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.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_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
......
...@@ -32,11 +32,13 @@ ...@@ -32,11 +32,13 @@
#define AXP20X_FREQ_DCDC_MASK 0x0f #define AXP20X_FREQ_DCDC_MASK 0x0f
#define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \ #define AXP20X_DESC_IO(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \
_emask, _enable_val, _disable_val) \ _ereg, _emask, _enable_val, _disable_val) \
[AXP20X_##_id] = { \ [AXP20X_##_id] = { \
.name = #_id, \ .name = #_id, \
.supply_name = (_supply), \ .supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \ .id = AXP20X_##_id, \
.n_voltages = (((_max) - (_min)) / (_step) + 1), \ .n_voltages = (((_max) - (_min)) / (_step) + 1), \
...@@ -52,11 +54,13 @@ ...@@ -52,11 +54,13 @@
.ops = &axp20x_ops, \ .ops = &axp20x_ops, \
} }
#define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \ #define AXP20X_DESC(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \
_emask) \ _ereg, _emask) \
[AXP20X_##_id] = { \ [AXP20X_##_id] = { \
.name = #_id, \ .name = #_id, \
.supply_name = (_supply), \ .supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \ .id = AXP20X_##_id, \
.n_voltages = (((_max) - (_min)) / (_step) + 1), \ .n_voltages = (((_max) - (_min)) / (_step) + 1), \
...@@ -70,10 +74,12 @@ ...@@ -70,10 +74,12 @@
.ops = &axp20x_ops, \ .ops = &axp20x_ops, \
} }
#define AXP20X_DESC_FIXED(_id, _supply, _volt) \ #define AXP20X_DESC_FIXED(_id, _match, _supply, _volt) \
[AXP20X_##_id] = { \ [AXP20X_##_id] = { \
.name = #_id, \ .name = #_id, \
.supply_name = (_supply), \ .supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \ .id = AXP20X_##_id, \
.n_voltages = 1, \ .n_voltages = 1, \
...@@ -82,10 +88,13 @@ ...@@ -82,10 +88,13 @@
.ops = &axp20x_ops_fixed \ .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] = { \ [AXP20X_##_id] = { \
.name = #_id, \ .name = #_id, \
.supply_name = (_supply), \ .supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \ .id = AXP20X_##_id, \
.n_voltages = ARRAY_SIZE(_table), \ .n_voltages = ARRAY_SIZE(_table), \
...@@ -127,36 +136,20 @@ static struct regulator_ops axp20x_ops = { ...@@ -127,36 +136,20 @@ static struct regulator_ops axp20x_ops = {
}; };
static const struct regulator_desc axp20x_regulators[] = { static const struct regulator_desc axp20x_regulators[] = {
AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f, AXP20X_DESC(DCDC2, "dcdc2", "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT,
AXP20X_PWR_OUT_CTRL, 0x10), 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f, AXP20X_DESC(DCDC3, "dcdc3", "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT,
AXP20X_PWR_OUT_CTRL, 0x02), 0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
AXP20X_DESC_FIXED(LDO1, "acin", 1300), AXP20X_DESC_FIXED(LDO1, "ldo1", "acin", 1300),
AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0, AXP20X_DESC(LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
AXP20X_PWR_OUT_CTRL, 0x04), AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f, AXP20X_DESC(LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT,
AXP20X_PWR_OUT_CTRL, 0x40), 0x7f, AXP20X_PWR_OUT_CTRL, 0x40),
AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f, AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data,
AXP20X_PWR_OUT_CTRL, 0x08), AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08),
AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0, AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED, AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07,
AXP20X_IO_DISABLED), 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),
}; };
static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) 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) ...@@ -193,13 +186,6 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
if (!regulators) { if (!regulators) {
dev_warn(&pdev->dev, "regulators node not found\n"); dev_warn(&pdev->dev, "regulators node not found\n");
} else { } 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; dcdcfreq = 1500;
of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq); of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
...@@ -233,23 +219,17 @@ static int axp20x_regulator_probe(struct platform_device *pdev) ...@@ -233,23 +219,17 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
{ {
struct regulator_dev *rdev; struct regulator_dev *rdev;
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { }; struct regulator_config config = {
struct regulator_init_data *init_data; .dev = pdev->dev.parent,
.regmap = axp20x->regmap,
};
int ret, i; int ret, i;
u32 workmode; u32 workmode;
ret = axp20x_regulator_parse_dt(pdev); /* This only sets the dcdc freq. Ignore any errors */
if (ret) axp20x_regulator_parse_dt(pdev);
return ret;
for (i = 0; i < AXP20X_REG_ID_MAX; i++) { 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], rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
&config); &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
...@@ -259,7 +239,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev) ...@@ -259,7 +239,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
return PTR_ERR(rdev); 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); &workmode);
if (!ret) { if (!ret) {
if (axp20x_set_dcdc_workmode(rdev, i, workmode)) if (axp20x_set_dcdc_workmode(rdev, i, workmode))
......
...@@ -632,49 +632,34 @@ static ssize_t regulator_bypass_show(struct device *dev, ...@@ -632,49 +632,34 @@ static ssize_t regulator_bypass_show(struct device *dev,
static DEVICE_ATTR(bypass, 0444, static DEVICE_ATTR(bypass, 0444,
regulator_bypass_show, NULL); regulator_bypass_show, NULL);
/*
* These are the only attributes are present for all regulators.
* Other attributes are a function of regulator functionality.
*/
static struct attribute *regulator_dev_attrs[] = {
&dev_attr_name.attr,
&dev_attr_num_users.attr,
&dev_attr_type.attr,
NULL,
};
ATTRIBUTE_GROUPS(regulator_dev);
static void regulator_dev_release(struct device *dev)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
kfree(rdev);
}
static struct class regulator_class = {
.name = "regulator",
.dev_release = regulator_dev_release,
.dev_groups = regulator_dev_groups,
};
/* Calculate the new optimum regulator operating mode based on the new total /* Calculate the new optimum regulator operating mode based on the new total
* consumer load. All locks held by caller */ * consumer load. All locks held by caller */
static void drms_uA_update(struct regulator_dev *rdev) static int drms_uA_update(struct regulator_dev *rdev)
{ {
struct regulator *sibling; struct regulator *sibling;
int current_uA = 0, output_uV, input_uV, err; int current_uA = 0, output_uV, input_uV, err;
unsigned int mode; unsigned int mode;
/*
* first check to see if we can set modes at all, otherwise just
* tell the consumer everything is OK.
*/
err = regulator_check_drms(rdev); err = regulator_check_drms(rdev);
if (err < 0 || !rdev->desc->ops->get_optimum_mode || if (err < 0)
(!rdev->desc->ops->get_voltage && return 0;
!rdev->desc->ops->get_voltage_sel) ||
!rdev->desc->ops->set_mode) if (!rdev->desc->ops->get_optimum_mode)
return; return 0;
if (!rdev->desc->ops->set_mode)
return -EINVAL;
/* get output voltage */ /* get output voltage */
output_uV = _regulator_get_voltage(rdev); output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) if (output_uV <= 0) {
return; rdev_err(rdev, "invalid output voltage found\n");
return -EINVAL;
}
/* get input voltage */ /* get input voltage */
input_uV = 0; input_uV = 0;
...@@ -682,8 +667,10 @@ static void drms_uA_update(struct regulator_dev *rdev) ...@@ -682,8 +667,10 @@ static void drms_uA_update(struct regulator_dev *rdev)
input_uV = regulator_get_voltage(rdev->supply); input_uV = regulator_get_voltage(rdev->supply);
if (input_uV <= 0) if (input_uV <= 0)
input_uV = rdev->constraints->input_uV; input_uV = rdev->constraints->input_uV;
if (input_uV <= 0) if (input_uV <= 0) {
return; rdev_err(rdev, "invalid input voltage found\n");
return -EINVAL;
}
/* calc total requested load */ /* calc total requested load */
list_for_each_entry(sibling, &rdev->consumer_list, list) list_for_each_entry(sibling, &rdev->consumer_list, list)
...@@ -695,8 +682,17 @@ static void drms_uA_update(struct regulator_dev *rdev) ...@@ -695,8 +682,17 @@ static void drms_uA_update(struct regulator_dev *rdev)
/* check the new mode is allowed */ /* check the new mode is allowed */
err = regulator_mode_constrain(rdev, &mode); err = regulator_mode_constrain(rdev, &mode);
if (err == 0) if (err < 0) {
rdev->desc->ops->set_mode(rdev, mode); rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
current_uA, input_uV, output_uV);
return err;
}
err = rdev->desc->ops->set_mode(rdev, mode);
if (err < 0)
rdev_err(rdev, "failed to set optimum mode %x\n", mode);
return err;
} }
static int suspend_set_state(struct regulator_dev *rdev, static int suspend_set_state(struct regulator_dev *rdev,
...@@ -3026,75 +3022,13 @@ EXPORT_SYMBOL_GPL(regulator_get_mode); ...@@ -3026,75 +3022,13 @@ EXPORT_SYMBOL_GPL(regulator_get_mode);
int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
{ {
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
struct regulator *consumer; int ret;
int ret, output_uV, input_uV = 0, total_uA_load = 0;
unsigned int mode;
if (rdev->supply)
input_uV = regulator_get_voltage(rdev->supply);
mutex_lock(&rdev->mutex); mutex_lock(&rdev->mutex);
/*
* first check to see if we can set modes at all, otherwise just
* tell the consumer everything is OK.
*/
regulator->uA_load = uA_load; regulator->uA_load = uA_load;
ret = regulator_check_drms(rdev); ret = drms_uA_update(rdev);
if (ret < 0) {
ret = 0;
goto out;
}
if (!rdev->desc->ops->get_optimum_mode)
goto out;
/*
* we can actually do this so any errors are indicators of
* potential real failure.
*/
ret = -EINVAL;
if (!rdev->desc->ops->set_mode)
goto out;
/* get output voltage */
output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) {
rdev_err(rdev, "invalid output voltage found\n");
goto out;
}
/* No supply? Use constraint voltage */
if (input_uV <= 0)
input_uV = rdev->constraints->input_uV;
if (input_uV <= 0) {
rdev_err(rdev, "invalid input voltage found\n");
goto out;
}
/* calc total requested load for this regulator */
list_for_each_entry(consumer, &rdev->consumer_list, list)
total_uA_load += consumer->uA_load;
mode = rdev->desc->ops->get_optimum_mode(rdev,
input_uV, output_uV,
total_uA_load);
ret = regulator_mode_constrain(rdev, &mode);
if (ret < 0) {
rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
total_uA_load, input_uV, output_uV);
goto out;
}
ret = rdev->desc->ops->set_mode(rdev, mode);
if (ret < 0) {
rdev_err(rdev, "failed to set optimum mode %x\n", mode);
goto out;
}
ret = mode;
out:
mutex_unlock(&rdev->mutex); mutex_unlock(&rdev->mutex);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
...@@ -3436,126 +3370,136 @@ int regulator_mode_to_status(unsigned int mode) ...@@ -3436,126 +3370,136 @@ int regulator_mode_to_status(unsigned int mode)
} }
EXPORT_SYMBOL_GPL(regulator_mode_to_status); EXPORT_SYMBOL_GPL(regulator_mode_to_status);
static struct attribute *regulator_dev_attrs[] = {
&dev_attr_name.attr,
&dev_attr_num_users.attr,
&dev_attr_type.attr,
&dev_attr_microvolts.attr,
&dev_attr_microamps.attr,
&dev_attr_opmode.attr,
&dev_attr_state.attr,
&dev_attr_status.attr,
&dev_attr_bypass.attr,
&dev_attr_requested_microamps.attr,
&dev_attr_min_microvolts.attr,
&dev_attr_max_microvolts.attr,
&dev_attr_min_microamps.attr,
&dev_attr_max_microamps.attr,
&dev_attr_suspend_standby_state.attr,
&dev_attr_suspend_mem_state.attr,
&dev_attr_suspend_disk_state.attr,
&dev_attr_suspend_standby_microvolts.attr,
&dev_attr_suspend_mem_microvolts.attr,
&dev_attr_suspend_disk_microvolts.attr,
&dev_attr_suspend_standby_mode.attr,
&dev_attr_suspend_mem_mode.attr,
&dev_attr_suspend_disk_mode.attr,
NULL
};
/* /*
* To avoid cluttering sysfs (and memory) with useless state, only * To avoid cluttering sysfs (and memory) with useless state, only
* create attributes that can be meaningfully displayed. * create attributes that can be meaningfully displayed.
*/ */
static int add_regulator_attributes(struct regulator_dev *rdev) static umode_t regulator_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{ {
struct device *dev = &rdev->dev; struct device *dev = kobj_to_dev(kobj);
struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev);
const struct regulator_ops *ops = rdev->desc->ops; const struct regulator_ops *ops = rdev->desc->ops;
int status = 0; umode_t mode = attr->mode;
/* these three are always present */
if (attr == &dev_attr_name.attr ||
attr == &dev_attr_num_users.attr ||
attr == &dev_attr_type.attr)
return mode;
/* some attributes need specific methods to be displayed */ /* some attributes need specific methods to be displayed */
if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || if (attr == &dev_attr_microvolts.attr) {
(ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
(ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
(rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1))) { (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) ||
status = device_create_file(dev, &dev_attr_microvolts); (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1))
if (status < 0) return mode;
return status; return 0;
}
if (ops->get_current_limit) {
status = device_create_file(dev, &dev_attr_microamps);
if (status < 0)
return status;
}
if (ops->get_mode) {
status = device_create_file(dev, &dev_attr_opmode);
if (status < 0)
return status;
}
if (rdev->ena_pin || ops->is_enabled) {
status = device_create_file(dev, &dev_attr_state);
if (status < 0)
return status;
}
if (ops->get_status) {
status = device_create_file(dev, &dev_attr_status);
if (status < 0)
return status;
}
if (ops->get_bypass) {
status = device_create_file(dev, &dev_attr_bypass);
if (status < 0)
return status;
} }
if (attr == &dev_attr_microamps.attr)
return ops->get_current_limit ? mode : 0;
if (attr == &dev_attr_opmode.attr)
return ops->get_mode ? mode : 0;
if (attr == &dev_attr_state.attr)
return (rdev->ena_pin || ops->is_enabled) ? mode : 0;
if (attr == &dev_attr_status.attr)
return ops->get_status ? mode : 0;
if (attr == &dev_attr_bypass.attr)
return ops->get_bypass ? mode : 0;
/* some attributes are type-specific */ /* some attributes are type-specific */
if (rdev->desc->type == REGULATOR_CURRENT) { if (attr == &dev_attr_requested_microamps.attr)
status = device_create_file(dev, &dev_attr_requested_microamps); return rdev->desc->type == REGULATOR_CURRENT ? mode : 0;
if (status < 0)
return status;
}
/* all the other attributes exist to support constraints; /* all the other attributes exist to support constraints;
* don't show them if there are no constraints, or if the * don't show them if there are no constraints, or if the
* relevant supporting methods are missing. * relevant supporting methods are missing.
*/ */
if (!rdev->constraints) if (!rdev->constraints)
return status; return 0;
/* constraints need specific supporting methods */ /* constraints need specific supporting methods */
if (ops->set_voltage || ops->set_voltage_sel) { if (attr == &dev_attr_min_microvolts.attr ||
status = device_create_file(dev, &dev_attr_min_microvolts); attr == &dev_attr_max_microvolts.attr)
if (status < 0) return (ops->set_voltage || ops->set_voltage_sel) ? mode : 0;
return status;
status = device_create_file(dev, &dev_attr_max_microvolts); if (attr == &dev_attr_min_microamps.attr ||
if (status < 0) attr == &dev_attr_max_microamps.attr)
return status; return ops->set_current_limit ? mode : 0;
}
if (ops->set_current_limit) {
status = device_create_file(dev, &dev_attr_min_microamps);
if (status < 0)
return status;
status = device_create_file(dev, &dev_attr_max_microamps);
if (status < 0)
return status;
}
status = device_create_file(dev, &dev_attr_suspend_standby_state);
if (status < 0)
return status;
status = device_create_file(dev, &dev_attr_suspend_mem_state);
if (status < 0)
return status;
status = device_create_file(dev, &dev_attr_suspend_disk_state);
if (status < 0)
return status;
if (ops->set_suspend_voltage) { if (attr == &dev_attr_suspend_standby_state.attr ||
status = device_create_file(dev, attr == &dev_attr_suspend_mem_state.attr ||
&dev_attr_suspend_standby_microvolts); attr == &dev_attr_suspend_disk_state.attr)
if (status < 0) return mode;
return status;
status = device_create_file(dev, if (attr == &dev_attr_suspend_standby_microvolts.attr ||
&dev_attr_suspend_mem_microvolts); attr == &dev_attr_suspend_mem_microvolts.attr ||
if (status < 0) attr == &dev_attr_suspend_disk_microvolts.attr)
return status; return ops->set_suspend_voltage ? mode : 0;
status = device_create_file(dev,
&dev_attr_suspend_disk_microvolts); if (attr == &dev_attr_suspend_standby_mode.attr ||
if (status < 0) attr == &dev_attr_suspend_mem_mode.attr ||
return status; attr == &dev_attr_suspend_disk_mode.attr)
} return ops->set_suspend_mode ? mode : 0;
if (ops->set_suspend_mode) { return mode;
status = device_create_file(dev,
&dev_attr_suspend_standby_mode);
if (status < 0)
return status;
status = device_create_file(dev,
&dev_attr_suspend_mem_mode);
if (status < 0)
return status;
status = device_create_file(dev,
&dev_attr_suspend_disk_mode);
if (status < 0)
return status;
}
return status;
} }
static const struct attribute_group regulator_dev_group = {
.attrs = regulator_dev_attrs,
.is_visible = regulator_attr_is_visible,
};
static const struct attribute_group *regulator_dev_groups[] = {
&regulator_dev_group,
NULL
};
static void regulator_dev_release(struct device *dev)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
kfree(rdev);
}
static struct class regulator_class = {
.name = "regulator",
.dev_release = regulator_dev_release,
.dev_groups = regulator_dev_groups,
};
static void rdev_init_debugfs(struct regulator_dev *rdev) static void rdev_init_debugfs(struct regulator_dev *rdev)
{ {
rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
...@@ -3575,7 +3519,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) ...@@ -3575,7 +3519,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
/** /**
* regulator_register - register regulator * regulator_register - register regulator
* @regulator_desc: regulator to register * @regulator_desc: regulator to register
* @config: runtime configuration for regulator * @cfg: runtime configuration for regulator
* *
* Called by regulator drivers to register a regulator. * Called by regulator drivers to register a regulator.
* Returns a valid pointer to struct regulator_dev on success * Returns a valid pointer to struct regulator_dev on success
...@@ -3583,20 +3527,21 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) ...@@ -3583,20 +3527,21 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
*/ */
struct regulator_dev * struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc, regulator_register(const struct regulator_desc *regulator_desc,
const struct regulator_config *config) const struct regulator_config *cfg)
{ {
const struct regulation_constraints *constraints = NULL; const struct regulation_constraints *constraints = NULL;
const struct regulator_init_data *init_data; const struct regulator_init_data *init_data;
static atomic_t regulator_no = ATOMIC_INIT(0); struct regulator_config *config = NULL;
static atomic_t regulator_no = ATOMIC_INIT(-1);
struct regulator_dev *rdev; struct regulator_dev *rdev;
struct device *dev; struct device *dev;
int ret, i; int ret, i;
const char *supply = NULL; const char *supply = NULL;
if (regulator_desc == NULL || config == NULL) if (regulator_desc == NULL || cfg == NULL)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
dev = config->dev; dev = cfg->dev;
WARN_ON(!dev); WARN_ON(!dev);
if (regulator_desc->name == NULL || regulator_desc->ops == NULL) if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
...@@ -3626,7 +3571,17 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -3626,7 +3571,17 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (rdev == NULL) if (rdev == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
init_data = regulator_of_get_init_data(dev, regulator_desc, /*
* Duplicate the config so the driver could override it after
* parsing init data.
*/
config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL);
if (config == NULL) {
kfree(rdev);
return ERR_PTR(-ENOMEM);
}
init_data = regulator_of_get_init_data(dev, regulator_desc, config,
&rdev->dev.of_node); &rdev->dev.of_node);
if (!init_data) { if (!init_data) {
init_data = config->init_data; init_data = config->init_data;
...@@ -3660,8 +3615,8 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -3660,8 +3615,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
/* register with sysfs */ /* register with sysfs */
rdev->dev.class = &regulator_class; rdev->dev.class = &regulator_class;
rdev->dev.parent = dev; rdev->dev.parent = dev;
dev_set_name(&rdev->dev, "regulator.%d", dev_set_name(&rdev->dev, "regulator.%lu",
atomic_inc_return(&regulator_no) - 1); (unsigned long) atomic_inc_return(&regulator_no));
ret = device_register(&rdev->dev); ret = device_register(&rdev->dev);
if (ret != 0) { if (ret != 0) {
put_device(&rdev->dev); put_device(&rdev->dev);
...@@ -3694,11 +3649,6 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -3694,11 +3649,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret < 0) if (ret < 0)
goto scrub; goto scrub;
/* add attributes supported by this regulator */
ret = add_regulator_attributes(rdev);
if (ret < 0)
goto scrub;
if (init_data && init_data->supply_regulator) if (init_data && init_data->supply_regulator)
supply = init_data->supply_regulator; supply = init_data->supply_regulator;
else if (regulator_desc->supply_name) else if (regulator_desc->supply_name)
...@@ -3754,6 +3704,7 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -3754,6 +3704,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
rdev_init_debugfs(rdev); rdev_init_debugfs(rdev);
out: out:
mutex_unlock(&regulator_list_mutex); mutex_unlock(&regulator_list_mutex);
kfree(config);
return rdev; return rdev;
unset_supplies: unset_supplies:
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h> #include <linux/regulator/of_regulator.h>
#include <linux/regulator/da9211.h> #include <linux/regulator/da9211.h>
#include "da9211-regulator.h" #include "da9211-regulator.h"
...@@ -276,7 +277,10 @@ static struct da9211_pdata *da9211_parse_regulators_dt( ...@@ -276,7 +277,10 @@ static struct da9211_pdata *da9211_parse_regulators_dt(
continue; continue;
pdata->init_data[n] = da9211_matches[i].init_data; 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++; n++;
} }
...@@ -364,7 +368,15 @@ static int da9211_regulator_init(struct da9211 *chip) ...@@ -364,7 +368,15 @@ static int da9211_regulator_init(struct da9211 *chip)
config.dev = chip->dev; config.dev = chip->dev;
config.driver_data = chip; config.driver_data = chip;
config.regmap = chip->regmap; 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, chip->rdev[i] = devm_regulator_register(chip->dev,
&da9211_regulators[i], &config); &da9211_regulators[i], &config);
......
...@@ -147,7 +147,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev) ...@@ -147,7 +147,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL; return REGULATOR_MODE_NORMAL;
} }
static int slew_rates[] = { static const int slew_rates[] = {
64000, 64000,
32000, 32000,
16000, 16000,
...@@ -296,7 +296,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, ...@@ -296,7 +296,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
return PTR_ERR_OR_ZERO(di->rdev); 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, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
}; };
......
...@@ -38,11 +38,13 @@ struct regulator { ...@@ -38,11 +38,13 @@ struct regulator {
#ifdef CONFIG_OF #ifdef CONFIG_OF
struct regulator_init_data *regulator_of_get_init_data(struct device *dev, struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc, const struct regulator_desc *desc,
struct regulator_config *config,
struct device_node **node); struct device_node **node);
#else #else
static inline struct regulator_init_data * static inline struct regulator_init_data *
regulator_of_get_init_data(struct device *dev, regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc, const struct regulator_desc *desc,
struct regulator_config *config,
struct device_node **node) struct device_node **node)
{ {
return NULL; return NULL;
......
...@@ -177,8 +177,10 @@ static int isl9305_i2c_probe(struct i2c_client *i2c, ...@@ -177,8 +177,10 @@ static int isl9305_i2c_probe(struct i2c_client *i2c,
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id isl9305_dt_ids[] = { static const struct of_device_id isl9305_dt_ids[] = {
{ .compatible = "isl,isl9305" }, { .compatible = "isl,isl9305" }, /* for backward compat., don't use */
{ .compatible = "isl,isl9305h" }, { .compatible = "isil,isl9305" },
{ .compatible = "isl,isl9305h" }, /* for backward compat., don't use */
{ .compatible = "isil,isl9305h" },
{}, {},
}; };
#endif #endif
......
...@@ -106,7 +106,6 @@ struct lp872x { ...@@ -106,7 +106,6 @@ struct lp872x {
struct device *dev; struct device *dev;
enum lp872x_id chipid; enum lp872x_id chipid;
struct lp872x_platform_data *pdata; struct lp872x_platform_data *pdata;
struct regulator_dev **regulators;
int num_regulators; int num_regulators;
enum lp872x_dvs_state dvs_pin; enum lp872x_dvs_state dvs_pin;
int dvs_gpio; int dvs_gpio;
...@@ -801,8 +800,6 @@ static int lp872x_regulator_register(struct lp872x *lp) ...@@ -801,8 +800,6 @@ static int lp872x_regulator_register(struct lp872x *lp)
dev_err(lp->dev, "regulator register err"); dev_err(lp->dev, "regulator register err");
return PTR_ERR(rdev); return PTR_ERR(rdev);
} }
*(lp->regulators + i) = rdev;
} }
return 0; return 0;
...@@ -906,7 +903,7 @@ static struct lp872x_platform_data ...@@ -906,7 +903,7 @@ static struct lp872x_platform_data
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{ {
struct lp872x *lp; struct lp872x *lp;
int ret, size, num_regulators; int ret;
const int lp872x_num_regulators[] = { const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS, [LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS, [LP8725] = LP8725_NUM_REGULATORS,
...@@ -918,38 +915,27 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) ...@@ -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); lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp) if (!lp)
goto err_mem; return -ENOMEM;
num_regulators = lp872x_num_regulators[id->driver_data];
size = sizeof(struct regulator_dev *) * num_regulators;
lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL); lp->num_regulators = lp872x_num_regulators[id->driver_data];
if (!lp->regulators)
goto err_mem;
lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config);
if (IS_ERR(lp->regmap)) { if (IS_ERR(lp->regmap)) {
ret = PTR_ERR(lp->regmap); ret = PTR_ERR(lp->regmap);
dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
goto err_dev; return ret;
} }
lp->dev = &cl->dev; lp->dev = &cl->dev;
lp->pdata = dev_get_platdata(&cl->dev); lp->pdata = dev_get_platdata(&cl->dev);
lp->chipid = id->driver_data; lp->chipid = id->driver_data;
lp->num_regulators = num_regulators;
i2c_set_clientdata(cl, lp); i2c_set_clientdata(cl, lp);
ret = lp872x_config(lp); ret = lp872x_config(lp);
if (ret) if (ret)
goto err_dev; return ret;
return lp872x_regulator_register(lp); return lp872x_regulator_register(lp);
err_mem:
return -ENOMEM;
err_dev:
return ret;
} }
static const struct of_device_id lp872x_dt_ids[] = { static const struct of_device_id lp872x_dt_ids[] = {
......
...@@ -103,6 +103,8 @@ static struct regulator_ops max14577_charger_ops = { ...@@ -103,6 +103,8 @@ static struct regulator_ops max14577_charger_ops = {
static const struct regulator_desc max14577_supported_regulators[] = { static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_SAFEOUT] = { [MAX14577_SAFEOUT] = {
.name = "SAFEOUT", .name = "SAFEOUT",
.of_match = of_match_ptr("SAFEOUT"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT, .id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops, .ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -114,6 +116,8 @@ static const struct regulator_desc max14577_supported_regulators[] = { ...@@ -114,6 +116,8 @@ static const struct regulator_desc max14577_supported_regulators[] = {
}, },
[MAX14577_CHARGER] = { [MAX14577_CHARGER] = {
.name = "CHARGER", .name = "CHARGER",
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER, .id = MAX14577_CHARGER,
.ops = &max14577_charger_ops, .ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT, .type = REGULATOR_CURRENT,
...@@ -137,6 +141,8 @@ static struct regulator_ops max77836_ldo_ops = { ...@@ -137,6 +141,8 @@ static struct regulator_ops max77836_ldo_ops = {
static const struct regulator_desc max77836_supported_regulators[] = { static const struct regulator_desc max77836_supported_regulators[] = {
[MAX14577_SAFEOUT] = { [MAX14577_SAFEOUT] = {
.name = "SAFEOUT", .name = "SAFEOUT",
.of_match = of_match_ptr("SAFEOUT"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT, .id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops, .ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -148,6 +154,8 @@ static const struct regulator_desc max77836_supported_regulators[] = { ...@@ -148,6 +154,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
}, },
[MAX14577_CHARGER] = { [MAX14577_CHARGER] = {
.name = "CHARGER", .name = "CHARGER",
.of_match = of_match_ptr("CHARGER"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER, .id = MAX14577_CHARGER,
.ops = &max14577_charger_ops, .ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT, .type = REGULATOR_CURRENT,
...@@ -157,6 +165,8 @@ static const struct regulator_desc max77836_supported_regulators[] = { ...@@ -157,6 +165,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
}, },
[MAX77836_LDO1] = { [MAX77836_LDO1] = {
.name = "LDO1", .name = "LDO1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO1, .id = MAX77836_LDO1,
.ops = &max77836_ldo_ops, .ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -171,6 +181,8 @@ static const struct regulator_desc max77836_supported_regulators[] = { ...@@ -171,6 +181,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
}, },
[MAX77836_LDO2] = { [MAX77836_LDO2] = {
.name = "LDO2", .name = "LDO2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO2, .id = MAX77836_LDO2,
.ops = &max77836_ldo_ops, .ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -198,43 +210,6 @@ static struct of_regulator_match max77836_regulator_matches[] = { ...@@ -198,43 +210,6 @@ static struct of_regulator_match max77836_regulator_matches[] = {
{ .name = "LDO2", }, { .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, static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type) enum maxim_device_type dev_type)
{ {
...@@ -261,11 +236,6 @@ static inline struct device_node *match_of_node(int index, ...@@ -261,11 +236,6 @@ static inline struct device_node *match_of_node(int index,
} }
} }
#else /* CONFIG_OF */ #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, static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type) enum maxim_device_type dev_type)
{ {
...@@ -308,16 +278,12 @@ static int max14577_regulator_probe(struct platform_device *pdev) ...@@ -308,16 +278,12 @@ static int max14577_regulator_probe(struct platform_device *pdev)
{ {
struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent); struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev); struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev);
int i, ret; int i, ret = 0;
struct regulator_config config = {}; struct regulator_config config = {};
const struct regulator_desc *supported_regulators; const struct regulator_desc *supported_regulators;
unsigned int supported_regulators_size; unsigned int supported_regulators_size;
enum maxim_device_type dev_type = max14577->dev_type; 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) { switch (dev_type) {
case MAXIM_DEVICE_TYPE_MAX77836: case MAXIM_DEVICE_TYPE_MAX77836:
supported_regulators = max77836_supported_regulators; supported_regulators = max77836_supported_regulators;
...@@ -329,7 +295,7 @@ static int max14577_regulator_probe(struct platform_device *pdev) ...@@ -329,7 +295,7 @@ static int max14577_regulator_probe(struct platform_device *pdev)
supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators); supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators);
} }
config.dev = &pdev->dev; config.dev = max14577->dev;
config.driver_data = max14577; config.driver_data = max14577;
for (i = 0; i < supported_regulators_size; i++) { for (i = 0; i < supported_regulators_size; i++) {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
...@@ -45,6 +46,11 @@ ...@@ -45,6 +46,11 @@
#define MAX77686_DVS_MINUV 600000 #define MAX77686_DVS_MINUV 600000
#define MAX77686_DVS_UVSTEP 12500 #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. * Values used for configuring LDOs and bucks.
* Forcing low power mode: LDO1, 3-5, 9, 13, 17-26 * Forcing low power mode: LDO1, 3-5, 9, 13, 17-26
...@@ -82,6 +88,8 @@ enum max77686_ramp_rate { ...@@ -82,6 +88,8 @@ enum max77686_ramp_rate {
}; };
struct max77686_data { struct max77686_data {
u64 gpio_enabled:MAX77686_REGULATORS;
/* Array indexed by regulator id */ /* Array indexed by regulator id */
unsigned int opmode[MAX77686_REGULATORS]; unsigned int opmode[MAX77686_REGULATORS];
}; };
...@@ -100,6 +108,26 @@ static unsigned int max77686_get_opmode_shift(int id) ...@@ -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 */ /* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */
static int max77686_set_suspend_disable(struct regulator_dev *rdev) static int max77686_set_suspend_disable(struct regulator_dev *rdev)
{ {
...@@ -136,7 +164,7 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev, ...@@ -136,7 +164,7 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev,
val = MAX77686_LDO_LOWPOWER_PWRREQ; val = MAX77686_LDO_LOWPOWER_PWRREQ;
break; break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
val = MAX77686_NORMAL; val = max77686_map_normal_mode(max77686, id);
break; break;
default: default:
pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", 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, ...@@ -160,7 +188,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
{ {
unsigned int val; unsigned int val;
struct max77686_data *max77686 = rdev_get_drvdata(rdev); struct max77686_data *max77686 = rdev_get_drvdata(rdev);
int ret; int ret, id = rdev_get_id(rdev);
switch (mode) { switch (mode) {
case REGULATOR_MODE_STANDBY: /* switch off */ case REGULATOR_MODE_STANDBY: /* switch off */
...@@ -170,7 +198,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, ...@@ -170,7 +198,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
val = MAX77686_LDO_LOWPOWER_PWRREQ; val = MAX77686_LDO_LOWPOWER_PWRREQ;
break; break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
val = MAX77686_NORMAL; val = max77686_map_normal_mode(max77686, id);
break; break;
default: default:
pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", 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, ...@@ -184,7 +212,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
if (ret) if (ret)
return ret; return ret;
max77686->opmode[rdev_get_id(rdev)] = val; max77686->opmode[id] = val;
return 0; return 0;
} }
...@@ -197,7 +225,7 @@ static int max77686_enable(struct regulator_dev *rdev) ...@@ -197,7 +225,7 @@ static int max77686_enable(struct regulator_dev *rdev)
shift = max77686_get_opmode_shift(id); shift = max77686_get_opmode_shift(id);
if (max77686->opmode[id] == MAX77686_OFF_PWRREQ) 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, return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, rdev->desc->enable_mask,
...@@ -229,6 +257,36 @@ static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) ...@@ -229,6 +257,36 @@ static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
MAX77686_RAMP_RATE_MASK, ramp_value << 6); 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 = { static struct regulator_ops max77686_ops = {
.list_voltage = regulator_list_voltage_linear, .list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear, .map_voltage = regulator_map_voltage_linear,
...@@ -283,6 +341,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { ...@@ -283,6 +341,7 @@ static struct regulator_ops max77686_buck_dvs_ops = {
.name = "LDO"#num, \ .name = "LDO"#num, \
.of_match = of_match_ptr("LDO"#num), \ .of_match = of_match_ptr("LDO"#num), \
.regulators_node = of_match_ptr("voltage-regulators"), \ .regulators_node = of_match_ptr("voltage-regulators"), \
.of_parse_cb = max77686_of_parse_cb, \
.id = MAX77686_LDO##num, \ .id = MAX77686_LDO##num, \
.ops = &max77686_ops, \ .ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
...@@ -355,6 +414,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { ...@@ -355,6 +414,7 @@ static struct regulator_ops max77686_buck_dvs_ops = {
.name = "BUCK"#num, \ .name = "BUCK"#num, \
.of_match = of_match_ptr("BUCK"#num), \ .of_match = of_match_ptr("BUCK"#num), \
.regulators_node = of_match_ptr("voltage-regulators"), \ .regulators_node = of_match_ptr("voltage-regulators"), \
.of_parse_cb = max77686_of_parse_cb, \
.id = MAX77686_BUCK##num, \ .id = MAX77686_BUCK##num, \
.ops = &max77686_ops, \ .ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \ .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) ...@@ -115,7 +115,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL; 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, .set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear, .list_voltage = regulator_list_voltage_linear,
...@@ -143,7 +143,7 @@ static struct regulator_desc dcdc_desc = { ...@@ -143,7 +143,7 @@ static struct regulator_desc dcdc_desc = {
.enable_is_inverted = true, .enable_is_inverted = true,
}; };
static struct regmap_config max8649_regmap_config = { static const struct regmap_config max8649_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
}; };
......
/*
* 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.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/mt6397-regulator.h>
#include <linux/regulator/of_regulator.h>
/*
* MT6397 regulators' information
*
* @desc: standard fields of regulator description.
* @qi: Mask for query enable signal status of regulators
* @vselon_reg: Register sections for hardware control mode of bucks
* @vselctrl_reg: Register for controlling the buck control mode.
* @vselctrl_mask: Mask for query buck's voltage control mode.
*/
struct mt6397_regulator_info {
struct regulator_desc desc;
u32 qi;
u32 vselon_reg;
u32 vselctrl_reg;
u32 vselctrl_mask;
};
#define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
vosel, vosel_mask, voselon, vosel_ctrl) \
[MT6397_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.ops = &mt6397_volt_range_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6397_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = (max - min)/step + 1, \
.linear_ranges = volt_ranges, \
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
.vsel_reg = vosel, \
.vsel_mask = vosel_mask, \
.enable_reg = enreg, \
.enable_mask = BIT(0), \
}, \
.qi = BIT(13), \
.vselon_reg = voselon, \
.vselctrl_reg = vosel_ctrl, \
.vselctrl_mask = BIT(1), \
}
#define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
vosel_mask) \
[MT6397_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.ops = &mt6397_volt_table_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6397_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(ldo_volt_table), \
.volt_table = ldo_volt_table, \
.vsel_reg = vosel, \
.vsel_mask = vosel_mask, \
.enable_reg = enreg, \
.enable_mask = BIT(enbit), \
}, \
.qi = BIT(15), \
}
#define MT6397_REG_FIXED(match, vreg, enreg, enbit, volt) \
[MT6397_ID_##vreg] = { \
.desc = { \
.name = #vreg, \
.of_match = of_match_ptr(match), \
.ops = &mt6397_volt_fixed_ops, \
.type = REGULATOR_VOLTAGE, \
.id = MT6397_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = 1, \
.enable_reg = enreg, \
.enable_mask = BIT(enbit), \
.min_uV = volt, \
}, \
.qi = BIT(15), \
}
static const struct regulator_linear_range buck_volt_range1[] = {
REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
};
static const struct regulator_linear_range buck_volt_range2[] = {
REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250),
};
static const struct regulator_linear_range buck_volt_range3[] = {
REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000),
};
static const u32 ldo_volt_table1[] = {
1500000, 1800000, 2500000, 2800000,
};
static const u32 ldo_volt_table2[] = {
1800000, 3300000,
};
static const u32 ldo_volt_table3[] = {
3000000, 3300000,
};
static const u32 ldo_volt_table4[] = {
1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table5[] = {
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table5_v2[] = {
1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
};
static const u32 ldo_volt_table6[] = {
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
};
static const u32 ldo_volt_table7[] = {
1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000,
};
static int mt6397_get_status(struct regulator_dev *rdev)
{
int ret;
u32 regval;
struct mt6397_regulator_info *info = rdev_get_drvdata(rdev);
ret = regmap_read(rdev->regmap, info->desc.enable_reg, &regval);
if (ret != 0) {
dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
return ret;
}
return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
}
static struct regulator_ops mt6397_volt_range_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_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,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6397_get_status,
};
static struct regulator_ops mt6397_volt_table_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.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,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6397_get_status,
};
static struct regulator_ops mt6397_volt_fixed_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6397_get_status,
};
/* The array is indexed by id(MT6397_ID_XXX) */
static struct mt6397_regulator_info mt6397_regulators[] = {
MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250,
buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f,
MT6397_VCA15_CON10, MT6397_VCA15_CON5),
MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250,
buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f,
MT6397_VPCA7_CON10, MT6397_VPCA7_CON5),
MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250,
buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9,
0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5),
MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250,
buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9,
0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5),
MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250,
buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f,
MT6397_VCORE_CON10, MT6397_VCORE_CON5),
MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1,
MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f,
MT6397_VGPU_CON10, MT6397_VGPU_CON5),
MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2,
MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f,
MT6397_VDRM_CON10, MT6397_VDRM_CON5),
MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000,
buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f,
MT6397_VIO18_CON10, MT6397_VIO18_CON5),
MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000),
MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000),
MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1,
MT6397_ANALDO_CON2, 15, MT6397_ANALDO_CON6, 0xC0),
MT6397_REG_FIXED("ldo_vio28", VIO28, MT6397_DIGLDO_CON0, 14, 2800000),
MT6397_REG_FIXED("ldo_vusb", VUSB, MT6397_DIGLDO_CON1, 14, 3300000),
MT6397_LDO("ldo_vmc", VMC, ldo_volt_table2,
MT6397_DIGLDO_CON2, 12, MT6397_DIGLDO_CON29, 0x10),
MT6397_LDO("ldo_vmch", VMCH, ldo_volt_table3,
MT6397_DIGLDO_CON3, 14, MT6397_DIGLDO_CON17, 0x80),
MT6397_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table3,
MT6397_DIGLDO_CON4, 14, MT6397_DIGLDO_CON18, 0x10),
MT6397_LDO("ldo_vgp1", VGP1, ldo_volt_table4,
MT6397_DIGLDO_CON5, 15, MT6397_DIGLDO_CON19, 0xE0),
MT6397_LDO("ldo_vgp2", VGP2, ldo_volt_table5,
MT6397_DIGLDO_CON6, 15, MT6397_DIGLDO_CON20, 0xE0),
MT6397_LDO("ldo_vgp3", VGP3, ldo_volt_table5,
MT6397_DIGLDO_CON7, 15, MT6397_DIGLDO_CON21, 0xE0),
MT6397_LDO("ldo_vgp4", VGP4, ldo_volt_table5,
MT6397_DIGLDO_CON8, 15, MT6397_DIGLDO_CON22, 0xE0),
MT6397_LDO("ldo_vgp5", VGP5, ldo_volt_table6,
MT6397_DIGLDO_CON9, 15, MT6397_DIGLDO_CON23, 0xE0),
MT6397_LDO("ldo_vgp6", VGP6, ldo_volt_table5,
MT6397_DIGLDO_CON10, 15, MT6397_DIGLDO_CON33, 0xE0),
MT6397_LDO("ldo_vibr", VIBR, ldo_volt_table7,
MT6397_DIGLDO_CON24, 15, MT6397_DIGLDO_CON25, 0xE00),
};
static int mt6397_set_buck_vosel_reg(struct platform_device *pdev)
{
struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
int i;
u32 regval;
for (i = 0; i < MT6397_MAX_REGULATOR; i++) {
if (mt6397_regulators[i].vselctrl_reg) {
if (regmap_read(mt6397->regmap,
mt6397_regulators[i].vselctrl_reg,
&regval) < 0) {
dev_err(&pdev->dev,
"Failed to read buck ctrl\n");
return -EIO;
}
if (regval & mt6397_regulators[i].vselctrl_mask) {
mt6397_regulators[i].desc.vsel_reg =
mt6397_regulators[i].vselon_reg;
}
}
}
return 0;
}
static int mt6397_regulator_probe(struct platform_device *pdev)
{
struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = {};
struct regulator_dev *rdev;
int i;
u32 reg_value, version;
/* Query buck controller to select activated voltage register part */
if (mt6397_set_buck_vosel_reg(pdev))
return -EIO;
/* Read PMIC chip revision to update constraints and voltage table */
if (regmap_read(mt6397->regmap, MT6397_CID, &reg_value) < 0) {
dev_err(&pdev->dev, "Failed to read Chip ID\n");
return -EIO;
}
dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
version = (reg_value & 0xFF);
switch (version) {
case MT6397_REGULATOR_ID91:
mt6397_regulators[MT6397_ID_VGP2].desc.volt_table =
ldo_volt_table5_v2;
break;
default:
break;
}
for (i = 0; i < MT6397_MAX_REGULATOR; i++) {
config.dev = &pdev->dev;
config.driver_data = &mt6397_regulators[i];
config.regmap = mt6397->regmap;
rdev = devm_regulator_register(&pdev->dev,
&mt6397_regulators[i].desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
mt6397_regulators[i].desc.name);
return PTR_ERR(rdev);
}
}
return 0;
}
static struct platform_driver mt6397_regulator_driver = {
.driver = {
.name = "mt6397-regulator",
},
.probe = mt6397_regulator_probe,
};
module_platform_driver(mt6397_regulator_driver);
MODULE_AUTHOR("Flora Fu <flora.fu@mediatek.com>");
MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mt6397-regulator");
...@@ -270,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match); ...@@ -270,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match);
struct regulator_init_data *regulator_of_get_init_data(struct device *dev, struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc, const struct regulator_desc *desc,
struct regulator_config *config,
struct device_node **node) struct device_node **node)
{ {
struct device_node *search, *child; struct device_node *search, *child;
...@@ -307,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, ...@@ -307,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
break; 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); of_node_get(child);
*node = child; *node = child;
break; break;
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
#define PFUZE100_VGEN5VOL 0x70 #define PFUZE100_VGEN5VOL 0x70
#define PFUZE100_VGEN6VOL 0x71 #define PFUZE100_VGEN6VOL 0x71
enum chips { PFUZE100, PFUZE200 }; enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 };
struct pfuze_regulator { struct pfuze_regulator {
struct regulator_desc desc; struct regulator_desc desc;
...@@ -80,9 +80,18 @@ static const int pfuze100_vsnvs[] = { ...@@ -80,9 +80,18 @@ static const int pfuze100_vsnvs[] = {
1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000, 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[] = { static const struct i2c_device_id pfuze_device_id[] = {
{.name = "pfuze100", .driver_data = PFUZE100}, {.name = "pfuze100", .driver_data = PFUZE100},
{.name = "pfuze200", .driver_data = PFUZE200}, {.name = "pfuze200", .driver_data = PFUZE200},
{.name = "pfuze3000", .driver_data = PFUZE3000},
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, pfuze_device_id); MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
...@@ -90,6 +99,7 @@ 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[] = { static const struct of_device_id pfuze_dt_ids[] = {
{ .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
{ .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
{ .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000},
{ } { }
}; };
MODULE_DEVICE_TABLE(of, pfuze_dt_ids); MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
...@@ -219,6 +229,60 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { ...@@ -219,6 +229,60 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
.stby_mask = 0x20, \ .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 */ /* PFUZE100 */
static struct pfuze_regulator pfuze100_regulators[] = { static struct pfuze_regulator pfuze100_regulators[] = {
PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
...@@ -254,6 +318,22 @@ static struct pfuze_regulator pfuze200_regulators[] = { ...@@ -254,6 +318,22 @@ static struct pfuze_regulator pfuze200_regulators[] = {
PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 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; static struct pfuze_regulator *pfuze_regulators;
#ifdef CONFIG_OF #ifdef CONFIG_OF
...@@ -294,6 +374,24 @@ static struct of_regulator_match pfuze200_matches[] = { ...@@ -294,6 +374,24 @@ static struct of_regulator_match pfuze200_matches[] = {
{ .name = "vgen6", }, { .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 struct of_regulator_match *pfuze_matches;
static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
...@@ -313,6 +411,11 @@ 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) { 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: case PFUZE200:
pfuze_matches = pfuze200_matches; pfuze_matches = pfuze200_matches;
ret = of_regulator_match(dev, parent, pfuze200_matches, ret = of_regulator_match(dev, parent, pfuze200_matches,
...@@ -378,7 +481,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip) ...@@ -378,7 +481,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
* as ID=8 in PFUZE100 * as ID=8 in PFUZE100
*/ */
dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); 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 */ /* device id NOT match with your setting */
dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
return -ENODEV; return -ENODEV;
...@@ -417,7 +521,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ...@@ -417,7 +521,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
int i, ret; int i, ret;
const struct of_device_id *match; const struct of_device_id *match;
u32 regulator_num; 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), pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip),
GFP_KERNEL); GFP_KERNEL);
...@@ -458,13 +562,19 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ...@@ -458,13 +562,19 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
/* use the right regulators after identify the right device */ /* use the right regulators after identify the right device */
switch (pfuze_chip->chip_id) { 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: case PFUZE200:
pfuze_regulators = pfuze200_regulators; pfuze_regulators = pfuze200_regulators;
regulator_num = ARRAY_SIZE(pfuze200_regulators); regulator_num = ARRAY_SIZE(pfuze200_regulators);
sw_check_start = PFUZE200_SW2; sw_check_start = PFUZE200_SW2;
sw_check_end = PFUZE200_SW3B; sw_check_end = PFUZE200_SW3B;
break; break;
case PFUZE100: case PFUZE100:
default: default:
pfuze_regulators = pfuze100_regulators; pfuze_regulators = pfuze100_regulators;
...@@ -474,7 +584,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ...@@ -474,7 +584,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
break; break;
} }
dev_info(&client->dev, "pfuze%s found.\n", 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, memcpy(pfuze_chip->regulator_descs, pfuze_regulators,
sizeof(pfuze_chip->regulator_descs)); sizeof(pfuze_chip->regulator_descs));
...@@ -498,10 +609,15 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ...@@ -498,10 +609,15 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
/* SW2~SW4 high bit check and modify the voltage value table */ /* SW2~SW4 high bit check and modify the voltage value table */
if (i >= sw_check_start && i <= sw_check_end) { if (i >= sw_check_start && i <= sw_check_end) {
regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
if (val & 0x40) { if (val & sw_hi) {
desc->min_uV = 800000; if (pfuze_chip->chip_id == PFUZE3000) {
desc->uV_step = 50000; desc->volt_table = pfuze3000_sw2hi;
desc->n_voltages = 51; 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, ...@@ -227,9 +227,11 @@ static int rpm_reg_set_mV_sel(struct regulator_dev *rdev,
return uV; return uV;
mutex_lock(&vreg->lock); mutex_lock(&vreg->lock);
vreg->uV = uV;
if (vreg->is_enabled) 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); mutex_unlock(&vreg->lock);
return ret; return ret;
...@@ -252,9 +254,11 @@ static int rpm_reg_set_uV_sel(struct regulator_dev *rdev, ...@@ -252,9 +254,11 @@ static int rpm_reg_set_uV_sel(struct regulator_dev *rdev,
return uV; return uV;
mutex_lock(&vreg->lock); mutex_lock(&vreg->lock);
vreg->uV = uV;
if (vreg->is_enabled) 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); mutex_unlock(&vreg->lock);
return ret; return ret;
...@@ -674,6 +678,7 @@ static int rpm_reg_probe(struct platform_device *pdev) ...@@ -674,6 +678,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
vreg->desc.owner = THIS_MODULE; vreg->desc.owner = THIS_MODULE;
vreg->desc.type = REGULATOR_VOLTAGE; vreg->desc.type = REGULATOR_VOLTAGE;
vreg->desc.name = pdev->dev.of_node->name; vreg->desc.name = pdev->dev.of_node->name;
vreg->desc.supply_name = "vin";
vreg->rpm = dev_get_drvdata(pdev->dev.parent); vreg->rpm = dev_get_drvdata(pdev->dev.parent);
if (!vreg->rpm) { if (!vreg->rpm) {
...@@ -768,7 +773,7 @@ static int rpm_reg_probe(struct platform_device *pdev) ...@@ -768,7 +773,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
break; break;
} }
if (force_mode < 0) { if (force_mode == -1) {
dev_err(&pdev->dev, "invalid force mode\n"); dev_err(&pdev->dev, "invalid force mode\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -97,7 +97,7 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) ...@@ -97,7 +97,7 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
RK808_RAMP_RATE_MASK, ramp_value); 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; unsigned int reg;
int sel = regulator_map_voltage_linear_range(rdev, uv, uv); 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) ...@@ -112,7 +112,7 @@ int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
sel); sel);
} }
int rk808_set_suspend_enable(struct regulator_dev *rdev) static int rk808_set_suspend_enable(struct regulator_dev *rdev)
{ {
unsigned int reg; unsigned int reg;
...@@ -123,7 +123,7 @@ int rk808_set_suspend_enable(struct regulator_dev *rdev) ...@@ -123,7 +123,7 @@ int rk808_set_suspend_enable(struct regulator_dev *rdev)
0); 0);
} }
int rk808_set_suspend_disable(struct regulator_dev *rdev) static int rk808_set_suspend_disable(struct regulator_dev *rdev)
{ {
unsigned int reg; unsigned int reg;
......
...@@ -36,6 +36,8 @@ static struct regulator_ops rt5033_buck_ops = { ...@@ -36,6 +36,8 @@ static struct regulator_ops rt5033_buck_ops = {
static const struct regulator_desc rt5033_supported_regulators[] = { static const struct regulator_desc rt5033_supported_regulators[] = {
[RT5033_BUCK] = { [RT5033_BUCK] = {
.name = "BUCK", .name = "BUCK",
.of_match = of_match_ptr("BUCK"),
.regulators_node = of_match_ptr("regulators"),
.id = RT5033_BUCK, .id = RT5033_BUCK,
.ops = &rt5033_buck_ops, .ops = &rt5033_buck_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -50,6 +52,8 @@ static const struct regulator_desc rt5033_supported_regulators[] = { ...@@ -50,6 +52,8 @@ static const struct regulator_desc rt5033_supported_regulators[] = {
}, },
[RT5033_LDO] = { [RT5033_LDO] = {
.name = "LDO", .name = "LDO",
.of_match = of_match_ptr("LDO"),
.regulators_node = of_match_ptr("regulators"),
.id = RT5033_LDO, .id = RT5033_LDO,
.ops = &rt5033_buck_ops, .ops = &rt5033_buck_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -64,6 +68,8 @@ static const struct regulator_desc rt5033_supported_regulators[] = { ...@@ -64,6 +68,8 @@ static const struct regulator_desc rt5033_supported_regulators[] = {
}, },
[RT5033_SAFE_LDO] = { [RT5033_SAFE_LDO] = {
.name = "SAFE_LDO", .name = "SAFE_LDO",
.of_match = of_match_ptr("SAFE_LDO"),
.regulators_node = of_match_ptr("regulators"),
.id = RT5033_SAFE_LDO, .id = RT5033_SAFE_LDO,
.ops = &rt5033_safe_ldo_ops, .ops = &rt5033_safe_ldo_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -81,7 +87,7 @@ static int rt5033_regulator_probe(struct platform_device *pdev) ...@@ -81,7 +87,7 @@ static int rt5033_regulator_probe(struct platform_device *pdev)
int ret, i; int ret, i;
struct regulator_config config = {}; struct regulator_config config = {};
config.dev = &pdev->dev; config.dev = rt5033->dev;
config.driver_data = rt5033; config.driver_data = rt5033;
for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) { 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, ...@@ -173,7 +173,7 @@ static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
} }
/* Operations permitted on VDCDCx */ /* 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, .is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap, .enable = regulator_enable_regmap,
.disable = regulator_disable_regmap, .disable = regulator_disable_regmap,
...@@ -184,7 +184,7 @@ static struct regulator_ops tps65023_dcdc_ops = { ...@@ -184,7 +184,7 @@ static struct regulator_ops tps65023_dcdc_ops = {
}; };
/* Operations permitted on LDOx */ /* 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, .is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap, .enable = regulator_enable_regmap,
.disable = regulator_disable_regmap, .disable = regulator_disable_regmap,
...@@ -194,7 +194,7 @@ static struct regulator_ops tps65023_ldo_ops = { ...@@ -194,7 +194,7 @@ static struct regulator_ops tps65023_ldo_ops = {
.map_voltage = regulator_map_voltage_ascend, .map_voltage = regulator_map_voltage_ascend,
}; };
static struct regmap_config tps65023_regmap_config = { static const struct regmap_config tps65023_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
}; };
......
...@@ -32,6 +32,8 @@ struct da9211_pdata { ...@@ -32,6 +32,8 @@ struct da9211_pdata {
* 2 : 2 phase 2 buck * 2 : 2 phase 2 buck
*/ */
int num_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]; struct regulator_init_data *init_data[DA9211_MAX_REGULATORS];
}; };
#endif #endif
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
struct regmap; struct regmap;
struct regulator_dev; struct regulator_dev;
struct regulator_config;
struct regulator_init_data; struct regulator_init_data;
struct regulator_enable_gpio; struct regulator_enable_gpio;
...@@ -205,6 +206,15 @@ enum regulator_type { ...@@ -205,6 +206,15 @@ enum regulator_type {
* @supply_name: Identifying the regulator supply * @supply_name: Identifying the regulator supply
* @of_match: Name used to identify regulator in DT. * @of_match: Name used to identify regulator in DT.
* @regulators_node: Name of node containing regulator definitions 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. * @id: Numerical identifier for the regulator.
* @ops: Regulator operations table. * @ops: Regulator operations table.
* @irq: Interrupt number for the regulator. * @irq: Interrupt number for the regulator.
...@@ -251,6 +261,9 @@ struct regulator_desc { ...@@ -251,6 +261,9 @@ struct regulator_desc {
const char *supply_name; const char *supply_name;
const char *of_match; const char *of_match;
const char *regulators_node; const char *regulators_node;
int (*of_parse_cb)(struct device_node *,
const struct regulator_desc *,
struct regulator_config *);
int id; int id;
bool continuous_voltage_range; bool continuous_voltage_range;
unsigned n_voltages; unsigned n_voltages;
......
...@@ -191,15 +191,22 @@ struct regulator_init_data { ...@@ -191,15 +191,22 @@ struct regulator_init_data {
void *driver_data; /* core does not touch this */ void *driver_data; /* core does not touch this */
}; };
int regulator_suspend_prepare(suspend_state_t state);
int regulator_suspend_finish(void);
#ifdef CONFIG_REGULATOR #ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void); void regulator_has_full_constraints(void);
int regulator_suspend_prepare(suspend_state_t state);
int regulator_suspend_finish(void);
#else #else
static inline void regulator_has_full_constraints(void) 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
#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 @@ ...@@ -49,6 +49,20 @@
#define PFUZE200_VGEN5 11 #define PFUZE200_VGEN5 11
#define PFUZE200_VGEN6 12 #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 regulator_init_data;
struct pfuze_regulator_platform_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