1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018-2021 Unisoc Inc. 4 */ 5 6 #include <linux/module.h> 7 #include <linux/of.h> 8 #include <linux/platform_device.h> 9 #include <linux/regmap.h> 10 #include <linux/regulator/driver.h> 11 #include <linux/regulator/of_regulator.h> 12 13 /* 14 * SC2730 regulator base address 15 */ 16 #define SC2730_REGULATOR_BASE 0x1800 17 18 /* 19 * SC2730 regulator lock register 20 */ 21 #define SC2730_WR_UNLOCK_VALUE 0x6e7f 22 #define SC2730_PWR_WR_PROT (SC2730_REGULATOR_BASE + 0x3d0) 23 24 /* 25 * SC2730 enable register 26 */ 27 #define SC2730_POWER_PD_SW (SC2730_REGULATOR_BASE + 0x01c) 28 #define SC2730_LDO_VDDRF18_PD (SC2730_REGULATOR_BASE + 0x10c) 29 #define SC2730_LDO_VDDCAMIO_PD (SC2730_REGULATOR_BASE + 0x118) 30 #define SC2730_LDO_VDDWCN_PD (SC2730_REGULATOR_BASE + 0x11c) 31 #define SC2730_LDO_VDDCAMD1_PD (SC2730_REGULATOR_BASE + 0x128) 32 #define SC2730_LDO_VDDCAMD0_PD (SC2730_REGULATOR_BASE + 0x134) 33 #define SC2730_LDO_VDDRF1V25_PD (SC2730_REGULATOR_BASE + 0x140) 34 #define SC2730_LDO_AVDD12_PD (SC2730_REGULATOR_BASE + 0x14c) 35 #define SC2730_LDO_VDDCAMA0_PD (SC2730_REGULATOR_BASE + 0x158) 36 #define SC2730_LDO_VDDCAMA1_PD (SC2730_REGULATOR_BASE + 0x164) 37 #define SC2730_LDO_VDDCAMMOT_PD (SC2730_REGULATOR_BASE + 0x170) 38 #define SC2730_LDO_VDDSIM2_PD (SC2730_REGULATOR_BASE + 0x194) 39 #define SC2730_LDO_VDDEMMCCORE_PD (SC2730_REGULATOR_BASE + 0x1a0) 40 #define SC2730_LDO_VDDSDCORE_PD (SC2730_REGULATOR_BASE + 0x1ac) 41 #define SC2730_LDO_VDDSDIO_PD (SC2730_REGULATOR_BASE + 0x1b8) 42 #define SC2730_LDO_VDDWIFIPA_PD (SC2730_REGULATOR_BASE + 0x1d0) 43 #define SC2730_LDO_VDDUSB33_PD (SC2730_REGULATOR_BASE + 0x1e8) 44 #define SC2730_LDO_VDDLDO0_PD (SC2730_REGULATOR_BASE + 0x1f4) 45 #define SC2730_LDO_VDDLDO1_PD (SC2730_REGULATOR_BASE + 0x200) 46 #define SC2730_LDO_VDDLDO2_PD (SC2730_REGULATOR_BASE + 0x20c) 47 #define SC2730_LDO_VDDKPLED_PD (SC2730_REGULATOR_BASE + 0x38c) 48 49 /* 50 * SC2730 enable mask 51 */ 52 #define SC2730_DCDC_CPU_PD_MASK BIT(4) 53 #define SC2730_DCDC_GPU_PD_MASK BIT(3) 54 #define SC2730_DCDC_CORE_PD_MASK BIT(5) 55 #define SC2730_DCDC_MODEM_PD_MASK BIT(11) 56 #define SC2730_DCDC_MEM_PD_MASK BIT(6) 57 #define SC2730_DCDC_MEMQ_PD_MASK BIT(12) 58 #define SC2730_DCDC_GEN0_PD_MASK BIT(8) 59 #define SC2730_DCDC_GEN1_PD_MASK BIT(7) 60 #define SC2730_DCDC_SRAM_PD_MASK BIT(13) 61 #define SC2730_LDO_AVDD18_PD_MASK BIT(2) 62 #define SC2730_LDO_VDDRF18_PD_MASK BIT(0) 63 #define SC2730_LDO_VDDCAMIO_PD_MASK BIT(0) 64 #define SC2730_LDO_VDDWCN_PD_MASK BIT(0) 65 #define SC2730_LDO_VDDCAMD1_PD_MASK BIT(0) 66 #define SC2730_LDO_VDDCAMD0_PD_MASK BIT(0) 67 #define SC2730_LDO_VDDRF1V25_PD_MASK BIT(0) 68 #define SC2730_LDO_AVDD12_PD_MASK BIT(0) 69 #define SC2730_LDO_VDDCAMA0_PD_MASK BIT(0) 70 #define SC2730_LDO_VDDCAMA1_PD_MASK BIT(0) 71 #define SC2730_LDO_VDDCAMMOT_PD_MASK BIT(0) 72 #define SC2730_LDO_VDDSIM2_PD_MASK BIT(0) 73 #define SC2730_LDO_VDDEMMCCORE_PD_MASK BIT(0) 74 #define SC2730_LDO_VDDSDCORE_PD_MASK BIT(0) 75 #define SC2730_LDO_VDDSDIO_PD_MASK BIT(0) 76 #define SC2730_LDO_VDD28_PD_MASK BIT(1) 77 #define SC2730_LDO_VDDWIFIPA_PD_MASK BIT(0) 78 #define SC2730_LDO_VDD18_DCXO_PD_MASK BIT(10) 79 #define SC2730_LDO_VDDUSB33_PD_MASK BIT(0) 80 #define SC2730_LDO_VDDLDO0_PD_MASK BIT(0) 81 #define SC2730_LDO_VDDLDO1_PD_MASK BIT(0) 82 #define SC2730_LDO_VDDLDO2_PD_MASK BIT(0) 83 #define SC2730_LDO_VDDKPLED_PD_MASK BIT(15) 84 85 /* 86 * SC2730 vsel register 87 */ 88 #define SC2730_DCDC_CPU_VOL (SC2730_REGULATOR_BASE + 0x44) 89 #define SC2730_DCDC_GPU_VOL (SC2730_REGULATOR_BASE + 0x54) 90 #define SC2730_DCDC_CORE_VOL (SC2730_REGULATOR_BASE + 0x64) 91 #define SC2730_DCDC_MODEM_VOL (SC2730_REGULATOR_BASE + 0x74) 92 #define SC2730_DCDC_MEM_VOL (SC2730_REGULATOR_BASE + 0x84) 93 #define SC2730_DCDC_MEMQ_VOL (SC2730_REGULATOR_BASE + 0x94) 94 #define SC2730_DCDC_GEN0_VOL (SC2730_REGULATOR_BASE + 0xa4) 95 #define SC2730_DCDC_GEN1_VOL (SC2730_REGULATOR_BASE + 0xb4) 96 #define SC2730_DCDC_SRAM_VOL (SC2730_REGULATOR_BASE + 0xdc) 97 #define SC2730_LDO_AVDD18_VOL (SC2730_REGULATOR_BASE + 0x104) 98 #define SC2730_LDO_VDDRF18_VOL (SC2730_REGULATOR_BASE + 0x110) 99 #define SC2730_LDO_VDDCAMIO_VOL (SC2730_REGULATOR_BASE + 0x28) 100 #define SC2730_LDO_VDDWCN_VOL (SC2730_REGULATOR_BASE + 0x120) 101 #define SC2730_LDO_VDDCAMD1_VOL (SC2730_REGULATOR_BASE + 0x12c) 102 #define SC2730_LDO_VDDCAMD0_VOL (SC2730_REGULATOR_BASE + 0x138) 103 #define SC2730_LDO_VDDRF1V25_VOL (SC2730_REGULATOR_BASE + 0x144) 104 #define SC2730_LDO_AVDD12_VOL (SC2730_REGULATOR_BASE + 0x150) 105 #define SC2730_LDO_VDDCAMA0_VOL (SC2730_REGULATOR_BASE + 0x15c) 106 #define SC2730_LDO_VDDCAMA1_VOL (SC2730_REGULATOR_BASE + 0x168) 107 #define SC2730_LDO_VDDCAMMOT_VOL (SC2730_REGULATOR_BASE + 0x174) 108 #define SC2730_LDO_VDDSIM2_VOL (SC2730_REGULATOR_BASE + 0x198) 109 #define SC2730_LDO_VDDEMMCCORE_VOL (SC2730_REGULATOR_BASE + 0x1a4) 110 #define SC2730_LDO_VDDSDCORE_VOL (SC2730_REGULATOR_BASE + 0x1b0) 111 #define SC2730_LDO_VDDSDIO_VOL (SC2730_REGULATOR_BASE + 0x1bc) 112 #define SC2730_LDO_VDD28_VOL (SC2730_REGULATOR_BASE + 0x1c8) 113 #define SC2730_LDO_VDDWIFIPA_VOL (SC2730_REGULATOR_BASE + 0x1d4) 114 #define SC2730_LDO_VDD18_DCXO_VOL (SC2730_REGULATOR_BASE + 0x1e0) 115 #define SC2730_LDO_VDDUSB33_VOL (SC2730_REGULATOR_BASE + 0x1ec) 116 #define SC2730_LDO_VDDLDO0_VOL (SC2730_REGULATOR_BASE + 0x1f8) 117 #define SC2730_LDO_VDDLDO1_VOL (SC2730_REGULATOR_BASE + 0x204) 118 #define SC2730_LDO_VDDLDO2_VOL (SC2730_REGULATOR_BASE + 0x210) 119 #define SC2730_LDO_VDDKPLED_VOL (SC2730_REGULATOR_BASE + 0x38c) 120 121 /* 122 * SC2730 vsel register mask 123 */ 124 #define SC2730_DCDC_CPU_VOL_MASK GENMASK(8, 0) 125 #define SC2730_DCDC_GPU_VOL_MASK GENMASK(8, 0) 126 #define SC2730_DCDC_CORE_VOL_MASK GENMASK(8, 0) 127 #define SC2730_DCDC_MODEM_VOL_MASK GENMASK(8, 0) 128 #define SC2730_DCDC_MEM_VOL_MASK GENMASK(7, 0) 129 #define SC2730_DCDC_MEMQ_VOL_MASK GENMASK(8, 0) 130 #define SC2730_DCDC_GEN0_VOL_MASK GENMASK(7, 0) 131 #define SC2730_DCDC_GEN1_VOL_MASK GENMASK(7, 0) 132 #define SC2730_DCDC_SRAM_VOL_MASK GENMASK(8, 0) 133 #define SC2730_LDO_AVDD18_VOL_MASK GENMASK(5, 0) 134 #define SC2730_LDO_VDDRF18_VOL_MASK GENMASK(5, 0) 135 #define SC2730_LDO_VDDCAMIO_VOL_MASK GENMASK(5, 0) 136 #define SC2730_LDO_VDDWCN_VOL_MASK GENMASK(5, 0) 137 #define SC2730_LDO_VDDCAMD1_VOL_MASK GENMASK(4, 0) 138 #define SC2730_LDO_VDDCAMD0_VOL_MASK GENMASK(4, 0) 139 #define SC2730_LDO_VDDRF1V25_VOL_MASK GENMASK(4, 0) 140 #define SC2730_LDO_AVDD12_VOL_MASK GENMASK(4, 0) 141 #define SC2730_LDO_VDDCAMA0_VOL_MASK GENMASK(7, 0) 142 #define SC2730_LDO_VDDCAMA1_VOL_MASK GENMASK(7, 0) 143 #define SC2730_LDO_VDDCAMMOT_VOL_MASK GENMASK(7, 0) 144 #define SC2730_LDO_VDDSIM2_VOL_MASK GENMASK(7, 0) 145 #define SC2730_LDO_VDDEMMCCORE_VOL_MASK GENMASK(7, 0) 146 #define SC2730_LDO_VDDSDCORE_VOL_MASK GENMASK(7, 0) 147 #define SC2730_LDO_VDDSDIO_VOL_MASK GENMASK(7, 0) 148 #define SC2730_LDO_VDD28_VOL_MASK GENMASK(7, 0) 149 #define SC2730_LDO_VDDWIFIPA_VOL_MASK GENMASK(7, 0) 150 #define SC2730_LDO_VDD18_DCXO_VOL_MASK GENMASK(7, 0) 151 #define SC2730_LDO_VDDUSB33_VOL_MASK GENMASK(7, 0) 152 #define SC2730_LDO_VDDLDO0_VOL_MASK GENMASK(7, 0) 153 #define SC2730_LDO_VDDLDO1_VOL_MASK GENMASK(7, 0) 154 #define SC2730_LDO_VDDLDO2_VOL_MASK GENMASK(7, 0) 155 #define SC2730_LDO_VDDKPLED_VOL_MASK GENMASK(14, 7) 156 157 enum sc2730_regulator_id { 158 SC2730_DCDC_CPU, 159 SC2730_DCDC_GPU, 160 SC2730_DCDC_CORE, 161 SC2730_DCDC_MODEM, 162 SC2730_DCDC_MEM, 163 SC2730_DCDC_MEMQ, 164 SC2730_DCDC_GEN0, 165 SC2730_DCDC_GEN1, 166 SC2730_DCDC_SRAM, 167 SC2730_LDO_AVDD18, 168 SC2730_LDO_VDDRF18, 169 SC2730_LDO_VDDCAMIO, 170 SC2730_LDO_VDDWCN, 171 SC2730_LDO_VDDCAMD1, 172 SC2730_LDO_VDDCAMD0, 173 SC2730_LDO_VDDRF1V25, 174 SC2730_LDO_AVDD12, 175 SC2730_LDO_VDDCAMA0, 176 SC2730_LDO_VDDCAMA1, 177 SC2730_LDO_VDDCAMMOT, 178 SC2730_LDO_VDDSIM2, 179 SC2730_LDO_VDDEMMCCORE, 180 SC2730_LDO_VDDSDCORE, 181 SC2730_LDO_VDDSDIO, 182 SC2730_LDO_VDD28, 183 SC2730_LDO_VDDWIFIPA, 184 SC2730_LDO_VDD18_DCXO, 185 SC2730_LDO_VDDUSB33, 186 SC2730_LDO_VDDLDO0, 187 SC2730_LDO_VDDLDO1, 188 SC2730_LDO_VDDLDO2, 189 SC2730_LDO_VDDKPLED, 190 }; 191 192 static const struct regulator_ops sc2730_regu_linear_ops = { 193 .enable = regulator_enable_regmap, 194 .disable = regulator_disable_regmap, 195 .is_enabled = regulator_is_enabled_regmap, 196 .list_voltage = regulator_list_voltage_linear, 197 .get_voltage_sel = regulator_get_voltage_sel_regmap, 198 .set_voltage_sel = regulator_set_voltage_sel_regmap, 199 }; 200 201 #define SC2730_REGU_LINEAR(_id, of_name, en_reg, en_mask, vreg, vmask, \ 202 vstep, vmin, vmax) { \ 203 .name = #_id, \ 204 .of_match = of_name, \ 205 .regulators_node = "regulators", \ 206 .ops = &sc2730_regu_linear_ops, \ 207 .type = REGULATOR_VOLTAGE, \ 208 .id = SC2730_##_id, \ 209 .owner = THIS_MODULE, \ 210 .min_uV = vmin, \ 211 .n_voltages = ((vmax) - (vmin)) / (vstep) + 1, \ 212 .uV_step = vstep, \ 213 .enable_is_inverted = true, \ 214 .enable_val = 0, \ 215 .enable_reg = en_reg, \ 216 .enable_mask = en_mask, \ 217 .vsel_reg = vreg, \ 218 .vsel_mask = vmask, \ 219 .linear_min_sel = 0, \ 220 } 221 222 static const struct regulator_desc regulators[] = { 223 SC2730_REGU_LINEAR(DCDC_CPU, "dcdc-cpu", SC2730_POWER_PD_SW, 224 SC2730_DCDC_CPU_PD_MASK, SC2730_DCDC_CPU_VOL, 225 SC2730_DCDC_CPU_VOL_MASK, 3125, 0, 1596875), 226 SC2730_REGU_LINEAR(DCDC_GPU, "dcdc-gpu", SC2730_POWER_PD_SW, 227 SC2730_DCDC_GPU_PD_MASK, SC2730_DCDC_GPU_VOL, 228 SC2730_DCDC_GPU_VOL_MASK, 3125, 0, 1596875), 229 SC2730_REGU_LINEAR(DCDC_CORE, "dcdc-core", SC2730_POWER_PD_SW, 230 SC2730_DCDC_CORE_PD_MASK, SC2730_DCDC_CORE_VOL, 231 SC2730_DCDC_CORE_VOL_MASK, 3125, 0, 1596875), 232 SC2730_REGU_LINEAR(DCDC_MODEM, "dcdc-modem", SC2730_POWER_PD_SW, 233 SC2730_DCDC_MODEM_PD_MASK, SC2730_DCDC_MODEM_VOL, 234 SC2730_DCDC_MODEM_VOL_MASK, 3125, 0, 1596875), 235 SC2730_REGU_LINEAR(DCDC_MEM, "dcdc-mem", SC2730_POWER_PD_SW, 236 SC2730_DCDC_MEM_PD_MASK, SC2730_DCDC_MEM_VOL, 237 SC2730_DCDC_MEM_VOL_MASK, 6250, 0, 1593750), 238 SC2730_REGU_LINEAR(DCDC_MEMQ, "dcdc-memq", SC2730_POWER_PD_SW, 239 SC2730_DCDC_MEMQ_PD_MASK, SC2730_DCDC_MEMQ_VOL, 240 SC2730_DCDC_MEMQ_VOL_MASK, 3125, 0, 1596875), 241 SC2730_REGU_LINEAR(DCDC_GEN0, "dcdc-gen0", SC2730_POWER_PD_SW, 242 SC2730_DCDC_GEN0_PD_MASK, SC2730_DCDC_GEN0_VOL, 243 SC2730_DCDC_GEN0_VOL_MASK, 9375, 20000, 2410625), 244 SC2730_REGU_LINEAR(DCDC_GEN1, "dcdc-gen1", SC2730_POWER_PD_SW, 245 SC2730_DCDC_GEN1_PD_MASK, SC2730_DCDC_GEN1_VOL, 246 SC2730_DCDC_GEN1_VOL_MASK, 6250, 50000, 1643750), 247 SC2730_REGU_LINEAR(DCDC_SRAM, "dcdc-sram", SC2730_POWER_PD_SW, 248 SC2730_DCDC_SRAM_PD_MASK, SC2730_DCDC_SRAM_VOL, 249 SC2730_DCDC_SRAM_VOL_MASK, 3125, 0, 1596875), 250 SC2730_REGU_LINEAR(LDO_AVDD18, "ldo-avdd18", SC2730_POWER_PD_SW, 251 SC2730_LDO_AVDD18_PD_MASK, SC2730_LDO_AVDD18_VOL, 252 SC2730_LDO_AVDD18_VOL_MASK, 10000, 1175000, 1805000), 253 SC2730_REGU_LINEAR(LDO_VDDRF18, "ldo-vddrf18", SC2730_LDO_VDDRF18_PD, 254 SC2730_LDO_VDDRF18_PD_MASK, SC2730_LDO_VDDRF18_VOL, 255 SC2730_LDO_VDDRF18_VOL_MASK, 10000, 1175000, 1805000), 256 SC2730_REGU_LINEAR(LDO_VDDCAMIO, "ldo-vddcamio", SC2730_LDO_VDDCAMIO_PD, 257 SC2730_LDO_VDDCAMIO_PD_MASK, SC2730_LDO_VDDCAMIO_VOL, 258 SC2730_LDO_VDDCAMIO_VOL_MASK, 10000, 1200000, 1830000), 259 SC2730_REGU_LINEAR(LDO_VDDWCN, "ldo-vddwcn", SC2730_LDO_VDDWCN_PD, 260 SC2730_LDO_VDDWCN_PD_MASK, SC2730_LDO_VDDWCN_VOL, 261 SC2730_LDO_VDDWCN_VOL_MASK, 15000, 900000, 1845000), 262 SC2730_REGU_LINEAR(LDO_VDDCAMD1, "ldo-vddcamd1", SC2730_LDO_VDDCAMD1_PD, 263 SC2730_LDO_VDDCAMD1_PD_MASK, SC2730_LDO_VDDCAMD1_VOL, 264 SC2730_LDO_VDDCAMD1_VOL_MASK, 15000, 900000, 1365000), 265 SC2730_REGU_LINEAR(LDO_VDDCAMD0, "ldo-vddcamd0", SC2730_LDO_VDDCAMD0_PD, 266 SC2730_LDO_VDDCAMD0_PD_MASK, SC2730_LDO_VDDCAMD0_VOL, 267 SC2730_LDO_VDDCAMD0_VOL_MASK, 15000, 900000, 1365000), 268 SC2730_REGU_LINEAR(LDO_VDDRF1V25, "ldo-vddrf1v25", SC2730_LDO_VDDRF1V25_PD, 269 SC2730_LDO_VDDRF1V25_PD_MASK, SC2730_LDO_VDDRF1V25_VOL, 270 SC2730_LDO_VDDRF1V25_VOL_MASK, 15000, 900000, 1365000), 271 SC2730_REGU_LINEAR(LDO_AVDD12, "ldo-avdd12", SC2730_LDO_AVDD12_PD, 272 SC2730_LDO_AVDD12_PD_MASK, SC2730_LDO_AVDD12_VOL, 273 SC2730_LDO_AVDD12_VOL_MASK, 15000, 900000, 1365000), 274 SC2730_REGU_LINEAR(LDO_VDDCAMA0, "ldo-vddcama0", SC2730_LDO_VDDCAMA0_PD, 275 SC2730_LDO_VDDCAMA0_PD_MASK, SC2730_LDO_VDDCAMA0_VOL, 276 SC2730_LDO_VDDCAMA0_VOL_MASK, 10000, 1200000, 3750000), 277 SC2730_REGU_LINEAR(LDO_VDDCAMA1, "ldo-vddcama1", SC2730_LDO_VDDCAMA1_PD, 278 SC2730_LDO_VDDCAMA1_PD_MASK, SC2730_LDO_VDDCAMA1_VOL, 279 SC2730_LDO_VDDCAMA1_VOL_MASK, 10000, 1200000, 3750000), 280 SC2730_REGU_LINEAR(LDO_VDDCAMMOT, "ldo-vddcammot", SC2730_LDO_VDDCAMMOT_PD, 281 SC2730_LDO_VDDCAMMOT_PD_MASK, SC2730_LDO_VDDCAMMOT_VOL, 282 SC2730_LDO_VDDCAMMOT_VOL_MASK, 10000, 1200000, 3750000), 283 SC2730_REGU_LINEAR(LDO_VDDSIM2, "ldo-vddsim2", SC2730_LDO_VDDSIM2_PD, 284 SC2730_LDO_VDDSIM2_PD_MASK, SC2730_LDO_VDDSIM2_VOL, 285 SC2730_LDO_VDDSIM2_VOL_MASK, 10000, 1200000, 3750000), 286 SC2730_REGU_LINEAR(LDO_VDDEMMCCORE, "ldo-vddemmccore", SC2730_LDO_VDDEMMCCORE_PD, 287 SC2730_LDO_VDDEMMCCORE_PD_MASK, SC2730_LDO_VDDEMMCCORE_VOL, 288 SC2730_LDO_VDDEMMCCORE_VOL_MASK, 10000, 1200000, 3750000), 289 SC2730_REGU_LINEAR(LDO_VDDSDCORE, "ldo-vddsdcore", SC2730_LDO_VDDSDCORE_PD, 290 SC2730_LDO_VDDSDCORE_PD_MASK, SC2730_LDO_VDDSDCORE_VOL, 291 SC2730_LDO_VDDSDCORE_VOL_MASK, 10000, 1200000, 3750000), 292 SC2730_REGU_LINEAR(LDO_VDDSDIO, "ldo-vddsdio", SC2730_LDO_VDDSDIO_PD, 293 SC2730_LDO_VDDSDIO_PD_MASK, SC2730_LDO_VDDSDIO_VOL, 294 SC2730_LDO_VDDSDIO_VOL_MASK, 10000, 1200000, 3750000), 295 SC2730_REGU_LINEAR(LDO_VDD28, "ldo-vdd28", SC2730_POWER_PD_SW, 296 SC2730_LDO_VDD28_PD_MASK, SC2730_LDO_VDD28_VOL, 297 SC2730_LDO_VDD28_VOL_MASK, 10000, 1200000, 3750000), 298 SC2730_REGU_LINEAR(LDO_VDDWIFIPA, "ldo-vddwifipa", SC2730_LDO_VDDWIFIPA_PD, 299 SC2730_LDO_VDDWIFIPA_PD_MASK, SC2730_LDO_VDDWIFIPA_VOL, 300 SC2730_LDO_VDDWIFIPA_VOL_MASK, 10000, 1200000, 3750000), 301 SC2730_REGU_LINEAR(LDO_VDD18_DCXO, "ldo-vdd18-dcxo", SC2730_POWER_PD_SW, 302 SC2730_LDO_VDD18_DCXO_PD_MASK, SC2730_LDO_VDD18_DCXO_VOL, 303 SC2730_LDO_VDD18_DCXO_VOL_MASK, 10000, 1200000, 3750000), 304 SC2730_REGU_LINEAR(LDO_VDDUSB33, "ldo-vddusb33", SC2730_LDO_VDDUSB33_PD, 305 SC2730_LDO_VDDUSB33_PD_MASK, SC2730_LDO_VDDUSB33_VOL, 306 SC2730_LDO_VDDUSB33_VOL_MASK, 10000, 1200000, 3750000), 307 SC2730_REGU_LINEAR(LDO_VDDLDO0, "ldo-vddldo0", SC2730_LDO_VDDLDO0_PD, 308 SC2730_LDO_VDDLDO0_PD_MASK, SC2730_LDO_VDDLDO0_VOL, 309 SC2730_LDO_VDDLDO0_VOL_MASK, 10000, 1200000, 3750000), 310 SC2730_REGU_LINEAR(LDO_VDDLDO1, "ldo-vddldo1", SC2730_LDO_VDDLDO1_PD, 311 SC2730_LDO_VDDLDO1_PD_MASK, SC2730_LDO_VDDLDO1_VOL, 312 SC2730_LDO_VDDLDO1_VOL_MASK, 10000, 1200000, 3750000), 313 SC2730_REGU_LINEAR(LDO_VDDLDO2, "ldo-vddldo2", SC2730_LDO_VDDLDO2_PD, 314 SC2730_LDO_VDDLDO2_PD_MASK, SC2730_LDO_VDDLDO2_VOL, 315 SC2730_LDO_VDDLDO2_VOL_MASK, 10000, 1200000, 3750000), 316 SC2730_REGU_LINEAR(LDO_VDDKPLED, "ldo-vddkpled", SC2730_LDO_VDDKPLED_PD, 317 SC2730_LDO_VDDKPLED_PD_MASK, SC2730_LDO_VDDKPLED_VOL, 318 SC2730_LDO_VDDKPLED_VOL_MASK, 10000, 1200000, 3750000), 319 }; 320 321 static int sc2730_regulator_unlock(struct regmap *regmap) 322 { 323 return regmap_write(regmap, SC2730_PWR_WR_PROT, SC2730_WR_UNLOCK_VALUE); 324 } 325 326 static int sc2730_regulator_probe(struct platform_device *pdev) 327 { 328 int i, ret; 329 struct regmap *regmap; 330 struct regulator_config config = { }; 331 struct regulator_dev *rdev; 332 333 regmap = dev_get_regmap(pdev->dev.parent, NULL); 334 if (!regmap) 335 return dev_err_probe(&pdev->dev, -ENODEV, "failed to get regmap\n"); 336 337 ret = sc2730_regulator_unlock(regmap); 338 if (ret) 339 return dev_err_probe(&pdev->dev, ret, "failed to release regulator lock\n"); 340 341 config.dev = pdev->dev.parent; 342 config.regmap = regmap; 343 344 for (i = 0; i < ARRAY_SIZE(regulators); i++) { 345 rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); 346 if (IS_ERR(rdev)) { 347 return dev_err_probe(&pdev->dev, PTR_ERR(rdev), 348 "failed to register regulator %s\n", 349 regulators[i].name); 350 } 351 } 352 353 return 0; 354 } 355 356 static const struct platform_device_id sc2730_regulator_id_table[] = { 357 { .name = "sc2730-regulator" }, 358 { } 359 }; 360 MODULE_DEVICE_TABLE(platform, sc2730_regulator_id_table); 361 362 static struct platform_driver sc2730_regulator_driver = { 363 .driver = { 364 .name = "sc2730-regulator", 365 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 366 }, 367 .probe = sc2730_regulator_probe, 368 .id_table = sc2730_regulator_id_table, 369 }; 370 371 module_platform_driver(sc2730_regulator_driver); 372 373 MODULE_AUTHOR("Zhongfa Wang <zhongfa.wang@unisoc.com>"); 374 MODULE_DESCRIPTION("Spreadtrum SC2730 regulator driver"); 375 MODULE_LICENSE("GPL"); 376