aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorKeerthy <j-keerthy@ti.com>2014-06-18 05:59:00 -0400
committerMark Brown <broonie@linaro.org>2014-06-23 07:30:56 -0400
commitd6f83370ed978d5570b7c8c22988310cb9376202 (patch)
tree70d485945d9cf7e91769c1180fce566a476965c6 /drivers/regulator
parentcac9e916245390d7b0b770b8577af4918f74d0ee (diff)
regulator: palmas: Add tps65917 PMIC support
Add tps65917 PMIC support. Signed-off-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/palmas-regulator.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index aa8e5516752e..8fa651e998da 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -227,6 +227,94 @@ static struct regs_info palmas_regs_info[] = {
227 }, 227 },
228}; 228};
229 229
230static struct regs_info tps65917_regs_info[] = {
231 {
232 .name = "SMPS1",
233 .sname = "smps1-in",
234 .vsel_addr = TPS65917_SMPS1_VOLTAGE,
235 .ctrl_addr = TPS65917_SMPS1_CTRL,
236 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS1,
237 },
238 {
239 .name = "SMPS2",
240 .sname = "smps2-in",
241 .vsel_addr = TPS65917_SMPS2_VOLTAGE,
242 .ctrl_addr = TPS65917_SMPS2_CTRL,
243 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS2,
244 },
245 {
246 .name = "SMPS3",
247 .sname = "smps3-in",
248 .vsel_addr = TPS65917_SMPS3_VOLTAGE,
249 .ctrl_addr = TPS65917_SMPS3_CTRL,
250 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS3,
251 },
252 {
253 .name = "SMPS4",
254 .sname = "smps4-in",
255 .vsel_addr = TPS65917_SMPS4_VOLTAGE,
256 .ctrl_addr = TPS65917_SMPS4_CTRL,
257 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS4,
258 },
259 {
260 .name = "SMPS5",
261 .sname = "smps5-in",
262 .vsel_addr = TPS65917_SMPS5_VOLTAGE,
263 .ctrl_addr = TPS65917_SMPS5_CTRL,
264 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS5,
265 },
266 {
267 .name = "LDO1",
268 .sname = "ldo1-in",
269 .vsel_addr = TPS65917_LDO1_VOLTAGE,
270 .ctrl_addr = TPS65917_LDO1_CTRL,
271 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO1,
272 },
273 {
274 .name = "LDO2",
275 .sname = "ldo2-in",
276 .vsel_addr = TPS65917_LDO2_VOLTAGE,
277 .ctrl_addr = TPS65917_LDO2_CTRL,
278 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO2,
279 },
280 {
281 .name = "LDO3",
282 .sname = "ldo3-in",
283 .vsel_addr = TPS65917_LDO3_VOLTAGE,
284 .ctrl_addr = TPS65917_LDO3_CTRL,
285 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO3,
286 },
287 {
288 .name = "LDO4",
289 .sname = "ldo4-in",
290 .vsel_addr = TPS65917_LDO4_VOLTAGE,
291 .ctrl_addr = TPS65917_LDO4_CTRL,
292 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO4,
293 },
294 {
295 .name = "LDO5",
296 .sname = "ldo5-in",
297 .vsel_addr = TPS65917_LDO5_VOLTAGE,
298 .ctrl_addr = TPS65917_LDO5_CTRL,
299 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO5,
300 },
301 {
302 .name = "REGEN1",
303 .ctrl_addr = TPS65917_REGEN1_CTRL,
304 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN1,
305 },
306 {
307 .name = "REGEN2",
308 .ctrl_addr = TPS65917_REGEN2_CTRL,
309 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN2,
310 },
311 {
312 .name = "REGEN3",
313 .ctrl_addr = TPS65917_REGEN3_CTRL,
314 .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN3,
315 },
316};
317
230#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \ 318#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \
231 [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \ 319 [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \
232 .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \ 320 .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \
@@ -263,6 +351,29 @@ struct palmas_sleep_requestor_info palma_sleep_req_info[] = {
263 EXTERNAL_REQUESTOR(LDOUSB, 3, 2), 351 EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
264}; 352};
265 353
354#define EXTERNAL_REQUESTOR_TPS65917(_id, _offset, _pos) \
355 [TPS65917_EXTERNAL_REQSTR_ID_##_id] = { \
356 .id = TPS65917_EXTERNAL_REQSTR_ID_##_id, \
357 .reg_offset = _offset, \
358 .bit_pos = _pos, \
359 }
360
361static struct palmas_sleep_requestor_info tps65917_sleep_req_info[] = {
362 EXTERNAL_REQUESTOR_TPS65917(REGEN1, 0, 0),
363 EXTERNAL_REQUESTOR_TPS65917(REGEN2, 0, 1),
364 EXTERNAL_REQUESTOR_TPS65917(REGEN3, 0, 6),
365 EXTERNAL_REQUESTOR_TPS65917(SMPS1, 1, 0),
366 EXTERNAL_REQUESTOR_TPS65917(SMPS2, 1, 1),
367 EXTERNAL_REQUESTOR_TPS65917(SMPS3, 1, 2),
368 EXTERNAL_REQUESTOR_TPS65917(SMPS4, 1, 3),
369 EXTERNAL_REQUESTOR_TPS65917(SMPS5, 1, 4),
370 EXTERNAL_REQUESTOR_TPS65917(LDO1, 2, 0),
371 EXTERNAL_REQUESTOR_TPS65917(LDO2, 2, 1),
372 EXTERNAL_REQUESTOR_TPS65917(LDO3, 2, 2),
373 EXTERNAL_REQUESTOR_TPS65917(LDO4, 2, 3),
374 EXTERNAL_REQUESTOR_TPS65917(LDO5, 2, 4),
375};
376
266static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; 377static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500};
267 378
268#define SMPS_CTRL_MODE_OFF 0x00 379#define SMPS_CTRL_MODE_OFF 0x00
@@ -451,6 +562,28 @@ static struct regulator_ops palmas_ops_smps10 = {
451 .get_bypass = regulator_get_bypass_regmap, 562 .get_bypass = regulator_get_bypass_regmap,
452}; 563};
453 564
565static struct regulator_ops tps65917_ops_smps = {
566 .is_enabled = regulator_is_enabled_regmap,
567 .enable = regulator_enable_regmap,
568 .disable = regulator_disable_regmap,
569 .set_mode = palmas_set_mode_smps,
570 .get_mode = palmas_get_mode_smps,
571 .get_voltage_sel = regulator_get_voltage_sel_regmap,
572 .set_voltage_sel = regulator_set_voltage_sel_regmap,
573 .list_voltage = regulator_list_voltage_linear_range,
574 .map_voltage = regulator_map_voltage_linear_range,
575 .set_voltage_time_sel = regulator_set_voltage_time_sel,
576};
577
578static struct regulator_ops tps65917_ops_ext_control_smps = {
579 .set_mode = palmas_set_mode_smps,
580 .get_mode = palmas_get_mode_smps,
581 .get_voltage_sel = regulator_get_voltage_sel_regmap,
582 .set_voltage_sel = regulator_set_voltage_sel_regmap,
583 .list_voltage = regulator_list_voltage_linear_range,
584 .map_voltage = regulator_map_voltage_linear_range,
585};
586
454static int palmas_is_enabled_ldo(struct regulator_dev *dev) 587static int palmas_is_enabled_ldo(struct regulator_dev *dev)
455{ 588{
456 struct palmas_pmic *pmic = rdev_get_drvdata(dev); 589 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
@@ -492,6 +625,17 @@ static struct regulator_ops palmas_ops_extreg = {
492static struct regulator_ops palmas_ops_ext_control_extreg = { 625static struct regulator_ops palmas_ops_ext_control_extreg = {
493}; 626};
494 627
628static struct regulator_ops tps65917_ops_ldo = {
629 .is_enabled = palmas_is_enabled_ldo,
630 .enable = regulator_enable_regmap,
631 .disable = regulator_disable_regmap,
632 .get_voltage_sel = regulator_get_voltage_sel_regmap,
633 .set_voltage_sel = regulator_set_voltage_sel_regmap,
634 .list_voltage = regulator_list_voltage_linear,
635 .map_voltage = regulator_map_voltage_linear,
636 .set_voltage_time_sel = regulator_set_voltage_time_sel,
637};
638
495static int palmas_regulator_config_external(struct palmas *palmas, int id, 639static int palmas_regulator_config_external(struct palmas *palmas, int id,
496 struct palmas_reg_init *reg_init) 640 struct palmas_reg_init *reg_init)
497{ 641{
@@ -826,6 +970,111 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic,
826 return 0; 970 return 0;
827} 971}
828 972
973static int tps65917_ldo_registration(struct palmas_pmic *pmic,
974 struct palmas_pmic_driver_data *ddata,
975 struct palmas_pmic_platform_data *pdata,
976 const char *pdev_name,
977 struct regulator_config config)
978{
979 int id, ret;
980 struct regulator_dev *rdev;
981 struct palmas_reg_init *reg_init;
982
983 for (id = ddata->ldo_begin; id < ddata->max_reg; id++) {
984 if (pdata && pdata->reg_init[id])
985 reg_init = pdata->reg_init[id];
986 else
987 reg_init = NULL;
988
989 /* Miss out regulators which are not available due
990 * to alternate functions.
991 */
992
993 /* Register the regulators */
994 pmic->desc[id].name = ddata->palmas_regs_info[id].name;
995 pmic->desc[id].id = id;
996 pmic->desc[id].type = REGULATOR_VOLTAGE;
997 pmic->desc[id].owner = THIS_MODULE;
998
999 if (id < TPS65917_REG_REGEN1) {
1000 pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
1001 if (reg_init && reg_init->roof_floor)
1002 pmic->desc[id].ops =
1003 &palmas_ops_ext_control_ldo;
1004 else
1005 pmic->desc[id].ops = &tps65917_ops_ldo;
1006 pmic->desc[id].min_uV = 900000;
1007 pmic->desc[id].uV_step = 50000;
1008 pmic->desc[id].linear_min_sel = 1;
1009 pmic->desc[id].enable_time = 500;
1010 pmic->desc[id].vsel_reg =
1011 PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
1012 ddata->palmas_regs_info[id].vsel_addr);
1013 pmic->desc[id].vsel_mask =
1014 PALMAS_LDO1_VOLTAGE_VSEL_MASK;
1015 pmic->desc[id].enable_reg =
1016 PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
1017 ddata->palmas_regs_info[id].ctrl_addr);
1018 pmic->desc[id].enable_mask =
1019 PALMAS_LDO1_CTRL_MODE_ACTIVE;
1020 /*
1021 * To be confirmed. Discussion on going with PMIC Team.
1022 * It is of the order of ~60mV/uS.
1023 */
1024 pmic->desc[id].ramp_delay = 2500;
1025 } else {
1026 pmic->desc[id].n_voltages = 1;
1027 if (reg_init && reg_init->roof_floor)
1028 pmic->desc[id].ops =
1029 &palmas_ops_ext_control_extreg;
1030 else
1031 pmic->desc[id].ops = &palmas_ops_extreg;
1032 pmic->desc[id].enable_reg =
1033 PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
1034 ddata->palmas_regs_info[id].ctrl_addr);
1035 pmic->desc[id].enable_mask =
1036 PALMAS_REGEN1_CTRL_MODE_ACTIVE;
1037 }
1038
1039 if (pdata)
1040 config.init_data = pdata->reg_data[id];
1041 else
1042 config.init_data = NULL;
1043
1044 pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname;
1045 config.of_node = ddata->palmas_matches[id].of_node;
1046
1047 rdev = devm_regulator_register(pmic->dev, &pmic->desc[id],
1048 &config);
1049 if (IS_ERR(rdev)) {
1050 dev_err(pmic->dev,
1051 "failed to register %s regulator\n",
1052 pdev_name);
1053 return PTR_ERR(rdev);
1054 }
1055
1056 /* Save regulator for cleanup */
1057 pmic->rdev[id] = rdev;
1058
1059 /* Initialise sleep/init values from platform data */
1060 if (pdata) {
1061 reg_init = pdata->reg_init[id];
1062 if (reg_init) {
1063 if (id < TPS65917_REG_REGEN1)
1064 ret = palmas_ldo_init(pmic->palmas,
1065 id, reg_init);
1066 else
1067 ret = palmas_extreg_init(pmic->palmas,
1068 id, reg_init);
1069 if (ret)
1070 return ret;
1071 }
1072 }
1073 }
1074
1075 return 0;
1076}
1077
829static int palmas_smps_registration(struct palmas_pmic *pmic, 1078static int palmas_smps_registration(struct palmas_pmic *pmic,
830 struct palmas_pmic_driver_data *ddata, 1079 struct palmas_pmic_driver_data *ddata,
831 struct palmas_pmic_platform_data *pdata, 1080 struct palmas_pmic_platform_data *pdata,
@@ -996,6 +1245,109 @@ static int palmas_smps_registration(struct palmas_pmic *pmic,
996 return 0; 1245 return 0;
997} 1246}
998 1247
1248static int tps65917_smps_registration(struct palmas_pmic *pmic,
1249 struct palmas_pmic_driver_data *ddata,
1250 struct palmas_pmic_platform_data *pdata,
1251 const char *pdev_name,
1252 struct regulator_config config)
1253{
1254 int id, ret;
1255 unsigned int addr, reg;
1256 struct regulator_dev *rdev;
1257 struct palmas_reg_init *reg_init;
1258
1259 for (id = ddata->smps_start; id <= ddata->smps_end; id++) {
1260 /*
1261 * Miss out regulators which are not available due
1262 * to slaving configurations.
1263 */
1264 pmic->desc[id].n_linear_ranges = 3;
1265 if ((id == TPS65917_REG_SMPS2) && pmic->smps12)
1266 continue;
1267
1268 /* Initialise sleep/init values from platform data */
1269 if (pdata && pdata->reg_init[id]) {
1270 reg_init = pdata->reg_init[id];
1271 ret = palmas_smps_init(pmic->palmas, id, reg_init);
1272 if (ret)
1273 return ret;
1274 } else {
1275 reg_init = NULL;
1276 }
1277
1278 /* Register the regulators */
1279 pmic->desc[id].name = ddata->palmas_regs_info[id].name;
1280 pmic->desc[id].id = id;
1281
1282 /*
1283 * Read and store the RANGE bit for later use
1284 * This must be done before regulator is probed,
1285 * otherwise we error in probe with unsupportable
1286 * ranges. Read the current smps mode for later use.
1287 */
1288 addr = ddata->palmas_regs_info[id].vsel_addr;
1289
1290 ret = palmas_smps_read(pmic->palmas, addr, &reg);
1291 if (ret)
1292 return ret;
1293 if (reg & TPS65917_SMPS1_VOLTAGE_RANGE)
1294 pmic->range[id] = 1;
1295
1296 if (pmic->range[id])
1297 pmic->desc[id].linear_ranges = smps_high_ranges;
1298 else
1299 pmic->desc[id].linear_ranges = smps_low_ranges;
1300
1301
1302 if (reg_init && reg_init->roof_floor)
1303 pmic->desc[id].ops =
1304 &tps65917_ops_ext_control_smps;
1305 else
1306 pmic->desc[id].ops = &tps65917_ops_smps;
1307 pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
1308 pmic->desc[id].vsel_reg =
1309 PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
1310 tps65917_regs_info[id].vsel_addr);
1311 pmic->desc[id].vsel_mask =
1312 PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
1313
1314 pmic->desc[id].ramp_delay = 2500;
1315
1316 /* Read the smps mode for later use. */
1317 addr = ddata->palmas_regs_info[id].ctrl_addr;
1318 ret = palmas_smps_read(pmic->palmas, addr, &reg);
1319 if (ret)
1320 return ret;
1321 pmic->current_reg_mode[id] = reg &
1322 PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
1323
1324 pmic->desc[id].type = REGULATOR_VOLTAGE;
1325 pmic->desc[id].owner = THIS_MODULE;
1326
1327 if (pdata)
1328 config.init_data = pdata->reg_data[id];
1329 else
1330 config.init_data = NULL;
1331
1332 pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname;
1333 config.of_node = ddata->palmas_matches[id].of_node;
1334
1335 rdev = devm_regulator_register(pmic->dev, &pmic->desc[id],
1336 &config);
1337 if (IS_ERR(rdev)) {
1338 dev_err(pmic->dev,
1339 "failed to register %s regulator\n",
1340 pdev_name);
1341 return PTR_ERR(rdev);
1342 }
1343
1344 /* Save regulator for cleanup */
1345 pmic->rdev[id] = rdev;
1346 }
1347
1348 return 0;
1349}
1350
999static struct of_regulator_match palmas_matches[] = { 1351static struct of_regulator_match palmas_matches[] = {
1000 { .name = "smps12", }, 1352 { .name = "smps12", },
1001 { .name = "smps123", }, 1353 { .name = "smps123", },
@@ -1026,6 +1378,24 @@ static struct of_regulator_match palmas_matches[] = {
1026 { .name = "sysen2", }, 1378 { .name = "sysen2", },
1027}; 1379};
1028 1380
1381static struct of_regulator_match tps65917_matches[] = {
1382 { .name = "smps1", },
1383 { .name = "smps2", },
1384 { .name = "smps3", },
1385 { .name = "smps4", },
1386 { .name = "smps5", },
1387 { .name = "ldo1", },
1388 { .name = "ldo2", },
1389 { .name = "ldo3", },
1390 { .name = "ldo4", },
1391 { .name = "ldo5", },
1392 { .name = "regen1", },
1393 { .name = "regen2", },
1394 { .name = "regen3", },
1395 { .name = "sysen1", },
1396 { .name = "sysen2", },
1397};
1398
1029struct palmas_pmic_driver_data palmas_ddata = { 1399struct palmas_pmic_driver_data palmas_ddata = {
1030 .smps_start = PALMAS_REG_SMPS12, 1400 .smps_start = PALMAS_REG_SMPS12,
1031 .smps_end = PALMAS_REG_SMPS10_OUT1, 1401 .smps_end = PALMAS_REG_SMPS10_OUT1,
@@ -1039,6 +1409,19 @@ struct palmas_pmic_driver_data palmas_ddata = {
1039 .ldo_register = palmas_ldo_registration, 1409 .ldo_register = palmas_ldo_registration,
1040}; 1410};
1041 1411
1412struct palmas_pmic_driver_data tps65917_ddata = {
1413 .smps_start = TPS65917_REG_SMPS1,
1414 .smps_end = TPS65917_REG_SMPS5,
1415 .ldo_begin = TPS65917_REG_LDO1,
1416 .ldo_end = TPS65917_REG_LDO5,
1417 .max_reg = TPS65917_NUM_REGS,
1418 .palmas_regs_info = tps65917_regs_info,
1419 .palmas_matches = tps65917_matches,
1420 .sleep_req_info = tps65917_sleep_req_info,
1421 .smps_register = tps65917_smps_registration,
1422 .ldo_register = tps65917_ldo_registration,
1423};
1424
1042static void palmas_dt_to_pdata(struct device *dev, 1425static void palmas_dt_to_pdata(struct device *dev,
1043 struct device_node *node, 1426 struct device_node *node,
1044 struct palmas_pmic_platform_data *pdata, 1427 struct palmas_pmic_platform_data *pdata,
@@ -1160,6 +1543,10 @@ static struct of_device_id of_palmas_match_tbl[] = {
1160 .compatible = "ti,tps659038-pmic", 1543 .compatible = "ti,tps659038-pmic",
1161 .data = &palmas_ddata, 1544 .data = &palmas_ddata,
1162 }, 1545 },
1546 {
1547 .compatible = "ti,tps65917-pmic",
1548 .data = &tps65917_ddata,
1549 },
1163 { /* end */ } 1550 { /* end */ }
1164}; 1551};
1165 1552