Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull regulator updates from Mark Brown:
"Aside from a fix for a spurious warning (which caused more problems
than it fixed in the fixing really) this is all driver updates,
including new drivers for Dialog PV88060/90 and TI LM363x and TPS65086
devices. The qcom_smd driver has had PM8916 and PMA8084 support
added"

* tag 'regulator-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (36 commits)
regulator: core: remove some dead code
regulator: core: use dev_to_rdev
regulator: lp872x: Get rid of duplicate reference to DVS GPIO
regulator: lp872x: Add missing of_match in regulators descriptions
regulator: axp20x: Fix GPIO LDO enable value for AXP22x
regulator: lp8788: constify regulator_ops structures
regulator: wm8*: constify regulator_ops structures
regulator: da9*: constify regulator_ops structures
regulator: mt6311: Use REGCACHE_RBTREE
regulator: tps65917/palmas: Add bypass ops for LDOs with bypass capability
regulator: qcom-smd: Add support for PMA8084
regulator: qcom-smd: Add PM8916 support
soc: qcom: documentation: Update SMD/RPM Docs
regulator: pv88090: logical vs bitwise AND typo
regulator: pv88090: Fix irq leak
regulator: pv88090: new regulator driver
regulator: wm831x-ldo: Use platform_register/unregister_drivers()
regulator: wm831x-dcdc: Use platform_register/unregister_drivers()
regulator: lp8788-ldo: Use platform_register/unregister_drivers()
regulator: core: Fix nested locking of supplies
...

+2414 -248
+34
Documentation/devicetree/bindings/regulator/lm363x-regulator.txt
··· 1 + TI LMU LM363x regulator device tree bindings 2 + 3 + LM363x regulator driver supports LM3631 and LM3632. 4 + LM3631 has five regulators and LM3632 supports three regulators. 5 + 6 + Required property: 7 + - compatible: "ti,lm363x-regulator" 8 + 9 + Optional properties: 10 + LM3632 has external enable pins for two LDOs. 11 + - ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin. 12 + - ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin. 13 + 14 + Child nodes: 15 + LM3631 16 + - vboost 17 + - vcont 18 + - voref 19 + - vpos 20 + - vneg 21 + 22 + LM3632 23 + - vboost 24 + - vpos 25 + - vneg 26 + 27 + Optional properties of a child node: 28 + Each sub-node should contain the constraints and initialization. 29 + Please refer to [1]. 30 + 31 + Examples: Please refer to ti-lmu dt-bindings [2]. 32 + 33 + [1] ../regulator/regulator.txt 34 + [2] ../mfd/ti-lmu.txt
+124
Documentation/devicetree/bindings/regulator/pv88060.txt
··· 1 + * Powerventure Semiconductor PV88060 Voltage Regulator 2 + 3 + Required properties: 4 + - compatible: "pvs,pv88060". 5 + - reg: I2C slave address, usually 0x49. 6 + - interrupts: the interrupt outputs of the controller 7 + - regulators: A node that houses a sub-node for each regulator within the 8 + device. Each sub-node is identified using the node's name, with valid 9 + values listed below. The content of each sub-node is defined by the 10 + standard binding for regulators; see regulator.txt. 11 + BUCK1, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, SW1, SW2, SW3, SW4, 12 + SW5, and SW6. 13 + 14 + Optional properties: 15 + - Any optional property defined in regulator.txt 16 + 17 + Example 18 + 19 + pmic: pv88060@49 { 20 + compatible = "pvs,pv88060"; 21 + reg = <0x49>; 22 + interrupt-parent = <&gpio>; 23 + interrupts = <24 24>; 24 + 25 + regulators { 26 + BUCK1 { 27 + regulator-name = "buck1"; 28 + regulator-min-microvolt = <2800000>; 29 + regulator-max-microvolt = <4387500>; 30 + regulator-min-microamp = <1496000>; 31 + regulator-max-microamp = <4189000>; 32 + regulator-boot-on; 33 + }; 34 + 35 + LDO1 { 36 + regulator-name = "ldo1"; 37 + regulator-min-microvolt = <1200000>; 38 + regulator-max-microvolt = <3350000>; 39 + regulator-boot-on; 40 + }; 41 + 42 + LDO2 { 43 + regulator-name = "ldo2"; 44 + regulator-min-microvolt = <1200000>; 45 + regulator-max-microvolt = <3350000>; 46 + regulator-boot-on; 47 + }; 48 + 49 + LDO3 { 50 + regulator-name = "ldo3"; 51 + regulator-min-microvolt = <1200000>; 52 + regulator-max-microvolt = <3350000>; 53 + regulator-boot-on; 54 + }; 55 + 56 + LDO4 { 57 + regulator-name = "ldo4"; 58 + regulator-min-microvolt = <1200000>; 59 + regulator-max-microvolt = <3350000>; 60 + regulator-boot-on; 61 + }; 62 + 63 + LDO5 { 64 + regulator-name = "ldo5"; 65 + regulator-min-microvolt = <1200000>; 66 + regulator-max-microvolt = <3350000>; 67 + regulator-boot-on; 68 + }; 69 + 70 + LDO6 { 71 + regulator-name = "ldo6"; 72 + regulator-min-microvolt = <1200000>; 73 + regulator-max-microvolt = <3350000>; 74 + regulator-boot-on; 75 + }; 76 + 77 + LDO7 { 78 + regulator-name = "ldo7"; 79 + regulator-min-microvolt = <1200000>; 80 + regulator-max-microvolt = <3350000>; 81 + regulator-boot-on; 82 + }; 83 + 84 + SW1 { 85 + regulator-name = "sw1"; 86 + regulator-min-microvolt = <5000000>; 87 + regulator-max-microvolt = <5000000>; 88 + }; 89 + 90 + SW2 { 91 + regulator-name = "sw2"; 92 + regulator-min-microvolt = <5000000>; 93 + regulator-max-microvolt = <5000000>; 94 + regulator-boot-on; 95 + }; 96 + 97 + SW3 { 98 + regulator-name = "sw3"; 99 + regulator-min-microvolt = <5000000>; 100 + regulator-max-microvolt = <5000000>; 101 + regulator-boot-on; 102 + }; 103 + 104 + SW4 { 105 + regulator-name = "sw4"; 106 + regulator-min-microvolt = <5000000>; 107 + regulator-max-microvolt = <5000000>; 108 + regulator-boot-on; 109 + }; 110 + 111 + SW5 { 112 + regulator-name = "sw5"; 113 + regulator-min-microvolt = <5000000>; 114 + regulator-max-microvolt = <5000000>; 115 + regulator-boot-on; 116 + }; 117 + 118 + SW6 { 119 + regulator-name = "sw6"; 120 + regulator-min-microvolt = <5000000>; 121 + regulator-max-microvolt = <5000000>; 122 + }; 123 + }; 124 + };
+65
Documentation/devicetree/bindings/regulator/pv88090.txt
··· 1 + * Powerventure Semiconductor PV88090 Voltage Regulator 2 + 3 + Required properties: 4 + - compatible: "pvs,pv88090". 5 + - reg: I2C slave address, usually 0x48. 6 + - interrupts: the interrupt outputs of the controller 7 + - regulators: A node that houses a sub-node for each regulator within the 8 + device. Each sub-node is identified using the node's name, with valid 9 + values listed below. The content of each sub-node is defined by the 10 + standard binding for regulators; see regulator.txt. 11 + BUCK1, BUCK2, BUCK3, LDO1, and LDO2. 12 + 13 + Optional properties: 14 + - Any optional property defined in regulator.txt 15 + 16 + Example 17 + 18 + pmic: pv88090@48 { 19 + compatible = "pvs,pv88090"; 20 + reg = <0x48>; 21 + interrupt-parent = <&gpio>; 22 + interrupts = <24 24>; 23 + 24 + regulators { 25 + BUCK1 { 26 + regulator-name = "buck1"; 27 + regulator-min-microvolt = < 600000>; 28 + regulator-max-microvolt = <1393750>; 29 + regulator-min-microamp = < 220000>; 30 + regulator-max-microamp = <7040000>; 31 + regulator-boot-on; 32 + }; 33 + 34 + BUCK2 { 35 + regulator-name = "buck2"; 36 + regulator-min-microvolt = < 600000>; 37 + regulator-max-microvolt = <1393750>; 38 + regulator-min-microamp = <1496000>; 39 + regulator-max-microamp = <4189000>; 40 + }; 41 + 42 + BUCK3 { 43 + regulator-name = "buck3"; 44 + regulator-min-microvolt = <600000>; 45 + regulator-max-microvolt = <1393750>; 46 + regulator-min-microamp = <1496000>; 47 + regulator-max-microamp = <4189000>; 48 + regulator-boot-on; 49 + }; 50 + 51 + LDO1 { 52 + regulator-name = "ldo1"; 53 + regulator-min-microvolt = <1200000>; 54 + regulator-max-microvolt = <4350000>; 55 + regulator-boot-on; 56 + }; 57 + 58 + LDO2 { 59 + regulator-name = "ldo2"; 60 + regulator-min-microvolt = < 650000>; 61 + regulator-max-microvolt = <2225000>; 62 + regulator-boot-on; 63 + }; 64 + }; 65 + };
+63 -21
Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
··· 1 - Qualcomm Resource Power Manager (RPM) over SMD 1 + QCOM SMD RPM REGULATOR 2 2 3 - This driver is used to interface with the Resource Power Manager (RPM) found in 4 - various Qualcomm platforms. The RPM allows each component in the system to vote 5 - for state of the system resources, such as clocks, regulators and bus 6 - frequencies. 3 + The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM. 4 + Because SMD is used as the communication transport mechanism, the RPM resides as 5 + a subnode of the SMD. As such, the SMD-RPM regulator requires that the SMD and 6 + RPM nodes be present. 7 7 8 - - compatible: 9 - Usage: required 10 - Value type: <string> 11 - Definition: must be one of: 12 - "qcom,rpm-msm8974" 8 + Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for 9 + information pertaining to the SMD node. 13 10 14 - - qcom,smd-channels: 15 - Usage: required 16 - Value type: <stringlist> 17 - Definition: Shared Memory channel used for communication with the RPM 11 + Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt for 12 + information regarding the RPM node. 18 13 19 - = SUBDEVICES 20 - 21 - The RPM exposes resources to its subnodes. The below bindings specify the set 22 - of valid subnodes that can operate on these resources. 23 - 24 - == Regulators 14 + == Regulator 25 15 26 16 Regulator nodes are identified by their compatible: 27 17 ··· 20 30 Value type: <string> 21 31 Definition: must be one of: 22 32 "qcom,rpm-pm8841-regulators" 33 + "qcom,rpm-pm8916-regulators" 23 34 "qcom,rpm-pm8941-regulators" 35 + "qcom,rpm-pma8084-regulators" 24 36 25 37 - vdd_s1-supply: 26 38 - vdd_s2-supply: ··· 33 41 - vdd_s7-supply: 34 42 - vdd_s8-supply: 35 43 Usage: optional (pm8841 only) 44 + Value type: <phandle> 45 + Definition: reference to regulator supplying the input pin, as 46 + described in the data sheet 47 + 48 + - vdd_s1-supply: 49 + - vdd_s2-supply: 50 + - vdd_s3-supply: 51 + - vdd_s4-supply: 52 + - vdd_l1_l2_l3-supply: 53 + - vdd_l4_l5_l6-supply: 54 + - vdd_l7-supply: 55 + - vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18-supply: 56 + Usage: optional (pm8916 only) 36 57 Value type: <phandle> 37 58 Definition: reference to regulator supplying the input pin, as 38 59 described in the data sheet ··· 68 63 Definition: reference to regulator supplying the input pin, as 69 64 described in the data sheet 70 65 66 + - vdd_s1-supply: 67 + - vdd_s2-supply: 68 + - vdd_s3-supply: 69 + - vdd_s4-supply: 70 + - vdd_s5-supply: 71 + - vdd_s6-supply: 72 + - vdd_s7-supply: 73 + - vdd_s8-supply: 74 + - vdd_s9-supply: 75 + - vdd_s10-supply: 76 + - vdd_s11-supply: 77 + - vdd_s12-supply: 78 + - vdd_l1_l11-supply: 79 + - vdd_l2_l3_l4_l27-supply: 80 + - vdd_l5_l7-supply: 81 + - vdd_l6_l12_l14_l15_l26-supply: 82 + - vdd_l8-supply: 83 + - vdd_l9_l10_l13_l20_l23_l24-supply: 84 + - vdd_l16_l25-supply: 85 + - vdd_l17-supply: 86 + - vdd_l18-supply: 87 + - vdd_l19-supply: 88 + - vdd_l21-supply: 89 + - vdd_l22-supply: 90 + Usage: optional (pma8084 only) 91 + Value type: <phandle> 92 + Definition: reference to regulator supplying the input pin, as 93 + described in the data sheet 94 + 71 95 The regulator node houses sub-nodes for each regulator within the device. Each 72 96 sub-node is identified using the node's name, with valid values listed for each 73 97 of the pmics below. ··· 104 70 pm8841: 105 71 s1, s2, s3, s4, s5, s6, s7, s8 106 72 73 + pm8916: 74 + s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, 75 + l14, l15, l16, l17, l18 76 + 107 77 pm8941: 108 78 s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, 109 79 l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, 110 80 lvs3, 5vs1, 5vs2 81 + 82 + pma8084: 83 + s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, 84 + l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, 85 + l21, l22, l23, l24, l25, l26, l27, lvs1, lvs2, lvs3, lvs4, 5vs1 111 86 112 87 The content of each sub-node is defined by the standard binding for regulators - 113 88 see regulator.txt. ··· 157 114 }; 158 115 }; 159 116 }; 160 -
+58
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt
··· 1 + Qualcomm Resource Power Manager (RPM) over SMD 2 + 3 + This driver is used to interface with the Resource Power Manager (RPM) found in 4 + various Qualcomm platforms. The RPM allows each component in the system to vote 5 + for state of the system resources, such as clocks, regulators and bus 6 + frequencies. 7 + 8 + The SMD information for the RPM edge should be filled out. See qcom,smd.txt for 9 + the required edge properties. All SMD related properties will reside within the 10 + RPM node itself. 11 + 12 + = SUBDEVICES 13 + 14 + The RPM exposes resources to its subnodes. The rpm_requests node must be 15 + present and this subnode may contain children that designate regulator 16 + resources. 17 + 18 + - compatible: 19 + Usage: required 20 + Value type: <string> 21 + Definition: must be one of: 22 + "qcom,rpm-apq8084" 23 + "qcom,rpm-msm8916" 24 + "qcom,rpm-msm8974" 25 + 26 + - qcom,smd-channels: 27 + Usage: required 28 + Value type: <string> 29 + Definition: must be "rpm_requests" 30 + 31 + Refer to Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt 32 + for information on the regulator subnodes that can exist under the rpm_requests. 33 + 34 + Example: 35 + 36 + soc { 37 + apcs: syscon@f9011000 { 38 + compatible = "syscon"; 39 + reg = <0xf9011000 0x1000>; 40 + }; 41 + }; 42 + 43 + smd { 44 + compatible = "qcom,smd"; 45 + 46 + rpm { 47 + interrupts = <0 168 1>; 48 + qcom,ipc = <&apcs 8 0>; 49 + qcom,smd-edge = <15>; 50 + 51 + rpm_requests { 52 + compatible = "qcom,rpm-msm8974"; 53 + qcom,smd-channels = "rpm_requests"; 54 + 55 + ... 56 + }; 57 + }; 58 + };
+33
drivers/regulator/Kconfig
··· 274 274 help 275 275 This driver supports ISL6271A voltage regulator chip. 276 276 277 + config REGULATOR_LM363X 278 + tristate "TI LM363X voltage regulators" 279 + depends on MFD_TI_LMU 280 + help 281 + This driver supports LM3631 and LM3632 voltage regulators for 282 + the LCD bias. 283 + One boost output voltage is configurable and always on. 284 + Other LDOs are used for the display module. 285 + 277 286 config REGULATOR_LP3971 278 287 tristate "National Semiconductors LP3971 PMIC regulator driver" 279 288 depends on I2C ··· 455 446 config REGULATOR_MT6311 456 447 tristate "MediaTek MT6311 PMIC" 457 448 depends on I2C 449 + select REGMAP_I2C 458 450 help 459 451 Say y here to select this option to enable the power regulator of 460 452 MediaTek MT6311 PMIC. ··· 513 503 help 514 504 Say y here to support the regulators found on the Freescale 515 505 PFUZE100/PFUZE200 PMIC. 506 + 507 + config REGULATOR_PV88060 508 + tristate "Powerventure Semiconductor PV88060 regulator" 509 + depends on I2C 510 + select REGMAP_I2C 511 + help 512 + Say y here to support the voltage regulators and convertors 513 + PV88060 514 + 515 + config REGULATOR_PV88090 516 + tristate "Powerventure Semiconductor PV88090 regulator" 517 + depends on I2C 518 + select REGMAP_I2C 519 + help 520 + Say y here to support the voltage regulators and convertors 521 + on PV88090 516 522 517 523 config REGULATOR_PWM 518 524 tristate "PWM voltage regulator" ··· 705 679 This driver supports TPS6507X voltage regulator chips. TPS6507X provides 706 680 three step-down converters and two general-purpose LDO voltage regulators. 707 681 It supports TI's software based Class-2 SmartReflex implementation. 682 + 683 + config REGULATOR_TPS65086 684 + tristate "TI TPS65086 Power regulators" 685 + depends on MFD_TPS65086 686 + help 687 + This driver provides support for the voltage regulators on 688 + TI TPS65086 PMICs. 708 689 709 690 config REGULATOR_TPS65090 710 691 tristate "TI TPS65090 Power regulator"
+4
drivers/regulator/Makefile
··· 36 36 obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o 37 37 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o 38 38 obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o 39 + obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o 39 40 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o 40 41 obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o 41 42 obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o ··· 67 66 obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o 68 67 obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o 69 68 obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o 69 + obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o 70 + obj-$(CONFIG_REGULATOR_PV88090) += pv88090-regulator.o 70 71 obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o 71 72 obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o 72 73 obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o ··· 88 85 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o 89 86 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o 90 87 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o 88 + obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o 91 89 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o 92 90 obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o 93 91 obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
+2 -2
drivers/regulator/axp20x-regulator.c
··· 27 27 #define AXP20X_IO_ENABLED 0x03 28 28 #define AXP20X_IO_DISABLED 0x07 29 29 30 - #define AXP22X_IO_ENABLED 0x04 31 - #define AXP22X_IO_DISABLED 0x03 30 + #define AXP22X_IO_ENABLED 0x03 31 + #define AXP22X_IO_DISABLED 0x04 32 32 33 33 #define AXP20X_WORKMODE_DCDC2_MASK BIT(2) 34 34 #define AXP20X_WORKMODE_DCDC3_MASK BIT(1)
+19 -22
drivers/regulator/core.c
··· 132 132 return has_full_constraints || of_have_populated_dt(); 133 133 } 134 134 135 + static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) 136 + { 137 + if (rdev && rdev->supply) 138 + return rdev->supply->rdev; 139 + 140 + return NULL; 141 + } 142 + 135 143 /** 136 144 * regulator_lock_supply - lock a regulator and its supplies 137 145 * @rdev: regulator source 138 146 */ 139 147 static void regulator_lock_supply(struct regulator_dev *rdev) 140 148 { 141 - struct regulator *supply; 142 - int i = 0; 149 + int i; 143 150 144 - while (1) { 145 - mutex_lock_nested(&rdev->mutex, i++); 146 - supply = rdev->supply; 147 - 148 - if (!rdev->supply) 149 - return; 150 - 151 - rdev = supply->rdev; 152 - } 151 + for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++) 152 + mutex_lock_nested(&rdev->mutex, i); 153 153 } 154 154 155 155 /** ··· 2368 2368 int regulator_disable_deferred(struct regulator *regulator, int ms) 2369 2369 { 2370 2370 struct regulator_dev *rdev = regulator->rdev; 2371 - int ret; 2372 2371 2373 2372 if (regulator->always_on) 2374 2373 return 0; ··· 2379 2380 rdev->deferred_disables++; 2380 2381 mutex_unlock(&rdev->mutex); 2381 2382 2382 - ret = queue_delayed_work(system_power_efficient_wq, 2383 - &rdev->disable_work, 2384 - msecs_to_jiffies(ms)); 2385 - if (ret < 0) 2386 - return ret; 2387 - else 2388 - return 0; 2383 + queue_delayed_work(system_power_efficient_wq, &rdev->disable_work, 2384 + msecs_to_jiffies(ms)); 2385 + return 0; 2389 2386 } 2390 2387 EXPORT_SYMBOL_GPL(regulator_disable_deferred); 2391 2388 ··· 3446 3451 consumers[i].consumer = NULL; 3447 3452 3448 3453 for (i = 0; i < num_consumers; i++) { 3449 - consumers[i].consumer = regulator_get(dev, 3450 - consumers[i].supply); 3454 + consumers[i].consumer = _regulator_get(dev, 3455 + consumers[i].supply, 3456 + false, 3457 + !consumers[i].optional); 3451 3458 if (IS_ERR(consumers[i].consumer)) { 3452 3459 ret = PTR_ERR(consumers[i].consumer); 3453 3460 dev_err(dev, "Failed to get supply '%s': %d\n", ··· 3705 3708 struct attribute *attr, int idx) 3706 3709 { 3707 3710 struct device *dev = kobj_to_dev(kobj); 3708 - struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev); 3711 + struct regulator_dev *rdev = dev_to_rdev(dev); 3709 3712 const struct regulator_ops *ops = rdev->desc->ops; 3710 3713 umode_t mode = attr->mode; 3711 3714
+5 -5
drivers/regulator/da903x.c
··· 257 257 REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000), 258 258 }; 259 259 260 - static struct regulator_ops da903x_regulator_ldo_ops = { 260 + static const struct regulator_ops da903x_regulator_ldo_ops = { 261 261 .set_voltage_sel = da903x_set_voltage_sel, 262 262 .get_voltage_sel = da903x_get_voltage_sel, 263 263 .list_voltage = regulator_list_voltage_linear, ··· 268 268 }; 269 269 270 270 /* NOTE: this is dedicated for the insane DA9030 LDO14 */ 271 - static struct regulator_ops da9030_regulator_ldo14_ops = { 271 + static const struct regulator_ops da9030_regulator_ldo14_ops = { 272 272 .set_voltage_sel = da903x_set_voltage_sel, 273 273 .get_voltage_sel = da903x_get_voltage_sel, 274 274 .list_voltage = da9030_list_ldo14_voltage, ··· 279 279 }; 280 280 281 281 /* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */ 282 - static struct regulator_ops da9030_regulator_ldo1_15_ops = { 282 + static const struct regulator_ops da9030_regulator_ldo1_15_ops = { 283 283 .set_voltage_sel = da9030_set_ldo1_15_voltage_sel, 284 284 .get_voltage_sel = da903x_get_voltage_sel, 285 285 .list_voltage = regulator_list_voltage_linear, ··· 289 289 .is_enabled = da903x_is_enabled, 290 290 }; 291 291 292 - static struct regulator_ops da9034_regulator_dvc_ops = { 292 + static const struct regulator_ops da9034_regulator_dvc_ops = { 293 293 .set_voltage_sel = da9034_set_dvc_voltage_sel, 294 294 .get_voltage_sel = da903x_get_voltage_sel, 295 295 .list_voltage = regulator_list_voltage_linear, ··· 300 300 }; 301 301 302 302 /* NOTE: this is dedicated for the insane LDO12 */ 303 - static struct regulator_ops da9034_regulator_ldo12_ops = { 303 + static const struct regulator_ops da9034_regulator_ldo12_ops = { 304 304 .set_voltage_sel = da903x_set_voltage_sel, 305 305 .get_voltage_sel = da903x_get_voltage_sel, 306 306 .list_voltage = regulator_list_voltage_linear_range,
+2 -2
drivers/regulator/da9052-regulator.c
··· 265 265 return ret; 266 266 } 267 267 268 - static struct regulator_ops da9052_dcdc_ops = { 268 + static const struct regulator_ops da9052_dcdc_ops = { 269 269 .get_current_limit = da9052_dcdc_get_current_limit, 270 270 .set_current_limit = da9052_dcdc_set_current_limit, 271 271 ··· 279 279 .disable = regulator_disable_regmap, 280 280 }; 281 281 282 - static struct regulator_ops da9052_ldo_ops = { 282 + static const struct regulator_ops da9052_ldo_ops = { 283 283 .list_voltage = da9052_list_voltage, 284 284 .map_voltage = da9052_map_voltage, 285 285 .get_voltage_sel = regulator_get_voltage_sel_regmap,
+2 -2
drivers/regulator/da9055-regulator.c
··· 324 324 return 0; 325 325 } 326 326 327 - static struct regulator_ops da9055_buck_ops = { 327 + static const struct regulator_ops da9055_buck_ops = { 328 328 .get_mode = da9055_buck_get_mode, 329 329 .set_mode = da9055_buck_set_mode, 330 330 ··· 345 345 .set_suspend_mode = da9055_buck_set_mode, 346 346 }; 347 347 348 - static struct regulator_ops da9055_ldo_ops = { 348 + static const struct regulator_ops da9055_ldo_ops = { 349 349 .get_mode = da9055_ldo_get_mode, 350 350 .set_mode = da9055_ldo_set_mode, 351 351
+2 -2
drivers/regulator/da9062-regulator.c
··· 371 371 return regmap_field_write(regl->suspend_sleep, val); 372 372 } 373 373 374 - static struct regulator_ops da9062_buck_ops = { 374 + static const struct regulator_ops da9062_buck_ops = { 375 375 .enable = regulator_enable_regmap, 376 376 .disable = regulator_disable_regmap, 377 377 .is_enabled = regulator_is_enabled_regmap, ··· 389 389 .set_suspend_mode = da9062_buck_set_suspend_mode, 390 390 }; 391 391 392 - static struct regulator_ops da9062_ldo_ops = { 392 + static const struct regulator_ops da9062_ldo_ops = { 393 393 .enable = regulator_enable_regmap, 394 394 .disable = regulator_disable_regmap, 395 395 .is_enabled = regulator_is_enabled_regmap,
+2 -2
drivers/regulator/da9063-regulator.c
··· 427 427 return regmap_field_write(regl->suspend_sleep, val); 428 428 } 429 429 430 - static struct regulator_ops da9063_buck_ops = { 430 + static const struct regulator_ops da9063_buck_ops = { 431 431 .enable = regulator_enable_regmap, 432 432 .disable = regulator_disable_regmap, 433 433 .is_enabled = regulator_is_enabled_regmap, ··· 445 445 .set_suspend_mode = da9063_buck_set_suspend_mode, 446 446 }; 447 447 448 - static struct regulator_ops da9063_ldo_ops = { 448 + static const struct regulator_ops da9063_ldo_ops = { 449 449 .enable = regulator_enable_regmap, 450 450 .disable = regulator_disable_regmap, 451 451 .is_enabled = regulator_is_enabled_regmap,
+1 -1
drivers/regulator/da9210-regulator.c
··· 46 46 int max_uA); 47 47 static int da9210_get_current_limit(struct regulator_dev *rdev); 48 48 49 - static struct regulator_ops da9210_buck_ops = { 49 + static const struct regulator_ops da9210_buck_ops = { 50 50 .enable = regulator_enable_regmap, 51 51 .disable = regulator_disable_regmap, 52 52 .is_enabled = regulator_is_enabled_regmap,
+1 -1
drivers/regulator/da9211-regulator.c
··· 219 219 return current_limits[data]; 220 220 } 221 221 222 - static struct regulator_ops da9211_buck_ops = { 222 + static const struct regulator_ops da9211_buck_ops = { 223 223 .get_mode = da9211_buck_get_mode, 224 224 .set_mode = da9211_buck_set_mode, 225 225 .enable = regulator_enable_regmap,
+5 -2
drivers/regulator/devres.c
··· 164 164 consumers[i].consumer = NULL; 165 165 166 166 for (i = 0; i < num_consumers; i++) { 167 - consumers[i].consumer = devm_regulator_get(dev, 168 - consumers[i].supply); 167 + consumers[i].consumer = _devm_regulator_get(dev, 168 + consumers[i].supply, 169 + consumers[i].optional ? 170 + OPTIONAL_GET : 171 + NORMAL_GET); 169 172 if (IS_ERR(consumers[i].consumer)) { 170 173 ret = PTR_ERR(consumers[i].consumer); 171 174 dev_err(dev, "Failed to get supply '%s': %d\n",
+291
drivers/regulator/lm363x-regulator.c
··· 1 + /* 2 + * TI LM363X Regulator Driver 3 + * 4 + * Copyright 2015 Texas Instruments 5 + * 6 + * Author: Milo Kim <milo.kim@ti.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/err.h> 14 + #include <linux/kernel.h> 15 + #include <linux/mfd/ti-lmu.h> 16 + #include <linux/mfd/ti-lmu-register.h> 17 + #include <linux/module.h> 18 + #include <linux/of.h> 19 + #include <linux/of_gpio.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/regulator/driver.h> 22 + #include <linux/regulator/of_regulator.h> 23 + #include <linux/slab.h> 24 + 25 + /* LM3631 */ 26 + #define LM3631_BOOST_VSEL_MAX 0x25 27 + #define LM3631_LDO_VSEL_MAX 0x28 28 + #define LM3631_CONT_VSEL_MAX 0x03 29 + #define LM3631_VBOOST_MIN 4500000 30 + #define LM3631_VCONT_MIN 1800000 31 + #define LM3631_VLDO_MIN 4000000 32 + #define ENABLE_TIME_USEC 1000 33 + 34 + /* LM3632 */ 35 + #define LM3632_BOOST_VSEL_MAX 0x26 36 + #define LM3632_LDO_VSEL_MAX 0x29 37 + #define LM3632_VBOOST_MIN 4500000 38 + #define LM3632_VLDO_MIN 4000000 39 + 40 + /* Common */ 41 + #define LM363X_STEP_50mV 50000 42 + #define LM363X_STEP_500mV 500000 43 + 44 + static const int ldo_cont_enable_time[] = { 45 + 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 46 + }; 47 + 48 + static int lm363x_regulator_enable_time(struct regulator_dev *rdev) 49 + { 50 + enum lm363x_regulator_id id = rdev_get_id(rdev); 51 + u8 val, addr, mask; 52 + 53 + switch (id) { 54 + case LM3631_LDO_CONT: 55 + addr = LM3631_REG_ENTIME_VCONT; 56 + mask = LM3631_ENTIME_CONT_MASK; 57 + break; 58 + case LM3631_LDO_OREF: 59 + addr = LM3631_REG_ENTIME_VOREF; 60 + mask = LM3631_ENTIME_MASK; 61 + break; 62 + case LM3631_LDO_POS: 63 + addr = LM3631_REG_ENTIME_VPOS; 64 + mask = LM3631_ENTIME_MASK; 65 + break; 66 + case LM3631_LDO_NEG: 67 + addr = LM3631_REG_ENTIME_VNEG; 68 + mask = LM3631_ENTIME_MASK; 69 + break; 70 + default: 71 + return 0; 72 + } 73 + 74 + if (regmap_read(rdev->regmap, addr, (unsigned int *)&val)) 75 + return -EINVAL; 76 + 77 + val = (val & mask) >> LM3631_ENTIME_SHIFT; 78 + 79 + if (id == LM3631_LDO_CONT) 80 + return ldo_cont_enable_time[val]; 81 + else 82 + return ENABLE_TIME_USEC * val; 83 + } 84 + 85 + static struct regulator_ops lm363x_boost_voltage_table_ops = { 86 + .list_voltage = regulator_list_voltage_linear, 87 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 88 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 89 + }; 90 + 91 + static struct regulator_ops lm363x_regulator_voltage_table_ops = { 92 + .list_voltage = regulator_list_voltage_linear, 93 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 94 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 95 + .enable = regulator_enable_regmap, 96 + .disable = regulator_disable_regmap, 97 + .is_enabled = regulator_is_enabled_regmap, 98 + .enable_time = lm363x_regulator_enable_time, 99 + }; 100 + 101 + static const struct regulator_desc lm363x_regulator_desc[] = { 102 + /* LM3631 */ 103 + { 104 + .name = "vboost", 105 + .of_match = "vboost", 106 + .id = LM3631_BOOST, 107 + .ops = &lm363x_boost_voltage_table_ops, 108 + .n_voltages = LM3631_BOOST_VSEL_MAX + 1, 109 + .min_uV = LM3631_VBOOST_MIN, 110 + .uV_step = LM363X_STEP_50mV, 111 + .type = REGULATOR_VOLTAGE, 112 + .owner = THIS_MODULE, 113 + .vsel_reg = LM3631_REG_VOUT_BOOST, 114 + .vsel_mask = LM3631_VOUT_MASK, 115 + }, 116 + { 117 + .name = "ldo_cont", 118 + .of_match = "vcont", 119 + .id = LM3631_LDO_CONT, 120 + .ops = &lm363x_regulator_voltage_table_ops, 121 + .n_voltages = LM3631_CONT_VSEL_MAX + 1, 122 + .min_uV = LM3631_VCONT_MIN, 123 + .uV_step = LM363X_STEP_500mV, 124 + .type = REGULATOR_VOLTAGE, 125 + .owner = THIS_MODULE, 126 + .vsel_reg = LM3631_REG_VOUT_CONT, 127 + .vsel_mask = LM3631_VOUT_CONT_MASK, 128 + .enable_reg = LM3631_REG_LDO_CTRL2, 129 + .enable_mask = LM3631_EN_CONT_MASK, 130 + }, 131 + { 132 + .name = "ldo_oref", 133 + .of_match = "voref", 134 + .id = LM3631_LDO_OREF, 135 + .ops = &lm363x_regulator_voltage_table_ops, 136 + .n_voltages = LM3631_LDO_VSEL_MAX + 1, 137 + .min_uV = LM3631_VLDO_MIN, 138 + .uV_step = LM363X_STEP_50mV, 139 + .type = REGULATOR_VOLTAGE, 140 + .owner = THIS_MODULE, 141 + .vsel_reg = LM3631_REG_VOUT_OREF, 142 + .vsel_mask = LM3631_VOUT_MASK, 143 + .enable_reg = LM3631_REG_LDO_CTRL1, 144 + .enable_mask = LM3631_EN_OREF_MASK, 145 + }, 146 + { 147 + .name = "ldo_vpos", 148 + .of_match = "vpos", 149 + .id = LM3631_LDO_POS, 150 + .ops = &lm363x_regulator_voltage_table_ops, 151 + .n_voltages = LM3631_LDO_VSEL_MAX + 1, 152 + .min_uV = LM3631_VLDO_MIN, 153 + .uV_step = LM363X_STEP_50mV, 154 + .type = REGULATOR_VOLTAGE, 155 + .owner = THIS_MODULE, 156 + .vsel_reg = LM3631_REG_VOUT_POS, 157 + .vsel_mask = LM3631_VOUT_MASK, 158 + .enable_reg = LM3631_REG_LDO_CTRL1, 159 + .enable_mask = LM3631_EN_VPOS_MASK, 160 + }, 161 + { 162 + .name = "ldo_vneg", 163 + .of_match = "vneg", 164 + .id = LM3631_LDO_NEG, 165 + .ops = &lm363x_regulator_voltage_table_ops, 166 + .n_voltages = LM3631_LDO_VSEL_MAX + 1, 167 + .min_uV = LM3631_VLDO_MIN, 168 + .uV_step = LM363X_STEP_50mV, 169 + .type = REGULATOR_VOLTAGE, 170 + .owner = THIS_MODULE, 171 + .vsel_reg = LM3631_REG_VOUT_NEG, 172 + .vsel_mask = LM3631_VOUT_MASK, 173 + .enable_reg = LM3631_REG_LDO_CTRL1, 174 + .enable_mask = LM3631_EN_VNEG_MASK, 175 + }, 176 + /* LM3632 */ 177 + { 178 + .name = "vboost", 179 + .of_match = "vboost", 180 + .id = LM3632_BOOST, 181 + .ops = &lm363x_boost_voltage_table_ops, 182 + .n_voltages = LM3632_BOOST_VSEL_MAX + 1, 183 + .min_uV = LM3632_VBOOST_MIN, 184 + .uV_step = LM363X_STEP_50mV, 185 + .type = REGULATOR_VOLTAGE, 186 + .owner = THIS_MODULE, 187 + .vsel_reg = LM3632_REG_VOUT_BOOST, 188 + .vsel_mask = LM3632_VOUT_MASK, 189 + }, 190 + { 191 + .name = "ldo_vpos", 192 + .of_match = "vpos", 193 + .id = LM3632_LDO_POS, 194 + .ops = &lm363x_regulator_voltage_table_ops, 195 + .n_voltages = LM3632_LDO_VSEL_MAX + 1, 196 + .min_uV = LM3632_VLDO_MIN, 197 + .uV_step = LM363X_STEP_50mV, 198 + .type = REGULATOR_VOLTAGE, 199 + .owner = THIS_MODULE, 200 + .vsel_reg = LM3632_REG_VOUT_POS, 201 + .vsel_mask = LM3632_VOUT_MASK, 202 + .enable_reg = LM3632_REG_BIAS_CONFIG, 203 + .enable_mask = LM3632_EN_VPOS_MASK, 204 + }, 205 + { 206 + .name = "ldo_vneg", 207 + .of_match = "vneg", 208 + .id = LM3632_LDO_NEG, 209 + .ops = &lm363x_regulator_voltage_table_ops, 210 + .n_voltages = LM3632_LDO_VSEL_MAX + 1, 211 + .min_uV = LM3632_VLDO_MIN, 212 + .uV_step = LM363X_STEP_50mV, 213 + .type = REGULATOR_VOLTAGE, 214 + .owner = THIS_MODULE, 215 + .vsel_reg = LM3632_REG_VOUT_NEG, 216 + .vsel_mask = LM3632_VOUT_MASK, 217 + .enable_reg = LM3632_REG_BIAS_CONFIG, 218 + .enable_mask = LM3632_EN_VNEG_MASK, 219 + }, 220 + }; 221 + 222 + static int lm363x_regulator_of_get_enable_gpio(struct device_node *np, int id) 223 + { 224 + /* 225 + * Check LCM_EN1/2_GPIO is configured. 226 + * Those pins are used for enabling VPOS/VNEG LDOs. 227 + */ 228 + switch (id) { 229 + case LM3632_LDO_POS: 230 + return of_get_named_gpio(np, "ti,lcm-en1-gpio", 0); 231 + case LM3632_LDO_NEG: 232 + return of_get_named_gpio(np, "ti,lcm-en2-gpio", 0); 233 + default: 234 + return -EINVAL; 235 + } 236 + } 237 + 238 + static int lm363x_regulator_probe(struct platform_device *pdev) 239 + { 240 + struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent); 241 + struct regmap *regmap = lmu->regmap; 242 + struct regulator_config cfg = { }; 243 + struct regulator_dev *rdev; 244 + struct device *dev = &pdev->dev; 245 + int id = pdev->id; 246 + int ret, ena_gpio; 247 + 248 + cfg.dev = dev; 249 + cfg.regmap = regmap; 250 + 251 + /* 252 + * LM3632 LDOs can be controlled by external pin. 253 + * Register update is required if the pin is used. 254 + */ 255 + ena_gpio = lm363x_regulator_of_get_enable_gpio(dev->of_node, id); 256 + if (gpio_is_valid(ena_gpio)) { 257 + cfg.ena_gpio = ena_gpio; 258 + cfg.ena_gpio_flags = GPIOF_OUT_INIT_LOW; 259 + 260 + ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG, 261 + LM3632_EXT_EN_MASK, 262 + LM3632_EXT_EN_MASK); 263 + if (ret) { 264 + dev_err(dev, "External pin err: %d\n", ret); 265 + return ret; 266 + } 267 + } 268 + 269 + rdev = devm_regulator_register(dev, &lm363x_regulator_desc[id], &cfg); 270 + if (IS_ERR(rdev)) { 271 + ret = PTR_ERR(rdev); 272 + dev_err(dev, "[%d] regulator register err: %d\n", id, ret); 273 + return ret; 274 + } 275 + 276 + return 0; 277 + } 278 + 279 + static struct platform_driver lm363x_regulator_driver = { 280 + .probe = lm363x_regulator_probe, 281 + .driver = { 282 + .name = "lm363x-regulator", 283 + }, 284 + }; 285 + 286 + module_platform_driver(lm363x_regulator_driver); 287 + 288 + MODULE_DESCRIPTION("TI LM363X Regulator Driver"); 289 + MODULE_AUTHOR("Milo Kim"); 290 + MODULE_LICENSE("GPL v2"); 291 + MODULE_ALIAS("platform:lm363x-regulator");
+15 -2
drivers/regulator/lp872x.c
··· 108 108 struct lp872x_platform_data *pdata; 109 109 int num_regulators; 110 110 enum lp872x_dvs_state dvs_pin; 111 - int dvs_gpio; 112 111 }; 113 112 114 113 /* LP8720/LP8725 shared voltage table for LDOs */ ··· 519 520 static struct regulator_desc lp8720_regulator_desc[] = { 520 521 { 521 522 .name = "ldo1", 523 + .of_match = of_match_ptr("ldo1"), 522 524 .id = LP8720_ID_LDO1, 523 525 .ops = &lp872x_ldo_ops, 524 526 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 533 533 }, 534 534 { 535 535 .name = "ldo2", 536 + .of_match = of_match_ptr("ldo2"), 536 537 .id = LP8720_ID_LDO2, 537 538 .ops = &lp872x_ldo_ops, 538 539 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 547 546 }, 548 547 { 549 548 .name = "ldo3", 549 + .of_match = of_match_ptr("ldo3"), 550 550 .id = LP8720_ID_LDO3, 551 551 .ops = &lp872x_ldo_ops, 552 552 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 561 559 }, 562 560 { 563 561 .name = "ldo4", 562 + .of_match = of_match_ptr("ldo4"), 564 563 .id = LP8720_ID_LDO4, 565 564 .ops = &lp872x_ldo_ops, 566 565 .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), ··· 575 572 }, 576 573 { 577 574 .name = "ldo5", 575 + .of_match = of_match_ptr("ldo5"), 578 576 .id = LP8720_ID_LDO5, 579 577 .ops = &lp872x_ldo_ops, 580 578 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 589 585 }, 590 586 { 591 587 .name = "buck", 588 + .of_match = of_match_ptr("buck"), 592 589 .id = LP8720_ID_BUCK, 593 590 .ops = &lp8720_buck_ops, 594 591 .n_voltages = ARRAY_SIZE(lp8720_buck_vtbl), ··· 604 599 static struct regulator_desc lp8725_regulator_desc[] = { 605 600 { 606 601 .name = "ldo1", 602 + .of_match = of_match_ptr("ldo1"), 607 603 .id = LP8725_ID_LDO1, 608 604 .ops = &lp872x_ldo_ops, 609 605 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 618 612 }, 619 613 { 620 614 .name = "ldo2", 615 + .of_match = of_match_ptr("ldo2"), 621 616 .id = LP8725_ID_LDO2, 622 617 .ops = &lp872x_ldo_ops, 623 618 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 632 625 }, 633 626 { 634 627 .name = "ldo3", 628 + .of_match = of_match_ptr("ldo3"), 635 629 .id = LP8725_ID_LDO3, 636 630 .ops = &lp872x_ldo_ops, 637 631 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 646 638 }, 647 639 { 648 640 .name = "ldo4", 641 + .of_match = of_match_ptr("ldo4"), 649 642 .id = LP8725_ID_LDO4, 650 643 .ops = &lp872x_ldo_ops, 651 644 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 660 651 }, 661 652 { 662 653 .name = "ldo5", 654 + .of_match = of_match_ptr("ldo5"), 663 655 .id = LP8725_ID_LDO5, 664 656 .ops = &lp872x_ldo_ops, 665 657 .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), ··· 674 664 }, 675 665 { 676 666 .name = "lilo1", 667 + .of_match = of_match_ptr("lilo1"), 677 668 .id = LP8725_ID_LILO1, 678 669 .ops = &lp872x_ldo_ops, 679 670 .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), ··· 688 677 }, 689 678 { 690 679 .name = "lilo2", 680 + .of_match = of_match_ptr("lilo2"), 691 681 .id = LP8725_ID_LILO2, 692 682 .ops = &lp872x_ldo_ops, 693 683 .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), ··· 702 690 }, 703 691 { 704 692 .name = "buck1", 693 + .of_match = of_match_ptr("buck1"), 705 694 .id = LP8725_ID_BUCK1, 706 695 .ops = &lp8725_buck_ops, 707 696 .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), ··· 714 701 }, 715 702 { 716 703 .name = "buck2", 704 + .of_match = of_match_ptr("buck2"), 717 705 .id = LP8725_ID_BUCK2, 718 706 .ops = &lp8725_buck_ops, 719 707 .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), ··· 751 737 } 752 738 753 739 lp->dvs_pin = pinstate; 754 - lp->dvs_gpio = gpio; 755 740 756 741 return 0; 757 742
+2 -2
drivers/regulator/lp8788-buck.c
··· 344 344 REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; 345 345 } 346 346 347 - static struct regulator_ops lp8788_buck12_ops = { 347 + static const struct regulator_ops lp8788_buck12_ops = { 348 348 .list_voltage = regulator_list_voltage_table, 349 349 .map_voltage = regulator_map_voltage_ascend, 350 350 .set_voltage_sel = lp8788_buck12_set_voltage_sel, ··· 357 357 .get_mode = lp8788_buck_get_mode, 358 358 }; 359 359 360 - static struct regulator_ops lp8788_buck34_ops = { 360 + static const struct regulator_ops lp8788_buck34_ops = { 361 361 .list_voltage = regulator_list_voltage_table, 362 362 .map_voltage = regulator_map_voltage_ascend, 363 363 .set_voltage_sel = regulator_set_voltage_sel_regmap,
+9 -11
drivers/regulator/lp8788-ldo.c
··· 170 170 return ENABLE_TIME_USEC * val; 171 171 } 172 172 173 - static struct regulator_ops lp8788_ldo_voltage_table_ops = { 173 + static const struct regulator_ops lp8788_ldo_voltage_table_ops = { 174 174 .list_voltage = regulator_list_voltage_table, 175 175 .set_voltage_sel = regulator_set_voltage_sel_regmap, 176 176 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 180 180 .enable_time = lp8788_ldo_enable_time, 181 181 }; 182 182 183 - static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { 183 + static const struct regulator_ops lp8788_ldo_voltage_fixed_ops = { 184 184 .list_voltage = regulator_list_voltage_linear, 185 185 .enable = regulator_enable_regmap, 186 186 .disable = regulator_disable_regmap, ··· 613 613 }, 614 614 }; 615 615 616 + static struct platform_driver * const drivers[] = { 617 + &lp8788_dldo_driver, 618 + &lp8788_aldo_driver, 619 + }; 620 + 616 621 static int __init lp8788_ldo_init(void) 617 622 { 618 - int ret; 619 - 620 - ret = platform_driver_register(&lp8788_dldo_driver); 621 - if (ret) 622 - return ret; 623 - 624 - return platform_driver_register(&lp8788_aldo_driver); 623 + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 625 624 } 626 625 subsys_initcall(lp8788_ldo_init); 627 626 628 627 static void __exit lp8788_ldo_exit(void) 629 628 { 630 - platform_driver_unregister(&lp8788_aldo_driver); 631 - platform_driver_unregister(&lp8788_dldo_driver); 629 + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 632 630 } 633 631 module_exit(lp8788_ldo_exit); 634 632
+1
drivers/regulator/mt6311-regulator.c
··· 30 30 .reg_bits = 8, 31 31 .val_bits = 8, 32 32 .max_register = MT6311_FQMTR_CON4, 33 + .cache_type = REGCACHE_RBTREE, 33 34 }; 34 35 35 36 /* Default limits measured in millivolts and milliamps */
+39
drivers/regulator/palmas-regulator.c
··· 612 612 .map_voltage = regulator_map_voltage_linear, 613 613 }; 614 614 615 + static struct regulator_ops palmas_ops_ldo9 = { 616 + .is_enabled = palmas_is_enabled_ldo, 617 + .enable = regulator_enable_regmap, 618 + .disable = regulator_disable_regmap, 619 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 620 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 621 + .list_voltage = regulator_list_voltage_linear, 622 + .map_voltage = regulator_map_voltage_linear, 623 + .set_bypass = regulator_set_bypass_regmap, 624 + .get_bypass = regulator_get_bypass_regmap, 625 + }; 626 + 615 627 static struct regulator_ops palmas_ops_ext_control_ldo = { 616 628 .get_voltage_sel = regulator_get_voltage_sel_regmap, 617 629 .set_voltage_sel = regulator_set_voltage_sel_regmap, ··· 649 637 .list_voltage = regulator_list_voltage_linear, 650 638 .map_voltage = regulator_map_voltage_linear, 651 639 .set_voltage_time_sel = regulator_set_voltage_time_sel, 640 + }; 641 + 642 + static struct regulator_ops tps65917_ops_ldo_1_2 = { 643 + .is_enabled = palmas_is_enabled_ldo, 644 + .enable = regulator_enable_regmap, 645 + .disable = regulator_disable_regmap, 646 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 647 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 648 + .list_voltage = regulator_list_voltage_linear, 649 + .map_voltage = regulator_map_voltage_linear, 650 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 651 + .set_bypass = regulator_set_bypass_regmap, 652 + .get_bypass = regulator_get_bypass_regmap, 652 653 }; 653 654 654 655 static int palmas_regulator_config_external(struct palmas *palmas, int id, ··· 940 915 if (pdata && pdata->ldo6_vibrator && 941 916 (id == PALMAS_REG_LDO6)) 942 917 desc->enable_time = 2000; 918 + 919 + if (id == PALMAS_REG_LDO9) { 920 + desc->ops = &palmas_ops_ldo9; 921 + desc->bypass_reg = desc->enable_reg; 922 + desc->bypass_mask = 923 + PALMAS_LDO9_CTRL_LDO_BYPASS_EN; 924 + } 943 925 } else { 944 926 if (!ddata->has_regen3 && id == PALMAS_REG_REGEN3) 945 927 continue; ··· 1051 1019 * It is of the order of ~60mV/uS. 1052 1020 */ 1053 1021 desc->ramp_delay = 2500; 1022 + if (id == TPS65917_REG_LDO1 || 1023 + id == TPS65917_REG_LDO2) { 1024 + desc->ops = &tps65917_ops_ldo_1_2; 1025 + desc->bypass_reg = desc->enable_reg; 1026 + desc->bypass_mask = 1027 + TPS65917_LDO1_CTRL_BYPASS_EN; 1028 + } 1054 1029 } else { 1055 1030 desc->n_voltages = 1; 1056 1031 if (reg_init && reg_init->roof_floor)
+437
drivers/regulator/pv88060-regulator.c
··· 1 + /* 2 + * pv88060-regulator.c - Regulator device driver for PV88060 3 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/err.h> 17 + #include <linux/gpio.h> 18 + #include <linux/i2c.h> 19 + #include <linux/module.h> 20 + #include <linux/init.h> 21 + #include <linux/slab.h> 22 + #include <linux/regulator/driver.h> 23 + #include <linux/regulator/machine.h> 24 + #include <linux/regmap.h> 25 + #include <linux/irq.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/regulator/of_regulator.h> 28 + #include <linux/proc_fs.h> 29 + #include <linux/uaccess.h> 30 + #include "pv88060-regulator.h" 31 + 32 + #define PV88060_MAX_REGULATORS 14 33 + 34 + /* PV88060 REGULATOR IDs */ 35 + enum { 36 + /* BUCKs */ 37 + PV88060_ID_BUCK1, 38 + 39 + /* LDOs */ 40 + PV88060_ID_LDO1, 41 + PV88060_ID_LDO2, 42 + PV88060_ID_LDO3, 43 + PV88060_ID_LDO4, 44 + PV88060_ID_LDO5, 45 + PV88060_ID_LDO6, 46 + PV88060_ID_LDO7, 47 + 48 + /* SWTs */ 49 + PV88060_ID_SW1, 50 + PV88060_ID_SW2, 51 + PV88060_ID_SW3, 52 + PV88060_ID_SW4, 53 + PV88060_ID_SW5, 54 + PV88060_ID_SW6, 55 + }; 56 + 57 + struct pv88060_regulator { 58 + struct regulator_desc desc; 59 + /* Current limiting */ 60 + unsigned n_current_limits; 61 + const int *current_limits; 62 + unsigned int limit_mask; 63 + unsigned int conf; /* buck configuration register */ 64 + }; 65 + 66 + struct pv88060 { 67 + struct device *dev; 68 + struct regmap *regmap; 69 + struct regulator_dev *rdev[PV88060_MAX_REGULATORS]; 70 + }; 71 + 72 + static const struct regmap_config pv88060_regmap_config = { 73 + .reg_bits = 8, 74 + .val_bits = 8, 75 + }; 76 + 77 + /* Current limits array (in uA) for BUCK1 78 + * Entry indexes corresponds to register values. 79 + */ 80 + 81 + static const int pv88060_buck1_limits[] = { 82 + 1496000, 2393000, 3291000, 4189000 83 + }; 84 + 85 + static unsigned int pv88060_buck_get_mode(struct regulator_dev *rdev) 86 + { 87 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 88 + unsigned int data; 89 + int ret, mode = 0; 90 + 91 + ret = regmap_read(rdev->regmap, info->conf, &data); 92 + if (ret < 0) 93 + return ret; 94 + 95 + switch (data & PV88060_BUCK_MODE_MASK) { 96 + case PV88060_BUCK_MODE_SYNC: 97 + mode = REGULATOR_MODE_FAST; 98 + break; 99 + case PV88060_BUCK_MODE_AUTO: 100 + mode = REGULATOR_MODE_NORMAL; 101 + break; 102 + case PV88060_BUCK_MODE_SLEEP: 103 + mode = REGULATOR_MODE_STANDBY; 104 + break; 105 + } 106 + 107 + return mode; 108 + } 109 + 110 + static int pv88060_buck_set_mode(struct regulator_dev *rdev, 111 + unsigned int mode) 112 + { 113 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 114 + int val = 0; 115 + 116 + switch (mode) { 117 + case REGULATOR_MODE_FAST: 118 + val = PV88060_BUCK_MODE_SYNC; 119 + break; 120 + case REGULATOR_MODE_NORMAL: 121 + val = PV88060_BUCK_MODE_AUTO; 122 + break; 123 + case REGULATOR_MODE_STANDBY: 124 + val = PV88060_BUCK_MODE_SLEEP; 125 + break; 126 + default: 127 + return -EINVAL; 128 + } 129 + 130 + return regmap_update_bits(rdev->regmap, info->conf, 131 + PV88060_BUCK_MODE_MASK, val); 132 + } 133 + 134 + static int pv88060_set_current_limit(struct regulator_dev *rdev, int min, 135 + int max) 136 + { 137 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 138 + int i; 139 + 140 + /* search for closest to maximum */ 141 + for (i = info->n_current_limits; i >= 0; i--) { 142 + if (min <= info->current_limits[i] 143 + && max >= info->current_limits[i]) { 144 + return regmap_update_bits(rdev->regmap, 145 + info->conf, 146 + info->limit_mask, 147 + i << PV88060_BUCK_ILIM_SHIFT); 148 + } 149 + } 150 + 151 + return -EINVAL; 152 + } 153 + 154 + static int pv88060_get_current_limit(struct regulator_dev *rdev) 155 + { 156 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 157 + unsigned int data; 158 + int ret; 159 + 160 + ret = regmap_read(rdev->regmap, info->conf, &data); 161 + if (ret < 0) 162 + return ret; 163 + 164 + data = (data & info->limit_mask) >> PV88060_BUCK_ILIM_SHIFT; 165 + return info->current_limits[data]; 166 + } 167 + 168 + static struct regulator_ops pv88060_buck_ops = { 169 + .get_mode = pv88060_buck_get_mode, 170 + .set_mode = pv88060_buck_set_mode, 171 + .enable = regulator_enable_regmap, 172 + .disable = regulator_disable_regmap, 173 + .is_enabled = regulator_is_enabled_regmap, 174 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 175 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 176 + .list_voltage = regulator_list_voltage_linear, 177 + .set_current_limit = pv88060_set_current_limit, 178 + .get_current_limit = pv88060_get_current_limit, 179 + }; 180 + 181 + static struct regulator_ops pv88060_ldo_ops = { 182 + .enable = regulator_enable_regmap, 183 + .disable = regulator_disable_regmap, 184 + .is_enabled = regulator_is_enabled_regmap, 185 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 186 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 187 + .list_voltage = regulator_list_voltage_linear, 188 + }; 189 + 190 + #define PV88060_BUCK(chip, regl_name, min, step, max, limits_array) \ 191 + {\ 192 + .desc = {\ 193 + .id = chip##_ID_##regl_name,\ 194 + .name = __stringify(chip##_##regl_name),\ 195 + .of_match = of_match_ptr(#regl_name),\ 196 + .regulators_node = of_match_ptr("regulators"),\ 197 + .type = REGULATOR_VOLTAGE,\ 198 + .owner = THIS_MODULE,\ 199 + .ops = &pv88060_buck_ops,\ 200 + .min_uV = min,\ 201 + .uV_step = step,\ 202 + .n_voltages = ((max) - (min))/(step) + 1,\ 203 + .enable_reg = PV88060_REG_##regl_name##_CONF0,\ 204 + .enable_mask = PV88060_BUCK_EN, \ 205 + .vsel_reg = PV88060_REG_##regl_name##_CONF0,\ 206 + .vsel_mask = PV88060_VBUCK_MASK,\ 207 + },\ 208 + .current_limits = limits_array,\ 209 + .n_current_limits = ARRAY_SIZE(limits_array),\ 210 + .limit_mask = PV88060_BUCK_ILIM_MASK, \ 211 + .conf = PV88060_REG_##regl_name##_CONF1,\ 212 + } 213 + 214 + #define PV88060_LDO(chip, regl_name, min, step, max) \ 215 + {\ 216 + .desc = {\ 217 + .id = chip##_ID_##regl_name,\ 218 + .name = __stringify(chip##_##regl_name),\ 219 + .of_match = of_match_ptr(#regl_name),\ 220 + .regulators_node = of_match_ptr("regulators"),\ 221 + .type = REGULATOR_VOLTAGE,\ 222 + .owner = THIS_MODULE,\ 223 + .ops = &pv88060_ldo_ops,\ 224 + .min_uV = min, \ 225 + .uV_step = step, \ 226 + .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ 227 + .enable_reg = PV88060_REG_##regl_name##_CONF, \ 228 + .enable_mask = PV88060_LDO_EN, \ 229 + .vsel_reg = PV88060_REG_##regl_name##_CONF, \ 230 + .vsel_mask = PV88060_VLDO_MASK, \ 231 + },\ 232 + } 233 + 234 + #define PV88060_SW(chip, regl_name, max) \ 235 + {\ 236 + .desc = {\ 237 + .id = chip##_ID_##regl_name,\ 238 + .name = __stringify(chip##_##regl_name),\ 239 + .of_match = of_match_ptr(#regl_name),\ 240 + .regulators_node = of_match_ptr("regulators"),\ 241 + .type = REGULATOR_VOLTAGE,\ 242 + .owner = THIS_MODULE,\ 243 + .ops = &pv88060_ldo_ops,\ 244 + .min_uV = max,\ 245 + .uV_step = 0,\ 246 + .n_voltages = 1,\ 247 + .enable_reg = PV88060_REG_##regl_name##_CONF,\ 248 + .enable_mask = PV88060_SW_EN,\ 249 + },\ 250 + } 251 + 252 + static const struct pv88060_regulator pv88060_regulator_info[] = { 253 + PV88060_BUCK(PV88060, BUCK1, 2800000, 12500, 4387500, 254 + pv88060_buck1_limits), 255 + PV88060_LDO(PV88060, LDO1, 1200000, 50000, 3350000), 256 + PV88060_LDO(PV88060, LDO2, 1200000, 50000, 3350000), 257 + PV88060_LDO(PV88060, LDO3, 1200000, 50000, 3350000), 258 + PV88060_LDO(PV88060, LDO4, 1200000, 50000, 3350000), 259 + PV88060_LDO(PV88060, LDO5, 1200000, 50000, 3350000), 260 + PV88060_LDO(PV88060, LDO6, 1200000, 50000, 3350000), 261 + PV88060_LDO(PV88060, LDO7, 1200000, 50000, 3350000), 262 + PV88060_SW(PV88060, SW1, 5000000), 263 + PV88060_SW(PV88060, SW2, 5000000), 264 + PV88060_SW(PV88060, SW3, 5000000), 265 + PV88060_SW(PV88060, SW4, 5000000), 266 + PV88060_SW(PV88060, SW5, 5000000), 267 + PV88060_SW(PV88060, SW6, 5000000), 268 + }; 269 + 270 + static irqreturn_t pv88060_irq_handler(int irq, void *data) 271 + { 272 + struct pv88060 *chip = data; 273 + int i, reg_val, err, ret = IRQ_NONE; 274 + 275 + err = regmap_read(chip->regmap, PV88060_REG_EVENT_A, &reg_val); 276 + if (err < 0) 277 + goto error_i2c; 278 + 279 + if (reg_val & PV88060_E_VDD_FLT) { 280 + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { 281 + if (chip->rdev[i] != NULL) { 282 + regulator_notifier_call_chain(chip->rdev[i], 283 + REGULATOR_EVENT_UNDER_VOLTAGE, 284 + NULL); 285 + } 286 + } 287 + 288 + err = regmap_update_bits(chip->regmap, PV88060_REG_EVENT_A, 289 + PV88060_E_VDD_FLT, PV88060_E_VDD_FLT); 290 + if (err < 0) 291 + goto error_i2c; 292 + 293 + ret = IRQ_HANDLED; 294 + } 295 + 296 + if (reg_val & PV88060_E_OVER_TEMP) { 297 + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { 298 + if (chip->rdev[i] != NULL) { 299 + regulator_notifier_call_chain(chip->rdev[i], 300 + REGULATOR_EVENT_OVER_TEMP, 301 + NULL); 302 + } 303 + } 304 + 305 + err = regmap_update_bits(chip->regmap, PV88060_REG_EVENT_A, 306 + PV88060_E_OVER_TEMP, PV88060_E_OVER_TEMP); 307 + if (err < 0) 308 + goto error_i2c; 309 + 310 + ret = IRQ_HANDLED; 311 + } 312 + 313 + return ret; 314 + 315 + error_i2c: 316 + dev_err(chip->dev, "I2C error : %d\n", err); 317 + return IRQ_NONE; 318 + } 319 + 320 + /* 321 + * I2C driver interface functions 322 + */ 323 + static int pv88060_i2c_probe(struct i2c_client *i2c, 324 + const struct i2c_device_id *id) 325 + { 326 + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); 327 + struct pv88060 *chip; 328 + struct regulator_config config = { }; 329 + int error, i, ret = 0; 330 + 331 + chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88060), GFP_KERNEL); 332 + if (!chip) 333 + return -ENOMEM; 334 + 335 + chip->dev = &i2c->dev; 336 + chip->regmap = devm_regmap_init_i2c(i2c, &pv88060_regmap_config); 337 + if (IS_ERR(chip->regmap)) { 338 + error = PTR_ERR(chip->regmap); 339 + dev_err(chip->dev, "Failed to allocate register map: %d\n", 340 + error); 341 + return error; 342 + } 343 + 344 + i2c_set_clientdata(i2c, chip); 345 + 346 + if (i2c->irq != 0) { 347 + ret = regmap_write(chip->regmap, PV88060_REG_MASK_A, 0xFF); 348 + if (ret < 0) { 349 + dev_err(chip->dev, 350 + "Failed to mask A reg: %d\n", ret); 351 + return ret; 352 + } 353 + 354 + ret = regmap_write(chip->regmap, PV88060_REG_MASK_B, 0xFF); 355 + if (ret < 0) { 356 + dev_err(chip->dev, 357 + "Failed to mask B reg: %d\n", ret); 358 + return ret; 359 + } 360 + 361 + ret = regmap_write(chip->regmap, PV88060_REG_MASK_C, 0xFF); 362 + if (ret < 0) { 363 + dev_err(chip->dev, 364 + "Failed to mask C reg: %d\n", ret); 365 + return ret; 366 + } 367 + 368 + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, 369 + pv88060_irq_handler, 370 + IRQF_TRIGGER_LOW|IRQF_ONESHOT, 371 + "pv88060", chip); 372 + if (ret != 0) { 373 + dev_err(chip->dev, "Failed to request IRQ: %d\n", 374 + i2c->irq); 375 + return ret; 376 + } 377 + 378 + ret = regmap_update_bits(chip->regmap, PV88060_REG_MASK_A, 379 + PV88060_M_VDD_FLT | PV88060_M_OVER_TEMP, 0); 380 + if (ret < 0) { 381 + dev_err(chip->dev, 382 + "Failed to update mask reg: %d\n", ret); 383 + return ret; 384 + } 385 + 386 + } else { 387 + dev_warn(chip->dev, "No IRQ configured\n"); 388 + } 389 + 390 + config.dev = chip->dev; 391 + config.regmap = chip->regmap; 392 + 393 + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { 394 + if (init_data) 395 + config.init_data = &init_data[i]; 396 + 397 + config.driver_data = (void *)&pv88060_regulator_info[i]; 398 + chip->rdev[i] = devm_regulator_register(chip->dev, 399 + &pv88060_regulator_info[i].desc, &config); 400 + if (IS_ERR(chip->rdev[i])) { 401 + dev_err(chip->dev, 402 + "Failed to register PV88060 regulator\n"); 403 + return PTR_ERR(chip->rdev[i]); 404 + } 405 + } 406 + 407 + return 0; 408 + } 409 + 410 + static const struct i2c_device_id pv88060_i2c_id[] = { 411 + {"pv88060", 0}, 412 + {}, 413 + }; 414 + MODULE_DEVICE_TABLE(i2c, pv88060_i2c_id); 415 + 416 + #ifdef CONFIG_OF 417 + static const struct of_device_id pv88060_dt_ids[] = { 418 + { .compatible = "pvs,pv88060", .data = &pv88060_i2c_id[0] }, 419 + {}, 420 + }; 421 + MODULE_DEVICE_TABLE(of, pv88060_dt_ids); 422 + #endif 423 + 424 + static struct i2c_driver pv88060_regulator_driver = { 425 + .driver = { 426 + .name = "pv88060", 427 + .of_match_table = of_match_ptr(pv88060_dt_ids), 428 + }, 429 + .probe = pv88060_i2c_probe, 430 + .id_table = pv88060_i2c_id, 431 + }; 432 + 433 + module_i2c_driver(pv88060_regulator_driver); 434 + 435 + MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); 436 + MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88060"); 437 + MODULE_LICENSE("GPL");
+69
drivers/regulator/pv88060-regulator.h
··· 1 + /* 2 + * pv88060-regulator.h - Regulator definitions for PV88060 3 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #ifndef __PV88060_REGISTERS_H__ 17 + #define __PV88060_REGISTERS_H__ 18 + 19 + /* System Control and Event Registers */ 20 + #define PV88060_REG_EVENT_A 0x04 21 + #define PV88060_REG_MASK_A 0x08 22 + #define PV88060_REG_MASK_B 0x09 23 + #define PV88060_REG_MASK_C 0x0A 24 + 25 + /* Regulator Registers */ 26 + #define PV88060_REG_BUCK1_CONF0 0x1B 27 + #define PV88060_REG_BUCK1_CONF1 0x1C 28 + #define PV88060_REG_LDO1_CONF 0x1D 29 + #define PV88060_REG_LDO2_CONF 0x1E 30 + #define PV88060_REG_LDO3_CONF 0x1F 31 + #define PV88060_REG_LDO4_CONF 0x20 32 + #define PV88060_REG_LDO5_CONF 0x21 33 + #define PV88060_REG_LDO6_CONF 0x22 34 + #define PV88060_REG_LDO7_CONF 0x23 35 + 36 + #define PV88060_REG_SW1_CONF 0x3B 37 + #define PV88060_REG_SW2_CONF 0x3C 38 + #define PV88060_REG_SW3_CONF 0x3D 39 + #define PV88060_REG_SW4_CONF 0x3E 40 + #define PV88060_REG_SW5_CONF 0x3F 41 + #define PV88060_REG_SW6_CONF 0x40 42 + 43 + /* PV88060_REG_EVENT_A (addr=0x04) */ 44 + #define PV88060_E_VDD_FLT 0x01 45 + #define PV88060_E_OVER_TEMP 0x02 46 + 47 + /* PV88060_REG_MASK_A (addr=0x08) */ 48 + #define PV88060_M_VDD_FLT 0x01 49 + #define PV88060_M_OVER_TEMP 0x02 50 + 51 + /* PV88060_REG_BUCK1_CONF0 (addr=0x1B) */ 52 + #define PV88060_BUCK_EN 0x80 53 + #define PV88060_VBUCK_MASK 0x7F 54 + /* PV88060_REG_LDO1/2/3/4/5/6/7_CONT */ 55 + #define PV88060_LDO_EN 0x40 56 + #define PV88060_VLDO_MASK 0x3F 57 + /* PV88060_REG_SW1/2/3/4/5_CONF */ 58 + #define PV88060_SW_EN 0x80 59 + 60 + /* PV88060_REG_BUCK1_CONF1 (addr=0x1C) */ 61 + #define PV88060_BUCK_ILIM_SHIFT 2 62 + #define PV88060_BUCK_ILIM_MASK 0x0C 63 + #define PV88060_BUCK_MODE_SHIFT 0 64 + #define PV88060_BUCK_MODE_MASK 0x03 65 + #define PV88060_BUCK_MODE_SLEEP 0x00 66 + #define PV88060_BUCK_MODE_AUTO 0x01 67 + #define PV88060_BUCK_MODE_SYNC 0x02 68 + 69 + #endif /* __PV88060_REGISTERS_H__ */
+458
drivers/regulator/pv88090-regulator.c
··· 1 + /* 2 + * pv88090-regulator.c - Regulator device driver for PV88090 3 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/err.h> 17 + #include <linux/gpio.h> 18 + #include <linux/i2c.h> 19 + #include <linux/module.h> 20 + #include <linux/init.h> 21 + #include <linux/slab.h> 22 + #include <linux/regulator/driver.h> 23 + #include <linux/regulator/machine.h> 24 + #include <linux/regmap.h> 25 + #include <linux/irq.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/regulator/of_regulator.h> 28 + #include <linux/proc_fs.h> 29 + #include <linux/uaccess.h> 30 + #include "pv88090-regulator.h" 31 + 32 + #define PV88090_MAX_REGULATORS 5 33 + 34 + /* PV88090 REGULATOR IDs */ 35 + enum { 36 + /* BUCKs */ 37 + PV88090_ID_BUCK1, 38 + PV88090_ID_BUCK2, 39 + PV88090_ID_BUCK3, 40 + 41 + /* LDOs */ 42 + PV88090_ID_LDO1, 43 + PV88090_ID_LDO2, 44 + }; 45 + 46 + struct pv88090_regulator { 47 + struct regulator_desc desc; 48 + /* Current limiting */ 49 + unsigned n_current_limits; 50 + const int *current_limits; 51 + unsigned int limit_mask; 52 + unsigned int conf; 53 + unsigned int conf2; 54 + }; 55 + 56 + struct pv88090 { 57 + struct device *dev; 58 + struct regmap *regmap; 59 + struct regulator_dev *rdev[PV88090_MAX_REGULATORS]; 60 + }; 61 + 62 + struct pv88090_buck_voltage { 63 + int min_uV; 64 + int max_uV; 65 + int uV_step; 66 + }; 67 + 68 + static const struct regmap_config pv88090_regmap_config = { 69 + .reg_bits = 8, 70 + .val_bits = 8, 71 + }; 72 + 73 + /* Current limits array (in uA) for BUCK1, BUCK2, BUCK3. 74 + * Entry indexes corresponds to register values. 75 + */ 76 + 77 + static const int pv88090_buck1_limits[] = { 78 + 220000, 440000, 660000, 880000, 1100000, 1320000, 1540000, 1760000, 79 + 1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000, 80 + 3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000, 81 + 5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000 82 + }; 83 + 84 + static const int pv88090_buck23_limits[] = { 85 + 1496000, 2393000, 3291000, 4189000 86 + }; 87 + 88 + static const struct pv88090_buck_voltage pv88090_buck_vol[3] = { 89 + { 90 + .min_uV = 600000, 91 + .max_uV = 1393750, 92 + .uV_step = 6250, 93 + }, 94 + 95 + { 96 + .min_uV = 1400000, 97 + .max_uV = 2193750, 98 + .uV_step = 6250, 99 + }, 100 + { 101 + .min_uV = 1250000, 102 + .max_uV = 2837500, 103 + .uV_step = 12500, 104 + }, 105 + }; 106 + 107 + static unsigned int pv88090_buck_get_mode(struct regulator_dev *rdev) 108 + { 109 + struct pv88090_regulator *info = rdev_get_drvdata(rdev); 110 + unsigned int data; 111 + int ret, mode = 0; 112 + 113 + ret = regmap_read(rdev->regmap, info->conf, &data); 114 + if (ret < 0) 115 + return ret; 116 + 117 + switch (data & PV88090_BUCK1_MODE_MASK) { 118 + case PV88090_BUCK_MODE_SYNC: 119 + mode = REGULATOR_MODE_FAST; 120 + break; 121 + case PV88090_BUCK_MODE_AUTO: 122 + mode = REGULATOR_MODE_NORMAL; 123 + break; 124 + case PV88090_BUCK_MODE_SLEEP: 125 + mode = REGULATOR_MODE_STANDBY; 126 + break; 127 + } 128 + 129 + return mode; 130 + } 131 + 132 + static int pv88090_buck_set_mode(struct regulator_dev *rdev, 133 + unsigned int mode) 134 + { 135 + struct pv88090_regulator *info = rdev_get_drvdata(rdev); 136 + int val = 0; 137 + 138 + switch (mode) { 139 + case REGULATOR_MODE_FAST: 140 + val = PV88090_BUCK_MODE_SYNC; 141 + break; 142 + case REGULATOR_MODE_NORMAL: 143 + val = PV88090_BUCK_MODE_AUTO; 144 + break; 145 + case REGULATOR_MODE_STANDBY: 146 + val = PV88090_BUCK_MODE_SLEEP; 147 + break; 148 + default: 149 + return -EINVAL; 150 + } 151 + 152 + return regmap_update_bits(rdev->regmap, info->conf, 153 + PV88090_BUCK1_MODE_MASK, val); 154 + } 155 + 156 + static int pv88090_set_current_limit(struct regulator_dev *rdev, int min, 157 + int max) 158 + { 159 + struct pv88090_regulator *info = rdev_get_drvdata(rdev); 160 + int i; 161 + 162 + /* search for closest to maximum */ 163 + for (i = info->n_current_limits; i >= 0; i--) { 164 + if (min <= info->current_limits[i] 165 + && max >= info->current_limits[i]) { 166 + return regmap_update_bits(rdev->regmap, 167 + info->conf, 168 + info->limit_mask, 169 + i << PV88090_BUCK1_ILIM_SHIFT); 170 + } 171 + } 172 + 173 + return -EINVAL; 174 + } 175 + 176 + static int pv88090_get_current_limit(struct regulator_dev *rdev) 177 + { 178 + struct pv88090_regulator *info = rdev_get_drvdata(rdev); 179 + unsigned int data; 180 + int ret; 181 + 182 + ret = regmap_read(rdev->regmap, info->conf, &data); 183 + if (ret < 0) 184 + return ret; 185 + 186 + data = (data & info->limit_mask) >> PV88090_BUCK1_ILIM_SHIFT; 187 + return info->current_limits[data]; 188 + } 189 + 190 + static struct regulator_ops pv88090_buck_ops = { 191 + .get_mode = pv88090_buck_get_mode, 192 + .set_mode = pv88090_buck_set_mode, 193 + .enable = regulator_enable_regmap, 194 + .disable = regulator_disable_regmap, 195 + .is_enabled = regulator_is_enabled_regmap, 196 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 197 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 198 + .list_voltage = regulator_list_voltage_linear, 199 + .set_current_limit = pv88090_set_current_limit, 200 + .get_current_limit = pv88090_get_current_limit, 201 + }; 202 + 203 + static struct regulator_ops pv88090_ldo_ops = { 204 + .enable = regulator_enable_regmap, 205 + .disable = regulator_disable_regmap, 206 + .is_enabled = regulator_is_enabled_regmap, 207 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 208 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 209 + .list_voltage = regulator_list_voltage_linear, 210 + }; 211 + 212 + #define PV88090_BUCK(chip, regl_name, min, step, max, limits_array) \ 213 + {\ 214 + .desc = {\ 215 + .id = chip##_ID_##regl_name,\ 216 + .name = __stringify(chip##_##regl_name),\ 217 + .of_match = of_match_ptr(#regl_name),\ 218 + .regulators_node = of_match_ptr("regulators"),\ 219 + .type = REGULATOR_VOLTAGE,\ 220 + .owner = THIS_MODULE,\ 221 + .ops = &pv88090_buck_ops,\ 222 + .min_uV = min, \ 223 + .uV_step = step, \ 224 + .n_voltages = ((max) - (min))/(step) + 1, \ 225 + .enable_reg = PV88090_REG_##regl_name##_CONF0, \ 226 + .enable_mask = PV88090_##regl_name##_EN, \ 227 + .vsel_reg = PV88090_REG_##regl_name##_CONF0, \ 228 + .vsel_mask = PV88090_V##regl_name##_MASK, \ 229 + },\ 230 + .current_limits = limits_array, \ 231 + .n_current_limits = ARRAY_SIZE(limits_array), \ 232 + .limit_mask = PV88090_##regl_name##_ILIM_MASK, \ 233 + .conf = PV88090_REG_##regl_name##_CONF1, \ 234 + .conf2 = PV88090_REG_##regl_name##_CONF2, \ 235 + } 236 + 237 + #define PV88090_LDO(chip, regl_name, min, step, max) \ 238 + {\ 239 + .desc = {\ 240 + .id = chip##_ID_##regl_name,\ 241 + .name = __stringify(chip##_##regl_name),\ 242 + .of_match = of_match_ptr(#regl_name),\ 243 + .regulators_node = of_match_ptr("regulators"),\ 244 + .type = REGULATOR_VOLTAGE,\ 245 + .owner = THIS_MODULE,\ 246 + .ops = &pv88090_ldo_ops,\ 247 + .min_uV = min, \ 248 + .uV_step = step, \ 249 + .n_voltages = ((max) - (min))/(step) + 1, \ 250 + .enable_reg = PV88090_REG_##regl_name##_CONT, \ 251 + .enable_mask = PV88090_##regl_name##_EN, \ 252 + .vsel_reg = PV88090_REG_##regl_name##_CONT, \ 253 + .vsel_mask = PV88090_V##regl_name##_MASK, \ 254 + },\ 255 + } 256 + 257 + static struct pv88090_regulator pv88090_regulator_info[] = { 258 + PV88090_BUCK(PV88090, BUCK1, 600000, 6250, 1393750, 259 + pv88090_buck1_limits), 260 + PV88090_BUCK(PV88090, BUCK2, 600000, 6250, 1393750, 261 + pv88090_buck23_limits), 262 + PV88090_BUCK(PV88090, BUCK3, 600000, 6250, 1393750, 263 + pv88090_buck23_limits), 264 + PV88090_LDO(PV88090, LDO1, 1200000, 50000, 4350000), 265 + PV88090_LDO(PV88090, LDO2, 650000, 25000, 2225000), 266 + }; 267 + 268 + static irqreturn_t pv88090_irq_handler(int irq, void *data) 269 + { 270 + struct pv88090 *chip = data; 271 + int i, reg_val, err, ret = IRQ_NONE; 272 + 273 + err = regmap_read(chip->regmap, PV88090_REG_EVENT_A, &reg_val); 274 + if (err < 0) 275 + goto error_i2c; 276 + 277 + if (reg_val & PV88090_E_VDD_FLT) { 278 + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { 279 + if (chip->rdev[i] != NULL) { 280 + regulator_notifier_call_chain(chip->rdev[i], 281 + REGULATOR_EVENT_UNDER_VOLTAGE, 282 + NULL); 283 + } 284 + } 285 + 286 + err = regmap_update_bits(chip->regmap, PV88090_REG_EVENT_A, 287 + PV88090_E_VDD_FLT, PV88090_E_VDD_FLT); 288 + if (err < 0) 289 + goto error_i2c; 290 + 291 + ret = IRQ_HANDLED; 292 + } 293 + 294 + if (reg_val & PV88090_E_OVER_TEMP) { 295 + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { 296 + if (chip->rdev[i] != NULL) { 297 + regulator_notifier_call_chain(chip->rdev[i], 298 + REGULATOR_EVENT_OVER_TEMP, 299 + NULL); 300 + } 301 + } 302 + 303 + err = regmap_update_bits(chip->regmap, PV88090_REG_EVENT_A, 304 + PV88090_E_OVER_TEMP, PV88090_E_OVER_TEMP); 305 + if (err < 0) 306 + goto error_i2c; 307 + 308 + ret = IRQ_HANDLED; 309 + } 310 + 311 + return ret; 312 + 313 + error_i2c: 314 + dev_err(chip->dev, "I2C error : %d\n", err); 315 + return IRQ_NONE; 316 + } 317 + 318 + /* 319 + * I2C driver interface functions 320 + */ 321 + static int pv88090_i2c_probe(struct i2c_client *i2c, 322 + const struct i2c_device_id *id) 323 + { 324 + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); 325 + struct pv88090 *chip; 326 + struct regulator_config config = { }; 327 + int error, i, ret = 0; 328 + unsigned int conf2, range, index; 329 + 330 + chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88090), GFP_KERNEL); 331 + if (!chip) 332 + return -ENOMEM; 333 + 334 + chip->dev = &i2c->dev; 335 + chip->regmap = devm_regmap_init_i2c(i2c, &pv88090_regmap_config); 336 + if (IS_ERR(chip->regmap)) { 337 + error = PTR_ERR(chip->regmap); 338 + dev_err(chip->dev, "Failed to allocate register map: %d\n", 339 + error); 340 + return error; 341 + } 342 + 343 + i2c_set_clientdata(i2c, chip); 344 + 345 + if (i2c->irq != 0) { 346 + ret = regmap_write(chip->regmap, PV88090_REG_MASK_A, 0xFF); 347 + if (ret < 0) { 348 + dev_err(chip->dev, 349 + "Failed to mask A reg: %d\n", ret); 350 + return ret; 351 + } 352 + 353 + ret = regmap_write(chip->regmap, PV88090_REG_MASK_B, 0xFF); 354 + if (ret < 0) { 355 + dev_err(chip->dev, 356 + "Failed to mask B reg: %d\n", ret); 357 + return ret; 358 + } 359 + 360 + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, 361 + pv88090_irq_handler, 362 + IRQF_TRIGGER_LOW|IRQF_ONESHOT, 363 + "pv88090", chip); 364 + if (ret != 0) { 365 + dev_err(chip->dev, "Failed to request IRQ: %d\n", 366 + i2c->irq); 367 + return ret; 368 + } 369 + 370 + ret = regmap_update_bits(chip->regmap, PV88090_REG_MASK_A, 371 + PV88090_M_VDD_FLT | PV88090_M_OVER_TEMP, 0); 372 + if (ret < 0) { 373 + dev_err(chip->dev, 374 + "Failed to update mask reg: %d\n", ret); 375 + return ret; 376 + } 377 + 378 + } else { 379 + dev_warn(chip->dev, "No IRQ configured\n"); 380 + } 381 + 382 + config.dev = chip->dev; 383 + config.regmap = chip->regmap; 384 + 385 + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { 386 + if (init_data) 387 + config.init_data = &init_data[i]; 388 + 389 + if (i == PV88090_ID_BUCK2 || i == PV88090_ID_BUCK3) { 390 + ret = regmap_read(chip->regmap, 391 + pv88090_regulator_info[i].conf2, &conf2); 392 + if (ret < 0) 393 + return ret; 394 + 395 + conf2 = (conf2 >> PV88090_BUCK_VDAC_RANGE_SHIFT) & 396 + PV88090_BUCK_VDAC_RANGE_MASK; 397 + 398 + ret = regmap_read(chip->regmap, 399 + PV88090_REG_BUCK_FOLD_RANGE, &range); 400 + if (ret < 0) 401 + return ret; 402 + 403 + range = (range >> 404 + (PV88080_BUCK_VRANGE_GAIN_SHIFT + i - 1)) & 405 + PV88080_BUCK_VRANGE_GAIN_MASK; 406 + index = ((range << 1) | conf2); 407 + 408 + pv88090_regulator_info[i].desc.min_uV 409 + = pv88090_buck_vol[index].min_uV; 410 + pv88090_regulator_info[i].desc.uV_step 411 + = pv88090_buck_vol[index].uV_step; 412 + pv88090_regulator_info[i].desc.n_voltages 413 + = ((pv88090_buck_vol[index].max_uV) 414 + - (pv88090_buck_vol[index].min_uV)) 415 + /(pv88090_buck_vol[index].uV_step) + 1; 416 + } 417 + 418 + config.driver_data = (void *)&pv88090_regulator_info[i]; 419 + chip->rdev[i] = devm_regulator_register(chip->dev, 420 + &pv88090_regulator_info[i].desc, &config); 421 + if (IS_ERR(chip->rdev[i])) { 422 + dev_err(chip->dev, 423 + "Failed to register PV88090 regulator\n"); 424 + return PTR_ERR(chip->rdev[i]); 425 + } 426 + } 427 + 428 + return 0; 429 + } 430 + 431 + static const struct i2c_device_id pv88090_i2c_id[] = { 432 + {"pv88090", 0}, 433 + {}, 434 + }; 435 + MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id); 436 + 437 + #ifdef CONFIG_OF 438 + static const struct of_device_id pv88090_dt_ids[] = { 439 + { .compatible = "pvs,pv88090", .data = &pv88090_i2c_id[0] }, 440 + {}, 441 + }; 442 + MODULE_DEVICE_TABLE(of, pv88090_dt_ids); 443 + #endif 444 + 445 + static struct i2c_driver pv88090_regulator_driver = { 446 + .driver = { 447 + .name = "pv88090", 448 + .of_match_table = of_match_ptr(pv88090_dt_ids), 449 + }, 450 + .probe = pv88090_i2c_probe, 451 + .id_table = pv88090_i2c_id, 452 + }; 453 + 454 + module_i2c_driver(pv88090_regulator_driver); 455 + 456 + MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); 457 + MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88090"); 458 + MODULE_LICENSE("GPL");
+98
drivers/regulator/pv88090-regulator.h
··· 1 + /* 2 + * pv88090-regulator.h - Regulator definitions for PV88090 3 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #ifndef __PV88090_REGISTERS_H__ 17 + #define __PV88090_REGISTERS_H__ 18 + 19 + /* System Control and Event Registers */ 20 + #define PV88090_REG_EVENT_A 0x03 21 + #define PV88090_REG_MASK_A 0x06 22 + #define PV88090_REG_MASK_B 0x07 23 + 24 + /* Regulator Registers */ 25 + #define PV88090_REG_BUCK1_CONF0 0x18 26 + #define PV88090_REG_BUCK1_CONF1 0x19 27 + #define PV88090_REG_BUCK1_CONF2 0x1a 28 + #define PV88090_REG_BUCK2_CONF0 0x1b 29 + #define PV88090_REG_BUCK2_CONF1 0x1c 30 + #define PV88090_REG_BUCK2_CONF2 0x58 31 + #define PV88090_REG_BUCK3_CONF0 0x1d 32 + #define PV88090_REG_BUCK3_CONF1 0x1e 33 + #define PV88090_REG_BUCK3_CONF2 0x5c 34 + 35 + #define PV88090_REG_LDO1_CONT 0x1f 36 + #define PV88090_REG_LDO2_CONT 0x20 37 + #define PV88090_REG_LDO3_CONT 0x21 38 + #define PV88090_REG_BUCK_FOLD_RANGE 0x61 39 + 40 + /* PV88090_REG_EVENT_A (addr=0x03) */ 41 + #define PV88090_E_VDD_FLT 0x01 42 + #define PV88090_E_OVER_TEMP 0x02 43 + 44 + /* PV88090_REG_MASK_A (addr=0x06) */ 45 + #define PV88090_M_VDD_FLT 0x01 46 + #define PV88090_M_OVER_TEMP 0x02 47 + 48 + /* PV88090_REG_BUCK1_CONF0 (addr=0x18) */ 49 + #define PV88090_BUCK1_EN 0x80 50 + #define PV88090_VBUCK1_MASK 0x7F 51 + /* PV88090_REG_BUCK2_CONF0 (addr=0x1b) */ 52 + #define PV88090_BUCK2_EN 0x80 53 + #define PV88090_VBUCK2_MASK 0x7F 54 + /* PV88090_REG_BUCK3_CONF0 (addr=0x1d) */ 55 + #define PV88090_BUCK3_EN 0x80 56 + #define PV88090_VBUCK3_MASK 0x7F 57 + /* PV88090_REG_LDO1_CONT (addr=0x1f) */ 58 + #define PV88090_LDO1_EN 0x40 59 + #define PV88090_VLDO1_MASK 0x3F 60 + /* PV88090_REG_LDO2_CONT (addr=0x20) */ 61 + #define PV88090_LDO2_EN 0x40 62 + #define PV88090_VLDO2_MASK 0x3F 63 + 64 + /* PV88090_REG_BUCK1_CONF1 (addr=0x19) */ 65 + #define PV88090_BUCK1_ILIM_SHIFT 2 66 + #define PV88090_BUCK1_ILIM_MASK 0x7C 67 + #define PV88090_BUCK1_MODE_MASK 0x03 68 + 69 + /* PV88090_REG_BUCK2_CONF1 (addr=0x1c) */ 70 + #define PV88090_BUCK2_ILIM_SHIFT 2 71 + #define PV88090_BUCK2_ILIM_MASK 0x0C 72 + #define PV88090_BUCK2_MODE_MASK 0x03 73 + 74 + /* PV88090_REG_BUCK3_CONF1 (addr=0x1e) */ 75 + #define PV88090_BUCK3_ILIM_SHIFT 2 76 + #define PV88090_BUCK3_ILIM_MASK 0x0C 77 + #define PV88090_BUCK3_MODE_MASK 0x03 78 + 79 + #define PV88090_BUCK_MODE_SLEEP 0x00 80 + #define PV88090_BUCK_MODE_AUTO 0x01 81 + #define PV88090_BUCK_MODE_SYNC 0x02 82 + 83 + /* PV88090_REG_BUCK2_CONF2 (addr=0x58) */ 84 + /* PV88090_REG_BUCK3_CONF2 (addr=0x5c) */ 85 + #define PV88090_BUCK_VDAC_RANGE_SHIFT 7 86 + #define PV88090_BUCK_VDAC_RANGE_MASK 0x01 87 + 88 + #define PV88090_BUCK_VDAC_RANGE_1 0x00 89 + #define PV88090_BUCK_VDAC_RANGE_2 0x01 90 + 91 + /* PV88090_REG_BUCK_FOLD_RANGE (addr=0x61) */ 92 + #define PV88080_BUCK_VRANGE_GAIN_SHIFT 3 93 + #define PV88080_BUCK_VRANGE_GAIN_MASK 0x01 94 + 95 + #define PV88080_BUCK_VRANGE_GAIN_1 0x00 96 + #define PV88080_BUCK_VRANGE_GAIN_2 0x01 97 + 98 + #endif /* __PV88090_REGISTERS_H__ */
+159
drivers/regulator/qcom_smd-regulator.c
··· 153 153 .is_enabled = rpm_reg_is_enabled, 154 154 }; 155 155 156 + static const struct regulator_desc pma8084_hfsmps = { 157 + .linear_ranges = (struct regulator_linear_range[]) { 158 + REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), 159 + REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000), 160 + }, 161 + .n_linear_ranges = 2, 162 + .n_voltages = 159, 163 + .ops = &rpm_smps_ldo_ops, 164 + }; 165 + 166 + static const struct regulator_desc pma8084_ftsmps = { 167 + .linear_ranges = (struct regulator_linear_range[]) { 168 + REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), 169 + REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000), 170 + }, 171 + .n_linear_ranges = 2, 172 + .n_voltages = 340, 173 + .ops = &rpm_smps_ldo_ops, 174 + }; 175 + 176 + static const struct regulator_desc pma8084_pldo = { 177 + .linear_ranges = (struct regulator_linear_range[]) { 178 + REGULATOR_LINEAR_RANGE(750000, 0, 30, 25000), 179 + REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000), 180 + }, 181 + .n_linear_ranges = 2, 182 + .n_voltages = 100, 183 + .ops = &rpm_smps_ldo_ops, 184 + }; 185 + 186 + static const struct regulator_desc pma8084_nldo = { 187 + .linear_ranges = (struct regulator_linear_range[]) { 188 + REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500), 189 + }, 190 + .n_linear_ranges = 1, 191 + .n_voltages = 64, 192 + .ops = &rpm_smps_ldo_ops, 193 + }; 194 + 195 + static const struct regulator_desc pma8084_switch = { 196 + .ops = &rpm_switch_ops, 197 + }; 198 + 156 199 static const struct regulator_desc pm8x41_hfsmps = { 157 200 .linear_ranges = (struct regulator_linear_range[]) { 158 201 REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500), ··· 254 211 .ops = &rpm_switch_ops, 255 212 }; 256 213 214 + static const struct regulator_desc pm8916_pldo = { 215 + .linear_ranges = (struct regulator_linear_range[]) { 216 + REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500), 217 + }, 218 + .n_linear_ranges = 1, 219 + .n_voltages = 209, 220 + .ops = &rpm_smps_ldo_ops, 221 + }; 222 + 223 + static const struct regulator_desc pm8916_nldo = { 224 + .linear_ranges = (struct regulator_linear_range[]) { 225 + REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500), 226 + }, 227 + .n_linear_ranges = 1, 228 + .n_voltages = 94, 229 + .ops = &rpm_smps_ldo_ops, 230 + }; 231 + 232 + static const struct regulator_desc pm8916_buck_lvo_smps = { 233 + .linear_ranges = (struct regulator_linear_range[]) { 234 + REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), 235 + REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000), 236 + }, 237 + .n_linear_ranges = 2, 238 + .n_voltages = 128, 239 + .ops = &rpm_smps_ldo_ops, 240 + }; 241 + 242 + static const struct regulator_desc pm8916_buck_hvo_smps = { 243 + .linear_ranges = (struct regulator_linear_range[]) { 244 + REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000), 245 + }, 246 + .n_linear_ranges = 1, 247 + .n_voltages = 32, 248 + .ops = &rpm_smps_ldo_ops, 249 + }; 250 + 257 251 struct rpm_regulator_data { 258 252 const char *name; 259 253 u32 type; ··· 308 228 { "s6", QCOM_SMD_RPM_SMPB, 6, &pm8841_ftsmps, "vdd_s6" }, 309 229 { "s7", QCOM_SMD_RPM_SMPB, 7, &pm8841_ftsmps, "vdd_s7" }, 310 230 { "s8", QCOM_SMD_RPM_SMPB, 8, &pm8841_ftsmps, "vdd_s8" }, 231 + {} 232 + }; 233 + 234 + static const struct rpm_regulator_data rpm_pm8916_regulators[] = { 235 + { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8916_buck_lvo_smps, "vdd_s1" }, 236 + { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8916_buck_lvo_smps, "vdd_s2" }, 237 + { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8916_buck_lvo_smps, "vdd_s3" }, 238 + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8916_buck_hvo_smps, "vdd_s4" }, 239 + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8916_nldo, "vdd_l1_l2_l3" }, 240 + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8916_nldo, "vdd_l1_l2_l3" }, 241 + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8916_nldo, "vdd_l1_l2_l3" }, 242 + { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8916_pldo, "vdd_l4_l5_l6" }, 243 + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8916_pldo, "vdd_l4_l5_l6" }, 244 + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8916_pldo, "vdd_l4_l5_l6" }, 245 + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8916_pldo, "vdd_l7" }, 246 + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" }, 247 + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" }, 248 + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 249 + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 250 + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 251 + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 252 + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 253 + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 254 + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 255 + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 256 + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, 311 257 {} 312 258 }; 313 259 ··· 378 272 {} 379 273 }; 380 274 275 + static const struct rpm_regulator_data rpm_pma8084_regulators[] = { 276 + { "s1", QCOM_SMD_RPM_SMPA, 1, &pma8084_ftsmps, "vdd_s1" }, 277 + { "s2", QCOM_SMD_RPM_SMPA, 2, &pma8084_ftsmps, "vdd_s2" }, 278 + { "s3", QCOM_SMD_RPM_SMPA, 3, &pma8084_hfsmps, "vdd_s3" }, 279 + { "s4", QCOM_SMD_RPM_SMPA, 4, &pma8084_hfsmps, "vdd_s4" }, 280 + { "s5", QCOM_SMD_RPM_SMPA, 5, &pma8084_hfsmps, "vdd_s5" }, 281 + { "s6", QCOM_SMD_RPM_SMPA, 6, &pma8084_ftsmps, "vdd_s6" }, 282 + { "s7", QCOM_SMD_RPM_SMPA, 7, &pma8084_ftsmps, "vdd_s7" }, 283 + { "s8", QCOM_SMD_RPM_SMPA, 8, &pma8084_ftsmps, "vdd_s8" }, 284 + { "s9", QCOM_SMD_RPM_SMPA, 9, &pma8084_ftsmps, "vdd_s9" }, 285 + { "s10", QCOM_SMD_RPM_SMPA, 10, &pma8084_ftsmps, "vdd_s10" }, 286 + { "s11", QCOM_SMD_RPM_SMPA, 11, &pma8084_ftsmps, "vdd_s11" }, 287 + { "s12", QCOM_SMD_RPM_SMPA, 12, &pma8084_ftsmps, "vdd_s12" }, 288 + 289 + { "l1", QCOM_SMD_RPM_LDOA, 1, &pma8084_nldo, "vdd_l1_l11" }, 290 + { "l2", QCOM_SMD_RPM_LDOA, 2, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, 291 + { "l3", QCOM_SMD_RPM_LDOA, 3, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, 292 + { "l4", QCOM_SMD_RPM_LDOA, 4, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, 293 + { "l5", QCOM_SMD_RPM_LDOA, 5, &pma8084_pldo, "vdd_l5_l7" }, 294 + { "l6", QCOM_SMD_RPM_LDOA, 6, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, 295 + { "l7", QCOM_SMD_RPM_LDOA, 7, &pma8084_pldo, "vdd_l5_l7" }, 296 + { "l8", QCOM_SMD_RPM_LDOA, 8, &pma8084_pldo, "vdd_l8" }, 297 + { "l9", QCOM_SMD_RPM_LDOA, 9, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, 298 + { "l10", QCOM_SMD_RPM_LDOA, 10, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, 299 + { "l11", QCOM_SMD_RPM_LDOA, 11, &pma8084_nldo, "vdd_l1_l11" }, 300 + { "l12", QCOM_SMD_RPM_LDOA, 12, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, 301 + { "l13", QCOM_SMD_RPM_LDOA, 13, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, 302 + { "l14", QCOM_SMD_RPM_LDOA, 14, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, 303 + { "l15", QCOM_SMD_RPM_LDOA, 15, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, 304 + { "l16", QCOM_SMD_RPM_LDOA, 16, &pma8084_pldo, "vdd_l16_l25" }, 305 + { "l17", QCOM_SMD_RPM_LDOA, 17, &pma8084_pldo, "vdd_l17" }, 306 + { "l18", QCOM_SMD_RPM_LDOA, 18, &pma8084_pldo, "vdd_l18" }, 307 + { "l19", QCOM_SMD_RPM_LDOA, 19, &pma8084_pldo, "vdd_l19" }, 308 + { "l20", QCOM_SMD_RPM_LDOA, 20, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, 309 + { "l21", QCOM_SMD_RPM_LDOA, 21, &pma8084_pldo, "vdd_l21" }, 310 + { "l22", QCOM_SMD_RPM_LDOA, 22, &pma8084_pldo, "vdd_l22" }, 311 + { "l23", QCOM_SMD_RPM_LDOA, 23, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, 312 + { "l24", QCOM_SMD_RPM_LDOA, 24, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, 313 + { "l25", QCOM_SMD_RPM_LDOA, 25, &pma8084_pldo, "vdd_l16_l25" }, 314 + { "l26", QCOM_SMD_RPM_LDOA, 26, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, 315 + { "l27", QCOM_SMD_RPM_LDOA, 27, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, 316 + 317 + { "lvs1", QCOM_SMD_RPM_VSA, 1, &pma8084_switch }, 318 + { "lvs2", QCOM_SMD_RPM_VSA, 2, &pma8084_switch }, 319 + { "lvs3", QCOM_SMD_RPM_VSA, 3, &pma8084_switch }, 320 + { "lvs4", QCOM_SMD_RPM_VSA, 4, &pma8084_switch }, 321 + { "5vs1", QCOM_SMD_RPM_VSA, 5, &pma8084_switch }, 322 + 323 + {} 324 + }; 325 + 381 326 static const struct of_device_id rpm_of_match[] = { 382 327 { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, 328 + { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, 383 329 { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, 330 + { .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators }, 384 331 {} 385 332 }; 386 333 MODULE_DEVICE_TABLE(of, rpm_of_match);
+12 -83
drivers/regulator/tps6105x-regulator.c
··· 27 27 5000000, /* There is an additional 5V */ 28 28 }; 29 29 30 - static int tps6105x_regulator_enable(struct regulator_dev *rdev) 31 - { 32 - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); 33 - int ret; 34 - 35 - /* Activate voltage mode */ 36 - ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, 37 - TPS6105X_REG0_MODE_MASK, 38 - TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT); 39 - if (ret) 40 - return ret; 41 - 42 - return 0; 43 - } 44 - 45 - static int tps6105x_regulator_disable(struct regulator_dev *rdev) 46 - { 47 - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); 48 - int ret; 49 - 50 - /* Set into shutdown mode */ 51 - ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, 52 - TPS6105X_REG0_MODE_MASK, 53 - TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); 54 - if (ret) 55 - return ret; 56 - 57 - return 0; 58 - } 59 - 60 - static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) 61 - { 62 - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); 63 - unsigned int regval; 64 - int ret; 65 - 66 - ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, &regval); 67 - if (ret) 68 - return ret; 69 - regval &= TPS6105X_REG0_MODE_MASK; 70 - regval >>= TPS6105X_REG0_MODE_SHIFT; 71 - 72 - if (regval == TPS6105X_REG0_MODE_VOLTAGE) 73 - return 1; 74 - 75 - return 0; 76 - } 77 - 78 - static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev) 79 - { 80 - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); 81 - unsigned int regval; 82 - int ret; 83 - 84 - ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, &regval); 85 - if (ret) 86 - return ret; 87 - 88 - regval &= TPS6105X_REG0_VOLTAGE_MASK; 89 - regval >>= TPS6105X_REG0_VOLTAGE_SHIFT; 90 - return (int) regval; 91 - } 92 - 93 - static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev, 94 - unsigned selector) 95 - { 96 - struct tps6105x *tps6105x = rdev_get_drvdata(rdev); 97 - int ret; 98 - 99 - ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, 100 - TPS6105X_REG0_VOLTAGE_MASK, 101 - selector << TPS6105X_REG0_VOLTAGE_SHIFT); 102 - if (ret) 103 - return ret; 104 - 105 - return 0; 106 - } 107 - 108 30 static struct regulator_ops tps6105x_regulator_ops = { 109 - .enable = tps6105x_regulator_enable, 110 - .disable = tps6105x_regulator_disable, 111 - .is_enabled = tps6105x_regulator_is_enabled, 112 - .get_voltage_sel = tps6105x_regulator_get_voltage_sel, 113 - .set_voltage_sel = tps6105x_regulator_set_voltage_sel, 31 + .enable = regulator_enable_regmap, 32 + .disable = regulator_disable_regmap, 33 + .is_enabled = regulator_is_enabled_regmap, 34 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 35 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 114 36 .list_voltage = regulator_list_voltage_table, 115 37 }; 116 38 ··· 44 122 .owner = THIS_MODULE, 45 123 .n_voltages = ARRAY_SIZE(tps6105x_voltages), 46 124 .volt_table = tps6105x_voltages, 125 + .vsel_reg = TPS6105X_REG_0, 126 + .vsel_mask = TPS6105X_REG0_VOLTAGE_MASK, 127 + .enable_reg = TPS6105X_REG_0, 128 + .enable_mask = TPS6105X_REG0_MODE_MASK, 129 + .enable_val = TPS6105X_REG0_MODE_VOLTAGE << 130 + TPS6105X_REG0_MODE_SHIFT, 47 131 }; 48 132 49 133 /* ··· 72 144 config.dev = &tps6105x->client->dev; 73 145 config.init_data = pdata->regulator_data; 74 146 config.driver_data = tps6105x; 147 + config.regmap = tps6105x->regmap; 75 148 76 149 /* Register regulator with framework */ 77 150 tps6105x->regulator = devm_regulator_register(&pdev->dev,
+251
drivers/regulator/tps65086-regulator.c
··· 1 + /* 2 + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 3 + * 4 + * Author: Andrew F. Davis <afd@ti.com> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 + * kind, whether expressed or implied; without even the implied warranty 12 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License version 2 for more details. 14 + * 15 + * Based on the TPS65912 driver 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include <linux/of.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/regulator/driver.h> 22 + 23 + #include <linux/mfd/tps65086.h> 24 + 25 + enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1, 26 + LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT }; 27 + 28 + #define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \ 29 + [_id] = { \ 30 + .desc = { \ 31 + .name = _name, \ 32 + .of_match = of_match_ptr(_of), \ 33 + .regulators_node = "regulators", \ 34 + .of_parse_cb = tps65086_of_parse_cb, \ 35 + .id = _id, \ 36 + .ops = &reg_ops, \ 37 + .n_voltages = _nv, \ 38 + .type = REGULATOR_VOLTAGE, \ 39 + .owner = THIS_MODULE, \ 40 + .vsel_reg = _vr, \ 41 + .vsel_mask = _vm, \ 42 + .enable_reg = _er, \ 43 + .enable_mask = _em, \ 44 + .volt_table = NULL, \ 45 + .linear_ranges = _lr, \ 46 + .n_linear_ranges = ARRAY_SIZE(_lr), \ 47 + }, \ 48 + .decay_reg = _dr, \ 49 + .decay_mask = _dm, \ 50 + } 51 + 52 + #define TPS65086_SWITCH(_name, _of, _id, _er, _em) \ 53 + [_id] = { \ 54 + .desc = { \ 55 + .name = _name, \ 56 + .of_match = of_match_ptr(_of), \ 57 + .regulators_node = "regulators", \ 58 + .of_parse_cb = tps65086_of_parse_cb, \ 59 + .id = _id, \ 60 + .ops = &switch_ops, \ 61 + .type = REGULATOR_VOLTAGE, \ 62 + .owner = THIS_MODULE, \ 63 + .enable_reg = _er, \ 64 + .enable_mask = _em, \ 65 + }, \ 66 + } 67 + 68 + struct tps65086_regulator { 69 + struct regulator_desc desc; 70 + unsigned int decay_reg; 71 + unsigned int decay_mask; 72 + }; 73 + 74 + static const struct regulator_linear_range tps65086_buck126_10mv_ranges[] = { 75 + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), 76 + REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000), 77 + }; 78 + 79 + static const struct regulator_linear_range tps65086_buck126_25mv_ranges[] = { 80 + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), 81 + REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x18, 0), 82 + REGULATOR_LINEAR_RANGE(1025000, 0x19, 0x7F, 25000), 83 + }; 84 + 85 + static const struct regulator_linear_range tps65086_buck345_ranges[] = { 86 + REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), 87 + REGULATOR_LINEAR_RANGE(425000, 0x1, 0x7F, 25000), 88 + }; 89 + 90 + static const struct regulator_linear_range tps65086_ldoa1_ranges[] = { 91 + REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0), 92 + REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000), 93 + REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xA, 100000), 94 + REGULATOR_LINEAR_RANGE(2700000, 0xB, 0xD, 150000), 95 + REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0), 96 + }; 97 + 98 + static const struct regulator_linear_range tps65086_ldoa23_ranges[] = { 99 + REGULATOR_LINEAR_RANGE(700000, 0x0, 0xD, 50000), 100 + REGULATOR_LINEAR_RANGE(1400000, 0xE, 0xF, 100000), 101 + }; 102 + 103 + /* Operations permitted on regulators */ 104 + static struct regulator_ops reg_ops = { 105 + .enable = regulator_enable_regmap, 106 + .disable = regulator_disable_regmap, 107 + .is_enabled = regulator_is_enabled_regmap, 108 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 109 + .map_voltage = regulator_map_voltage_linear_range, 110 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 111 + .list_voltage = regulator_list_voltage_linear_range, 112 + }; 113 + 114 + /* Operations permitted on load switches */ 115 + static struct regulator_ops switch_ops = { 116 + .enable = regulator_enable_regmap, 117 + .disable = regulator_disable_regmap, 118 + .is_enabled = regulator_is_enabled_regmap, 119 + }; 120 + 121 + static int tps65086_of_parse_cb(struct device_node *dev, 122 + const struct regulator_desc *desc, 123 + struct regulator_config *config); 124 + 125 + static struct tps65086_regulator regulators[] = { 126 + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, 127 + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), 128 + tps65086_buck126_10mv_ranges, TPS65086_BUCK1CTRL, 129 + BIT(0)), 130 + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, 131 + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), 132 + tps65086_buck126_10mv_ranges, TPS65086_BUCK2CTRL, 133 + BIT(0)), 134 + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, 135 + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), 136 + tps65086_buck345_ranges, TPS65086_BUCK3DECAY, 137 + BIT(0)), 138 + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, 139 + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), 140 + tps65086_buck345_ranges, TPS65086_BUCK4VID, 141 + BIT(0)), 142 + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, 143 + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), 144 + tps65086_buck345_ranges, TPS65086_BUCK5CTRL, 145 + BIT(0)), 146 + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, 147 + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), 148 + tps65086_buck126_10mv_ranges, TPS65086_BUCK6CTRL, 149 + BIT(0)), 150 + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, 151 + VDOA1_VID_MASK, TPS65086_LDOA1CTRL, BIT(0), 152 + tps65086_ldoa1_ranges, 0, 0), 153 + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, 154 + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), 155 + tps65086_ldoa23_ranges, 0, 0), 156 + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, 157 + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), 158 + tps65086_ldoa23_ranges, 0, 0), 159 + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), 160 + TPS65086_SWITCH("SWB1", "swa2", SWB1, TPS65086_SWVTT_EN, BIT(6)), 161 + TPS65086_SWITCH("SWB2", "swa3", SWB2, TPS65086_SWVTT_EN, BIT(7)), 162 + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), 163 + }; 164 + 165 + static inline bool has_25mv_mode(int id) 166 + { 167 + switch (id) { 168 + case BUCK1: 169 + case BUCK2: 170 + case BUCK6: 171 + return true; 172 + default: 173 + return false; 174 + } 175 + } 176 + 177 + static int tps65086_of_parse_cb(struct device_node *dev, 178 + const struct regulator_desc *desc, 179 + struct regulator_config *config) 180 + { 181 + int ret; 182 + 183 + /* Check for 25mV step mode */ 184 + if (has_25mv_mode(desc->id) && 185 + of_property_read_bool(config->of_node, "ti,regulator-step-size-25mv")) { 186 + regulators[desc->id].desc.linear_ranges = 187 + tps65086_buck126_25mv_ranges; 188 + regulators[desc->id].desc.n_linear_ranges = 189 + ARRAY_SIZE(tps65086_buck126_25mv_ranges); 190 + } 191 + 192 + /* Check for decay mode */ 193 + if (desc->id <= BUCK6 && of_property_read_bool(config->of_node, "ti,regulator-decay")) { 194 + ret = regmap_write_bits(config->regmap, 195 + regulators[desc->id].decay_reg, 196 + regulators[desc->id].decay_mask, 197 + regulators[desc->id].decay_mask); 198 + if (ret) { 199 + dev_err(config->dev, "Error setting decay\n"); 200 + return ret; 201 + } 202 + } 203 + 204 + return 0; 205 + } 206 + 207 + static int tps65086_regulator_probe(struct platform_device *pdev) 208 + { 209 + struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent); 210 + struct regulator_config config = { }; 211 + struct regulator_dev *rdev; 212 + int i; 213 + 214 + platform_set_drvdata(pdev, tps); 215 + 216 + config.dev = &pdev->dev; 217 + config.dev->of_node = tps->dev->of_node; 218 + config.driver_data = tps; 219 + config.regmap = tps->regmap; 220 + 221 + for (i = 0; i < ARRAY_SIZE(regulators); i++) { 222 + rdev = devm_regulator_register(&pdev->dev, &regulators[i].desc, 223 + &config); 224 + if (IS_ERR(rdev)) { 225 + dev_err(tps->dev, "failed to register %s regulator\n", 226 + pdev->name); 227 + return PTR_ERR(rdev); 228 + } 229 + } 230 + 231 + return 0; 232 + } 233 + 234 + static const struct platform_device_id tps65086_regulator_id_table[] = { 235 + { "tps65086-regulator", }, 236 + { /* sentinel */ } 237 + }; 238 + MODULE_DEVICE_TABLE(platform, tps65086_regulator_id_table); 239 + 240 + static struct platform_driver tps65086_regulator_driver = { 241 + .driver = { 242 + .name = "tps65086-regulator", 243 + }, 244 + .probe = tps65086_regulator_probe, 245 + .id_table = tps65086_regulator_id_table, 246 + }; 247 + module_platform_driver(tps65086_regulator_driver); 248 + 249 + MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); 250 + MODULE_DESCRIPTION("TPS65086 Regulator driver"); 251 + MODULE_LICENSE("GPL v2");
+107 -30
drivers/regulator/tps65218-regulator.c
··· 27 27 #include <linux/regulator/machine.h> 28 28 #include <linux/mfd/tps65218.h> 29 29 30 - enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; 30 + enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, 31 + DCDC5, DCDC6, LDO1, LS3 }; 31 32 32 - #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, \ 33 - _lr, _nlr, _delay, _fuv) \ 33 + #define TPS65218_REGULATOR(_name, _id, _type, _ops, _n, _vr, _vm, _er, _em, \ 34 + _cr, _cm, _lr, _nlr, _delay, _fuv) \ 34 35 { \ 35 36 .name = _name, \ 36 37 .id = _id, \ 37 38 .ops = &_ops, \ 38 39 .n_voltages = _n, \ 39 - .type = REGULATOR_VOLTAGE, \ 40 + .type = _type, \ 40 41 .owner = THIS_MODULE, \ 41 42 .vsel_reg = _vr, \ 42 43 .vsel_mask = _vm, \ 44 + .csel_reg = _cr, \ 45 + .csel_mask = _cm, \ 43 46 .enable_reg = _er, \ 44 47 .enable_mask = _em, \ 45 48 .volt_table = NULL, \ ··· 83 80 TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000), 84 81 TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000), 85 82 TPS65218_INFO(LDO1, "LDO1", 900000, 3400000), 83 + TPS65218_INFO(LS3, "LS3", -1, -1), 86 84 }; 87 85 88 86 #define TPS65218_OF_MATCH(comp, label) \ ··· 100 96 TPS65218_OF_MATCH("ti,tps65218-dcdc5", tps65218_pmic_regs[DCDC5]), 101 97 TPS65218_OF_MATCH("ti,tps65218-dcdc6", tps65218_pmic_regs[DCDC6]), 102 98 TPS65218_OF_MATCH("ti,tps65218-ldo1", tps65218_pmic_regs[LDO1]), 99 + TPS65218_OF_MATCH("ti,tps65218-ls3", tps65218_pmic_regs[LS3]), 103 100 { } 104 101 }; 105 102 MODULE_DEVICE_TABLE(of, tps65218_of_match); ··· 180 175 .map_voltage = regulator_map_voltage_linear_range, 181 176 }; 182 177 178 + static const int ls3_currents[] = { 100, 200, 500, 1000 }; 179 + 180 + static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, 181 + int lim_uA) 182 + { 183 + unsigned int index = 0; 184 + unsigned int num_currents = ARRAY_SIZE(ls3_currents); 185 + struct tps65218 *tps = rdev_get_drvdata(dev); 186 + 187 + while (index < num_currents && ls3_currents[index] != lim_uA) 188 + index++; 189 + 190 + if (index == num_currents) 191 + return -EINVAL; 192 + 193 + return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, 194 + index << 2, TPS65218_PROTECT_L1); 195 + } 196 + 197 + static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, 198 + int min_uA, int max_uA) 199 + { 200 + int index = 0; 201 + unsigned int num_currents = ARRAY_SIZE(ls3_currents); 202 + struct tps65218 *tps = rdev_get_drvdata(dev); 203 + 204 + while (index < num_currents && ls3_currents[index] < max_uA) 205 + index++; 206 + 207 + index--; 208 + 209 + if (index < 0 || ls3_currents[index] < min_uA) 210 + return -EINVAL; 211 + 212 + return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, 213 + index << 2, TPS65218_PROTECT_L1); 214 + } 215 + 216 + static int tps65218_pmic_get_current_limit(struct regulator_dev *dev) 217 + { 218 + int retval; 219 + unsigned int index; 220 + struct tps65218 *tps = rdev_get_drvdata(dev); 221 + 222 + retval = tps65218_reg_read(tps, dev->desc->csel_reg, &index); 223 + if (retval < 0) 224 + return retval; 225 + 226 + index = (index & dev->desc->csel_mask) >> 2; 227 + 228 + return ls3_currents[index]; 229 + } 230 + 231 + static struct regulator_ops tps65218_ls3_ops = { 232 + .is_enabled = regulator_is_enabled_regmap, 233 + .enable = tps65218_pmic_enable, 234 + .disable = tps65218_pmic_disable, 235 + .set_input_current_limit = tps65218_pmic_set_input_current_lim, 236 + .set_current_limit = tps65218_pmic_set_current_limit, 237 + .get_current_limit = tps65218_pmic_get_current_limit, 238 + }; 239 + 183 240 /* Operations permitted on DCDC5, DCDC6 */ 184 241 static struct regulator_ops tps65218_dcdc56_pmic_ops = { 185 242 .is_enabled = regulator_is_enabled_regmap, ··· 250 183 }; 251 184 252 185 static const struct regulator_desc regulators[] = { 253 - TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64, 254 - TPS65218_REG_CONTROL_DCDC1, 255 - TPS65218_CONTROL_DCDC1_MASK, 256 - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, 257 - dcdc1_dcdc2_ranges, 2, 4000, 0), 258 - TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, 259 - TPS65218_REG_CONTROL_DCDC2, 260 - TPS65218_CONTROL_DCDC2_MASK, 261 - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, 262 - dcdc1_dcdc2_ranges, 2, 4000, 0), 263 - TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, 264 - 64, TPS65218_REG_CONTROL_DCDC3, 186 + TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, REGULATOR_VOLTAGE, 187 + tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1, 188 + TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, 189 + TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, 190 + 2, 4000, 0), 191 + TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, REGULATOR_VOLTAGE, 192 + tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, 193 + TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, 194 + TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, 195 + 2, 4000, 0), 196 + TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, REGULATOR_VOLTAGE, 197 + tps65218_ldo1_dcdc34_ops, 64, 198 + TPS65218_REG_CONTROL_DCDC3, 265 199 TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, 266 - TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0, 0), 267 - TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, 268 - 53, TPS65218_REG_CONTROL_DCDC4, 269 - TPS65218_CONTROL_DCDC4_MASK, 270 - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, 271 - dcdc4_ranges, 2, 0, 0), 272 - TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, 273 - 1, -1, -1, TPS65218_REG_ENABLE1, 274 - TPS65218_ENABLE1_DC5_EN, NULL, 0, 0, 1000000), 275 - TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, 276 - 1, -1, -1, TPS65218_REG_ENABLE1, 277 - TPS65218_ENABLE1_DC6_EN, NULL, 0, 0, 1800000), 278 - TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, 200 + TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, 201 + 0, 0), 202 + TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, REGULATOR_VOLTAGE, 203 + tps65218_ldo1_dcdc34_ops, 53, 204 + TPS65218_REG_CONTROL_DCDC4, 205 + TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, 206 + TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, 207 + 0, 0), 208 + TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, REGULATOR_VOLTAGE, 209 + tps65218_dcdc56_pmic_ops, 1, -1, -1, 210 + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0, 211 + NULL, 0, 0, 1000000), 212 + TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, REGULATOR_VOLTAGE, 213 + tps65218_dcdc56_pmic_ops, 1, -1, -1, 214 + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0, 215 + NULL, 0, 0, 1800000), 216 + TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, REGULATOR_VOLTAGE, 217 + tps65218_ldo1_dcdc34_ops, 64, 279 218 TPS65218_REG_CONTROL_LDO1, 280 219 TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, 281 - TPS65218_ENABLE2_LDO1_EN, ldo1_dcdc3_ranges, 220 + TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, 282 221 2, 0, 0), 222 + TPS65218_REGULATOR("LS3", TPS65218_LS_3, REGULATOR_CURRENT, 223 + tps65218_ls3_ops, 0, 0, 0, TPS65218_REG_ENABLE2, 224 + TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2, 225 + TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0), 283 226 }; 284 227 285 228 static int tps65218_regulator_probe(struct platform_device *pdev)
+13 -26
drivers/regulator/wm831x-dcdc.c
··· 365 365 return wm831x_dcdc_ilim[val]; 366 366 } 367 367 368 - static struct regulator_ops wm831x_buckv_ops = { 368 + static const struct regulator_ops wm831x_buckv_ops = { 369 369 .set_voltage_sel = wm831x_buckv_set_voltage_sel, 370 370 .get_voltage_sel = wm831x_buckv_get_voltage_sel, 371 371 .list_voltage = wm831x_buckv_list_voltage, ··· 585 585 return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, sel); 586 586 } 587 587 588 - static struct regulator_ops wm831x_buckp_ops = { 588 + static const struct regulator_ops wm831x_buckp_ops = { 589 589 .set_voltage_sel = regulator_set_voltage_sel_regmap, 590 590 .get_voltage_sel = regulator_get_voltage_sel_regmap, 591 591 .list_voltage = regulator_list_voltage_linear, ··· 725 725 return REGULATOR_STATUS_OFF; 726 726 } 727 727 728 - static struct regulator_ops wm831x_boostp_ops = { 728 + static const struct regulator_ops wm831x_boostp_ops = { 729 729 .get_status = wm831x_boostp_get_status, 730 730 731 731 .is_enabled = regulator_is_enabled_regmap, ··· 818 818 819 819 #define WM831X_EPE_BASE 6 820 820 821 - static struct regulator_ops wm831x_epe_ops = { 821 + static const struct regulator_ops wm831x_epe_ops = { 822 822 .is_enabled = regulator_is_enabled_regmap, 823 823 .enable = regulator_enable_regmap, 824 824 .disable = regulator_disable_regmap, ··· 884 884 }, 885 885 }; 886 886 887 + static struct platform_driver * const drivers[] = { 888 + &wm831x_buckv_driver, 889 + &wm831x_buckp_driver, 890 + &wm831x_boostp_driver, 891 + &wm831x_epe_driver, 892 + }; 893 + 887 894 static int __init wm831x_dcdc_init(void) 888 895 { 889 - int ret; 890 - ret = platform_driver_register(&wm831x_buckv_driver); 891 - if (ret != 0) 892 - pr_err("Failed to register WM831x BUCKV driver: %d\n", ret); 893 - 894 - ret = platform_driver_register(&wm831x_buckp_driver); 895 - if (ret != 0) 896 - pr_err("Failed to register WM831x BUCKP driver: %d\n", ret); 897 - 898 - ret = platform_driver_register(&wm831x_boostp_driver); 899 - if (ret != 0) 900 - pr_err("Failed to register WM831x BOOST driver: %d\n", ret); 901 - 902 - ret = platform_driver_register(&wm831x_epe_driver); 903 - if (ret != 0) 904 - pr_err("Failed to register WM831x EPE driver: %d\n", ret); 905 - 906 - return 0; 896 + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 907 897 } 908 898 subsys_initcall(wm831x_dcdc_init); 909 899 910 900 static void __exit wm831x_dcdc_exit(void) 911 901 { 912 - platform_driver_unregister(&wm831x_epe_driver); 913 - platform_driver_unregister(&wm831x_boostp_driver); 914 - platform_driver_unregister(&wm831x_buckp_driver); 915 - platform_driver_unregister(&wm831x_buckv_driver); 902 + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 916 903 } 917 904 module_exit(wm831x_dcdc_exit); 918 905
+1 -1
drivers/regulator/wm831x-isink.c
··· 128 128 return wm831x_isinkv_values[ret]; 129 129 } 130 130 131 - static struct regulator_ops wm831x_isink_ops = { 131 + static const struct regulator_ops wm831x_isink_ops = { 132 132 .is_enabled = wm831x_isink_is_enabled, 133 133 .enable = wm831x_isink_enable, 134 134 .disable = wm831x_isink_disable,
+11 -22
drivers/regulator/wm831x-ldo.c
··· 198 198 } 199 199 200 200 201 - static struct regulator_ops wm831x_gp_ldo_ops = { 201 + static const struct regulator_ops wm831x_gp_ldo_ops = { 202 202 .list_voltage = regulator_list_voltage_linear_range, 203 203 .map_voltage = regulator_map_voltage_linear_range, 204 204 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 409 409 return regulator_mode_to_status(ret); 410 410 } 411 411 412 - static struct regulator_ops wm831x_aldo_ops = { 412 + static const struct regulator_ops wm831x_aldo_ops = { 413 413 .list_voltage = regulator_list_voltage_linear_range, 414 414 .map_voltage = regulator_map_voltage_linear_range, 415 415 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 557 557 return REGULATOR_STATUS_OFF; 558 558 } 559 559 560 - static struct regulator_ops wm831x_alive_ldo_ops = { 560 + static const struct regulator_ops wm831x_alive_ldo_ops = { 561 561 .list_voltage = regulator_list_voltage_linear, 562 562 .map_voltage = regulator_map_voltage_linear, 563 563 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 653 653 }, 654 654 }; 655 655 656 + static struct platform_driver * const drivers[] = { 657 + &wm831x_gp_ldo_driver, 658 + &wm831x_aldo_driver, 659 + &wm831x_alive_ldo_driver, 660 + }; 661 + 656 662 static int __init wm831x_ldo_init(void) 657 663 { 658 - int ret; 659 - 660 - ret = platform_driver_register(&wm831x_gp_ldo_driver); 661 - if (ret != 0) 662 - pr_err("Failed to register WM831x GP LDO driver: %d\n", ret); 663 - 664 - ret = platform_driver_register(&wm831x_aldo_driver); 665 - if (ret != 0) 666 - pr_err("Failed to register WM831x ALDO driver: %d\n", ret); 667 - 668 - ret = platform_driver_register(&wm831x_alive_ldo_driver); 669 - if (ret != 0) 670 - pr_err("Failed to register WM831x alive LDO driver: %d\n", 671 - ret); 672 - 673 - return 0; 664 + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 674 665 } 675 666 subsys_initcall(wm831x_ldo_init); 676 667 677 668 static void __exit wm831x_ldo_exit(void) 678 669 { 679 - platform_driver_unregister(&wm831x_alive_ldo_driver); 680 - platform_driver_unregister(&wm831x_aldo_driver); 681 - platform_driver_unregister(&wm831x_gp_ldo_driver); 670 + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 682 671 } 683 672 module_exit(wm831x_ldo_exit); 684 673
+4 -4
drivers/regulator/wm8350-regulator.c
··· 941 941 return mode; 942 942 } 943 943 944 - static struct regulator_ops wm8350_dcdc_ops = { 944 + static const struct regulator_ops wm8350_dcdc_ops = { 945 945 .set_voltage_sel = regulator_set_voltage_sel_regmap, 946 946 .get_voltage_sel = regulator_get_voltage_sel_regmap, 947 947 .list_voltage = regulator_list_voltage_linear, ··· 958 958 .set_suspend_mode = wm8350_dcdc_set_suspend_mode, 959 959 }; 960 960 961 - static struct regulator_ops wm8350_dcdc2_5_ops = { 961 + static const struct regulator_ops wm8350_dcdc2_5_ops = { 962 962 .enable = regulator_enable_regmap, 963 963 .disable = regulator_disable_regmap, 964 964 .is_enabled = regulator_is_enabled_regmap, ··· 966 966 .set_suspend_disable = wm8350_dcdc25_set_suspend_disable, 967 967 }; 968 968 969 - static struct regulator_ops wm8350_ldo_ops = { 969 + static const struct regulator_ops wm8350_ldo_ops = { 970 970 .map_voltage = regulator_map_voltage_linear_range, 971 971 .set_voltage_sel = regulator_set_voltage_sel_regmap, 972 972 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 980 980 .set_suspend_disable = wm8350_ldo_set_suspend_disable, 981 981 }; 982 982 983 - static struct regulator_ops wm8350_isink_ops = { 983 + static const struct regulator_ops wm8350_isink_ops = { 984 984 .set_current_limit = wm8350_isink_set_current, 985 985 .get_current_limit = wm8350_isink_get_current, 986 986 .enable = wm8350_isink_enable,
+2 -2
drivers/regulator/wm8400-regulator.c
··· 24 24 REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000), 25 25 }; 26 26 27 - static struct regulator_ops wm8400_ldo_ops = { 27 + static const struct regulator_ops wm8400_ldo_ops = { 28 28 .is_enabled = regulator_is_enabled_regmap, 29 29 .enable = regulator_enable_regmap, 30 30 .disable = regulator_disable_regmap, ··· 106 106 return REGULATOR_MODE_NORMAL; 107 107 } 108 108 109 - static struct regulator_ops wm8400_dcdc_ops = { 109 + static const struct regulator_ops wm8400_dcdc_ops = { 110 110 .is_enabled = regulator_is_enabled_regmap, 111 111 .enable = regulator_enable_regmap, 112 112 .disable = regulator_disable_regmap,
+2 -2
drivers/regulator/wm8994-regulator.c
··· 36 36 #define WM8994_LDO1_MAX_SELECTOR 0x7 37 37 #define WM8994_LDO2_MAX_SELECTOR 0x3 38 38 39 - static struct regulator_ops wm8994_ldo1_ops = { 39 + static const struct regulator_ops wm8994_ldo1_ops = { 40 40 .list_voltage = regulator_list_voltage_linear, 41 41 .map_voltage = regulator_map_voltage_linear, 42 42 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 69 69 } 70 70 } 71 71 72 - static struct regulator_ops wm8994_ldo2_ops = { 72 + static const struct regulator_ops wm8994_ldo2_ops = { 73 73 .list_voltage = wm8994_ldo2_list_voltage, 74 74 .get_voltage_sel = regulator_get_voltage_sel_regmap, 75 75 .set_voltage_sel = regulator_set_voltage_sel_regmap,
+6 -1
include/linux/mfd/tps65218.h
··· 200 200 TPS65218_DCDC_4, 201 201 TPS65218_DCDC_5, 202 202 TPS65218_DCDC_6, 203 + /* LS's */ 204 + TPS65218_LS_3, 203 205 /* LDOs */ 204 206 TPS65218_LDO_1, 205 207 }; ··· 212 210 #define TPS65218_NUM_DCDC 6 213 211 /* Number of LDO voltage regulators available */ 214 212 #define TPS65218_NUM_LDO 1 213 + /* Number of total LS current regulators available */ 214 + #define TPS65218_NUM_LS 1 215 215 /* Number of total regulators available */ 216 - #define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO) 216 + #define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO \ 217 + + TPS65218_NUM_LS) 217 218 218 219 /* Define the TPS65218 IRQ numbers */ 219 220 enum tps65218_irqs {
+3
include/linux/regulator/consumer.h
··· 140 140 * 141 141 * @supply: The name of the supply. Initialised by the user before 142 142 * using the bulk regulator APIs. 143 + * @optional: The supply should be considered optional. Initialised by the user 144 + * before using the bulk regulator APIs. 143 145 * @consumer: The regulator consumer for the supply. This will be managed 144 146 * by the bulk API. 145 147 * ··· 151 149 */ 152 150 struct regulator_bulk_data { 153 151 const char *supply; 152 + bool optional; 154 153 struct regulator *consumer; 155 154 156 155 /* private: Internal use */
+2
include/linux/regulator/driver.h
··· 302 302 303 303 unsigned int vsel_reg; 304 304 unsigned int vsel_mask; 305 + unsigned int csel_reg; 306 + unsigned int csel_mask; 305 307 unsigned int apply_reg; 306 308 unsigned int apply_bit; 307 309 unsigned int enable_reg;