blob: a1fd65682f4c888b018dde07bab72125b11381e0 [file] [log] [blame]
Anuj Aggarwal30e65992009-08-21 00:39:31 +05301/*
2 * tps65023-regulator.c
3 *
4 * Supports TPS65023 Regulator
5 *
6 * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation version 2.
11 *
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
13 * whether express or implied; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/err.h>
22#include <linux/platform_device.h>
23#include <linux/regulator/driver.h>
24#include <linux/regulator/machine.h>
25#include <linux/i2c.h>
26#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090027#include <linux/slab.h>
Mark Brown90923352011-06-18 01:18:51 +010028#include <linux/regmap.h>
Anuj Aggarwal30e65992009-08-21 00:39:31 +053029
30/* Register definitions */
31#define TPS65023_REG_VERSION 0
32#define TPS65023_REG_PGOODZ 1
33#define TPS65023_REG_MASK 2
34#define TPS65023_REG_REG_CTRL 3
35#define TPS65023_REG_CON_CTRL 4
36#define TPS65023_REG_CON_CTRL2 5
37#define TPS65023_REG_DEF_CORE 6
38#define TPS65023_REG_DEFSLEW 7
39#define TPS65023_REG_LDO_CTRL 8
40
41/* PGOODZ bitfields */
42#define TPS65023_PGOODZ_PWRFAILZ BIT(7)
43#define TPS65023_PGOODZ_LOWBATTZ BIT(6)
44#define TPS65023_PGOODZ_VDCDC1 BIT(5)
45#define TPS65023_PGOODZ_VDCDC2 BIT(4)
46#define TPS65023_PGOODZ_VDCDC3 BIT(3)
47#define TPS65023_PGOODZ_LDO2 BIT(2)
48#define TPS65023_PGOODZ_LDO1 BIT(1)
49
50/* MASK bitfields */
51#define TPS65023_MASK_PWRFAILZ BIT(7)
52#define TPS65023_MASK_LOWBATTZ BIT(6)
53#define TPS65023_MASK_VDCDC1 BIT(5)
54#define TPS65023_MASK_VDCDC2 BIT(4)
55#define TPS65023_MASK_VDCDC3 BIT(3)
56#define TPS65023_MASK_LDO2 BIT(2)
57#define TPS65023_MASK_LDO1 BIT(1)
58
59/* REG_CTRL bitfields */
60#define TPS65023_REG_CTRL_VDCDC1_EN BIT(5)
61#define TPS65023_REG_CTRL_VDCDC2_EN BIT(4)
62#define TPS65023_REG_CTRL_VDCDC3_EN BIT(3)
63#define TPS65023_REG_CTRL_LDO2_EN BIT(2)
64#define TPS65023_REG_CTRL_LDO1_EN BIT(1)
65
Marcus Folkessonfc999b82011-08-04 13:33:49 +020066/* REG_CTRL2 bitfields */
67#define TPS65023_REG_CTRL2_GO BIT(7)
68#define TPS65023_REG_CTRL2_CORE_ADJ BIT(6)
69#define TPS65023_REG_CTRL2_DCDC2 BIT(2)
Marcus Folkessonf068ad82011-08-08 20:29:32 +020070#define TPS65023_REG_CTRL2_DCDC1 BIT(1)
71#define TPS65023_REG_CTRL2_DCDC3 BIT(0)
72
Anuj Aggarwal30e65992009-08-21 00:39:31 +053073/* LDO_CTRL bitfields */
74#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4)
Axel Lin70618732012-03-26 13:46:44 +080075#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4))
Anuj Aggarwal30e65992009-08-21 00:39:31 +053076
77/* Number of step-down converters available */
78#define TPS65023_NUM_DCDC 3
79/* Number of LDO voltage regulators available */
80#define TPS65023_NUM_LDO 2
81/* Number of total regulators available */
82#define TPS65023_NUM_REGULATOR (TPS65023_NUM_DCDC + TPS65023_NUM_LDO)
83
84/* DCDCs */
85#define TPS65023_DCDC_1 0
86#define TPS65023_DCDC_2 1
87#define TPS65023_DCDC_3 2
88/* LDOs */
89#define TPS65023_LDO_1 3
90#define TPS65023_LDO_2 4
91
92#define TPS65023_MAX_REG_ID TPS65023_LDO_2
93
94/* Supported voltage values for regulators */
Marcus Folkesson1c3ede02011-08-08 20:29:34 +020095static const u16 VCORE_VSEL_table[] = {
Anuj Aggarwal30e65992009-08-21 00:39:31 +053096 800, 825, 850, 875,
97 900, 925, 950, 975,
98 1000, 1025, 1050, 1075,
99 1100, 1125, 1150, 1175,
100 1200, 1225, 1250, 1275,
101 1300, 1325, 1350, 1375,
102 1400, 1425, 1450, 1475,
103 1500, 1525, 1550, 1600,
104};
105
Marcus Folkesson437afd22011-08-08 20:29:35 +0200106/* Supported voltage values for LDO regulators for tps65020 */
107static const u16 TPS65020_LDO1_VSEL_table[] = {
108 1000, 1050, 1100, 1300,
109 1800, 2500, 3000, 3300,
110};
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200111
Marcus Folkesson437afd22011-08-08 20:29:35 +0200112static const u16 TPS65020_LDO2_VSEL_table[] = {
113 1000, 1050, 1100, 1300,
114 1800, 2500, 3000, 3300,
115};
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200116
117/* Supported voltage values for LDO regulators
118 * for tps65021 and tps65023 */
119static const u16 TPS65023_LDO1_VSEL_table[] = {
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530120 1000, 1100, 1300, 1800,
121 2200, 2600, 2800, 3150,
122};
123
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200124static const u16 TPS65023_LDO2_VSEL_table[] = {
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530125 1050, 1200, 1300, 1800,
126 2500, 2800, 3000, 3300,
127};
128
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530129/* Regulator specific details */
130struct tps_info {
131 const char *name;
132 unsigned min_uV;
133 unsigned max_uV;
134 bool fixed;
135 u8 table_len;
136 const u16 *table;
137};
138
139/* PMIC details */
140struct tps_pmic {
141 struct regulator_desc desc[TPS65023_NUM_REGULATOR];
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530142 struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
143 const struct tps_info *info[TPS65023_NUM_REGULATOR];
Mark Brown90923352011-06-18 01:18:51 +0100144 struct regmap *regmap;
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200145 u8 core_regulator;
146};
147
148/* Struct passed as driver data */
149struct tps_driver_data {
150 const struct tps_info *info;
151 u8 core_regulator;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530152};
153
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530154static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
155{
156 struct tps_pmic *tps = rdev_get_drvdata(dev);
Jonghwan Choi43530b62011-11-07 08:16:04 +0900157 int ret;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530158 int data, dcdc = rdev_get_id(dev);
159
160 if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
161 return -EINVAL;
162
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200163 if (dcdc == tps->core_regulator) {
Jonghwan Choi43530b62011-11-07 08:16:04 +0900164 ret = regmap_read(tps->regmap, TPS65023_REG_DEF_CORE, &data);
165 if (ret != 0)
166 return ret;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530167 data &= (tps->info[dcdc]->table_len - 1);
168 return tps->info[dcdc]->table[data] * 1000;
169 } else
170 return tps->info[dcdc]->min_uV;
171}
172
Axel Lin70618732012-03-26 13:46:44 +0800173static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
174 unsigned selector)
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530175{
176 struct tps_pmic *tps = rdev_get_drvdata(dev);
177 int dcdc = rdev_get_id(dev);
Marcus Folkessoncc17ef32011-08-08 20:29:33 +0200178 int ret;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530179
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200180 if (dcdc != tps->core_regulator)
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530181 return -EINVAL;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530182
Axel Lin70618732012-03-26 13:46:44 +0800183 ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, selector);
184 if (ret)
185 goto out;
Marcus Folkessoncc17ef32011-08-08 20:29:33 +0200186
187 /* Tell the chip that we have changed the value in DEFCORE
188 * and its time to update the core voltage
189 */
Axel Lin70618732012-03-26 13:46:44 +0800190 ret = regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
191 TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
Marcus Folkessoncc17ef32011-08-08 20:29:33 +0200192
Axel Lin70618732012-03-26 13:46:44 +0800193out:
Marcus Folkessoncc17ef32011-08-08 20:29:33 +0200194 return ret;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530195}
196
197static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
198{
199 struct tps_pmic *tps = rdev_get_drvdata(dev);
200 int data, ldo = rdev_get_id(dev);
Jonghwan Choi43530b62011-11-07 08:16:04 +0900201 int ret;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530202
203 if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
204 return -EINVAL;
205
Jonghwan Choi43530b62011-11-07 08:16:04 +0900206 ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
207 if (ret != 0)
208 return ret;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530209
210 data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1));
211 data &= (tps->info[ldo]->table_len - 1);
212 return tps->info[ldo]->table[data] * 1000;
213}
214
Axel Lin70618732012-03-26 13:46:44 +0800215static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev,
216 unsigned selector)
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530217{
218 struct tps_pmic *tps = rdev_get_drvdata(dev);
Axel Lin70618732012-03-26 13:46:44 +0800219 int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530220
Axel Lin70618732012-03-26 13:46:44 +0800221 return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL,
222 TPS65023_LDO_CTRL_LDOx_MASK(ldo_index),
223 selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index));
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530224}
225
226static int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
227 unsigned selector)
228{
229 struct tps_pmic *tps = rdev_get_drvdata(dev);
230 int dcdc = rdev_get_id(dev);
231
232 if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
233 return -EINVAL;
234
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200235 if (dcdc == tps->core_regulator) {
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530236 if (selector >= tps->info[dcdc]->table_len)
237 return -EINVAL;
238 else
239 return tps->info[dcdc]->table[selector] * 1000;
240 } else
241 return tps->info[dcdc]->min_uV;
242}
243
244static int tps65023_ldo_list_voltage(struct regulator_dev *dev,
245 unsigned selector)
246{
247 struct tps_pmic *tps = rdev_get_drvdata(dev);
248 int ldo = rdev_get_id(dev);
249
250 if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
251 return -EINVAL;
252
253 if (selector >= tps->info[ldo]->table_len)
254 return -EINVAL;
255 else
256 return tps->info[ldo]->table[selector] * 1000;
257}
258
259/* Operations permitted on VDCDCx */
260static struct regulator_ops tps65023_dcdc_ops = {
Axel Linee7b1912012-04-16 19:03:09 +0800261 .is_enabled = regulator_is_enabled_regmap,
262 .enable = regulator_enable_regmap,
263 .disable = regulator_disable_regmap,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530264 .get_voltage = tps65023_dcdc_get_voltage,
Axel Lin70618732012-03-26 13:46:44 +0800265 .set_voltage_sel = tps65023_dcdc_set_voltage_sel,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530266 .list_voltage = tps65023_dcdc_list_voltage,
267};
268
269/* Operations permitted on LDOx */
270static struct regulator_ops tps65023_ldo_ops = {
Axel Linee7b1912012-04-16 19:03:09 +0800271 .is_enabled = regulator_is_enabled_regmap,
272 .enable = regulator_enable_regmap,
273 .disable = regulator_disable_regmap,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530274 .get_voltage = tps65023_ldo_get_voltage,
Axel Lin70618732012-03-26 13:46:44 +0800275 .set_voltage_sel = tps65023_ldo_set_voltage_sel,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530276 .list_voltage = tps65023_ldo_list_voltage,
277};
278
Mark Brown90923352011-06-18 01:18:51 +0100279static struct regmap_config tps65023_regmap_config = {
280 .reg_bits = 8,
281 .val_bits = 8,
282};
283
Dmitry Torokhov54d13ab2010-02-23 23:38:06 -0800284static int __devinit tps_65023_probe(struct i2c_client *client,
285 const struct i2c_device_id *id)
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530286{
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200287 const struct tps_driver_data *drv_data = (void *)id->driver_data;
288 const struct tps_info *info = drv_data->info;
Mark Brownc1727082012-04-04 00:50:22 +0100289 struct regulator_config config = { };
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530290 struct regulator_init_data *init_data;
291 struct regulator_dev *rdev;
292 struct tps_pmic *tps;
293 int i;
Dmitry Torokhov54d13ab2010-02-23 23:38:06 -0800294 int error;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530295
296 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
297 return -EIO;
298
299 /**
300 * init_data points to array of regulator_init structures
301 * coming from the board-evm file.
302 */
303 init_data = client->dev.platform_data;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530304 if (!init_data)
305 return -EIO;
306
Axel Lin19a8da22012-04-07 23:31:44 +0800307 tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530308 if (!tps)
309 return -ENOMEM;
310
Axel Lin19a8da22012-04-07 23:31:44 +0800311 tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config);
Mark Brown90923352011-06-18 01:18:51 +0100312 if (IS_ERR(tps->regmap)) {
313 error = PTR_ERR(tps->regmap);
314 dev_err(&client->dev, "Failed to allocate register map: %d\n",
315 error);
Axel Lin19a8da22012-04-07 23:31:44 +0800316 return error;
Mark Brown90923352011-06-18 01:18:51 +0100317 }
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530318
319 /* common for all regulators */
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200320 tps->core_regulator = drv_data->core_regulator;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530321
322 for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) {
323 /* Store regulator specific information */
324 tps->info[i] = info;
325
326 tps->desc[i].name = info->name;
Axel Lin77fa44d2011-05-12 13:47:50 +0800327 tps->desc[i].id = i;
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200328 tps->desc[i].n_voltages = info->table_len;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530329 tps->desc[i].ops = (i > TPS65023_DCDC_3 ?
330 &tps65023_ldo_ops : &tps65023_dcdc_ops);
331 tps->desc[i].type = REGULATOR_VOLTAGE;
332 tps->desc[i].owner = THIS_MODULE;
333
Axel Linee7b1912012-04-16 19:03:09 +0800334 tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL;
335 if (i == TPS65023_LDO_1)
336 tps->desc[i].enable_mask = 1 << 1;
337 else if (i == TPS65023_LDO_2)
338 tps->desc[i].enable_mask = 1 << 2;
339 else /* DCDCx */
340 tps->desc[i].enable_mask =
341 1 << (TPS65023_NUM_REGULATOR - i);
342
Mark Brownc1727082012-04-04 00:50:22 +0100343 config.dev = &client->dev;
344 config.init_data = init_data;
345 config.driver_data = tps;
Axel Linee7b1912012-04-16 19:03:09 +0800346 config.regmap = tps->regmap;
Mark Brownc1727082012-04-04 00:50:22 +0100347
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530348 /* Register the regulators */
Mark Brownc1727082012-04-04 00:50:22 +0100349 rdev = regulator_register(&tps->desc[i], &config);
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530350 if (IS_ERR(rdev)) {
351 dev_err(&client->dev, "failed to register %s\n",
352 id->name);
Dmitry Torokhov54d13ab2010-02-23 23:38:06 -0800353 error = PTR_ERR(rdev);
354 goto fail;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530355 }
356
357 /* Save regulator for cleanup */
358 tps->rdev[i] = rdev;
359 }
360
361 i2c_set_clientdata(client, tps);
362
Marcus Folkessonfc999b82011-08-04 13:33:49 +0200363 /* Enable setting output voltage by I2C */
Jonghwan Choi43530b62011-11-07 08:16:04 +0900364 regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
365 TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
Marcus Folkessonfc999b82011-08-04 13:33:49 +0200366
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530367 return 0;
Dmitry Torokhov54d13ab2010-02-23 23:38:06 -0800368
369 fail:
370 while (--i >= 0)
371 regulator_unregister(tps->rdev[i]);
Dmitry Torokhov54d13ab2010-02-23 23:38:06 -0800372 return error;
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530373}
374
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530375static int __devexit tps_65023_remove(struct i2c_client *client)
376{
377 struct tps_pmic *tps = i2c_get_clientdata(client);
378 int i;
379
380 for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
381 regulator_unregister(tps->rdev[i]);
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530382 return 0;
383}
384
Marcus Folkesson437afd22011-08-08 20:29:35 +0200385static const struct tps_info tps65020_regs[] = {
386 {
387 .name = "VDCDC1",
388 .min_uV = 3300000,
389 .max_uV = 3300000,
390 .fixed = 1,
391 },
392 {
393 .name = "VDCDC2",
394 .min_uV = 1800000,
395 .max_uV = 1800000,
396 .fixed = 1,
397 },
398 {
399 .name = "VDCDC3",
400 .min_uV = 800000,
401 .max_uV = 1600000,
402 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
403 .table = VCORE_VSEL_table,
404 },
405
406 {
407 .name = "LDO1",
408 .min_uV = 1000000,
409 .max_uV = 3150000,
410 .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table),
411 .table = TPS65020_LDO1_VSEL_table,
412 },
413 {
414 .name = "LDO2",
415 .min_uV = 1050000,
416 .max_uV = 3300000,
417 .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table),
418 .table = TPS65020_LDO2_VSEL_table,
419 },
420};
421
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200422static const struct tps_info tps65021_regs[] = {
423 {
424 .name = "VDCDC1",
425 .min_uV = 3300000,
426 .max_uV = 3300000,
427 .fixed = 1,
428 },
429 {
430 .name = "VDCDC2",
431 .min_uV = 1800000,
432 .max_uV = 1800000,
433 .fixed = 1,
434 },
435 {
436 .name = "VDCDC3",
437 .min_uV = 800000,
438 .max_uV = 1600000,
439 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
440 .table = VCORE_VSEL_table,
441 },
442 {
443 .name = "LDO1",
444 .min_uV = 1000000,
445 .max_uV = 3150000,
446 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
447 .table = TPS65023_LDO1_VSEL_table,
448 },
449 {
450 .name = "LDO2",
451 .min_uV = 1050000,
452 .max_uV = 3300000,
453 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
454 .table = TPS65023_LDO2_VSEL_table,
455 },
456};
457
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530458static const struct tps_info tps65023_regs[] = {
459 {
460 .name = "VDCDC1",
461 .min_uV = 800000,
462 .max_uV = 1600000,
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200463 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
464 .table = VCORE_VSEL_table,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530465 },
466 {
467 .name = "VDCDC2",
468 .min_uV = 3300000,
469 .max_uV = 3300000,
470 .fixed = 1,
471 },
472 {
473 .name = "VDCDC3",
474 .min_uV = 1800000,
475 .max_uV = 1800000,
476 .fixed = 1,
477 },
478 {
479 .name = "LDO1",
480 .min_uV = 1000000,
481 .max_uV = 3150000,
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200482 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
483 .table = TPS65023_LDO1_VSEL_table,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530484 },
485 {
486 .name = "LDO2",
487 .min_uV = 1050000,
488 .max_uV = 3300000,
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200489 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
490 .table = TPS65023_LDO2_VSEL_table,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530491 },
492};
493
Marcus Folkesson437afd22011-08-08 20:29:35 +0200494static struct tps_driver_data tps65020_drv_data = {
495 .info = tps65020_regs,
496 .core_regulator = TPS65023_DCDC_3,
497};
498
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200499static struct tps_driver_data tps65021_drv_data = {
Axel Lin70618732012-03-26 13:46:44 +0800500 .info = tps65021_regs,
501 .core_regulator = TPS65023_DCDC_3,
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200502};
503
504static struct tps_driver_data tps65023_drv_data = {
Axel Lin70618732012-03-26 13:46:44 +0800505 .info = tps65023_regs,
506 .core_regulator = TPS65023_DCDC_1,
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200507};
508
Liam Girdwood9e108d32009-08-24 10:31:34 +0100509static const struct i2c_device_id tps_65023_id[] = {
510 {.name = "tps65023",
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200511 .driver_data = (unsigned long) &tps65023_drv_data},
Marek Vasut1880a2f2010-06-24 15:49:49 +0200512 {.name = "tps65021",
Marcus Folkesson1c3ede02011-08-08 20:29:34 +0200513 .driver_data = (unsigned long) &tps65021_drv_data,},
Marcus Folkesson437afd22011-08-08 20:29:35 +0200514 {.name = "tps65020",
515 .driver_data = (unsigned long) &tps65020_drv_data},
Liam Girdwood9e108d32009-08-24 10:31:34 +0100516 { },
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530517};
518
519MODULE_DEVICE_TABLE(i2c, tps_65023_id);
520
521static struct i2c_driver tps_65023_i2c_driver = {
522 .driver = {
523 .name = "tps65023",
524 .owner = THIS_MODULE,
525 },
526 .probe = tps_65023_probe,
527 .remove = __devexit_p(tps_65023_remove),
Liam Girdwood9e108d32009-08-24 10:31:34 +0100528 .id_table = tps_65023_id,
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530529};
530
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530531static int __init tps_65023_init(void)
532{
533 return i2c_add_driver(&tps_65023_i2c_driver);
534}
535subsys_initcall(tps_65023_init);
536
Anuj Aggarwal30e65992009-08-21 00:39:31 +0530537static void __exit tps_65023_cleanup(void)
538{
539 i2c_del_driver(&tps_65023_i2c_driver);
540}
541module_exit(tps_65023_cleanup);
542
543MODULE_AUTHOR("Texas Instruments");
544MODULE_DESCRIPTION("TPS65023 voltage regulator driver");
Liam Girdwood9e108d32009-08-24 10:31:34 +0100545MODULE_LICENSE("GPL v2");