diff options
-rw-r--r-- | drivers/regulator/tps65023-regulator.c | 96 |
1 files changed, 75 insertions, 21 deletions
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 11c9e1f14079..42740ffc0be8 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -99,7 +99,7 @@ | |||
99 | #define TPS65023_MAX_REG_ID TPS65023_LDO_2 | 99 | #define TPS65023_MAX_REG_ID TPS65023_LDO_2 |
100 | 100 | ||
101 | /* Supported voltage values for regulators */ | 101 | /* Supported voltage values for regulators */ |
102 | static const u16 VDCDC1_VSEL_table[] = { | 102 | static const u16 VCORE_VSEL_table[] = { |
103 | 800, 825, 850, 875, | 103 | 800, 825, 850, 875, |
104 | 900, 925, 950, 975, | 104 | 900, 925, 950, 975, |
105 | 1000, 1025, 1050, 1075, | 105 | 1000, 1025, 1050, 1075, |
@@ -110,20 +110,20 @@ static const u16 VDCDC1_VSEL_table[] = { | |||
110 | 1500, 1525, 1550, 1600, | 110 | 1500, 1525, 1550, 1600, |
111 | }; | 111 | }; |
112 | 112 | ||
113 | static const u16 LDO1_VSEL_table[] = { | 113 | |
114 | |||
115 | /* Supported voltage values for LDO regulators | ||
116 | * for tps65021 and tps65023 */ | ||
117 | static const u16 TPS65023_LDO1_VSEL_table[] = { | ||
114 | 1000, 1100, 1300, 1800, | 118 | 1000, 1100, 1300, 1800, |
115 | 2200, 2600, 2800, 3150, | 119 | 2200, 2600, 2800, 3150, |
116 | }; | 120 | }; |
117 | 121 | ||
118 | static const u16 LDO2_VSEL_table[] = { | 122 | static const u16 TPS65023_LDO2_VSEL_table[] = { |
119 | 1050, 1200, 1300, 1800, | 123 | 1050, 1200, 1300, 1800, |
120 | 2500, 2800, 3000, 3300, | 124 | 2500, 2800, 3000, 3300, |
121 | }; | 125 | }; |
122 | 126 | ||
123 | static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDC1_VSEL_table), | ||
124 | 0, 0, ARRAY_SIZE(LDO1_VSEL_table), | ||
125 | ARRAY_SIZE(LDO2_VSEL_table)}; | ||
126 | |||
127 | /* Regulator specific details */ | 127 | /* Regulator specific details */ |
128 | struct tps_info { | 128 | struct tps_info { |
129 | const char *name; | 129 | const char *name; |
@@ -141,6 +141,13 @@ struct tps_pmic { | |||
141 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; | 141 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; |
142 | const struct tps_info *info[TPS65023_NUM_REGULATOR]; | 142 | const struct tps_info *info[TPS65023_NUM_REGULATOR]; |
143 | struct regmap *regmap; | 143 | struct regmap *regmap; |
144 | u8 core_regulator; | ||
145 | }; | ||
146 | |||
147 | /* Struct passed as driver data */ | ||
148 | struct tps_driver_data { | ||
149 | const struct tps_info *info; | ||
150 | u8 core_regulator; | ||
144 | }; | 151 | }; |
145 | 152 | ||
146 | static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) | 153 | static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) |
@@ -267,7 +274,7 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) | |||
267 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | 274 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) |
268 | return -EINVAL; | 275 | return -EINVAL; |
269 | 276 | ||
270 | if (dcdc == TPS65023_DCDC_1) { | 277 | if (dcdc == tps->core_regulator) { |
271 | data = tps_65023_reg_read(tps, TPS65023_REG_DEF_CORE); | 278 | data = tps_65023_reg_read(tps, TPS65023_REG_DEF_CORE); |
272 | if (data < 0) | 279 | if (data < 0) |
273 | return data; | 280 | return data; |
@@ -286,9 +293,8 @@ static int tps65023_dcdc_set_voltage(struct regulator_dev *dev, | |||
286 | int vsel; | 293 | int vsel; |
287 | int ret; | 294 | int ret; |
288 | 295 | ||
289 | if (dcdc != TPS65023_DCDC_1) | 296 | if (dcdc != tps->core_regulator) |
290 | return -EINVAL; | 297 | return -EINVAL; |
291 | |||
292 | if (min_uV < tps->info[dcdc]->min_uV | 298 | if (min_uV < tps->info[dcdc]->min_uV |
293 | || min_uV > tps->info[dcdc]->max_uV) | 299 | || min_uV > tps->info[dcdc]->max_uV) |
294 | return -EINVAL; | 300 | return -EINVAL; |
@@ -387,7 +393,7 @@ static int tps65023_dcdc_list_voltage(struct regulator_dev *dev, | |||
387 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | 393 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) |
388 | return -EINVAL; | 394 | return -EINVAL; |
389 | 395 | ||
390 | if (dcdc == TPS65023_DCDC_1) { | 396 | if (dcdc == tps->core_regulator) { |
391 | if (selector >= tps->info[dcdc]->table_len) | 397 | if (selector >= tps->info[dcdc]->table_len) |
392 | return -EINVAL; | 398 | return -EINVAL; |
393 | else | 399 | else |
@@ -439,7 +445,8 @@ static struct regmap_config tps65023_regmap_config = { | |||
439 | static int __devinit tps_65023_probe(struct i2c_client *client, | 445 | static int __devinit tps_65023_probe(struct i2c_client *client, |
440 | const struct i2c_device_id *id) | 446 | const struct i2c_device_id *id) |
441 | { | 447 | { |
442 | const struct tps_info *info = (void *)id->driver_data; | 448 | const struct tps_driver_data *drv_data = (void *)id->driver_data; |
449 | const struct tps_info *info = drv_data->info; | ||
443 | struct regulator_init_data *init_data; | 450 | struct regulator_init_data *init_data; |
444 | struct regulator_dev *rdev; | 451 | struct regulator_dev *rdev; |
445 | struct tps_pmic *tps; | 452 | struct tps_pmic *tps; |
@@ -471,6 +478,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client, | |||
471 | 478 | ||
472 | /* common for all regulators */ | 479 | /* common for all regulators */ |
473 | tps->client = client; | 480 | tps->client = client; |
481 | tps->core_regulator = drv_data->core_regulator; | ||
474 | 482 | ||
475 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) { | 483 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) { |
476 | /* Store regulator specific information */ | 484 | /* Store regulator specific information */ |
@@ -478,7 +486,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client, | |||
478 | 486 | ||
479 | tps->desc[i].name = info->name; | 487 | tps->desc[i].name = info->name; |
480 | tps->desc[i].id = i; | 488 | tps->desc[i].id = i; |
481 | tps->desc[i].n_voltages = num_voltages[i]; | 489 | tps->desc[i].n_voltages = info->table_len; |
482 | tps->desc[i].ops = (i > TPS65023_DCDC_3 ? | 490 | tps->desc[i].ops = (i > TPS65023_DCDC_3 ? |
483 | &tps65023_ldo_ops : &tps65023_dcdc_ops); | 491 | &tps65023_ldo_ops : &tps65023_dcdc_ops); |
484 | tps->desc[i].type = REGULATOR_VOLTAGE; | 492 | tps->desc[i].type = REGULATOR_VOLTAGE; |
@@ -540,13 +548,49 @@ static int __devexit tps_65023_remove(struct i2c_client *client) | |||
540 | return 0; | 548 | return 0; |
541 | } | 549 | } |
542 | 550 | ||
551 | static const struct tps_info tps65021_regs[] = { | ||
552 | { | ||
553 | .name = "VDCDC1", | ||
554 | .min_uV = 3300000, | ||
555 | .max_uV = 3300000, | ||
556 | .fixed = 1, | ||
557 | }, | ||
558 | { | ||
559 | .name = "VDCDC2", | ||
560 | .min_uV = 1800000, | ||
561 | .max_uV = 1800000, | ||
562 | .fixed = 1, | ||
563 | }, | ||
564 | { | ||
565 | .name = "VDCDC3", | ||
566 | .min_uV = 800000, | ||
567 | .max_uV = 1600000, | ||
568 | .table_len = ARRAY_SIZE(VCORE_VSEL_table), | ||
569 | .table = VCORE_VSEL_table, | ||
570 | }, | ||
571 | { | ||
572 | .name = "LDO1", | ||
573 | .min_uV = 1000000, | ||
574 | .max_uV = 3150000, | ||
575 | .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), | ||
576 | .table = TPS65023_LDO1_VSEL_table, | ||
577 | }, | ||
578 | { | ||
579 | .name = "LDO2", | ||
580 | .min_uV = 1050000, | ||
581 | .max_uV = 3300000, | ||
582 | .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), | ||
583 | .table = TPS65023_LDO2_VSEL_table, | ||
584 | }, | ||
585 | }; | ||
586 | |||
543 | static const struct tps_info tps65023_regs[] = { | 587 | static const struct tps_info tps65023_regs[] = { |
544 | { | 588 | { |
545 | .name = "VDCDC1", | 589 | .name = "VDCDC1", |
546 | .min_uV = 800000, | 590 | .min_uV = 800000, |
547 | .max_uV = 1600000, | 591 | .max_uV = 1600000, |
548 | .table_len = ARRAY_SIZE(VDCDC1_VSEL_table), | 592 | .table_len = ARRAY_SIZE(VCORE_VSEL_table), |
549 | .table = VDCDC1_VSEL_table, | 593 | .table = VCORE_VSEL_table, |
550 | }, | 594 | }, |
551 | { | 595 | { |
552 | .name = "VDCDC2", | 596 | .name = "VDCDC2", |
@@ -564,23 +608,33 @@ static const struct tps_info tps65023_regs[] = { | |||
564 | .name = "LDO1", | 608 | .name = "LDO1", |
565 | .min_uV = 1000000, | 609 | .min_uV = 1000000, |
566 | .max_uV = 3150000, | 610 | .max_uV = 3150000, |
567 | .table_len = ARRAY_SIZE(LDO1_VSEL_table), | 611 | .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), |
568 | .table = LDO1_VSEL_table, | 612 | .table = TPS65023_LDO1_VSEL_table, |
569 | }, | 613 | }, |
570 | { | 614 | { |
571 | .name = "LDO2", | 615 | .name = "LDO2", |
572 | .min_uV = 1050000, | 616 | .min_uV = 1050000, |
573 | .max_uV = 3300000, | 617 | .max_uV = 3300000, |
574 | .table_len = ARRAY_SIZE(LDO2_VSEL_table), | 618 | .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), |
575 | .table = LDO2_VSEL_table, | 619 | .table = TPS65023_LDO2_VSEL_table, |
576 | }, | 620 | }, |
577 | }; | 621 | }; |
578 | 622 | ||
623 | static struct tps_driver_data tps65021_drv_data = { | ||
624 | .info = tps65021_regs, | ||
625 | .core_regulator = TPS65023_DCDC_3, | ||
626 | }; | ||
627 | |||
628 | static struct tps_driver_data tps65023_drv_data = { | ||
629 | .info = tps65023_regs, | ||
630 | .core_regulator = TPS65023_DCDC_1, | ||
631 | }; | ||
632 | |||
579 | static const struct i2c_device_id tps_65023_id[] = { | 633 | static const struct i2c_device_id tps_65023_id[] = { |
580 | {.name = "tps65023", | 634 | {.name = "tps65023", |
581 | .driver_data = (unsigned long) tps65023_regs,}, | 635 | .driver_data = (unsigned long) &tps65023_drv_data}, |
582 | {.name = "tps65021", | 636 | {.name = "tps65021", |
583 | .driver_data = (unsigned long) tps65023_regs,}, | 637 | .driver_data = (unsigned long) &tps65021_drv_data,}, |
584 | { }, | 638 | { }, |
585 | }; | 639 | }; |
586 | 640 | ||