diff options
author | Alberto Panizzo <maramaopercheseimorto@gmail.com> | 2010-01-19 06:48:54 -0500 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2010-03-03 09:49:23 -0500 |
commit | f4b97b36b7c6b2d4455f27d6371869f915cbe8fd (patch) | |
tree | 460b29d5ed24c2f3d499099d35df2ee7ae01bba4 /drivers/regulator | |
parent | eda79a3041a2cada0d4ee9491c99c3874b322356 (diff) |
regulator: mc13783: consider Power Gates as digital regulators.
GPO regulators are digital outputs that can be enabled or disabled by a
dedicated bit in mc13783 POWERMISC register.
In this family can be count in also Power Gates (PWGT1 and 2): enabled by
a dedicated pin a Power Gate is an hardware driven supply where the output
(PWGTnDRV) follow this law:
Bit PWGTxSPIEN | Pin PWGTxEN | PWGTxDRV | Read Back
0 = default | | | PWGTxSPIEN
---------------+-------------+----------+------------
1 | x | Low | 0
0 | 0 | High | 1
0 | 1 | Low | 0
As read back value of control bit reflects the PWGTxDRV state (not the
control value previously written) and mc13783 POWERMISC register contain
only regulator related bits, a dedicated function to manage these bits is
created here with the aim of tracing the real value of PWGTxSPIEN bits
and reproduce it on next writes.
All POWERMISC users _must_ use the new function to not accidentally
disable Power Gates supplies.
v2 changes:
-Better utilization of abstraction layers.
-Voltage query support. GPO's and PWGTxDRV are fixed voltage regulator
with voltage value of 3.1V and 5.5V respectively.
Signed-off-by: Alberto Panizzo <maramaopercheseimorto@gmail.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/mc13783-regulator.c | 132 |
1 files changed, 126 insertions, 6 deletions
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index a40e35ab8555..f7b81845a196 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -82,6 +82,11 @@ | |||
82 | #define MC13783_REG_POWERMISC_GPO2EN (1 << 8) | 82 | #define MC13783_REG_POWERMISC_GPO2EN (1 << 8) |
83 | #define MC13783_REG_POWERMISC_GPO3EN (1 << 10) | 83 | #define MC13783_REG_POWERMISC_GPO3EN (1 << 10) |
84 | #define MC13783_REG_POWERMISC_GPO4EN (1 << 12) | 84 | #define MC13783_REG_POWERMISC_GPO4EN (1 << 12) |
85 | #define MC13783_REG_POWERMISC_PWGT1SPIEN (1 << 15) | ||
86 | #define MC13783_REG_POWERMISC_PWGT2SPIEN (1 << 16) | ||
87 | |||
88 | #define MC13783_REG_POWERMISC_PWGTSPI_M (3 << 15) | ||
89 | |||
85 | 90 | ||
86 | struct mc13783_regulator { | 91 | struct mc13783_regulator { |
87 | struct regulator_desc desc; | 92 | struct regulator_desc desc; |
@@ -161,8 +166,17 @@ static const int const mc13783_vrf_val[] = { | |||
161 | 1500000, 1875000, 2700000, 2775000, | 166 | 1500000, 1875000, 2700000, 2775000, |
162 | }; | 167 | }; |
163 | 168 | ||
169 | static const int const mc13783_gpo_val[] = { | ||
170 | 3100000, | ||
171 | }; | ||
172 | |||
173 | static const int const mc13783_pwgtdrv_val[] = { | ||
174 | 5500000, | ||
175 | }; | ||
176 | |||
164 | static struct regulator_ops mc13783_regulator_ops; | 177 | static struct regulator_ops mc13783_regulator_ops; |
165 | static struct regulator_ops mc13783_fixed_regulator_ops; | 178 | static struct regulator_ops mc13783_fixed_regulator_ops; |
179 | static struct regulator_ops mc13783_gpo_regulator_ops; | ||
166 | 180 | ||
167 | #define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages) \ | 181 | #define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages) \ |
168 | [MC13783_ ## prefix ## _ ## _name] = { \ | 182 | [MC13783_ ## prefix ## _ ## _name] = { \ |
@@ -197,17 +211,19 @@ static struct regulator_ops mc13783_fixed_regulator_ops; | |||
197 | .voltages = _voltages, \ | 211 | .voltages = _voltages, \ |
198 | } | 212 | } |
199 | 213 | ||
200 | #define MC13783_GPO_DEFINE(prefix, _name, _reg) \ | 214 | #define MC13783_GPO_DEFINE(prefix, _name, _reg, _voltages) \ |
201 | [MC13783_ ## prefix ## _ ## _name] = { \ | 215 | [MC13783_ ## prefix ## _ ## _name] = { \ |
202 | .desc = { \ | 216 | .desc = { \ |
203 | .name = #prefix "_" #_name, \ | 217 | .name = #prefix "_" #_name, \ |
204 | .ops = &mc13783_regulator_ops, \ | 218 | .n_voltages = ARRAY_SIZE(_voltages), \ |
219 | .ops = &mc13783_gpo_regulator_ops, \ | ||
205 | .type = REGULATOR_VOLTAGE, \ | 220 | .type = REGULATOR_VOLTAGE, \ |
206 | .id = MC13783_ ## prefix ## _ ## _name, \ | 221 | .id = MC13783_ ## prefix ## _ ## _name, \ |
207 | .owner = THIS_MODULE, \ | 222 | .owner = THIS_MODULE, \ |
208 | }, \ | 223 | }, \ |
209 | .reg = MC13783_REG_ ## _reg, \ | 224 | .reg = MC13783_REG_ ## _reg, \ |
210 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | 225 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ |
226 | .voltages = _voltages, \ | ||
211 | } | 227 | } |
212 | 228 | ||
213 | #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages) \ | 229 | #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages) \ |
@@ -249,14 +265,17 @@ static struct mc13783_regulator mc13783_regulators[] = { | |||
249 | mc13783_vmmc_val), | 265 | mc13783_vmmc_val), |
250 | MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, \ | 266 | MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, \ |
251 | mc13783_vmmc_val), | 267 | mc13783_vmmc_val), |
252 | MC13783_GPO_DEFINE(REGU, GPO1, POWERMISC), | 268 | MC13783_GPO_DEFINE(REGU, GPO1, POWERMISC, mc13783_gpo_val), |
253 | MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC), | 269 | MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC, mc13783_gpo_val), |
254 | MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC), | 270 | MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC, mc13783_gpo_val), |
255 | MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC), | 271 | MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC, mc13783_gpo_val), |
272 | MC13783_GPO_DEFINE(REGU, PWGT1SPI, POWERMISC, mc13783_pwgtdrv_val), | ||
273 | MC13783_GPO_DEFINE(REGU, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val), | ||
256 | }; | 274 | }; |
257 | 275 | ||
258 | struct mc13783_regulator_priv { | 276 | struct mc13783_regulator_priv { |
259 | struct mc13783 *mc13783; | 277 | struct mc13783 *mc13783; |
278 | u32 powermisc_pwgt_state; | ||
260 | struct regulator_dev *regulators[]; | 279 | struct regulator_dev *regulators[]; |
261 | }; | 280 | }; |
262 | 281 | ||
@@ -445,6 +464,107 @@ static struct regulator_ops mc13783_fixed_regulator_ops = { | |||
445 | .get_voltage = mc13783_fixed_regulator_get_voltage, | 464 | .get_voltage = mc13783_fixed_regulator_get_voltage, |
446 | }; | 465 | }; |
447 | 466 | ||
467 | int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask, | ||
468 | u32 val) | ||
469 | { | ||
470 | struct mc13783 *mc13783 = priv->mc13783; | ||
471 | int ret; | ||
472 | u32 valread; | ||
473 | |||
474 | BUG_ON(val & ~mask); | ||
475 | |||
476 | ret = mc13783_reg_read(mc13783, MC13783_REG_POWERMISC, &valread); | ||
477 | if (ret) | ||
478 | return ret; | ||
479 | |||
480 | /* Update the stored state for Power Gates. */ | ||
481 | priv->powermisc_pwgt_state = | ||
482 | (priv->powermisc_pwgt_state & ~mask) | val; | ||
483 | priv->powermisc_pwgt_state &= MC13783_REG_POWERMISC_PWGTSPI_M; | ||
484 | |||
485 | /* Construct the new register value */ | ||
486 | valread = (valread & ~mask) | val; | ||
487 | /* Overwrite the PWGTxEN with the stored version */ | ||
488 | valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) | | ||
489 | priv->powermisc_pwgt_state; | ||
490 | |||
491 | return mc13783_reg_write(mc13783, MC13783_REG_POWERMISC, valread); | ||
492 | } | ||
493 | |||
494 | static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) | ||
495 | { | ||
496 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
497 | int id = rdev_get_id(rdev); | ||
498 | int ret; | ||
499 | u32 en_val = mc13783_regulators[id].enable_bit; | ||
500 | |||
501 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
502 | |||
503 | /* Power Gate enable value is 0 */ | ||
504 | if (id == MC13783_REGU_PWGT1SPI || | ||
505 | id == MC13783_REGU_PWGT2SPI) | ||
506 | en_val = 0; | ||
507 | |||
508 | mc13783_lock(priv->mc13783); | ||
509 | ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit, | ||
510 | en_val); | ||
511 | mc13783_unlock(priv->mc13783); | ||
512 | |||
513 | return ret; | ||
514 | } | ||
515 | |||
516 | static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) | ||
517 | { | ||
518 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
519 | int id = rdev_get_id(rdev); | ||
520 | int ret; | ||
521 | u32 dis_val = 0; | ||
522 | |||
523 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
524 | |||
525 | /* Power Gate disable value is 1 */ | ||
526 | if (id == MC13783_REGU_PWGT1SPI || | ||
527 | id == MC13783_REGU_PWGT2SPI) | ||
528 | dis_val = mc13783_regulators[id].enable_bit; | ||
529 | |||
530 | mc13783_lock(priv->mc13783); | ||
531 | ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit, | ||
532 | dis_val); | ||
533 | mc13783_unlock(priv->mc13783); | ||
534 | |||
535 | return ret; | ||
536 | } | ||
537 | |||
538 | static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) | ||
539 | { | ||
540 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
541 | int ret, id = rdev_get_id(rdev); | ||
542 | unsigned int val; | ||
543 | |||
544 | mc13783_lock(priv->mc13783); | ||
545 | ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); | ||
546 | mc13783_unlock(priv->mc13783); | ||
547 | |||
548 | if (ret) | ||
549 | return ret; | ||
550 | |||
551 | /* Power Gates state is stored in powermisc_pwgt_state | ||
552 | * where the meaning of bits is negated */ | ||
553 | val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) | | ||
554 | (priv->powermisc_pwgt_state ^ MC13783_REG_POWERMISC_PWGTSPI_M); | ||
555 | |||
556 | return (val & mc13783_regulators[id].enable_bit) != 0; | ||
557 | } | ||
558 | |||
559 | static struct regulator_ops mc13783_gpo_regulator_ops = { | ||
560 | .enable = mc13783_gpo_regulator_enable, | ||
561 | .disable = mc13783_gpo_regulator_disable, | ||
562 | .is_enabled = mc13783_gpo_regulator_is_enabled, | ||
563 | .list_voltage = mc13783_regulator_list_voltage, | ||
564 | .set_voltage = mc13783_fixed_regulator_set_voltage, | ||
565 | .get_voltage = mc13783_fixed_regulator_get_voltage, | ||
566 | }; | ||
567 | |||
448 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | 568 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) |
449 | { | 569 | { |
450 | struct mc13783_regulator_priv *priv; | 570 | struct mc13783_regulator_priv *priv; |