diff options
Diffstat (limited to 'drivers/regulator/tps65023-regulator.c')
-rw-r--r-- | drivers/regulator/tps65023-regulator.c | 201 |
1 files changed, 62 insertions, 139 deletions
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 8f1be8586c72..6998d579d07b 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -69,10 +69,6 @@ #define TPS65023_REG_CTRL2_DCDC1 BIT(1) #define TPS65023_REG_CTRL2_DCDC3 BIT(0) -/* LDO_CTRL bitfields */ -#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) -#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x07 << ((ldo_id)*4)) - /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 /* Number of LDO voltage regulators available */ @@ -91,48 +87,53 @@ #define TPS65023_MAX_REG_ID TPS65023_LDO_2 /* Supported voltage values for regulators */ -static const u16 VCORE_VSEL_table[] = { - 800, 825, 850, 875, - 900, 925, 950, 975, - 1000, 1025, 1050, 1075, - 1100, 1125, 1150, 1175, - 1200, 1225, 1250, 1275, - 1300, 1325, 1350, 1375, - 1400, 1425, 1450, 1475, - 1500, 1525, 1550, 1600, +static const unsigned int VCORE_VSEL_table[] = { + 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, 1600000, +}; + +static const unsigned int DCDC_FIXED_3300000_VSEL_table[] = { + 3300000, +}; + +static const unsigned int DCDC_FIXED_1800000_VSEL_table[] = { + 1800000, }; /* Supported voltage values for LDO regulators for tps65020 */ -static const u16 TPS65020_LDO1_VSEL_table[] = { - 1000, 1050, 1100, 1300, - 1800, 2500, 3000, 3300, +static const unsigned int TPS65020_LDO1_VSEL_table[] = { + 1000000, 1050000, 1100000, 1300000, + 1800000, 2500000, 3000000, 3300000, }; -static const u16 TPS65020_LDO2_VSEL_table[] = { - 1000, 1050, 1100, 1300, - 1800, 2500, 3000, 3300, +static const unsigned int TPS65020_LDO2_VSEL_table[] = { + 1000000, 1050000, 1100000, 1300000, + 1800000, 2500000, 3000000, 3300000, }; /* Supported voltage values for LDO regulators * for tps65021 and tps65023 */ -static const u16 TPS65023_LDO1_VSEL_table[] = { - 1000, 1100, 1300, 1800, - 2200, 2600, 2800, 3150, +static const unsigned int TPS65023_LDO1_VSEL_table[] = { + 1000000, 1100000, 1300000, 1800000, + 2200000, 2600000, 2800000, 3150000, }; -static const u16 TPS65023_LDO2_VSEL_table[] = { - 1050, 1200, 1300, 1800, - 2500, 2800, 3000, 3300, +static const unsigned int TPS65023_LDO2_VSEL_table[] = { + 1050000, 1200000, 1300000, 1800000, + 2500000, 2800000, 3000000, 3300000, }; /* Regulator specific details */ struct tps_info { const char *name; - unsigned min_uV; - unsigned max_uV; - bool fixed; u8 table_len; - const u16 *table; + const unsigned int *table; }; /* PMIC details */ @@ -150,7 +151,7 @@ struct tps_driver_data { u8 core_regulator; }; -static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) +static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev) { struct tps_pmic *tps = rdev_get_drvdata(dev); int ret; @@ -164,9 +165,9 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) if (ret != 0) return ret; data &= (tps->info[dcdc]->table_len - 1); - return tps->info[dcdc]->table[data] * 1000; + return data; } else - return tps->info[dcdc]->min_uV; + return 0; } static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, @@ -193,76 +194,14 @@ out: return ret; } -static int tps65023_ldo_get_voltage(struct regulator_dev *dev) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int data, ldo = rdev_get_id(dev); - int ret; - - if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) - return -EINVAL; - - ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data); - if (ret != 0) - return ret; - - data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)); - data &= (tps->info[ldo]->table_len - 1); - return tps->info[ldo]->table[data] * 1000; -} - -static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1; - - return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL, - TPS65023_LDO_CTRL_LDOx_MASK(ldo_index), - selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index)); -} - -static int tps65023_dcdc_list_voltage(struct regulator_dev *dev, - unsigned selector) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int dcdc = rdev_get_id(dev); - - if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) - return -EINVAL; - - if (dcdc == tps->core_regulator) { - if (selector >= tps->info[dcdc]->table_len) - return -EINVAL; - else - return tps->info[dcdc]->table[selector] * 1000; - } else - return tps->info[dcdc]->min_uV; -} - -static int tps65023_ldo_list_voltage(struct regulator_dev *dev, - unsigned selector) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int ldo = rdev_get_id(dev); - - if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) - return -EINVAL; - - if (selector >= tps->info[ldo]->table_len) - return -EINVAL; - else - return tps->info[ldo]->table[selector] * 1000; -} - /* Operations permitted on VDCDCx */ static struct regulator_ops tps65023_dcdc_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage = tps65023_dcdc_get_voltage, + .get_voltage_sel = tps65023_dcdc_get_voltage_sel, .set_voltage_sel = tps65023_dcdc_set_voltage_sel, - .list_voltage = tps65023_dcdc_list_voltage, + .list_voltage = regulator_list_voltage_table, }; /* Operations permitted on LDOx */ @@ -270,9 +209,9 @@ static struct regulator_ops tps65023_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage = tps65023_ldo_get_voltage, - .set_voltage_sel = tps65023_ldo_set_voltage_sel, - .list_voltage = tps65023_ldo_list_voltage, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_table, }; static struct regmap_config tps65023_regmap_config = { @@ -325,19 +264,28 @@ static int __devinit tps_65023_probe(struct i2c_client *client, tps->desc[i].name = info->name; tps->desc[i].id = i; tps->desc[i].n_voltages = info->table_len; + tps->desc[i].volt_table = info->table; tps->desc[i].ops = (i > TPS65023_DCDC_3 ? &tps65023_ldo_ops : &tps65023_dcdc_ops); tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL; - if (i == TPS65023_LDO_1) + switch (i) { + case TPS65023_LDO_1: + tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; + tps->desc[i].vsel_mask = 0x07; tps->desc[i].enable_mask = 1 << 1; - else if (i == TPS65023_LDO_2) + break; + case TPS65023_LDO_2: + tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; + tps->desc[i].vsel_mask = 0x70; tps->desc[i].enable_mask = 1 << 2; - else /* DCDCx */ + break; + default: /* DCDCx */ tps->desc[i].enable_mask = 1 << (TPS65023_NUM_REGULATOR - i); + } config.dev = &client->dev; config.init_data = init_data; @@ -384,35 +332,26 @@ static int __devexit tps_65023_remove(struct i2c_client *client) static const struct tps_info tps65020_regs[] = { { .name = "VDCDC1", - .min_uV = 3300000, - .max_uV = 3300000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), + .table = DCDC_FIXED_3300000_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 1800000, - .max_uV = 1800000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), + .table = DCDC_FIXED_1800000_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 800000, - .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, - { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table), .table = TPS65020_LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 1050000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table), .table = TPS65020_LDO2_VSEL_table, }, @@ -421,34 +360,26 @@ static const struct tps_info tps65020_regs[] = { static const struct tps_info tps65021_regs[] = { { .name = "VDCDC1", - .min_uV = 3300000, - .max_uV = 3300000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), + .table = DCDC_FIXED_3300000_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 1800000, - .max_uV = 1800000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), + .table = DCDC_FIXED_1800000_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 800000, - .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), .table = TPS65023_LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 1050000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), .table = TPS65023_LDO2_VSEL_table, }, @@ -457,34 +388,26 @@ static const struct tps_info tps65021_regs[] = { static const struct tps_info tps65023_regs[] = { { .name = "VDCDC1", - .min_uV = 800000, - .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 3300000, - .max_uV = 3300000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), + .table = DCDC_FIXED_3300000_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 1800000, - .max_uV = 1800000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), + .table = DCDC_FIXED_1800000_VSEL_table, }, { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), .table = TPS65023_LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 1050000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), .table = TPS65023_LDO2_VSEL_table, }, |