diff options
82 files changed, 3556 insertions, 746 deletions
diff --git a/Documentation/devicetree/bindings/mfd/s2mpa01.txt b/Documentation/devicetree/bindings/mfd/s2mpa01.txt new file mode 100644 index 000000000000..c13d3d8c3947 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/s2mpa01.txt | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | |||
| 2 | * Samsung S2MPA01 Voltage and Current Regulator | ||
| 3 | |||
| 4 | The Samsung S2MPA01 is a multi-function device which includes high | ||
| 5 | efficiency buck converters including Dual-Phase buck converter, various LDOs, | ||
| 6 | and an RTC. It is interfaced to the host controller using an I2C interface. | ||
| 7 | Each sub-block is addressed by the host system using different I2C slave | ||
| 8 | addresses. | ||
| 9 | |||
| 10 | Required properties: | ||
| 11 | - compatible: Should be "samsung,s2mpa01-pmic". | ||
| 12 | - reg: Specifies the I2C slave address of the PMIC block. It should be 0x66. | ||
| 13 | |||
| 14 | Optional properties: | ||
| 15 | - interrupt-parent: Specifies the phandle of the interrupt controller to which | ||
| 16 | the interrupts from s2mpa01 are delivered to. | ||
| 17 | - interrupts: An interrupt specifier for the sole interrupt generated by the | ||
| 18 | device. | ||
| 19 | |||
| 20 | Optional nodes: | ||
| 21 | - regulators: The regulators of s2mpa01 that have to be instantiated should be | ||
| 22 | included in a sub-node named 'regulators'. Regulator nodes and constraints | ||
| 23 | included in this sub-node use the standard regulator bindings which are | ||
| 24 | documented elsewhere. | ||
| 25 | |||
| 26 | Properties for BUCK regulator nodes: | ||
| 27 | - regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500 | ||
| 28 | (default), 25000, or 50000. May be 0 for disabling the ramp delay on | ||
| 29 | BUCK{1,2,3,4}. | ||
| 30 | |||
| 31 | In the absence of the regulator-ramp-delay property, the default ramp | ||
| 32 | delay will be used. | ||
| 33 | |||
| 34 | NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set | ||
| 35 | for a particular group of BUCKs. So provide same regulator-ramp-delay=<value>. | ||
| 36 | |||
| 37 | The following BUCKs share ramp settings: | ||
| 38 | * 1 and 6 | ||
| 39 | * 2 and 4 | ||
| 40 | * 8, 9, and 10 | ||
| 41 | |||
| 42 | The following are the names of the regulators that the s2mpa01 PMIC block | ||
| 43 | supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number | ||
| 44 | as per the datasheet of s2mpa01. | ||
| 45 | |||
| 46 | - LDOn | ||
| 47 | - valid values for n are 1 to 26 | ||
| 48 | - Example: LDO1, LD02, LDO26 | ||
| 49 | - BUCKn | ||
| 50 | - valid values for n are 1 to 10. | ||
| 51 | - Example: BUCK1, BUCK2, BUCK9 | ||
| 52 | |||
| 53 | Example: | ||
| 54 | |||
| 55 | s2mpa01_pmic@66 { | ||
| 56 | compatible = "samsung,s2mpa01-pmic"; | ||
| 57 | reg = <0x66>; | ||
| 58 | |||
| 59 | regulators { | ||
| 60 | ldo1_reg: LDO1 { | ||
| 61 | regulator-name = "VDD_ALIVE"; | ||
| 62 | regulator-min-microvolt = <1000000>; | ||
| 63 | regulator-max-microvolt = <1000000>; | ||
| 64 | }; | ||
| 65 | |||
| 66 | ldo2_reg: LDO2 { | ||
| 67 | regulator-name = "VDDQ_MMC2"; | ||
| 68 | regulator-min-microvolt = <2800000>; | ||
| 69 | regulator-max-microvolt = <2800000>; | ||
| 70 | regulator-always-on; | ||
| 71 | }; | ||
| 72 | |||
| 73 | buck1_reg: BUCK1 { | ||
| 74 | regulator-name = "vdd_mif"; | ||
| 75 | regulator-min-microvolt = <950000>; | ||
| 76 | regulator-max-microvolt = <1350000>; | ||
| 77 | regulator-always-on; | ||
| 78 | regulator-boot-on; | ||
| 79 | }; | ||
| 80 | |||
| 81 | buck2_reg: BUCK2 { | ||
| 82 | regulator-name = "vdd_arm"; | ||
| 83 | regulator-min-microvolt = <950000>; | ||
| 84 | regulator-max-microvolt = <1350000>; | ||
| 85 | regulator-always-on; | ||
| 86 | regulator-boot-on; | ||
| 87 | regulator-ramp-delay = <50000>; | ||
| 88 | }; | ||
| 89 | }; | ||
| 90 | }; | ||
diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt index 15ee89c3cc7b..f69bec294f02 100644 --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | 1 | ||
| 2 | * Samsung S2MPS11 Voltage and Current Regulator | 2 | * Samsung S2MPS11 and S2MPS14 Voltage and Current Regulator |
| 3 | 3 | ||
| 4 | The Samsung S2MPS11 is a multi-function device which includes voltage and | 4 | The Samsung S2MPS11 is a multi-function device which includes voltage and |
| 5 | current regulators, RTC, charger controller and other sub-blocks. It is | 5 | current regulators, RTC, charger controller and other sub-blocks. It is |
| @@ -7,7 +7,7 @@ interfaced to the host controller using an I2C interface. Each sub-block is | |||
| 7 | addressed by the host system using different I2C slave addresses. | 7 | addressed by the host system using different I2C slave addresses. |
| 8 | 8 | ||
| 9 | Required properties: | 9 | Required properties: |
| 10 | - compatible: Should be "samsung,s2mps11-pmic". | 10 | - compatible: Should be "samsung,s2mps11-pmic" or "samsung,s2mps14-pmic". |
| 11 | - reg: Specifies the I2C slave address of the pmic block. It should be 0x66. | 11 | - reg: Specifies the I2C slave address of the pmic block. It should be 0x66. |
| 12 | 12 | ||
| 13 | Optional properties: | 13 | Optional properties: |
| @@ -59,10 +59,14 @@ supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number | |||
| 59 | as per the datasheet of s2mps11. | 59 | as per the datasheet of s2mps11. |
| 60 | 60 | ||
| 61 | - LDOn | 61 | - LDOn |
| 62 | - valid values for n are 1 to 38 | 62 | - valid values for n are: |
| 63 | - S2MPS11: 1 to 38 | ||
| 64 | - S2MPS14: 1 to 25 | ||
| 63 | - Example: LDO1, LD02, LDO28 | 65 | - Example: LDO1, LD02, LDO28 |
| 64 | - BUCKn | 66 | - BUCKn |
| 65 | - valid values for n are 1 to 10. | 67 | - valid values for n are: |
| 68 | - S2MPS11: 1 to 10 | ||
| 69 | - S2MPS14: 1 to 5 | ||
| 66 | - Example: BUCK1, BUCK2, BUCK9 | 70 | - Example: BUCK1, BUCK2, BUCK9 |
| 67 | 71 | ||
| 68 | Example: | 72 | Example: |
diff --git a/Documentation/devicetree/bindings/mfd/tps65910.txt b/Documentation/devicetree/bindings/mfd/tps65910.txt index b4bd98af1cc7..38833e63a59f 100644 --- a/Documentation/devicetree/bindings/mfd/tps65910.txt +++ b/Documentation/devicetree/bindings/mfd/tps65910.txt | |||
| @@ -11,7 +11,7 @@ Required properties: | |||
| 11 | - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. | 11 | - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. |
| 12 | The first cell is the IRQ number. | 12 | The first cell is the IRQ number. |
| 13 | The second cell is the flags, encoded as the trigger masks from | 13 | The second cell is the flags, encoded as the trigger masks from |
| 14 | Documentation/devicetree/bindings/interrupts.txt | 14 | Documentation/devicetree/bindings/interrupt-controller/interrupts.txt |
| 15 | - regulators: This is the list of child nodes that specify the regulator | 15 | - regulators: This is the list of child nodes that specify the regulator |
| 16 | initialization data for defined regulators. Not all regulators for the given | 16 | initialization data for defined regulators. Not all regulators for the given |
| 17 | device need to be present. The definition for each of these nodes is defined | 17 | device need to be present. The definition for each of these nodes is defined |
diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt index 63c659800c03..e5cac1e0ca8a 100644 --- a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt | |||
| @@ -8,8 +8,12 @@ Required properties: | |||
| 8 | Optional properties: | 8 | Optional properties: |
| 9 | - enable-gpio : GPIO to use to enable/disable the regulator. | 9 | - enable-gpio : GPIO to use to enable/disable the regulator. |
| 10 | - gpios : GPIO group used to control voltage. | 10 | - gpios : GPIO group used to control voltage. |
| 11 | - gpios-states : gpios pin's initial states array. 0: LOW, 1: HIGH. | ||
| 12 | defualt is LOW if nothing is specified. | ||
| 11 | - startup-delay-us : Startup time in microseconds. | 13 | - startup-delay-us : Startup time in microseconds. |
| 12 | - enable-active-high : Polarity of GPIO is active high (default is low). | 14 | - enable-active-high : Polarity of GPIO is active high (default is low). |
| 15 | - regulator-type : Specifies what is being regulated, must be either | ||
| 16 | "voltage" or "current", defaults to current. | ||
| 13 | 17 | ||
| 14 | Any property defined as part of the core regulator binding defined in | 18 | Any property defined as part of the core regulator binding defined in |
| 15 | regulator.txt can also be used. | 19 | regulator.txt can also be used. |
diff --git a/Documentation/devicetree/bindings/regulator/pfuze100.txt b/Documentation/devicetree/bindings/regulator/pfuze100.txt index fc989b2e8057..34ef5d16d0f1 100644 --- a/Documentation/devicetree/bindings/regulator/pfuze100.txt +++ b/Documentation/devicetree/bindings/regulator/pfuze100.txt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | PFUZE100 family of regulators | 1 | PFUZE100 family of regulators |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: "fsl,pfuze100" | 4 | - compatible: "fsl,pfuze100" or "fsl,pfuze200" |
| 5 | - reg: I2C slave address | 5 | - reg: I2C slave address |
| 6 | 6 | ||
| 7 | Required child node: | 7 | Required child node: |
| @@ -10,11 +10,14 @@ Required child node: | |||
| 10 | Documentation/devicetree/bindings/regulator/regulator.txt. | 10 | Documentation/devicetree/bindings/regulator/regulator.txt. |
| 11 | 11 | ||
| 12 | The valid names for regulators are: | 12 | The valid names for regulators are: |
| 13 | --PFUZE100 | ||
| 13 | sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6 | 14 | sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6 |
| 15 | --PFUZE200 | ||
| 16 | sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6 | ||
| 14 | 17 | ||
| 15 | Each regulator is defined using the standard binding for regulators. | 18 | Each regulator is defined using the standard binding for regulators. |
| 16 | 19 | ||
| 17 | Example: | 20 | Example 1: PFUZE100 |
| 18 | 21 | ||
| 19 | pmic: pfuze100@08 { | 22 | pmic: pfuze100@08 { |
| 20 | compatible = "fsl,pfuze100"; | 23 | compatible = "fsl,pfuze100"; |
| @@ -113,3 +116,92 @@ Example: | |||
| 113 | }; | 116 | }; |
| 114 | }; | 117 | }; |
| 115 | }; | 118 | }; |
| 119 | |||
| 120 | |||
| 121 | Example 2: PFUZE200 | ||
| 122 | |||
| 123 | pmic: pfuze200@08 { | ||
| 124 | compatible = "fsl,pfuze200"; | ||
| 125 | reg = <0x08>; | ||
| 126 | |||
| 127 | regulators { | ||
| 128 | sw1a_reg: sw1ab { | ||
| 129 | regulator-min-microvolt = <300000>; | ||
| 130 | regulator-max-microvolt = <1875000>; | ||
| 131 | regulator-boot-on; | ||
| 132 | regulator-always-on; | ||
| 133 | regulator-ramp-delay = <6250>; | ||
| 134 | }; | ||
| 135 | |||
| 136 | sw2_reg: sw2 { | ||
| 137 | regulator-min-microvolt = <800000>; | ||
| 138 | regulator-max-microvolt = <3300000>; | ||
| 139 | regulator-boot-on; | ||
| 140 | regulator-always-on; | ||
| 141 | }; | ||
| 142 | |||
| 143 | sw3a_reg: sw3a { | ||
| 144 | regulator-min-microvolt = <400000>; | ||
| 145 | regulator-max-microvolt = <1975000>; | ||
| 146 | regulator-boot-on; | ||
| 147 | regulator-always-on; | ||
| 148 | }; | ||
| 149 | |||
| 150 | sw3b_reg: sw3b { | ||
| 151 | regulator-min-microvolt = <400000>; | ||
| 152 | regulator-max-microvolt = <1975000>; | ||
| 153 | regulator-boot-on; | ||
| 154 | regulator-always-on; | ||
| 155 | }; | ||
| 156 | |||
| 157 | swbst_reg: swbst { | ||
| 158 | regulator-min-microvolt = <5000000>; | ||
| 159 | regulator-max-microvolt = <5150000>; | ||
| 160 | }; | ||
| 161 | |||
| 162 | snvs_reg: vsnvs { | ||
| 163 | regulator-min-microvolt = <1000000>; | ||
| 164 | regulator-max-microvolt = <3000000>; | ||
| 165 | regulator-boot-on; | ||
| 166 | regulator-always-on; | ||
| 167 | }; | ||
| 168 | |||
| 169 | vref_reg: vrefddr { | ||
| 170 | regulator-boot-on; | ||
| 171 | regulator-always-on; | ||
| 172 | }; | ||
| 173 | |||
| 174 | vgen1_reg: vgen1 { | ||
| 175 | regulator-min-microvolt = <800000>; | ||
| 176 | regulator-max-microvolt = <1550000>; | ||
| 177 | }; | ||
| 178 | |||
| 179 | vgen2_reg: vgen2 { | ||
| 180 | regulator-min-microvolt = <800000>; | ||
| 181 | regulator-max-microvolt = <1550000>; | ||
| 182 | }; | ||
| 183 | |||
| 184 | vgen3_reg: vgen3 { | ||
| 185 | regulator-min-microvolt = <1800000>; | ||
| 186 | regulator-max-microvolt = <3300000>; | ||
| 187 | }; | ||
| 188 | |||
| 189 | vgen4_reg: vgen4 { | ||
| 190 | regulator-min-microvolt = <1800000>; | ||
| 191 | regulator-max-microvolt = <3300000>; | ||
| 192 | regulator-always-on; | ||
| 193 | }; | ||
| 194 | |||
| 195 | vgen5_reg: vgen5 { | ||
| 196 | regulator-min-microvolt = <1800000>; | ||
| 197 | regulator-max-microvolt = <3300000>; | ||
| 198 | regulator-always-on; | ||
| 199 | }; | ||
| 200 | |||
| 201 | vgen6_reg: vgen6 { | ||
| 202 | regulator-min-microvolt = <1800000>; | ||
| 203 | regulator-max-microvolt = <3300000>; | ||
| 204 | regulator-always-on; | ||
| 205 | }; | ||
| 206 | }; | ||
| 207 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt b/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt index fc6b38f035bd..d290988ed975 100644 --- a/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt | |||
| @@ -69,13 +69,16 @@ sub-node should be of the format as listed below. | |||
| 69 | }; | 69 | }; |
| 70 | }; | 70 | }; |
| 71 | The above regulator entries are defined in regulator bindings documentation | 71 | The above regulator entries are defined in regulator bindings documentation |
| 72 | except op_mode description. | 72 | except these properties: |
| 73 | - op_mode: describes the different operating modes of the LDO's with | 73 | - op_mode: describes the different operating modes of the LDO's with |
| 74 | power mode change in SOC. The different possible values are, | 74 | power mode change in SOC. The different possible values are, |
| 75 | 0 - always off mode | 75 | 0 - always off mode |
| 76 | 1 - on in normal mode | 76 | 1 - on in normal mode |
| 77 | 2 - low power mode | 77 | 2 - low power mode |
| 78 | 3 - suspend mode | 78 | 3 - suspend mode |
| 79 | - s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one | ||
| 80 | GPIO controlling this regulator (enable/disable); This is | ||
| 81 | valid only for buck9. | ||
| 79 | 82 | ||
| 80 | The following are the names of the regulators that the s5m8767 pmic block | 83 | The following are the names of the regulators that the s5m8767 pmic block |
| 81 | supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number | 84 | supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number |
| @@ -148,5 +151,13 @@ Example: | |||
| 148 | regulator-always-on; | 151 | regulator-always-on; |
| 149 | regulator-boot-on; | 152 | regulator-boot-on; |
| 150 | }; | 153 | }; |
| 154 | |||
| 155 | vemmc_reg: BUCK9 { | ||
| 156 | regulator-name = "VMEM_VDD_2.8V"; | ||
| 157 | regulator-min-microvolt = <2800000>; | ||
| 158 | regulator-max-microvolt = <2800000>; | ||
| 159 | op_mode = <3>; /* Standby Mode */ | ||
| 160 | s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>; | ||
| 161 | }; | ||
| 151 | }; | 162 | }; |
| 152 | }; | 163 | }; |
diff --git a/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt b/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt index 2e57a33e9029..c58db75f959e 100644 --- a/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt | |||
| @@ -4,10 +4,14 @@ Required Properties: | |||
| 4 | - compatible: Should be one of: | 4 | - compatible: Should be one of: |
| 5 | - "ti,abb-v1" for older SoCs like OMAP3 | 5 | - "ti,abb-v1" for older SoCs like OMAP3 |
| 6 | - "ti,abb-v2" for newer SoCs like OMAP4, OMAP5 | 6 | - "ti,abb-v2" for newer SoCs like OMAP4, OMAP5 |
| 7 | - "ti,abb-v3" for a generic definition where setup and control registers are | ||
| 8 | provided (example: DRA7) | ||
| 7 | - reg: Address and length of the register set for the device. It contains | 9 | - reg: Address and length of the register set for the device. It contains |
| 8 | the information of registers in the same order as described by reg-names | 10 | the information of registers in the same order as described by reg-names |
| 9 | - reg-names: Should contain the reg names | 11 | - reg-names: Should contain the reg names |
| 10 | - "base-address" - contains base address of ABB module | 12 | - "base-address" - contains base address of ABB module (ti,abb-v1,ti,abb-v2) |
| 13 | - "control-address" - contains control register address of ABB module (ti,abb-v3) | ||
| 14 | - "setup-address" - contains setup register address of ABB module (ti,abb-v3) | ||
| 11 | - "int-address" - contains address of interrupt register for ABB module | 15 | - "int-address" - contains address of interrupt register for ABB module |
| 12 | (also see Optional properties) | 16 | (also see Optional properties) |
| 13 | - #address-cell: should be 0 | 17 | - #address-cell: should be 0 |
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 545c4de412c3..db4e264eecb6 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
| @@ -791,6 +791,32 @@ void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) | |||
| 791 | EXPORT_SYMBOL_GPL(devm_kmalloc); | 791 | EXPORT_SYMBOL_GPL(devm_kmalloc); |
| 792 | 792 | ||
| 793 | /** | 793 | /** |
| 794 | * devm_kstrdup - Allocate resource managed space and | ||
| 795 | * copy an existing string into that. | ||
| 796 | * @dev: Device to allocate memory for | ||
| 797 | * @s: the string to duplicate | ||
| 798 | * @gfp: the GFP mask used in the devm_kmalloc() call when | ||
| 799 | * allocating memory | ||
| 800 | * RETURNS: | ||
| 801 | * Pointer to allocated string on success, NULL on failure. | ||
| 802 | */ | ||
| 803 | char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) | ||
| 804 | { | ||
| 805 | size_t size; | ||
| 806 | char *buf; | ||
| 807 | |||
| 808 | if (!s) | ||
| 809 | return NULL; | ||
| 810 | |||
| 811 | size = strlen(s) + 1; | ||
| 812 | buf = devm_kmalloc(dev, size, gfp); | ||
| 813 | if (buf) | ||
| 814 | memcpy(buf, s, size); | ||
| 815 | return buf; | ||
| 816 | } | ||
| 817 | EXPORT_SYMBOL_GPL(devm_kstrdup); | ||
| 818 | |||
| 819 | /** | ||
| 794 | * devm_kfree - Resource-managed kfree | 820 | * devm_kfree - Resource-managed kfree |
| 795 | * @dev: Device this memory belongs to | 821 | * @dev: Device this memory belongs to |
| 796 | * @p: Memory to free | 822 | * @p: Memory to free |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 714e2135210e..281a82747275 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
| @@ -26,7 +26,9 @@ | |||
| 26 | #include <linux/mfd/samsung/core.h> | 26 | #include <linux/mfd/samsung/core.h> |
| 27 | #include <linux/mfd/samsung/irq.h> | 27 | #include <linux/mfd/samsung/irq.h> |
| 28 | #include <linux/mfd/samsung/rtc.h> | 28 | #include <linux/mfd/samsung/rtc.h> |
| 29 | #include <linux/mfd/samsung/s2mpa01.h> | ||
| 29 | #include <linux/mfd/samsung/s2mps11.h> | 30 | #include <linux/mfd/samsung/s2mps11.h> |
| 31 | #include <linux/mfd/samsung/s2mps14.h> | ||
| 30 | #include <linux/mfd/samsung/s5m8763.h> | 32 | #include <linux/mfd/samsung/s5m8763.h> |
| 31 | #include <linux/mfd/samsung/s5m8767.h> | 33 | #include <linux/mfd/samsung/s5m8767.h> |
| 32 | #include <linux/regmap.h> | 34 | #include <linux/regmap.h> |
| @@ -69,18 +71,53 @@ static const struct mfd_cell s2mps11_devs[] = { | |||
| 69 | } | 71 | } |
| 70 | }; | 72 | }; |
| 71 | 73 | ||
| 74 | static const struct mfd_cell s2mps14_devs[] = { | ||
| 75 | { | ||
| 76 | .name = "s2mps14-pmic", | ||
| 77 | }, { | ||
| 78 | .name = "s2mps14-rtc", | ||
| 79 | }, { | ||
| 80 | .name = "s2mps14-clk", | ||
| 81 | } | ||
| 82 | }; | ||
| 83 | |||
| 84 | static const struct mfd_cell s2mpa01_devs[] = { | ||
| 85 | { | ||
| 86 | .name = "s2mpa01-pmic", | ||
| 87 | }, | ||
| 88 | }; | ||
| 89 | |||
| 72 | #ifdef CONFIG_OF | 90 | #ifdef CONFIG_OF |
| 73 | static struct of_device_id sec_dt_match[] = { | 91 | static struct of_device_id sec_dt_match[] = { |
| 74 | { .compatible = "samsung,s5m8767-pmic", | 92 | { .compatible = "samsung,s5m8767-pmic", |
| 75 | .data = (void *)S5M8767X, | 93 | .data = (void *)S5M8767X, |
| 76 | }, | 94 | }, { |
| 77 | { .compatible = "samsung,s2mps11-pmic", | 95 | .compatible = "samsung,s2mps11-pmic", |
| 78 | .data = (void *)S2MPS11X, | 96 | .data = (void *)S2MPS11X, |
| 97 | }, { | ||
| 98 | .compatible = "samsung,s2mps14-pmic", | ||
| 99 | .data = (void *)S2MPS14X, | ||
| 100 | }, { | ||
| 101 | .compatible = "samsung,s2mpa01-pmic", | ||
| 102 | .data = (void *)S2MPA01, | ||
| 103 | }, { | ||
| 104 | /* Sentinel */ | ||
| 79 | }, | 105 | }, |
| 80 | {}, | ||
| 81 | }; | 106 | }; |
| 82 | #endif | 107 | #endif |
| 83 | 108 | ||
| 109 | static bool s2mpa01_volatile(struct device *dev, unsigned int reg) | ||
| 110 | { | ||
| 111 | switch (reg) { | ||
| 112 | case S2MPA01_REG_INT1M: | ||
| 113 | case S2MPA01_REG_INT2M: | ||
| 114 | case S2MPA01_REG_INT3M: | ||
| 115 | return false; | ||
| 116 | default: | ||
| 117 | return true; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 84 | static bool s2mps11_volatile(struct device *dev, unsigned int reg) | 121 | static bool s2mps11_volatile(struct device *dev, unsigned int reg) |
| 85 | { | 122 | { |
| 86 | switch (reg) { | 123 | switch (reg) { |
| @@ -111,6 +148,15 @@ static const struct regmap_config sec_regmap_config = { | |||
| 111 | .val_bits = 8, | 148 | .val_bits = 8, |
| 112 | }; | 149 | }; |
| 113 | 150 | ||
| 151 | static const struct regmap_config s2mpa01_regmap_config = { | ||
| 152 | .reg_bits = 8, | ||
| 153 | .val_bits = 8, | ||
| 154 | |||
| 155 | .max_register = S2MPA01_REG_LDO_OVCB4, | ||
| 156 | .volatile_reg = s2mpa01_volatile, | ||
| 157 | .cache_type = REGCACHE_FLAT, | ||
| 158 | }; | ||
| 159 | |||
| 114 | static const struct regmap_config s2mps11_regmap_config = { | 160 | static const struct regmap_config s2mps11_regmap_config = { |
| 115 | .reg_bits = 8, | 161 | .reg_bits = 8, |
| 116 | .val_bits = 8, | 162 | .val_bits = 8, |
| @@ -120,6 +166,15 @@ static const struct regmap_config s2mps11_regmap_config = { | |||
| 120 | .cache_type = REGCACHE_FLAT, | 166 | .cache_type = REGCACHE_FLAT, |
| 121 | }; | 167 | }; |
| 122 | 168 | ||
| 169 | static const struct regmap_config s2mps14_regmap_config = { | ||
| 170 | .reg_bits = 8, | ||
| 171 | .val_bits = 8, | ||
| 172 | |||
| 173 | .max_register = S2MPS14_REG_LDODSCH3, | ||
| 174 | .volatile_reg = s2mps11_volatile, | ||
| 175 | .cache_type = REGCACHE_FLAT, | ||
| 176 | }; | ||
| 177 | |||
| 123 | static const struct regmap_config s5m8763_regmap_config = { | 178 | static const struct regmap_config s5m8763_regmap_config = { |
| 124 | .reg_bits = 8, | 179 | .reg_bits = 8, |
| 125 | .val_bits = 8, | 180 | .val_bits = 8, |
| @@ -138,9 +193,18 @@ static const struct regmap_config s5m8767_regmap_config = { | |||
| 138 | .cache_type = REGCACHE_FLAT, | 193 | .cache_type = REGCACHE_FLAT, |
| 139 | }; | 194 | }; |
| 140 | 195 | ||
| 141 | static const struct regmap_config sec_rtc_regmap_config = { | 196 | static const struct regmap_config s5m_rtc_regmap_config = { |
| 197 | .reg_bits = 8, | ||
| 198 | .val_bits = 8, | ||
| 199 | |||
| 200 | .max_register = SEC_RTC_REG_MAX, | ||
| 201 | }; | ||
| 202 | |||
| 203 | static const struct regmap_config s2mps14_rtc_regmap_config = { | ||
| 142 | .reg_bits = 8, | 204 | .reg_bits = 8, |
| 143 | .val_bits = 8, | 205 | .val_bits = 8, |
| 206 | |||
| 207 | .max_register = S2MPS_RTC_REG_MAX, | ||
| 144 | }; | 208 | }; |
| 145 | 209 | ||
| 146 | #ifdef CONFIG_OF | 210 | #ifdef CONFIG_OF |
| @@ -180,24 +244,24 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( | |||
| 180 | } | 244 | } |
| 181 | #endif | 245 | #endif |
| 182 | 246 | ||
| 183 | static inline int sec_i2c_get_driver_data(struct i2c_client *i2c, | 247 | static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c, |
| 184 | const struct i2c_device_id *id) | 248 | const struct i2c_device_id *id) |
| 185 | { | 249 | { |
| 186 | #ifdef CONFIG_OF | 250 | #ifdef CONFIG_OF |
| 187 | if (i2c->dev.of_node) { | 251 | if (i2c->dev.of_node) { |
| 188 | const struct of_device_id *match; | 252 | const struct of_device_id *match; |
| 189 | match = of_match_node(sec_dt_match, i2c->dev.of_node); | 253 | match = of_match_node(sec_dt_match, i2c->dev.of_node); |
| 190 | return (int)match->data; | 254 | return (unsigned long)match->data; |
| 191 | } | 255 | } |
| 192 | #endif | 256 | #endif |
| 193 | return (int)id->driver_data; | 257 | return id->driver_data; |
| 194 | } | 258 | } |
| 195 | 259 | ||
| 196 | static int sec_pmic_probe(struct i2c_client *i2c, | 260 | static int sec_pmic_probe(struct i2c_client *i2c, |
| 197 | const struct i2c_device_id *id) | 261 | const struct i2c_device_id *id) |
| 198 | { | 262 | { |
| 199 | struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); | 263 | struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); |
| 200 | const struct regmap_config *regmap; | 264 | const struct regmap_config *regmap, *regmap_rtc; |
| 201 | struct sec_pmic_dev *sec_pmic; | 265 | struct sec_pmic_dev *sec_pmic; |
| 202 | int ret; | 266 | int ret; |
| 203 | 267 | ||
| @@ -229,17 +293,34 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
| 229 | } | 293 | } |
| 230 | 294 | ||
| 231 | switch (sec_pmic->device_type) { | 295 | switch (sec_pmic->device_type) { |
| 296 | case S2MPA01: | ||
| 297 | regmap = &s2mpa01_regmap_config; | ||
| 298 | break; | ||
| 232 | case S2MPS11X: | 299 | case S2MPS11X: |
| 233 | regmap = &s2mps11_regmap_config; | 300 | regmap = &s2mps11_regmap_config; |
| 301 | /* | ||
| 302 | * The rtc-s5m driver does not support S2MPS11 and there | ||
| 303 | * is no mfd_cell for S2MPS11 RTC device. | ||
| 304 | * However we must pass something to devm_regmap_init_i2c() | ||
| 305 | * so use S5M-like regmap config even though it wouldn't work. | ||
| 306 | */ | ||
| 307 | regmap_rtc = &s5m_rtc_regmap_config; | ||
| 308 | break; | ||
| 309 | case S2MPS14X: | ||
| 310 | regmap = &s2mps14_regmap_config; | ||
| 311 | regmap_rtc = &s2mps14_rtc_regmap_config; | ||
| 234 | break; | 312 | break; |
| 235 | case S5M8763X: | 313 | case S5M8763X: |
| 236 | regmap = &s5m8763_regmap_config; | 314 | regmap = &s5m8763_regmap_config; |
| 315 | regmap_rtc = &s5m_rtc_regmap_config; | ||
| 237 | break; | 316 | break; |
| 238 | case S5M8767X: | 317 | case S5M8767X: |
| 239 | regmap = &s5m8767_regmap_config; | 318 | regmap = &s5m8767_regmap_config; |
| 319 | regmap_rtc = &s5m_rtc_regmap_config; | ||
| 240 | break; | 320 | break; |
| 241 | default: | 321 | default: |
| 242 | regmap = &sec_regmap_config; | 322 | regmap = &sec_regmap_config; |
| 323 | regmap_rtc = &s5m_rtc_regmap_config; | ||
| 243 | break; | 324 | break; |
| 244 | } | 325 | } |
| 245 | 326 | ||
| @@ -252,10 +333,13 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
| 252 | } | 333 | } |
| 253 | 334 | ||
| 254 | sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); | 335 | sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); |
| 336 | if (!sec_pmic->rtc) { | ||
| 337 | dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n"); | ||
| 338 | return -ENODEV; | ||
| 339 | } | ||
| 255 | i2c_set_clientdata(sec_pmic->rtc, sec_pmic); | 340 | i2c_set_clientdata(sec_pmic->rtc, sec_pmic); |
| 256 | 341 | ||
| 257 | sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, | 342 | sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, regmap_rtc); |
| 258 | &sec_rtc_regmap_config); | ||
| 259 | if (IS_ERR(sec_pmic->regmap_rtc)) { | 343 | if (IS_ERR(sec_pmic->regmap_rtc)) { |
| 260 | ret = PTR_ERR(sec_pmic->regmap_rtc); | 344 | ret = PTR_ERR(sec_pmic->regmap_rtc); |
| 261 | dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n", | 345 | dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n", |
| @@ -283,10 +367,18 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
| 283 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, | 367 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, |
| 284 | ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); | 368 | ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); |
| 285 | break; | 369 | break; |
| 370 | case S2MPA01: | ||
| 371 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mpa01_devs, | ||
| 372 | ARRAY_SIZE(s2mpa01_devs), NULL, 0, NULL); | ||
| 373 | break; | ||
| 286 | case S2MPS11X: | 374 | case S2MPS11X: |
| 287 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, | 375 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, |
| 288 | ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); | 376 | ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); |
| 289 | break; | 377 | break; |
| 378 | case S2MPS14X: | ||
| 379 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs, | ||
| 380 | ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL); | ||
| 381 | break; | ||
| 290 | default: | 382 | default: |
| 291 | /* If this happens the probe function is problem */ | 383 | /* If this happens the probe function is problem */ |
| 292 | BUG(); | 384 | BUG(); |
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 4de494f51d40..64e7913aadc6 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * sec-irq.c | 2 | * sec-irq.c |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd | 4 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd |
| 5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/mfd/samsung/core.h> | 19 | #include <linux/mfd/samsung/core.h> |
| 20 | #include <linux/mfd/samsung/irq.h> | 20 | #include <linux/mfd/samsung/irq.h> |
| 21 | #include <linux/mfd/samsung/s2mps11.h> | 21 | #include <linux/mfd/samsung/s2mps11.h> |
| 22 | #include <linux/mfd/samsung/s2mps14.h> | ||
| 22 | #include <linux/mfd/samsung/s5m8763.h> | 23 | #include <linux/mfd/samsung/s5m8763.h> |
| 23 | #include <linux/mfd/samsung/s5m8767.h> | 24 | #include <linux/mfd/samsung/s5m8767.h> |
| 24 | 25 | ||
| @@ -59,13 +60,13 @@ static const struct regmap_irq s2mps11_irqs[] = { | |||
| 59 | .reg_offset = 1, | 60 | .reg_offset = 1, |
| 60 | .mask = S2MPS11_IRQ_RTC60S_MASK, | 61 | .mask = S2MPS11_IRQ_RTC60S_MASK, |
| 61 | }, | 62 | }, |
| 62 | [S2MPS11_IRQ_RTCA1] = { | 63 | [S2MPS11_IRQ_RTCA0] = { |
| 63 | .reg_offset = 1, | 64 | .reg_offset = 1, |
| 64 | .mask = S2MPS11_IRQ_RTCA1_MASK, | 65 | .mask = S2MPS11_IRQ_RTCA0_MASK, |
| 65 | }, | 66 | }, |
| 66 | [S2MPS11_IRQ_RTCA2] = { | 67 | [S2MPS11_IRQ_RTCA1] = { |
| 67 | .reg_offset = 1, | 68 | .reg_offset = 1, |
| 68 | .mask = S2MPS11_IRQ_RTCA2_MASK, | 69 | .mask = S2MPS11_IRQ_RTCA1_MASK, |
| 69 | }, | 70 | }, |
| 70 | [S2MPS11_IRQ_SMPL] = { | 71 | [S2MPS11_IRQ_SMPL] = { |
| 71 | .reg_offset = 1, | 72 | .reg_offset = 1, |
| @@ -89,6 +90,76 @@ static const struct regmap_irq s2mps11_irqs[] = { | |||
| 89 | }, | 90 | }, |
| 90 | }; | 91 | }; |
| 91 | 92 | ||
| 93 | static const struct regmap_irq s2mps14_irqs[] = { | ||
| 94 | [S2MPS14_IRQ_PWRONF] = { | ||
| 95 | .reg_offset = 0, | ||
| 96 | .mask = S2MPS11_IRQ_PWRONF_MASK, | ||
| 97 | }, | ||
| 98 | [S2MPS14_IRQ_PWRONR] = { | ||
| 99 | .reg_offset = 0, | ||
| 100 | .mask = S2MPS11_IRQ_PWRONR_MASK, | ||
| 101 | }, | ||
| 102 | [S2MPS14_IRQ_JIGONBF] = { | ||
| 103 | .reg_offset = 0, | ||
| 104 | .mask = S2MPS11_IRQ_JIGONBF_MASK, | ||
| 105 | }, | ||
| 106 | [S2MPS14_IRQ_JIGONBR] = { | ||
| 107 | .reg_offset = 0, | ||
| 108 | .mask = S2MPS11_IRQ_JIGONBR_MASK, | ||
| 109 | }, | ||
| 110 | [S2MPS14_IRQ_ACOKBF] = { | ||
| 111 | .reg_offset = 0, | ||
| 112 | .mask = S2MPS11_IRQ_ACOKBF_MASK, | ||
| 113 | }, | ||
| 114 | [S2MPS14_IRQ_ACOKBR] = { | ||
| 115 | .reg_offset = 0, | ||
| 116 | .mask = S2MPS11_IRQ_ACOKBR_MASK, | ||
| 117 | }, | ||
| 118 | [S2MPS14_IRQ_PWRON1S] = { | ||
| 119 | .reg_offset = 0, | ||
| 120 | .mask = S2MPS11_IRQ_PWRON1S_MASK, | ||
| 121 | }, | ||
| 122 | [S2MPS14_IRQ_MRB] = { | ||
| 123 | .reg_offset = 0, | ||
| 124 | .mask = S2MPS11_IRQ_MRB_MASK, | ||
| 125 | }, | ||
| 126 | [S2MPS14_IRQ_RTC60S] = { | ||
| 127 | .reg_offset = 1, | ||
| 128 | .mask = S2MPS11_IRQ_RTC60S_MASK, | ||
| 129 | }, | ||
| 130 | [S2MPS14_IRQ_RTCA1] = { | ||
| 131 | .reg_offset = 1, | ||
| 132 | .mask = S2MPS11_IRQ_RTCA1_MASK, | ||
| 133 | }, | ||
| 134 | [S2MPS14_IRQ_RTCA0] = { | ||
| 135 | .reg_offset = 1, | ||
| 136 | .mask = S2MPS11_IRQ_RTCA0_MASK, | ||
| 137 | }, | ||
| 138 | [S2MPS14_IRQ_SMPL] = { | ||
| 139 | .reg_offset = 1, | ||
| 140 | .mask = S2MPS11_IRQ_SMPL_MASK, | ||
| 141 | }, | ||
| 142 | [S2MPS14_IRQ_RTC1S] = { | ||
| 143 | .reg_offset = 1, | ||
| 144 | .mask = S2MPS11_IRQ_RTC1S_MASK, | ||
| 145 | }, | ||
| 146 | [S2MPS14_IRQ_WTSR] = { | ||
| 147 | .reg_offset = 1, | ||
| 148 | .mask = S2MPS11_IRQ_WTSR_MASK, | ||
| 149 | }, | ||
| 150 | [S2MPS14_IRQ_INT120C] = { | ||
| 151 | .reg_offset = 2, | ||
| 152 | .mask = S2MPS11_IRQ_INT120C_MASK, | ||
| 153 | }, | ||
| 154 | [S2MPS14_IRQ_INT140C] = { | ||
| 155 | .reg_offset = 2, | ||
| 156 | .mask = S2MPS11_IRQ_INT140C_MASK, | ||
| 157 | }, | ||
| 158 | [S2MPS14_IRQ_TSD] = { | ||
| 159 | .reg_offset = 2, | ||
| 160 | .mask = S2MPS14_IRQ_TSD_MASK, | ||
| 161 | }, | ||
| 162 | }; | ||
| 92 | 163 | ||
| 93 | static const struct regmap_irq s5m8767_irqs[] = { | 164 | static const struct regmap_irq s5m8767_irqs[] = { |
| 94 | [S5M8767_IRQ_PWRR] = { | 165 | [S5M8767_IRQ_PWRR] = { |
| @@ -246,6 +317,16 @@ static const struct regmap_irq_chip s2mps11_irq_chip = { | |||
| 246 | .ack_base = S2MPS11_REG_INT1, | 317 | .ack_base = S2MPS11_REG_INT1, |
| 247 | }; | 318 | }; |
| 248 | 319 | ||
| 320 | static const struct regmap_irq_chip s2mps14_irq_chip = { | ||
| 321 | .name = "s2mps14", | ||
| 322 | .irqs = s2mps14_irqs, | ||
| 323 | .num_irqs = ARRAY_SIZE(s2mps14_irqs), | ||
| 324 | .num_regs = 3, | ||
| 325 | .status_base = S2MPS14_REG_INT1, | ||
| 326 | .mask_base = S2MPS14_REG_INT1M, | ||
| 327 | .ack_base = S2MPS14_REG_INT1, | ||
| 328 | }; | ||
| 329 | |||
| 249 | static const struct regmap_irq_chip s5m8767_irq_chip = { | 330 | static const struct regmap_irq_chip s5m8767_irq_chip = { |
| 250 | .name = "s5m8767", | 331 | .name = "s5m8767", |
| 251 | .irqs = s5m8767_irqs, | 332 | .irqs = s5m8767_irqs, |
| @@ -297,6 +378,12 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) | |||
| 297 | sec_pmic->irq_base, &s2mps11_irq_chip, | 378 | sec_pmic->irq_base, &s2mps11_irq_chip, |
| 298 | &sec_pmic->irq_data); | 379 | &sec_pmic->irq_data); |
| 299 | break; | 380 | break; |
| 381 | case S2MPS14X: | ||
| 382 | ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, | ||
| 383 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
| 384 | sec_pmic->irq_base, &s2mps14_irq_chip, | ||
| 385 | &sec_pmic->irq_data); | ||
| 386 | break; | ||
| 300 | default: | 387 | default: |
| 301 | dev_err(sec_pmic->dev, "Unknown device type %d\n", | 388 | dev_err(sec_pmic->dev, "Unknown device type %d\n", |
| 302 | sec_pmic->device_type); | 389 | sec_pmic->device_type); |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 89e888a78899..1b95a405628f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -904,6 +904,38 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
| 904 | EXPORT_SYMBOL(of_find_node_by_phandle); | 904 | EXPORT_SYMBOL(of_find_node_by_phandle); |
| 905 | 905 | ||
| 906 | /** | 906 | /** |
| 907 | * of_property_count_elems_of_size - Count the number of elements in a property | ||
| 908 | * | ||
| 909 | * @np: device node from which the property value is to be read. | ||
| 910 | * @propname: name of the property to be searched. | ||
| 911 | * @elem_size: size of the individual element | ||
| 912 | * | ||
| 913 | * Search for a property in a device node and count the number of elements of | ||
| 914 | * size elem_size in it. Returns number of elements on sucess, -EINVAL if the | ||
| 915 | * property does not exist or its length does not match a multiple of elem_size | ||
| 916 | * and -ENODATA if the property does not have a value. | ||
| 917 | */ | ||
| 918 | int of_property_count_elems_of_size(const struct device_node *np, | ||
| 919 | const char *propname, int elem_size) | ||
| 920 | { | ||
| 921 | struct property *prop = of_find_property(np, propname, NULL); | ||
| 922 | |||
| 923 | if (!prop) | ||
| 924 | return -EINVAL; | ||
| 925 | if (!prop->value) | ||
| 926 | return -ENODATA; | ||
| 927 | |||
| 928 | if (prop->length % elem_size != 0) { | ||
| 929 | pr_err("size of %s in node %s is not a multiple of %d\n", | ||
| 930 | propname, np->full_name, elem_size); | ||
| 931 | return -EINVAL; | ||
| 932 | } | ||
| 933 | |||
| 934 | return prop->length / elem_size; | ||
| 935 | } | ||
| 936 | EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); | ||
| 937 | |||
| 938 | /** | ||
| 907 | * of_find_property_value_of_size | 939 | * of_find_property_value_of_size |
| 908 | * | 940 | * |
| 909 | * @np: device node from which the property value is to be read. | 941 | * @np: device node from which the property value is to be read. |
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index d333f7eac106..7a721d67e6ac 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c | |||
| @@ -310,10 +310,8 @@ static int pm800_regulator_probe(struct platform_device *pdev) | |||
| 310 | 310 | ||
| 311 | pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), | 311 | pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), |
| 312 | GFP_KERNEL); | 312 | GFP_KERNEL); |
| 313 | if (!pm800_data) { | 313 | if (!pm800_data) |
| 314 | dev_err(&pdev->dev, "Failed to allocate pm800_regualtors"); | ||
| 315 | return -ENOMEM; | 314 | return -ENOMEM; |
| 316 | } | ||
| 317 | 315 | ||
| 318 | pm800_data->map = chip->subchip->regmap_power; | 316 | pm800_data->map = chip->subchip->regmap_power; |
| 319 | pm800_data->chip = chip; | 317 | pm800_data->chip = chip; |
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index f704d83c93c4..337634ad0562 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Regulators driver for Marvell 88PM8607 | 2 | * Regulators driver for Marvell 88PM8607 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Marvell International Ltd. | 4 | * Copyright (C) 2009 Marvell International Ltd. |
| 5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | 5 | * Haojian Zhuang <haojian.zhuang@marvell.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -78,7 +78,7 @@ static const unsigned int BUCK2_suspend_table[] = { | |||
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | static const unsigned int BUCK3_table[] = { | 80 | static const unsigned int BUCK3_table[] = { |
| 81 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, | 81 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, |
| 82 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, | 82 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, |
| 83 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, | 83 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, |
| 84 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, | 84 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, |
| @@ -89,7 +89,7 @@ static const unsigned int BUCK3_table[] = { | |||
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | static const unsigned int BUCK3_suspend_table[] = { | 91 | static const unsigned int BUCK3_suspend_table[] = { |
| 92 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, | 92 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, |
| 93 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, | 93 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, |
| 94 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, | 94 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, |
| 95 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, | 95 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, |
| @@ -322,7 +322,7 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev, | |||
| 322 | nproot = of_node_get(pdev->dev.parent->of_node); | 322 | nproot = of_node_get(pdev->dev.parent->of_node); |
| 323 | if (!nproot) | 323 | if (!nproot) |
| 324 | return -ENODEV; | 324 | return -ENODEV; |
| 325 | nproot = of_find_node_by_name(nproot, "regulators"); | 325 | nproot = of_get_child_by_name(nproot, "regulators"); |
| 326 | if (!nproot) { | 326 | if (!nproot) { |
| 327 | dev_err(&pdev->dev, "failed to find regulators node\n"); | 327 | dev_err(&pdev->dev, "failed to find regulators node\n"); |
| 328 | return -ENODEV; | 328 | return -ENODEV; |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 6a7932822e37..1cd8584a7b88 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -139,6 +139,14 @@ config REGULATOR_AS3722 | |||
| 139 | AS3722 PMIC. This will enable support for all the software | 139 | AS3722 PMIC. This will enable support for all the software |
| 140 | controllable DCDC/LDO regulators. | 140 | controllable DCDC/LDO regulators. |
| 141 | 141 | ||
| 142 | config REGULATOR_BCM590XX | ||
| 143 | tristate "Broadcom BCM590xx PMU Regulators" | ||
| 144 | depends on MFD_BCM590XX | ||
| 145 | help | ||
| 146 | This driver provides support for the voltage regulators on the | ||
| 147 | BCM590xx PMUs. This will enable support for the software | ||
| 148 | controllable LDO/Switching regulators. | ||
| 149 | |||
| 142 | config REGULATOR_DA903X | 150 | config REGULATOR_DA903X |
| 143 | tristate "Dialog Semiconductor DA9030/DA9034 regulators" | 151 | tristate "Dialog Semiconductor DA9030/DA9034 regulators" |
| 144 | depends on PMIC_DA903X | 152 | depends on PMIC_DA903X |
| @@ -399,12 +407,12 @@ config REGULATOR_PCF50633 | |||
| 399 | on PCF50633 | 407 | on PCF50633 |
| 400 | 408 | ||
| 401 | config REGULATOR_PFUZE100 | 409 | config REGULATOR_PFUZE100 |
| 402 | tristate "Freescale PFUZE100 regulator driver" | 410 | tristate "Freescale PFUZE100/PFUZE200 regulator driver" |
| 403 | depends on I2C | 411 | depends on I2C |
| 404 | select REGMAP_I2C | 412 | select REGMAP_I2C |
| 405 | help | 413 | help |
| 406 | Say y here to support the regulators found on the Freescale PFUZE100 | 414 | Say y here to support the regulators found on the Freescale |
| 407 | PMIC. | 415 | PFUZE100/PFUZE200 PMIC. |
| 408 | 416 | ||
| 409 | config REGULATOR_RC5T583 | 417 | config REGULATOR_RC5T583 |
| 410 | tristate "RICOH RC5T583 Power regulators" | 418 | tristate "RICOH RC5T583 Power regulators" |
| @@ -416,13 +424,21 @@ config REGULATOR_RC5T583 | |||
| 416 | through regulator interface. The device supports multiple DCDC/LDO | 424 | through regulator interface. The device supports multiple DCDC/LDO |
| 417 | outputs which can be controlled by i2c communication. | 425 | outputs which can be controlled by i2c communication. |
| 418 | 426 | ||
| 427 | config REGULATOR_S2MPA01 | ||
| 428 | tristate "Samsung S2MPA01 voltage regulator" | ||
| 429 | depends on MFD_SEC_CORE | ||
| 430 | help | ||
| 431 | This driver controls Samsung S2MPA01 voltage output regulator | ||
| 432 | via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. | ||
| 433 | |||
| 419 | config REGULATOR_S2MPS11 | 434 | config REGULATOR_S2MPS11 |
| 420 | tristate "Samsung S2MPS11 voltage regulator" | 435 | tristate "Samsung S2MPS11/S2MPS14 voltage regulator" |
| 421 | depends on MFD_SEC_CORE | 436 | depends on MFD_SEC_CORE |
| 422 | help | 437 | help |
| 423 | This driver supports a Samsung S2MPS11 voltage output regulator | 438 | This driver supports a Samsung S2MPS11/S2MPS14 voltage output |
| 424 | via I2C bus. S2MPS11 is comprised of high efficient Buck converters | 439 | regulator via I2C bus. The chip is comprised of high efficient Buck |
| 425 | including Dual-Phase Buck converter, Buck-Boost converter, various LDOs. | 440 | converters including Dual-Phase Buck converter, Buck-Boost converter, |
| 441 | various LDOs. | ||
| 426 | 442 | ||
| 427 | config REGULATOR_S5M8767 | 443 | config REGULATOR_S5M8767 |
| 428 | tristate "Samsung S5M8767A voltage regulator" | 444 | tristate "Samsung S5M8767A voltage regulator" |
| @@ -432,6 +448,12 @@ config REGULATOR_S5M8767 | |||
| 432 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and | 448 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and |
| 433 | supports DVS mode with 8bits of output voltage control. | 449 | supports DVS mode with 8bits of output voltage control. |
| 434 | 450 | ||
| 451 | config REGULATOR_ST_PWM | ||
| 452 | tristate "STMicroelectronics PWM voltage regulator" | ||
| 453 | depends on ARCH_STI | ||
| 454 | help | ||
| 455 | This driver supports ST's PWM controlled voltage regulators. | ||
| 456 | |||
| 435 | config REGULATOR_TI_ABB | 457 | config REGULATOR_TI_ABB |
| 436 | tristate "TI Adaptive Body Bias on-chip LDO" | 458 | tristate "TI Adaptive Body Bias on-chip LDO" |
| 437 | depends on ARCH_OMAP | 459 | depends on ARCH_OMAP |
| @@ -513,6 +535,15 @@ config REGULATOR_TPS65217 | |||
| 513 | voltage regulators. It supports software based voltage control | 535 | voltage regulators. It supports software based voltage control |
| 514 | for different voltage domains | 536 | for different voltage domains |
| 515 | 537 | ||
| 538 | config REGULATOR_TPS65218 | ||
| 539 | tristate "TI TPS65218 Power regulators" | ||
| 540 | depends on MFD_TPS65218 && OF | ||
| 541 | help | ||
| 542 | This driver supports TPS65218 voltage regulator chips. TPS65218 | ||
| 543 | provides six step-down converters and one general-purpose LDO | ||
| 544 | voltage regulators. It supports software based voltage control | ||
| 545 | for different voltage domains | ||
| 546 | |||
| 516 | config REGULATOR_TPS6524X | 547 | config REGULATOR_TPS6524X |
| 517 | tristate "TI TPS6524X Power regulators" | 548 | tristate "TI TPS6524X Power regulators" |
| 518 | depends on SPI | 549 | depends on SPI |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 979f9ddcf259..f0fe0c50b59c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
| @@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o | |||
| 20 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o | 20 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o |
| 21 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o | 21 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o |
| 22 | obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o | 22 | obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o |
| 23 | obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o | ||
| 23 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | 24 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o |
| 24 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | 25 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o |
| 25 | obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o | 26 | obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o |
| @@ -57,8 +58,10 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o | |||
| 57 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 58 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
| 58 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 59 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
| 59 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 60 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
| 61 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o | ||
| 60 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o | 62 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o |
| 61 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o | 63 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o |
| 64 | obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o | ||
| 62 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o | 65 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o |
| 63 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o | 66 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o |
| 64 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o | 67 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o |
| @@ -67,6 +70,7 @@ obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o | |||
| 67 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o | 70 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o |
| 68 | obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o | 71 | obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o |
| 69 | obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o | 72 | obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o |
| 73 | obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o | ||
| 70 | obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o | 74 | obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o |
| 71 | obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o | 75 | obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o |
| 72 | obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o | 76 | obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o |
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index f70a9bfa5ff2..c873ee0082cf 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c | |||
| @@ -99,6 +99,7 @@ static int aat2870_ldo_is_enabled(struct regulator_dev *rdev) | |||
| 99 | 99 | ||
| 100 | static struct regulator_ops aat2870_ldo_ops = { | 100 | static struct regulator_ops aat2870_ldo_ops = { |
| 101 | .list_voltage = regulator_list_voltage_table, | 101 | .list_voltage = regulator_list_voltage_table, |
| 102 | .map_voltage = regulator_map_voltage_ascend, | ||
| 102 | .set_voltage_sel = aat2870_ldo_set_voltage_sel, | 103 | .set_voltage_sel = aat2870_ldo_set_voltage_sel, |
| 103 | .get_voltage_sel = aat2870_ldo_get_voltage_sel, | 104 | .get_voltage_sel = aat2870_ldo_get_voltage_sel, |
| 104 | .enable = aat2870_ldo_enable, | 105 | .enable = aat2870_ldo_enable, |
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 084cc0819a52..b92d7dd01a18 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c | |||
| @@ -62,7 +62,6 @@ | |||
| 62 | #define ACT8865_VOLTAGE_NUM 64 | 62 | #define ACT8865_VOLTAGE_NUM 64 |
| 63 | 63 | ||
| 64 | struct act8865 { | 64 | struct act8865 { |
| 65 | struct regulator_dev *rdev[ACT8865_REG_NUM]; | ||
| 66 | struct regmap *regmap; | 65 | struct regmap *regmap; |
| 67 | }; | 66 | }; |
| 68 | 67 | ||
| @@ -213,7 +212,7 @@ static int act8865_pdata_from_dt(struct device *dev, | |||
| 213 | struct device_node *np; | 212 | struct device_node *np; |
| 214 | struct act8865_regulator_data *regulator; | 213 | struct act8865_regulator_data *regulator; |
| 215 | 214 | ||
| 216 | np = of_find_node_by_name(dev->of_node, "regulators"); | 215 | np = of_get_child_by_name(dev->of_node, "regulators"); |
| 217 | if (!np) { | 216 | if (!np) { |
| 218 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | 217 | dev_err(dev, "missing 'regulators' subnode in DT\n"); |
| 219 | return -EINVAL; | 218 | return -EINVAL; |
| @@ -221,17 +220,15 @@ static int act8865_pdata_from_dt(struct device *dev, | |||
| 221 | 220 | ||
| 222 | matched = of_regulator_match(dev, np, | 221 | matched = of_regulator_match(dev, np, |
| 223 | act8865_matches, ARRAY_SIZE(act8865_matches)); | 222 | act8865_matches, ARRAY_SIZE(act8865_matches)); |
| 223 | of_node_put(np); | ||
| 224 | if (matched <= 0) | 224 | if (matched <= 0) |
| 225 | return matched; | 225 | return matched; |
| 226 | 226 | ||
| 227 | pdata->regulators = devm_kzalloc(dev, | 227 | pdata->regulators = devm_kzalloc(dev, |
| 228 | sizeof(struct act8865_regulator_data) * | 228 | sizeof(struct act8865_regulator_data) * |
| 229 | ARRAY_SIZE(act8865_matches), GFP_KERNEL); | 229 | ARRAY_SIZE(act8865_matches), GFP_KERNEL); |
| 230 | if (!pdata->regulators) { | 230 | if (!pdata->regulators) |
| 231 | dev_err(dev, "%s: failed to allocate act8865 registor\n", | ||
| 232 | __func__); | ||
| 233 | return -ENOMEM; | 231 | return -ENOMEM; |
| 234 | } | ||
| 235 | 232 | ||
| 236 | pdata->num_regulators = matched; | 233 | pdata->num_regulators = matched; |
| 237 | regulator = pdata->regulators; | 234 | regulator = pdata->regulators; |
| @@ -258,7 +255,7 @@ static inline int act8865_pdata_from_dt(struct device *dev, | |||
| 258 | static int act8865_pmic_probe(struct i2c_client *client, | 255 | static int act8865_pmic_probe(struct i2c_client *client, |
| 259 | const struct i2c_device_id *i2c_id) | 256 | const struct i2c_device_id *i2c_id) |
| 260 | { | 257 | { |
| 261 | struct regulator_dev **rdev; | 258 | struct regulator_dev *rdev; |
| 262 | struct device *dev = &client->dev; | 259 | struct device *dev = &client->dev; |
| 263 | struct act8865_platform_data *pdata = dev_get_platdata(dev); | 260 | struct act8865_platform_data *pdata = dev_get_platdata(dev); |
| 264 | struct regulator_config config = { }; | 261 | struct regulator_config config = { }; |
| @@ -292,8 +289,6 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
| 292 | if (!act8865) | 289 | if (!act8865) |
| 293 | return -ENOMEM; | 290 | return -ENOMEM; |
| 294 | 291 | ||
| 295 | rdev = act8865->rdev; | ||
| 296 | |||
| 297 | act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); | 292 | act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); |
| 298 | if (IS_ERR(act8865->regmap)) { | 293 | if (IS_ERR(act8865->regmap)) { |
| 299 | error = PTR_ERR(act8865->regmap); | 294 | error = PTR_ERR(act8865->regmap); |
| @@ -313,12 +308,12 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
| 313 | config.driver_data = act8865; | 308 | config.driver_data = act8865; |
| 314 | config.regmap = act8865->regmap; | 309 | config.regmap = act8865->regmap; |
| 315 | 310 | ||
| 316 | rdev[i] = devm_regulator_register(&client->dev, | 311 | rdev = devm_regulator_register(&client->dev, &act8865_reg[i], |
| 317 | &act8865_reg[i], &config); | 312 | &config); |
| 318 | if (IS_ERR(rdev[i])) { | 313 | if (IS_ERR(rdev)) { |
| 319 | dev_err(dev, "failed to register %s\n", | 314 | dev_err(dev, "failed to register %s\n", |
| 320 | act8865_reg[id].name); | 315 | act8865_reg[id].name); |
| 321 | return PTR_ERR(rdev[i]); | 316 | return PTR_ERR(rdev); |
| 322 | } | 317 | } |
| 323 | } | 318 | } |
| 324 | 319 | ||
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 862e63e451d0..7c397bb81e01 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
| @@ -34,6 +34,9 @@ | |||
| 34 | #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ | 34 | #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ |
| 35 | #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ | 35 | #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ |
| 36 | 36 | ||
| 37 | #define LDO_POWER_GATE 0x00 | ||
| 38 | #define LDO_FET_FULL_ON 0x1f | ||
| 39 | |||
| 37 | struct anatop_regulator { | 40 | struct anatop_regulator { |
| 38 | const char *name; | 41 | const char *name; |
| 39 | u32 control_reg; | 42 | u32 control_reg; |
| @@ -48,19 +51,10 @@ struct anatop_regulator { | |||
| 48 | int max_voltage; | 51 | int max_voltage; |
| 49 | struct regulator_desc rdesc; | 52 | struct regulator_desc rdesc; |
| 50 | struct regulator_init_data *initdata; | 53 | struct regulator_init_data *initdata; |
| 54 | bool bypass; | ||
| 55 | int sel; | ||
| 51 | }; | 56 | }; |
| 52 | 57 | ||
| 53 | static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, | ||
| 54 | unsigned selector) | ||
| 55 | { | ||
| 56 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 57 | |||
| 58 | if (!anatop_reg->control_reg) | ||
| 59 | return -ENOTSUPP; | ||
| 60 | |||
| 61 | return regulator_set_voltage_sel_regmap(reg, selector); | ||
| 62 | } | ||
| 63 | |||
| 64 | static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, | 58 | static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, |
| 65 | unsigned int old_sel, | 59 | unsigned int old_sel, |
| 66 | unsigned int new_sel) | 60 | unsigned int new_sel) |
| @@ -87,22 +81,99 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, | |||
| 87 | return ret; | 81 | return ret; |
| 88 | } | 82 | } |
| 89 | 83 | ||
| 90 | static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) | 84 | static int anatop_regmap_enable(struct regulator_dev *reg) |
| 91 | { | 85 | { |
| 92 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 86 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
| 87 | int sel; | ||
| 93 | 88 | ||
| 94 | if (!anatop_reg->control_reg) | 89 | sel = anatop_reg->bypass ? LDO_FET_FULL_ON : anatop_reg->sel; |
| 95 | return -ENOTSUPP; | 90 | return regulator_set_voltage_sel_regmap(reg, sel); |
| 91 | } | ||
| 92 | |||
| 93 | static int anatop_regmap_disable(struct regulator_dev *reg) | ||
| 94 | { | ||
| 95 | return regulator_set_voltage_sel_regmap(reg, LDO_POWER_GATE); | ||
| 96 | } | ||
| 97 | |||
| 98 | static int anatop_regmap_is_enabled(struct regulator_dev *reg) | ||
| 99 | { | ||
| 100 | return regulator_get_voltage_sel_regmap(reg) != LDO_POWER_GATE; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int anatop_regmap_core_set_voltage_sel(struct regulator_dev *reg, | ||
| 104 | unsigned selector) | ||
| 105 | { | ||
| 106 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 107 | int ret; | ||
| 108 | |||
| 109 | if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) { | ||
| 110 | anatop_reg->sel = selector; | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | ret = regulator_set_voltage_sel_regmap(reg, selector); | ||
| 115 | if (!ret) | ||
| 116 | anatop_reg->sel = selector; | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int anatop_regmap_core_get_voltage_sel(struct regulator_dev *reg) | ||
| 121 | { | ||
| 122 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 123 | |||
| 124 | if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) | ||
| 125 | return anatop_reg->sel; | ||
| 96 | 126 | ||
| 97 | return regulator_get_voltage_sel_regmap(reg); | 127 | return regulator_get_voltage_sel_regmap(reg); |
| 98 | } | 128 | } |
| 99 | 129 | ||
| 130 | static int anatop_regmap_get_bypass(struct regulator_dev *reg, bool *enable) | ||
| 131 | { | ||
| 132 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 133 | int sel; | ||
| 134 | |||
| 135 | sel = regulator_get_voltage_sel_regmap(reg); | ||
| 136 | if (sel == LDO_FET_FULL_ON) | ||
| 137 | WARN_ON(!anatop_reg->bypass); | ||
| 138 | else if (sel != LDO_POWER_GATE) | ||
| 139 | WARN_ON(anatop_reg->bypass); | ||
| 140 | |||
| 141 | *enable = anatop_reg->bypass; | ||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int anatop_regmap_set_bypass(struct regulator_dev *reg, bool enable) | ||
| 146 | { | ||
| 147 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 148 | int sel; | ||
| 149 | |||
| 150 | if (enable == anatop_reg->bypass) | ||
| 151 | return 0; | ||
| 152 | |||
| 153 | sel = enable ? LDO_FET_FULL_ON : anatop_reg->sel; | ||
| 154 | anatop_reg->bypass = enable; | ||
| 155 | |||
| 156 | return regulator_set_voltage_sel_regmap(reg, sel); | ||
| 157 | } | ||
| 158 | |||
| 100 | static struct regulator_ops anatop_rops = { | 159 | static struct regulator_ops anatop_rops = { |
| 101 | .set_voltage_sel = anatop_regmap_set_voltage_sel, | 160 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 161 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 162 | .list_voltage = regulator_list_voltage_linear, | ||
| 163 | .map_voltage = regulator_map_voltage_linear, | ||
| 164 | }; | ||
| 165 | |||
| 166 | static struct regulator_ops anatop_core_rops = { | ||
| 167 | .enable = anatop_regmap_enable, | ||
| 168 | .disable = anatop_regmap_disable, | ||
| 169 | .is_enabled = anatop_regmap_is_enabled, | ||
| 170 | .set_voltage_sel = anatop_regmap_core_set_voltage_sel, | ||
| 102 | .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel, | 171 | .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel, |
| 103 | .get_voltage_sel = anatop_regmap_get_voltage_sel, | 172 | .get_voltage_sel = anatop_regmap_core_get_voltage_sel, |
| 104 | .list_voltage = regulator_list_voltage_linear, | 173 | .list_voltage = regulator_list_voltage_linear, |
| 105 | .map_voltage = regulator_map_voltage_linear, | 174 | .map_voltage = regulator_map_voltage_linear, |
| 175 | .get_bypass = anatop_regmap_get_bypass, | ||
| 176 | .set_bypass = anatop_regmap_set_bypass, | ||
| 106 | }; | 177 | }; |
| 107 | 178 | ||
| 108 | static int anatop_regulator_probe(struct platform_device *pdev) | 179 | static int anatop_regulator_probe(struct platform_device *pdev) |
| @@ -116,6 +187,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
| 116 | struct regulator_init_data *initdata; | 187 | struct regulator_init_data *initdata; |
| 117 | struct regulator_config config = { }; | 188 | struct regulator_config config = { }; |
| 118 | int ret = 0; | 189 | int ret = 0; |
| 190 | u32 val; | ||
| 119 | 191 | ||
| 120 | initdata = of_get_regulator_init_data(dev, np); | 192 | initdata = of_get_regulator_init_data(dev, np); |
| 121 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); | 193 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); |
| @@ -125,7 +197,6 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
| 125 | sreg->name = of_get_property(np, "regulator-name", NULL); | 197 | sreg->name = of_get_property(np, "regulator-name", NULL); |
| 126 | rdesc = &sreg->rdesc; | 198 | rdesc = &sreg->rdesc; |
| 127 | rdesc->name = sreg->name; | 199 | rdesc->name = sreg->name; |
| 128 | rdesc->ops = &anatop_rops; | ||
| 129 | rdesc->type = REGULATOR_VOLTAGE; | 200 | rdesc->type = REGULATOR_VOLTAGE; |
| 130 | rdesc->owner = THIS_MODULE; | 201 | rdesc->owner = THIS_MODULE; |
| 131 | 202 | ||
| @@ -197,6 +268,25 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
| 197 | config.of_node = pdev->dev.of_node; | 268 | config.of_node = pdev->dev.of_node; |
| 198 | config.regmap = sreg->anatop; | 269 | config.regmap = sreg->anatop; |
| 199 | 270 | ||
| 271 | /* Only core regulators have the ramp up delay configuration. */ | ||
| 272 | if (sreg->control_reg && sreg->delay_bit_width) { | ||
| 273 | rdesc->ops = &anatop_core_rops; | ||
| 274 | |||
| 275 | ret = regmap_read(config.regmap, rdesc->vsel_reg, &val); | ||
| 276 | if (ret) { | ||
| 277 | dev_err(dev, "failed to read initial state\n"); | ||
| 278 | return ret; | ||
| 279 | } | ||
| 280 | |||
| 281 | sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift; | ||
| 282 | if (sreg->sel == LDO_FET_FULL_ON) { | ||
| 283 | sreg->sel = 0; | ||
| 284 | sreg->bypass = true; | ||
| 285 | } | ||
| 286 | } else { | ||
| 287 | rdesc->ops = &anatop_rops; | ||
| 288 | } | ||
| 289 | |||
| 200 | /* register regulator */ | 290 | /* register regulator */ |
| 201 | rdev = devm_regulator_register(dev, rdesc, &config); | 291 | rdev = devm_regulator_register(dev, rdesc, &config); |
| 202 | if (IS_ERR(rdev)) { | 292 | if (IS_ERR(rdev)) { |
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 4f6c2055f6b2..b1033d30b504 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
| @@ -153,11 +153,9 @@ static const struct regulator_desc arizona_ldo1 = { | |||
| 153 | 153 | ||
| 154 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, | 154 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, |
| 155 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, | 155 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, |
| 156 | .bypass_reg = ARIZONA_LDO1_CONTROL_1, | ||
| 157 | .bypass_mask = ARIZONA_LDO1_BYPASS, | ||
| 158 | .min_uV = 900000, | 156 | .min_uV = 900000, |
| 159 | .uV_step = 50000, | 157 | .uV_step = 25000, |
| 160 | .n_voltages = 7, | 158 | .n_voltages = 13, |
| 161 | .enable_time = 500, | 159 | .enable_time = 500, |
| 162 | 160 | ||
| 163 | .owner = THIS_MODULE, | 161 | .owner = THIS_MODULE, |
| @@ -189,10 +187,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
| 189 | int ret; | 187 | int ret; |
| 190 | 188 | ||
| 191 | ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); | 189 | ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); |
| 192 | if (ldo1 == NULL) { | 190 | if (!ldo1) |
| 193 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 194 | return -ENOMEM; | 191 | return -ENOMEM; |
| 195 | } | ||
| 196 | 192 | ||
| 197 | ldo1->arizona = arizona; | 193 | ldo1->arizona = arizona; |
| 198 | 194 | ||
| @@ -203,6 +199,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
| 203 | */ | 199 | */ |
| 204 | switch (arizona->type) { | 200 | switch (arizona->type) { |
| 205 | case WM5102: | 201 | case WM5102: |
| 202 | case WM8997: | ||
| 206 | desc = &arizona_ldo1_hc; | 203 | desc = &arizona_ldo1_hc; |
| 207 | ldo1->init_data = arizona_ldo1_dvfs; | 204 | ldo1->init_data = arizona_ldo1_dvfs; |
| 208 | break; | 205 | break; |
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 034ece707083..6fdd9bf6927f 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c | |||
| @@ -204,10 +204,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev) | |||
| 204 | int ret; | 204 | int ret; |
| 205 | 205 | ||
| 206 | micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); | 206 | micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); |
| 207 | if (micsupp == NULL) { | 207 | if (!micsupp) |
| 208 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 209 | return -ENOMEM; | 208 | return -ENOMEM; |
| 210 | } | ||
| 211 | 209 | ||
| 212 | micsupp->arizona = arizona; | 210 | micsupp->arizona = arizona; |
| 213 | INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); | 211 | INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); |
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index c77a58478cca..b47283f91e2d 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c | |||
| @@ -191,7 +191,7 @@ static int as3711_regulator_parse_dt(struct device *dev, | |||
| 191 | { | 191 | { |
| 192 | struct as3711_regulator_pdata *pdata = dev_get_platdata(dev); | 192 | struct as3711_regulator_pdata *pdata = dev_get_platdata(dev); |
| 193 | struct device_node *regulators = | 193 | struct device_node *regulators = |
| 194 | of_find_node_by_name(dev->parent->of_node, "regulators"); | 194 | of_get_child_by_name(dev->parent->of_node, "regulators"); |
| 195 | struct of_regulator_match *match; | 195 | struct of_regulator_match *match; |
| 196 | int ret, i; | 196 | int ret, i; |
| 197 | 197 | ||
| @@ -221,7 +221,6 @@ static int as3711_regulator_probe(struct platform_device *pdev) | |||
| 221 | { | 221 | { |
| 222 | struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); | 222 | struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); |
| 223 | struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); | 223 | struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); |
| 224 | struct regulator_init_data *reg_data; | ||
| 225 | struct regulator_config config = {.dev = &pdev->dev,}; | 224 | struct regulator_config config = {.dev = &pdev->dev,}; |
| 226 | struct as3711_regulator *reg = NULL; | 225 | struct as3711_regulator *reg = NULL; |
| 227 | struct as3711_regulator *regs; | 226 | struct as3711_regulator *regs; |
| @@ -246,22 +245,14 @@ static int as3711_regulator_probe(struct platform_device *pdev) | |||
| 246 | 245 | ||
| 247 | regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * | 246 | regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * |
| 248 | sizeof(struct as3711_regulator), GFP_KERNEL); | 247 | sizeof(struct as3711_regulator), GFP_KERNEL); |
| 249 | if (!regs) { | 248 | if (!regs) |
| 250 | dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); | ||
| 251 | return -ENOMEM; | 249 | return -ENOMEM; |
| 252 | } | ||
| 253 | 250 | ||
| 254 | for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { | 251 | for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { |
| 255 | reg_data = pdata->init_data[id]; | ||
| 256 | |||
| 257 | /* No need to register if there is no regulator data */ | ||
| 258 | if (!reg_data) | ||
| 259 | continue; | ||
| 260 | |||
| 261 | reg = ®s[id]; | 252 | reg = ®s[id]; |
| 262 | reg->reg_info = ri; | 253 | reg->reg_info = ri; |
| 263 | 254 | ||
| 264 | config.init_data = reg_data; | 255 | config.init_data = pdata->init_data[id]; |
| 265 | config.driver_data = reg; | 256 | config.driver_data = reg; |
| 266 | config.regmap = as3711->regmap; | 257 | config.regmap = as3711->regmap; |
| 267 | config.of_node = of_node[id]; | 258 | config.of_node = of_node[id]; |
diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 8b17d786cb71..85585219ce82 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c | |||
| @@ -719,6 +719,7 @@ static int as3722_get_regulator_dt_data(struct platform_device *pdev, | |||
| 719 | 719 | ||
| 720 | ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches, | 720 | ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches, |
| 721 | ARRAY_SIZE(as3722_regulator_matches)); | 721 | ARRAY_SIZE(as3722_regulator_matches)); |
| 722 | of_node_put(np); | ||
| 722 | if (ret < 0) { | 723 | if (ret < 0) { |
| 723 | dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n", | 724 | dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n", |
| 724 | ret); | 725 | ret); |
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c new file mode 100644 index 000000000000..ab08ca7cfb08 --- /dev/null +++ b/drivers/regulator/bcm590xx-regulator.c | |||
| @@ -0,0 +1,403 @@ | |||
| 1 | /* | ||
| 2 | * Broadcom BCM590xx regulator driver | ||
| 3 | * | ||
| 4 | * Copyright 2014 Linaro Limited | ||
| 5 | * Author: Matt Porter <mporter@linaro.org> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/mfd/bcm590xx.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/regulator/driver.h> | ||
| 21 | #include <linux/regulator/machine.h> | ||
| 22 | #include <linux/regulator/of_regulator.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | |||
| 25 | /* Register defs */ | ||
| 26 | #define BCM590XX_RFLDOPMCTRL1 0x60 | ||
| 27 | #define BCM590XX_IOSR1PMCTRL1 0x7a | ||
| 28 | #define BCM590XX_IOSR2PMCTRL1 0x7c | ||
| 29 | #define BCM590XX_CSRPMCTRL1 0x7e | ||
| 30 | #define BCM590XX_SDSR1PMCTRL1 0x82 | ||
| 31 | #define BCM590XX_SDSR2PMCTRL1 0x86 | ||
| 32 | #define BCM590XX_MSRPMCTRL1 0x8a | ||
| 33 | #define BCM590XX_VSRPMCTRL1 0x8e | ||
| 34 | #define BCM590XX_REG_ENABLE BIT(7) | ||
| 35 | |||
| 36 | #define BCM590XX_RFLDOCTRL 0x96 | ||
| 37 | #define BCM590XX_CSRVOUT1 0xc0 | ||
| 38 | #define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3) | ||
| 39 | #define BCM590XX_SR_VSEL_MASK GENMASK(5, 0) | ||
| 40 | |||
| 41 | /* LDO regulator IDs */ | ||
| 42 | #define BCM590XX_REG_RFLDO 0 | ||
| 43 | #define BCM590XX_REG_CAMLDO1 1 | ||
| 44 | #define BCM590XX_REG_CAMLDO2 2 | ||
| 45 | #define BCM590XX_REG_SIMLDO1 3 | ||
| 46 | #define BCM590XX_REG_SIMLDO2 4 | ||
| 47 | #define BCM590XX_REG_SDLDO 5 | ||
| 48 | #define BCM590XX_REG_SDXLDO 6 | ||
| 49 | #define BCM590XX_REG_MMCLDO1 7 | ||
| 50 | #define BCM590XX_REG_MMCLDO2 8 | ||
| 51 | #define BCM590XX_REG_AUDLDO 9 | ||
| 52 | #define BCM590XX_REG_MICLDO 10 | ||
| 53 | #define BCM590XX_REG_USBLDO 11 | ||
| 54 | #define BCM590XX_REG_VIBLDO 12 | ||
| 55 | |||
| 56 | /* DCDC regulator IDs */ | ||
| 57 | #define BCM590XX_REG_CSR 13 | ||
| 58 | #define BCM590XX_REG_IOSR1 14 | ||
| 59 | #define BCM590XX_REG_IOSR2 15 | ||
| 60 | #define BCM590XX_REG_MSR 16 | ||
| 61 | #define BCM590XX_REG_SDSR1 17 | ||
| 62 | #define BCM590XX_REG_SDSR2 18 | ||
| 63 | #define BCM590XX_REG_VSR 19 | ||
| 64 | |||
| 65 | #define BCM590XX_NUM_REGS 20 | ||
| 66 | |||
| 67 | #define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR) | ||
| 68 | |||
| 69 | struct bcm590xx_board { | ||
| 70 | struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS]; | ||
| 71 | }; | ||
| 72 | |||
| 73 | /* LDO group A: supported voltages in microvolts */ | ||
| 74 | static const unsigned int ldo_a_table[] = { | ||
| 75 | 1200000, 1800000, 2500000, 2700000, 2800000, | ||
| 76 | 2900000, 3000000, 3300000, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* LDO group C: supported voltages in microvolts */ | ||
| 80 | static const unsigned int ldo_c_table[] = { | ||
| 81 | 3100000, 1800000, 2500000, 2700000, 2800000, | ||
| 82 | 2900000, 3000000, 3300000, | ||
| 83 | }; | ||
| 84 | |||
| 85 | /* DCDC group CSR: supported voltages in microvolts */ | ||
| 86 | static const struct regulator_linear_range dcdc_csr_ranges[] = { | ||
| 87 | REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), | ||
| 88 | REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000), | ||
| 89 | REGULATOR_LINEAR_RANGE(900000, 56, 63, 0), | ||
| 90 | }; | ||
| 91 | |||
| 92 | /* DCDC group IOSR1: supported voltages in microvolts */ | ||
| 93 | static const struct regulator_linear_range dcdc_iosr1_ranges[] = { | ||
| 94 | REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000), | ||
| 95 | REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0), | ||
| 96 | REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0), | ||
| 97 | REGULATOR_LINEAR_RANGE(900000, 54, 63, 0), | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* DCDC group SDSR1: supported voltages in microvolts */ | ||
| 101 | static const struct regulator_linear_range dcdc_sdsr1_ranges[] = { | ||
| 102 | REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), | ||
| 103 | REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0), | ||
| 104 | REGULATOR_LINEAR_RANGE(900000, 52, 63, 0), | ||
| 105 | }; | ||
| 106 | |||
| 107 | struct bcm590xx_info { | ||
| 108 | const char *name; | ||
| 109 | const char *vin_name; | ||
| 110 | u8 n_voltages; | ||
| 111 | const unsigned int *volt_table; | ||
| 112 | u8 n_linear_ranges; | ||
| 113 | const struct regulator_linear_range *linear_ranges; | ||
| 114 | }; | ||
| 115 | |||
| 116 | #define BCM590XX_REG_TABLE(_name, _table) \ | ||
| 117 | { \ | ||
| 118 | .name = #_name, \ | ||
| 119 | .n_voltages = ARRAY_SIZE(_table), \ | ||
| 120 | .volt_table = _table, \ | ||
| 121 | } | ||
| 122 | |||
| 123 | #define BCM590XX_REG_RANGES(_name, _ranges) \ | ||
| 124 | { \ | ||
| 125 | .name = #_name, \ | ||
| 126 | .n_linear_ranges = ARRAY_SIZE(_ranges), \ | ||
| 127 | .linear_ranges = _ranges, \ | ||
| 128 | } | ||
| 129 | |||
| 130 | static struct bcm590xx_info bcm590xx_regs[] = { | ||
| 131 | BCM590XX_REG_TABLE(rfldo, ldo_a_table), | ||
| 132 | BCM590XX_REG_TABLE(camldo1, ldo_c_table), | ||
| 133 | BCM590XX_REG_TABLE(camldo2, ldo_c_table), | ||
| 134 | BCM590XX_REG_TABLE(simldo1, ldo_a_table), | ||
| 135 | BCM590XX_REG_TABLE(simldo2, ldo_a_table), | ||
| 136 | BCM590XX_REG_TABLE(sdldo, ldo_c_table), | ||
| 137 | BCM590XX_REG_TABLE(sdxldo, ldo_a_table), | ||
| 138 | BCM590XX_REG_TABLE(mmcldo1, ldo_a_table), | ||
| 139 | BCM590XX_REG_TABLE(mmcldo2, ldo_a_table), | ||
| 140 | BCM590XX_REG_TABLE(audldo, ldo_a_table), | ||
| 141 | BCM590XX_REG_TABLE(micldo, ldo_a_table), | ||
| 142 | BCM590XX_REG_TABLE(usbldo, ldo_a_table), | ||
| 143 | BCM590XX_REG_TABLE(vibldo, ldo_c_table), | ||
| 144 | BCM590XX_REG_RANGES(csr, dcdc_csr_ranges), | ||
| 145 | BCM590XX_REG_RANGES(iosr1, dcdc_iosr1_ranges), | ||
| 146 | BCM590XX_REG_RANGES(iosr2, dcdc_iosr1_ranges), | ||
| 147 | BCM590XX_REG_RANGES(msr, dcdc_iosr1_ranges), | ||
| 148 | BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges), | ||
| 149 | BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges), | ||
| 150 | BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges), | ||
| 151 | }; | ||
| 152 | |||
| 153 | struct bcm590xx_reg { | ||
| 154 | struct regulator_desc *desc; | ||
| 155 | struct bcm590xx *mfd; | ||
| 156 | struct bcm590xx_info **info; | ||
| 157 | }; | ||
| 158 | |||
| 159 | static int bcm590xx_get_vsel_register(int id) | ||
| 160 | { | ||
| 161 | if (BCM590XX_REG_IS_LDO(id)) | ||
| 162 | return BCM590XX_RFLDOCTRL + id; | ||
| 163 | else | ||
| 164 | return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int bcm590xx_get_enable_register(int id) | ||
| 168 | { | ||
| 169 | int reg = 0; | ||
| 170 | |||
| 171 | if (BCM590XX_REG_IS_LDO(id)) | ||
| 172 | reg = BCM590XX_RFLDOPMCTRL1 + id * 2; | ||
| 173 | else | ||
| 174 | switch (id) { | ||
| 175 | case BCM590XX_REG_CSR: | ||
| 176 | reg = BCM590XX_CSRPMCTRL1; | ||
| 177 | break; | ||
| 178 | case BCM590XX_REG_IOSR1: | ||
| 179 | reg = BCM590XX_IOSR1PMCTRL1; | ||
| 180 | break; | ||
| 181 | case BCM590XX_REG_IOSR2: | ||
| 182 | reg = BCM590XX_IOSR2PMCTRL1; | ||
| 183 | break; | ||
| 184 | case BCM590XX_REG_MSR: | ||
| 185 | reg = BCM590XX_MSRPMCTRL1; | ||
| 186 | break; | ||
| 187 | case BCM590XX_REG_SDSR1: | ||
| 188 | reg = BCM590XX_SDSR1PMCTRL1; | ||
| 189 | break; | ||
| 190 | case BCM590XX_REG_SDSR2: | ||
| 191 | reg = BCM590XX_SDSR2PMCTRL1; | ||
| 192 | break; | ||
| 193 | }; | ||
| 194 | |||
| 195 | return reg; | ||
| 196 | } | ||
| 197 | |||
| 198 | static struct regulator_ops bcm590xx_ops_ldo = { | ||
| 199 | .is_enabled = regulator_is_enabled_regmap, | ||
| 200 | .enable = regulator_enable_regmap, | ||
| 201 | .disable = regulator_disable_regmap, | ||
| 202 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 203 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 204 | .list_voltage = regulator_list_voltage_table, | ||
| 205 | .map_voltage = regulator_map_voltage_iterate, | ||
| 206 | }; | ||
| 207 | |||
| 208 | static struct regulator_ops bcm590xx_ops_dcdc = { | ||
| 209 | .is_enabled = regulator_is_enabled_regmap, | ||
| 210 | .enable = regulator_enable_regmap, | ||
| 211 | .disable = regulator_disable_regmap, | ||
| 212 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 213 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 214 | .list_voltage = regulator_list_voltage_linear_range, | ||
| 215 | .map_voltage = regulator_map_voltage_linear_range, | ||
| 216 | }; | ||
| 217 | |||
| 218 | #define BCM590XX_MATCH(_name, _id) \ | ||
| 219 | { \ | ||
| 220 | .name = #_name, \ | ||
| 221 | .driver_data = (void *)&bcm590xx_regs[BCM590XX_REG_##_id], \ | ||
| 222 | } | ||
| 223 | |||
| 224 | static struct of_regulator_match bcm590xx_matches[] = { | ||
| 225 | BCM590XX_MATCH(rfldo, RFLDO), | ||
| 226 | BCM590XX_MATCH(camldo1, CAMLDO1), | ||
| 227 | BCM590XX_MATCH(camldo2, CAMLDO2), | ||
| 228 | BCM590XX_MATCH(simldo1, SIMLDO1), | ||
| 229 | BCM590XX_MATCH(simldo2, SIMLDO2), | ||
| 230 | BCM590XX_MATCH(sdldo, SDLDO), | ||
| 231 | BCM590XX_MATCH(sdxldo, SDXLDO), | ||
| 232 | BCM590XX_MATCH(mmcldo1, MMCLDO1), | ||
| 233 | BCM590XX_MATCH(mmcldo2, MMCLDO2), | ||
| 234 | BCM590XX_MATCH(audldo, AUDLDO), | ||
| 235 | BCM590XX_MATCH(micldo, MICLDO), | ||
| 236 | BCM590XX_MATCH(usbldo, USBLDO), | ||
| 237 | BCM590XX_MATCH(vibldo, VIBLDO), | ||
| 238 | BCM590XX_MATCH(csr, CSR), | ||
| 239 | BCM590XX_MATCH(iosr1, IOSR1), | ||
| 240 | BCM590XX_MATCH(iosr2, IOSR2), | ||
| 241 | BCM590XX_MATCH(msr, MSR), | ||
| 242 | BCM590XX_MATCH(sdsr1, SDSR1), | ||
| 243 | BCM590XX_MATCH(sdsr2, SDSR2), | ||
| 244 | BCM590XX_MATCH(vsr, VSR), | ||
| 245 | }; | ||
| 246 | |||
| 247 | static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( | ||
| 248 | struct platform_device *pdev, | ||
| 249 | struct of_regulator_match **bcm590xx_reg_matches) | ||
| 250 | { | ||
| 251 | struct bcm590xx_board *data; | ||
| 252 | struct device_node *np = pdev->dev.parent->of_node; | ||
| 253 | struct device_node *regulators; | ||
| 254 | struct of_regulator_match *matches = bcm590xx_matches; | ||
| 255 | int count = ARRAY_SIZE(bcm590xx_matches); | ||
| 256 | int idx = 0; | ||
| 257 | int ret; | ||
| 258 | |||
| 259 | if (!np) { | ||
| 260 | dev_err(&pdev->dev, "of node not found\n"); | ||
| 261 | return NULL; | ||
| 262 | } | ||
| 263 | |||
| 264 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
| 265 | if (!data) { | ||
| 266 | dev_err(&pdev->dev, "failed to allocate regulator board data\n"); | ||
| 267 | return NULL; | ||
| 268 | } | ||
| 269 | |||
| 270 | np = of_node_get(np); | ||
| 271 | regulators = of_get_child_by_name(np, "regulators"); | ||
| 272 | if (!regulators) { | ||
| 273 | dev_warn(&pdev->dev, "regulator node not found\n"); | ||
| 274 | return NULL; | ||
| 275 | } | ||
| 276 | |||
| 277 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); | ||
| 278 | of_node_put(regulators); | ||
| 279 | if (ret < 0) { | ||
| 280 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | ||
| 281 | ret); | ||
| 282 | return NULL; | ||
| 283 | } | ||
| 284 | |||
| 285 | *bcm590xx_reg_matches = matches; | ||
| 286 | |||
| 287 | for (idx = 0; idx < count; idx++) { | ||
| 288 | if (!matches[idx].init_data || !matches[idx].of_node) | ||
| 289 | continue; | ||
| 290 | |||
| 291 | data->bcm590xx_pmu_init_data[idx] = matches[idx].init_data; | ||
| 292 | } | ||
| 293 | |||
| 294 | return data; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int bcm590xx_probe(struct platform_device *pdev) | ||
| 298 | { | ||
| 299 | struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent); | ||
| 300 | struct bcm590xx_board *pmu_data = NULL; | ||
| 301 | struct bcm590xx_reg *pmu; | ||
| 302 | struct regulator_config config = { }; | ||
| 303 | struct bcm590xx_info *info; | ||
| 304 | struct regulator_init_data *reg_data; | ||
| 305 | struct regulator_dev *rdev; | ||
| 306 | struct of_regulator_match *bcm590xx_reg_matches = NULL; | ||
| 307 | int i; | ||
| 308 | |||
| 309 | pmu_data = bcm590xx_parse_dt_reg_data(pdev, | ||
| 310 | &bcm590xx_reg_matches); | ||
| 311 | |||
| 312 | pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); | ||
| 313 | if (!pmu) { | ||
| 314 | dev_err(&pdev->dev, "Memory allocation failed for pmu\n"); | ||
| 315 | return -ENOMEM; | ||
| 316 | } | ||
| 317 | |||
| 318 | pmu->mfd = bcm590xx; | ||
| 319 | |||
| 320 | platform_set_drvdata(pdev, pmu); | ||
| 321 | |||
| 322 | pmu->desc = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * | ||
| 323 | sizeof(struct regulator_desc), GFP_KERNEL); | ||
| 324 | if (!pmu->desc) { | ||
| 325 | dev_err(&pdev->dev, "Memory alloc fails for desc\n"); | ||
| 326 | return -ENOMEM; | ||
| 327 | } | ||
| 328 | |||
| 329 | pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * | ||
| 330 | sizeof(struct bcm590xx_info *), GFP_KERNEL); | ||
| 331 | if (!pmu->info) { | ||
| 332 | dev_err(&pdev->dev, "Memory alloc fails for info\n"); | ||
| 333 | return -ENOMEM; | ||
| 334 | } | ||
| 335 | |||
| 336 | info = bcm590xx_regs; | ||
| 337 | |||
| 338 | for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { | ||
| 339 | if (pmu_data) | ||
| 340 | reg_data = pmu_data->bcm590xx_pmu_init_data[i]; | ||
| 341 | else | ||
| 342 | reg_data = NULL; | ||
| 343 | |||
| 344 | /* Register the regulators */ | ||
| 345 | pmu->info[i] = info; | ||
| 346 | |||
| 347 | pmu->desc[i].name = info->name; | ||
| 348 | pmu->desc[i].supply_name = info->vin_name; | ||
| 349 | pmu->desc[i].id = i; | ||
| 350 | pmu->desc[i].volt_table = info->volt_table; | ||
| 351 | pmu->desc[i].n_voltages = info->n_voltages; | ||
| 352 | pmu->desc[i].linear_ranges = info->linear_ranges; | ||
| 353 | pmu->desc[i].n_linear_ranges = info->n_linear_ranges; | ||
| 354 | |||
| 355 | if (BCM590XX_REG_IS_LDO(i)) { | ||
| 356 | pmu->desc[i].ops = &bcm590xx_ops_ldo; | ||
| 357 | pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK; | ||
| 358 | } else { | ||
| 359 | pmu->desc[i].ops = &bcm590xx_ops_dcdc; | ||
| 360 | pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK; | ||
| 361 | } | ||
| 362 | |||
| 363 | pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i); | ||
| 364 | pmu->desc[i].enable_is_inverted = true; | ||
| 365 | pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE; | ||
| 366 | pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i); | ||
| 367 | pmu->desc[i].type = REGULATOR_VOLTAGE; | ||
| 368 | pmu->desc[i].owner = THIS_MODULE; | ||
| 369 | |||
| 370 | config.dev = bcm590xx->dev; | ||
| 371 | config.init_data = reg_data; | ||
| 372 | config.driver_data = pmu; | ||
| 373 | config.regmap = bcm590xx->regmap; | ||
| 374 | |||
| 375 | if (bcm590xx_reg_matches) | ||
| 376 | config.of_node = bcm590xx_reg_matches[i].of_node; | ||
| 377 | |||
| 378 | rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i], | ||
| 379 | &config); | ||
| 380 | if (IS_ERR(rdev)) { | ||
| 381 | dev_err(bcm590xx->dev, | ||
| 382 | "failed to register %s regulator\n", | ||
| 383 | pdev->name); | ||
| 384 | return PTR_ERR(rdev); | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | |||
| 391 | static struct platform_driver bcm590xx_regulator_driver = { | ||
| 392 | .driver = { | ||
| 393 | .name = "bcm590xx-vregs", | ||
| 394 | .owner = THIS_MODULE, | ||
| 395 | }, | ||
| 396 | .probe = bcm590xx_probe, | ||
| 397 | }; | ||
| 398 | module_platform_driver(bcm590xx_regulator_driver); | ||
| 399 | |||
| 400 | MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); | ||
| 401 | MODULE_DESCRIPTION("BCM590xx voltage regulator driver"); | ||
| 402 | MODULE_LICENSE("GPL v2"); | ||
| 403 | MODULE_ALIAS("platform:bcm590xx-vregs"); | ||
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index afca1bc24f26..bac485acc7f3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -2399,6 +2399,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
| 2399 | struct regulator_dev *rdev = regulator->rdev; | 2399 | struct regulator_dev *rdev = regulator->rdev; |
| 2400 | int ret = 0; | 2400 | int ret = 0; |
| 2401 | int old_min_uV, old_max_uV; | 2401 | int old_min_uV, old_max_uV; |
| 2402 | int current_uV; | ||
| 2402 | 2403 | ||
| 2403 | mutex_lock(&rdev->mutex); | 2404 | mutex_lock(&rdev->mutex); |
| 2404 | 2405 | ||
| @@ -2409,6 +2410,19 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
| 2409 | if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) | 2410 | if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) |
| 2410 | goto out; | 2411 | goto out; |
| 2411 | 2412 | ||
| 2413 | /* If we're trying to set a range that overlaps the current voltage, | ||
| 2414 | * return succesfully even though the regulator does not support | ||
| 2415 | * changing the voltage. | ||
| 2416 | */ | ||
| 2417 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { | ||
| 2418 | current_uV = _regulator_get_voltage(rdev); | ||
| 2419 | if (min_uV <= current_uV && current_uV <= max_uV) { | ||
| 2420 | regulator->min_uV = min_uV; | ||
| 2421 | regulator->max_uV = max_uV; | ||
| 2422 | goto out; | ||
| 2423 | } | ||
| 2424 | } | ||
| 2425 | |||
| 2412 | /* sanity check */ | 2426 | /* sanity check */ |
| 2413 | if (!rdev->desc->ops->set_voltage && | 2427 | if (!rdev->desc->ops->set_voltage && |
| 2414 | !rdev->desc->ops->set_voltage_sel) { | 2428 | !rdev->desc->ops->set_voltage_sel) { |
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 3adeaeffc485..fdb6ea8ae7e6 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c | |||
| @@ -240,6 +240,31 @@ static int da9052_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
| 240 | return ret; | 240 | return ret; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | ||
| 244 | unsigned int old_sel, | ||
| 245 | unsigned int new_sel) | ||
| 246 | { | ||
| 247 | struct da9052_regulator *regulator = rdev_get_drvdata(rdev); | ||
| 248 | struct da9052_regulator_info *info = regulator->info; | ||
| 249 | int id = rdev_get_id(rdev); | ||
| 250 | int ret = 0; | ||
| 251 | |||
| 252 | /* The DVC controlled LDOs and DCDCs ramp with 6.25mV/µs after enabling | ||
| 253 | * the activate bit. | ||
| 254 | */ | ||
| 255 | switch (id) { | ||
| 256 | case DA9052_ID_BUCK1: | ||
| 257 | case DA9052_ID_BUCK2: | ||
| 258 | case DA9052_ID_BUCK3: | ||
| 259 | case DA9052_ID_LDO2: | ||
| 260 | case DA9052_ID_LDO3: | ||
| 261 | ret = (new_sel - old_sel) * info->step_uV / 6250; | ||
| 262 | break; | ||
| 263 | } | ||
| 264 | |||
| 265 | return ret; | ||
| 266 | } | ||
| 267 | |||
| 243 | static struct regulator_ops da9052_dcdc_ops = { | 268 | static struct regulator_ops da9052_dcdc_ops = { |
| 244 | .get_current_limit = da9052_dcdc_get_current_limit, | 269 | .get_current_limit = da9052_dcdc_get_current_limit, |
| 245 | .set_current_limit = da9052_dcdc_set_current_limit, | 270 | .set_current_limit = da9052_dcdc_set_current_limit, |
| @@ -248,6 +273,7 @@ static struct regulator_ops da9052_dcdc_ops = { | |||
| 248 | .map_voltage = da9052_map_voltage, | 273 | .map_voltage = da9052_map_voltage, |
| 249 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 274 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 250 | .set_voltage_sel = da9052_regulator_set_voltage_sel, | 275 | .set_voltage_sel = da9052_regulator_set_voltage_sel, |
| 276 | .set_voltage_time_sel = da9052_regulator_set_voltage_time_sel, | ||
| 251 | .is_enabled = regulator_is_enabled_regmap, | 277 | .is_enabled = regulator_is_enabled_regmap, |
| 252 | .enable = regulator_enable_regmap, | 278 | .enable = regulator_enable_regmap, |
| 253 | .disable = regulator_disable_regmap, | 279 | .disable = regulator_disable_regmap, |
| @@ -258,6 +284,7 @@ static struct regulator_ops da9052_ldo_ops = { | |||
| 258 | .map_voltage = da9052_map_voltage, | 284 | .map_voltage = da9052_map_voltage, |
| 259 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 285 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 260 | .set_voltage_sel = da9052_regulator_set_voltage_sel, | 286 | .set_voltage_sel = da9052_regulator_set_voltage_sel, |
| 287 | .set_voltage_time_sel = da9052_regulator_set_voltage_time_sel, | ||
| 261 | .is_enabled = regulator_is_enabled_regmap, | 288 | .is_enabled = regulator_is_enabled_regmap, |
| 262 | .enable = regulator_enable_regmap, | 289 | .enable = regulator_enable_regmap, |
| 263 | .disable = regulator_disable_regmap, | 290 | .disable = regulator_disable_regmap, |
| @@ -401,7 +428,7 @@ static int da9052_regulator_probe(struct platform_device *pdev) | |||
| 401 | if (!nproot) | 428 | if (!nproot) |
| 402 | return -ENODEV; | 429 | return -ENODEV; |
| 403 | 430 | ||
| 404 | nproot = of_find_node_by_name(nproot, "regulators"); | 431 | nproot = of_get_child_by_name(nproot, "regulators"); |
| 405 | if (!nproot) | 432 | if (!nproot) |
| 406 | return -ENODEV; | 433 | return -ENODEV; |
| 407 | 434 | ||
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index b14ebdad5dd2..9516317e1a9f 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/regulator/driver.h> | 20 | #include <linux/regulator/driver.h> |
| 21 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/regulator/of_regulator.h> | ||
| 22 | 24 | ||
| 23 | #include <linux/mfd/da9055/core.h> | 25 | #include <linux/mfd/da9055/core.h> |
| 24 | #include <linux/mfd/da9055/reg.h> | 26 | #include <linux/mfd/da9055/reg.h> |
| @@ -446,6 +448,9 @@ static int da9055_gpio_init(struct da9055_regulator *regulator, | |||
| 446 | struct da9055_regulator_info *info = regulator->info; | 448 | struct da9055_regulator_info *info = regulator->info; |
| 447 | int ret = 0; | 449 | int ret = 0; |
| 448 | 450 | ||
| 451 | if (!pdata) | ||
| 452 | return 0; | ||
| 453 | |||
| 449 | if (pdata->gpio_ren && pdata->gpio_ren[id]) { | 454 | if (pdata->gpio_ren && pdata->gpio_ren[id]) { |
| 450 | char name[18]; | 455 | char name[18]; |
| 451 | int gpio_mux = pdata->gpio_ren[id]; | 456 | int gpio_mux = pdata->gpio_ren[id]; |
| @@ -530,6 +535,59 @@ static inline struct da9055_regulator_info *find_regulator_info(int id) | |||
| 530 | return NULL; | 535 | return NULL; |
| 531 | } | 536 | } |
| 532 | 537 | ||
| 538 | #ifdef CONFIG_OF | ||
| 539 | static struct of_regulator_match da9055_reg_matches[] = { | ||
| 540 | { .name = "BUCK1", }, | ||
| 541 | { .name = "BUCK2", }, | ||
| 542 | { .name = "LDO1", }, | ||
| 543 | { .name = "LDO2", }, | ||
| 544 | { .name = "LDO3", }, | ||
| 545 | { .name = "LDO4", }, | ||
| 546 | { .name = "LDO5", }, | ||
| 547 | { .name = "LDO6", }, | ||
| 548 | }; | ||
| 549 | |||
| 550 | static int da9055_regulator_dt_init(struct platform_device *pdev, | ||
| 551 | struct da9055_regulator *regulator, | ||
| 552 | struct regulator_config *config, | ||
| 553 | int regid) | ||
| 554 | { | ||
| 555 | struct device_node *nproot, *np; | ||
| 556 | int ret; | ||
| 557 | |||
| 558 | nproot = of_node_get(pdev->dev.parent->of_node); | ||
| 559 | if (!nproot) | ||
| 560 | return -ENODEV; | ||
| 561 | |||
| 562 | np = of_get_child_by_name(nproot, "regulators"); | ||
| 563 | if (!np) | ||
| 564 | return -ENODEV; | ||
| 565 | |||
| 566 | ret = of_regulator_match(&pdev->dev, np, &da9055_reg_matches[regid], 1); | ||
| 567 | of_node_put(nproot); | ||
| 568 | if (ret < 0) { | ||
| 569 | dev_err(&pdev->dev, "Error matching regulator: %d\n", ret); | ||
| 570 | return ret; | ||
| 571 | } | ||
| 572 | |||
| 573 | config->init_data = da9055_reg_matches[regid].init_data; | ||
| 574 | config->of_node = da9055_reg_matches[regid].of_node; | ||
| 575 | |||
| 576 | if (!config->of_node) | ||
| 577 | return -ENODEV; | ||
| 578 | |||
| 579 | return 0; | ||
| 580 | } | ||
| 581 | #else | ||
| 582 | static inline int da9055_regulator_dt_init(struct platform_device *pdev, | ||
| 583 | struct da9055_regulator *regulator, | ||
| 584 | struct regulator_config *config, | ||
| 585 | int regid) | ||
| 586 | { | ||
| 587 | return -ENODEV; | ||
| 588 | } | ||
| 589 | #endif /* CONFIG_OF */ | ||
| 590 | |||
| 533 | static int da9055_regulator_probe(struct platform_device *pdev) | 591 | static int da9055_regulator_probe(struct platform_device *pdev) |
| 534 | { | 592 | { |
| 535 | struct regulator_config config = { }; | 593 | struct regulator_config config = { }; |
| @@ -538,9 +596,6 @@ static int da9055_regulator_probe(struct platform_device *pdev) | |||
| 538 | struct da9055_pdata *pdata = dev_get_platdata(da9055->dev); | 596 | struct da9055_pdata *pdata = dev_get_platdata(da9055->dev); |
| 539 | int ret, irq; | 597 | int ret, irq; |
| 540 | 598 | ||
| 541 | if (pdata == NULL || pdata->regulators[pdev->id] == NULL) | ||
| 542 | return -ENODEV; | ||
| 543 | |||
| 544 | regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), | 599 | regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), |
| 545 | GFP_KERNEL); | 600 | GFP_KERNEL); |
| 546 | if (!regulator) | 601 | if (!regulator) |
| @@ -557,8 +612,14 @@ static int da9055_regulator_probe(struct platform_device *pdev) | |||
| 557 | config.driver_data = regulator; | 612 | config.driver_data = regulator; |
| 558 | config.regmap = da9055->regmap; | 613 | config.regmap = da9055->regmap; |
| 559 | 614 | ||
| 560 | if (pdata && pdata->regulators) | 615 | if (pdata && pdata->regulators) { |
| 561 | config.init_data = pdata->regulators[pdev->id]; | 616 | config.init_data = pdata->regulators[pdev->id]; |
| 617 | } else { | ||
| 618 | ret = da9055_regulator_dt_init(pdev, regulator, &config, | ||
| 619 | pdev->id); | ||
| 620 | if (ret < 0) | ||
| 621 | return ret; | ||
| 622 | } | ||
| 562 | 623 | ||
| 563 | ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); | 624 | ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); |
| 564 | if (ret < 0) | 625 | if (ret < 0) |
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 91e99a2c8dc1..7c9461d13313 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c | |||
| @@ -365,7 +365,7 @@ static int da9063_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
| 365 | 365 | ||
| 366 | sel = regulator_map_voltage_linear(rdev, uV, uV); | 366 | sel = regulator_map_voltage_linear(rdev, uV, uV); |
| 367 | if (sel < 0) | 367 | if (sel < 0) |
| 368 | return -EINVAL; | 368 | return sel; |
| 369 | 369 | ||
| 370 | sel <<= ffs(rdev->desc->vsel_mask) - 1; | 370 | sel <<= ffs(rdev->desc->vsel_mask) - 1; |
| 371 | 371 | ||
| @@ -666,7 +666,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
| 666 | struct device_node *node; | 666 | struct device_node *node; |
| 667 | int i, n, num; | 667 | int i, n, num; |
| 668 | 668 | ||
| 669 | node = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); | 669 | node = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); |
| 670 | if (!node) { | 670 | if (!node) { |
| 671 | dev_err(&pdev->dev, "Regulators device node not found\n"); | 671 | dev_err(&pdev->dev, "Regulators device node not found\n"); |
| 672 | return ERR_PTR(-ENODEV); | 672 | return ERR_PTR(-ENODEV); |
| @@ -674,6 +674,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
| 674 | 674 | ||
| 675 | num = of_regulator_match(&pdev->dev, node, da9063_matches, | 675 | num = of_regulator_match(&pdev->dev, node, da9063_matches, |
| 676 | ARRAY_SIZE(da9063_matches)); | 676 | ARRAY_SIZE(da9063_matches)); |
| 677 | of_node_put(node); | ||
| 677 | if (num < 0) { | 678 | if (num < 0) { |
| 678 | dev_err(&pdev->dev, "Failed to match regulators\n"); | 679 | dev_err(&pdev->dev, "Failed to match regulators\n"); |
| 679 | return ERR_PTR(-EINVAL); | 680 | return ERR_PTR(-EINVAL); |
| @@ -710,7 +711,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
| 710 | struct platform_device *pdev, | 711 | struct platform_device *pdev, |
| 711 | struct of_regulator_match **da9063_reg_matches) | 712 | struct of_regulator_match **da9063_reg_matches) |
| 712 | { | 713 | { |
| 713 | da9063_reg_matches = NULL; | 714 | *da9063_reg_matches = NULL; |
| 714 | return ERR_PTR(-ENODEV); | 715 | return ERR_PTR(-ENODEV); |
| 715 | } | 716 | } |
| 716 | #endif | 717 | #endif |
| @@ -756,7 +757,7 @@ static int da9063_regulator_probe(struct platform_device *pdev) | |||
| 756 | if (ret < 0) { | 757 | if (ret < 0) { |
| 757 | dev_err(&pdev->dev, | 758 | dev_err(&pdev->dev, |
| 758 | "Error while reading BUCKs configuration\n"); | 759 | "Error while reading BUCKs configuration\n"); |
| 759 | return -EIO; | 760 | return ret; |
| 760 | } | 761 | } |
| 761 | bcores_merged = val & DA9063_BCORE_MERGE; | 762 | bcores_merged = val & DA9063_BCORE_MERGE; |
| 762 | bmem_bio_merged = val & DA9063_BUCK_MERGE; | 763 | bmem_bio_merged = val & DA9063_BUCK_MERGE; |
| @@ -775,10 +776,8 @@ static int da9063_regulator_probe(struct platform_device *pdev) | |||
| 775 | size = sizeof(struct da9063_regulators) + | 776 | size = sizeof(struct da9063_regulators) + |
| 776 | n_regulators * sizeof(struct da9063_regulator); | 777 | n_regulators * sizeof(struct da9063_regulator); |
| 777 | regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | 778 | regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
| 778 | if (!regulators) { | 779 | if (!regulators) |
| 779 | dev_err(&pdev->dev, "No memory for regulators\n"); | ||
| 780 | return -ENOMEM; | 780 | return -ENOMEM; |
| 781 | } | ||
| 782 | 781 | ||
| 783 | regulators->n_regulators = n_regulators; | 782 | regulators->n_regulators = n_regulators; |
| 784 | platform_set_drvdata(pdev, regulators); | 783 | platform_set_drvdata(pdev, regulators); |
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 6f5ecbe1132e..7a320dd11c46 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c | |||
| @@ -134,11 +134,8 @@ static int da9210_i2c_probe(struct i2c_client *i2c, | |||
| 134 | int error; | 134 | int error; |
| 135 | 135 | ||
| 136 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9210), GFP_KERNEL); | 136 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9210), GFP_KERNEL); |
| 137 | if (NULL == chip) { | 137 | if (!chip) |
| 138 | dev_err(&i2c->dev, | ||
| 139 | "Cannot kzalloc memory for regulator structure\n"); | ||
| 140 | return -ENOMEM; | 138 | return -ENOMEM; |
| 141 | } | ||
| 142 | 139 | ||
| 143 | chip->regmap = devm_regmap_init_i2c(i2c, &da9210_regmap_config); | 140 | chip->regmap = devm_regmap_init_i2c(i2c, &da9210_regmap_config); |
| 144 | if (IS_ERR(chip->regmap)) { | 141 | if (IS_ERR(chip->regmap)) { |
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 846acf240e48..617c1adca816 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
| @@ -263,6 +263,8 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { | |||
| 263 | .ops = &db8500_regulator_ops, | 263 | .ops = &db8500_regulator_ops, |
| 264 | .type = REGULATOR_VOLTAGE, | 264 | .type = REGULATOR_VOLTAGE, |
| 265 | .owner = THIS_MODULE, | 265 | .owner = THIS_MODULE, |
| 266 | .fixed_uV = 1800000, | ||
| 267 | .n_voltages = 1, | ||
| 266 | }, | 268 | }, |
| 267 | .exclude_from_power_state = true, | 269 | .exclude_from_power_state = true, |
| 268 | }, | 270 | }, |
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index ce89f7848a57..2d16b9f16de7 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c | |||
| @@ -78,6 +78,7 @@ static struct ux500_regulator_debug { | |||
| 78 | void ux500_regulator_suspend_debug(void) | 78 | void ux500_regulator_suspend_debug(void) |
| 79 | { | 79 | { |
| 80 | int i; | 80 | int i; |
| 81 | |||
| 81 | for (i = 0; i < rdebug.num_regulators; i++) | 82 | for (i = 0; i < rdebug.num_regulators; i++) |
| 82 | rdebug.state_before_suspend[i] = | 83 | rdebug.state_before_suspend[i] = |
| 83 | rdebug.regulator_array[i].is_enabled; | 84 | rdebug.regulator_array[i].is_enabled; |
| @@ -86,6 +87,7 @@ void ux500_regulator_suspend_debug(void) | |||
| 86 | void ux500_regulator_resume_debug(void) | 87 | void ux500_regulator_resume_debug(void) |
| 87 | { | 88 | { |
| 88 | int i; | 89 | int i; |
| 90 | |||
| 89 | for (i = 0; i < rdebug.num_regulators; i++) | 91 | for (i = 0; i < rdebug.num_regulators; i++) |
| 90 | rdebug.state_after_suspend[i] = | 92 | rdebug.state_after_suspend[i] = |
| 91 | rdebug.regulator_array[i].is_enabled; | 93 | rdebug.regulator_array[i].is_enabled; |
| @@ -127,9 +129,9 @@ static int ux500_regulator_status_print(struct seq_file *s, void *p) | |||
| 127 | int i; | 129 | int i; |
| 128 | 130 | ||
| 129 | /* print dump header */ | 131 | /* print dump header */ |
| 130 | err = seq_printf(s, "ux500-regulator status:\n"); | 132 | err = seq_puts(s, "ux500-regulator status:\n"); |
| 131 | if (err < 0) | 133 | if (err < 0) |
| 132 | dev_err(dev, "seq_printf overflow\n"); | 134 | dev_err(dev, "seq_puts overflow\n"); |
| 133 | 135 | ||
| 134 | err = seq_printf(s, "%31s : %8s : %8s\n", "current", | 136 | err = seq_printf(s, "%31s : %8s : %8s\n", "current", |
| 135 | "before", "after"); | 137 | "before", "after"); |
| @@ -202,18 +204,12 @@ ux500_regulator_debug_init(struct platform_device *pdev, | |||
| 202 | rdebug.num_regulators = num_regulators; | 204 | rdebug.num_regulators = num_regulators; |
| 203 | 205 | ||
| 204 | rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); | 206 | rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); |
| 205 | if (!rdebug.state_before_suspend) { | 207 | if (!rdebug.state_before_suspend) |
| 206 | dev_err(&pdev->dev, | ||
| 207 | "could not allocate memory for saving state\n"); | ||
| 208 | goto exit_destroy_power_state; | 208 | goto exit_destroy_power_state; |
| 209 | } | ||
| 210 | 209 | ||
| 211 | rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); | 210 | rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); |
| 212 | if (!rdebug.state_after_suspend) { | 211 | if (!rdebug.state_after_suspend) |
| 213 | dev_err(&pdev->dev, | ||
| 214 | "could not allocate memory for saving state\n"); | ||
| 215 | goto exit_free; | 212 | goto exit_free; |
| 216 | } | ||
| 217 | 213 | ||
| 218 | dbx500_regulator_testcase(regulator_info, num_regulators); | 214 | dbx500_regulator_testcase(regulator_info, num_regulators); |
| 219 | return 0; | 215 | return 0; |
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index df9f42524abb..2436db9e2ca3 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c | |||
| @@ -25,7 +25,11 @@ | |||
| 25 | 25 | ||
| 26 | struct regulator_dev *dummy_regulator_rdev; | 26 | struct regulator_dev *dummy_regulator_rdev; |
| 27 | 27 | ||
| 28 | static struct regulator_init_data dummy_initdata; | 28 | static struct regulator_init_data dummy_initdata = { |
| 29 | .constraints = { | ||
| 30 | .always_on = 1, | ||
| 31 | }, | ||
| 32 | }; | ||
| 29 | 33 | ||
| 30 | static struct regulator_ops dummy_ops; | 34 | static struct regulator_ops dummy_ops; |
| 31 | 35 | ||
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 7ca3d9e3b0fe..714fd9a89aa1 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c | |||
| @@ -90,11 +90,11 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
| 90 | return 0; | 90 | return 0; |
| 91 | ret = regulator_map_voltage_linear(rdev, uV, uV); | 91 | ret = regulator_map_voltage_linear(rdev, uV, uV); |
| 92 | if (ret < 0) | 92 | if (ret < 0) |
| 93 | return -EINVAL; | 93 | return ret; |
| 94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, | 94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, |
| 95 | VSEL_NSEL_MASK, ret); | 95 | VSEL_NSEL_MASK, ret); |
| 96 | if (ret < 0) | 96 | if (ret < 0) |
| 97 | return -EINVAL; | 97 | return ret; |
| 98 | /* Cache the sleep voltage setting. | 98 | /* Cache the sleep voltage setting. |
| 99 | * Might not be the real voltage which is rounded */ | 99 | * Might not be the real voltage which is rounded */ |
| 100 | di->sleep_vol_cache = uV; | 100 | di->sleep_vol_cache = uV; |
| @@ -244,10 +244,9 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
| 244 | 244 | ||
| 245 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), | 245 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), |
| 246 | GFP_KERNEL); | 246 | GFP_KERNEL); |
| 247 | if (!di) { | 247 | if (!di) |
| 248 | dev_err(&client->dev, "Failed to allocate device info data!\n"); | ||
| 249 | return -ENOMEM; | 248 | return -ENOMEM; |
| 250 | } | 249 | |
| 251 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); | 250 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); |
| 252 | if (IS_ERR(di->regmap)) { | 251 | if (IS_ERR(di->regmap)) { |
| 253 | dev_err(&client->dev, "Failed to allocate regmap!\n"); | 252 | dev_err(&client->dev, "Failed to allocate regmap!\n"); |
| @@ -260,14 +259,14 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
| 260 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); | 259 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); |
| 261 | if (ret < 0) { | 260 | if (ret < 0) { |
| 262 | dev_err(&client->dev, "Failed to get chip ID!\n"); | 261 | dev_err(&client->dev, "Failed to get chip ID!\n"); |
| 263 | return -ENODEV; | 262 | return ret; |
| 264 | } | 263 | } |
| 265 | di->chip_id = val & DIE_ID; | 264 | di->chip_id = val & DIE_ID; |
| 266 | /* Get chip revision */ | 265 | /* Get chip revision */ |
| 267 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); | 266 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); |
| 268 | if (ret < 0) { | 267 | if (ret < 0) { |
| 269 | dev_err(&client->dev, "Failed to get chip Rev!\n"); | 268 | dev_err(&client->dev, "Failed to get chip Rev!\n"); |
| 270 | return -ENODEV; | 269 | return ret; |
| 271 | } | 270 | } |
| 272 | di->chip_rev = val & DIE_REV; | 271 | di->chip_rev = val & DIE_REV; |
| 273 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", | 272 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", |
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 5ea64b94341c..c61f7e97e4f8 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
| @@ -130,17 +130,15 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 130 | 130 | ||
| 131 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), | 131 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), |
| 132 | GFP_KERNEL); | 132 | GFP_KERNEL); |
| 133 | if (drvdata == NULL) { | 133 | if (!drvdata) |
| 134 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | 134 | return -ENOMEM; |
| 135 | ret = -ENOMEM; | ||
| 136 | goto err; | ||
| 137 | } | ||
| 138 | 135 | ||
| 139 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 136 | drvdata->desc.name = devm_kstrdup(&pdev->dev, |
| 137 | config->supply_name, | ||
| 138 | GFP_KERNEL); | ||
| 140 | if (drvdata->desc.name == NULL) { | 139 | if (drvdata->desc.name == NULL) { |
| 141 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); | 140 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); |
| 142 | ret = -ENOMEM; | 141 | return -ENOMEM; |
| 143 | goto err; | ||
| 144 | } | 142 | } |
| 145 | drvdata->desc.type = REGULATOR_VOLTAGE; | 143 | drvdata->desc.type = REGULATOR_VOLTAGE; |
| 146 | drvdata->desc.owner = THIS_MODULE; | 144 | drvdata->desc.owner = THIS_MODULE; |
| @@ -149,13 +147,13 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 149 | drvdata->desc.enable_time = config->startup_delay; | 147 | drvdata->desc.enable_time = config->startup_delay; |
| 150 | 148 | ||
| 151 | if (config->input_supply) { | 149 | if (config->input_supply) { |
| 152 | drvdata->desc.supply_name = kstrdup(config->input_supply, | 150 | drvdata->desc.supply_name = devm_kstrdup(&pdev->dev, |
| 153 | GFP_KERNEL); | 151 | config->input_supply, |
| 152 | GFP_KERNEL); | ||
| 154 | if (!drvdata->desc.supply_name) { | 153 | if (!drvdata->desc.supply_name) { |
| 155 | dev_err(&pdev->dev, | 154 | dev_err(&pdev->dev, |
| 156 | "Failed to allocate input supply\n"); | 155 | "Failed to allocate input supply\n"); |
| 157 | ret = -ENOMEM; | 156 | return -ENOMEM; |
| 158 | goto err_name; | ||
| 159 | } | 157 | } |
| 160 | } | 158 | } |
| 161 | 159 | ||
| @@ -186,11 +184,12 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 186 | cfg.driver_data = drvdata; | 184 | cfg.driver_data = drvdata; |
| 187 | cfg.of_node = pdev->dev.of_node; | 185 | cfg.of_node = pdev->dev.of_node; |
| 188 | 186 | ||
| 189 | drvdata->dev = regulator_register(&drvdata->desc, &cfg); | 187 | drvdata->dev = devm_regulator_register(&pdev->dev, &drvdata->desc, |
| 188 | &cfg); | ||
| 190 | if (IS_ERR(drvdata->dev)) { | 189 | if (IS_ERR(drvdata->dev)) { |
| 191 | ret = PTR_ERR(drvdata->dev); | 190 | ret = PTR_ERR(drvdata->dev); |
| 192 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); | 191 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); |
| 193 | goto err_input; | 192 | return ret; |
| 194 | } | 193 | } |
| 195 | 194 | ||
| 196 | platform_set_drvdata(pdev, drvdata); | 195 | platform_set_drvdata(pdev, drvdata); |
| @@ -199,24 +198,6 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 199 | drvdata->desc.fixed_uV); | 198 | drvdata->desc.fixed_uV); |
| 200 | 199 | ||
| 201 | return 0; | 200 | return 0; |
| 202 | |||
| 203 | err_input: | ||
| 204 | kfree(drvdata->desc.supply_name); | ||
| 205 | err_name: | ||
| 206 | kfree(drvdata->desc.name); | ||
| 207 | err: | ||
| 208 | return ret; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int reg_fixed_voltage_remove(struct platform_device *pdev) | ||
| 212 | { | ||
| 213 | struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev); | ||
| 214 | |||
| 215 | regulator_unregister(drvdata->dev); | ||
| 216 | kfree(drvdata->desc.supply_name); | ||
| 217 | kfree(drvdata->desc.name); | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | 201 | } |
| 221 | 202 | ||
| 222 | #if defined(CONFIG_OF) | 203 | #if defined(CONFIG_OF) |
| @@ -229,7 +210,6 @@ MODULE_DEVICE_TABLE(of, fixed_of_match); | |||
| 229 | 210 | ||
| 230 | static struct platform_driver regulator_fixed_voltage_driver = { | 211 | static struct platform_driver regulator_fixed_voltage_driver = { |
| 231 | .probe = reg_fixed_voltage_probe, | 212 | .probe = reg_fixed_voltage_probe, |
| 232 | .remove = reg_fixed_voltage_remove, | ||
| 233 | .driver = { | 213 | .driver = { |
| 234 | .name = "reg-fixed-voltage", | 214 | .name = "reg-fixed-voltage", |
| 235 | .owner = THIS_MODULE, | 215 | .owner = THIS_MODULE, |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index c0a1d00b78c9..989b23b377c0 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
| @@ -136,7 +136,6 @@ static struct gpio_regulator_config * | |||
| 136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | 136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) |
| 137 | { | 137 | { |
| 138 | struct gpio_regulator_config *config; | 138 | struct gpio_regulator_config *config; |
| 139 | struct property *prop; | ||
| 140 | const char *regtype; | 139 | const char *regtype; |
| 141 | int proplen, gpio, i; | 140 | int proplen, gpio, i; |
| 142 | int ret; | 141 | int ret; |
| @@ -172,22 +171,35 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
| 172 | if (!config->gpios) | 171 | if (!config->gpios) |
| 173 | return ERR_PTR(-ENOMEM); | 172 | return ERR_PTR(-ENOMEM); |
| 174 | 173 | ||
| 174 | proplen = of_property_count_u32_elems(np, "gpios-states"); | ||
| 175 | /* optional property */ | ||
| 176 | if (proplen < 0) | ||
| 177 | proplen = 0; | ||
| 178 | |||
| 179 | if (proplen > 0 && proplen != config->nr_gpios) { | ||
| 180 | dev_warn(dev, "gpios <-> gpios-states mismatch\n"); | ||
| 181 | proplen = 0; | ||
| 182 | } | ||
| 183 | |||
| 175 | for (i = 0; i < config->nr_gpios; i++) { | 184 | for (i = 0; i < config->nr_gpios; i++) { |
| 176 | gpio = of_get_named_gpio(np, "gpios", i); | 185 | gpio = of_get_named_gpio(np, "gpios", i); |
| 177 | if (gpio < 0) | 186 | if (gpio < 0) |
| 178 | break; | 187 | break; |
| 179 | config->gpios[i].gpio = gpio; | 188 | config->gpios[i].gpio = gpio; |
| 189 | if (proplen > 0) { | ||
| 190 | of_property_read_u32_index(np, "gpios-states", i, &ret); | ||
| 191 | if (ret) | ||
| 192 | config->gpios[i].flags = GPIOF_OUT_INIT_HIGH; | ||
| 193 | } | ||
| 180 | } | 194 | } |
| 181 | 195 | ||
| 182 | /* Fetch states. */ | 196 | /* Fetch states. */ |
| 183 | prop = of_find_property(np, "states", NULL); | 197 | proplen = of_property_count_u32_elems(np, "states"); |
| 184 | if (!prop) { | 198 | if (proplen < 0) { |
| 185 | dev_err(dev, "No 'states' property found\n"); | 199 | dev_err(dev, "No 'states' property found\n"); |
| 186 | return ERR_PTR(-EINVAL); | 200 | return ERR_PTR(-EINVAL); |
| 187 | } | 201 | } |
| 188 | 202 | ||
| 189 | proplen = prop->length / sizeof(int); | ||
| 190 | |||
| 191 | config->states = devm_kzalloc(dev, | 203 | config->states = devm_kzalloc(dev, |
| 192 | sizeof(struct gpio_regulator_state) | 204 | sizeof(struct gpio_regulator_state) |
| 193 | * (proplen / 2), | 205 | * (proplen / 2), |
| @@ -196,10 +208,10 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
| 196 | return ERR_PTR(-ENOMEM); | 208 | return ERR_PTR(-ENOMEM); |
| 197 | 209 | ||
| 198 | for (i = 0; i < proplen / 2; i++) { | 210 | for (i = 0; i < proplen / 2; i++) { |
| 199 | config->states[i].value = | 211 | of_property_read_u32_index(np, "states", i * 2, |
| 200 | be32_to_cpup((int *)prop->value + (i * 2)); | 212 | &config->states[i].value); |
| 201 | config->states[i].gpios = | 213 | of_property_read_u32_index(np, "states", i * 2 + 1, |
| 202 | be32_to_cpup((int *)prop->value + (i * 2 + 1)); | 214 | &config->states[i].gpios); |
| 203 | } | 215 | } |
| 204 | config->nr_states = i; | 216 | config->nr_states = i; |
| 205 | 217 | ||
| @@ -239,10 +251,8 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
| 239 | 251 | ||
| 240 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), | 252 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), |
| 241 | GFP_KERNEL); | 253 | GFP_KERNEL); |
| 242 | if (drvdata == NULL) { | 254 | if (drvdata == NULL) |
| 243 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | ||
| 244 | return -ENOMEM; | 255 | return -ENOMEM; |
| 245 | } | ||
| 246 | 256 | ||
| 247 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 257 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); |
| 248 | if (drvdata->desc.name == NULL) { | 258 | if (drvdata->desc.name == NULL) { |
diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index e221a271ba56..cbc39096c78d 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c | |||
| @@ -37,10 +37,17 @@ int regulator_is_enabled_regmap(struct regulator_dev *rdev) | |||
| 37 | if (ret != 0) | 37 | if (ret != 0) |
| 38 | return ret; | 38 | return ret; |
| 39 | 39 | ||
| 40 | if (rdev->desc->enable_is_inverted) | 40 | val &= rdev->desc->enable_mask; |
| 41 | return (val & rdev->desc->enable_mask) == 0; | 41 | |
| 42 | else | 42 | if (rdev->desc->enable_is_inverted) { |
| 43 | return (val & rdev->desc->enable_mask) != 0; | 43 | if (rdev->desc->enable_val) |
| 44 | return val != rdev->desc->enable_val; | ||
| 45 | return val == 0; | ||
| 46 | } else { | ||
| 47 | if (rdev->desc->enable_val) | ||
| 48 | return val == rdev->desc->enable_val; | ||
| 49 | return val != 0; | ||
| 50 | } | ||
| 44 | } | 51 | } |
| 45 | EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); | 52 | EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); |
| 46 | 53 | ||
| @@ -57,10 +64,13 @@ int regulator_enable_regmap(struct regulator_dev *rdev) | |||
| 57 | { | 64 | { |
| 58 | unsigned int val; | 65 | unsigned int val; |
| 59 | 66 | ||
| 60 | if (rdev->desc->enable_is_inverted) | 67 | if (rdev->desc->enable_is_inverted) { |
| 61 | val = 0; | 68 | val = rdev->desc->disable_val; |
| 62 | else | 69 | } else { |
| 63 | val = rdev->desc->enable_mask; | 70 | val = rdev->desc->enable_val; |
| 71 | if (!val) | ||
| 72 | val = rdev->desc->enable_mask; | ||
| 73 | } | ||
| 64 | 74 | ||
| 65 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 75 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
| 66 | rdev->desc->enable_mask, val); | 76 | rdev->desc->enable_mask, val); |
| @@ -80,10 +90,13 @@ int regulator_disable_regmap(struct regulator_dev *rdev) | |||
| 80 | { | 90 | { |
| 81 | unsigned int val; | 91 | unsigned int val; |
| 82 | 92 | ||
| 83 | if (rdev->desc->enable_is_inverted) | 93 | if (rdev->desc->enable_is_inverted) { |
| 84 | val = rdev->desc->enable_mask; | 94 | val = rdev->desc->enable_val; |
| 85 | else | 95 | if (!val) |
| 86 | val = 0; | 96 | val = rdev->desc->enable_mask; |
| 97 | } else { | ||
| 98 | val = rdev->desc->disable_val; | ||
| 99 | } | ||
| 87 | 100 | ||
| 88 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 101 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
| 89 | rdev->desc->enable_mask, val); | 102 | rdev->desc->enable_mask, val); |
| @@ -419,10 +432,13 @@ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | |||
| 419 | { | 432 | { |
| 420 | unsigned int val; | 433 | unsigned int val; |
| 421 | 434 | ||
| 422 | if (enable) | 435 | if (enable) { |
| 423 | val = rdev->desc->bypass_mask; | 436 | val = rdev->desc->bypass_val_on; |
| 424 | else | 437 | if (!val) |
| 425 | val = 0; | 438 | val = rdev->desc->bypass_mask; |
| 439 | } else { | ||
| 440 | val = rdev->desc->bypass_val_off; | ||
| 441 | } | ||
| 426 | 442 | ||
| 427 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | 443 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, |
| 428 | rdev->desc->bypass_mask, val); | 444 | rdev->desc->bypass_mask, val); |
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 3b1102b75071..66fd2330dca0 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
| @@ -327,7 +327,7 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, | |||
| 327 | return -EIO; | 327 | return -EIO; |
| 328 | ret = i2c_smbus_read_byte_data(i2c, reg); | 328 | ret = i2c_smbus_read_byte_data(i2c, reg); |
| 329 | if (ret < 0) | 329 | if (ret < 0) |
| 330 | return -EIO; | 330 | return ret; |
| 331 | 331 | ||
| 332 | *dest = ret; | 332 | *dest = ret; |
| 333 | return 0; | 333 | return 0; |
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 2e4734ff79fc..2e022aabd951 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c | |||
| @@ -211,7 +211,7 @@ static int lp872x_get_timestep_usec(struct lp872x *lp) | |||
| 211 | 211 | ||
| 212 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); | 212 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); |
| 213 | if (ret) | 213 | if (ret) |
| 214 | return -EINVAL; | 214 | return ret; |
| 215 | 215 | ||
| 216 | val = (val & mask) >> shift; | 216 | val = (val & mask) >> shift; |
| 217 | if (val >= size) | 217 | if (val >= size) |
| @@ -229,7 +229,7 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) | |||
| 229 | u8 addr, val; | 229 | u8 addr, val; |
| 230 | 230 | ||
| 231 | if (time_step_us < 0) | 231 | if (time_step_us < 0) |
| 232 | return -EINVAL; | 232 | return time_step_us; |
| 233 | 233 | ||
| 234 | switch (rid) { | 234 | switch (rid) { |
| 235 | case LP8720_ID_LDO1 ... LP8720_ID_BUCK: | 235 | case LP8720_ID_LDO1 ... LP8720_ID_BUCK: |
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index e0619526708c..ed60baaeceec 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * max14577.c - Regulator driver for the Maxim 14577 | 2 | * max14577.c - Regulator driver for the Maxim 14577 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2013 Samsung Electronics | 4 | * Copyright (C) 2013,2014 Samsung Electronics |
| 5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> | 5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -22,12 +22,6 @@ | |||
| 22 | #include <linux/mfd/max14577-private.h> | 22 | #include <linux/mfd/max14577-private.h> |
| 23 | #include <linux/regulator/of_regulator.h> | 23 | #include <linux/regulator/of_regulator.h> |
| 24 | 24 | ||
| 25 | struct max14577_regulator { | ||
| 26 | struct device *dev; | ||
| 27 | struct max14577 *max14577; | ||
| 28 | struct regulator_dev **regulators; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static int max14577_reg_is_enabled(struct regulator_dev *rdev) | 25 | static int max14577_reg_is_enabled(struct regulator_dev *rdev) |
| 32 | { | 26 | { |
| 33 | int rid = rdev_get_id(rdev); | 27 | int rid = rdev_get_id(rdev); |
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index e242dd316d36..d23d0577754b 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
| @@ -46,8 +46,6 @@ struct max1586_data { | |||
| 46 | 46 | ||
| 47 | unsigned int v3_curr_sel; | 47 | unsigned int v3_curr_sel; |
| 48 | unsigned int v6_curr_sel; | 48 | unsigned int v6_curr_sel; |
| 49 | |||
| 50 | struct regulator_dev *rdev[0]; | ||
| 51 | }; | 49 | }; |
| 52 | 50 | ||
| 53 | /* | 51 | /* |
| @@ -162,14 +160,12 @@ static struct regulator_desc max1586_reg[] = { | |||
| 162 | static int max1586_pmic_probe(struct i2c_client *client, | 160 | static int max1586_pmic_probe(struct i2c_client *client, |
| 163 | const struct i2c_device_id *i2c_id) | 161 | const struct i2c_device_id *i2c_id) |
| 164 | { | 162 | { |
| 165 | struct regulator_dev **rdev; | ||
| 166 | struct max1586_platform_data *pdata = dev_get_platdata(&client->dev); | 163 | struct max1586_platform_data *pdata = dev_get_platdata(&client->dev); |
| 167 | struct regulator_config config = { }; | 164 | struct regulator_config config = { }; |
| 168 | struct max1586_data *max1586; | 165 | struct max1586_data *max1586; |
| 169 | int i, id; | 166 | int i, id; |
| 170 | 167 | ||
| 171 | max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) + | 168 | max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data), |
| 172 | sizeof(struct regulator_dev *) * (MAX1586_V6 + 1), | ||
| 173 | GFP_KERNEL); | 169 | GFP_KERNEL); |
| 174 | if (!max1586) | 170 | if (!max1586) |
| 175 | return -ENOMEM; | 171 | return -ENOMEM; |
| @@ -186,8 +182,9 @@ static int max1586_pmic_probe(struct i2c_client *client, | |||
| 186 | max1586->v3_curr_sel = 24; /* 1.3V */ | 182 | max1586->v3_curr_sel = 24; /* 1.3V */ |
| 187 | max1586->v6_curr_sel = 0; | 183 | max1586->v6_curr_sel = 0; |
| 188 | 184 | ||
| 189 | rdev = max1586->rdev; | ||
| 190 | for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { | 185 | for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { |
| 186 | struct regulator_dev *rdev; | ||
| 187 | |||
| 191 | id = pdata->subdevs[i].id; | 188 | id = pdata->subdevs[i].id; |
| 192 | if (!pdata->subdevs[i].platform_data) | 189 | if (!pdata->subdevs[i].platform_data) |
| 193 | continue; | 190 | continue; |
| @@ -207,12 +204,12 @@ static int max1586_pmic_probe(struct i2c_client *client, | |||
| 207 | config.init_data = pdata->subdevs[i].platform_data; | 204 | config.init_data = pdata->subdevs[i].platform_data; |
| 208 | config.driver_data = max1586; | 205 | config.driver_data = max1586; |
| 209 | 206 | ||
| 210 | rdev[i] = devm_regulator_register(&client->dev, | 207 | rdev = devm_regulator_register(&client->dev, |
| 211 | &max1586_reg[id], &config); | 208 | &max1586_reg[id], &config); |
| 212 | if (IS_ERR(rdev[i])) { | 209 | if (IS_ERR(rdev)) { |
| 213 | dev_err(&client->dev, "failed to register %s\n", | 210 | dev_err(&client->dev, "failed to register %s\n", |
| 214 | max1586_reg[id].name); | 211 | max1586_reg[id].name); |
| 215 | return PTR_ERR(rdev[i]); | 212 | return PTR_ERR(rdev); |
| 216 | } | 213 | } |
| 217 | } | 214 | } |
| 218 | 215 | ||
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index ae001ccf26f4..ef1af2debbd2 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
| @@ -65,7 +65,6 @@ enum max77686_ramp_rate { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | struct max77686_data { | 67 | struct max77686_data { |
| 68 | struct regulator_dev *rdev[MAX77686_REGULATORS]; | ||
| 69 | unsigned int opmode[MAX77686_REGULATORS]; | 68 | unsigned int opmode[MAX77686_REGULATORS]; |
| 70 | }; | 69 | }; |
| 71 | 70 | ||
| @@ -400,7 +399,7 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 400 | unsigned int i; | 399 | unsigned int i; |
| 401 | 400 | ||
| 402 | pmic_np = iodev->dev->of_node; | 401 | pmic_np = iodev->dev->of_node; |
| 403 | regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators"); | 402 | regulators_np = of_get_child_by_name(pmic_np, "voltage-regulators"); |
| 404 | if (!regulators_np) { | 403 | if (!regulators_np) { |
| 405 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 404 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
| 406 | return -EINVAL; | 405 | return -EINVAL; |
| @@ -410,8 +409,7 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 410 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | 409 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
| 411 | pdata->num_regulators, GFP_KERNEL); | 410 | pdata->num_regulators, GFP_KERNEL); |
| 412 | if (!rdata) { | 411 | if (!rdata) { |
| 413 | dev_err(&pdev->dev, | 412 | of_node_put(regulators_np); |
| 414 | "could not allocate memory for regulator data\n"); | ||
| 415 | return -ENOMEM; | 413 | return -ENOMEM; |
| 416 | } | 414 | } |
| 417 | 415 | ||
| @@ -425,6 +423,7 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 425 | } | 423 | } |
| 426 | 424 | ||
| 427 | pdata->regulators = rdata; | 425 | pdata->regulators = rdata; |
| 426 | of_node_put(regulators_np); | ||
| 428 | 427 | ||
| 429 | return 0; | 428 | return 0; |
| 430 | } | 429 | } |
| @@ -474,16 +473,18 @@ static int max77686_pmic_probe(struct platform_device *pdev) | |||
| 474 | platform_set_drvdata(pdev, max77686); | 473 | platform_set_drvdata(pdev, max77686); |
| 475 | 474 | ||
| 476 | for (i = 0; i < MAX77686_REGULATORS; i++) { | 475 | for (i = 0; i < MAX77686_REGULATORS; i++) { |
| 476 | struct regulator_dev *rdev; | ||
| 477 | |||
| 477 | config.init_data = pdata->regulators[i].initdata; | 478 | config.init_data = pdata->regulators[i].initdata; |
| 478 | config.of_node = pdata->regulators[i].of_node; | 479 | config.of_node = pdata->regulators[i].of_node; |
| 479 | 480 | ||
| 480 | max77686->opmode[i] = regulators[i].enable_mask; | 481 | max77686->opmode[i] = regulators[i].enable_mask; |
| 481 | max77686->rdev[i] = devm_regulator_register(&pdev->dev, | 482 | rdev = devm_regulator_register(&pdev->dev, |
| 482 | ®ulators[i], &config); | 483 | ®ulators[i], &config); |
| 483 | if (IS_ERR(max77686->rdev[i])) { | 484 | if (IS_ERR(rdev)) { |
| 484 | dev_err(&pdev->dev, | 485 | dev_err(&pdev->dev, |
| 485 | "regulator init failed for %d\n", i); | 486 | "regulator init failed for %d\n", i); |
| 486 | return PTR_ERR(max77686->rdev[i]); | 487 | return PTR_ERR(rdev); |
| 487 | } | 488 | } |
| 488 | } | 489 | } |
| 489 | 490 | ||
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index 5fb899f461d0..653a58b49cdf 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c | |||
| @@ -34,13 +34,6 @@ | |||
| 34 | 34 | ||
| 35 | #define CHGIN_ILIM_STEP_20mA 20000 | 35 | #define CHGIN_ILIM_STEP_20mA 20000 |
| 36 | 36 | ||
| 37 | struct max77693_pmic_dev { | ||
| 38 | struct device *dev; | ||
| 39 | struct max77693_dev *iodev; | ||
| 40 | int num_regulators; | ||
| 41 | struct regulator_dev **rdev; | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* CHARGER regulator ops */ | 37 | /* CHARGER regulator ops */ |
| 45 | /* CHARGER regulator uses two bits for enabling */ | 38 | /* CHARGER regulator uses two bits for enabling */ |
| 46 | static int max77693_chg_is_enabled(struct regulator_dev *rdev) | 39 | static int max77693_chg_is_enabled(struct regulator_dev *rdev) |
| @@ -170,19 +163,22 @@ static int max77693_pmic_dt_parse_rdata(struct device *dev, | |||
| 170 | struct max77693_regulator_data *tmp; | 163 | struct max77693_regulator_data *tmp; |
| 171 | int i, matched = 0; | 164 | int i, matched = 0; |
| 172 | 165 | ||
| 173 | np = of_find_node_by_name(dev->parent->of_node, "regulators"); | 166 | np = of_get_child_by_name(dev->parent->of_node, "regulators"); |
| 174 | if (!np) | 167 | if (!np) |
| 175 | return -EINVAL; | 168 | return -EINVAL; |
| 176 | 169 | ||
| 177 | rmatch = devm_kzalloc(dev, | 170 | rmatch = devm_kzalloc(dev, |
| 178 | sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL); | 171 | sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL); |
| 179 | if (!rmatch) | 172 | if (!rmatch) { |
| 173 | of_node_put(np); | ||
| 180 | return -ENOMEM; | 174 | return -ENOMEM; |
| 175 | } | ||
| 181 | 176 | ||
| 182 | for (i = 0; i < ARRAY_SIZE(regulators); i++) | 177 | for (i = 0; i < ARRAY_SIZE(regulators); i++) |
| 183 | rmatch[i].name = regulators[i].name; | 178 | rmatch[i].name = regulators[i].name; |
| 184 | 179 | ||
| 185 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators)); | 180 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators)); |
| 181 | of_node_put(np); | ||
| 186 | if (matched <= 0) | 182 | if (matched <= 0) |
| 187 | return matched; | 183 | return matched; |
| 188 | *rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL); | 184 | *rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL); |
| @@ -229,7 +225,6 @@ static int max77693_pmic_init_rdata(struct device *dev, | |||
| 229 | static int max77693_pmic_probe(struct platform_device *pdev) | 225 | static int max77693_pmic_probe(struct platform_device *pdev) |
| 230 | { | 226 | { |
| 231 | struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 227 | struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 232 | struct max77693_pmic_dev *max77693_pmic; | ||
| 233 | struct max77693_regulator_data *rdata = NULL; | 228 | struct max77693_regulator_data *rdata = NULL; |
| 234 | int num_rdata, i; | 229 | int num_rdata, i; |
| 235 | struct regulator_config config; | 230 | struct regulator_config config; |
| @@ -240,39 +235,22 @@ static int max77693_pmic_probe(struct platform_device *pdev) | |||
| 240 | return -ENODEV; | 235 | return -ENODEV; |
| 241 | } | 236 | } |
| 242 | 237 | ||
| 243 | max77693_pmic = devm_kzalloc(&pdev->dev, | ||
| 244 | sizeof(struct max77693_pmic_dev), | ||
| 245 | GFP_KERNEL); | ||
| 246 | if (!max77693_pmic) | ||
| 247 | return -ENOMEM; | ||
| 248 | |||
| 249 | max77693_pmic->rdev = devm_kzalloc(&pdev->dev, | ||
| 250 | sizeof(struct regulator_dev *) * num_rdata, | ||
| 251 | GFP_KERNEL); | ||
| 252 | if (!max77693_pmic->rdev) | ||
| 253 | return -ENOMEM; | ||
| 254 | |||
| 255 | max77693_pmic->dev = &pdev->dev; | ||
| 256 | max77693_pmic->iodev = iodev; | ||
| 257 | max77693_pmic->num_regulators = num_rdata; | ||
| 258 | |||
| 259 | config.dev = &pdev->dev; | 238 | config.dev = &pdev->dev; |
| 260 | config.regmap = iodev->regmap; | 239 | config.regmap = iodev->regmap; |
| 261 | config.driver_data = max77693_pmic; | ||
| 262 | platform_set_drvdata(pdev, max77693_pmic); | ||
| 263 | 240 | ||
| 264 | for (i = 0; i < max77693_pmic->num_regulators; i++) { | 241 | for (i = 0; i < num_rdata; i++) { |
| 265 | int id = rdata[i].id; | 242 | int id = rdata[i].id; |
| 243 | struct regulator_dev *rdev; | ||
| 266 | 244 | ||
| 267 | config.init_data = rdata[i].initdata; | 245 | config.init_data = rdata[i].initdata; |
| 268 | config.of_node = rdata[i].of_node; | 246 | config.of_node = rdata[i].of_node; |
| 269 | 247 | ||
| 270 | max77693_pmic->rdev[i] = devm_regulator_register(&pdev->dev, | 248 | rdev = devm_regulator_register(&pdev->dev, |
| 271 | ®ulators[id], &config); | 249 | ®ulators[id], &config); |
| 272 | if (IS_ERR(max77693_pmic->rdev[i])) { | 250 | if (IS_ERR(rdev)) { |
| 273 | dev_err(max77693_pmic->dev, | 251 | dev_err(&pdev->dev, |
| 274 | "Failed to initialize regulator-%d\n", id); | 252 | "Failed to initialize regulator-%d\n", id); |
| 275 | return PTR_ERR(max77693_pmic->rdev[i]); | 253 | return PTR_ERR(rdev); |
| 276 | } | 254 | } |
| 277 | } | 255 | } |
| 278 | 256 | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 7f049c92ee52..3172da847d24 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | #define MAX8649_RAMP_DOWN (1 << 1) | 49 | #define MAX8649_RAMP_DOWN (1 << 1) |
| 50 | 50 | ||
| 51 | struct max8649_regulator_info { | 51 | struct max8649_regulator_info { |
| 52 | struct regulator_dev *regulator; | ||
| 53 | struct device *dev; | 52 | struct device *dev; |
| 54 | struct regmap *regmap; | 53 | struct regmap *regmap; |
| 55 | 54 | ||
| @@ -154,6 +153,7 @@ static int max8649_regulator_probe(struct i2c_client *client, | |||
| 154 | { | 153 | { |
| 155 | struct max8649_platform_data *pdata = dev_get_platdata(&client->dev); | 154 | struct max8649_platform_data *pdata = dev_get_platdata(&client->dev); |
| 156 | struct max8649_regulator_info *info = NULL; | 155 | struct max8649_regulator_info *info = NULL; |
| 156 | struct regulator_dev *regulator; | ||
| 157 | struct regulator_config config = { }; | 157 | struct regulator_config config = { }; |
| 158 | unsigned int val; | 158 | unsigned int val; |
| 159 | unsigned char data; | 159 | unsigned char data; |
| @@ -234,12 +234,12 @@ static int max8649_regulator_probe(struct i2c_client *client, | |||
| 234 | config.driver_data = info; | 234 | config.driver_data = info; |
| 235 | config.regmap = info->regmap; | 235 | config.regmap = info->regmap; |
| 236 | 236 | ||
| 237 | info->regulator = devm_regulator_register(&client->dev, &dcdc_desc, | 237 | regulator = devm_regulator_register(&client->dev, &dcdc_desc, |
| 238 | &config); | 238 | &config); |
| 239 | if (IS_ERR(info->regulator)) { | 239 | if (IS_ERR(regulator)) { |
| 240 | dev_err(info->dev, "failed to register regulator %s\n", | 240 | dev_err(info->dev, "failed to register regulator %s\n", |
| 241 | dcdc_desc.name); | 241 | dcdc_desc.name); |
| 242 | return PTR_ERR(info->regulator); | 242 | return PTR_ERR(regulator); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | return 0; | 245 | return 0; |
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 8d94d3d7f97f..2fc411188794 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
| @@ -81,16 +81,17 @@ enum { | |||
| 81 | struct max8660 { | 81 | struct max8660 { |
| 82 | struct i2c_client *client; | 82 | struct i2c_client *client; |
| 83 | u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ | 83 | u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ |
| 84 | struct regulator_dev *rdev[]; | ||
| 85 | }; | 84 | }; |
| 86 | 85 | ||
| 87 | static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) | 86 | static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) |
| 88 | { | 87 | { |
| 89 | static const u8 max8660_addresses[MAX8660_N_REGS] = | 88 | static const u8 max8660_addresses[MAX8660_N_REGS] = { |
| 90 | { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 }; | 89 | 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 |
| 90 | }; | ||
| 91 | 91 | ||
| 92 | int ret; | 92 | int ret; |
| 93 | u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; | 93 | u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; |
| 94 | |||
| 94 | dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", | 95 | dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", |
| 95 | max8660_addresses[reg], reg_val); | 96 | max8660_addresses[reg], reg_val); |
| 96 | 97 | ||
| @@ -112,6 +113,7 @@ static int max8660_dcdc_is_enabled(struct regulator_dev *rdev) | |||
| 112 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 113 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 113 | u8 val = max8660->shadow_regs[MAX8660_OVER1]; | 114 | u8 val = max8660->shadow_regs[MAX8660_OVER1]; |
| 114 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; | 115 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; |
| 116 | |||
| 115 | return !!(val & mask); | 117 | return !!(val & mask); |
| 116 | } | 118 | } |
| 117 | 119 | ||
| @@ -119,6 +121,7 @@ static int max8660_dcdc_enable(struct regulator_dev *rdev) | |||
| 119 | { | 121 | { |
| 120 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 122 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 121 | u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; | 123 | u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; |
| 124 | |||
| 122 | return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); | 125 | return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); |
| 123 | } | 126 | } |
| 124 | 127 | ||
| @@ -126,15 +129,16 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev) | |||
| 126 | { | 129 | { |
| 127 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 130 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 128 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; | 131 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; |
| 132 | |||
| 129 | return max8660_write(max8660, MAX8660_OVER1, mask, 0); | 133 | return max8660_write(max8660, MAX8660_OVER1, mask, 0); |
| 130 | } | 134 | } |
| 131 | 135 | ||
| 132 | static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) | 136 | static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) |
| 133 | { | 137 | { |
| 134 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 138 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 135 | |||
| 136 | u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; | 139 | u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; |
| 137 | u8 selector = max8660->shadow_regs[reg]; | 140 | u8 selector = max8660->shadow_regs[reg]; |
| 141 | |||
| 138 | return selector; | 142 | return selector; |
| 139 | } | 143 | } |
| 140 | 144 | ||
| @@ -207,6 +211,7 @@ static int max8660_ldo67_is_enabled(struct regulator_dev *rdev) | |||
| 207 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 211 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 208 | u8 val = max8660->shadow_regs[MAX8660_OVER2]; | 212 | u8 val = max8660->shadow_regs[MAX8660_OVER2]; |
| 209 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; | 213 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; |
| 214 | |||
| 210 | return !!(val & mask); | 215 | return !!(val & mask); |
| 211 | } | 216 | } |
| 212 | 217 | ||
| @@ -214,6 +219,7 @@ static int max8660_ldo67_enable(struct regulator_dev *rdev) | |||
| 214 | { | 219 | { |
| 215 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 220 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 216 | u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; | 221 | u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; |
| 222 | |||
| 217 | return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); | 223 | return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); |
| 218 | } | 224 | } |
| 219 | 225 | ||
| @@ -221,15 +227,16 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev) | |||
| 221 | { | 227 | { |
| 222 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 228 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 223 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; | 229 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; |
| 230 | |||
| 224 | return max8660_write(max8660, MAX8660_OVER2, mask, 0); | 231 | return max8660_write(max8660, MAX8660_OVER2, mask, 0); |
| 225 | } | 232 | } |
| 226 | 233 | ||
| 227 | static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) | 234 | static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) |
| 228 | { | 235 | { |
| 229 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 236 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 230 | |||
| 231 | u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; | 237 | u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; |
| 232 | u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; | 238 | u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; |
| 239 | |||
| 233 | return selector; | 240 | return selector; |
| 234 | } | 241 | } |
| 235 | 242 | ||
| @@ -330,7 +337,7 @@ static int max8660_pdata_from_dt(struct device *dev, | |||
| 330 | struct max8660_subdev_data *sub; | 337 | struct max8660_subdev_data *sub; |
| 331 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; | 338 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; |
| 332 | 339 | ||
| 333 | np = of_find_node_by_name(dev->of_node, "regulators"); | 340 | np = of_get_child_by_name(dev->of_node, "regulators"); |
| 334 | if (!np) { | 341 | if (!np) { |
| 335 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | 342 | dev_err(dev, "missing 'regulators' subnode in DT\n"); |
| 336 | return -EINVAL; | 343 | return -EINVAL; |
| @@ -340,6 +347,7 @@ static int max8660_pdata_from_dt(struct device *dev, | |||
| 340 | rmatch[i].name = max8660_reg[i].name; | 347 | rmatch[i].name = max8660_reg[i].name; |
| 341 | 348 | ||
| 342 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); | 349 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); |
| 350 | of_node_put(np); | ||
| 343 | if (matched <= 0) | 351 | if (matched <= 0) |
| 344 | return matched; | 352 | return matched; |
| 345 | 353 | ||
| @@ -373,7 +381,6 @@ static inline int max8660_pdata_from_dt(struct device *dev, | |||
| 373 | static int max8660_probe(struct i2c_client *client, | 381 | static int max8660_probe(struct i2c_client *client, |
| 374 | const struct i2c_device_id *i2c_id) | 382 | const struct i2c_device_id *i2c_id) |
| 375 | { | 383 | { |
| 376 | struct regulator_dev **rdev; | ||
| 377 | struct device *dev = &client->dev; | 384 | struct device *dev = &client->dev; |
| 378 | struct max8660_platform_data *pdata = dev_get_platdata(dev); | 385 | struct max8660_platform_data *pdata = dev_get_platdata(dev); |
| 379 | struct regulator_config config = { }; | 386 | struct regulator_config config = { }; |
| @@ -406,14 +413,11 @@ static int max8660_probe(struct i2c_client *client, | |||
| 406 | return -EINVAL; | 413 | return -EINVAL; |
| 407 | } | 414 | } |
| 408 | 415 | ||
| 409 | max8660 = devm_kzalloc(dev, sizeof(struct max8660) + | 416 | max8660 = devm_kzalloc(dev, sizeof(struct max8660), GFP_KERNEL); |
| 410 | sizeof(struct regulator_dev *) * MAX8660_V_END, | ||
| 411 | GFP_KERNEL); | ||
| 412 | if (!max8660) | 417 | if (!max8660) |
| 413 | return -ENOMEM; | 418 | return -ENOMEM; |
| 414 | 419 | ||
| 415 | max8660->client = client; | 420 | max8660->client = client; |
| 416 | rdev = max8660->rdev; | ||
| 417 | 421 | ||
| 418 | if (pdata->en34_is_high) { | 422 | if (pdata->en34_is_high) { |
| 419 | /* Simulate always on */ | 423 | /* Simulate always on */ |
| @@ -481,6 +485,7 @@ static int max8660_probe(struct i2c_client *client, | |||
| 481 | 485 | ||
| 482 | /* Finally register devices */ | 486 | /* Finally register devices */ |
| 483 | for (i = 0; i < pdata->num_subdevs; i++) { | 487 | for (i = 0; i < pdata->num_subdevs; i++) { |
| 488 | struct regulator_dev *rdev; | ||
| 484 | 489 | ||
| 485 | id = pdata->subdevs[i].id; | 490 | id = pdata->subdevs[i].id; |
| 486 | 491 | ||
| @@ -489,13 +494,13 @@ static int max8660_probe(struct i2c_client *client, | |||
| 489 | config.of_node = of_node[i]; | 494 | config.of_node = of_node[i]; |
| 490 | config.driver_data = max8660; | 495 | config.driver_data = max8660; |
| 491 | 496 | ||
| 492 | rdev[i] = devm_regulator_register(&client->dev, | 497 | rdev = devm_regulator_register(&client->dev, |
| 493 | &max8660_reg[id], &config); | 498 | &max8660_reg[id], &config); |
| 494 | if (IS_ERR(rdev[i])) { | 499 | if (IS_ERR(rdev)) { |
| 495 | ret = PTR_ERR(rdev[i]); | 500 | ret = PTR_ERR(rdev); |
| 496 | dev_err(&client->dev, "failed to register %s\n", | 501 | dev_err(&client->dev, "failed to register %s\n", |
| 497 | max8660_reg[id].name); | 502 | max8660_reg[id].name); |
| 498 | return PTR_ERR(rdev[i]); | 503 | return PTR_ERR(rdev); |
| 499 | } | 504 | } |
| 500 | } | 505 | } |
| 501 | 506 | ||
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 0c5fe6c6ac26..9623e9e290bf 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | 34 | ||
| 35 | struct max8907_regulator { | 35 | struct max8907_regulator { |
| 36 | struct regulator_desc desc[MAX8907_NUM_REGULATORS]; | 36 | struct regulator_desc desc[MAX8907_NUM_REGULATORS]; |
| 37 | struct regulator_dev *rdev[MAX8907_NUM_REGULATORS]; | ||
| 38 | }; | 37 | }; |
| 39 | 38 | ||
| 40 | #define REG_MBATT() \ | 39 | #define REG_MBATT() \ |
| @@ -231,7 +230,7 @@ static int max8907_regulator_parse_dt(struct platform_device *pdev) | |||
| 231 | if (!np) | 230 | if (!np) |
| 232 | return 0; | 231 | return 0; |
| 233 | 232 | ||
| 234 | regulators = of_find_node_by_name(np, "regulators"); | 233 | regulators = of_get_child_by_name(np, "regulators"); |
| 235 | if (!regulators) { | 234 | if (!regulators) { |
| 236 | dev_err(&pdev->dev, "regulators node not found\n"); | 235 | dev_err(&pdev->dev, "regulators node not found\n"); |
| 237 | return -EINVAL; | 236 | return -EINVAL; |
| @@ -292,10 +291,9 @@ static int max8907_regulator_probe(struct platform_device *pdev) | |||
| 292 | return ret; | 291 | return ret; |
| 293 | 292 | ||
| 294 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | 293 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); |
| 295 | if (!pmic) { | 294 | if (!pmic) |
| 296 | dev_err(&pdev->dev, "Failed to alloc pmic\n"); | ||
| 297 | return -ENOMEM; | 295 | return -ENOMEM; |
| 298 | } | 296 | |
| 299 | platform_set_drvdata(pdev, pmic); | 297 | platform_set_drvdata(pdev, pmic); |
| 300 | 298 | ||
| 301 | memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); | 299 | memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); |
| @@ -311,6 +309,8 @@ static int max8907_regulator_probe(struct platform_device *pdev) | |||
| 311 | } | 309 | } |
| 312 | 310 | ||
| 313 | for (i = 0; i < MAX8907_NUM_REGULATORS; i++) { | 311 | for (i = 0; i < MAX8907_NUM_REGULATORS; i++) { |
| 312 | struct regulator_dev *rdev; | ||
| 313 | |||
| 314 | config.dev = pdev->dev.parent; | 314 | config.dev = pdev->dev.parent; |
| 315 | if (pdata) | 315 | if (pdata) |
| 316 | idata = pdata->init_data[i]; | 316 | idata = pdata->init_data[i]; |
| @@ -350,13 +350,13 @@ static int max8907_regulator_probe(struct platform_device *pdev) | |||
| 350 | pmic->desc[i].ops = &max8907_out5v_hwctl_ops; | 350 | pmic->desc[i].ops = &max8907_out5v_hwctl_ops; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | pmic->rdev[i] = devm_regulator_register(&pdev->dev, | 353 | rdev = devm_regulator_register(&pdev->dev, |
| 354 | &pmic->desc[i], &config); | 354 | &pmic->desc[i], &config); |
| 355 | if (IS_ERR(pmic->rdev[i])) { | 355 | if (IS_ERR(rdev)) { |
| 356 | dev_err(&pdev->dev, | 356 | dev_err(&pdev->dev, |
| 357 | "failed to register %s regulator\n", | 357 | "failed to register %s regulator\n", |
| 358 | pmic->desc[i].name); | 358 | pmic->desc[i].name); |
| 359 | return PTR_ERR(pmic->rdev[i]); | 359 | return PTR_ERR(rdev); |
| 360 | } | 360 | } |
| 361 | } | 361 | } |
| 362 | 362 | ||
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 759510789e71..dad2bcd14e96 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c | |||
| @@ -36,9 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | struct max8925_regulator_info { | 37 | struct max8925_regulator_info { |
| 38 | struct regulator_desc desc; | 38 | struct regulator_desc desc; |
| 39 | struct regulator_dev *regulator; | ||
| 40 | struct i2c_client *i2c; | 39 | struct i2c_client *i2c; |
| 41 | struct max8925_chip *chip; | ||
| 42 | 40 | ||
| 43 | int vol_reg; | 41 | int vol_reg; |
| 44 | int enable_reg; | 42 | int enable_reg; |
| @@ -251,10 +249,11 @@ static int max8925_regulator_dt_init(struct platform_device *pdev, | |||
| 251 | { | 249 | { |
| 252 | struct device_node *nproot, *np; | 250 | struct device_node *nproot, *np; |
| 253 | int rcount; | 251 | int rcount; |
| 252 | |||
| 254 | nproot = of_node_get(pdev->dev.parent->of_node); | 253 | nproot = of_node_get(pdev->dev.parent->of_node); |
| 255 | if (!nproot) | 254 | if (!nproot) |
| 256 | return -ENODEV; | 255 | return -ENODEV; |
| 257 | np = of_find_node_by_name(nproot, "regulators"); | 256 | np = of_get_child_by_name(nproot, "regulators"); |
| 258 | if (!np) { | 257 | if (!np) { |
| 259 | dev_err(&pdev->dev, "failed to find regulators node\n"); | 258 | dev_err(&pdev->dev, "failed to find regulators node\n"); |
| 260 | return -ENODEV; | 259 | return -ENODEV; |
| @@ -264,7 +263,7 @@ static int max8925_regulator_dt_init(struct platform_device *pdev, | |||
| 264 | &max8925_regulator_matches[ridx], 1); | 263 | &max8925_regulator_matches[ridx], 1); |
| 265 | of_node_put(np); | 264 | of_node_put(np); |
| 266 | if (rcount < 0) | 265 | if (rcount < 0) |
| 267 | return -ENODEV; | 266 | return rcount; |
| 268 | config->init_data = max8925_regulator_matches[ridx].init_data; | 267 | config->init_data = max8925_regulator_matches[ridx].init_data; |
| 269 | config->of_node = max8925_regulator_matches[ridx].of_node; | 268 | config->of_node = max8925_regulator_matches[ridx].of_node; |
| 270 | 269 | ||
| @@ -303,7 +302,6 @@ static int max8925_regulator_probe(struct platform_device *pdev) | |||
| 303 | return -EINVAL; | 302 | return -EINVAL; |
| 304 | } | 303 | } |
| 305 | ri->i2c = chip->i2c; | 304 | ri->i2c = chip->i2c; |
| 306 | ri->chip = chip; | ||
| 307 | 305 | ||
| 308 | config.dev = &pdev->dev; | 306 | config.dev = &pdev->dev; |
| 309 | config.driver_data = ri; | 307 | config.driver_data = ri; |
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 788e5ae2af1b..d920f5a32ec8 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c | |||
| @@ -48,9 +48,7 @@ enum { | |||
| 48 | 48 | ||
| 49 | struct max8952_data { | 49 | struct max8952_data { |
| 50 | struct i2c_client *client; | 50 | struct i2c_client *client; |
| 51 | struct device *dev; | ||
| 52 | struct max8952_platform_data *pdata; | 51 | struct max8952_platform_data *pdata; |
| 53 | struct regulator_dev *rdev; | ||
| 54 | 52 | ||
| 55 | bool vid0; | 53 | bool vid0; |
| 56 | bool vid1; | 54 | bool vid1; |
| @@ -59,6 +57,7 @@ struct max8952_data { | |||
| 59 | static int max8952_read_reg(struct max8952_data *max8952, u8 reg) | 57 | static int max8952_read_reg(struct max8952_data *max8952, u8 reg) |
| 60 | { | 58 | { |
| 61 | int ret = i2c_smbus_read_byte_data(max8952->client, reg); | 59 | int ret = i2c_smbus_read_byte_data(max8952->client, reg); |
| 60 | |||
| 62 | if (ret > 0) | 61 | if (ret > 0) |
| 63 | ret &= 0xff; | 62 | ret &= 0xff; |
| 64 | 63 | ||
| @@ -144,10 +143,8 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev) | |||
| 144 | int i; | 143 | int i; |
| 145 | 144 | ||
| 146 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); | 145 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); |
| 147 | if (!pd) { | 146 | if (!pd) |
| 148 | dev_err(dev, "Failed to allocate platform data\n"); | ||
| 149 | return NULL; | 147 | return NULL; |
| 150 | } | ||
| 151 | 148 | ||
| 152 | pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0); | 149 | pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0); |
| 153 | pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1); | 150 | pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1); |
| @@ -199,6 +196,7 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 199 | struct max8952_platform_data *pdata = dev_get_platdata(&client->dev); | 196 | struct max8952_platform_data *pdata = dev_get_platdata(&client->dev); |
| 200 | struct regulator_config config = { }; | 197 | struct regulator_config config = { }; |
| 201 | struct max8952_data *max8952; | 198 | struct max8952_data *max8952; |
| 199 | struct regulator_dev *rdev; | ||
| 202 | 200 | ||
| 203 | int ret = 0, err = 0; | 201 | int ret = 0, err = 0; |
| 204 | 202 | ||
| @@ -219,10 +217,9 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 219 | return -ENOMEM; | 217 | return -ENOMEM; |
| 220 | 218 | ||
| 221 | max8952->client = client; | 219 | max8952->client = client; |
| 222 | max8952->dev = &client->dev; | ||
| 223 | max8952->pdata = pdata; | 220 | max8952->pdata = pdata; |
| 224 | 221 | ||
| 225 | config.dev = max8952->dev; | 222 | config.dev = &client->dev; |
| 226 | config.init_data = pdata->reg_data; | 223 | config.init_data = pdata->reg_data; |
| 227 | config.driver_data = max8952; | 224 | config.driver_data = max8952; |
| 228 | config.of_node = client->dev.of_node; | 225 | config.of_node = client->dev.of_node; |
| @@ -231,11 +228,11 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 231 | if (pdata->reg_data->constraints.boot_on) | 228 | if (pdata->reg_data->constraints.boot_on) |
| 232 | config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; | 229 | config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; |
| 233 | 230 | ||
| 234 | max8952->rdev = regulator_register(®ulator, &config); | 231 | rdev = devm_regulator_register(&client->dev, ®ulator, &config); |
| 235 | 232 | ||
| 236 | if (IS_ERR(max8952->rdev)) { | 233 | if (IS_ERR(rdev)) { |
| 237 | ret = PTR_ERR(max8952->rdev); | 234 | ret = PTR_ERR(rdev); |
| 238 | dev_err(max8952->dev, "regulator init failed (%d)\n", ret); | 235 | dev_err(&client->dev, "regulator init failed (%d)\n", ret); |
| 239 | return ret; | 236 | return ret; |
| 240 | } | 237 | } |
| 241 | 238 | ||
| @@ -263,7 +260,7 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 263 | err = 3; | 260 | err = 3; |
| 264 | 261 | ||
| 265 | if (err) { | 262 | if (err) { |
| 266 | dev_warn(max8952->dev, "VID0/1 gpio invalid: " | 263 | dev_warn(&client->dev, "VID0/1 gpio invalid: " |
| 267 | "DVS not available.\n"); | 264 | "DVS not available.\n"); |
| 268 | max8952->vid0 = 0; | 265 | max8952->vid0 = 0; |
| 269 | max8952->vid1 = 0; | 266 | max8952->vid1 = 0; |
| @@ -274,7 +271,7 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 274 | /* Disable Pulldown of EN only */ | 271 | /* Disable Pulldown of EN only */ |
| 275 | max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60); | 272 | max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60); |
| 276 | 273 | ||
| 277 | dev_err(max8952->dev, "DVS modes disabled because VID0 and VID1" | 274 | dev_err(&client->dev, "DVS modes disabled because VID0 and VID1" |
| 278 | " do not have proper controls.\n"); | 275 | " do not have proper controls.\n"); |
| 279 | } else { | 276 | } else { |
| 280 | /* | 277 | /* |
| @@ -321,9 +318,6 @@ static int max8952_pmic_remove(struct i2c_client *client) | |||
| 321 | { | 318 | { |
| 322 | struct max8952_data *max8952 = i2c_get_clientdata(client); | 319 | struct max8952_data *max8952 = i2c_get_clientdata(client); |
| 323 | struct max8952_platform_data *pdata = max8952->pdata; | 320 | struct max8952_platform_data *pdata = max8952->pdata; |
| 324 | struct regulator_dev *rdev = max8952->rdev; | ||
| 325 | |||
| 326 | regulator_unregister(rdev); | ||
| 327 | 321 | ||
| 328 | gpio_free(pdata->gpio_vid0); | 322 | gpio_free(pdata->gpio_vid0); |
| 329 | gpio_free(pdata->gpio_vid1); | 323 | gpio_free(pdata->gpio_vid1); |
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 892aa1e5b96c..dbedf1768db0 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c | |||
| @@ -93,7 +93,6 @@ | |||
| 93 | struct max8973_chip { | 93 | struct max8973_chip { |
| 94 | struct device *dev; | 94 | struct device *dev; |
| 95 | struct regulator_desc desc; | 95 | struct regulator_desc desc; |
| 96 | struct regulator_dev *rdev; | ||
| 97 | struct regmap *regmap; | 96 | struct regmap *regmap; |
| 98 | bool enable_external_control; | 97 | bool enable_external_control; |
| 99 | int dvs_gpio; | 98 | int dvs_gpio; |
| @@ -379,10 +378,8 @@ static int max8973_probe(struct i2c_client *client, | |||
| 379 | } | 378 | } |
| 380 | 379 | ||
| 381 | max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); | 380 | max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); |
| 382 | if (!max) { | 381 | if (!max) |
| 383 | dev_err(&client->dev, "Memory allocation for max failed\n"); | ||
| 384 | return -ENOMEM; | 382 | return -ENOMEM; |
| 385 | } | ||
| 386 | 383 | ||
| 387 | max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config); | 384 | max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config); |
| 388 | if (IS_ERR(max->regmap)) { | 385 | if (IS_ERR(max->regmap)) { |
| @@ -474,7 +471,6 @@ static int max8973_probe(struct i2c_client *client, | |||
| 474 | return ret; | 471 | return ret; |
| 475 | } | 472 | } |
| 476 | 473 | ||
| 477 | max->rdev = rdev; | ||
| 478 | return 0; | 474 | return 0; |
| 479 | } | 475 | } |
| 480 | 476 | ||
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 2d618fc9c1af..90b4c530dee5 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
| @@ -38,7 +38,6 @@ struct max8997_data { | |||
| 38 | struct device *dev; | 38 | struct device *dev; |
| 39 | struct max8997_dev *iodev; | 39 | struct max8997_dev *iodev; |
| 40 | int num_regulators; | 40 | int num_regulators; |
| 41 | struct regulator_dev **rdev; | ||
| 42 | int ramp_delay; /* in mV/us */ | 41 | int ramp_delay; /* in mV/us */ |
| 43 | 42 | ||
| 44 | bool buck1_gpiodvs; | 43 | bool buck1_gpiodvs; |
| @@ -924,7 +923,7 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 924 | return -ENODEV; | 923 | return -ENODEV; |
| 925 | } | 924 | } |
| 926 | 925 | ||
| 927 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | 926 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); |
| 928 | if (!regulators_np) { | 927 | if (!regulators_np) { |
| 929 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 928 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
| 930 | return -EINVAL; | 929 | return -EINVAL; |
| @@ -937,7 +936,6 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 937 | pdata->num_regulators, GFP_KERNEL); | 936 | pdata->num_regulators, GFP_KERNEL); |
| 938 | if (!rdata) { | 937 | if (!rdata) { |
| 939 | of_node_put(regulators_np); | 938 | of_node_put(regulators_np); |
| 940 | dev_err(&pdev->dev, "could not allocate memory for regulator data\n"); | ||
| 941 | return -ENOMEM; | 939 | return -ENOMEM; |
| 942 | } | 940 | } |
| 943 | 941 | ||
| @@ -1030,10 +1028,10 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
| 1030 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 1028 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 1031 | struct max8997_platform_data *pdata = iodev->pdata; | 1029 | struct max8997_platform_data *pdata = iodev->pdata; |
| 1032 | struct regulator_config config = { }; | 1030 | struct regulator_config config = { }; |
| 1033 | struct regulator_dev **rdev; | 1031 | struct regulator_dev *rdev; |
| 1034 | struct max8997_data *max8997; | 1032 | struct max8997_data *max8997; |
| 1035 | struct i2c_client *i2c; | 1033 | struct i2c_client *i2c; |
| 1036 | int i, ret, size, nr_dvs; | 1034 | int i, ret, nr_dvs; |
| 1037 | u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; | 1035 | u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; |
| 1038 | 1036 | ||
| 1039 | if (!pdata) { | 1037 | if (!pdata) { |
| @@ -1052,12 +1050,6 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
| 1052 | if (!max8997) | 1050 | if (!max8997) |
| 1053 | return -ENOMEM; | 1051 | return -ENOMEM; |
| 1054 | 1052 | ||
| 1055 | size = sizeof(struct regulator_dev *) * pdata->num_regulators; | ||
| 1056 | max8997->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
| 1057 | if (!max8997->rdev) | ||
| 1058 | return -ENOMEM; | ||
| 1059 | |||
| 1060 | rdev = max8997->rdev; | ||
| 1061 | max8997->dev = &pdev->dev; | 1053 | max8997->dev = &pdev->dev; |
| 1062 | max8997->iodev = iodev; | 1054 | max8997->iodev = iodev; |
| 1063 | max8997->num_regulators = pdata->num_regulators; | 1055 | max8997->num_regulators = pdata->num_regulators; |
| @@ -1205,12 +1197,12 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
| 1205 | config.driver_data = max8997; | 1197 | config.driver_data = max8997; |
| 1206 | config.of_node = pdata->regulators[i].reg_node; | 1198 | config.of_node = pdata->regulators[i].reg_node; |
| 1207 | 1199 | ||
| 1208 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], | 1200 | rdev = devm_regulator_register(&pdev->dev, ®ulators[id], |
| 1209 | &config); | 1201 | &config); |
| 1210 | if (IS_ERR(rdev[i])) { | 1202 | if (IS_ERR(rdev)) { |
| 1211 | dev_err(max8997->dev, "regulator init failed for %d\n", | 1203 | dev_err(max8997->dev, "regulator init failed for %d\n", |
| 1212 | id); | 1204 | id); |
| 1213 | return PTR_ERR(rdev[i]); | 1205 | return PTR_ERR(rdev); |
| 1214 | } | 1206 | } |
| 1215 | } | 1207 | } |
| 1216 | 1208 | ||
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index ae3f0656feb0..961091b46557 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
| @@ -40,7 +40,6 @@ struct max8998_data { | |||
| 40 | struct device *dev; | 40 | struct device *dev; |
| 41 | struct max8998_dev *iodev; | 41 | struct max8998_dev *iodev; |
| 42 | int num_regulators; | 42 | int num_regulators; |
| 43 | struct regulator_dev **rdev; | ||
| 44 | u8 buck1_vol[4]; /* voltages for selection */ | 43 | u8 buck1_vol[4]; /* voltages for selection */ |
| 45 | u8 buck2_vol[2]; | 44 | u8 buck2_vol[2]; |
| 46 | unsigned int buck1_idx; /* index to last changed voltage */ | 45 | unsigned int buck1_idx; /* index to last changed voltage */ |
| @@ -674,8 +673,10 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, | |||
| 674 | 673 | ||
| 675 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * | 674 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * |
| 676 | pdata->num_regulators, GFP_KERNEL); | 675 | pdata->num_regulators, GFP_KERNEL); |
| 677 | if (!rdata) | 676 | if (!rdata) { |
| 677 | of_node_put(regulators_np); | ||
| 678 | return -ENOMEM; | 678 | return -ENOMEM; |
| 679 | } | ||
| 679 | 680 | ||
| 680 | pdata->regulators = rdata; | 681 | pdata->regulators = rdata; |
| 681 | for (i = 0; i < ARRAY_SIZE(regulators); ++i) { | 682 | for (i = 0; i < ARRAY_SIZE(regulators); ++i) { |
| @@ -692,6 +693,9 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, | |||
| 692 | } | 693 | } |
| 693 | pdata->num_regulators = rdata - pdata->regulators; | 694 | pdata->num_regulators = rdata - pdata->regulators; |
| 694 | 695 | ||
| 696 | of_node_put(reg_np); | ||
| 697 | of_node_put(regulators_np); | ||
| 698 | |||
| 695 | ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); | 699 | ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); |
| 696 | if (ret) | 700 | if (ret) |
| 697 | return -EINVAL; | 701 | return -EINVAL; |
| @@ -741,10 +745,10 @@ static int max8998_pmic_probe(struct platform_device *pdev) | |||
| 741 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 745 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 742 | struct max8998_platform_data *pdata = iodev->pdata; | 746 | struct max8998_platform_data *pdata = iodev->pdata; |
| 743 | struct regulator_config config = { }; | 747 | struct regulator_config config = { }; |
| 744 | struct regulator_dev **rdev; | 748 | struct regulator_dev *rdev; |
| 745 | struct max8998_data *max8998; | 749 | struct max8998_data *max8998; |
| 746 | struct i2c_client *i2c; | 750 | struct i2c_client *i2c; |
| 747 | int i, ret, size; | 751 | int i, ret; |
| 748 | unsigned int v; | 752 | unsigned int v; |
| 749 | 753 | ||
| 750 | if (!pdata) { | 754 | if (!pdata) { |
| @@ -763,12 +767,6 @@ static int max8998_pmic_probe(struct platform_device *pdev) | |||
| 763 | if (!max8998) | 767 | if (!max8998) |
| 764 | return -ENOMEM; | 768 | return -ENOMEM; |
| 765 | 769 | ||
| 766 | size = sizeof(struct regulator_dev *) * pdata->num_regulators; | ||
| 767 | max8998->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
| 768 | if (!max8998->rdev) | ||
| 769 | return -ENOMEM; | ||
| 770 | |||
| 771 | rdev = max8998->rdev; | ||
| 772 | max8998->dev = &pdev->dev; | 770 | max8998->dev = &pdev->dev; |
| 773 | max8998->iodev = iodev; | 771 | max8998->iodev = iodev; |
| 774 | max8998->num_regulators = pdata->num_regulators; | 772 | max8998->num_regulators = pdata->num_regulators; |
| @@ -872,13 +870,12 @@ static int max8998_pmic_probe(struct platform_device *pdev) | |||
| 872 | config.init_data = pdata->regulators[i].initdata; | 870 | config.init_data = pdata->regulators[i].initdata; |
| 873 | config.driver_data = max8998; | 871 | config.driver_data = max8998; |
| 874 | 872 | ||
| 875 | rdev[i] = devm_regulator_register(&pdev->dev, | 873 | rdev = devm_regulator_register(&pdev->dev, ®ulators[index], |
| 876 | ®ulators[index], &config); | 874 | &config); |
| 877 | if (IS_ERR(rdev[i])) { | 875 | if (IS_ERR(rdev)) { |
| 878 | ret = PTR_ERR(rdev[i]); | 876 | ret = PTR_ERR(rdev); |
| 879 | dev_err(max8998->dev, "regulator %s init failed (%d)\n", | 877 | dev_err(max8998->dev, "regulator %s init failed (%d)\n", |
| 880 | regulators[index].name, ret); | 878 | regulators[index].name, ret); |
| 881 | rdev[i] = NULL; | ||
| 882 | return ret; | 879 | return ret; |
| 883 | } | 880 | } |
| 884 | } | 881 | } |
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index da4859282302..05b971726ffa 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
| @@ -167,8 +167,10 @@ int mc13xxx_get_num_regulators_dt(struct platform_device *pdev) | |||
| 167 | struct device_node *parent; | 167 | struct device_node *parent; |
| 168 | int num; | 168 | int num; |
| 169 | 169 | ||
| 170 | of_node_get(pdev->dev.parent->of_node); | 170 | if (!pdev->dev.parent->of_node) |
| 171 | parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); | 171 | return -ENODEV; |
| 172 | |||
| 173 | parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); | ||
| 172 | if (!parent) | 174 | if (!parent) |
| 173 | return -ENODEV; | 175 | return -ENODEV; |
| 174 | 176 | ||
| @@ -187,8 +189,10 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( | |||
| 187 | struct device_node *parent, *child; | 189 | struct device_node *parent, *child; |
| 188 | int i, parsed = 0; | 190 | int i, parsed = 0; |
| 189 | 191 | ||
| 190 | of_node_get(pdev->dev.parent->of_node); | 192 | if (!pdev->dev.parent->of_node) |
| 191 | parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); | 193 | return NULL; |
| 194 | |||
| 195 | parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); | ||
| 192 | if (!parent) | 196 | if (!parent) |
| 193 | return NULL; | 197 | return NULL; |
| 194 | 198 | ||
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index ab174f20ca11..67e678c4301c 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c | |||
| @@ -56,6 +56,8 @@ | |||
| 56 | #define PFUZE100_VGEN5VOL 0x70 | 56 | #define PFUZE100_VGEN5VOL 0x70 |
| 57 | #define PFUZE100_VGEN6VOL 0x71 | 57 | #define PFUZE100_VGEN6VOL 0x71 |
| 58 | 58 | ||
| 59 | enum chips { PFUZE100, PFUZE200 }; | ||
| 60 | |||
| 59 | struct pfuze_regulator { | 61 | struct pfuze_regulator { |
| 60 | struct regulator_desc desc; | 62 | struct regulator_desc desc; |
| 61 | unsigned char stby_reg; | 63 | unsigned char stby_reg; |
| @@ -63,6 +65,7 @@ struct pfuze_regulator { | |||
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| 65 | struct pfuze_chip { | 67 | struct pfuze_chip { |
| 68 | int chip_id; | ||
| 66 | struct regmap *regmap; | 69 | struct regmap *regmap; |
| 67 | struct device *dev; | 70 | struct device *dev; |
| 68 | struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; | 71 | struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; |
| @@ -78,21 +81,23 @@ static const int pfuze100_vsnvs[] = { | |||
| 78 | }; | 81 | }; |
| 79 | 82 | ||
| 80 | static const struct i2c_device_id pfuze_device_id[] = { | 83 | static const struct i2c_device_id pfuze_device_id[] = { |
| 81 | {.name = "pfuze100"}, | 84 | {.name = "pfuze100", .driver_data = PFUZE100}, |
| 82 | {}, | 85 | {.name = "pfuze200", .driver_data = PFUZE200}, |
| 86 | { } | ||
| 83 | }; | 87 | }; |
| 84 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); | 88 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); |
| 85 | 89 | ||
| 86 | static const struct of_device_id pfuze_dt_ids[] = { | 90 | static const struct of_device_id pfuze_dt_ids[] = { |
| 87 | { .compatible = "fsl,pfuze100" }, | 91 | { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, |
| 88 | {}, | 92 | { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, |
| 93 | { } | ||
| 89 | }; | 94 | }; |
| 90 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); | 95 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); |
| 91 | 96 | ||
| 92 | static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | 97 | static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) |
| 93 | { | 98 | { |
| 94 | struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); | 99 | struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); |
| 95 | int id = rdev->desc->id; | 100 | int id = rdev_get_id(rdev); |
| 96 | unsigned int ramp_bits; | 101 | unsigned int ramp_bits; |
| 97 | int ret; | 102 | int ret; |
| 98 | 103 | ||
| @@ -139,14 +144,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 139 | 144 | ||
| 140 | }; | 145 | }; |
| 141 | 146 | ||
| 142 | #define PFUZE100_FIXED_REG(_name, base, voltage) \ | 147 | #define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \ |
| 143 | [PFUZE100_ ## _name] = { \ | 148 | [_chip ## _ ## _name] = { \ |
| 144 | .desc = { \ | 149 | .desc = { \ |
| 145 | .name = #_name, \ | 150 | .name = #_name, \ |
| 146 | .n_voltages = 1, \ | 151 | .n_voltages = 1, \ |
| 147 | .ops = &pfuze100_fixed_regulator_ops, \ | 152 | .ops = &pfuze100_fixed_regulator_ops, \ |
| 148 | .type = REGULATOR_VOLTAGE, \ | 153 | .type = REGULATOR_VOLTAGE, \ |
| 149 | .id = PFUZE100_ ## _name, \ | 154 | .id = _chip ## _ ## _name, \ |
| 150 | .owner = THIS_MODULE, \ | 155 | .owner = THIS_MODULE, \ |
| 151 | .min_uV = (voltage), \ | 156 | .min_uV = (voltage), \ |
| 152 | .enable_reg = (base), \ | 157 | .enable_reg = (base), \ |
| @@ -154,14 +159,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 154 | }, \ | 159 | }, \ |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 157 | #define PFUZE100_SW_REG(_name, base, min, max, step) \ | 162 | #define PFUZE100_SW_REG(_chip, _name, base, min, max, step) \ |
| 158 | [PFUZE100_ ## _name] = { \ | 163 | [_chip ## _ ## _name] = { \ |
| 159 | .desc = { \ | 164 | .desc = { \ |
| 160 | .name = #_name,\ | 165 | .name = #_name,\ |
| 161 | .n_voltages = ((max) - (min)) / (step) + 1, \ | 166 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
| 162 | .ops = &pfuze100_sw_regulator_ops, \ | 167 | .ops = &pfuze100_sw_regulator_ops, \ |
| 163 | .type = REGULATOR_VOLTAGE, \ | 168 | .type = REGULATOR_VOLTAGE, \ |
| 164 | .id = PFUZE100_ ## _name, \ | 169 | .id = _chip ## _ ## _name, \ |
| 165 | .owner = THIS_MODULE, \ | 170 | .owner = THIS_MODULE, \ |
| 166 | .min_uV = (min), \ | 171 | .min_uV = (min), \ |
| 167 | .uV_step = (step), \ | 172 | .uV_step = (step), \ |
| @@ -172,14 +177,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 172 | .stby_mask = 0x3f, \ | 177 | .stby_mask = 0x3f, \ |
| 173 | } | 178 | } |
| 174 | 179 | ||
| 175 | #define PFUZE100_SWB_REG(_name, base, mask, voltages) \ | 180 | #define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \ |
| 176 | [PFUZE100_ ## _name] = { \ | 181 | [_chip ## _ ## _name] = { \ |
| 177 | .desc = { \ | 182 | .desc = { \ |
| 178 | .name = #_name, \ | 183 | .name = #_name, \ |
| 179 | .n_voltages = ARRAY_SIZE(voltages), \ | 184 | .n_voltages = ARRAY_SIZE(voltages), \ |
| 180 | .ops = &pfuze100_swb_regulator_ops, \ | 185 | .ops = &pfuze100_swb_regulator_ops, \ |
| 181 | .type = REGULATOR_VOLTAGE, \ | 186 | .type = REGULATOR_VOLTAGE, \ |
| 182 | .id = PFUZE100_ ## _name, \ | 187 | .id = _chip ## _ ## _name, \ |
| 183 | .owner = THIS_MODULE, \ | 188 | .owner = THIS_MODULE, \ |
| 184 | .volt_table = voltages, \ | 189 | .volt_table = voltages, \ |
| 185 | .vsel_reg = (base), \ | 190 | .vsel_reg = (base), \ |
| @@ -187,14 +192,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 187 | }, \ | 192 | }, \ |
| 188 | } | 193 | } |
| 189 | 194 | ||
| 190 | #define PFUZE100_VGEN_REG(_name, base, min, max, step) \ | 195 | #define PFUZE100_VGEN_REG(_chip, _name, base, min, max, step) \ |
| 191 | [PFUZE100_ ## _name] = { \ | 196 | [_chip ## _ ## _name] = { \ |
| 192 | .desc = { \ | 197 | .desc = { \ |
| 193 | .name = #_name, \ | 198 | .name = #_name, \ |
| 194 | .n_voltages = ((max) - (min)) / (step) + 1, \ | 199 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
| 195 | .ops = &pfuze100_ldo_regulator_ops, \ | 200 | .ops = &pfuze100_ldo_regulator_ops, \ |
| 196 | .type = REGULATOR_VOLTAGE, \ | 201 | .type = REGULATOR_VOLTAGE, \ |
| 197 | .id = PFUZE100_ ## _name, \ | 202 | .id = _chip ## _ ## _name, \ |
| 198 | .owner = THIS_MODULE, \ | 203 | .owner = THIS_MODULE, \ |
| 199 | .min_uV = (min), \ | 204 | .min_uV = (min), \ |
| 200 | .uV_step = (step), \ | 205 | .uV_step = (step), \ |
| @@ -207,25 +212,45 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 207 | .stby_mask = 0x20, \ | 212 | .stby_mask = 0x20, \ |
| 208 | } | 213 | } |
| 209 | 214 | ||
| 215 | /* PFUZE100 */ | ||
| 210 | static struct pfuze_regulator pfuze100_regulators[] = { | 216 | static struct pfuze_regulator pfuze100_regulators[] = { |
| 211 | PFUZE100_SW_REG(SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), | 217 | PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), |
| 212 | PFUZE100_SW_REG(SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000), | 218 | PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000), |
| 213 | PFUZE100_SW_REG(SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), | 219 | PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), |
| 214 | PFUZE100_SW_REG(SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), | 220 | PFUZE100_SW_REG(PFUZE100, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), |
| 215 | PFUZE100_SW_REG(SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), | 221 | PFUZE100_SW_REG(PFUZE100, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), |
| 216 | PFUZE100_SW_REG(SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000), | 222 | PFUZE100_SW_REG(PFUZE100, SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000), |
| 217 | PFUZE100_SWB_REG(SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), | 223 | PFUZE100_SWB_REG(PFUZE100, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), |
| 218 | PFUZE100_SWB_REG(VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), | 224 | PFUZE100_SWB_REG(PFUZE100, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), |
| 219 | PFUZE100_FIXED_REG(VREFDDR, PFUZE100_VREFDDRCON, 750000), | 225 | PFUZE100_FIXED_REG(PFUZE100, VREFDDR, PFUZE100_VREFDDRCON, 750000), |
| 220 | PFUZE100_VGEN_REG(VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), | 226 | PFUZE100_VGEN_REG(PFUZE100, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), |
| 221 | PFUZE100_VGEN_REG(VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), | 227 | PFUZE100_VGEN_REG(PFUZE100, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), |
| 222 | PFUZE100_VGEN_REG(VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), | 228 | PFUZE100_VGEN_REG(PFUZE100, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), |
| 223 | PFUZE100_VGEN_REG(VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), | 229 | PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), |
| 224 | PFUZE100_VGEN_REG(VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), | 230 | PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), |
| 225 | PFUZE100_VGEN_REG(VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | 231 | PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), |
| 232 | }; | ||
| 233 | |||
| 234 | static struct pfuze_regulator pfuze200_regulators[] = { | ||
| 235 | PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), | ||
| 236 | PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), | ||
| 237 | PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), | ||
| 238 | PFUZE100_SW_REG(PFUZE200, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), | ||
| 239 | PFUZE100_SWB_REG(PFUZE200, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), | ||
| 240 | PFUZE100_SWB_REG(PFUZE200, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), | ||
| 241 | PFUZE100_FIXED_REG(PFUZE200, VREFDDR, PFUZE100_VREFDDRCON, 750000), | ||
| 242 | PFUZE100_VGEN_REG(PFUZE200, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), | ||
| 243 | PFUZE100_VGEN_REG(PFUZE200, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), | ||
| 244 | PFUZE100_VGEN_REG(PFUZE200, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), | ||
| 245 | PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), | ||
| 246 | PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), | ||
| 247 | PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | ||
| 226 | }; | 248 | }; |
| 227 | 249 | ||
| 250 | static struct pfuze_regulator *pfuze_regulators; | ||
| 251 | |||
| 228 | #ifdef CONFIG_OF | 252 | #ifdef CONFIG_OF |
| 253 | /* PFUZE100 */ | ||
| 229 | static struct of_regulator_match pfuze100_matches[] = { | 254 | static struct of_regulator_match pfuze100_matches[] = { |
| 230 | { .name = "sw1ab", }, | 255 | { .name = "sw1ab", }, |
| 231 | { .name = "sw1c", }, | 256 | { .name = "sw1c", }, |
| @@ -244,24 +269,56 @@ static struct of_regulator_match pfuze100_matches[] = { | |||
| 244 | { .name = "vgen6", }, | 269 | { .name = "vgen6", }, |
| 245 | }; | 270 | }; |
| 246 | 271 | ||
| 272 | /* PFUZE200 */ | ||
| 273 | static struct of_regulator_match pfuze200_matches[] = { | ||
| 274 | |||
| 275 | { .name = "sw1ab", }, | ||
| 276 | { .name = "sw2", }, | ||
| 277 | { .name = "sw3a", }, | ||
| 278 | { .name = "sw3b", }, | ||
| 279 | { .name = "swbst", }, | ||
| 280 | { .name = "vsnvs", }, | ||
| 281 | { .name = "vrefddr", }, | ||
| 282 | { .name = "vgen1", }, | ||
| 283 | { .name = "vgen2", }, | ||
| 284 | { .name = "vgen3", }, | ||
| 285 | { .name = "vgen4", }, | ||
| 286 | { .name = "vgen5", }, | ||
| 287 | { .name = "vgen6", }, | ||
| 288 | }; | ||
| 289 | |||
| 290 | static struct of_regulator_match *pfuze_matches; | ||
| 291 | |||
| 247 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | 292 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) |
| 248 | { | 293 | { |
| 249 | struct device *dev = chip->dev; | 294 | struct device *dev = chip->dev; |
| 250 | struct device_node *np, *parent; | 295 | struct device_node *np, *parent; |
| 251 | int ret; | 296 | int ret; |
| 252 | 297 | ||
| 253 | np = of_node_get(dev->parent->of_node); | 298 | np = of_node_get(dev->of_node); |
| 254 | if (!np) | 299 | if (!np) |
| 255 | return 0; | 300 | return -EINVAL; |
| 256 | 301 | ||
| 257 | parent = of_find_node_by_name(np, "regulators"); | 302 | parent = of_get_child_by_name(np, "regulators"); |
| 258 | if (!parent) { | 303 | if (!parent) { |
| 259 | dev_err(dev, "regulators node not found\n"); | 304 | dev_err(dev, "regulators node not found\n"); |
| 260 | return -EINVAL; | 305 | return -EINVAL; |
| 261 | } | 306 | } |
| 262 | 307 | ||
| 263 | ret = of_regulator_match(dev, parent, pfuze100_matches, | 308 | switch (chip->chip_id) { |
| 264 | ARRAY_SIZE(pfuze100_matches)); | 309 | case PFUZE200: |
| 310 | pfuze_matches = pfuze200_matches; | ||
| 311 | ret = of_regulator_match(dev, parent, pfuze200_matches, | ||
| 312 | ARRAY_SIZE(pfuze200_matches)); | ||
| 313 | break; | ||
| 314 | |||
| 315 | case PFUZE100: | ||
| 316 | default: | ||
| 317 | pfuze_matches = pfuze100_matches; | ||
| 318 | ret = of_regulator_match(dev, parent, pfuze100_matches, | ||
| 319 | ARRAY_SIZE(pfuze100_matches)); | ||
| 320 | break; | ||
| 321 | } | ||
| 265 | 322 | ||
| 266 | of_node_put(parent); | 323 | of_node_put(parent); |
| 267 | if (ret < 0) { | 324 | if (ret < 0) { |
| @@ -275,12 +332,12 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | |||
| 275 | 332 | ||
| 276 | static inline struct regulator_init_data *match_init_data(int index) | 333 | static inline struct regulator_init_data *match_init_data(int index) |
| 277 | { | 334 | { |
| 278 | return pfuze100_matches[index].init_data; | 335 | return pfuze_matches[index].init_data; |
| 279 | } | 336 | } |
| 280 | 337 | ||
| 281 | static inline struct device_node *match_of_node(int index) | 338 | static inline struct device_node *match_of_node(int index) |
| 282 | { | 339 | { |
| 283 | return pfuze100_matches[index].of_node; | 340 | return pfuze_matches[index].of_node; |
| 284 | } | 341 | } |
| 285 | #else | 342 | #else |
| 286 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | 343 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) |
| @@ -308,16 +365,14 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip) | |||
| 308 | if (ret) | 365 | if (ret) |
| 309 | return ret; | 366 | return ret; |
| 310 | 367 | ||
| 311 | switch (value & 0x0f) { | 368 | if (((value & 0x0f) == 0x8) && (pfuze_chip->chip_id == PFUZE100)) { |
| 312 | /* | 369 | /* |
| 313 | * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 | 370 | * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 |
| 314 | * as ID=8 | 371 | * as ID=8 in PFUZE100 |
| 315 | */ | 372 | */ |
| 316 | case 0x8: | ||
| 317 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); | 373 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); |
| 318 | case 0x0: | 374 | } else if ((value & 0x0f) != pfuze_chip->chip_id) { |
| 319 | break; | 375 | /* device id NOT match with your setting */ |
| 320 | default: | ||
| 321 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); | 376 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); |
| 322 | return -ENODEV; | 377 | return -ENODEV; |
| 323 | } | 378 | } |
| @@ -353,17 +408,31 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 353 | dev_get_platdata(&client->dev); | 408 | dev_get_platdata(&client->dev); |
| 354 | struct regulator_config config = { }; | 409 | struct regulator_config config = { }; |
| 355 | int i, ret; | 410 | int i, ret; |
| 411 | const struct of_device_id *match; | ||
| 412 | u32 regulator_num; | ||
| 413 | u32 sw_check_start, sw_check_end; | ||
| 356 | 414 | ||
| 357 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), | 415 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), |
| 358 | GFP_KERNEL); | 416 | GFP_KERNEL); |
| 359 | if (!pfuze_chip) | 417 | if (!pfuze_chip) |
| 360 | return -ENOMEM; | 418 | return -ENOMEM; |
| 361 | 419 | ||
| 362 | i2c_set_clientdata(client, pfuze_chip); | 420 | if (client->dev.of_node) { |
| 363 | 421 | match = of_match_device(of_match_ptr(pfuze_dt_ids), | |
| 364 | memcpy(pfuze_chip->regulator_descs, pfuze100_regulators, | 422 | &client->dev); |
| 365 | sizeof(pfuze_chip->regulator_descs)); | 423 | if (!match) { |
| 424 | dev_err(&client->dev, "Error: No device match found\n"); | ||
| 425 | return -ENODEV; | ||
| 426 | } | ||
| 427 | pfuze_chip->chip_id = (int)(long)match->data; | ||
| 428 | } else if (id) { | ||
| 429 | pfuze_chip->chip_id = id->driver_data; | ||
| 430 | } else { | ||
| 431 | dev_err(&client->dev, "No dts match or id table match found\n"); | ||
| 432 | return -ENODEV; | ||
| 433 | } | ||
| 366 | 434 | ||
| 435 | i2c_set_clientdata(client, pfuze_chip); | ||
| 367 | pfuze_chip->dev = &client->dev; | 436 | pfuze_chip->dev = &client->dev; |
| 368 | 437 | ||
| 369 | pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config); | 438 | pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config); |
| @@ -380,11 +449,34 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 380 | return ret; | 449 | return ret; |
| 381 | } | 450 | } |
| 382 | 451 | ||
| 452 | /* use the right regulators after identify the right device */ | ||
| 453 | switch (pfuze_chip->chip_id) { | ||
| 454 | case PFUZE200: | ||
| 455 | pfuze_regulators = pfuze200_regulators; | ||
| 456 | regulator_num = ARRAY_SIZE(pfuze200_regulators); | ||
| 457 | sw_check_start = PFUZE200_SW2; | ||
| 458 | sw_check_end = PFUZE200_SW3B; | ||
| 459 | break; | ||
| 460 | |||
| 461 | case PFUZE100: | ||
| 462 | default: | ||
| 463 | pfuze_regulators = pfuze100_regulators; | ||
| 464 | regulator_num = ARRAY_SIZE(pfuze100_regulators); | ||
| 465 | sw_check_start = PFUZE100_SW2; | ||
| 466 | sw_check_end = PFUZE100_SW4; | ||
| 467 | break; | ||
| 468 | } | ||
| 469 | dev_info(&client->dev, "pfuze%s found.\n", | ||
| 470 | (pfuze_chip->chip_id == PFUZE100) ? "100" : "200"); | ||
| 471 | |||
| 472 | memcpy(pfuze_chip->regulator_descs, pfuze_regulators, | ||
| 473 | sizeof(pfuze_chip->regulator_descs)); | ||
| 474 | |||
| 383 | ret = pfuze_parse_regulators_dt(pfuze_chip); | 475 | ret = pfuze_parse_regulators_dt(pfuze_chip); |
| 384 | if (ret) | 476 | if (ret) |
| 385 | return ret; | 477 | return ret; |
| 386 | 478 | ||
| 387 | for (i = 0; i < PFUZE100_MAX_REGULATOR; i++) { | 479 | for (i = 0; i < regulator_num; i++) { |
| 388 | struct regulator_init_data *init_data; | 480 | struct regulator_init_data *init_data; |
| 389 | struct regulator_desc *desc; | 481 | struct regulator_desc *desc; |
| 390 | int val; | 482 | int val; |
| @@ -397,7 +489,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 397 | init_data = match_init_data(i); | 489 | init_data = match_init_data(i); |
| 398 | 490 | ||
| 399 | /* SW2~SW4 high bit check and modify the voltage value table */ | 491 | /* SW2~SW4 high bit check and modify the voltage value table */ |
| 400 | if (i > PFUZE100_SW1C && i < PFUZE100_SWBST) { | 492 | if (i >= sw_check_start && i <= sw_check_end) { |
| 401 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); | 493 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); |
| 402 | if (val & 0x40) { | 494 | if (val & 0x40) { |
| 403 | desc->min_uV = 800000; | 495 | desc->min_uV = 800000; |
| @@ -415,7 +507,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 415 | devm_regulator_register(&client->dev, desc, &config); | 507 | devm_regulator_register(&client->dev, desc, &config); |
| 416 | if (IS_ERR(pfuze_chip->regulators[i])) { | 508 | if (IS_ERR(pfuze_chip->regulators[i])) { |
| 417 | dev_err(&client->dev, "register regulator%s failed\n", | 509 | dev_err(&client->dev, "register regulator%s failed\n", |
| 418 | pfuze100_regulators[i].desc.name); | 510 | pfuze_regulators[i].desc.name); |
| 419 | return PTR_ERR(pfuze_chip->regulators[i]); | 511 | return PTR_ERR(pfuze_chip->regulators[i]); |
| 420 | } | 512 | } |
| 421 | } | 513 | } |
| @@ -435,6 +527,6 @@ static struct i2c_driver pfuze_driver = { | |||
| 435 | module_i2c_driver(pfuze_driver); | 527 | module_i2c_driver(pfuze_driver); |
| 436 | 528 | ||
| 437 | MODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); | 529 | MODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); |
| 438 | MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100 PMIC"); | 530 | MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/PFUZE200 PMIC"); |
| 439 | MODULE_LICENSE("GPL v2"); | 531 | MODULE_LICENSE("GPL v2"); |
| 440 | MODULE_ALIAS("i2c:pfuze100-regulator"); | 532 | MODULE_ALIAS("i2c:pfuze100-regulator"); |
diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index b58affb33143..4c414ae109ae 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c | |||
| @@ -119,7 +119,6 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) | |||
| 119 | { | 119 | { |
| 120 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); | 120 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); |
| 121 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); | 121 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); |
| 122 | struct regulator_init_data *reg_data; | ||
| 123 | struct regulator_config config = { }; | 122 | struct regulator_config config = { }; |
| 124 | struct rc5t583_regulator *reg = NULL; | 123 | struct rc5t583_regulator *reg = NULL; |
| 125 | struct rc5t583_regulator *regs; | 124 | struct rc5t583_regulator *regs; |
| @@ -135,19 +134,11 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) | |||
| 135 | 134 | ||
| 136 | regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * | 135 | regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * |
| 137 | sizeof(struct rc5t583_regulator), GFP_KERNEL); | 136 | sizeof(struct rc5t583_regulator), GFP_KERNEL); |
| 138 | if (!regs) { | 137 | if (!regs) |
| 139 | dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); | ||
| 140 | return -ENOMEM; | 138 | return -ENOMEM; |
| 141 | } | ||
| 142 | 139 | ||
| 143 | 140 | ||
| 144 | for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { | 141 | for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { |
| 145 | reg_data = pdata->reg_init_data[id]; | ||
| 146 | |||
| 147 | /* No need to register if there is no regulator data */ | ||
| 148 | if (!reg_data) | ||
| 149 | continue; | ||
| 150 | |||
| 151 | reg = ®s[id]; | 142 | reg = ®s[id]; |
| 152 | ri = &rc5t583_reg_info[id]; | 143 | ri = &rc5t583_reg_info[id]; |
| 153 | reg->reg_info = ri; | 144 | reg->reg_info = ri; |
| @@ -169,7 +160,7 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) | |||
| 169 | 160 | ||
| 170 | skip_ext_pwr_config: | 161 | skip_ext_pwr_config: |
| 171 | config.dev = &pdev->dev; | 162 | config.dev = &pdev->dev; |
| 172 | config.init_data = reg_data; | 163 | config.init_data = pdata->reg_init_data[id]; |
| 173 | config.driver_data = reg; | 164 | config.driver_data = reg; |
| 174 | config.regmap = rc5t583->regmap; | 165 | config.regmap = rc5t583->regmap; |
| 175 | 166 | ||
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c new file mode 100644 index 000000000000..808b3aa7a42c --- /dev/null +++ b/drivers/regulator/s2mpa01.c | |||
| @@ -0,0 +1,481 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Samsung Electronics Co., Ltd | ||
| 3 | * http://www.samsung.com | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License as published by the | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/bug.h> | ||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/regmap.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/regulator/driver.h> | ||
| 21 | #include <linux/regulator/machine.h> | ||
| 22 | #include <linux/regulator/of_regulator.h> | ||
| 23 | #include <linux/mfd/samsung/core.h> | ||
| 24 | #include <linux/mfd/samsung/s2mpa01.h> | ||
| 25 | |||
| 26 | #define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators) | ||
| 27 | |||
| 28 | struct s2mpa01_info { | ||
| 29 | int ramp_delay24; | ||
| 30 | int ramp_delay3; | ||
| 31 | int ramp_delay5; | ||
| 32 | int ramp_delay16; | ||
| 33 | int ramp_delay7; | ||
| 34 | int ramp_delay8910; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static int get_ramp_delay(int ramp_delay) | ||
| 38 | { | ||
| 39 | unsigned char cnt = 0; | ||
| 40 | |||
| 41 | ramp_delay /= 6250; | ||
| 42 | |||
| 43 | while (true) { | ||
| 44 | ramp_delay = ramp_delay >> 1; | ||
| 45 | if (ramp_delay == 0) | ||
| 46 | break; | ||
| 47 | cnt++; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (cnt > 3) | ||
| 51 | cnt = 3; | ||
| 52 | |||
| 53 | return cnt; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | ||
| 57 | unsigned int old_selector, | ||
| 58 | unsigned int new_selector) | ||
| 59 | { | ||
| 60 | struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev); | ||
| 61 | unsigned int ramp_delay = 0; | ||
| 62 | int old_volt, new_volt; | ||
| 63 | |||
| 64 | switch (rdev->desc->id) { | ||
| 65 | case S2MPA01_BUCK2: | ||
| 66 | case S2MPA01_BUCK4: | ||
| 67 | ramp_delay = s2mpa01->ramp_delay24; | ||
| 68 | break; | ||
| 69 | case S2MPA01_BUCK3: | ||
| 70 | ramp_delay = s2mpa01->ramp_delay3; | ||
| 71 | break; | ||
| 72 | case S2MPA01_BUCK5: | ||
| 73 | ramp_delay = s2mpa01->ramp_delay5; | ||
| 74 | break; | ||
| 75 | case S2MPA01_BUCK1: | ||
| 76 | case S2MPA01_BUCK6: | ||
| 77 | ramp_delay = s2mpa01->ramp_delay16; | ||
| 78 | break; | ||
| 79 | case S2MPA01_BUCK7: | ||
| 80 | ramp_delay = s2mpa01->ramp_delay7; | ||
| 81 | break; | ||
| 82 | case S2MPA01_BUCK8: | ||
| 83 | case S2MPA01_BUCK9: | ||
| 84 | case S2MPA01_BUCK10: | ||
| 85 | ramp_delay = s2mpa01->ramp_delay8910; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (ramp_delay == 0) | ||
| 90 | ramp_delay = rdev->desc->ramp_delay; | ||
| 91 | |||
| 92 | old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector); | ||
| 93 | new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector); | ||
| 94 | |||
| 95 | return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); | ||
| 96 | } | ||
| 97 | |||
| 98 | static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | ||
| 99 | { | ||
| 100 | struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev); | ||
| 101 | unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2; | ||
| 102 | unsigned int ramp_enable = 1, enable_shift = 0; | ||
| 103 | int ret; | ||
| 104 | |||
| 105 | switch (rdev->desc->id) { | ||
| 106 | case S2MPA01_BUCK1: | ||
| 107 | enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT; | ||
| 108 | if (!ramp_delay) { | ||
| 109 | ramp_enable = 0; | ||
| 110 | break; | ||
| 111 | } | ||
| 112 | |||
| 113 | if (ramp_delay > s2mpa01->ramp_delay16) | ||
| 114 | s2mpa01->ramp_delay16 = ramp_delay; | ||
| 115 | else | ||
| 116 | ramp_delay = s2mpa01->ramp_delay16; | ||
| 117 | |||
| 118 | ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; | ||
| 119 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 120 | break; | ||
| 121 | case S2MPA01_BUCK2: | ||
| 122 | enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT; | ||
| 123 | if (!ramp_delay) { | ||
| 124 | ramp_enable = 0; | ||
| 125 | break; | ||
| 126 | } | ||
| 127 | |||
| 128 | if (ramp_delay > s2mpa01->ramp_delay24) | ||
| 129 | s2mpa01->ramp_delay24 = ramp_delay; | ||
| 130 | else | ||
| 131 | ramp_delay = s2mpa01->ramp_delay24; | ||
| 132 | |||
| 133 | ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT; | ||
| 134 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 135 | break; | ||
| 136 | case S2MPA01_BUCK3: | ||
| 137 | enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT; | ||
| 138 | if (!ramp_delay) { | ||
| 139 | ramp_enable = 0; | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | |||
| 143 | s2mpa01->ramp_delay3 = ramp_delay; | ||
| 144 | ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT; | ||
| 145 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 146 | break; | ||
| 147 | case S2MPA01_BUCK4: | ||
| 148 | enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT; | ||
| 149 | if (!ramp_delay) { | ||
| 150 | ramp_enable = 0; | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | |||
| 154 | if (ramp_delay > s2mpa01->ramp_delay24) | ||
| 155 | s2mpa01->ramp_delay24 = ramp_delay; | ||
| 156 | else | ||
| 157 | ramp_delay = s2mpa01->ramp_delay24; | ||
| 158 | |||
| 159 | ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT; | ||
| 160 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 161 | break; | ||
| 162 | case S2MPA01_BUCK5: | ||
| 163 | s2mpa01->ramp_delay5 = ramp_delay; | ||
| 164 | ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT; | ||
| 165 | break; | ||
| 166 | case S2MPA01_BUCK6: | ||
| 167 | if (ramp_delay > s2mpa01->ramp_delay16) | ||
| 168 | s2mpa01->ramp_delay16 = ramp_delay; | ||
| 169 | else | ||
| 170 | ramp_delay = s2mpa01->ramp_delay16; | ||
| 171 | |||
| 172 | ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; | ||
| 173 | break; | ||
| 174 | case S2MPA01_BUCK7: | ||
| 175 | s2mpa01->ramp_delay7 = ramp_delay; | ||
| 176 | ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT; | ||
| 177 | break; | ||
| 178 | case S2MPA01_BUCK8: | ||
| 179 | case S2MPA01_BUCK9: | ||
| 180 | case S2MPA01_BUCK10: | ||
| 181 | if (ramp_delay > s2mpa01->ramp_delay8910) | ||
| 182 | s2mpa01->ramp_delay8910 = ramp_delay; | ||
| 183 | else | ||
| 184 | ramp_delay = s2mpa01->ramp_delay8910; | ||
| 185 | |||
| 186 | ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT; | ||
| 187 | break; | ||
| 188 | default: | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | if (!ramp_enable) | ||
| 193 | goto ramp_disable; | ||
| 194 | |||
| 195 | if (enable_shift) { | ||
| 196 | ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, | ||
| 197 | 1 << enable_shift, 1 << enable_shift); | ||
| 198 | if (ret) { | ||
| 199 | dev_err(&rdev->dev, "failed to enable ramp rate\n"); | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | ramp_val = get_ramp_delay(ramp_delay); | ||
| 205 | |||
| 206 | return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift, | ||
| 207 | ramp_val << ramp_shift); | ||
| 208 | |||
| 209 | ramp_disable: | ||
| 210 | return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, | ||
| 211 | 1 << enable_shift, 0); | ||
| 212 | } | ||
| 213 | |||
| 214 | static struct regulator_ops s2mpa01_ldo_ops = { | ||
| 215 | .list_voltage = regulator_list_voltage_linear, | ||
| 216 | .map_voltage = regulator_map_voltage_linear, | ||
| 217 | .is_enabled = regulator_is_enabled_regmap, | ||
| 218 | .enable = regulator_enable_regmap, | ||
| 219 | .disable = regulator_disable_regmap, | ||
| 220 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 221 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 222 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 223 | }; | ||
| 224 | |||
| 225 | static struct regulator_ops s2mpa01_buck_ops = { | ||
| 226 | .list_voltage = regulator_list_voltage_linear, | ||
| 227 | .map_voltage = regulator_map_voltage_linear, | ||
| 228 | .is_enabled = regulator_is_enabled_regmap, | ||
| 229 | .enable = regulator_enable_regmap, | ||
| 230 | .disable = regulator_disable_regmap, | ||
| 231 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 232 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 233 | .set_voltage_time_sel = s2mpa01_regulator_set_voltage_time_sel, | ||
| 234 | .set_ramp_delay = s2mpa01_set_ramp_delay, | ||
| 235 | }; | ||
| 236 | |||
| 237 | #define regulator_desc_ldo1(num) { \ | ||
| 238 | .name = "LDO"#num, \ | ||
| 239 | .id = S2MPA01_LDO##num, \ | ||
| 240 | .ops = &s2mpa01_ldo_ops, \ | ||
| 241 | .type = REGULATOR_VOLTAGE, \ | ||
| 242 | .owner = THIS_MODULE, \ | ||
| 243 | .min_uV = S2MPA01_LDO_MIN, \ | ||
| 244 | .uV_step = S2MPA01_LDO_STEP1, \ | ||
| 245 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ | ||
| 246 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 247 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ | ||
| 248 | .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 249 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 250 | } | ||
| 251 | #define regulator_desc_ldo2(num) { \ | ||
| 252 | .name = "LDO"#num, \ | ||
| 253 | .id = S2MPA01_LDO##num, \ | ||
| 254 | .ops = &s2mpa01_ldo_ops, \ | ||
| 255 | .type = REGULATOR_VOLTAGE, \ | ||
| 256 | .owner = THIS_MODULE, \ | ||
| 257 | .min_uV = S2MPA01_LDO_MIN, \ | ||
| 258 | .uV_step = S2MPA01_LDO_STEP2, \ | ||
| 259 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ | ||
| 260 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 261 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ | ||
| 262 | .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 263 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 264 | } | ||
| 265 | |||
| 266 | #define regulator_desc_buck1_4(num) { \ | ||
| 267 | .name = "BUCK"#num, \ | ||
| 268 | .id = S2MPA01_BUCK##num, \ | ||
| 269 | .ops = &s2mpa01_buck_ops, \ | ||
| 270 | .type = REGULATOR_VOLTAGE, \ | ||
| 271 | .owner = THIS_MODULE, \ | ||
| 272 | .min_uV = S2MPA01_BUCK_MIN1, \ | ||
| 273 | .uV_step = S2MPA01_BUCK_STEP1, \ | ||
| 274 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 275 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 276 | .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \ | ||
| 277 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 278 | .enable_reg = S2MPA01_REG_B1CTRL1 + (num - 1) * 2, \ | ||
| 279 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 280 | } | ||
| 281 | |||
| 282 | #define regulator_desc_buck5 { \ | ||
| 283 | .name = "BUCK5", \ | ||
| 284 | .id = S2MPA01_BUCK5, \ | ||
| 285 | .ops = &s2mpa01_buck_ops, \ | ||
| 286 | .type = REGULATOR_VOLTAGE, \ | ||
| 287 | .owner = THIS_MODULE, \ | ||
| 288 | .min_uV = S2MPA01_BUCK_MIN2, \ | ||
| 289 | .uV_step = S2MPA01_BUCK_STEP1, \ | ||
| 290 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 291 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 292 | .vsel_reg = S2MPA01_REG_B5CTRL2, \ | ||
| 293 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 294 | .enable_reg = S2MPA01_REG_B5CTRL1, \ | ||
| 295 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 296 | } | ||
| 297 | |||
| 298 | #define regulator_desc_buck6_7(num) { \ | ||
| 299 | .name = "BUCK"#num, \ | ||
| 300 | .id = S2MPA01_BUCK##num, \ | ||
| 301 | .ops = &s2mpa01_buck_ops, \ | ||
| 302 | .type = REGULATOR_VOLTAGE, \ | ||
| 303 | .owner = THIS_MODULE, \ | ||
| 304 | .min_uV = S2MPA01_BUCK_MIN1, \ | ||
| 305 | .uV_step = S2MPA01_BUCK_STEP1, \ | ||
| 306 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 307 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 308 | .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ | ||
| 309 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 310 | .enable_reg = S2MPA01_REG_B6CTRL1 + (num - 6) * 2, \ | ||
| 311 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 312 | } | ||
| 313 | |||
| 314 | #define regulator_desc_buck8 { \ | ||
| 315 | .name = "BUCK8", \ | ||
| 316 | .id = S2MPA01_BUCK8, \ | ||
| 317 | .ops = &s2mpa01_buck_ops, \ | ||
| 318 | .type = REGULATOR_VOLTAGE, \ | ||
| 319 | .owner = THIS_MODULE, \ | ||
| 320 | .min_uV = S2MPA01_BUCK_MIN2, \ | ||
| 321 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
| 322 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 323 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 324 | .vsel_reg = S2MPA01_REG_B8CTRL2, \ | ||
| 325 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 326 | .enable_reg = S2MPA01_REG_B8CTRL1, \ | ||
| 327 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 328 | } | ||
| 329 | |||
| 330 | #define regulator_desc_buck9 { \ | ||
| 331 | .name = "BUCK9", \ | ||
| 332 | .id = S2MPA01_BUCK9, \ | ||
| 333 | .ops = &s2mpa01_buck_ops, \ | ||
| 334 | .type = REGULATOR_VOLTAGE, \ | ||
| 335 | .owner = THIS_MODULE, \ | ||
| 336 | .min_uV = S2MPA01_BUCK_MIN4, \ | ||
| 337 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
| 338 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 339 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 340 | .vsel_reg = S2MPA01_REG_B9CTRL2, \ | ||
| 341 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 342 | .enable_reg = S2MPA01_REG_B9CTRL1, \ | ||
| 343 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 344 | } | ||
| 345 | |||
| 346 | #define regulator_desc_buck10 { \ | ||
| 347 | .name = "BUCK10", \ | ||
| 348 | .id = S2MPA01_BUCK10, \ | ||
| 349 | .ops = &s2mpa01_buck_ops, \ | ||
| 350 | .type = REGULATOR_VOLTAGE, \ | ||
| 351 | .owner = THIS_MODULE, \ | ||
| 352 | .min_uV = S2MPA01_BUCK_MIN3, \ | ||
| 353 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
| 354 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 355 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 356 | .vsel_reg = S2MPA01_REG_B10CTRL2, \ | ||
| 357 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 358 | .enable_reg = S2MPA01_REG_B10CTRL1, \ | ||
| 359 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 360 | } | ||
| 361 | |||
| 362 | static struct regulator_desc regulators[] = { | ||
| 363 | regulator_desc_ldo2(1), | ||
| 364 | regulator_desc_ldo1(2), | ||
| 365 | regulator_desc_ldo1(3), | ||
| 366 | regulator_desc_ldo1(4), | ||
| 367 | regulator_desc_ldo1(5), | ||
| 368 | regulator_desc_ldo2(6), | ||
| 369 | regulator_desc_ldo1(7), | ||
| 370 | regulator_desc_ldo1(8), | ||
| 371 | regulator_desc_ldo1(9), | ||
| 372 | regulator_desc_ldo1(10), | ||
| 373 | regulator_desc_ldo2(11), | ||
| 374 | regulator_desc_ldo1(12), | ||
| 375 | regulator_desc_ldo1(13), | ||
| 376 | regulator_desc_ldo1(14), | ||
| 377 | regulator_desc_ldo1(15), | ||
| 378 | regulator_desc_ldo1(16), | ||
| 379 | regulator_desc_ldo1(17), | ||
| 380 | regulator_desc_ldo1(18), | ||
| 381 | regulator_desc_ldo1(19), | ||
| 382 | regulator_desc_ldo1(20), | ||
| 383 | regulator_desc_ldo1(21), | ||
| 384 | regulator_desc_ldo2(22), | ||
| 385 | regulator_desc_ldo2(23), | ||
| 386 | regulator_desc_ldo1(24), | ||
| 387 | regulator_desc_ldo1(25), | ||
| 388 | regulator_desc_ldo1(26), | ||
| 389 | regulator_desc_buck1_4(1), | ||
| 390 | regulator_desc_buck1_4(2), | ||
| 391 | regulator_desc_buck1_4(3), | ||
| 392 | regulator_desc_buck1_4(4), | ||
| 393 | regulator_desc_buck5, | ||
| 394 | regulator_desc_buck6_7(6), | ||
| 395 | regulator_desc_buck6_7(7), | ||
| 396 | regulator_desc_buck8, | ||
| 397 | regulator_desc_buck9, | ||
| 398 | regulator_desc_buck10, | ||
| 399 | }; | ||
| 400 | |||
| 401 | static int s2mpa01_pmic_probe(struct platform_device *pdev) | ||
| 402 | { | ||
| 403 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
| 404 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
| 405 | struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX]; | ||
| 406 | struct device_node *reg_np = NULL; | ||
| 407 | struct regulator_config config = { }; | ||
| 408 | struct s2mpa01_info *s2mpa01; | ||
| 409 | int i; | ||
| 410 | |||
| 411 | s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL); | ||
| 412 | if (!s2mpa01) | ||
| 413 | return -ENOMEM; | ||
| 414 | |||
| 415 | for (i = 0; i < S2MPA01_REGULATOR_CNT; i++) | ||
| 416 | rdata[i].name = regulators[i].name; | ||
| 417 | |||
| 418 | if (iodev->dev->of_node) { | ||
| 419 | reg_np = of_get_child_by_name(iodev->dev->of_node, | ||
| 420 | "regulators"); | ||
| 421 | if (!reg_np) { | ||
| 422 | dev_err(&pdev->dev, | ||
| 423 | "could not find regulators sub-node\n"); | ||
| 424 | return -EINVAL; | ||
| 425 | } | ||
| 426 | |||
| 427 | of_regulator_match(&pdev->dev, reg_np, rdata, | ||
| 428 | S2MPA01_REGULATOR_MAX); | ||
| 429 | of_node_put(reg_np); | ||
| 430 | } | ||
| 431 | |||
| 432 | platform_set_drvdata(pdev, s2mpa01); | ||
| 433 | |||
| 434 | config.dev = &pdev->dev; | ||
| 435 | config.regmap = iodev->regmap_pmic; | ||
| 436 | config.driver_data = s2mpa01; | ||
| 437 | |||
| 438 | for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) { | ||
| 439 | struct regulator_dev *rdev; | ||
| 440 | if (pdata) | ||
| 441 | config.init_data = pdata->regulators[i].initdata; | ||
| 442 | else | ||
| 443 | config.init_data = rdata[i].init_data; | ||
| 444 | |||
| 445 | if (reg_np) | ||
| 446 | config.of_node = rdata[i].of_node; | ||
| 447 | |||
| 448 | rdev = devm_regulator_register(&pdev->dev, | ||
| 449 | ®ulators[i], &config); | ||
| 450 | if (IS_ERR(rdev)) { | ||
| 451 | dev_err(&pdev->dev, "regulator init failed for %d\n", | ||
| 452 | i); | ||
| 453 | return PTR_ERR(rdev); | ||
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | static const struct platform_device_id s2mpa01_pmic_id[] = { | ||
| 461 | { "s2mpa01-pmic", 0}, | ||
| 462 | { }, | ||
| 463 | }; | ||
| 464 | MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id); | ||
| 465 | |||
| 466 | static struct platform_driver s2mpa01_pmic_driver = { | ||
| 467 | .driver = { | ||
| 468 | .name = "s2mpa01-pmic", | ||
| 469 | .owner = THIS_MODULE, | ||
| 470 | }, | ||
| 471 | .probe = s2mpa01_pmic_probe, | ||
| 472 | .id_table = s2mpa01_pmic_id, | ||
| 473 | }; | ||
| 474 | |||
| 475 | module_platform_driver(s2mpa01_pmic_driver); | ||
| 476 | |||
| 477 | /* Module information */ | ||
| 478 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | ||
| 479 | MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>"); | ||
| 480 | MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver"); | ||
| 481 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index cd0b9e35a56d..68fd54702edb 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
| @@ -1,13 +1,18 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * s2mps11.c | 2 | * s2mps11.c |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2012 Samsung Electronics Co., Ltd | 4 | * Copyright (c) 2012-2014 Samsung Electronics Co., Ltd |
| 5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| 8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
| 10 | * option) any later version. | 10 | * option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 11 | * | 16 | * |
| 12 | */ | 17 | */ |
| 13 | 18 | ||
| @@ -24,18 +29,21 @@ | |||
| 24 | #include <linux/regulator/of_regulator.h> | 29 | #include <linux/regulator/of_regulator.h> |
| 25 | #include <linux/mfd/samsung/core.h> | 30 | #include <linux/mfd/samsung/core.h> |
| 26 | #include <linux/mfd/samsung/s2mps11.h> | 31 | #include <linux/mfd/samsung/s2mps11.h> |
| 27 | 32 | #include <linux/mfd/samsung/s2mps14.h> | |
| 28 | #define S2MPS11_REGULATOR_CNT ARRAY_SIZE(regulators) | ||
| 29 | 33 | ||
| 30 | struct s2mps11_info { | 34 | struct s2mps11_info { |
| 31 | struct regulator_dev *rdev[S2MPS11_REGULATOR_MAX]; | 35 | unsigned int rdev_num; |
| 32 | |||
| 33 | int ramp_delay2; | 36 | int ramp_delay2; |
| 34 | int ramp_delay34; | 37 | int ramp_delay34; |
| 35 | int ramp_delay5; | 38 | int ramp_delay5; |
| 36 | int ramp_delay16; | 39 | int ramp_delay16; |
| 37 | int ramp_delay7810; | 40 | int ramp_delay7810; |
| 38 | int ramp_delay9; | 41 | int ramp_delay9; |
| 42 | /* | ||
| 43 | * One bit for each S2MPS14 regulator whether the suspend mode | ||
| 44 | * was enabled. | ||
| 45 | */ | ||
| 46 | unsigned int s2mps14_suspend_state:30; | ||
| 39 | }; | 47 | }; |
| 40 | 48 | ||
| 41 | static int get_ramp_delay(int ramp_delay) | 49 | static int get_ramp_delay(int ramp_delay) |
| @@ -65,7 +73,7 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | |||
| 65 | unsigned int ramp_delay = 0; | 73 | unsigned int ramp_delay = 0; |
| 66 | int old_volt, new_volt; | 74 | int old_volt, new_volt; |
| 67 | 75 | ||
| 68 | switch (rdev->desc->id) { | 76 | switch (rdev_get_id(rdev)) { |
| 69 | case S2MPS11_BUCK2: | 77 | case S2MPS11_BUCK2: |
| 70 | ramp_delay = s2mps11->ramp_delay2; | 78 | ramp_delay = s2mps11->ramp_delay2; |
| 71 | break; | 79 | break; |
| @@ -105,7 +113,7 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
| 105 | unsigned int ramp_enable = 1, enable_shift = 0; | 113 | unsigned int ramp_enable = 1, enable_shift = 0; |
| 106 | int ret; | 114 | int ret; |
| 107 | 115 | ||
| 108 | switch (rdev->desc->id) { | 116 | switch (rdev_get_id(rdev)) { |
| 109 | case S2MPS11_BUCK1: | 117 | case S2MPS11_BUCK1: |
| 110 | if (ramp_delay > s2mps11->ramp_delay16) | 118 | if (ramp_delay > s2mps11->ramp_delay16) |
| 111 | s2mps11->ramp_delay16 = ramp_delay; | 119 | s2mps11->ramp_delay16 = ramp_delay; |
| @@ -236,7 +244,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 236 | .set_ramp_delay = s2mps11_set_ramp_delay, | 244 | .set_ramp_delay = s2mps11_set_ramp_delay, |
| 237 | }; | 245 | }; |
| 238 | 246 | ||
| 239 | #define regulator_desc_ldo1(num) { \ | 247 | #define regulator_desc_s2mps11_ldo1(num) { \ |
| 240 | .name = "LDO"#num, \ | 248 | .name = "LDO"#num, \ |
| 241 | .id = S2MPS11_LDO##num, \ | 249 | .id = S2MPS11_LDO##num, \ |
| 242 | .ops = &s2mps11_ldo_ops, \ | 250 | .ops = &s2mps11_ldo_ops, \ |
| @@ -250,7 +258,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 250 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ | 258 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ |
| 251 | .enable_mask = S2MPS11_ENABLE_MASK \ | 259 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 252 | } | 260 | } |
| 253 | #define regulator_desc_ldo2(num) { \ | 261 | #define regulator_desc_s2mps11_ldo2(num) { \ |
| 254 | .name = "LDO"#num, \ | 262 | .name = "LDO"#num, \ |
| 255 | .id = S2MPS11_LDO##num, \ | 263 | .id = S2MPS11_LDO##num, \ |
| 256 | .ops = &s2mps11_ldo_ops, \ | 264 | .ops = &s2mps11_ldo_ops, \ |
| @@ -265,7 +273,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 265 | .enable_mask = S2MPS11_ENABLE_MASK \ | 273 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 266 | } | 274 | } |
| 267 | 275 | ||
| 268 | #define regulator_desc_buck1_4(num) { \ | 276 | #define regulator_desc_s2mps11_buck1_4(num) { \ |
| 269 | .name = "BUCK"#num, \ | 277 | .name = "BUCK"#num, \ |
| 270 | .id = S2MPS11_BUCK##num, \ | 278 | .id = S2MPS11_BUCK##num, \ |
| 271 | .ops = &s2mps11_buck_ops, \ | 279 | .ops = &s2mps11_buck_ops, \ |
| @@ -281,7 +289,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 281 | .enable_mask = S2MPS11_ENABLE_MASK \ | 289 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 282 | } | 290 | } |
| 283 | 291 | ||
| 284 | #define regulator_desc_buck5 { \ | 292 | #define regulator_desc_s2mps11_buck5 { \ |
| 285 | .name = "BUCK5", \ | 293 | .name = "BUCK5", \ |
| 286 | .id = S2MPS11_BUCK5, \ | 294 | .id = S2MPS11_BUCK5, \ |
| 287 | .ops = &s2mps11_buck_ops, \ | 295 | .ops = &s2mps11_buck_ops, \ |
| @@ -297,7 +305,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 297 | .enable_mask = S2MPS11_ENABLE_MASK \ | 305 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 298 | } | 306 | } |
| 299 | 307 | ||
| 300 | #define regulator_desc_buck6_8(num) { \ | 308 | #define regulator_desc_s2mps11_buck6_8(num) { \ |
| 301 | .name = "BUCK"#num, \ | 309 | .name = "BUCK"#num, \ |
| 302 | .id = S2MPS11_BUCK##num, \ | 310 | .id = S2MPS11_BUCK##num, \ |
| 303 | .ops = &s2mps11_buck_ops, \ | 311 | .ops = &s2mps11_buck_ops, \ |
| @@ -313,7 +321,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 313 | .enable_mask = S2MPS11_ENABLE_MASK \ | 321 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 314 | } | 322 | } |
| 315 | 323 | ||
| 316 | #define regulator_desc_buck9 { \ | 324 | #define regulator_desc_s2mps11_buck9 { \ |
| 317 | .name = "BUCK9", \ | 325 | .name = "BUCK9", \ |
| 318 | .id = S2MPS11_BUCK9, \ | 326 | .id = S2MPS11_BUCK9, \ |
| 319 | .ops = &s2mps11_buck_ops, \ | 327 | .ops = &s2mps11_buck_ops, \ |
| @@ -329,7 +337,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 329 | .enable_mask = S2MPS11_ENABLE_MASK \ | 337 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 330 | } | 338 | } |
| 331 | 339 | ||
| 332 | #define regulator_desc_buck10 { \ | 340 | #define regulator_desc_s2mps11_buck10 { \ |
| 333 | .name = "BUCK10", \ | 341 | .name = "BUCK10", \ |
| 334 | .id = S2MPS11_BUCK10, \ | 342 | .id = S2MPS11_BUCK10, \ |
| 335 | .ops = &s2mps11_buck_ops, \ | 343 | .ops = &s2mps11_buck_ops, \ |
| @@ -345,72 +353,252 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 345 | .enable_mask = S2MPS11_ENABLE_MASK \ | 353 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 346 | } | 354 | } |
| 347 | 355 | ||
| 348 | static struct regulator_desc regulators[] = { | 356 | static const struct regulator_desc s2mps11_regulators[] = { |
| 349 | regulator_desc_ldo2(1), | 357 | regulator_desc_s2mps11_ldo2(1), |
| 350 | regulator_desc_ldo1(2), | 358 | regulator_desc_s2mps11_ldo1(2), |
| 351 | regulator_desc_ldo1(3), | 359 | regulator_desc_s2mps11_ldo1(3), |
| 352 | regulator_desc_ldo1(4), | 360 | regulator_desc_s2mps11_ldo1(4), |
| 353 | regulator_desc_ldo1(5), | 361 | regulator_desc_s2mps11_ldo1(5), |
| 354 | regulator_desc_ldo2(6), | 362 | regulator_desc_s2mps11_ldo2(6), |
| 355 | regulator_desc_ldo1(7), | 363 | regulator_desc_s2mps11_ldo1(7), |
| 356 | regulator_desc_ldo1(8), | 364 | regulator_desc_s2mps11_ldo1(8), |
| 357 | regulator_desc_ldo1(9), | 365 | regulator_desc_s2mps11_ldo1(9), |
| 358 | regulator_desc_ldo1(10), | 366 | regulator_desc_s2mps11_ldo1(10), |
| 359 | regulator_desc_ldo2(11), | 367 | regulator_desc_s2mps11_ldo2(11), |
| 360 | regulator_desc_ldo1(12), | 368 | regulator_desc_s2mps11_ldo1(12), |
| 361 | regulator_desc_ldo1(13), | 369 | regulator_desc_s2mps11_ldo1(13), |
| 362 | regulator_desc_ldo1(14), | 370 | regulator_desc_s2mps11_ldo1(14), |
| 363 | regulator_desc_ldo1(15), | 371 | regulator_desc_s2mps11_ldo1(15), |
| 364 | regulator_desc_ldo1(16), | 372 | regulator_desc_s2mps11_ldo1(16), |
| 365 | regulator_desc_ldo1(17), | 373 | regulator_desc_s2mps11_ldo1(17), |
| 366 | regulator_desc_ldo1(18), | 374 | regulator_desc_s2mps11_ldo1(18), |
| 367 | regulator_desc_ldo1(19), | 375 | regulator_desc_s2mps11_ldo1(19), |
| 368 | regulator_desc_ldo1(20), | 376 | regulator_desc_s2mps11_ldo1(20), |
| 369 | regulator_desc_ldo1(21), | 377 | regulator_desc_s2mps11_ldo1(21), |
| 370 | regulator_desc_ldo2(22), | 378 | regulator_desc_s2mps11_ldo2(22), |
| 371 | regulator_desc_ldo2(23), | 379 | regulator_desc_s2mps11_ldo2(23), |
| 372 | regulator_desc_ldo1(24), | 380 | regulator_desc_s2mps11_ldo1(24), |
| 373 | regulator_desc_ldo1(25), | 381 | regulator_desc_s2mps11_ldo1(25), |
| 374 | regulator_desc_ldo1(26), | 382 | regulator_desc_s2mps11_ldo1(26), |
| 375 | regulator_desc_ldo2(27), | 383 | regulator_desc_s2mps11_ldo2(27), |
| 376 | regulator_desc_ldo1(28), | 384 | regulator_desc_s2mps11_ldo1(28), |
| 377 | regulator_desc_ldo1(29), | 385 | regulator_desc_s2mps11_ldo1(29), |
| 378 | regulator_desc_ldo1(30), | 386 | regulator_desc_s2mps11_ldo1(30), |
| 379 | regulator_desc_ldo1(31), | 387 | regulator_desc_s2mps11_ldo1(31), |
| 380 | regulator_desc_ldo1(32), | 388 | regulator_desc_s2mps11_ldo1(32), |
| 381 | regulator_desc_ldo1(33), | 389 | regulator_desc_s2mps11_ldo1(33), |
| 382 | regulator_desc_ldo1(34), | 390 | regulator_desc_s2mps11_ldo1(34), |
| 383 | regulator_desc_ldo1(35), | 391 | regulator_desc_s2mps11_ldo1(35), |
| 384 | regulator_desc_ldo1(36), | 392 | regulator_desc_s2mps11_ldo1(36), |
| 385 | regulator_desc_ldo1(37), | 393 | regulator_desc_s2mps11_ldo1(37), |
| 386 | regulator_desc_ldo1(38), | 394 | regulator_desc_s2mps11_ldo1(38), |
| 387 | regulator_desc_buck1_4(1), | 395 | regulator_desc_s2mps11_buck1_4(1), |
| 388 | regulator_desc_buck1_4(2), | 396 | regulator_desc_s2mps11_buck1_4(2), |
| 389 | regulator_desc_buck1_4(3), | 397 | regulator_desc_s2mps11_buck1_4(3), |
| 390 | regulator_desc_buck1_4(4), | 398 | regulator_desc_s2mps11_buck1_4(4), |
| 391 | regulator_desc_buck5, | 399 | regulator_desc_s2mps11_buck5, |
| 392 | regulator_desc_buck6_8(6), | 400 | regulator_desc_s2mps11_buck6_8(6), |
| 393 | regulator_desc_buck6_8(7), | 401 | regulator_desc_s2mps11_buck6_8(7), |
| 394 | regulator_desc_buck6_8(8), | 402 | regulator_desc_s2mps11_buck6_8(8), |
| 395 | regulator_desc_buck9, | 403 | regulator_desc_s2mps11_buck9, |
| 396 | regulator_desc_buck10, | 404 | regulator_desc_s2mps11_buck10, |
| 405 | }; | ||
| 406 | |||
| 407 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | ||
| 408 | { | ||
| 409 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
| 410 | unsigned int val; | ||
| 411 | |||
| 412 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | ||
| 413 | val = S2MPS14_ENABLE_SUSPEND; | ||
| 414 | else | ||
| 415 | val = rdev->desc->enable_mask; | ||
| 416 | |||
| 417 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 418 | rdev->desc->enable_mask, val); | ||
| 419 | } | ||
| 420 | |||
| 421 | static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | ||
| 422 | { | ||
| 423 | int ret; | ||
| 424 | unsigned int val; | ||
| 425 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
| 426 | |||
| 427 | /* LDO3 should be always on and does not support suspend mode */ | ||
| 428 | if (rdev_get_id(rdev) == S2MPS14_LDO3) | ||
| 429 | return 0; | ||
| 430 | |||
| 431 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); | ||
| 432 | if (ret < 0) | ||
| 433 | return ret; | ||
| 434 | |||
| 435 | s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev)); | ||
| 436 | /* | ||
| 437 | * Don't enable suspend mode if regulator is already disabled because | ||
| 438 | * this would effectively for a short time turn on the regulator after | ||
| 439 | * resuming. | ||
| 440 | * However we still want to toggle the suspend_state bit for regulator | ||
| 441 | * in case if it got enabled before suspending the system. | ||
| 442 | */ | ||
| 443 | if (!(val & rdev->desc->enable_mask)) | ||
| 444 | return 0; | ||
| 445 | |||
| 446 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 447 | rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); | ||
| 448 | } | ||
| 449 | |||
| 450 | static struct regulator_ops s2mps14_reg_ops = { | ||
| 451 | .list_voltage = regulator_list_voltage_linear, | ||
| 452 | .map_voltage = regulator_map_voltage_linear, | ||
| 453 | .is_enabled = regulator_is_enabled_regmap, | ||
| 454 | .enable = s2mps14_regulator_enable, | ||
| 455 | .disable = regulator_disable_regmap, | ||
| 456 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 457 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 458 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 459 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | ||
| 460 | }; | ||
| 461 | |||
| 462 | #define regulator_desc_s2mps14_ldo1(num) { \ | ||
| 463 | .name = "LDO"#num, \ | ||
| 464 | .id = S2MPS14_LDO##num, \ | ||
| 465 | .ops = &s2mps14_reg_ops, \ | ||
| 466 | .type = REGULATOR_VOLTAGE, \ | ||
| 467 | .owner = THIS_MODULE, \ | ||
| 468 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
| 469 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
| 470 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
| 471 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 472 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
| 473 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 474 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 475 | } | ||
| 476 | #define regulator_desc_s2mps14_ldo2(num) { \ | ||
| 477 | .name = "LDO"#num, \ | ||
| 478 | .id = S2MPS14_LDO##num, \ | ||
| 479 | .ops = &s2mps14_reg_ops, \ | ||
| 480 | .type = REGULATOR_VOLTAGE, \ | ||
| 481 | .owner = THIS_MODULE, \ | ||
| 482 | .min_uV = S2MPS14_LDO_MIN_1800MV, \ | ||
| 483 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
| 484 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
| 485 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 486 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
| 487 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 488 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 489 | } | ||
| 490 | #define regulator_desc_s2mps14_ldo3(num) { \ | ||
| 491 | .name = "LDO"#num, \ | ||
| 492 | .id = S2MPS14_LDO##num, \ | ||
| 493 | .ops = &s2mps14_reg_ops, \ | ||
| 494 | .type = REGULATOR_VOLTAGE, \ | ||
| 495 | .owner = THIS_MODULE, \ | ||
| 496 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
| 497 | .uV_step = S2MPS14_LDO_STEP_12_5MV, \ | ||
| 498 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
| 499 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 500 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
| 501 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 502 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 503 | } | ||
| 504 | #define regulator_desc_s2mps14_buck1235(num) { \ | ||
| 505 | .name = "BUCK"#num, \ | ||
| 506 | .id = S2MPS14_BUCK##num, \ | ||
| 507 | .ops = &s2mps14_reg_ops, \ | ||
| 508 | .type = REGULATOR_VOLTAGE, \ | ||
| 509 | .owner = THIS_MODULE, \ | ||
| 510 | .min_uV = S2MPS14_BUCK1235_MIN_600MV, \ | ||
| 511 | .uV_step = S2MPS14_BUCK1235_STEP_6_25MV, \ | ||
| 512 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
| 513 | .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ | ||
| 514 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
| 515 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
| 516 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
| 517 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
| 518 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 519 | } | ||
| 520 | #define regulator_desc_s2mps14_buck4(num) { \ | ||
| 521 | .name = "BUCK"#num, \ | ||
| 522 | .id = S2MPS14_BUCK##num, \ | ||
| 523 | .ops = &s2mps14_reg_ops, \ | ||
| 524 | .type = REGULATOR_VOLTAGE, \ | ||
| 525 | .owner = THIS_MODULE, \ | ||
| 526 | .min_uV = S2MPS14_BUCK4_MIN_1400MV, \ | ||
| 527 | .uV_step = S2MPS14_BUCK4_STEP_12_5MV, \ | ||
| 528 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
| 529 | .linear_min_sel = S2MPS14_BUCK4_START_SEL, \ | ||
| 530 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
| 531 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
| 532 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
| 533 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
| 534 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 535 | } | ||
| 536 | |||
| 537 | static const struct regulator_desc s2mps14_regulators[] = { | ||
| 538 | regulator_desc_s2mps14_ldo3(1), | ||
| 539 | regulator_desc_s2mps14_ldo3(2), | ||
| 540 | regulator_desc_s2mps14_ldo1(3), | ||
| 541 | regulator_desc_s2mps14_ldo1(4), | ||
| 542 | regulator_desc_s2mps14_ldo3(5), | ||
| 543 | regulator_desc_s2mps14_ldo3(6), | ||
| 544 | regulator_desc_s2mps14_ldo1(7), | ||
| 545 | regulator_desc_s2mps14_ldo2(8), | ||
| 546 | regulator_desc_s2mps14_ldo3(9), | ||
| 547 | regulator_desc_s2mps14_ldo3(10), | ||
| 548 | regulator_desc_s2mps14_ldo1(11), | ||
| 549 | regulator_desc_s2mps14_ldo2(12), | ||
| 550 | regulator_desc_s2mps14_ldo2(13), | ||
| 551 | regulator_desc_s2mps14_ldo2(14), | ||
| 552 | regulator_desc_s2mps14_ldo2(15), | ||
| 553 | regulator_desc_s2mps14_ldo2(16), | ||
| 554 | regulator_desc_s2mps14_ldo2(17), | ||
| 555 | regulator_desc_s2mps14_ldo2(18), | ||
| 556 | regulator_desc_s2mps14_ldo1(19), | ||
| 557 | regulator_desc_s2mps14_ldo1(20), | ||
| 558 | regulator_desc_s2mps14_ldo1(21), | ||
| 559 | regulator_desc_s2mps14_ldo3(22), | ||
| 560 | regulator_desc_s2mps14_ldo1(23), | ||
| 561 | regulator_desc_s2mps14_ldo2(24), | ||
| 562 | regulator_desc_s2mps14_ldo2(25), | ||
| 563 | regulator_desc_s2mps14_buck1235(1), | ||
| 564 | regulator_desc_s2mps14_buck1235(2), | ||
| 565 | regulator_desc_s2mps14_buck1235(3), | ||
| 566 | regulator_desc_s2mps14_buck4(4), | ||
| 567 | regulator_desc_s2mps14_buck1235(5), | ||
| 397 | }; | 568 | }; |
| 398 | 569 | ||
| 399 | static int s2mps11_pmic_probe(struct platform_device *pdev) | 570 | static int s2mps11_pmic_probe(struct platform_device *pdev) |
| 400 | { | 571 | { |
| 401 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 572 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 402 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); | 573 | struct sec_platform_data *pdata = iodev->pdata; |
| 403 | struct of_regulator_match rdata[S2MPS11_REGULATOR_MAX]; | 574 | struct of_regulator_match *rdata = NULL; |
| 404 | struct device_node *reg_np = NULL; | 575 | struct device_node *reg_np = NULL; |
| 405 | struct regulator_config config = { }; | 576 | struct regulator_config config = { }; |
| 406 | struct s2mps11_info *s2mps11; | 577 | struct s2mps11_info *s2mps11; |
| 407 | int i, ret; | 578 | int i, ret = 0; |
| 579 | const struct regulator_desc *regulators; | ||
| 580 | enum sec_device_type dev_type; | ||
| 408 | 581 | ||
| 409 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), | 582 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), |
| 410 | GFP_KERNEL); | 583 | GFP_KERNEL); |
| 411 | if (!s2mps11) | 584 | if (!s2mps11) |
| 412 | return -ENOMEM; | 585 | return -ENOMEM; |
| 413 | 586 | ||
| 587 | dev_type = platform_get_device_id(pdev)->driver_data; | ||
| 588 | switch (dev_type) { | ||
| 589 | case S2MPS11X: | ||
| 590 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); | ||
| 591 | regulators = s2mps11_regulators; | ||
| 592 | break; | ||
| 593 | case S2MPS14X: | ||
| 594 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); | ||
| 595 | regulators = s2mps14_regulators; | ||
| 596 | break; | ||
| 597 | default: | ||
| 598 | dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); | ||
| 599 | return -EINVAL; | ||
| 600 | }; | ||
| 601 | |||
| 414 | if (!iodev->dev->of_node) { | 602 | if (!iodev->dev->of_node) { |
| 415 | if (pdata) { | 603 | if (pdata) { |
| 416 | goto common_reg; | 604 | goto common_reg; |
| @@ -421,16 +609,22 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
| 421 | } | 609 | } |
| 422 | } | 610 | } |
| 423 | 611 | ||
| 424 | for (i = 0; i < S2MPS11_REGULATOR_CNT; i++) | 612 | rdata = kzalloc(sizeof(*rdata) * s2mps11->rdev_num, GFP_KERNEL); |
| 613 | if (!rdata) | ||
| 614 | return -ENOMEM; | ||
| 615 | |||
| 616 | for (i = 0; i < s2mps11->rdev_num; i++) | ||
| 425 | rdata[i].name = regulators[i].name; | 617 | rdata[i].name = regulators[i].name; |
| 426 | 618 | ||
| 427 | reg_np = of_find_node_by_name(iodev->dev->of_node, "regulators"); | 619 | reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); |
| 428 | if (!reg_np) { | 620 | if (!reg_np) { |
| 429 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 621 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
| 430 | return -EINVAL; | 622 | ret = -EINVAL; |
| 623 | goto out; | ||
| 431 | } | 624 | } |
| 432 | 625 | ||
| 433 | of_regulator_match(&pdev->dev, reg_np, rdata, S2MPS11_REGULATOR_MAX); | 626 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); |
| 627 | of_node_put(reg_np); | ||
| 434 | 628 | ||
| 435 | common_reg: | 629 | common_reg: |
| 436 | platform_set_drvdata(pdev, s2mps11); | 630 | platform_set_drvdata(pdev, s2mps11); |
| @@ -438,7 +632,9 @@ common_reg: | |||
| 438 | config.dev = &pdev->dev; | 632 | config.dev = &pdev->dev; |
| 439 | config.regmap = iodev->regmap_pmic; | 633 | config.regmap = iodev->regmap_pmic; |
| 440 | config.driver_data = s2mps11; | 634 | config.driver_data = s2mps11; |
| 441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { | 635 | for (i = 0; i < s2mps11->rdev_num; i++) { |
| 636 | struct regulator_dev *regulator; | ||
| 637 | |||
| 442 | if (!reg_np) { | 638 | if (!reg_np) { |
| 443 | config.init_data = pdata->regulators[i].initdata; | 639 | config.init_data = pdata->regulators[i].initdata; |
| 444 | config.of_node = pdata->regulators[i].reg_node; | 640 | config.of_node = pdata->regulators[i].reg_node; |
| @@ -447,21 +643,25 @@ common_reg: | |||
| 447 | config.of_node = rdata[i].of_node; | 643 | config.of_node = rdata[i].of_node; |
| 448 | } | 644 | } |
| 449 | 645 | ||
| 450 | s2mps11->rdev[i] = devm_regulator_register(&pdev->dev, | 646 | regulator = devm_regulator_register(&pdev->dev, |
| 451 | ®ulators[i], &config); | 647 | ®ulators[i], &config); |
| 452 | if (IS_ERR(s2mps11->rdev[i])) { | 648 | if (IS_ERR(regulator)) { |
| 453 | ret = PTR_ERR(s2mps11->rdev[i]); | 649 | ret = PTR_ERR(regulator); |
| 454 | dev_err(&pdev->dev, "regulator init failed for %d\n", | 650 | dev_err(&pdev->dev, "regulator init failed for %d\n", |
| 455 | i); | 651 | i); |
| 456 | return ret; | 652 | goto out; |
| 457 | } | 653 | } |
| 458 | } | 654 | } |
| 459 | 655 | ||
| 460 | return 0; | 656 | out: |
| 657 | kfree(rdata); | ||
| 658 | |||
| 659 | return ret; | ||
| 461 | } | 660 | } |
| 462 | 661 | ||
| 463 | static const struct platform_device_id s2mps11_pmic_id[] = { | 662 | static const struct platform_device_id s2mps11_pmic_id[] = { |
| 464 | { "s2mps11-pmic", 0}, | 663 | { "s2mps11-pmic", S2MPS11X}, |
| 664 | { "s2mps14-pmic", S2MPS14X}, | ||
| 465 | { }, | 665 | { }, |
| 466 | }; | 666 | }; |
| 467 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); | 667 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); |
| @@ -489,5 +689,5 @@ module_exit(s2mps11_pmic_exit); | |||
| 489 | 689 | ||
| 490 | /* Module information */ | 690 | /* Module information */ |
| 491 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | 691 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); |
| 492 | MODULE_DESCRIPTION("SAMSUNG S2MPS11 Regulator Driver"); | 692 | MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14 Regulator Driver"); |
| 493 | MODULE_LICENSE("GPL"); | 693 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index d958dfa05125..f05badabd69e 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c | |||
| @@ -11,11 +11,8 @@ | |||
| 11 | * | 11 | * |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/bug.h> | ||
| 15 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 16 | #include <linux/gpio.h> | ||
| 17 | #include <linux/of_gpio.h> | 15 | #include <linux/of_gpio.h> |
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 20 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 21 | #include <linux/regulator/driver.h> | 18 | #include <linux/regulator/driver.h> |
| @@ -170,12 +167,11 @@ static unsigned int s5m8767_opmode_reg[][4] = { | |||
| 170 | {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ | 167 | {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ |
| 171 | }; | 168 | }; |
| 172 | 169 | ||
| 173 | static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, | 170 | static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id, |
| 174 | int *enable_ctrl) | 171 | int *reg, int *enable_ctrl) |
| 175 | { | 172 | { |
| 176 | int i, reg_id = rdev_get_id(rdev); | 173 | int i; |
| 177 | unsigned int mode; | 174 | unsigned int mode; |
| 178 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 179 | 175 | ||
| 180 | switch (reg_id) { | 176 | switch (reg_id) { |
| 181 | case S5M8767_LDO1 ... S5M8767_LDO2: | 177 | case S5M8767_LDO1 ... S5M8767_LDO2: |
| @@ -214,53 +210,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, | |||
| 214 | return 0; | 210 | return 0; |
| 215 | } | 211 | } |
| 216 | 212 | ||
| 217 | static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) | ||
| 218 | { | ||
| 219 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 220 | int ret, reg; | ||
| 221 | int enable_ctrl; | ||
| 222 | unsigned int val; | ||
| 223 | |||
| 224 | ret = s5m8767_get_register(rdev, ®, &enable_ctrl); | ||
| 225 | if (ret == -EINVAL) | ||
| 226 | return 1; | ||
| 227 | else if (ret) | ||
| 228 | return ret; | ||
| 229 | |||
| 230 | ret = regmap_read(s5m8767->iodev->regmap_pmic, reg, &val); | ||
| 231 | if (ret) | ||
| 232 | return ret; | ||
| 233 | |||
| 234 | return (val & S5M8767_ENCTRL_MASK) == enable_ctrl; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int s5m8767_reg_enable(struct regulator_dev *rdev) | ||
| 238 | { | ||
| 239 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 240 | int ret, reg; | ||
| 241 | int enable_ctrl; | ||
| 242 | |||
| 243 | ret = s5m8767_get_register(rdev, ®, &enable_ctrl); | ||
| 244 | if (ret) | ||
| 245 | return ret; | ||
| 246 | |||
| 247 | return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg, | ||
| 248 | S5M8767_ENCTRL_MASK, enable_ctrl); | ||
| 249 | } | ||
| 250 | |||
| 251 | static int s5m8767_reg_disable(struct regulator_dev *rdev) | ||
| 252 | { | ||
| 253 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 254 | int ret, reg, enable_ctrl; | ||
| 255 | |||
| 256 | ret = s5m8767_get_register(rdev, ®, &enable_ctrl); | ||
| 257 | if (ret) | ||
| 258 | return ret; | ||
| 259 | |||
| 260 | return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg, | ||
| 261 | S5M8767_ENCTRL_MASK, ~S5M8767_ENCTRL_MASK); | ||
| 262 | } | ||
| 263 | |||
| 264 | static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) | 213 | static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) |
| 265 | { | 214 | { |
| 266 | int reg; | 215 | int reg; |
| @@ -410,9 +359,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, | |||
| 410 | 359 | ||
| 411 | static struct regulator_ops s5m8767_ops = { | 360 | static struct regulator_ops s5m8767_ops = { |
| 412 | .list_voltage = regulator_list_voltage_linear, | 361 | .list_voltage = regulator_list_voltage_linear, |
| 413 | .is_enabled = s5m8767_reg_is_enabled, | 362 | .is_enabled = regulator_is_enabled_regmap, |
| 414 | .enable = s5m8767_reg_enable, | 363 | .enable = regulator_enable_regmap, |
| 415 | .disable = s5m8767_reg_disable, | 364 | .disable = regulator_disable_regmap, |
| 416 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 365 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 417 | .set_voltage_sel = s5m8767_set_voltage_sel, | 366 | .set_voltage_sel = s5m8767_set_voltage_sel, |
| 418 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, | 367 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, |
| @@ -420,9 +369,9 @@ static struct regulator_ops s5m8767_ops = { | |||
| 420 | 369 | ||
| 421 | static struct regulator_ops s5m8767_buck78_ops = { | 370 | static struct regulator_ops s5m8767_buck78_ops = { |
| 422 | .list_voltage = regulator_list_voltage_linear, | 371 | .list_voltage = regulator_list_voltage_linear, |
| 423 | .is_enabled = s5m8767_reg_is_enabled, | 372 | .is_enabled = regulator_is_enabled_regmap, |
| 424 | .enable = s5m8767_reg_enable, | 373 | .enable = regulator_enable_regmap, |
| 425 | .disable = s5m8767_reg_disable, | 374 | .disable = regulator_disable_regmap, |
| 426 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 375 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 427 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 376 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 428 | }; | 377 | }; |
| @@ -483,6 +432,66 @@ static struct regulator_desc regulators[] = { | |||
| 483 | s5m8767_regulator_desc(BUCK9), | 432 | s5m8767_regulator_desc(BUCK9), |
| 484 | }; | 433 | }; |
| 485 | 434 | ||
| 435 | /* | ||
| 436 | * Enable GPIO control over BUCK9 in regulator_config for that regulator. | ||
| 437 | */ | ||
| 438 | static void s5m8767_regulator_config_ext_control(struct s5m8767_info *s5m8767, | ||
| 439 | struct sec_regulator_data *rdata, | ||
| 440 | struct regulator_config *config) | ||
| 441 | { | ||
| 442 | int i, mode = 0; | ||
| 443 | |||
| 444 | if (rdata->id != S5M8767_BUCK9) | ||
| 445 | return; | ||
| 446 | |||
| 447 | /* Check if opmode for regulator matches S5M8767_ENCTRL_USE_GPIO */ | ||
| 448 | for (i = 0; i < s5m8767->num_regulators; i++) { | ||
| 449 | const struct sec_opmode_data *opmode = &s5m8767->opmode[i]; | ||
| 450 | if (opmode->id == rdata->id) { | ||
| 451 | mode = s5m8767_opmode_reg[rdata->id][opmode->mode]; | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | } | ||
| 455 | if (mode != S5M8767_ENCTRL_USE_GPIO) { | ||
| 456 | dev_warn(s5m8767->dev, | ||
| 457 | "ext-control for %s: mismatched op_mode (%x), ignoring\n", | ||
| 458 | rdata->reg_node->name, mode); | ||
| 459 | return; | ||
| 460 | } | ||
| 461 | |||
| 462 | if (!gpio_is_valid(rdata->ext_control_gpio)) { | ||
| 463 | dev_warn(s5m8767->dev, | ||
| 464 | "ext-control for %s: GPIO not valid, ignoring\n", | ||
| 465 | rdata->reg_node->name); | ||
| 466 | return; | ||
| 467 | } | ||
| 468 | |||
| 469 | config->ena_gpio = rdata->ext_control_gpio; | ||
| 470 | config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
| 471 | } | ||
| 472 | |||
| 473 | /* | ||
| 474 | * Turn on GPIO control over BUCK9. | ||
| 475 | */ | ||
| 476 | static int s5m8767_enable_ext_control(struct s5m8767_info *s5m8767, | ||
| 477 | struct regulator_dev *rdev) | ||
| 478 | { | ||
| 479 | int id = rdev_get_id(rdev); | ||
| 480 | int ret, reg, enable_ctrl; | ||
| 481 | |||
| 482 | if (id != S5M8767_BUCK9) | ||
| 483 | return -EINVAL; | ||
| 484 | |||
| 485 | ret = s5m8767_get_register(s5m8767, id, ®, &enable_ctrl); | ||
| 486 | if (ret) | ||
| 487 | return ret; | ||
| 488 | |||
| 489 | return regmap_update_bits(s5m8767->iodev->regmap_pmic, | ||
| 490 | reg, S5M8767_ENCTRL_MASK, | ||
| 491 | S5M8767_ENCTRL_USE_GPIO << S5M8767_ENCTRL_SHIFT); | ||
| 492 | } | ||
| 493 | |||
| 494 | |||
| 486 | #ifdef CONFIG_OF | 495 | #ifdef CONFIG_OF |
| 487 | static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, | 496 | static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, |
| 488 | struct sec_platform_data *pdata, | 497 | struct sec_platform_data *pdata, |
| @@ -520,6 +529,16 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev, | |||
| 520 | return 0; | 529 | return 0; |
| 521 | } | 530 | } |
| 522 | 531 | ||
| 532 | static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev, | ||
| 533 | struct sec_regulator_data *rdata, | ||
| 534 | struct device_node *reg_np) | ||
| 535 | { | ||
| 536 | rdata->ext_control_gpio = of_get_named_gpio(reg_np, | ||
| 537 | "s5m8767,pmic-ext-control-gpios", 0); | ||
| 538 | if (!gpio_is_valid(rdata->ext_control_gpio)) | ||
| 539 | rdata->ext_control_gpio = 0; | ||
| 540 | } | ||
| 541 | |||
| 523 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | 542 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, |
| 524 | struct sec_platform_data *pdata) | 543 | struct sec_platform_data *pdata) |
| 525 | { | 544 | { |
| @@ -546,19 +565,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 546 | 565 | ||
| 547 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | 566 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
| 548 | pdata->num_regulators, GFP_KERNEL); | 567 | pdata->num_regulators, GFP_KERNEL); |
| 549 | if (!rdata) { | 568 | if (!rdata) |
| 550 | dev_err(iodev->dev, | ||
| 551 | "could not allocate memory for regulator data\n"); | ||
| 552 | return -ENOMEM; | 569 | return -ENOMEM; |
| 553 | } | ||
| 554 | 570 | ||
| 555 | rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * | 571 | rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * |
| 556 | pdata->num_regulators, GFP_KERNEL); | 572 | pdata->num_regulators, GFP_KERNEL); |
| 557 | if (!rmode) { | 573 | if (!rmode) |
| 558 | dev_err(iodev->dev, | ||
| 559 | "could not allocate memory for regulator mode\n"); | ||
| 560 | return -ENOMEM; | 574 | return -ENOMEM; |
| 561 | } | ||
| 562 | 575 | ||
| 563 | pdata->regulators = rdata; | 576 | pdata->regulators = rdata; |
| 564 | pdata->opmode = rmode; | 577 | pdata->opmode = rmode; |
| @@ -574,6 +587,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 574 | continue; | 587 | continue; |
| 575 | } | 588 | } |
| 576 | 589 | ||
| 590 | s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np); | ||
| 591 | |||
| 577 | rdata->id = i; | 592 | rdata->id = i; |
| 578 | rdata->initdata = of_get_regulator_init_data( | 593 | rdata->initdata = of_get_regulator_init_data( |
| 579 | &pdev->dev, reg_np); | 594 | &pdev->dev, reg_np); |
| @@ -922,6 +937,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 922 | for (i = 0; i < pdata->num_regulators; i++) { | 937 | for (i = 0; i < pdata->num_regulators; i++) { |
| 923 | const struct sec_voltage_desc *desc; | 938 | const struct sec_voltage_desc *desc; |
| 924 | int id = pdata->regulators[i].id; | 939 | int id = pdata->regulators[i].id; |
| 940 | int enable_reg, enable_val; | ||
| 925 | 941 | ||
| 926 | desc = reg_voltage_map[id]; | 942 | desc = reg_voltage_map[id]; |
| 927 | if (desc) { | 943 | if (desc) { |
| @@ -935,6 +951,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 935 | regulators[id].vsel_mask = 0x3f; | 951 | regulators[id].vsel_mask = 0x3f; |
| 936 | else | 952 | else |
| 937 | regulators[id].vsel_mask = 0xff; | 953 | regulators[id].vsel_mask = 0xff; |
| 954 | |||
| 955 | s5m8767_get_register(s5m8767, id, &enable_reg, | ||
| 956 | &enable_val); | ||
| 957 | regulators[id].enable_reg = enable_reg; | ||
| 958 | regulators[id].enable_mask = S5M8767_ENCTRL_MASK; | ||
| 959 | regulators[id].enable_val = enable_val; | ||
| 938 | } | 960 | } |
| 939 | 961 | ||
| 940 | config.dev = s5m8767->dev; | 962 | config.dev = s5m8767->dev; |
| @@ -942,6 +964,9 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 942 | config.driver_data = s5m8767; | 964 | config.driver_data = s5m8767; |
| 943 | config.regmap = iodev->regmap_pmic; | 965 | config.regmap = iodev->regmap_pmic; |
| 944 | config.of_node = pdata->regulators[i].reg_node; | 966 | config.of_node = pdata->regulators[i].reg_node; |
| 967 | if (pdata->regulators[i].ext_control_gpio) | ||
| 968 | s5m8767_regulator_config_ext_control(s5m8767, | ||
| 969 | &pdata->regulators[i], &config); | ||
| 945 | 970 | ||
| 946 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], | 971 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], |
| 947 | &config); | 972 | &config); |
| @@ -951,6 +976,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 951 | id); | 976 | id); |
| 952 | return ret; | 977 | return ret; |
| 953 | } | 978 | } |
| 979 | |||
| 980 | if (pdata->regulators[i].ext_control_gpio) { | ||
| 981 | ret = s5m8767_enable_ext_control(s5m8767, rdev[i]); | ||
| 982 | if (ret < 0) { | ||
| 983 | dev_err(s5m8767->dev, | ||
| 984 | "failed to enable gpio control over %s: %d\n", | ||
| 985 | rdev[i]->desc->name, ret); | ||
| 986 | return ret; | ||
| 987 | } | ||
| 988 | } | ||
| 954 | } | 989 | } |
| 955 | 990 | ||
| 956 | return 0; | 991 | return 0; |
diff --git a/drivers/regulator/st-pwm.c b/drivers/regulator/st-pwm.c new file mode 100644 index 000000000000..e367af1c5f9d --- /dev/null +++ b/drivers/regulator/st-pwm.c | |||
| @@ -0,0 +1,190 @@ | |||
| 1 | /* | ||
| 2 | * Regulator driver for ST's PWM Regulators | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 - STMicroelectronics Inc. | ||
| 5 | * | ||
| 6 | * Author: Lee Jones <lee.jones@linaro.org> | ||
| 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/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/regulator/driver.h> | ||
| 17 | #include <linux/regulator/machine.h> | ||
| 18 | #include <linux/regulator/of_regulator.h> | ||
| 19 | #include <linux/of.h> | ||
| 20 | #include <linux/of_device.h> | ||
| 21 | #include <linux/pwm.h> | ||
| 22 | |||
| 23 | #define ST_PWM_REG_PERIOD 8448 | ||
| 24 | |||
| 25 | struct st_pwm_regulator_pdata { | ||
| 26 | const struct regulator_desc *desc; | ||
| 27 | struct st_pwm_voltages *duty_cycle_table; | ||
| 28 | }; | ||
| 29 | |||
| 30 | struct st_pwm_regulator_data { | ||
| 31 | const struct st_pwm_regulator_pdata *pdata; | ||
| 32 | struct pwm_device *pwm; | ||
| 33 | bool enabled; | ||
| 34 | int state; | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct st_pwm_voltages { | ||
| 38 | unsigned int uV; | ||
| 39 | unsigned int dutycycle; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static int st_pwm_regulator_get_voltage_sel(struct regulator_dev *dev) | ||
| 43 | { | ||
| 44 | struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
| 45 | |||
| 46 | return drvdata->state; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int st_pwm_regulator_set_voltage_sel(struct regulator_dev *dev, | ||
| 50 | unsigned selector) | ||
| 51 | { | ||
| 52 | struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
| 53 | int dutycycle; | ||
| 54 | int ret; | ||
| 55 | |||
| 56 | dutycycle = (ST_PWM_REG_PERIOD / 100) * | ||
| 57 | drvdata->pdata->duty_cycle_table[selector].dutycycle; | ||
| 58 | |||
| 59 | ret = pwm_config(drvdata->pwm, dutycycle, ST_PWM_REG_PERIOD); | ||
| 60 | if (ret) { | ||
| 61 | dev_err(&dev->dev, "Failed to configure PWM\n"); | ||
| 62 | return ret; | ||
| 63 | } | ||
| 64 | |||
| 65 | drvdata->state = selector; | ||
| 66 | |||
| 67 | if (!drvdata->enabled) { | ||
| 68 | ret = pwm_enable(drvdata->pwm); | ||
| 69 | if (ret) { | ||
| 70 | dev_err(&dev->dev, "Failed to enable PWM\n"); | ||
| 71 | return ret; | ||
| 72 | } | ||
| 73 | drvdata->enabled = true; | ||
| 74 | } | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int st_pwm_regulator_list_voltage(struct regulator_dev *dev, | ||
| 80 | unsigned selector) | ||
| 81 | { | ||
| 82 | struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
| 83 | |||
| 84 | if (selector >= dev->desc->n_voltages) | ||
| 85 | return -EINVAL; | ||
| 86 | |||
| 87 | return drvdata->pdata->duty_cycle_table[selector].uV; | ||
| 88 | } | ||
| 89 | |||
| 90 | static struct regulator_ops st_pwm_regulator_voltage_ops = { | ||
| 91 | .set_voltage_sel = st_pwm_regulator_set_voltage_sel, | ||
| 92 | .get_voltage_sel = st_pwm_regulator_get_voltage_sel, | ||
| 93 | .list_voltage = st_pwm_regulator_list_voltage, | ||
| 94 | .map_voltage = regulator_map_voltage_iterate, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static struct st_pwm_voltages b2105_duty_cycle_table[] = { | ||
| 98 | { .uV = 1114000, .dutycycle = 0, }, | ||
| 99 | { .uV = 1095000, .dutycycle = 10, }, | ||
| 100 | { .uV = 1076000, .dutycycle = 20, }, | ||
| 101 | { .uV = 1056000, .dutycycle = 30, }, | ||
| 102 | { .uV = 1036000, .dutycycle = 40, }, | ||
| 103 | { .uV = 1016000, .dutycycle = 50, }, | ||
| 104 | /* WARNING: Values above 50% duty-cycle cause boot failures. */ | ||
| 105 | }; | ||
| 106 | |||
| 107 | static const struct regulator_desc b2105_desc = { | ||
| 108 | .name = "b2105-pwm-regulator", | ||
| 109 | .ops = &st_pwm_regulator_voltage_ops, | ||
| 110 | .type = REGULATOR_VOLTAGE, | ||
| 111 | .owner = THIS_MODULE, | ||
| 112 | .n_voltages = ARRAY_SIZE(b2105_duty_cycle_table), | ||
| 113 | .supply_name = "pwm", | ||
| 114 | }; | ||
| 115 | |||
| 116 | static const struct st_pwm_regulator_pdata b2105_info = { | ||
| 117 | .desc = &b2105_desc, | ||
| 118 | .duty_cycle_table = b2105_duty_cycle_table, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct of_device_id st_pwm_of_match[] = { | ||
| 122 | { .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, }, | ||
| 123 | { }, | ||
| 124 | }; | ||
| 125 | MODULE_DEVICE_TABLE(of, st_pwm_of_match); | ||
| 126 | |||
| 127 | static int st_pwm_regulator_probe(struct platform_device *pdev) | ||
| 128 | { | ||
| 129 | struct st_pwm_regulator_data *drvdata; | ||
| 130 | struct regulator_dev *regulator; | ||
| 131 | struct regulator_config config = { }; | ||
| 132 | struct device_node *np = pdev->dev.of_node; | ||
| 133 | const struct of_device_id *of_match; | ||
| 134 | |||
| 135 | if (!np) { | ||
| 136 | dev_err(&pdev->dev, "Device Tree node missing\n"); | ||
| 137 | return -EINVAL; | ||
| 138 | } | ||
| 139 | |||
| 140 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
| 141 | if (!drvdata) | ||
| 142 | return -ENOMEM; | ||
| 143 | |||
| 144 | of_match = of_match_device(st_pwm_of_match, &pdev->dev); | ||
| 145 | if (!of_match) { | ||
| 146 | dev_err(&pdev->dev, "failed to match of device\n"); | ||
| 147 | return -ENODEV; | ||
| 148 | } | ||
| 149 | drvdata->pdata = of_match->data; | ||
| 150 | |||
| 151 | config.init_data = of_get_regulator_init_data(&pdev->dev, np); | ||
| 152 | if (!config.init_data) | ||
| 153 | return -ENOMEM; | ||
| 154 | |||
| 155 | config.of_node = np; | ||
| 156 | config.dev = &pdev->dev; | ||
| 157 | config.driver_data = drvdata; | ||
| 158 | |||
| 159 | drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); | ||
| 160 | if (IS_ERR(drvdata->pwm)) { | ||
| 161 | dev_err(&pdev->dev, "Failed to get PWM\n"); | ||
| 162 | return PTR_ERR(drvdata->pwm); | ||
| 163 | } | ||
| 164 | |||
| 165 | regulator = devm_regulator_register(&pdev->dev, | ||
| 166 | drvdata->pdata->desc, &config); | ||
| 167 | if (IS_ERR(regulator)) { | ||
| 168 | dev_err(&pdev->dev, "Failed to register regulator %s\n", | ||
| 169 | drvdata->pdata->desc->name); | ||
| 170 | return PTR_ERR(regulator); | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | static struct platform_driver st_pwm_regulator_driver = { | ||
| 177 | .driver = { | ||
| 178 | .name = "st-pwm-regulator", | ||
| 179 | .owner = THIS_MODULE, | ||
| 180 | .of_match_table = of_match_ptr(st_pwm_of_match), | ||
| 181 | }, | ||
| 182 | .probe = st_pwm_regulator_probe, | ||
| 183 | }; | ||
| 184 | |||
| 185 | module_platform_driver(st_pwm_regulator_driver); | ||
| 186 | |||
| 187 | MODULE_LICENSE("GPL"); | ||
| 188 | MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>"); | ||
| 189 | MODULE_DESCRIPTION("ST PWM Regulator Driver"); | ||
| 190 | MODULE_ALIAS("platform:st_pwm-regulator"); | ||
diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index b187b6bba7ad..a2dabb575b97 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c | |||
| @@ -54,8 +54,8 @@ struct ti_abb_info { | |||
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | * struct ti_abb_reg - Register description for ABB block | 56 | * struct ti_abb_reg - Register description for ABB block |
| 57 | * @setup_reg: setup register offset from base | 57 | * @setup_off: setup register offset from base |
| 58 | * @control_reg: control register offset from base | 58 | * @control_off: control register offset from base |
| 59 | * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask | 59 | * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask |
| 60 | * @fbb_sel_mask: setup register- FBB sel mask | 60 | * @fbb_sel_mask: setup register- FBB sel mask |
| 61 | * @rbb_sel_mask: setup register- RBB sel mask | 61 | * @rbb_sel_mask: setup register- RBB sel mask |
| @@ -64,8 +64,8 @@ struct ti_abb_info { | |||
| 64 | * @opp_sel_mask: control register - mask for mode to operate | 64 | * @opp_sel_mask: control register - mask for mode to operate |
| 65 | */ | 65 | */ |
| 66 | struct ti_abb_reg { | 66 | struct ti_abb_reg { |
| 67 | u32 setup_reg; | 67 | u32 setup_off; |
| 68 | u32 control_reg; | 68 | u32 control_off; |
| 69 | 69 | ||
| 70 | /* Setup register fields */ | 70 | /* Setup register fields */ |
| 71 | u32 sr2_wtcnt_value_mask; | 71 | u32 sr2_wtcnt_value_mask; |
| @@ -83,6 +83,8 @@ struct ti_abb_reg { | |||
| 83 | * @rdesc: regulator descriptor | 83 | * @rdesc: regulator descriptor |
| 84 | * @clk: clock(usually sysclk) supplying ABB block | 84 | * @clk: clock(usually sysclk) supplying ABB block |
| 85 | * @base: base address of ABB block | 85 | * @base: base address of ABB block |
| 86 | * @setup_reg: setup register of ABB block | ||
| 87 | * @control_reg: control register of ABB block | ||
| 86 | * @int_base: interrupt register base address | 88 | * @int_base: interrupt register base address |
| 87 | * @efuse_base: (optional) efuse base address for ABB modes | 89 | * @efuse_base: (optional) efuse base address for ABB modes |
| 88 | * @ldo_base: (optional) LDOVBB vset override base address | 90 | * @ldo_base: (optional) LDOVBB vset override base address |
| @@ -99,6 +101,8 @@ struct ti_abb { | |||
| 99 | struct regulator_desc rdesc; | 101 | struct regulator_desc rdesc; |
| 100 | struct clk *clk; | 102 | struct clk *clk; |
| 101 | void __iomem *base; | 103 | void __iomem *base; |
| 104 | void __iomem *setup_reg; | ||
| 105 | void __iomem *control_reg; | ||
| 102 | void __iomem *int_base; | 106 | void __iomem *int_base; |
| 103 | void __iomem *efuse_base; | 107 | void __iomem *efuse_base; |
| 104 | void __iomem *ldo_base; | 108 | void __iomem *ldo_base; |
| @@ -118,20 +122,18 @@ struct ti_abb { | |||
| 118 | * ti_abb_rmw() - handy wrapper to set specific register bits | 122 | * ti_abb_rmw() - handy wrapper to set specific register bits |
| 119 | * @mask: mask for register field | 123 | * @mask: mask for register field |
| 120 | * @value: value shifted to mask location and written | 124 | * @value: value shifted to mask location and written |
| 121 | * @offset: offset of register | 125 | * @reg: register address |
| 122 | * @base: base address | ||
| 123 | * | 126 | * |
| 124 | * Return: final register value (may be unused) | 127 | * Return: final register value (may be unused) |
| 125 | */ | 128 | */ |
| 126 | static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset, | 129 | static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg) |
| 127 | void __iomem *base) | ||
| 128 | { | 130 | { |
| 129 | u32 val; | 131 | u32 val; |
| 130 | 132 | ||
| 131 | val = readl(base + offset); | 133 | val = readl(reg); |
| 132 | val &= ~mask; | 134 | val &= ~mask; |
| 133 | val |= (value << __ffs(mask)) & mask; | 135 | val |= (value << __ffs(mask)) & mask; |
| 134 | writel(val, base + offset); | 136 | writel(val, reg); |
| 135 | 137 | ||
| 136 | return val; | 138 | return val; |
| 137 | } | 139 | } |
| @@ -263,21 +265,19 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, | |||
| 263 | if (ret) | 265 | if (ret) |
| 264 | goto out; | 266 | goto out; |
| 265 | 267 | ||
| 266 | ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg, | 268 | ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg); |
| 267 | abb->base); | ||
| 268 | 269 | ||
| 269 | switch (info->opp_sel) { | 270 | switch (info->opp_sel) { |
| 270 | case TI_ABB_SLOW_OPP: | 271 | case TI_ABB_SLOW_OPP: |
| 271 | ti_abb_rmw(regs->rbb_sel_mask, 1, regs->setup_reg, abb->base); | 272 | ti_abb_rmw(regs->rbb_sel_mask, 1, abb->setup_reg); |
| 272 | break; | 273 | break; |
| 273 | case TI_ABB_FAST_OPP: | 274 | case TI_ABB_FAST_OPP: |
| 274 | ti_abb_rmw(regs->fbb_sel_mask, 1, regs->setup_reg, abb->base); | 275 | ti_abb_rmw(regs->fbb_sel_mask, 1, abb->setup_reg); |
| 275 | break; | 276 | break; |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | /* program next state of ABB ldo */ | 279 | /* program next state of ABB ldo */ |
| 279 | ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg, | 280 | ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg); |
| 280 | abb->base); | ||
| 281 | 281 | ||
| 282 | /* | 282 | /* |
| 283 | * program LDO VBB vset override if needed for !bypass mode | 283 | * program LDO VBB vset override if needed for !bypass mode |
| @@ -288,7 +288,7 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, | |||
| 288 | ti_abb_program_ldovbb(dev, abb, info); | 288 | ti_abb_program_ldovbb(dev, abb, info); |
| 289 | 289 | ||
| 290 | /* Initiate ABB ldo change */ | 290 | /* Initiate ABB ldo change */ |
| 291 | ti_abb_rmw(regs->opp_change_mask, 1, regs->control_reg, abb->base); | 291 | ti_abb_rmw(regs->opp_change_mask, 1, abb->control_reg); |
| 292 | 292 | ||
| 293 | /* Wait for ABB LDO to complete transition to new Bias setting */ | 293 | /* Wait for ABB LDO to complete transition to new Bias setting */ |
| 294 | ret = ti_abb_wait_txdone(dev, abb); | 294 | ret = ti_abb_wait_txdone(dev, abb); |
| @@ -490,8 +490,7 @@ static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb) | |||
| 490 | dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, | 490 | dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, |
| 491 | clk_get_rate(abb->clk), sr2_wt_cnt_val); | 491 | clk_get_rate(abb->clk), sr2_wt_cnt_val); |
| 492 | 492 | ||
| 493 | ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg, | 493 | ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg); |
| 494 | abb->base); | ||
| 495 | 494 | ||
| 496 | return 0; | 495 | return 0; |
| 497 | } | 496 | } |
| @@ -508,32 +507,24 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, | |||
| 508 | struct regulator_init_data *rinit_data) | 507 | struct regulator_init_data *rinit_data) |
| 509 | { | 508 | { |
| 510 | struct ti_abb_info *info; | 509 | struct ti_abb_info *info; |
| 511 | const struct property *prop; | ||
| 512 | const __be32 *abb_info; | ||
| 513 | const u32 num_values = 6; | 510 | const u32 num_values = 6; |
| 514 | char *pname = "ti,abb_info"; | 511 | char *pname = "ti,abb_info"; |
| 515 | u32 num_entries, i; | 512 | u32 i; |
| 516 | unsigned int *volt_table; | 513 | unsigned int *volt_table; |
| 517 | int min_uV = INT_MAX, max_uV = 0; | 514 | int num_entries, min_uV = INT_MAX, max_uV = 0; |
| 518 | struct regulation_constraints *c = &rinit_data->constraints; | 515 | struct regulation_constraints *c = &rinit_data->constraints; |
| 519 | 516 | ||
| 520 | prop = of_find_property(dev->of_node, pname, NULL); | ||
| 521 | if (!prop) { | ||
| 522 | dev_err(dev, "No '%s' property?\n", pname); | ||
| 523 | return -ENODEV; | ||
| 524 | } | ||
| 525 | |||
| 526 | if (!prop->value) { | ||
| 527 | dev_err(dev, "Empty '%s' property?\n", pname); | ||
| 528 | return -ENODATA; | ||
| 529 | } | ||
| 530 | |||
| 531 | /* | 517 | /* |
| 532 | * Each abb_info is a set of n-tuple, where n is num_values, consisting | 518 | * Each abb_info is a set of n-tuple, where n is num_values, consisting |
| 533 | * of voltage and a set of detection logic for ABB information for that | 519 | * of voltage and a set of detection logic for ABB information for that |
| 534 | * voltage to apply. | 520 | * voltage to apply. |
| 535 | */ | 521 | */ |
| 536 | num_entries = prop->length / sizeof(u32); | 522 | num_entries = of_property_count_u32_elems(dev->of_node, pname); |
| 523 | if (num_entries < 0) { | ||
| 524 | dev_err(dev, "No '%s' property?\n", pname); | ||
| 525 | return num_entries; | ||
| 526 | } | ||
| 527 | |||
| 537 | if (!num_entries || (num_entries % num_values)) { | 528 | if (!num_entries || (num_entries % num_values)) { |
| 538 | dev_err(dev, "All '%s' list entries need %d vals\n", pname, | 529 | dev_err(dev, "All '%s' list entries need %d vals\n", pname, |
| 539 | num_values); | 530 | num_values); |
| @@ -542,38 +533,38 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, | |||
| 542 | num_entries /= num_values; | 533 | num_entries /= num_values; |
| 543 | 534 | ||
| 544 | info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); | 535 | info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); |
| 545 | if (!info) { | 536 | if (!info) |
| 546 | dev_err(dev, "Can't allocate info table for '%s' property\n", | ||
| 547 | pname); | ||
| 548 | return -ENOMEM; | 537 | return -ENOMEM; |
| 549 | } | 538 | |
| 550 | abb->info = info; | 539 | abb->info = info; |
| 551 | 540 | ||
| 552 | volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, | 541 | volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, |
| 553 | GFP_KERNEL); | 542 | GFP_KERNEL); |
| 554 | if (!volt_table) { | 543 | if (!volt_table) |
| 555 | dev_err(dev, "Can't allocate voltage table for '%s' property\n", | ||
| 556 | pname); | ||
| 557 | return -ENOMEM; | 544 | return -ENOMEM; |
| 558 | } | ||
| 559 | 545 | ||
| 560 | abb->rdesc.n_voltages = num_entries; | 546 | abb->rdesc.n_voltages = num_entries; |
| 561 | abb->rdesc.volt_table = volt_table; | 547 | abb->rdesc.volt_table = volt_table; |
| 562 | /* We do not know where the OPP voltage is at the moment */ | 548 | /* We do not know where the OPP voltage is at the moment */ |
| 563 | abb->current_info_idx = -EINVAL; | 549 | abb->current_info_idx = -EINVAL; |
| 564 | 550 | ||
| 565 | abb_info = prop->value; | ||
| 566 | for (i = 0; i < num_entries; i++, info++, volt_table++) { | 551 | for (i = 0; i < num_entries; i++, info++, volt_table++) { |
| 567 | u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; | 552 | u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; |
| 568 | u32 efuse_val; | 553 | u32 efuse_val; |
| 569 | 554 | ||
| 570 | /* NOTE: num_values should equal to entries picked up here */ | 555 | /* NOTE: num_values should equal to entries picked up here */ |
| 571 | *volt_table = be32_to_cpup(abb_info++); | 556 | of_property_read_u32_index(dev->of_node, pname, i * num_values, |
| 572 | info->opp_sel = be32_to_cpup(abb_info++); | 557 | volt_table); |
| 573 | efuse_offset = be32_to_cpup(abb_info++); | 558 | of_property_read_u32_index(dev->of_node, pname, |
| 574 | rbb_mask = be32_to_cpup(abb_info++); | 559 | i * num_values + 1, &info->opp_sel); |
| 575 | fbb_mask = be32_to_cpup(abb_info++); | 560 | of_property_read_u32_index(dev->of_node, pname, |
| 576 | vset_mask = be32_to_cpup(abb_info++); | 561 | i * num_values + 2, &efuse_offset); |
| 562 | of_property_read_u32_index(dev->of_node, pname, | ||
| 563 | i * num_values + 3, &rbb_mask); | ||
| 564 | of_property_read_u32_index(dev->of_node, pname, | ||
| 565 | i * num_values + 4, &fbb_mask); | ||
| 566 | of_property_read_u32_index(dev->of_node, pname, | ||
| 567 | i * num_values + 5, &vset_mask); | ||
| 577 | 568 | ||
| 578 | dev_dbg(dev, | 569 | dev_dbg(dev, |
| 579 | "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", | 570 | "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", |
| @@ -648,8 +639,8 @@ static struct regulator_ops ti_abb_reg_ops = { | |||
| 648 | /* Default ABB block offsets, IF this changes in future, create new one */ | 639 | /* Default ABB block offsets, IF this changes in future, create new one */ |
| 649 | static const struct ti_abb_reg abb_regs_v1 = { | 640 | static const struct ti_abb_reg abb_regs_v1 = { |
| 650 | /* WARNING: registers are wrongly documented in TRM */ | 641 | /* WARNING: registers are wrongly documented in TRM */ |
| 651 | .setup_reg = 0x04, | 642 | .setup_off = 0x04, |
| 652 | .control_reg = 0x00, | 643 | .control_off = 0x00, |
| 653 | 644 | ||
| 654 | .sr2_wtcnt_value_mask = (0xff << 8), | 645 | .sr2_wtcnt_value_mask = (0xff << 8), |
| 655 | .fbb_sel_mask = (0x01 << 2), | 646 | .fbb_sel_mask = (0x01 << 2), |
| @@ -661,8 +652,8 @@ static const struct ti_abb_reg abb_regs_v1 = { | |||
| 661 | }; | 652 | }; |
| 662 | 653 | ||
| 663 | static const struct ti_abb_reg abb_regs_v2 = { | 654 | static const struct ti_abb_reg abb_regs_v2 = { |
| 664 | .setup_reg = 0x00, | 655 | .setup_off = 0x00, |
| 665 | .control_reg = 0x04, | 656 | .control_off = 0x04, |
| 666 | 657 | ||
| 667 | .sr2_wtcnt_value_mask = (0xff << 8), | 658 | .sr2_wtcnt_value_mask = (0xff << 8), |
| 668 | .fbb_sel_mask = (0x01 << 2), | 659 | .fbb_sel_mask = (0x01 << 2), |
| @@ -673,9 +664,20 @@ static const struct ti_abb_reg abb_regs_v2 = { | |||
| 673 | .opp_sel_mask = (0x03 << 0), | 664 | .opp_sel_mask = (0x03 << 0), |
| 674 | }; | 665 | }; |
| 675 | 666 | ||
| 667 | static const struct ti_abb_reg abb_regs_generic = { | ||
| 668 | .sr2_wtcnt_value_mask = (0xff << 8), | ||
| 669 | .fbb_sel_mask = (0x01 << 2), | ||
| 670 | .rbb_sel_mask = (0x01 << 1), | ||
| 671 | .sr2_en_mask = (0x01 << 0), | ||
| 672 | |||
| 673 | .opp_change_mask = (0x01 << 2), | ||
| 674 | .opp_sel_mask = (0x03 << 0), | ||
| 675 | }; | ||
| 676 | |||
| 676 | static const struct of_device_id ti_abb_of_match[] = { | 677 | static const struct of_device_id ti_abb_of_match[] = { |
| 677 | {.compatible = "ti,abb-v1", .data = &abb_regs_v1}, | 678 | {.compatible = "ti,abb-v1", .data = &abb_regs_v1}, |
| 678 | {.compatible = "ti,abb-v2", .data = &abb_regs_v2}, | 679 | {.compatible = "ti,abb-v2", .data = &abb_regs_v2}, |
| 680 | {.compatible = "ti,abb-v3", .data = &abb_regs_generic}, | ||
| 679 | { }, | 681 | { }, |
| 680 | }; | 682 | }; |
| 681 | 683 | ||
| @@ -722,11 +724,29 @@ static int ti_abb_probe(struct platform_device *pdev) | |||
| 722 | abb->regs = match->data; | 724 | abb->regs = match->data; |
| 723 | 725 | ||
| 724 | /* Map ABB resources */ | 726 | /* Map ABB resources */ |
| 725 | pname = "base-address"; | 727 | if (abb->regs->setup_off || abb->regs->control_off) { |
| 726 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | 728 | pname = "base-address"; |
| 727 | abb->base = devm_ioremap_resource(dev, res); | 729 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
| 728 | if (IS_ERR(abb->base)) | 730 | abb->base = devm_ioremap_resource(dev, res); |
| 729 | return PTR_ERR(abb->base); | 731 | if (IS_ERR(abb->base)) |
| 732 | return PTR_ERR(abb->base); | ||
| 733 | |||
| 734 | abb->setup_reg = abb->base + abb->regs->setup_off; | ||
| 735 | abb->control_reg = abb->base + abb->regs->control_off; | ||
| 736 | |||
| 737 | } else { | ||
| 738 | pname = "control-address"; | ||
| 739 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | ||
| 740 | abb->control_reg = devm_ioremap_resource(dev, res); | ||
| 741 | if (IS_ERR(abb->control_reg)) | ||
| 742 | return PTR_ERR(abb->control_reg); | ||
| 743 | |||
| 744 | pname = "setup-address"; | ||
| 745 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | ||
| 746 | abb->setup_reg = devm_ioremap_resource(dev, res); | ||
| 747 | if (IS_ERR(abb->setup_reg)) | ||
| 748 | return PTR_ERR(abb->setup_reg); | ||
| 749 | } | ||
| 730 | 750 | ||
| 731 | pname = "int-address"; | 751 | pname = "int-address"; |
| 732 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | 752 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
| @@ -860,7 +880,7 @@ skip_opt: | |||
| 860 | platform_set_drvdata(pdev, rdev); | 880 | platform_set_drvdata(pdev, rdev); |
| 861 | 881 | ||
| 862 | /* Enable the ldo if not already done by bootloader */ | 882 | /* Enable the ldo if not already done by bootloader */ |
| 863 | ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base); | 883 | ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg); |
| 864 | 884 | ||
| 865 | return 0; | 885 | return 0; |
| 866 | } | 886 | } |
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index b3764f594ee9..f31f22e3e1bd 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c | |||
| @@ -227,10 +227,8 @@ static struct tps51632_regulator_platform_data * | |||
| 227 | struct device_node *np = dev->of_node; | 227 | struct device_node *np = dev->of_node; |
| 228 | 228 | ||
| 229 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 229 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| 230 | if (!pdata) { | 230 | if (!pdata) |
| 231 | dev_err(dev, "Memory alloc failed for platform data\n"); | ||
| 232 | return NULL; | 231 | return NULL; |
| 233 | } | ||
| 234 | 232 | ||
| 235 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); | 233 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); |
| 236 | if (!pdata->reg_init_data) { | 234 | if (!pdata->reg_init_data) { |
| @@ -299,10 +297,8 @@ static int tps51632_probe(struct i2c_client *client, | |||
| 299 | } | 297 | } |
| 300 | 298 | ||
| 301 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 299 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
| 302 | if (!tps) { | 300 | if (!tps) |
| 303 | dev_err(&client->dev, "Memory allocation failed\n"); | ||
| 304 | return -ENOMEM; | 301 | return -ENOMEM; |
| 305 | } | ||
| 306 | 302 | ||
| 307 | tps->dev = &client->dev; | 303 | tps->dev = &client->dev; |
| 308 | tps->desc.name = client->name; | 304 | tps->desc.name = client->name; |
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index c3fa15a299b1..a1672044e519 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c | |||
| @@ -299,10 +299,8 @@ static struct tps62360_regulator_platform_data * | |||
| 299 | struct device_node *np = dev->of_node; | 299 | struct device_node *np = dev->of_node; |
| 300 | 300 | ||
| 301 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 301 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| 302 | if (!pdata) { | 302 | if (!pdata) |
| 303 | dev_err(dev, "Memory alloc failed for platform data\n"); | ||
| 304 | return NULL; | 303 | return NULL; |
| 305 | } | ||
| 306 | 304 | ||
| 307 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); | 305 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); |
| 308 | if (!pdata->reg_init_data) { | 306 | if (!pdata->reg_init_data) { |
| @@ -377,11 +375,8 @@ static int tps62360_probe(struct i2c_client *client, | |||
| 377 | } | 375 | } |
| 378 | 376 | ||
| 379 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 377 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
| 380 | if (!tps) { | 378 | if (!tps) |
| 381 | dev_err(&client->dev, "%s(): Memory allocation failed\n", | ||
| 382 | __func__); | ||
| 383 | return -ENOMEM; | 379 | return -ENOMEM; |
| 384 | } | ||
| 385 | 380 | ||
| 386 | tps->en_discharge = pdata->en_discharge; | 381 | tps->en_discharge = pdata->en_discharge; |
| 387 | tps->en_internal_pulldn = pdata->en_internal_pulldn; | 382 | tps->en_internal_pulldn = pdata->en_internal_pulldn; |
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 162a0fae20b3..98e66ce26723 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
| @@ -359,7 +359,6 @@ static struct regulator_ops tps6507x_pmic_ops = { | |||
| 359 | .map_voltage = regulator_map_voltage_ascend, | 359 | .map_voltage = regulator_map_voltage_ascend, |
| 360 | }; | 360 | }; |
| 361 | 361 | ||
| 362 | #ifdef CONFIG_OF | ||
| 363 | static struct of_regulator_match tps6507x_matches[] = { | 362 | static struct of_regulator_match tps6507x_matches[] = { |
| 364 | { .name = "VDCDC1"}, | 363 | { .name = "VDCDC1"}, |
| 365 | { .name = "VDCDC2"}, | 364 | { .name = "VDCDC2"}, |
| @@ -381,12 +380,10 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 381 | 380 | ||
| 382 | tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), | 381 | tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), |
| 383 | GFP_KERNEL); | 382 | GFP_KERNEL); |
| 384 | if (!tps_board) { | 383 | if (!tps_board) |
| 385 | dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n"); | ||
| 386 | return NULL; | 384 | return NULL; |
| 387 | } | ||
| 388 | 385 | ||
| 389 | regulators = of_find_node_by_name(np, "regulators"); | 386 | regulators = of_get_child_by_name(np, "regulators"); |
| 390 | if (!regulators) { | 387 | if (!regulators) { |
| 391 | dev_err(&pdev->dev, "regulator node not found\n"); | 388 | dev_err(&pdev->dev, "regulator node not found\n"); |
| 392 | return NULL; | 389 | return NULL; |
| @@ -396,6 +393,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 396 | matches = tps6507x_matches; | 393 | matches = tps6507x_matches; |
| 397 | 394 | ||
| 398 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); | 395 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); |
| 396 | of_node_put(regulators); | ||
| 399 | if (ret < 0) { | 397 | if (ret < 0) { |
| 400 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | 398 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", |
| 401 | ret); | 399 | ret); |
| @@ -406,10 +404,8 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 406 | 404 | ||
| 407 | reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) | 405 | reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) |
| 408 | * TPS6507X_NUM_REGULATOR), GFP_KERNEL); | 406 | * TPS6507X_NUM_REGULATOR), GFP_KERNEL); |
| 409 | if (!reg_data) { | 407 | if (!reg_data) |
| 410 | dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n"); | ||
| 411 | return NULL; | 408 | return NULL; |
| 412 | } | ||
| 413 | 409 | ||
| 414 | tps_board->tps6507x_pmic_init_data = reg_data; | 410 | tps_board->tps6507x_pmic_init_data = reg_data; |
| 415 | 411 | ||
| @@ -424,15 +420,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 424 | 420 | ||
| 425 | return tps_board; | 421 | return tps_board; |
| 426 | } | 422 | } |
| 427 | #else | 423 | |
| 428 | static inline struct tps6507x_board *tps6507x_parse_dt_reg_data( | ||
| 429 | struct platform_device *pdev, | ||
| 430 | struct of_regulator_match **tps6507x_reg_matches) | ||
| 431 | { | ||
| 432 | *tps6507x_reg_matches = NULL; | ||
| 433 | return NULL; | ||
| 434 | } | ||
| 435 | #endif | ||
| 436 | static int tps6507x_pmic_probe(struct platform_device *pdev) | 424 | static int tps6507x_pmic_probe(struct platform_device *pdev) |
| 437 | { | 425 | { |
| 438 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | 426 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
| @@ -453,9 +441,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) | |||
| 453 | */ | 441 | */ |
| 454 | 442 | ||
| 455 | tps_board = dev_get_platdata(tps6507x_dev->dev); | 443 | tps_board = dev_get_platdata(tps6507x_dev->dev); |
| 456 | if (!tps_board && tps6507x_dev->dev->of_node) | 444 | if (IS_ENABLED(CONFIG_OF) && !tps_board && |
| 445 | tps6507x_dev->dev->of_node) | ||
| 457 | tps_board = tps6507x_parse_dt_reg_data(pdev, | 446 | tps_board = tps6507x_parse_dt_reg_data(pdev, |
| 458 | &tps6507x_reg_matches); | 447 | &tps6507x_reg_matches); |
| 459 | if (!tps_board) | 448 | if (!tps_board) |
| 460 | return -EINVAL; | 449 | return -EINVAL; |
| 461 | 450 | ||
| @@ -481,7 +470,7 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) | |||
| 481 | tps->info[i] = info; | 470 | tps->info[i] = info; |
| 482 | if (init_data->driver_data) { | 471 | if (init_data->driver_data) { |
| 483 | struct tps6507x_reg_platform_data *data = | 472 | struct tps6507x_reg_platform_data *data = |
| 484 | init_data->driver_data; | 473 | init_data->driver_data; |
| 485 | tps->info[i]->defdcdc_default = data->defdcdc_default; | 474 | tps->info[i]->defdcdc_default = data->defdcdc_default; |
| 486 | } | 475 | } |
| 487 | 476 | ||
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 676f75548f00..2e92ef68574d 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c | |||
| @@ -168,17 +168,13 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( | |||
| 168 | 168 | ||
| 169 | tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata), | 169 | tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata), |
| 170 | GFP_KERNEL); | 170 | GFP_KERNEL); |
| 171 | if (!tps65090_pdata) { | 171 | if (!tps65090_pdata) |
| 172 | dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n"); | ||
| 173 | return ERR_PTR(-ENOMEM); | 172 | return ERR_PTR(-ENOMEM); |
| 174 | } | ||
| 175 | 173 | ||
| 176 | reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * | 174 | reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * |
| 177 | sizeof(*reg_pdata), GFP_KERNEL); | 175 | sizeof(*reg_pdata), GFP_KERNEL); |
| 178 | if (!reg_pdata) { | 176 | if (!reg_pdata) |
| 179 | dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n"); | ||
| 180 | return ERR_PTR(-ENOMEM); | 177 | return ERR_PTR(-ENOMEM); |
| 181 | } | ||
| 182 | 178 | ||
| 183 | regulators = of_get_child_by_name(np, "regulators"); | 179 | regulators = of_get_child_by_name(np, "regulators"); |
| 184 | if (!regulators) { | 180 | if (!regulators) { |
| @@ -188,6 +184,7 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( | |||
| 188 | 184 | ||
| 189 | ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches, | 185 | ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches, |
| 190 | ARRAY_SIZE(tps65090_matches)); | 186 | ARRAY_SIZE(tps65090_matches)); |
| 187 | of_node_put(regulators); | ||
| 191 | if (ret < 0) { | 188 | if (ret < 0) { |
| 192 | dev_err(&pdev->dev, | 189 | dev_err(&pdev->dev, |
| 193 | "Error parsing regulator init data: %d\n", ret); | 190 | "Error parsing regulator init data: %d\n", ret); |
| @@ -252,10 +249,8 @@ static int tps65090_regulator_probe(struct platform_device *pdev) | |||
| 252 | 249 | ||
| 253 | pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), | 250 | pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), |
| 254 | GFP_KERNEL); | 251 | GFP_KERNEL); |
| 255 | if (!pmic) { | 252 | if (!pmic) |
| 256 | dev_err(&pdev->dev, "mem alloc for pmic failed\n"); | ||
| 257 | return -ENOMEM; | 253 | return -ENOMEM; |
| 258 | } | ||
| 259 | 254 | ||
| 260 | for (num = 0; num < TPS65090_REGULATOR_MAX; num++) { | 255 | for (num = 0; num < TPS65090_REGULATOR_MAX; num++) { |
| 261 | tps_pdata = tps65090_pdata->reg_pdata[num]; | 256 | tps_pdata = tps65090_pdata->reg_pdata[num]; |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 9ea1bf26bd13..10b78d2b766a 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
| @@ -187,7 +187,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | |||
| 187 | struct device_node *regs; | 187 | struct device_node *regs; |
| 188 | int i, count; | 188 | int i, count; |
| 189 | 189 | ||
| 190 | regs = of_find_node_by_name(node, "regulators"); | 190 | regs = of_get_child_by_name(node, "regulators"); |
| 191 | if (!regs) | 191 | if (!regs) |
| 192 | return NULL; | 192 | return NULL; |
| 193 | 193 | ||
| @@ -202,7 +202,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | |||
| 202 | return NULL; | 202 | return NULL; |
| 203 | 203 | ||
| 204 | for (i = 0; i < count; i++) { | 204 | for (i = 0; i < count; i++) { |
| 205 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | 205 | if (!reg_matches[i].of_node) |
| 206 | continue; | 206 | continue; |
| 207 | 207 | ||
| 208 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | 208 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; |
| @@ -222,7 +222,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
| 222 | { | 222 | { |
| 223 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | 223 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); |
| 224 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | 224 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); |
| 225 | struct regulator_init_data *reg_data; | ||
| 226 | struct regulator_dev *rdev; | 225 | struct regulator_dev *rdev; |
| 227 | struct regulator_config config = { }; | 226 | struct regulator_config config = { }; |
| 228 | int i; | 227 | int i; |
| @@ -243,19 +242,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
| 243 | platform_set_drvdata(pdev, tps); | 242 | platform_set_drvdata(pdev, tps); |
| 244 | 243 | ||
| 245 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | 244 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { |
| 246 | |||
| 247 | reg_data = pdata->tps65217_init_data[i]; | ||
| 248 | |||
| 249 | /* | ||
| 250 | * Regulator API handles empty constraints but not NULL | ||
| 251 | * constraints | ||
| 252 | */ | ||
| 253 | if (!reg_data) | ||
| 254 | continue; | ||
| 255 | |||
| 256 | /* Register the regulators */ | 245 | /* Register the regulators */ |
| 257 | config.dev = tps->dev; | 246 | config.dev = tps->dev; |
| 258 | config.init_data = reg_data; | 247 | config.init_data = pdata->tps65217_init_data[i]; |
| 259 | config.driver_data = tps; | 248 | config.driver_data = tps; |
| 260 | config.regmap = tps->regmap; | 249 | config.regmap = tps->regmap; |
| 261 | if (tps->dev->of_node) | 250 | if (tps->dev->of_node) |
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c new file mode 100644 index 000000000000..cec72fa71d1d --- /dev/null +++ b/drivers/regulator/tps65218-regulator.c | |||
| @@ -0,0 +1,285 @@ | |||
| 1 | /* | ||
| 2 | * tps65218-regulator.c | ||
| 3 | * | ||
| 4 | * Regulator driver for TPS65218 PMIC | ||
| 5 | * | ||
| 6 | * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
| 13 | * kind, whether expressed or implied; without even the implied warranty | ||
| 14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License version 2 for more details. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/device.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/err.h> | ||
| 23 | #include <linux/platform_device.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 25 | #include <linux/regulator/of_regulator.h> | ||
| 26 | #include <linux/regulator/driver.h> | ||
| 27 | #include <linux/regulator/machine.h> | ||
| 28 | #include <linux/mfd/tps65218.h> | ||
| 29 | |||
| 30 | static unsigned int tps65218_ramp_delay = 4000; | ||
| 31 | |||
| 32 | enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; | ||
| 33 | |||
| 34 | #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \ | ||
| 35 | _lr, _nlr) \ | ||
| 36 | { \ | ||
| 37 | .name = _name, \ | ||
| 38 | .id = _id, \ | ||
| 39 | .ops = &_ops, \ | ||
| 40 | .n_voltages = _n, \ | ||
| 41 | .type = REGULATOR_VOLTAGE, \ | ||
| 42 | .owner = THIS_MODULE, \ | ||
| 43 | .vsel_reg = _vr, \ | ||
| 44 | .vsel_mask = _vm, \ | ||
| 45 | .enable_reg = _er, \ | ||
| 46 | .enable_mask = _em, \ | ||
| 47 | .volt_table = _t, \ | ||
| 48 | .linear_ranges = _lr, \ | ||
| 49 | .n_linear_ranges = _nlr, \ | ||
| 50 | } \ | ||
| 51 | |||
| 52 | #define TPS65218_INFO(_id, _nm, _min, _max) \ | ||
| 53 | { \ | ||
| 54 | .id = _id, \ | ||
| 55 | .name = _nm, \ | ||
| 56 | .min_uV = _min, \ | ||
| 57 | .max_uV = _max, \ | ||
| 58 | } | ||
| 59 | |||
| 60 | static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = { | ||
| 61 | REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000), | ||
| 62 | REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000), | ||
| 63 | }; | ||
| 64 | |||
| 65 | static const struct regulator_linear_range ldo1_dcdc3_ranges[] = { | ||
| 66 | REGULATOR_LINEAR_RANGE(900000, 0x0, 0x1a, 25000), | ||
| 67 | REGULATOR_LINEAR_RANGE(1600000, 0x1b, 0x3f, 50000), | ||
| 68 | }; | ||
| 69 | |||
| 70 | static const struct regulator_linear_range dcdc4_ranges[] = { | ||
| 71 | REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), | ||
| 72 | REGULATOR_LINEAR_RANGE(1550000, 0x10, 0x34, 50000), | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct tps_info tps65218_pmic_regs[] = { | ||
| 76 | TPS65218_INFO(0, "DCDC1", 850000, 167500), | ||
| 77 | TPS65218_INFO(1, "DCDC2", 850000, 1675000), | ||
| 78 | TPS65218_INFO(2, "DCDC3", 900000, 3400000), | ||
| 79 | TPS65218_INFO(3, "DCDC4", 1175000, 3400000), | ||
| 80 | TPS65218_INFO(4, "DCDC5", 1000000, 1000000), | ||
| 81 | TPS65218_INFO(5, "DCDC6", 1800000, 1800000), | ||
| 82 | TPS65218_INFO(6, "LDO1", 900000, 3400000), | ||
| 83 | }; | ||
| 84 | |||
| 85 | #define TPS65218_OF_MATCH(comp, label) \ | ||
| 86 | { \ | ||
| 87 | .compatible = comp, \ | ||
| 88 | .data = &label, \ | ||
| 89 | } | ||
| 90 | |||
| 91 | static const struct of_device_id tps65218_of_match[] = { | ||
| 92 | TPS65218_OF_MATCH("ti,tps65218-dcdc1", tps65218_pmic_regs[DCDC1]), | ||
| 93 | TPS65218_OF_MATCH("ti,tps65218-dcdc2", tps65218_pmic_regs[DCDC2]), | ||
| 94 | TPS65218_OF_MATCH("ti,tps65218-dcdc3", tps65218_pmic_regs[DCDC3]), | ||
| 95 | TPS65218_OF_MATCH("ti,tps65218-dcdc4", tps65218_pmic_regs[DCDC4]), | ||
| 96 | TPS65218_OF_MATCH("ti,tps65218-dcdc5", tps65218_pmic_regs[DCDC5]), | ||
| 97 | TPS65218_OF_MATCH("ti,tps65218-dcdc6", tps65218_pmic_regs[DCDC6]), | ||
| 98 | TPS65218_OF_MATCH("ti,tps65218-ldo1", tps65218_pmic_regs[LDO1]), | ||
| 99 | { } | ||
| 100 | }; | ||
| 101 | MODULE_DEVICE_TABLE(of, tps65218_of_match); | ||
| 102 | |||
| 103 | static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev, | ||
| 104 | unsigned selector) | ||
| 105 | { | ||
| 106 | int ret; | ||
| 107 | struct tps65218 *tps = rdev_get_drvdata(dev); | ||
| 108 | unsigned int rid = rdev_get_id(dev); | ||
| 109 | |||
| 110 | /* Set the voltage based on vsel value and write protect level is 2 */ | ||
| 111 | ret = tps65218_set_bits(tps, dev->desc->vsel_reg, dev->desc->vsel_mask, | ||
| 112 | selector, TPS65218_PROTECT_L1); | ||
| 113 | |||
| 114 | /* Set GO bit for DCDC1/2 to initiate voltage transistion */ | ||
| 115 | switch (rid) { | ||
| 116 | case TPS65218_DCDC_1: | ||
| 117 | case TPS65218_DCDC_2: | ||
| 118 | ret = tps65218_set_bits(tps, TPS65218_REG_CONTRL_SLEW_RATE, | ||
| 119 | TPS65218_SLEW_RATE_GO, | ||
| 120 | TPS65218_SLEW_RATE_GO, | ||
| 121 | TPS65218_PROTECT_L1); | ||
| 122 | break; | ||
| 123 | } | ||
| 124 | |||
| 125 | return ret; | ||
| 126 | } | ||
| 127 | |||
| 128 | static int tps65218_pmic_enable(struct regulator_dev *dev) | ||
| 129 | { | ||
| 130 | struct tps65218 *tps = rdev_get_drvdata(dev); | ||
| 131 | unsigned int rid = rdev_get_id(dev); | ||
| 132 | |||
| 133 | if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) | ||
| 134 | return -EINVAL; | ||
| 135 | |||
| 136 | /* Enable the regulator and password protection is level 1 */ | ||
| 137 | return tps65218_set_bits(tps, dev->desc->enable_reg, | ||
| 138 | dev->desc->enable_mask, dev->desc->enable_mask, | ||
| 139 | TPS65218_PROTECT_L1); | ||
| 140 | } | ||
| 141 | |||
| 142 | static int tps65218_pmic_disable(struct regulator_dev *dev) | ||
| 143 | { | ||
| 144 | struct tps65218 *tps = rdev_get_drvdata(dev); | ||
| 145 | unsigned int rid = rdev_get_id(dev); | ||
| 146 | |||
| 147 | if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) | ||
| 148 | return -EINVAL; | ||
| 149 | |||
| 150 | /* Disable the regulator and password protection is level 1 */ | ||
| 151 | return tps65218_clear_bits(tps, dev->desc->enable_reg, | ||
| 152 | dev->desc->enable_mask, TPS65218_PROTECT_L1); | ||
| 153 | } | ||
| 154 | |||
| 155 | static int tps65218_set_voltage_time_sel(struct regulator_dev *rdev, | ||
| 156 | unsigned int old_selector, unsigned int new_selector) | ||
| 157 | { | ||
| 158 | int old_uv, new_uv; | ||
| 159 | |||
| 160 | old_uv = regulator_list_voltage_linear_range(rdev, old_selector); | ||
| 161 | if (old_uv < 0) | ||
| 162 | return old_uv; | ||
| 163 | |||
| 164 | new_uv = regulator_list_voltage_linear_range(rdev, new_selector); | ||
| 165 | if (new_uv < 0) | ||
| 166 | return new_uv; | ||
| 167 | |||
| 168 | return DIV_ROUND_UP(abs(old_uv - new_uv), tps65218_ramp_delay); | ||
| 169 | } | ||
| 170 | |||
| 171 | /* Operations permitted on DCDC1, DCDC2 */ | ||
| 172 | static struct regulator_ops tps65218_dcdc12_ops = { | ||
| 173 | .is_enabled = regulator_is_enabled_regmap, | ||
| 174 | .enable = tps65218_pmic_enable, | ||
| 175 | .disable = tps65218_pmic_disable, | ||
| 176 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 177 | .set_voltage_sel = tps65218_pmic_set_voltage_sel, | ||
| 178 | .list_voltage = regulator_list_voltage_linear_range, | ||
| 179 | .map_voltage = regulator_map_voltage_linear_range, | ||
| 180 | .set_voltage_time_sel = tps65218_set_voltage_time_sel, | ||
| 181 | }; | ||
| 182 | |||
| 183 | /* Operations permitted on DCDC3, DCDC4 and LDO1 */ | ||
| 184 | static struct regulator_ops tps65218_ldo1_dcdc34_ops = { | ||
| 185 | .is_enabled = regulator_is_enabled_regmap, | ||
| 186 | .enable = tps65218_pmic_enable, | ||
| 187 | .disable = tps65218_pmic_disable, | ||
| 188 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 189 | .set_voltage_sel = tps65218_pmic_set_voltage_sel, | ||
| 190 | .list_voltage = regulator_list_voltage_linear_range, | ||
| 191 | .map_voltage = regulator_map_voltage_linear_range, | ||
| 192 | }; | ||
| 193 | |||
| 194 | /* Operations permitted on DCDC5, DCDC6 */ | ||
| 195 | static struct regulator_ops tps65218_dcdc56_pmic_ops = { | ||
| 196 | .is_enabled = regulator_is_enabled_regmap, | ||
| 197 | .enable = tps65218_pmic_enable, | ||
| 198 | .disable = tps65218_pmic_disable, | ||
| 199 | }; | ||
| 200 | |||
| 201 | static const struct regulator_desc regulators[] = { | ||
| 202 | TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64, | ||
| 203 | TPS65218_REG_CONTROL_DCDC1, | ||
| 204 | TPS65218_CONTROL_DCDC1_MASK, | ||
| 205 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL, | ||
| 206 | dcdc1_dcdc2_ranges, 2), | ||
| 207 | TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, | ||
| 208 | TPS65218_REG_CONTROL_DCDC2, | ||
| 209 | TPS65218_CONTROL_DCDC2_MASK, | ||
| 210 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL, | ||
| 211 | dcdc1_dcdc2_ranges, 2), | ||
| 212 | TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, | ||
| 213 | 64, TPS65218_REG_CONTROL_DCDC3, | ||
| 214 | TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, | ||
| 215 | TPS65218_ENABLE1_DC3_EN, NULL, | ||
| 216 | ldo1_dcdc3_ranges, 2), | ||
| 217 | TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, | ||
| 218 | 53, TPS65218_REG_CONTROL_DCDC4, | ||
| 219 | TPS65218_CONTROL_DCDC4_MASK, | ||
| 220 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL, | ||
| 221 | dcdc4_ranges, 2), | ||
| 222 | TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, | ||
| 223 | 1, -1, -1, TPS65218_REG_ENABLE1, | ||
| 224 | TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0), | ||
| 225 | TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, | ||
| 226 | 1, -1, -1, TPS65218_REG_ENABLE1, | ||
| 227 | TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0), | ||
| 228 | TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, | ||
| 229 | TPS65218_REG_CONTROL_DCDC4, | ||
| 230 | TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, | ||
| 231 | TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, | ||
| 232 | 2), | ||
| 233 | }; | ||
| 234 | |||
| 235 | static int tps65218_regulator_probe(struct platform_device *pdev) | ||
| 236 | { | ||
| 237 | struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent); | ||
| 238 | struct regulator_init_data *init_data; | ||
| 239 | const struct tps_info *template; | ||
| 240 | struct regulator_dev *rdev; | ||
| 241 | const struct of_device_id *match; | ||
| 242 | struct regulator_config config = { }; | ||
| 243 | int id; | ||
| 244 | |||
| 245 | match = of_match_device(tps65218_of_match, &pdev->dev); | ||
| 246 | if (!match) | ||
| 247 | return -ENODEV; | ||
| 248 | |||
| 249 | template = match->data; | ||
| 250 | id = template->id; | ||
| 251 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); | ||
| 252 | |||
| 253 | platform_set_drvdata(pdev, tps); | ||
| 254 | |||
| 255 | tps->info[id] = &tps65218_pmic_regs[id]; | ||
| 256 | config.dev = &pdev->dev; | ||
| 257 | config.init_data = init_data; | ||
| 258 | config.driver_data = tps; | ||
| 259 | config.regmap = tps->regmap; | ||
| 260 | |||
| 261 | rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config); | ||
| 262 | if (IS_ERR(rdev)) { | ||
| 263 | dev_err(tps->dev, "failed to register %s regulator\n", | ||
| 264 | pdev->name); | ||
| 265 | return PTR_ERR(rdev); | ||
| 266 | } | ||
| 267 | |||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | |||
| 271 | static struct platform_driver tps65218_regulator_driver = { | ||
| 272 | .driver = { | ||
| 273 | .name = "tps65218-pmic", | ||
| 274 | .owner = THIS_MODULE, | ||
| 275 | .of_match_table = tps65218_of_match, | ||
| 276 | }, | ||
| 277 | .probe = tps65218_regulator_probe, | ||
| 278 | }; | ||
| 279 | |||
| 280 | module_platform_driver(tps65218_regulator_driver); | ||
| 281 | |||
| 282 | MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); | ||
| 283 | MODULE_DESCRIPTION("TPS65218 voltage regulator driver"); | ||
| 284 | MODULE_ALIAS("platform:tps65218-pmic"); | ||
| 285 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 9f6bfda711b7..5b494db9f95c 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c | |||
| @@ -593,10 +593,9 @@ static int pmic_probe(struct spi_device *spi) | |||
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL); | 595 | hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL); |
| 596 | if (!hw) { | 596 | if (!hw) |
| 597 | dev_err(dev, "cannot allocate regulator private data\n"); | ||
| 598 | return -ENOMEM; | 597 | return -ENOMEM; |
| 599 | } | 598 | |
| 600 | spi_set_drvdata(spi, hw); | 599 | spi_set_drvdata(spi, hw); |
| 601 | 600 | ||
| 602 | memset(hw, 0, sizeof(struct tps6524x)); | 601 | memset(hw, 0, sizeof(struct tps6524x)); |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 0485d47f0d8a..32f38a63d944 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
| @@ -363,10 +363,8 @@ static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( | |||
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 365 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
| 366 | if (!pdata) { | 366 | if (!pdata) |
| 367 | dev_err(&pdev->dev, "Memory alloction failed\n"); | ||
| 368 | return NULL; | 367 | return NULL; |
| 369 | } | ||
| 370 | 368 | ||
| 371 | for (i = 0; i < num; i++) { | 369 | for (i = 0; i < num; i++) { |
| 372 | int id; | 370 | int id; |
| @@ -398,7 +396,7 @@ static int tps6586x_regulator_probe(struct platform_device *pdev) | |||
| 398 | { | 396 | { |
| 399 | struct tps6586x_regulator *ri = NULL; | 397 | struct tps6586x_regulator *ri = NULL; |
| 400 | struct regulator_config config = { }; | 398 | struct regulator_config config = { }; |
| 401 | struct regulator_dev **rdev; | 399 | struct regulator_dev *rdev; |
| 402 | struct regulator_init_data *reg_data; | 400 | struct regulator_init_data *reg_data; |
| 403 | struct tps6586x_platform_data *pdata; | 401 | struct tps6586x_platform_data *pdata; |
| 404 | struct of_regulator_match *tps6586x_reg_matches = NULL; | 402 | struct of_regulator_match *tps6586x_reg_matches = NULL; |
| @@ -418,13 +416,6 @@ static int tps6586x_regulator_probe(struct platform_device *pdev) | |||
| 418 | return -ENODEV; | 416 | return -ENODEV; |
| 419 | } | 417 | } |
| 420 | 418 | ||
| 421 | rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR * | ||
| 422 | sizeof(*rdev), GFP_KERNEL); | ||
| 423 | if (!rdev) { | ||
| 424 | dev_err(&pdev->dev, "Mmemory alloc failed\n"); | ||
| 425 | return -ENOMEM; | ||
| 426 | } | ||
| 427 | |||
| 428 | version = tps6586x_get_version(pdev->dev.parent); | 419 | version = tps6586x_get_version(pdev->dev.parent); |
| 429 | 420 | ||
| 430 | for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) { | 421 | for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) { |
| @@ -451,12 +442,11 @@ static int tps6586x_regulator_probe(struct platform_device *pdev) | |||
| 451 | if (tps6586x_reg_matches) | 442 | if (tps6586x_reg_matches) |
| 452 | config.of_node = tps6586x_reg_matches[id].of_node; | 443 | config.of_node = tps6586x_reg_matches[id].of_node; |
| 453 | 444 | ||
| 454 | rdev[id] = devm_regulator_register(&pdev->dev, &ri->desc, | 445 | rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); |
| 455 | &config); | 446 | if (IS_ERR(rdev)) { |
| 456 | if (IS_ERR(rdev[id])) { | ||
| 457 | dev_err(&pdev->dev, "failed to register regulator %s\n", | 447 | dev_err(&pdev->dev, "failed to register regulator %s\n", |
| 458 | ri->desc.name); | 448 | ri->desc.name); |
| 459 | return PTR_ERR(rdev[id]); | 449 | return PTR_ERR(rdev); |
| 460 | } | 450 | } |
| 461 | 451 | ||
| 462 | if (reg_data) { | 452 | if (reg_data) { |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index f50dd847eebc..fa7db8847578 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
| @@ -1011,11 +1011,8 @@ static struct tps65910_board *tps65910_parse_dt_reg_data( | |||
| 1011 | 1011 | ||
| 1012 | pmic_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pmic_plat_data), | 1012 | pmic_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pmic_plat_data), |
| 1013 | GFP_KERNEL); | 1013 | GFP_KERNEL); |
| 1014 | 1014 | if (!pmic_plat_data) | |
| 1015 | if (!pmic_plat_data) { | ||
| 1016 | dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n"); | ||
| 1017 | return NULL; | 1015 | return NULL; |
| 1018 | } | ||
| 1019 | 1016 | ||
| 1020 | np = of_node_get(pdev->dev.parent->of_node); | 1017 | np = of_node_get(pdev->dev.parent->of_node); |
| 1021 | regulators = of_get_child_by_name(np, "regulators"); | 1018 | regulators = of_get_child_by_name(np, "regulators"); |
| @@ -1098,10 +1095,8 @@ static int tps65910_probe(struct platform_device *pdev) | |||
| 1098 | } | 1095 | } |
| 1099 | 1096 | ||
| 1100 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | 1097 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); |
| 1101 | if (!pmic) { | 1098 | if (!pmic) |
| 1102 | dev_err(&pdev->dev, "Memory allocation failed for pmic\n"); | ||
| 1103 | return -ENOMEM; | 1099 | return -ENOMEM; |
| 1104 | } | ||
| 1105 | 1100 | ||
| 1106 | pmic->mfd = tps65910; | 1101 | pmic->mfd = tps65910; |
| 1107 | platform_set_drvdata(pdev, pmic); | 1102 | platform_set_drvdata(pdev, pmic); |
| @@ -1130,24 +1125,18 @@ static int tps65910_probe(struct platform_device *pdev) | |||
| 1130 | 1125 | ||
| 1131 | pmic->desc = devm_kzalloc(&pdev->dev, pmic->num_regulators * | 1126 | pmic->desc = devm_kzalloc(&pdev->dev, pmic->num_regulators * |
| 1132 | sizeof(struct regulator_desc), GFP_KERNEL); | 1127 | sizeof(struct regulator_desc), GFP_KERNEL); |
| 1133 | if (!pmic->desc) { | 1128 | if (!pmic->desc) |
| 1134 | dev_err(&pdev->dev, "Memory alloc fails for desc\n"); | ||
| 1135 | return -ENOMEM; | 1129 | return -ENOMEM; |
| 1136 | } | ||
| 1137 | 1130 | ||
| 1138 | pmic->info = devm_kzalloc(&pdev->dev, pmic->num_regulators * | 1131 | pmic->info = devm_kzalloc(&pdev->dev, pmic->num_regulators * |
| 1139 | sizeof(struct tps_info *), GFP_KERNEL); | 1132 | sizeof(struct tps_info *), GFP_KERNEL); |
| 1140 | if (!pmic->info) { | 1133 | if (!pmic->info) |
| 1141 | dev_err(&pdev->dev, "Memory alloc fails for info\n"); | ||
| 1142 | return -ENOMEM; | 1134 | return -ENOMEM; |
| 1143 | } | ||
| 1144 | 1135 | ||
| 1145 | pmic->rdev = devm_kzalloc(&pdev->dev, pmic->num_regulators * | 1136 | pmic->rdev = devm_kzalloc(&pdev->dev, pmic->num_regulators * |
| 1146 | sizeof(struct regulator_dev *), GFP_KERNEL); | 1137 | sizeof(struct regulator_dev *), GFP_KERNEL); |
| 1147 | if (!pmic->rdev) { | 1138 | if (!pmic->rdev) |
| 1148 | dev_err(&pdev->dev, "Memory alloc fails for rdev\n"); | ||
| 1149 | return -ENOMEM; | 1139 | return -ENOMEM; |
| 1150 | } | ||
| 1151 | 1140 | ||
| 1152 | for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; | 1141 | for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; |
| 1153 | i++, info++) { | 1142 | i++, info++) { |
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index 71f457a42623..26aa6d9c308f 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c | |||
| @@ -115,7 +115,7 @@ static int tps80031_reg_is_enabled(struct regulator_dev *rdev) | |||
| 115 | ri->rinfo->state_reg, ret); | 115 | ri->rinfo->state_reg, ret); |
| 116 | return ret; | 116 | return ret; |
| 117 | } | 117 | } |
| 118 | return ((reg_val & TPS80031_STATE_MASK) == TPS80031_STATE_ON); | 118 | return (reg_val & TPS80031_STATE_MASK) == TPS80031_STATE_ON; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | static int tps80031_reg_enable(struct regulator_dev *rdev) | 121 | static int tps80031_reg_enable(struct regulator_dev *rdev) |
| @@ -693,10 +693,8 @@ static int tps80031_regulator_probe(struct platform_device *pdev) | |||
| 693 | 693 | ||
| 694 | pmic = devm_kzalloc(&pdev->dev, | 694 | pmic = devm_kzalloc(&pdev->dev, |
| 695 | TPS80031_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL); | 695 | TPS80031_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL); |
| 696 | if (!pmic) { | 696 | if (!pmic) |
| 697 | dev_err(&pdev->dev, "mem alloc for pmic failed\n"); | ||
| 698 | return -ENOMEM; | 697 | return -ENOMEM; |
| 699 | } | ||
| 700 | 698 | ||
| 701 | for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { | 699 | for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { |
| 702 | tps_pdata = pdata->regulator_pdata[num]; | 700 | tps_pdata = pdata->regulator_pdata[num]; |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 04cf9c16ef23..0d88a82ab2a2 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
| @@ -469,10 +469,8 @@ static int wm831x_buckv_probe(struct platform_device *pdev) | |||
| 469 | 469 | ||
| 470 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), | 470 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), |
| 471 | GFP_KERNEL); | 471 | GFP_KERNEL); |
| 472 | if (dcdc == NULL) { | 472 | if (!dcdc) |
| 473 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 474 | return -ENOMEM; | 473 | return -ENOMEM; |
| 475 | } | ||
| 476 | 474 | ||
| 477 | dcdc->wm831x = wm831x; | 475 | dcdc->wm831x = wm831x; |
| 478 | 476 | ||
| @@ -622,10 +620,8 @@ static int wm831x_buckp_probe(struct platform_device *pdev) | |||
| 622 | 620 | ||
| 623 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), | 621 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), |
| 624 | GFP_KERNEL); | 622 | GFP_KERNEL); |
| 625 | if (dcdc == NULL) { | 623 | if (!dcdc) |
| 626 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 627 | return -ENOMEM; | 624 | return -ENOMEM; |
| 628 | } | ||
| 629 | 625 | ||
| 630 | dcdc->wm831x = wm831x; | 626 | dcdc->wm831x = wm831x; |
| 631 | 627 | ||
| @@ -752,10 +748,8 @@ static int wm831x_boostp_probe(struct platform_device *pdev) | |||
| 752 | return -ENODEV; | 748 | return -ENODEV; |
| 753 | 749 | ||
| 754 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); | 750 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); |
| 755 | if (dcdc == NULL) { | 751 | if (!dcdc) |
| 756 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 757 | return -ENOMEM; | 752 | return -ENOMEM; |
| 758 | } | ||
| 759 | 753 | ||
| 760 | dcdc->wm831x = wm831x; | 754 | dcdc->wm831x = wm831x; |
| 761 | 755 | ||
| @@ -842,10 +836,8 @@ static int wm831x_epe_probe(struct platform_device *pdev) | |||
| 842 | dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1); | 836 | dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1); |
| 843 | 837 | ||
| 844 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); | 838 | dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); |
| 845 | if (dcdc == NULL) { | 839 | if (!dcdc) |
| 846 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 847 | return -ENOMEM; | 840 | return -ENOMEM; |
| 848 | } | ||
| 849 | 841 | ||
| 850 | dcdc->wm831x = wm831x; | 842 | dcdc->wm831x = wm831x; |
| 851 | 843 | ||
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 0339b886df5d..72e385e76a9d 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c | |||
| @@ -165,10 +165,8 @@ static int wm831x_isink_probe(struct platform_device *pdev) | |||
| 165 | 165 | ||
| 166 | isink = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_isink), | 166 | isink = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_isink), |
| 167 | GFP_KERNEL); | 167 | GFP_KERNEL); |
| 168 | if (isink == NULL) { | 168 | if (!isink) |
| 169 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 170 | return -ENOMEM; | 169 | return -ENOMEM; |
| 171 | } | ||
| 172 | 170 | ||
| 173 | isink->wm831x = wm831x; | 171 | isink->wm831x = wm831x; |
| 174 | 172 | ||
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 46d6700467b5..eca0eeb78acd 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
| @@ -235,10 +235,8 @@ static int wm831x_gp_ldo_probe(struct platform_device *pdev) | |||
| 235 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 235 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
| 236 | 236 | ||
| 237 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); | 237 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); |
| 238 | if (ldo == NULL) { | 238 | if (!ldo) |
| 239 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 240 | return -ENOMEM; | 239 | return -ENOMEM; |
| 241 | } | ||
| 242 | 240 | ||
| 243 | ldo->wm831x = wm831x; | 241 | ldo->wm831x = wm831x; |
| 244 | 242 | ||
| @@ -447,10 +445,8 @@ static int wm831x_aldo_probe(struct platform_device *pdev) | |||
| 447 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 445 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
| 448 | 446 | ||
| 449 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); | 447 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); |
| 450 | if (ldo == NULL) { | 448 | if (!ldo) |
| 451 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 452 | return -ENOMEM; | 449 | return -ENOMEM; |
| 453 | } | ||
| 454 | 450 | ||
| 455 | ldo->wm831x = wm831x; | 451 | ldo->wm831x = wm831x; |
| 456 | 452 | ||
| @@ -594,10 +590,8 @@ static int wm831x_alive_ldo_probe(struct platform_device *pdev) | |||
| 594 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 590 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
| 595 | 591 | ||
| 596 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); | 592 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); |
| 597 | if (ldo == NULL) { | 593 | if (!ldo) |
| 598 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 599 | return -ENOMEM; | 594 | return -ENOMEM; |
| 600 | } | ||
| 601 | 595 | ||
| 602 | ldo->wm831x = wm831x; | 596 | ldo->wm831x = wm831x; |
| 603 | 597 | ||
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index de7b9c73e3fa..7ec7c390eeda 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c | |||
| @@ -361,7 +361,7 @@ static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
| 361 | 361 | ||
| 362 | sel = regulator_map_voltage_linear(rdev, uV, uV); | 362 | sel = regulator_map_voltage_linear(rdev, uV, uV); |
| 363 | if (sel < 0) | 363 | if (sel < 0) |
| 364 | return -EINVAL; | 364 | return sel; |
| 365 | 365 | ||
| 366 | /* all DCDCs have same mV bits */ | 366 | /* all DCDCs have same mV bits */ |
| 367 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; | 367 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; |
| @@ -574,7 +574,7 @@ static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
| 574 | 574 | ||
| 575 | sel = regulator_map_voltage_linear_range(rdev, uV, uV); | 575 | sel = regulator_map_voltage_linear_range(rdev, uV, uV); |
| 576 | if (sel < 0) | 576 | if (sel < 0) |
| 577 | return -EINVAL; | 577 | return sel; |
| 578 | 578 | ||
| 579 | /* all LDOs have same mV bits */ | 579 | /* all LDOs have same mV bits */ |
| 580 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; | 580 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; |
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 71c5911f2e71..c24346db8a71 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
| @@ -134,10 +134,8 @@ static int wm8994_ldo_probe(struct platform_device *pdev) | |||
| 134 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 134 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
| 135 | 135 | ||
| 136 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_ldo), GFP_KERNEL); | 136 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_ldo), GFP_KERNEL); |
| 137 | if (ldo == NULL) { | 137 | if (!ldo) |
| 138 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 139 | return -ENOMEM; | 138 | return -ENOMEM; |
| 140 | } | ||
| 141 | 139 | ||
| 142 | ldo->wm8994 = wm8994; | 140 | ldo->wm8994 = wm8994; |
| 143 | ldo->supply = wm8994_ldo_consumer[id]; | 141 | ldo->supply = wm8994_ldo_consumer[id]; |
diff --git a/include/linux/device.h b/include/linux/device.h index 952b01033c32..ec1b6e21f0ef 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -626,6 +626,7 @@ static inline void *devm_kcalloc(struct device *dev, | |||
| 626 | return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); | 626 | return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); |
| 627 | } | 627 | } |
| 628 | extern void devm_kfree(struct device *dev, void *p); | 628 | extern void devm_kfree(struct device *dev, void *p); |
| 629 | extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp); | ||
| 629 | 630 | ||
| 630 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); | 631 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); |
| 631 | void __iomem *devm_request_and_ioremap(struct device *dev, | 632 | void __iomem *devm_request_and_ioremap(struct device *dev, |
diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 41c9bde410c5..157e32b6ca28 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h | |||
| @@ -18,7 +18,9 @@ enum sec_device_type { | |||
| 18 | S5M8751X, | 18 | S5M8751X, |
| 19 | S5M8763X, | 19 | S5M8763X, |
| 20 | S5M8767X, | 20 | S5M8767X, |
| 21 | S2MPA01, | ||
| 21 | S2MPS11X, | 22 | S2MPS11X, |
| 23 | S2MPS14X, | ||
| 22 | }; | 24 | }; |
| 23 | 25 | ||
| 24 | /** | 26 | /** |
| @@ -50,7 +52,7 @@ struct sec_pmic_dev { | |||
| 50 | struct regmap_irq_chip_data *irq_data; | 52 | struct regmap_irq_chip_data *irq_data; |
| 51 | 53 | ||
| 52 | int ono; | 54 | int ono; |
| 53 | int type; | 55 | unsigned long type; |
| 54 | bool wakeup; | 56 | bool wakeup; |
| 55 | bool wtsr_smpl; | 57 | bool wtsr_smpl; |
| 56 | }; | 58 | }; |
| @@ -92,7 +94,7 @@ struct sec_platform_data { | |||
| 92 | int buck3_default_idx; | 94 | int buck3_default_idx; |
| 93 | int buck4_default_idx; | 95 | int buck4_default_idx; |
| 94 | 96 | ||
| 95 | int buck_ramp_delay; | 97 | int buck_ramp_delay; |
| 96 | 98 | ||
| 97 | int buck2_ramp_delay; | 99 | int buck2_ramp_delay; |
| 98 | int buck34_ramp_delay; | 100 | int buck34_ramp_delay; |
| @@ -100,10 +102,15 @@ struct sec_platform_data { | |||
| 100 | int buck16_ramp_delay; | 102 | int buck16_ramp_delay; |
| 101 | int buck7810_ramp_delay; | 103 | int buck7810_ramp_delay; |
| 102 | int buck9_ramp_delay; | 104 | int buck9_ramp_delay; |
| 103 | 105 | int buck24_ramp_delay; | |
| 104 | bool buck2_ramp_enable; | 106 | int buck3_ramp_delay; |
| 105 | bool buck3_ramp_enable; | 107 | int buck7_ramp_delay; |
| 106 | bool buck4_ramp_enable; | 108 | int buck8910_ramp_delay; |
| 109 | |||
| 110 | bool buck1_ramp_enable; | ||
| 111 | bool buck2_ramp_enable; | ||
| 112 | bool buck3_ramp_enable; | ||
| 113 | bool buck4_ramp_enable; | ||
| 107 | bool buck6_ramp_enable; | 114 | bool buck6_ramp_enable; |
| 108 | 115 | ||
| 109 | int buck2_init; | 116 | int buck2_init; |
| @@ -119,7 +126,8 @@ struct sec_platform_data { | |||
| 119 | struct sec_regulator_data { | 126 | struct sec_regulator_data { |
| 120 | int id; | 127 | int id; |
| 121 | struct regulator_init_data *initdata; | 128 | struct regulator_init_data *initdata; |
| 122 | struct device_node *reg_node; | 129 | struct device_node *reg_node; |
| 130 | int ext_control_gpio; | ||
| 123 | }; | 131 | }; |
| 124 | 132 | ||
| 125 | /* | 133 | /* |
diff --git a/include/linux/mfd/samsung/irq.h b/include/linux/mfd/samsung/irq.h index d43b4f9e7fb2..1224f447356b 100644 --- a/include/linux/mfd/samsung/irq.h +++ b/include/linux/mfd/samsung/irq.h | |||
| @@ -13,6 +13,56 @@ | |||
| 13 | #ifndef __LINUX_MFD_SEC_IRQ_H | 13 | #ifndef __LINUX_MFD_SEC_IRQ_H |
| 14 | #define __LINUX_MFD_SEC_IRQ_H | 14 | #define __LINUX_MFD_SEC_IRQ_H |
| 15 | 15 | ||
| 16 | enum s2mpa01_irq { | ||
| 17 | S2MPA01_IRQ_PWRONF, | ||
| 18 | S2MPA01_IRQ_PWRONR, | ||
| 19 | S2MPA01_IRQ_JIGONBF, | ||
| 20 | S2MPA01_IRQ_JIGONBR, | ||
| 21 | S2MPA01_IRQ_ACOKBF, | ||
| 22 | S2MPA01_IRQ_ACOKBR, | ||
| 23 | S2MPA01_IRQ_PWRON1S, | ||
| 24 | S2MPA01_IRQ_MRB, | ||
| 25 | |||
| 26 | S2MPA01_IRQ_RTC60S, | ||
| 27 | S2MPA01_IRQ_RTCA1, | ||
| 28 | S2MPA01_IRQ_RTCA0, | ||
| 29 | S2MPA01_IRQ_SMPL, | ||
| 30 | S2MPA01_IRQ_RTC1S, | ||
| 31 | S2MPA01_IRQ_WTSR, | ||
| 32 | |||
| 33 | S2MPA01_IRQ_INT120C, | ||
| 34 | S2MPA01_IRQ_INT140C, | ||
| 35 | S2MPA01_IRQ_LDO3_TSD, | ||
| 36 | S2MPA01_IRQ_B16_TSD, | ||
| 37 | S2MPA01_IRQ_B24_TSD, | ||
| 38 | S2MPA01_IRQ_B35_TSD, | ||
| 39 | |||
| 40 | S2MPA01_IRQ_NR, | ||
| 41 | }; | ||
| 42 | |||
| 43 | #define S2MPA01_IRQ_PWRONF_MASK (1 << 0) | ||
| 44 | #define S2MPA01_IRQ_PWRONR_MASK (1 << 1) | ||
| 45 | #define S2MPA01_IRQ_JIGONBF_MASK (1 << 2) | ||
| 46 | #define S2MPA01_IRQ_JIGONBR_MASK (1 << 3) | ||
| 47 | #define S2MPA01_IRQ_ACOKBF_MASK (1 << 4) | ||
| 48 | #define S2MPA01_IRQ_ACOKBR_MASK (1 << 5) | ||
| 49 | #define S2MPA01_IRQ_PWRON1S_MASK (1 << 6) | ||
| 50 | #define S2MPA01_IRQ_MRB_MASK (1 << 7) | ||
| 51 | |||
| 52 | #define S2MPA01_IRQ_RTC60S_MASK (1 << 0) | ||
| 53 | #define S2MPA01_IRQ_RTCA1_MASK (1 << 1) | ||
| 54 | #define S2MPA01_IRQ_RTCA0_MASK (1 << 2) | ||
| 55 | #define S2MPA01_IRQ_SMPL_MASK (1 << 3) | ||
| 56 | #define S2MPA01_IRQ_RTC1S_MASK (1 << 4) | ||
| 57 | #define S2MPA01_IRQ_WTSR_MASK (1 << 5) | ||
| 58 | |||
| 59 | #define S2MPA01_IRQ_INT120C_MASK (1 << 0) | ||
| 60 | #define S2MPA01_IRQ_INT140C_MASK (1 << 1) | ||
| 61 | #define S2MPA01_IRQ_LDO3_TSD_MASK (1 << 2) | ||
| 62 | #define S2MPA01_IRQ_B16_TSD_MASK (1 << 3) | ||
| 63 | #define S2MPA01_IRQ_B24_TSD_MASK (1 << 4) | ||
| 64 | #define S2MPA01_IRQ_B35_TSD_MASK (1 << 5) | ||
| 65 | |||
| 16 | enum s2mps11_irq { | 66 | enum s2mps11_irq { |
| 17 | S2MPS11_IRQ_PWRONF, | 67 | S2MPS11_IRQ_PWRONF, |
| 18 | S2MPS11_IRQ_PWRONR, | 68 | S2MPS11_IRQ_PWRONR, |
| @@ -24,8 +74,8 @@ enum s2mps11_irq { | |||
| 24 | S2MPS11_IRQ_MRB, | 74 | S2MPS11_IRQ_MRB, |
| 25 | 75 | ||
| 26 | S2MPS11_IRQ_RTC60S, | 76 | S2MPS11_IRQ_RTC60S, |
| 77 | S2MPS11_IRQ_RTCA0, | ||
| 27 | S2MPS11_IRQ_RTCA1, | 78 | S2MPS11_IRQ_RTCA1, |
| 28 | S2MPS11_IRQ_RTCA2, | ||
| 29 | S2MPS11_IRQ_SMPL, | 79 | S2MPS11_IRQ_SMPL, |
| 30 | S2MPS11_IRQ_RTC1S, | 80 | S2MPS11_IRQ_RTC1S, |
| 31 | S2MPS11_IRQ_WTSR, | 81 | S2MPS11_IRQ_WTSR, |
| @@ -47,7 +97,7 @@ enum s2mps11_irq { | |||
| 47 | 97 | ||
| 48 | #define S2MPS11_IRQ_RTC60S_MASK (1 << 0) | 98 | #define S2MPS11_IRQ_RTC60S_MASK (1 << 0) |
| 49 | #define S2MPS11_IRQ_RTCA1_MASK (1 << 1) | 99 | #define S2MPS11_IRQ_RTCA1_MASK (1 << 1) |
| 50 | #define S2MPS11_IRQ_RTCA2_MASK (1 << 2) | 100 | #define S2MPS11_IRQ_RTCA0_MASK (1 << 2) |
| 51 | #define S2MPS11_IRQ_SMPL_MASK (1 << 3) | 101 | #define S2MPS11_IRQ_SMPL_MASK (1 << 3) |
| 52 | #define S2MPS11_IRQ_RTC1S_MASK (1 << 4) | 102 | #define S2MPS11_IRQ_RTC1S_MASK (1 << 4) |
| 53 | #define S2MPS11_IRQ_WTSR_MASK (1 << 5) | 103 | #define S2MPS11_IRQ_WTSR_MASK (1 << 5) |
| @@ -55,6 +105,33 @@ enum s2mps11_irq { | |||
| 55 | #define S2MPS11_IRQ_INT120C_MASK (1 << 0) | 105 | #define S2MPS11_IRQ_INT120C_MASK (1 << 0) |
| 56 | #define S2MPS11_IRQ_INT140C_MASK (1 << 1) | 106 | #define S2MPS11_IRQ_INT140C_MASK (1 << 1) |
| 57 | 107 | ||
| 108 | enum s2mps14_irq { | ||
| 109 | S2MPS14_IRQ_PWRONF, | ||
| 110 | S2MPS14_IRQ_PWRONR, | ||
| 111 | S2MPS14_IRQ_JIGONBF, | ||
| 112 | S2MPS14_IRQ_JIGONBR, | ||
| 113 | S2MPS14_IRQ_ACOKBF, | ||
| 114 | S2MPS14_IRQ_ACOKBR, | ||
| 115 | S2MPS14_IRQ_PWRON1S, | ||
| 116 | S2MPS14_IRQ_MRB, | ||
| 117 | |||
| 118 | S2MPS14_IRQ_RTC60S, | ||
| 119 | S2MPS14_IRQ_RTCA1, | ||
| 120 | S2MPS14_IRQ_RTCA0, | ||
| 121 | S2MPS14_IRQ_SMPL, | ||
| 122 | S2MPS14_IRQ_RTC1S, | ||
| 123 | S2MPS14_IRQ_WTSR, | ||
| 124 | |||
| 125 | S2MPS14_IRQ_INT120C, | ||
| 126 | S2MPS14_IRQ_INT140C, | ||
| 127 | S2MPS14_IRQ_TSD, | ||
| 128 | |||
| 129 | S2MPS14_IRQ_NR, | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* Masks for interrupts are the same as in s2mps11 */ | ||
| 133 | #define S2MPS14_IRQ_TSD_MASK (1 << 2) | ||
| 134 | |||
| 58 | enum s5m8767_irq { | 135 | enum s5m8767_irq { |
| 59 | S5M8767_IRQ_PWRR, | 136 | S5M8767_IRQ_PWRR, |
| 60 | S5M8767_IRQ_PWRF, | 137 | S5M8767_IRQ_PWRF, |
diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h index 94b7cd6d8891..3e02b768d537 100644 --- a/include/linux/mfd/samsung/rtc.h +++ b/include/linux/mfd/samsung/rtc.h | |||
| @@ -1,12 +1,17 @@ | |||
| 1 | /* rtc.h | 1 | /* rtc.h |
| 2 | * | 2 | * |
| 3 | * Copyright (c) 2011 Samsung Electronics Co., Ltd | 3 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd |
| 4 | * http://www.samsung.com | 4 | * http://www.samsung.com |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | 8 | * Free Software Foundation; either version 2 of the License, or (at your |
| 9 | * option) any later version. | 9 | * option) any later version. |
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 10 | * | 15 | * |
| 11 | */ | 16 | */ |
| 12 | 17 | ||
| @@ -43,6 +48,39 @@ enum sec_rtc_reg { | |||
| 43 | SEC_RTC_STATUS, | 48 | SEC_RTC_STATUS, |
| 44 | SEC_WTSR_SMPL_CNTL, | 49 | SEC_WTSR_SMPL_CNTL, |
| 45 | SEC_RTC_UDR_CON, | 50 | SEC_RTC_UDR_CON, |
| 51 | |||
| 52 | SEC_RTC_REG_MAX, | ||
| 53 | }; | ||
| 54 | |||
| 55 | enum s2mps_rtc_reg { | ||
| 56 | S2MPS_RTC_CTRL, | ||
| 57 | S2MPS_WTSR_SMPL_CNTL, | ||
| 58 | S2MPS_RTC_UDR_CON, | ||
| 59 | S2MPS_RSVD, | ||
| 60 | S2MPS_RTC_SEC, | ||
| 61 | S2MPS_RTC_MIN, | ||
| 62 | S2MPS_RTC_HOUR, | ||
| 63 | S2MPS_RTC_WEEKDAY, | ||
| 64 | S2MPS_RTC_DATE, | ||
| 65 | S2MPS_RTC_MONTH, | ||
| 66 | S2MPS_RTC_YEAR, | ||
| 67 | S2MPS_ALARM0_SEC, | ||
| 68 | S2MPS_ALARM0_MIN, | ||
| 69 | S2MPS_ALARM0_HOUR, | ||
| 70 | S2MPS_ALARM0_WEEKDAY, | ||
| 71 | S2MPS_ALARM0_DATE, | ||
| 72 | S2MPS_ALARM0_MONTH, | ||
| 73 | S2MPS_ALARM0_YEAR, | ||
| 74 | S2MPS_ALARM1_SEC, | ||
| 75 | S2MPS_ALARM1_MIN, | ||
| 76 | S2MPS_ALARM1_HOUR, | ||
| 77 | S2MPS_ALARM1_WEEKDAY, | ||
| 78 | S2MPS_ALARM1_DATE, | ||
| 79 | S2MPS_ALARM1_MONTH, | ||
| 80 | S2MPS_ALARM1_YEAR, | ||
| 81 | S2MPS_OFFSRC, | ||
| 82 | |||
| 83 | S2MPS_RTC_REG_MAX, | ||
| 46 | }; | 84 | }; |
| 47 | 85 | ||
| 48 | #define RTC_I2C_ADDR (0x0C >> 1) | 86 | #define RTC_I2C_ADDR (0x0C >> 1) |
| @@ -54,6 +92,9 @@ enum sec_rtc_reg { | |||
| 54 | #define ALARM1_STATUS (1 << 2) | 92 | #define ALARM1_STATUS (1 << 2) |
| 55 | #define UPDATE_AD (1 << 0) | 93 | #define UPDATE_AD (1 << 0) |
| 56 | 94 | ||
| 95 | #define S2MPS_ALARM0_STATUS (1 << 2) | ||
| 96 | #define S2MPS_ALARM1_STATUS (1 << 1) | ||
| 97 | |||
| 57 | /* RTC Control Register */ | 98 | /* RTC Control Register */ |
| 58 | #define BCD_EN_SHIFT 0 | 99 | #define BCD_EN_SHIFT 0 |
| 59 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | 100 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) |
| @@ -62,6 +103,10 @@ enum sec_rtc_reg { | |||
| 62 | /* RTC Update Register1 */ | 103 | /* RTC Update Register1 */ |
| 63 | #define RTC_UDR_SHIFT 0 | 104 | #define RTC_UDR_SHIFT 0 |
| 64 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | 105 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) |
| 106 | #define S2MPS_RTC_WUDR_SHIFT 4 | ||
| 107 | #define S2MPS_RTC_WUDR_MASK (1 << S2MPS_RTC_WUDR_SHIFT) | ||
| 108 | #define S2MPS_RTC_RUDR_SHIFT 0 | ||
| 109 | #define S2MPS_RTC_RUDR_MASK (1 << S2MPS_RTC_RUDR_SHIFT) | ||
| 65 | #define RTC_TCON_SHIFT 1 | 110 | #define RTC_TCON_SHIFT 1 |
| 66 | #define RTC_TCON_MASK (1 << RTC_TCON_SHIFT) | 111 | #define RTC_TCON_MASK (1 << RTC_TCON_SHIFT) |
| 67 | #define RTC_TIME_EN_SHIFT 3 | 112 | #define RTC_TIME_EN_SHIFT 3 |
diff --git a/include/linux/mfd/samsung/s2mpa01.h b/include/linux/mfd/samsung/s2mpa01.h new file mode 100644 index 000000000000..fbc63bc0d6a2 --- /dev/null +++ b/include/linux/mfd/samsung/s2mpa01.h | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Samsung Electronics Co., Ltd | ||
| 3 | * http://www.samsung.com | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License as published by the | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __LINUX_MFD_S2MPA01_H | ||
| 13 | #define __LINUX_MFD_S2MPA01_H | ||
| 14 | |||
| 15 | /* S2MPA01 registers */ | ||
| 16 | enum s2mpa01_reg { | ||
| 17 | S2MPA01_REG_ID, | ||
| 18 | S2MPA01_REG_INT1, | ||
| 19 | S2MPA01_REG_INT2, | ||
| 20 | S2MPA01_REG_INT3, | ||
| 21 | S2MPA01_REG_INT1M, | ||
| 22 | S2MPA01_REG_INT2M, | ||
| 23 | S2MPA01_REG_INT3M, | ||
| 24 | S2MPA01_REG_ST1, | ||
| 25 | S2MPA01_REG_ST2, | ||
| 26 | S2MPA01_REG_PWRONSRC, | ||
| 27 | S2MPA01_REG_OFFSRC, | ||
| 28 | S2MPA01_REG_RTC_BUF, | ||
| 29 | S2MPA01_REG_CTRL1, | ||
| 30 | S2MPA01_REG_ETC_TEST, | ||
| 31 | S2MPA01_REG_RSVD1, | ||
| 32 | S2MPA01_REG_BU_CHG, | ||
| 33 | S2MPA01_REG_RAMP1, | ||
| 34 | S2MPA01_REG_RAMP2, | ||
| 35 | S2MPA01_REG_LDO_DSCH1, | ||
| 36 | S2MPA01_REG_LDO_DSCH2, | ||
| 37 | S2MPA01_REG_LDO_DSCH3, | ||
| 38 | S2MPA01_REG_LDO_DSCH4, | ||
| 39 | S2MPA01_REG_OTP_ADRL, | ||
| 40 | S2MPA01_REG_OTP_ADRH, | ||
| 41 | S2MPA01_REG_OTP_DATA, | ||
| 42 | S2MPA01_REG_MON1SEL, | ||
| 43 | S2MPA01_REG_MON2SEL, | ||
| 44 | S2MPA01_REG_LEE, | ||
| 45 | S2MPA01_REG_RSVD2, | ||
| 46 | S2MPA01_REG_RSVD3, | ||
| 47 | S2MPA01_REG_RSVD4, | ||
| 48 | S2MPA01_REG_RSVD5, | ||
| 49 | S2MPA01_REG_RSVD6, | ||
| 50 | S2MPA01_REG_TOP_RSVD, | ||
| 51 | S2MPA01_REG_DVS_SEL, | ||
| 52 | S2MPA01_REG_DVS_PTR, | ||
| 53 | S2MPA01_REG_DVS_DATA, | ||
| 54 | S2MPA01_REG_RSVD_NO, | ||
| 55 | S2MPA01_REG_UVLO, | ||
| 56 | S2MPA01_REG_LEE_NO, | ||
| 57 | S2MPA01_REG_B1CTRL1, | ||
| 58 | S2MPA01_REG_B1CTRL2, | ||
| 59 | S2MPA01_REG_B2CTRL1, | ||
| 60 | S2MPA01_REG_B2CTRL2, | ||
| 61 | S2MPA01_REG_B3CTRL1, | ||
| 62 | S2MPA01_REG_B3CTRL2, | ||
| 63 | S2MPA01_REG_B4CTRL1, | ||
| 64 | S2MPA01_REG_B4CTRL2, | ||
| 65 | S2MPA01_REG_B5CTRL1, | ||
| 66 | S2MPA01_REG_B5CTRL2, | ||
| 67 | S2MPA01_REG_B5CTRL3, | ||
| 68 | S2MPA01_REG_B5CTRL4, | ||
| 69 | S2MPA01_REG_B5CTRL5, | ||
| 70 | S2MPA01_REG_B5CTRL6, | ||
| 71 | S2MPA01_REG_B6CTRL1, | ||
| 72 | S2MPA01_REG_B6CTRL2, | ||
| 73 | S2MPA01_REG_B7CTRL1, | ||
| 74 | S2MPA01_REG_B7CTRL2, | ||
| 75 | S2MPA01_REG_B8CTRL1, | ||
| 76 | S2MPA01_REG_B8CTRL2, | ||
| 77 | S2MPA01_REG_B9CTRL1, | ||
| 78 | S2MPA01_REG_B9CTRL2, | ||
| 79 | S2MPA01_REG_B10CTRL1, | ||
| 80 | S2MPA01_REG_B10CTRL2, | ||
| 81 | S2MPA01_REG_L1CTRL, | ||
| 82 | S2MPA01_REG_L2CTRL, | ||
| 83 | S2MPA01_REG_L3CTRL, | ||
| 84 | S2MPA01_REG_L4CTRL, | ||
| 85 | S2MPA01_REG_L5CTRL, | ||
| 86 | S2MPA01_REG_L6CTRL, | ||
| 87 | S2MPA01_REG_L7CTRL, | ||
| 88 | S2MPA01_REG_L8CTRL, | ||
| 89 | S2MPA01_REG_L9CTRL, | ||
| 90 | S2MPA01_REG_L10CTRL, | ||
| 91 | S2MPA01_REG_L11CTRL, | ||
| 92 | S2MPA01_REG_L12CTRL, | ||
| 93 | S2MPA01_REG_L13CTRL, | ||
| 94 | S2MPA01_REG_L14CTRL, | ||
| 95 | S2MPA01_REG_L15CTRL, | ||
| 96 | S2MPA01_REG_L16CTRL, | ||
| 97 | S2MPA01_REG_L17CTRL, | ||
| 98 | S2MPA01_REG_L18CTRL, | ||
| 99 | S2MPA01_REG_L19CTRL, | ||
| 100 | S2MPA01_REG_L20CTRL, | ||
| 101 | S2MPA01_REG_L21CTRL, | ||
| 102 | S2MPA01_REG_L22CTRL, | ||
| 103 | S2MPA01_REG_L23CTRL, | ||
| 104 | S2MPA01_REG_L24CTRL, | ||
| 105 | S2MPA01_REG_L25CTRL, | ||
| 106 | S2MPA01_REG_L26CTRL, | ||
| 107 | |||
| 108 | S2MPA01_REG_LDO_OVCB1, | ||
| 109 | S2MPA01_REG_LDO_OVCB2, | ||
| 110 | S2MPA01_REG_LDO_OVCB3, | ||
| 111 | S2MPA01_REG_LDO_OVCB4, | ||
| 112 | |||
| 113 | }; | ||
| 114 | |||
| 115 | /* S2MPA01 regulator ids */ | ||
| 116 | enum s2mpa01_regulators { | ||
| 117 | S2MPA01_LDO1, | ||
| 118 | S2MPA01_LDO2, | ||
| 119 | S2MPA01_LDO3, | ||
| 120 | S2MPA01_LDO4, | ||
| 121 | S2MPA01_LDO5, | ||
| 122 | S2MPA01_LDO6, | ||
| 123 | S2MPA01_LDO7, | ||
| 124 | S2MPA01_LDO8, | ||
| 125 | S2MPA01_LDO9, | ||
| 126 | S2MPA01_LDO10, | ||
| 127 | S2MPA01_LDO11, | ||
| 128 | S2MPA01_LDO12, | ||
| 129 | S2MPA01_LDO13, | ||
| 130 | S2MPA01_LDO14, | ||
| 131 | S2MPA01_LDO15, | ||
| 132 | S2MPA01_LDO16, | ||
| 133 | S2MPA01_LDO17, | ||
| 134 | S2MPA01_LDO18, | ||
| 135 | S2MPA01_LDO19, | ||
| 136 | S2MPA01_LDO20, | ||
| 137 | S2MPA01_LDO21, | ||
| 138 | S2MPA01_LDO22, | ||
| 139 | S2MPA01_LDO23, | ||
| 140 | S2MPA01_LDO24, | ||
| 141 | S2MPA01_LDO25, | ||
| 142 | S2MPA01_LDO26, | ||
| 143 | |||
| 144 | S2MPA01_BUCK1, | ||
| 145 | S2MPA01_BUCK2, | ||
| 146 | S2MPA01_BUCK3, | ||
| 147 | S2MPA01_BUCK4, | ||
| 148 | S2MPA01_BUCK5, | ||
| 149 | S2MPA01_BUCK6, | ||
| 150 | S2MPA01_BUCK7, | ||
| 151 | S2MPA01_BUCK8, | ||
| 152 | S2MPA01_BUCK9, | ||
| 153 | S2MPA01_BUCK10, | ||
| 154 | |||
| 155 | S2MPA01_REGULATOR_MAX, | ||
| 156 | }; | ||
| 157 | |||
| 158 | #define S2MPA01_BUCK_MIN1 600000 | ||
| 159 | #define S2MPA01_BUCK_MIN2 800000 | ||
| 160 | #define S2MPA01_BUCK_MIN3 1000000 | ||
| 161 | #define S2MPA01_BUCK_MIN4 1500000 | ||
| 162 | #define S2MPA01_LDO_MIN 800000 | ||
| 163 | |||
| 164 | #define S2MPA01_BUCK_STEP1 6250 | ||
| 165 | #define S2MPA01_BUCK_STEP2 12500 | ||
| 166 | |||
| 167 | #define S2MPA01_LDO_STEP1 50000 | ||
| 168 | #define S2MPA01_LDO_STEP2 25000 | ||
| 169 | |||
| 170 | #define S2MPA01_LDO_VSEL_MASK 0x3F | ||
| 171 | #define S2MPA01_BUCK_VSEL_MASK 0xFF | ||
| 172 | #define S2MPA01_ENABLE_MASK (0x03 << S2MPA01_ENABLE_SHIFT) | ||
| 173 | #define S2MPA01_ENABLE_SHIFT 0x06 | ||
| 174 | #define S2MPA01_LDO_N_VOLTAGES (S2MPA01_LDO_VSEL_MASK + 1) | ||
| 175 | #define S2MPA01_BUCK_N_VOLTAGES (S2MPA01_BUCK_VSEL_MASK + 1) | ||
| 176 | |||
| 177 | #define S2MPA01_RAMP_DELAY 12500 /* uV/us */ | ||
| 178 | |||
| 179 | #define S2MPA01_BUCK16_RAMP_SHIFT 4 | ||
| 180 | #define S2MPA01_BUCK24_RAMP_SHIFT 6 | ||
| 181 | #define S2MPA01_BUCK3_RAMP_SHIFT 4 | ||
| 182 | #define S2MPA01_BUCK5_RAMP_SHIFT 6 | ||
| 183 | #define S2MPA01_BUCK7_RAMP_SHIFT 2 | ||
| 184 | #define S2MPA01_BUCK8910_RAMP_SHIFT 0 | ||
| 185 | |||
| 186 | #define S2MPA01_BUCK1_RAMP_EN_SHIFT 3 | ||
| 187 | #define S2MPA01_BUCK2_RAMP_EN_SHIFT 2 | ||
| 188 | #define S2MPA01_BUCK3_RAMP_EN_SHIFT 1 | ||
| 189 | #define S2MPA01_BUCK4_RAMP_EN_SHIFT 0 | ||
| 190 | #define S2MPA01_PMIC_EN_SHIFT 6 | ||
| 191 | |||
| 192 | #endif /*__LINUX_MFD_S2MPA01_H */ | ||
diff --git a/include/linux/mfd/samsung/s2mps14.h b/include/linux/mfd/samsung/s2mps14.h new file mode 100644 index 000000000000..4b449b8ac548 --- /dev/null +++ b/include/linux/mfd/samsung/s2mps14.h | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | /* | ||
| 2 | * s2mps14.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Samsung Electronics Co., Ltd | ||
| 5 | * http://www.samsung.com | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __LINUX_MFD_S2MPS14_H | ||
| 20 | #define __LINUX_MFD_S2MPS14_H | ||
| 21 | |||
| 22 | /* S2MPS14 registers */ | ||
| 23 | enum s2mps14_reg { | ||
| 24 | S2MPS14_REG_ID, | ||
| 25 | S2MPS14_REG_INT1, | ||
| 26 | S2MPS14_REG_INT2, | ||
| 27 | S2MPS14_REG_INT3, | ||
| 28 | S2MPS14_REG_INT1M, | ||
| 29 | S2MPS14_REG_INT2M, | ||
| 30 | S2MPS14_REG_INT3M, | ||
| 31 | S2MPS14_REG_ST1, | ||
| 32 | S2MPS14_REG_ST2, | ||
| 33 | S2MPS14_REG_PWRONSRC, | ||
| 34 | S2MPS14_REG_OFFSRC, | ||
| 35 | S2MPS14_REG_BU_CHG, | ||
| 36 | S2MPS14_REG_RTCCTRL, | ||
| 37 | S2MPS14_REG_CTRL1, | ||
| 38 | S2MPS14_REG_CTRL2, | ||
| 39 | S2MPS14_REG_RSVD1, | ||
| 40 | S2MPS14_REG_RSVD2, | ||
| 41 | S2MPS14_REG_RSVD3, | ||
| 42 | S2MPS14_REG_RSVD4, | ||
| 43 | S2MPS14_REG_RSVD5, | ||
| 44 | S2MPS14_REG_RSVD6, | ||
| 45 | S2MPS14_REG_CTRL3, | ||
| 46 | S2MPS14_REG_RSVD7, | ||
| 47 | S2MPS14_REG_RSVD8, | ||
| 48 | S2MPS14_REG_WRSTBI, | ||
| 49 | S2MPS14_REG_B1CTRL1, | ||
| 50 | S2MPS14_REG_B1CTRL2, | ||
| 51 | S2MPS14_REG_B2CTRL1, | ||
| 52 | S2MPS14_REG_B2CTRL2, | ||
| 53 | S2MPS14_REG_B3CTRL1, | ||
| 54 | S2MPS14_REG_B3CTRL2, | ||
| 55 | S2MPS14_REG_B4CTRL1, | ||
| 56 | S2MPS14_REG_B4CTRL2, | ||
| 57 | S2MPS14_REG_B5CTRL1, | ||
| 58 | S2MPS14_REG_B5CTRL2, | ||
| 59 | S2MPS14_REG_L1CTRL, | ||
| 60 | S2MPS14_REG_L2CTRL, | ||
| 61 | S2MPS14_REG_L3CTRL, | ||
| 62 | S2MPS14_REG_L4CTRL, | ||
| 63 | S2MPS14_REG_L5CTRL, | ||
| 64 | S2MPS14_REG_L6CTRL, | ||
| 65 | S2MPS14_REG_L7CTRL, | ||
| 66 | S2MPS14_REG_L8CTRL, | ||
| 67 | S2MPS14_REG_L9CTRL, | ||
| 68 | S2MPS14_REG_L10CTRL, | ||
| 69 | S2MPS14_REG_L11CTRL, | ||
| 70 | S2MPS14_REG_L12CTRL, | ||
| 71 | S2MPS14_REG_L13CTRL, | ||
| 72 | S2MPS14_REG_L14CTRL, | ||
| 73 | S2MPS14_REG_L15CTRL, | ||
| 74 | S2MPS14_REG_L16CTRL, | ||
| 75 | S2MPS14_REG_L17CTRL, | ||
| 76 | S2MPS14_REG_L18CTRL, | ||
| 77 | S2MPS14_REG_L19CTRL, | ||
| 78 | S2MPS14_REG_L20CTRL, | ||
| 79 | S2MPS14_REG_L21CTRL, | ||
| 80 | S2MPS14_REG_L22CTRL, | ||
| 81 | S2MPS14_REG_L23CTRL, | ||
| 82 | S2MPS14_REG_L24CTRL, | ||
| 83 | S2MPS14_REG_L25CTRL, | ||
| 84 | S2MPS14_REG_LDODSCH1, | ||
| 85 | S2MPS14_REG_LDODSCH2, | ||
| 86 | S2MPS14_REG_LDODSCH3, | ||
| 87 | }; | ||
| 88 | |||
| 89 | /* S2MPS14 regulator ids */ | ||
| 90 | enum s2mps14_regulators { | ||
| 91 | S2MPS14_LDO1, | ||
| 92 | S2MPS14_LDO2, | ||
| 93 | S2MPS14_LDO3, | ||
| 94 | S2MPS14_LDO4, | ||
| 95 | S2MPS14_LDO5, | ||
| 96 | S2MPS14_LDO6, | ||
| 97 | S2MPS14_LDO7, | ||
| 98 | S2MPS14_LDO8, | ||
| 99 | S2MPS14_LDO9, | ||
| 100 | S2MPS14_LDO10, | ||
| 101 | S2MPS14_LDO11, | ||
| 102 | S2MPS14_LDO12, | ||
| 103 | S2MPS14_LDO13, | ||
| 104 | S2MPS14_LDO14, | ||
| 105 | S2MPS14_LDO15, | ||
| 106 | S2MPS14_LDO16, | ||
| 107 | S2MPS14_LDO17, | ||
| 108 | S2MPS14_LDO18, | ||
| 109 | S2MPS14_LDO19, | ||
| 110 | S2MPS14_LDO20, | ||
| 111 | S2MPS14_LDO21, | ||
| 112 | S2MPS14_LDO22, | ||
| 113 | S2MPS14_LDO23, | ||
| 114 | S2MPS14_LDO24, | ||
| 115 | S2MPS14_LDO25, | ||
| 116 | S2MPS14_BUCK1, | ||
| 117 | S2MPS14_BUCK2, | ||
| 118 | S2MPS14_BUCK3, | ||
| 119 | S2MPS14_BUCK4, | ||
| 120 | S2MPS14_BUCK5, | ||
| 121 | |||
| 122 | S2MPS14_REGULATOR_MAX, | ||
| 123 | }; | ||
| 124 | |||
| 125 | /* Regulator constraints for BUCKx */ | ||
| 126 | #define S2MPS14_BUCK1235_MIN_600MV 600000 | ||
| 127 | #define S2MPS14_BUCK4_MIN_1400MV 1400000 | ||
| 128 | #define S2MPS14_BUCK1235_STEP_6_25MV 6250 | ||
| 129 | #define S2MPS14_BUCK4_STEP_12_5MV 12500 | ||
| 130 | #define S2MPS14_BUCK1235_START_SEL 0x20 | ||
| 131 | #define S2MPS14_BUCK4_START_SEL 0x40 | ||
| 132 | /* | ||
| 133 | * Default ramp delay in uv/us. Datasheet says that ramp delay can be | ||
| 134 | * controlled however it does not specify which register is used for that. | ||
| 135 | * Let's assume that default value will be set. | ||
| 136 | */ | ||
| 137 | #define S2MPS14_BUCK_RAMP_DELAY 12500 | ||
| 138 | |||
| 139 | /* Regulator constraints for different types of LDOx */ | ||
| 140 | #define S2MPS14_LDO_MIN_800MV 800000 | ||
| 141 | #define S2MPS14_LDO_MIN_1800MV 1800000 | ||
| 142 | #define S2MPS14_LDO_STEP_12_5MV 12500 | ||
| 143 | #define S2MPS14_LDO_STEP_25MV 25000 | ||
| 144 | |||
| 145 | #define S2MPS14_LDO_VSEL_MASK 0x3F | ||
| 146 | #define S2MPS14_BUCK_VSEL_MASK 0xFF | ||
| 147 | #define S2MPS14_ENABLE_MASK (0x03 << S2MPS14_ENABLE_SHIFT) | ||
| 148 | #define S2MPS14_ENABLE_SHIFT 6 | ||
| 149 | /* On/Off controlled by PWREN */ | ||
| 150 | #define S2MPS14_ENABLE_SUSPEND (0x01 << S2MPS14_ENABLE_SHIFT) | ||
| 151 | #define S2MPS14_LDO_N_VOLTAGES (S2MPS14_LDO_VSEL_MASK + 1) | ||
| 152 | #define S2MPS14_BUCK_N_VOLTAGES (S2MPS14_BUCK_VSEL_MASK + 1) | ||
| 153 | |||
| 154 | #endif /* __LINUX_MFD_S2MPS14_H */ | ||
diff --git a/include/linux/mfd/samsung/s5m8767.h b/include/linux/mfd/samsung/s5m8767.h index 2ab0b0f03641..243b58fec33d 100644 --- a/include/linux/mfd/samsung/s5m8767.h +++ b/include/linux/mfd/samsung/s5m8767.h | |||
| @@ -183,10 +183,17 @@ enum s5m8767_regulators { | |||
| 183 | S5M8767_REG_MAX, | 183 | S5M8767_REG_MAX, |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | /* LDO_EN/BUCK_EN field in registers */ | ||
| 186 | #define S5M8767_ENCTRL_SHIFT 6 | 187 | #define S5M8767_ENCTRL_SHIFT 6 |
| 187 | #define S5M8767_ENCTRL_MASK (0x3 << S5M8767_ENCTRL_SHIFT) | 188 | #define S5M8767_ENCTRL_MASK (0x3 << S5M8767_ENCTRL_SHIFT) |
| 188 | 189 | ||
| 189 | /* | 190 | /* |
| 191 | * LDO_EN/BUCK_EN register value for controlling this Buck or LDO | ||
| 192 | * by GPIO (PWREN, BUCKEN). | ||
| 193 | */ | ||
| 194 | #define S5M8767_ENCTRL_USE_GPIO 0x1 | ||
| 195 | |||
| 196 | /* | ||
| 190 | * Values for BUCK_RAMP field in DVS_RAMP register, matching raw values | 197 | * Values for BUCK_RAMP field in DVS_RAMP register, matching raw values |
| 191 | * in mV/us. | 198 | * in mV/us. |
| 192 | */ | 199 | */ |
diff --git a/include/linux/of.h b/include/linux/of.h index 435cb995904d..83d1ac80c91e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -198,6 +198,8 @@ extern struct device_node *of_find_node_with_property( | |||
| 198 | extern struct property *of_find_property(const struct device_node *np, | 198 | extern struct property *of_find_property(const struct device_node *np, |
| 199 | const char *name, | 199 | const char *name, |
| 200 | int *lenp); | 200 | int *lenp); |
| 201 | extern int of_property_count_elems_of_size(const struct device_node *np, | ||
| 202 | const char *propname, int elem_size); | ||
| 201 | extern int of_property_read_u32_index(const struct device_node *np, | 203 | extern int of_property_read_u32_index(const struct device_node *np, |
| 202 | const char *propname, | 204 | const char *propname, |
| 203 | u32 index, u32 *out_value); | 205 | u32 index, u32 *out_value); |
| @@ -390,6 +392,12 @@ static inline struct device_node *of_find_compatible_node( | |||
| 390 | return NULL; | 392 | return NULL; |
| 391 | } | 393 | } |
| 392 | 394 | ||
| 395 | static inline int of_property_count_elems_of_size(const struct device_node *np, | ||
| 396 | const char *propname, int elem_size) | ||
| 397 | { | ||
| 398 | return -ENOSYS; | ||
| 399 | } | ||
| 400 | |||
| 393 | static inline int of_property_read_u32_index(const struct device_node *np, | 401 | static inline int of_property_read_u32_index(const struct device_node *np, |
| 394 | const char *propname, u32 index, u32 *out_value) | 402 | const char *propname, u32 index, u32 *out_value) |
| 395 | { | 403 | { |
| @@ -536,6 +544,74 @@ static inline struct device_node *of_find_matching_node( | |||
| 536 | } | 544 | } |
| 537 | 545 | ||
| 538 | /** | 546 | /** |
| 547 | * of_property_count_u8_elems - Count the number of u8 elements in a property | ||
| 548 | * | ||
| 549 | * @np: device node from which the property value is to be read. | ||
| 550 | * @propname: name of the property to be searched. | ||
| 551 | * | ||
| 552 | * Search for a property in a device node and count the number of u8 elements | ||
| 553 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
| 554 | * not exist or its length does not match a multiple of u8 and -ENODATA if the | ||
| 555 | * property does not have a value. | ||
| 556 | */ | ||
| 557 | static inline int of_property_count_u8_elems(const struct device_node *np, | ||
| 558 | const char *propname) | ||
| 559 | { | ||
| 560 | return of_property_count_elems_of_size(np, propname, sizeof(u8)); | ||
| 561 | } | ||
| 562 | |||
| 563 | /** | ||
| 564 | * of_property_count_u16_elems - Count the number of u16 elements in a property | ||
| 565 | * | ||
| 566 | * @np: device node from which the property value is to be read. | ||
| 567 | * @propname: name of the property to be searched. | ||
| 568 | * | ||
| 569 | * Search for a property in a device node and count the number of u16 elements | ||
| 570 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
| 571 | * not exist or its length does not match a multiple of u16 and -ENODATA if the | ||
| 572 | * property does not have a value. | ||
| 573 | */ | ||
| 574 | static inline int of_property_count_u16_elems(const struct device_node *np, | ||
| 575 | const char *propname) | ||
| 576 | { | ||
| 577 | return of_property_count_elems_of_size(np, propname, sizeof(u16)); | ||
| 578 | } | ||
| 579 | |||
| 580 | /** | ||
| 581 | * of_property_count_u32_elems - Count the number of u32 elements in a property | ||
| 582 | * | ||
| 583 | * @np: device node from which the property value is to be read. | ||
| 584 | * @propname: name of the property to be searched. | ||
| 585 | * | ||
| 586 | * Search for a property in a device node and count the number of u32 elements | ||
| 587 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
| 588 | * not exist or its length does not match a multiple of u32 and -ENODATA if the | ||
| 589 | * property does not have a value. | ||
| 590 | */ | ||
| 591 | static inline int of_property_count_u32_elems(const struct device_node *np, | ||
| 592 | const char *propname) | ||
| 593 | { | ||
| 594 | return of_property_count_elems_of_size(np, propname, sizeof(u32)); | ||
| 595 | } | ||
| 596 | |||
| 597 | /** | ||
| 598 | * of_property_count_u64_elems - Count the number of u64 elements in a property | ||
| 599 | * | ||
| 600 | * @np: device node from which the property value is to be read. | ||
| 601 | * @propname: name of the property to be searched. | ||
| 602 | * | ||
| 603 | * Search for a property in a device node and count the number of u64 elements | ||
| 604 | * in it. Returns number of elements on sucess, -EINVAL if the property does | ||
| 605 | * not exist or its length does not match a multiple of u64 and -ENODATA if the | ||
| 606 | * property does not have a value. | ||
| 607 | */ | ||
| 608 | static inline int of_property_count_u64_elems(const struct device_node *np, | ||
| 609 | const char *propname) | ||
| 610 | { | ||
| 611 | return of_property_count_elems_of_size(np, propname, sizeof(u64)); | ||
| 612 | } | ||
| 613 | |||
| 614 | /** | ||
| 539 | * of_property_read_bool - Findfrom a property | 615 | * of_property_read_bool - Findfrom a property |
| 540 | * @np: device node from which the property value is to be read. | 616 | * @np: device node from which the property value is to be read. |
| 541 | * @propname: name of the property to be searched. | 617 | * @propname: name of the property to be searched. |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 9370e65348a4..bbe03a1924c0 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
| @@ -228,10 +228,14 @@ enum regulator_type { | |||
| 228 | * output when using regulator_set_voltage_sel_regmap | 228 | * output when using regulator_set_voltage_sel_regmap |
| 229 | * @enable_reg: Register for control when using regmap enable/disable ops | 229 | * @enable_reg: Register for control when using regmap enable/disable ops |
| 230 | * @enable_mask: Mask for control when using regmap enable/disable ops | 230 | * @enable_mask: Mask for control when using regmap enable/disable ops |
| 231 | * @enable_val: Enabling value for control when using regmap enable/disable ops | ||
| 232 | * @disable_val: Disabling value for control when using regmap enable/disable ops | ||
| 231 | * @enable_is_inverted: A flag to indicate set enable_mask bits to disable | 233 | * @enable_is_inverted: A flag to indicate set enable_mask bits to disable |
| 232 | * when using regulator_enable_regmap and friends APIs. | 234 | * when using regulator_enable_regmap and friends APIs. |
| 233 | * @bypass_reg: Register for control when using regmap set_bypass | 235 | * @bypass_reg: Register for control when using regmap set_bypass |
| 234 | * @bypass_mask: Mask for control when using regmap set_bypass | 236 | * @bypass_mask: Mask for control when using regmap set_bypass |
| 237 | * @bypass_val_on: Enabling value for control when using regmap set_bypass | ||
| 238 | * @bypass_val_off: Disabling value for control when using regmap set_bypass | ||
| 235 | * | 239 | * |
| 236 | * @enable_time: Time taken for initial enable of regulator (in uS). | 240 | * @enable_time: Time taken for initial enable of regulator (in uS). |
| 237 | */ | 241 | */ |
| @@ -263,9 +267,13 @@ struct regulator_desc { | |||
| 263 | unsigned int apply_bit; | 267 | unsigned int apply_bit; |
| 264 | unsigned int enable_reg; | 268 | unsigned int enable_reg; |
| 265 | unsigned int enable_mask; | 269 | unsigned int enable_mask; |
| 270 | unsigned int enable_val; | ||
| 271 | unsigned int disable_val; | ||
| 266 | bool enable_is_inverted; | 272 | bool enable_is_inverted; |
| 267 | unsigned int bypass_reg; | 273 | unsigned int bypass_reg; |
| 268 | unsigned int bypass_mask; | 274 | unsigned int bypass_mask; |
| 275 | unsigned int bypass_val_on; | ||
| 276 | unsigned int bypass_val_off; | ||
| 269 | 277 | ||
| 270 | unsigned int enable_time; | 278 | unsigned int enable_time; |
| 271 | }; | 279 | }; |
diff --git a/include/linux/regulator/pfuze100.h b/include/linux/regulator/pfuze100.h index 65d550bf3954..364f7a7c43db 100644 --- a/include/linux/regulator/pfuze100.h +++ b/include/linux/regulator/pfuze100.h | |||
| @@ -35,6 +35,20 @@ | |||
| 35 | #define PFUZE100_VGEN6 14 | 35 | #define PFUZE100_VGEN6 14 |
| 36 | #define PFUZE100_MAX_REGULATOR 15 | 36 | #define PFUZE100_MAX_REGULATOR 15 |
| 37 | 37 | ||
| 38 | #define PFUZE200_SW1AB 0 | ||
| 39 | #define PFUZE200_SW2 1 | ||
| 40 | #define PFUZE200_SW3A 2 | ||
| 41 | #define PFUZE200_SW3B 3 | ||
| 42 | #define PFUZE200_SWBST 4 | ||
| 43 | #define PFUZE200_VSNVS 5 | ||
| 44 | #define PFUZE200_VREFDDR 6 | ||
| 45 | #define PFUZE200_VGEN1 7 | ||
| 46 | #define PFUZE200_VGEN2 8 | ||
| 47 | #define PFUZE200_VGEN3 9 | ||
| 48 | #define PFUZE200_VGEN4 10 | ||
| 49 | #define PFUZE200_VGEN5 11 | ||
| 50 | #define PFUZE200_VGEN6 12 | ||
| 51 | |||
| 38 | struct regulator_init_data; | 52 | struct regulator_init_data; |
| 39 | 53 | ||
| 40 | struct pfuze_regulator_platform_data { | 54 | struct pfuze_regulator_platform_data { |
