2 * drivers/regulator/rt5025-regulator.c
3 * Driver foo Richtek RT5025 PMIC Regulator
5 * Copyright (C) 2013 Richtek Electronics
6 * cy_huang <cy_huang@richtek.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/err.h>
16 #include <linux/i2c.h>
17 #include <linux/platform_device.h>
18 #include <linux/regulator/machine.h>
19 #include <linux/regulator/driver.h>
20 #include <linux/version.h>
21 #include <linux/mfd/rt5025.h>
22 #include <linux/regulator/rt5025-regulator.h>
24 struct rt5025_regulator_info {
25 struct regulator_desc desc;
26 struct regulator_dev *regulator;
27 struct i2c_client *i2c;
28 struct rt5025_chip *chip;
29 const unsigned int *vol_output_list;
30 const int vol_output_size;
43 static const unsigned int rt5025_vol_output_list1[] =
45 700*1000, 725*1000, 750*1000, 775*1000, 800*1000, 825*1000, 850*1000, 875*1000,
46 900*1000, 925*1000, 950*1000, 975*1000, 1000*1000, 1025*1000, 1050*1000, 1075*1000,
47 1100*1000, 1125*1000, 1150*1000, 1175*1000, 1200*1000, 1225*1000, 1250*1000, 1275*1000,
48 1300*1000, 1325*1000, 1350*1000, 1375*1000, 1400*1000, 1425*1000, 1450*1000, 1475*1000,
49 1500*1000, 1525*1000, 1550*1000, 1575*1000, 1600*1000, 1625*1000, 1650*1000, 1675*1000,
50 1700*1000, 1725*1000, 1750*1000, 1775*1000, 1800*1000, 1825*1000, 1850*1000, 1875*1000,
51 1900*1000, 1925*1000, 1950*1000, 1975*1000, 2000*2000, 2025*1000, 2050*1000, 2075*1000,
52 2100*1000, 2125*1000, 2150*1000, 2175*1000, 2200*1000, 2225*1000, 2250*1000, 2275*1000,
54 #define rt5025_vol_output_size1 ARRAY_SIZE(rt5025_vol_output_list1)
57 static const unsigned int rt5025_vol_output_list2[] =
59 700*1000, 725*1000, 750*1000, 775*1000, 800*1000, 825*1000, 850*1000, 875*1000,
60 900*1000, 925*1000, 950*1000, 975*1000, 1000*1000, 1025*1000, 1050*1000, 1075*1000,
61 1100*1000, 1125*1000, 1150*1000, 1175*1000, 1200*1000, 1225*1000, 1250*1000, 1275*1000,
62 1300*1000, 1325*1000, 1350*1000, 1375*1000, 1400*1000, 1425*1000, 1450*1000, 1475*1000,
63 1500*1000, 1525*1000, 1550*1000, 1575*1000, 1600*1000, 1625*1000, 1650*1000, 1675*1000,
64 1700*1000, 1725*1000, 1750*1000, 1775*1000, 1800*1000, 1825*1000, 1850*1000, 1875*1000,
65 1900*1000, 1925*1000, 1950*1000, 1975*1000, 2000*2000, 2025*1000, 2050*1000, 2075*1000,
66 2100*1000, 2125*1000, 2150*1000, 2175*1000, 2200*1000, 2225*1000, 2250*1000, 2275*1000,
67 2300*1000, 2325*1000, 2350*1000, 2375*1000, 2400*1000, 2425*1000, 2450*1000, 2475*1000,
68 2500*1000, 2525*1000, 2550*1000, 2575*1000, 2600*1000, 2625*1000, 2650*1000, 2675*1000,
69 2700*1000, 2725*1000, 2750*1000, 2775*1000, 2800*1000, 2825*1000, 2850*1000, 2875*1000,
70 2900*1000, 2925*1000, 2950*1000, 2975*1000, 3000*1000, 3025*1000, 3050*1000, 3075*1000,
71 3100*1000, 3125*1000, 3150*1000, 3175*1000, 3200*1000, 3225*1000, 3250*1000, 3275*1000,
72 3300*1000, 3325*1000, 3350*1000, 3375*1000, 3400*1000, 3425*1000, 3450*1000, 3475*1000,
73 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000,
74 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000,
76 #define rt5025_vol_output_size2 ARRAY_SIZE(rt5025_vol_output_list2)
79 static const unsigned int rt5025_vol_output_list3[] =
81 700*1000, 750*1000, 800*1000, 850*1000, 900*1000, 950*1000, 1000*1000, 1050*1000,
82 1100*1000, 1150*1000, 1200*1000, 1250*1000, 1300*1000, 1350*1000, 1400*1000, 1450*1000,
83 1500*1000, 1550*1000, 1600*1000, 1650*1000, 1700*1000, 1750*1000, 1800*1000, 1850*1000,
84 1900*1000, 1950*1000, 2000*1000, 2050*1000, 2100*1000, 2150*1000, 2200*1000, 2250*1000,
85 2300*1000, 2350*1000, 2400*1000, 2450*1000, 2500*1000, 2550*1000, 2600*1000, 2650*1000,
86 2700*1000, 2750*1000, 2800*1000, 2850*1000, 2900*1000, 2950*1000, 3000*1000, 3050*1000,
87 3100*1000, 3150*1000, 3200*1000, 3250*1000, 3300*1000, 3350*1000, 3400*1000, 3450*1000,
88 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000, 3500*1000,
90 #define rt5025_vol_output_size3 ARRAY_SIZE(rt5025_vol_output_list3)
93 static const unsigned int rt5025_vol_output_list4[] =
95 4500*1000, 4600*1000, 4700*1000, 4800*1000, 4900*1000, 5000*1000, 5100*1000, 5200*1000,
96 5300*1000, 5400*1000, 5500*1000, 5500*1000, 5500*1000, 5500*1000, 5500*1000, 5500*1000,
98 #define rt5025_vol_output_size4 ARRAY_SIZE(rt5025_vol_output_list4)
100 //LDO3, LDO4, LDO5, LDO6
101 static const unsigned int rt5025_vol_output_list5[] =
103 1000*1000, 1100*1000, 1200*1000, 1300*1000, 1400*1000, 1500*1000, 1600*1000, 1700*1000,
104 1800*1000, 1900*1000, 2000*1000, 2100*1000, 2200*1000, 2300*1000, 2400*1000, 2500*1000,
105 2600*1000, 2700*1000, 2800*1000, 2900*1000, 3000*1000, 3100*1000, 3200*1000, 3300*1000,
106 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000,
107 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000, 3300*1000,
109 #define rt5025_vol_output_size5 ARRAY_SIZE(rt5025_vol_output_list5)
111 static inline int check_range(struct rt5025_regulator_info *info,
112 int min_uV, int max_uV)
114 if (min_uV < info->min_uV || min_uV > info->max_uV)
120 static int rt5025_list_voltage(struct regulator_dev *rdev, unsigned index)
122 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
124 return (index>=info->vol_output_size)? \
126 info->vol_output_list[index];
129 #if 0 //(LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,38))
130 static int rt5025_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
132 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
134 const int count = info->vol_output_size;
138 data = (unsigned char)selector;
139 data <<= info->vol_shift;
140 return rt5025_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data);
143 static int rt5025_get_voltage_sel(struct regulator_dev *rdev)
145 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
147 ret = rt5025_reg_read(info->i2c, info->vol_reg);
150 return (ret & info->vol_mask) >> info->vol_shift;
153 static int rt5025_find_voltage(struct regulator_dev *rdev,
154 int min_uV, int max_uV)
156 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
158 const int count = info->vol_output_size;
159 for (i=0;i<count;i++)
161 if ((info->vol_output_list[i]>=min_uV)
162 && (info->vol_output_list[i]<=max_uV))
168 static int rt5025_set_voltage(struct regulator_dev *rdev,
169 int min_uV, int max_uV, unsigned *selector)
172 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
175 if (check_range(info, min_uV, max_uV)) {
176 dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
180 data = rt5025_find_voltage(rdev,min_uV,max_uV);
181 data <<= info->vol_shift;
183 return rt5025_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data);
187 static int rt5025_get_voltage(struct regulator_dev *rdev)
189 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
191 ret = rt5025_reg_read(info->i2c, info->vol_reg);
194 ret = (ret & info->vol_mask) >> info->vol_shift;
195 return rt5025_list_voltage(rdev, ret);
197 #endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,38) */
199 static int rt5025_enable(struct regulator_dev *rdev)
201 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
203 return rt5025_set_bits(info->i2c, info->enable_reg,
207 static int rt5025_disable(struct regulator_dev *rdev)
209 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
211 return rt5025_clr_bits(info->i2c, info->enable_reg,
215 static int rt5025_is_enabled(struct regulator_dev *rdev)
217 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
220 ret = rt5025_reg_read(info->i2c, info->enable_reg);
224 return (ret & (info->enable_bit))?1:0;
227 static int rt5025_set_mode(struct regulator_dev *rdev, unsigned int mode)
229 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
237 case REGULATOR_MODE_NORMAL:
238 ret = rt5025_set_bits(info->i2c, info->mode_reg, info->mode_bit);
240 case REGULATOR_MODE_FAST:
241 ret = rt5025_clr_bits(info->i2c, info->mode_reg, info->mode_bit);
251 static unsigned int rt5025_get_mode(struct regulator_dev *rdev)
253 struct rt5025_regulator_info *info = rdev_get_drvdata(rdev);
258 mode = REGULATOR_MODE_NORMAL;
261 data = rt5025_reg_read(info->i2c, info->mode_reg);
262 mode = (data & info->mode_bit)?REGULATOR_MODE_NORMAL:REGULATOR_MODE_FAST;
267 static struct regulator_ops rt5025_regulator_ops = {
268 .list_voltage = rt5025_list_voltage,
269 #if 0 //(LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,38))
270 .get_voltage_sel = rt5025_get_voltage_sel,
271 .set_voltage_sel = rt5025_set_voltage_sel,
273 .set_voltage = rt5025_set_voltage,
274 .get_voltage = rt5025_get_voltage,
275 #endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,38) */
276 .enable = rt5025_enable,
277 .disable = rt5025_disable,
278 .is_enabled = rt5025_is_enabled,
279 .set_mode = rt5025_set_mode,
280 .get_mode = rt5025_get_mode,
283 #define RT5025_DCDCVOUT_LIST1 rt5025_vol_output_list1
284 #define RT5025_DCDCVOUT_LIST2 rt5025_vol_output_list2
285 #define RT5025_DCDCVOUT_LIST3 rt5025_vol_output_list3
286 #define RT5025_DCDCVOUT_LIST4 rt5025_vol_output_list4
287 #define RT5025_LDOVOUT_LIST1 rt5025_vol_output_list2
288 #define RT5025_LDOVOUT_LIST2 rt5025_vol_output_list2
289 #define RT5025_LDOVOUT_LIST3 rt5025_vol_output_list5
290 #define RT5025_LDOVOUT_LIST4 rt5025_vol_output_list5
291 #define RT5025_LDOVOUT_LIST5 rt5025_vol_output_list5
292 #define RT5025_LDOVOUT_LIST6 rt5025_vol_output_list5
294 #define RT5025_DCDCVOUT_SIZE1 rt5025_vol_output_size1
295 #define RT5025_DCDCVOUT_SIZE2 rt5025_vol_output_size2
296 #define RT5025_DCDCVOUT_SIZE3 rt5025_vol_output_size3
297 #define RT5025_DCDCVOUT_SIZE4 rt5025_vol_output_size4
298 #define RT5025_LDOVOUT_SIZE1 rt5025_vol_output_size2
299 #define RT5025_LDOVOUT_SIZE2 rt5025_vol_output_size2
300 #define RT5025_LDOVOUT_SIZE3 rt5025_vol_output_size5
301 #define RT5025_LDOVOUT_SIZE4 rt5025_vol_output_size5
302 #define RT5025_LDOVOUT_SIZE5 rt5025_vol_output_size5
303 #define RT5025_LDOVOUT_SIZE6 rt5025_vol_output_size5
306 #define RT5025_DCDC(_id, min, max) \
309 .name = "rt5025-dcdc" #_id, \
310 .n_voltages = RT5025_DCDCVOUT_SIZE##_id, \
311 .ops = &rt5025_regulator_ops, \
312 .type = REGULATOR_VOLTAGE, \
313 .id = RT5025_ID_DCDC##_id, \
314 .owner = THIS_MODULE, \
316 .vol_output_list= RT5025_DCDCVOUT_LIST##_id, \
317 .vol_output_size= RT5025_DCDCVOUT_SIZE##_id, \
320 .vol_reg = RT5025_DCDCVOUT##_id, \
321 .vol_shift = RT5025_DCDCVOUT_SHIFT##_id, \
322 .vol_mask = RT5025_DCDCVOUT_MASK##_id, \
323 .enable_reg = RT5025_DCDC_OUTPUT_EN, \
324 .enable_bit = RT5025_DCDCEN_MASK##_id, \
325 .mode_reg = RT5025_REG_DCDCVRC, \
326 .mode_bit = RT5025_DCDCMODE_MASK##_id \
329 #define RT5025_LDO(_id, min, max) \
332 .name = "rt5025-ldo" #_id, \
333 .n_voltages = RT5025_LDOVOUT_SIZE##_id, \
334 .ops = &rt5025_regulator_ops, \
335 .type = REGULATOR_VOLTAGE, \
336 .id = RT5025_ID_LDO##_id, \
337 .owner = THIS_MODULE, \
339 .vol_output_list= RT5025_LDOVOUT_LIST##_id, \
340 .vol_output_size= RT5025_LDOVOUT_SIZE##_id, \
343 .vol_reg = RT5025_LDOVOUT##_id, \
344 .vol_shift = RT5025_LDOVOUT_SHIFT##_id, \
345 .vol_mask = RT5025_LDOVOUT_MASK##_id, \
346 .enable_reg = RT5025_LDO_OUTPUT_EN, \
347 .enable_bit = RT5025_LDOEN_MASK##_id, \
348 .mode_reg = RT5025_REG_LDOVRC, \
349 .mode_bit = RT5025_LDOMODE_MASK##_id, \
352 static struct rt5025_regulator_info rt5025_regulator_info[] =
354 RT5025_DCDC(1, 700000, 2275000),
355 RT5025_DCDC(2, 700000, 3500000),
356 RT5025_DCDC(3, 700000, 3500000),
357 RT5025_DCDC(4, 4500000, 5500000),
358 RT5025_LDO( 1, 700000, 3500000),
359 RT5025_LDO( 2, 700000, 3500000),
360 RT5025_LDO( 3, 1000000, 3300000),
361 RT5025_LDO( 4, 1000000, 3300000),
362 RT5025_LDO( 5, 1000000, 3300000),
363 RT5025_LDO( 6, 1000000, 3300000),
366 static struct rt5025_regulator_info * __devinit find_regulator_info(int id)
368 struct rt5025_regulator_info *ri;
371 for (i = 0; i < ARRAY_SIZE(rt5025_regulator_info); i++) {
372 ri = &rt5025_regulator_info[i];
373 if (ri->desc.id == id)
379 inline struct regulator_dev* rt5025_regulator_register(struct regulator_desc *regulator_desc,
380 struct device *dev, struct regulator_init_data *init_data,
383 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0))
384 struct regulator_config config = {
386 .init_data = init_data,
387 .driver_data = driver_data,
389 return regulator_register(®ulator_desc, &config);
391 return regulator_register(regulator_desc,dev,init_data,driver_data);
392 #endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0)) */
395 static int __devinit rt5025_regulator_probe(struct platform_device *pdev)
397 struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
398 struct rt5025_platform_data *pdata = chip->dev->platform_data;
399 struct rt5025_regulator_info *ri;
400 struct regulator_dev *rdev;
401 struct regulator_init_data* init_data;
403 ri = find_regulator_info(pdev->id);
405 dev_err(&pdev->dev, "invalid regulator ID specified\n");
408 init_data = pdata->regulator[pdev->id];
409 if (init_data == NULL) {
410 dev_err(&pdev->dev, "no initializing data\n");
416 rdev = rt5025_regulator_register(&ri->desc, &pdev->dev,
419 dev_err(&pdev->dev, "failed to register regulator %s\n",
421 return PTR_ERR(rdev);
424 platform_set_drvdata(pdev, rdev);
429 static int __devexit rt5025_regulator_remove(struct platform_device *pdev)
431 struct regulator_dev *rdev = platform_get_drvdata(pdev);
433 platform_set_drvdata(pdev, NULL);
434 regulator_unregister(rdev);
439 static struct platform_driver rt5025_regulator_driver =
442 .name = RT5025_DEVICE_NAME "-regulator",
443 .owner = THIS_MODULE,
445 .probe = rt5025_regulator_probe,
446 .remove = __devexit_p(rt5025_regulator_remove),
449 static int __init rt5025_regulator_init(void)
451 return platform_driver_register(&rt5025_regulator_driver);
453 subsys_initcall_sync(rt5025_regulator_init);
455 static void __exit rt5025_regulator_exit(void)
457 platform_driver_unregister(&rt5025_regulator_driver);
459 module_exit(rt5025_regulator_exit);
461 MODULE_LICENSE("GPL v2");
462 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
463 MODULE_DESCRIPTION("Regulator driver for RT5025");
464 MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-regulator");
465 MODULE_VERSION(RT5025_DRV_VER);