diff options
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/s2mpa01.txt | 90 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/s2mps11.txt | 12 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/regulator/pfuze100.txt | 96 | ||||
| -rw-r--r-- | drivers/mfd/sec-core.c | 112 | ||||
| -rw-r--r-- | drivers/mfd/sec-irq.c | 97 | ||||
| -rw-r--r-- | drivers/regulator/Kconfig | 22 | ||||
| -rw-r--r-- | drivers/regulator/Makefile | 1 | ||||
| -rw-r--r-- | drivers/regulator/max8973-regulator.c | 6 | ||||
| -rw-r--r-- | drivers/regulator/max8997.c | 22 | ||||
| -rw-r--r-- | drivers/regulator/max8998.c | 27 | ||||
| -rw-r--r-- | drivers/regulator/mc13xxx-regulator-core.c | 12 | ||||
| -rw-r--r-- | drivers/regulator/pfuze100-regulator.c | 202 | ||||
| -rw-r--r-- | drivers/regulator/rc5t583-regulator.c | 13 | ||||
| -rw-r--r-- | drivers/regulator/s2mpa01.c | 481 | ||||
| -rw-r--r-- | drivers/regulator/s2mps11.c | 360 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/core.h | 19 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/irq.h | 81 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/rtc.h | 57 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/s2mpa01.h | 192 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/s2mps14.h | 154 | ||||
| -rw-r--r-- | include/linux/regulator/pfuze100.h | 14 |
21 files changed, 1843 insertions, 227 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/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/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/regulator/Kconfig b/drivers/regulator/Kconfig index 1169a42519d5..e5e4017b1011 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -407,12 +407,12 @@ config REGULATOR_PCF50633 | |||
| 407 | on PCF50633 | 407 | on PCF50633 |
| 408 | 408 | ||
| 409 | config REGULATOR_PFUZE100 | 409 | config REGULATOR_PFUZE100 |
| 410 | tristate "Freescale PFUZE100 regulator driver" | 410 | tristate "Freescale PFUZE100/PFUZE200 regulator driver" |
| 411 | depends on I2C | 411 | depends on I2C |
| 412 | select REGMAP_I2C | 412 | select REGMAP_I2C |
| 413 | help | 413 | help |
| 414 | Say y here to support the regulators found on the Freescale PFUZE100 | 414 | Say y here to support the regulators found on the Freescale |
| 415 | PMIC. | 415 | PFUZE100/PFUZE200 PMIC. |
| 416 | 416 | ||
| 417 | config REGULATOR_RC5T583 | 417 | config REGULATOR_RC5T583 |
| 418 | tristate "RICOH RC5T583 Power regulators" | 418 | tristate "RICOH RC5T583 Power regulators" |
| @@ -424,13 +424,21 @@ config REGULATOR_RC5T583 | |||
| 424 | through regulator interface. The device supports multiple DCDC/LDO | 424 | through regulator interface. The device supports multiple DCDC/LDO |
| 425 | outputs which can be controlled by i2c communication. | 425 | outputs which can be controlled by i2c communication. |
| 426 | 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 | |||
| 427 | config REGULATOR_S2MPS11 | 434 | config REGULATOR_S2MPS11 |
| 428 | tristate "Samsung S2MPS11 voltage regulator" | 435 | tristate "Samsung S2MPS11/S2MPS14 voltage regulator" |
| 429 | depends on MFD_SEC_CORE | 436 | depends on MFD_SEC_CORE |
| 430 | help | 437 | help |
| 431 | This driver supports a Samsung S2MPS11 voltage output regulator | 438 | This driver supports a Samsung S2MPS11/S2MPS14 voltage output |
| 432 | via I2C bus. S2MPS11 is comprised of high efficient Buck converters | 439 | regulator via I2C bus. The chip is comprised of high efficient Buck |
| 433 | including Dual-Phase Buck converter, Buck-Boost converter, various LDOs. | 440 | converters including Dual-Phase Buck converter, Buck-Boost converter, |
| 441 | various LDOs. | ||
| 434 | 442 | ||
| 435 | config REGULATOR_S5M8767 | 443 | config REGULATOR_S5M8767 |
| 436 | tristate "Samsung S5M8767A voltage regulator" | 444 | tristate "Samsung S5M8767A voltage regulator" |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e1ab514f03c5..c3416728c14d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
| @@ -58,6 +58,7 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o | |||
| 58 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 58 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
| 59 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 59 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
| 60 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 60 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
| 61 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o | ||
| 61 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o | 62 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o |
| 62 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o | 63 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o |
| 63 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o | 64 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o |
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 b699d4e7acc5..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,14 +81,16 @@ 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 | ||
| @@ -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 89966213315c..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) |
| @@ -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/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 41c9bde410c5..900bc9e1888b 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; |
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/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 { |
