Blame view
drivers/regulator/mc13892-regulator.c
20 KB
5e428d5ce regulator: suppor... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* * Regulator Driver for Freescale MC13892 PMIC * * Copyright 2010 Yong Shen <yong.shen@linaro.org> * * Based on draft driver from Arnaud Patard <arnaud.patard@rtp-net.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/mfd/mc13892.h> #include <linux/regulator/machine.h> #include <linux/regulator/driver.h> #include <linux/platform_device.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/err.h> |
65602c32e regulator: Add mo... |
21 |
#include <linux/module.h> |
5e428d5ce regulator: suppor... |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
#include "mc13xxx.h" #define MC13892_REVISION 7 #define MC13892_POWERCTL0 13 #define MC13892_POWERCTL0_USEROFFSPI 3 #define MC13892_POWERCTL0_VCOINCELLVSEL 20 #define MC13892_POWERCTL0_VCOINCELLVSEL_M (7<<20) #define MC13892_POWERCTL0_VCOINCELLEN (1<<23) #define MC13892_SWITCHERS0_SWxHI (1<<23) #define MC13892_SWITCHERS0 24 #define MC13892_SWITCHERS0_SW1VSEL 0 #define MC13892_SWITCHERS0_SW1VSEL_M (0x1f<<0) #define MC13892_SWITCHERS0_SW1HI (1<<23) #define MC13892_SWITCHERS0_SW1EN 0 #define MC13892_SWITCHERS1 25 #define MC13892_SWITCHERS1_SW2VSEL 0 #define MC13892_SWITCHERS1_SW2VSEL_M (0x1f<<0) #define MC13892_SWITCHERS1_SW2HI (1<<23) #define MC13892_SWITCHERS1_SW2EN 0 #define MC13892_SWITCHERS2 26 #define MC13892_SWITCHERS2_SW3VSEL 0 #define MC13892_SWITCHERS2_SW3VSEL_M (0x1f<<0) #define MC13892_SWITCHERS2_SW3HI (1<<23) #define MC13892_SWITCHERS2_SW3EN 0 #define MC13892_SWITCHERS3 27 #define MC13892_SWITCHERS3_SW4VSEL 0 #define MC13892_SWITCHERS3_SW4VSEL_M (0x1f<<0) #define MC13892_SWITCHERS3_SW4HI (1<<23) #define MC13892_SWITCHERS3_SW4EN 0 #define MC13892_SWITCHERS4 28 #define MC13892_SWITCHERS4_SW1MODE 0 #define MC13892_SWITCHERS4_SW1MODE_AUTO (8<<0) #define MC13892_SWITCHERS4_SW1MODE_M (0xf<<0) #define MC13892_SWITCHERS4_SW2MODE 10 #define MC13892_SWITCHERS4_SW2MODE_AUTO (8<<10) #define MC13892_SWITCHERS4_SW2MODE_M (0xf<<10) #define MC13892_SWITCHERS5 29 #define MC13892_SWITCHERS5_SW3MODE 0 #define MC13892_SWITCHERS5_SW3MODE_AUTO (8<<0) #define MC13892_SWITCHERS5_SW3MODE_M (0xf<<0) #define MC13892_SWITCHERS5_SW4MODE 8 #define MC13892_SWITCHERS5_SW4MODE_AUTO (8<<8) #define MC13892_SWITCHERS5_SW4MODE_M (0xf<<8) #define MC13892_SWITCHERS5_SWBSTEN (1<<20) #define MC13892_REGULATORSETTING0 30 #define MC13892_REGULATORSETTING0_VGEN1VSEL 0 #define MC13892_REGULATORSETTING0_VDIGVSEL 4 #define MC13892_REGULATORSETTING0_VGEN2VSEL 6 #define MC13892_REGULATORSETTING0_VPLLVSEL 9 #define MC13892_REGULATORSETTING0_VUSB2VSEL 11 #define MC13892_REGULATORSETTING0_VGEN3VSEL 14 #define MC13892_REGULATORSETTING0_VCAMVSEL 16 #define MC13892_REGULATORSETTING0_VGEN1VSEL_M (3<<0) #define MC13892_REGULATORSETTING0_VDIGVSEL_M (3<<4) #define MC13892_REGULATORSETTING0_VGEN2VSEL_M (7<<6) #define MC13892_REGULATORSETTING0_VPLLVSEL_M (3<<9) #define MC13892_REGULATORSETTING0_VUSB2VSEL_M (3<<11) #define MC13892_REGULATORSETTING0_VGEN3VSEL_M (1<<14) #define MC13892_REGULATORSETTING0_VCAMVSEL_M (3<<16) #define MC13892_REGULATORSETTING1 31 #define MC13892_REGULATORSETTING1_VVIDEOVSEL 2 #define MC13892_REGULATORSETTING1_VAUDIOVSEL 4 #define MC13892_REGULATORSETTING1_VSDVSEL 6 #define MC13892_REGULATORSETTING1_VVIDEOVSEL_M (3<<2) #define MC13892_REGULATORSETTING1_VAUDIOVSEL_M (3<<4) #define MC13892_REGULATORSETTING1_VSDVSEL_M (7<<6) #define MC13892_REGULATORMODE0 32 #define MC13892_REGULATORMODE0_VGEN1EN (1<<0) #define MC13892_REGULATORMODE0_VGEN1STDBY (1<<1) #define MC13892_REGULATORMODE0_VGEN1MODE (1<<2) #define MC13892_REGULATORMODE0_VIOHIEN (1<<3) #define MC13892_REGULATORMODE0_VIOHISTDBY (1<<4) #define MC13892_REGULATORMODE0_VIOHIMODE (1<<5) #define MC13892_REGULATORMODE0_VDIGEN (1<<9) #define MC13892_REGULATORMODE0_VDIGSTDBY (1<<10) #define MC13892_REGULATORMODE0_VDIGMODE (1<<11) #define MC13892_REGULATORMODE0_VGEN2EN (1<<12) #define MC13892_REGULATORMODE0_VGEN2STDBY (1<<13) #define MC13892_REGULATORMODE0_VGEN2MODE (1<<14) #define MC13892_REGULATORMODE0_VPLLEN (1<<15) #define MC13892_REGULATORMODE0_VPLLSTDBY (1<<16) #define MC13892_REGULATORMODE0_VPLLMODE (1<<17) #define MC13892_REGULATORMODE0_VUSB2EN (1<<18) #define MC13892_REGULATORMODE0_VUSB2STDBY (1<<19) #define MC13892_REGULATORMODE0_VUSB2MODE (1<<20) #define MC13892_REGULATORMODE1 33 #define MC13892_REGULATORMODE1_VGEN3EN (1<<0) #define MC13892_REGULATORMODE1_VGEN3STDBY (1<<1) #define MC13892_REGULATORMODE1_VGEN3MODE (1<<2) #define MC13892_REGULATORMODE1_VCAMEN (1<<6) #define MC13892_REGULATORMODE1_VCAMSTDBY (1<<7) #define MC13892_REGULATORMODE1_VCAMMODE (1<<8) #define MC13892_REGULATORMODE1_VCAMCONFIGEN (1<<9) #define MC13892_REGULATORMODE1_VVIDEOEN (1<<12) #define MC13892_REGULATORMODE1_VVIDEOSTDBY (1<<13) #define MC13892_REGULATORMODE1_VVIDEOMODE (1<<14) #define MC13892_REGULATORMODE1_VAUDIOEN (1<<15) #define MC13892_REGULATORMODE1_VAUDIOSTDBY (1<<16) #define MC13892_REGULATORMODE1_VAUDIOMODE (1<<17) #define MC13892_REGULATORMODE1_VSDEN (1<<18) #define MC13892_REGULATORMODE1_VSDSTDBY (1<<19) #define MC13892_REGULATORMODE1_VSDMODE (1<<20) #define MC13892_POWERMISC 34 #define MC13892_POWERMISC_GPO1EN (1<<6) #define MC13892_POWERMISC_GPO2EN (1<<8) #define MC13892_POWERMISC_GPO3EN (1<<10) #define MC13892_POWERMISC_GPO4EN (1<<12) #define MC13892_POWERMISC_PWGT1SPIEN (1<<15) #define MC13892_POWERMISC_PWGT2SPIEN (1<<16) #define MC13892_POWERMISC_GPO4ADINEN (1<<21) #define MC13892_POWERMISC_PWGTSPI_M (3 << 15) #define MC13892_USB1 50 #define MC13892_USB1_VUSBEN (1<<3) |
34e74f39f regulator: mc13xx... |
152 |
static const unsigned int mc13892_vcoincell[] = { |
5e428d5ce regulator: suppor... |
153 154 155 |
2500000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, }; |
34e74f39f regulator: mc13xx... |
156 |
static const unsigned int mc13892_sw1[] = { |
5e428d5ce regulator: suppor... |
157 158 159 160 161 162 163 |
600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000 }; |
ccf3ed782 regulator: mc1389... |
164 165 166 167 168 169 170 |
/* * Note: this table is used to derive SWxVSEL by index into * the array. Offset the values by the index of 1100000uV * to get the actual register value for that voltage selector * if the HI bit is to be set as well. */ #define MC13892_SWxHI_SEL_OFFSET 20 |
34e74f39f regulator: mc13xx... |
171 |
static const unsigned int mc13892_sw[] = { |
5e428d5ce regulator: suppor... |
172 173 174 175 176 177 178 179 180 181 |
600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000, 1600000, 1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000 }; |
34e74f39f regulator: mc13xx... |
182 |
static const unsigned int mc13892_swbst[] = { |
5e428d5ce regulator: suppor... |
183 184 |
5000000, }; |
34e74f39f regulator: mc13xx... |
185 |
static const unsigned int mc13892_viohi[] = { |
5e428d5ce regulator: suppor... |
186 187 |
2775000, }; |
34e74f39f regulator: mc13xx... |
188 |
static const unsigned int mc13892_vpll[] = { |
5e428d5ce regulator: suppor... |
189 190 |
1050000, 1250000, 1650000, 1800000, }; |
34e74f39f regulator: mc13xx... |
191 |
static const unsigned int mc13892_vdig[] = { |
5e428d5ce regulator: suppor... |
192 193 |
1050000, 1250000, 1650000, 1800000, }; |
34e74f39f regulator: mc13xx... |
194 |
static const unsigned int mc13892_vsd[] = { |
5e428d5ce regulator: suppor... |
195 196 197 |
1800000, 2000000, 2600000, 2700000, 2800000, 2900000, 3000000, 3150000, }; |
34e74f39f regulator: mc13xx... |
198 |
static const unsigned int mc13892_vusb2[] = { |
5e428d5ce regulator: suppor... |
199 200 |
2400000, 2600000, 2700000, 2775000, }; |
34e74f39f regulator: mc13xx... |
201 |
static const unsigned int mc13892_vvideo[] = { |
5e428d5ce regulator: suppor... |
202 203 |
2700000, 2775000, 2500000, 2600000, }; |
34e74f39f regulator: mc13xx... |
204 |
static const unsigned int mc13892_vaudio[] = { |
5e428d5ce regulator: suppor... |
205 206 |
2300000, 2500000, 2775000, 3000000, }; |
34e74f39f regulator: mc13xx... |
207 |
static const unsigned int mc13892_vcam[] = { |
5e428d5ce regulator: suppor... |
208 209 |
2500000, 2600000, 2750000, 3000000, }; |
34e74f39f regulator: mc13xx... |
210 |
static const unsigned int mc13892_vgen1[] = { |
5e428d5ce regulator: suppor... |
211 212 |
1200000, 1500000, 2775000, 3150000, }; |
34e74f39f regulator: mc13xx... |
213 |
static const unsigned int mc13892_vgen2[] = { |
5e428d5ce regulator: suppor... |
214 215 216 |
1200000, 1500000, 1600000, 1800000, 2700000, 2800000, 3000000, 3150000, }; |
34e74f39f regulator: mc13xx... |
217 |
static const unsigned int mc13892_vgen3[] = { |
5e428d5ce regulator: suppor... |
218 219 |
1800000, 2900000, }; |
34e74f39f regulator: mc13xx... |
220 |
static const unsigned int mc13892_vusb[] = { |
5e428d5ce regulator: suppor... |
221 222 |
3300000, }; |
34e74f39f regulator: mc13xx... |
223 |
static const unsigned int mc13892_gpo[] = { |
5e428d5ce regulator: suppor... |
224 225 |
2750000, }; |
34e74f39f regulator: mc13xx... |
226 |
static const unsigned int mc13892_pwgtdrv[] = { |
5e428d5ce regulator: suppor... |
227 228 229 230 |
5000000, }; static struct regulator_ops mc13892_gpo_regulator_ops; |
5e428d5ce regulator: suppor... |
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
static struct regulator_ops mc13892_sw_regulator_ops; #define MC13892_FIXED_DEFINE(name, reg, voltages) \ MC13xxx_FIXED_DEFINE(MC13892_, name, reg, voltages, \ mc13xxx_fixed_regulator_ops) #define MC13892_GPO_DEFINE(name, reg, voltages) \ MC13xxx_GPO_DEFINE(MC13892_, name, reg, voltages, \ mc13892_gpo_regulator_ops) #define MC13892_SW_DEFINE(name, reg, vsel_reg, voltages) \ MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \ mc13892_sw_regulator_ops) #define MC13892_DEFINE_REGU(name, reg, vsel_reg, voltages) \ MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \ mc13xxx_regulator_ops) static struct mc13xxx_regulator mc13892_regulators[] = { |
327e15af1 Revert "regulator... |
251 |
MC13892_DEFINE_REGU(VCOINCELL, POWERCTL0, POWERCTL0, mc13892_vcoincell), |
5e428d5ce regulator: suppor... |
252 253 254 255 256 257 |
MC13892_SW_DEFINE(SW1, SWITCHERS0, SWITCHERS0, mc13892_sw1), MC13892_SW_DEFINE(SW2, SWITCHERS1, SWITCHERS1, mc13892_sw), MC13892_SW_DEFINE(SW3, SWITCHERS2, SWITCHERS2, mc13892_sw), MC13892_SW_DEFINE(SW4, SWITCHERS3, SWITCHERS3, mc13892_sw), MC13892_FIXED_DEFINE(SWBST, SWITCHERS5, mc13892_swbst), MC13892_FIXED_DEFINE(VIOHI, REGULATORMODE0, mc13892_viohi), |
c6a21f246 regulator: mc1389... |
258 |
MC13892_DEFINE_REGU(VPLL, REGULATORMODE0, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
259 |
mc13892_vpll), |
c6a21f246 regulator: mc1389... |
260 |
MC13892_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
261 |
mc13892_vdig), |
c6a21f246 regulator: mc1389... |
262 |
MC13892_DEFINE_REGU(VSD, REGULATORMODE1, REGULATORSETTING1, |
5e428d5ce regulator: suppor... |
263 |
mc13892_vsd), |
c6a21f246 regulator: mc1389... |
264 |
MC13892_DEFINE_REGU(VUSB2, REGULATORMODE0, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
265 |
mc13892_vusb2), |
c6a21f246 regulator: mc1389... |
266 |
MC13892_DEFINE_REGU(VVIDEO, REGULATORMODE1, REGULATORSETTING1, |
5e428d5ce regulator: suppor... |
267 |
mc13892_vvideo), |
c6a21f246 regulator: mc1389... |
268 |
MC13892_DEFINE_REGU(VAUDIO, REGULATORMODE1, REGULATORSETTING1, |
5e428d5ce regulator: suppor... |
269 |
mc13892_vaudio), |
c6a21f246 regulator: mc1389... |
270 |
MC13892_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
271 |
mc13892_vcam), |
c6a21f246 regulator: mc1389... |
272 |
MC13892_DEFINE_REGU(VGEN1, REGULATORMODE0, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
273 |
mc13892_vgen1), |
c6a21f246 regulator: mc1389... |
274 |
MC13892_DEFINE_REGU(VGEN2, REGULATORMODE0, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
275 |
mc13892_vgen2), |
c6a21f246 regulator: mc1389... |
276 |
MC13892_DEFINE_REGU(VGEN3, REGULATORMODE1, REGULATORSETTING0, |
5e428d5ce regulator: suppor... |
277 278 279 280 281 282 283 284 285 |
mc13892_vgen3), MC13892_FIXED_DEFINE(VUSB, USB1, mc13892_vusb), MC13892_GPO_DEFINE(GPO1, POWERMISC, mc13892_gpo), MC13892_GPO_DEFINE(GPO2, POWERMISC, mc13892_gpo), MC13892_GPO_DEFINE(GPO3, POWERMISC, mc13892_gpo), MC13892_GPO_DEFINE(GPO4, POWERMISC, mc13892_gpo), MC13892_GPO_DEFINE(PWGT1SPI, POWERMISC, mc13892_pwgtdrv), MC13892_GPO_DEFINE(PWGT2SPI, POWERMISC, mc13892_pwgtdrv), }; |
27315cf61 regulator: Static... |
286 287 |
static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, u32 val) |
5e428d5ce regulator: suppor... |
288 289 290 291 292 293 |
{ struct mc13xxx *mc13892 = priv->mc13xxx; int ret; u32 valread; BUG_ON(val & ~mask); |
825d10591 regulator: mc1389... |
294 |
mc13xxx_lock(priv->mc13xxx); |
5e428d5ce regulator: suppor... |
295 296 |
ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread); if (ret) |
825d10591 regulator: mc1389... |
297 |
goto out; |
5e428d5ce regulator: suppor... |
298 299 300 301 302 303 304 305 306 307 308 |
/* Update the stored state for Power Gates. */ priv->powermisc_pwgt_state = (priv->powermisc_pwgt_state & ~mask) | val; priv->powermisc_pwgt_state &= MC13892_POWERMISC_PWGTSPI_M; /* Construct the new register value */ valread = (valread & ~mask) | val; /* Overwrite the PWGTxEN with the stored version */ valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) | priv->powermisc_pwgt_state; |
825d10591 regulator: mc1389... |
309 310 311 312 |
ret = mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread); out: mc13xxx_unlock(priv->mc13xxx); return ret; |
5e428d5ce regulator: suppor... |
313 314 315 316 317 318 |
} static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); |
5e428d5ce regulator: suppor... |
319 320 321 322 323 324 325 326 327 328 329 330 |
u32 en_val = mc13892_regulators[id].enable_bit; u32 mask = mc13892_regulators[id].enable_bit; dev_dbg(rdev_get_dev(rdev), "%s id: %d ", __func__, id); /* Power Gate enable value is 0 */ if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI) en_val = 0; if (id == MC13892_GPO4) mask |= MC13892_POWERMISC_GPO4ADINEN; |
825d10591 regulator: mc1389... |
331 |
return mc13892_powermisc_rmw(priv, mask, en_val); |
5e428d5ce regulator: suppor... |
332 333 334 335 336 337 |
} static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); |
5e428d5ce regulator: suppor... |
338 339 340 341 342 343 344 345 |
u32 dis_val = 0; dev_dbg(rdev_get_dev(rdev), "%s id: %d ", __func__, id); /* Power Gate disable value is 1 */ if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI) dis_val = mc13892_regulators[id].enable_bit; |
825d10591 regulator: mc1389... |
346 |
return mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit, |
5e428d5ce regulator: suppor... |
347 |
dis_val); |
5e428d5ce regulator: suppor... |
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
} static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; /* Power Gates state is stored in powermisc_pwgt_state * where the meaning of bits is negated */ val = (val & ~MC13892_POWERMISC_PWGTSPI_M) | (priv->powermisc_pwgt_state ^ MC13892_POWERMISC_PWGTSPI_M); return (val & mc13892_regulators[id].enable_bit) != 0; } static struct regulator_ops mc13892_gpo_regulator_ops = { .enable = mc13892_gpo_regulator_enable, .disable = mc13892_gpo_regulator_disable, .is_enabled = mc13892_gpo_regulator_is_enabled, |
34e74f39f regulator: mc13xx... |
376 |
.list_voltage = regulator_list_voltage_table, |
5e428d5ce regulator: suppor... |
377 |
.set_voltage = mc13xxx_fixed_regulator_set_voltage, |
5e428d5ce regulator: suppor... |
378 |
}; |
f1dcf9e4e regulator: mc1389... |
379 |
static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev) |
5e428d5ce regulator: suppor... |
380 381 382 |
{ struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); |
ccf3ed782 regulator: mc1389... |
383 |
unsigned int val, selector; |
5e428d5ce regulator: suppor... |
384 385 386 387 388 389 390 391 392 393 |
dev_dbg(rdev_get_dev(rdev), "%s id: %d ", __func__, id); mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].vsel_reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; |
ccf3ed782 regulator: mc1389... |
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
/* * Figure out if the HI bit is set inside the switcher mode register * since this means the selector value we return is at a different * offset into the selector table. * * According to the MC13892 documentation note 59 (Table 47) the SW1 * buck switcher does not support output range programming therefore * the HI bit must always remain 0. So do not do anything strange if * our register is MC13892_SWITCHERS0. */ selector = val & mc13892_regulators[id].vsel_mask; if ((mc13892_regulators[id].vsel_reg != MC13892_SWITCHERS0) && (val & MC13892_SWITCHERS0_SWxHI)) { selector += MC13892_SWxHI_SEL_OFFSET; } |
5e428d5ce regulator: suppor... |
411 |
|
ccf3ed782 regulator: mc1389... |
412 413 414 |
dev_dbg(rdev_get_dev(rdev), "%s id: %d val: 0x%08x selector: %d ", __func__, id, val, selector); |
5e428d5ce regulator: suppor... |
415 |
|
ccf3ed782 regulator: mc1389... |
416 |
return selector; |
5e428d5ce regulator: suppor... |
417 |
} |
939b62d89 regulator: Conver... |
418 419 |
static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) |
5e428d5ce regulator: suppor... |
420 421 |
{ struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
8db98440f regulator: mc1389... |
422 423 |
int volt, mask, id = rdev_get_id(rdev); u32 reg_value; |
5e428d5ce regulator: suppor... |
424 |
int ret; |
8db98440f regulator: mc1389... |
425 426 |
volt = rdev->desc->volt_table[selector]; mask = mc13892_regulators[id].vsel_mask; |
ccf3ed782 regulator: mc1389... |
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
reg_value = selector; /* * Don't mess with the HI bit or support HI voltage offsets for SW1. * * Since the get_voltage_sel callback has given a fudged value for * the selector offset, we need to back out that offset if HI is * to be set so we write the correct value to the register. * * The HI bit addition and selector offset handling COULD be more * complicated by shifting and masking off the voltage selector part * of the register then logical OR it back in, but since the selector * is at bits 4:0 there is very little point. This makes the whole * thing more readable and we do far less work. */ if (mc13892_regulators[id].vsel_reg != MC13892_SWITCHERS0) { |
78040b630 regulator: mc1389... |
444 |
mask |= MC13892_SWITCHERS0_SWxHI; |
ccf3ed782 regulator: mc1389... |
445 446 447 |
if (volt > 1375000) { reg_value -= MC13892_SWxHI_SEL_OFFSET; reg_value |= MC13892_SWITCHERS0_SWxHI; |
78040b630 regulator: mc1389... |
448 |
} else { |
ccf3ed782 regulator: mc1389... |
449 |
reg_value &= ~MC13892_SWITCHERS0_SWxHI; |
ccf3ed782 regulator: mc1389... |
450 |
} |
8db98440f regulator: mc1389... |
451 |
} |
5e428d5ce regulator: suppor... |
452 |
|
8db98440f regulator: mc1389... |
453 |
mc13xxx_lock(priv->mc13xxx); |
c6a21f246 regulator: mc1389... |
454 455 |
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg, mask, reg_value); |
5e428d5ce regulator: suppor... |
456 457 458 459 460 461 |
mc13xxx_unlock(priv->mc13xxx); return ret; } static struct regulator_ops mc13892_sw_regulator_ops = { |
34e74f39f regulator: mc13xx... |
462 |
.list_voltage = regulator_list_voltage_table, |
3bdf59928 regulator: mc1389... |
463 |
.map_voltage = regulator_map_voltage_ascend, |
939b62d89 regulator: Conver... |
464 |
.set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, |
f1dcf9e4e regulator: mc1389... |
465 |
.get_voltage_sel = mc13892_sw_regulator_get_voltage_sel, |
5e428d5ce regulator: suppor... |
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
}; static int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode) { unsigned int en_val = 0; struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); if (mode == REGULATOR_MODE_FAST) en_val = MC13892_REGULATORMODE1_VCAMCONFIGEN; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].reg, MC13892_REGULATORMODE1_VCAMCONFIGEN, en_val); mc13xxx_unlock(priv->mc13xxx); return ret; } |
27315cf61 regulator: Static... |
484 |
static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev) |
5e428d5ce regulator: suppor... |
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
{ struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; if (val & MC13892_REGULATORMODE1_VCAMCONFIGEN) return REGULATOR_MODE_FAST; return REGULATOR_MODE_NORMAL; } |
39f5460d7 regulator: core: ... |
502 |
static struct regulator_ops mc13892_vcam_ops; |
5e428d5ce regulator: suppor... |
503 |
|
a5023574d regulator: remove... |
504 |
static int mc13892_regulator_probe(struct platform_device *pdev) |
5e428d5ce regulator: suppor... |
505 506 507 |
{ struct mc13xxx_regulator_priv *priv; struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); |
c8a03c96b mfd: Use mfd cell... |
508 509 |
struct mc13xxx_regulator_platform_data *pdata = dev_get_platdata(&pdev->dev); |
93bcb23b3 regulator: mc1389... |
510 |
struct mc13xxx_regulator_init_data *mc13xxx_data; |
a9d580104 regulator: Fix bu... |
511 |
struct regulator_config config = { }; |
5e428d5ce regulator: suppor... |
512 |
int i, ret; |
eb0d8e7a1 regulator: mc13xx... |
513 |
int num_regulators = 0; |
5e428d5ce regulator: suppor... |
514 |
u32 val; |
93bcb23b3 regulator: mc1389... |
515 |
num_regulators = mc13xxx_get_num_regulators_dt(pdev); |
2c8a5dcaa regulator: mc1389... |
516 |
|
93bcb23b3 regulator: mc1389... |
517 518 519 520 |
if (num_regulators <= 0 && pdata) num_regulators = pdata->num_regulators; if (num_regulators <= 0) return -EINVAL; |
4fef21eaa regulator: mc1389... |
521 |
priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + |
93bcb23b3 regulator: mc1389... |
522 |
num_regulators * sizeof(priv->regulators[0]), |
5e428d5ce regulator: suppor... |
523 524 525 |
GFP_KERNEL); if (!priv) return -ENOMEM; |
93bcb23b3 regulator: mc1389... |
526 |
priv->num_regulators = num_regulators; |
5e428d5ce regulator: suppor... |
527 528 |
priv->mc13xxx_regulators = mc13892_regulators; priv->mc13xxx = mc13892; |
93bcb23b3 regulator: mc1389... |
529 |
platform_set_drvdata(pdev, priv); |
5e428d5ce regulator: suppor... |
530 531 532 533 |
mc13xxx_lock(mc13892); ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); if (ret) |
5777d9b34 regulator: Fix un... |
534 |
goto err_unlock; |
5e428d5ce regulator: suppor... |
535 |
|
ccf3ed782 regulator: mc1389... |
536 |
/* enable switch auto mode (on 2.0A silicon only) */ |
5e428d5ce regulator: suppor... |
537 538 539 540 541 542 543 |
if ((val & 0x0000FFFF) == 0x45d0) { ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS4, MC13892_SWITCHERS4_SW1MODE_M | MC13892_SWITCHERS4_SW2MODE_M, MC13892_SWITCHERS4_SW1MODE_AUTO | MC13892_SWITCHERS4_SW2MODE_AUTO); if (ret) |
5777d9b34 regulator: Fix un... |
544 |
goto err_unlock; |
5e428d5ce regulator: suppor... |
545 |
|
923430cfe regulator: Assign... |
546 |
ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5, |
5e428d5ce regulator: suppor... |
547 548 549 550 551 |
MC13892_SWITCHERS5_SW3MODE_M | MC13892_SWITCHERS5_SW4MODE_M, MC13892_SWITCHERS5_SW3MODE_AUTO | MC13892_SWITCHERS5_SW4MODE_AUTO); if (ret) |
5777d9b34 regulator: Fix un... |
552 |
goto err_unlock; |
5e428d5ce regulator: suppor... |
553 554 |
} mc13xxx_unlock(mc13892); |
39f5460d7 regulator: core: ... |
555 556 557 558 559 560 |
/* update mc13892_vcam ops */ memcpy(&mc13892_vcam_ops, mc13892_regulators[MC13892_VCAM].desc.ops, sizeof(struct regulator_ops)); mc13892_vcam_ops.set_mode = mc13892_vcam_set_mode, mc13892_vcam_ops.get_mode = mc13892_vcam_get_mode, mc13892_regulators[MC13892_VCAM].desc.ops = &mc13892_vcam_ops; |
93bcb23b3 regulator: mc1389... |
561 562 |
mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, |
eb0d8e7a1 regulator: mc13xx... |
563 |
ARRAY_SIZE(mc13892_regulators)); |
2c8a5dcaa regulator: mc1389... |
564 |
|
eb0d8e7a1 regulator: mc13xx... |
565 |
for (i = 0; i < priv->num_regulators; i++) { |
93bcb23b3 regulator: mc1389... |
566 567 568 569 570 571 572 573 574 575 576 577 578 579 |
struct regulator_init_data *init_data; struct regulator_desc *desc; struct device_node *node = NULL; int id; if (mc13xxx_data) { id = mc13xxx_data[i].id; init_data = mc13xxx_data[i].init_data; node = mc13xxx_data[i].node; } else { id = pdata->regulators[i].id; init_data = pdata->regulators[i].init_data; } desc = &mc13892_regulators[id].desc; |
a9d580104 regulator: Fix bu... |
580 581 582 583 |
config.dev = &pdev->dev; config.init_data = init_data; config.driver_data = priv; config.of_node = node; |
5e428d5ce regulator: suppor... |
584 |
|
8c0b4ab50 regulator: mc1389... |
585 586 |
priv->regulators[i] = devm_regulator_register(&pdev->dev, desc, &config); |
5e428d5ce regulator: suppor... |
587 588 589 590 |
if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s ", mc13892_regulators[i].desc.name); |
8c0b4ab50 regulator: mc1389... |
591 |
return PTR_ERR(priv->regulators[i]); |
5e428d5ce regulator: suppor... |
592 593 |
} } |
5e428d5ce regulator: suppor... |
594 |
return 0; |
5e428d5ce regulator: suppor... |
595 |
|
5777d9b34 regulator: Fix un... |
596 |
err_unlock: |
5e428d5ce regulator: suppor... |
597 |
mc13xxx_unlock(mc13892); |
5e428d5ce regulator: suppor... |
598 599 |
return ret; } |
5e428d5ce regulator: suppor... |
600 601 602 |
static struct platform_driver mc13892_regulator_driver = { .driver = { .name = "mc13892-regulator", |
5e428d5ce regulator: suppor... |
603 |
}, |
5e428d5ce regulator: suppor... |
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 |
.probe = mc13892_regulator_probe, }; static int __init mc13892_regulator_init(void) { return platform_driver_register(&mc13892_regulator_driver); } subsys_initcall(mc13892_regulator_init); static void __exit mc13892_regulator_exit(void) { platform_driver_unregister(&mc13892_regulator_driver); } module_exit(mc13892_regulator_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>"); MODULE_DESCRIPTION("Regulator Driver for Freescale MC13892 PMIC"); MODULE_ALIAS("platform:mc13892-regulator"); |