1 /*
2  * tps65217-regulator.c
3  *
4  * Regulator driver for TPS65217 PMIC
5  *
6  * Copyright (C) 2011 Texas Instruments 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
13  * kind, whether express or implied; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17 
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/device.h>
21 #include <linux/init.h>
22 #include <linux/err.h>
23 #include <linux/platform_device.h>
24 
25 #include <linux/regulator/driver.h>
26 #include <linux/regulator/machine.h>
27 #include <linux/mfd/tps65217.h>
28 
29 #define TPS65217_REGULATOR(_name, _id, _ops, _n)	\
30 	{						\
31 		.name		= _name,		\
32 		.id		= _id,			\
33 		.ops		= &_ops,		\
34 		.n_voltages	= _n,			\
35 		.type		= REGULATOR_VOLTAGE,	\
36 		.owner		= THIS_MODULE,		\
37 	}						\
38 
39 #define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm)	\
40 	{						\
41 		.name		= _nm,			\
42 		.min_uV		= _min,			\
43 		.max_uV		= _max,			\
44 		.vsel_to_uv	= _f1,			\
45 		.uv_to_vsel	= _f2,			\
46 		.table		= _t,			\
47 		.table_len	= _n,			\
48 		.enable_mask	= _em,			\
49 		.set_vout_reg	= _vr,			\
50 		.set_vout_mask	= _vm,			\
51 	}
52 
53 static const int LDO1_VSEL_table[] = {
54 	1000000, 1100000, 1200000, 1250000,
55 	1300000, 1350000, 1400000, 1500000,
56 	1600000, 1800000, 2500000, 2750000,
57 	2800000, 3000000, 3100000, 3300000,
58 };
59 
tps65217_vsel_to_uv1(unsigned int vsel)60 static int tps65217_vsel_to_uv1(unsigned int vsel)
61 {
62 	int uV = 0;
63 
64 	if (vsel > 63)
65 		return -EINVAL;
66 
67 	if (vsel <= 24)
68 		uV = vsel * 25000 + 900000;
69 	else if (vsel <= 52)
70 		uV = (vsel - 24) * 50000 + 1500000;
71 	else if (vsel < 56)
72 		uV = (vsel - 52) * 100000 + 2900000;
73 	else
74 		uV = 3300000;
75 
76 	return uV;
77 }
78 
tps65217_uv_to_vsel1(int uV,unsigned int * vsel)79 static int tps65217_uv_to_vsel1(int uV, unsigned int *vsel)
80 {
81 	if ((uV < 0) && (uV > 3300000))
82 		return -EINVAL;
83 
84 	if (uV <= 1500000)
85 		*vsel = DIV_ROUND_UP(uV - 900000, 25000);
86 	else if (uV <= 2900000)
87 		*vsel = 24 + DIV_ROUND_UP(uV - 1500000, 50000);
88 	else if (uV < 3300000)
89 		*vsel = 52 + DIV_ROUND_UP(uV - 2900000, 100000);
90 	else
91 		*vsel = 56;
92 
93 	return 0;
94 }
95 
tps65217_vsel_to_uv2(unsigned int vsel)96 static int tps65217_vsel_to_uv2(unsigned int vsel)
97 {
98 	int uV = 0;
99 
100 	if (vsel > 31)
101 		return -EINVAL;
102 
103 	if (vsel <= 8)
104 		uV = vsel * 50000 + 1500000;
105 	else if (vsel <= 13)
106 		uV = (vsel - 8) * 100000 + 1900000;
107 	else
108 		uV = (vsel - 13) * 50000 + 2400000;
109 
110 	return uV;
111 }
112 
tps65217_uv_to_vsel2(int uV,unsigned int * vsel)113 static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel)
114 {
115 	if ((uV < 0) && (uV > 3300000))
116 		return -EINVAL;
117 
118 	if (uV <= 1900000)
119 		*vsel = DIV_ROUND_UP(uV - 1500000, 50000);
120 	else if (uV <= 2400000)
121 		*vsel = 8 + DIV_ROUND_UP(uV - 1900000, 100000);
122 	else
123 		*vsel = 13 + DIV_ROUND_UP(uV - 2400000, 50000);
124 
125 	return 0;
126 }
127 
128 static struct tps_info tps65217_pmic_regs[] = {
129 	TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1,
130 			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN,
131 			TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK),
132 	TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1,
133 			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN,
134 			TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK),
135 	TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1,
136 			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN,
137 			TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK),
138 	TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table,
139 			16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1,
140 			TPS65217_DEFLDO1_LDO1_MASK),
141 	TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1,
142 			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN,
143 			TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK),
144 	TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2,
145 			tps65217_uv_to_vsel2, NULL, 32,
146 			TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN,
147 			TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK),
148 	TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2,
149 			tps65217_uv_to_vsel2, NULL, 32,
150 			TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN,
151 			TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK),
152 };
153 
tps65217_pmic_is_enabled(struct regulator_dev * dev)154 static int tps65217_pmic_is_enabled(struct regulator_dev *dev)
155 {
156 	int ret;
157 	struct tps65217 *tps = rdev_get_drvdata(dev);
158 	unsigned int data, rid = rdev_get_id(dev);
159 
160 	if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
161 		return -EINVAL;
162 
163 	ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data);
164 	if (ret)
165 		return ret;
166 
167 	return (data & tps->info[rid]->enable_mask) ? 1 : 0;
168 }
169 
tps65217_pmic_enable(struct regulator_dev * dev)170 static int tps65217_pmic_enable(struct regulator_dev *dev)
171 {
172 	struct tps65217 *tps = rdev_get_drvdata(dev);
173 	unsigned int rid = rdev_get_id(dev);
174 
175 	if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
176 		return -EINVAL;
177 
178 	/* Enable the regulator and password protection is level 1 */
179 	return tps65217_set_bits(tps, TPS65217_REG_ENABLE,
180 				tps->info[rid]->enable_mask,
181 				tps->info[rid]->enable_mask,
182 				TPS65217_PROTECT_L1);
183 }
184 
tps65217_pmic_disable(struct regulator_dev * dev)185 static int tps65217_pmic_disable(struct regulator_dev *dev)
186 {
187 	struct tps65217 *tps = rdev_get_drvdata(dev);
188 	unsigned int rid = rdev_get_id(dev);
189 
190 	if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
191 		return -EINVAL;
192 
193 	/* Disable the regulator and password protection is level 1 */
194 	return tps65217_clear_bits(tps, TPS65217_REG_ENABLE,
195 			tps->info[rid]->enable_mask, TPS65217_PROTECT_L1);
196 }
197 
tps65217_pmic_get_voltage_sel(struct regulator_dev * dev)198 static int tps65217_pmic_get_voltage_sel(struct regulator_dev *dev)
199 {
200 	int ret;
201 	struct tps65217 *tps = rdev_get_drvdata(dev);
202 	unsigned int selector, rid = rdev_get_id(dev);
203 
204 	if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
205 		return -EINVAL;
206 
207 	ret = tps65217_reg_read(tps, tps->info[rid]->set_vout_reg, &selector);
208 	if (ret)
209 		return ret;
210 
211 	selector &= tps->info[rid]->set_vout_mask;
212 
213 	return selector;
214 }
215 
tps65217_pmic_ldo1_set_voltage_sel(struct regulator_dev * dev,unsigned selector)216 static int tps65217_pmic_ldo1_set_voltage_sel(struct regulator_dev *dev,
217 						unsigned selector)
218 {
219 	struct tps65217 *tps = rdev_get_drvdata(dev);
220 	int ldo = rdev_get_id(dev);
221 
222 	if (ldo != TPS65217_LDO_1)
223 		return -EINVAL;
224 
225 	if (selector >= tps->info[ldo]->table_len)
226 		return -EINVAL;
227 
228 	/* Set the voltage based on vsel value and write protect level is 2 */
229 	return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg,
230 					tps->info[ldo]->set_vout_mask,
231 					selector, TPS65217_PROTECT_L2);
232 }
233 
tps65217_pmic_set_voltage(struct regulator_dev * dev,int min_uV,int max_uV,unsigned * selector)234 static int tps65217_pmic_set_voltage(struct regulator_dev *dev,
235 				  int min_uV, int max_uV, unsigned *selector)
236 {
237 	int ret;
238 	struct tps65217 *tps = rdev_get_drvdata(dev);
239 	unsigned int rid = rdev_get_id(dev);
240 
241 	/* LDO1 implements set_voltage_sel callback */
242 	if (rid == TPS65217_LDO_1)
243 		return -EINVAL;
244 
245 	if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
246 		return -EINVAL;
247 
248 	if (min_uV < tps->info[rid]->min_uV
249 		|| min_uV > tps->info[rid]->max_uV)
250 		return -EINVAL;
251 
252 	if (max_uV < tps->info[rid]->min_uV
253 		|| max_uV > tps->info[rid]->max_uV)
254 		return -EINVAL;
255 
256 	ret = tps->info[rid]->uv_to_vsel(min_uV, selector);
257 	if (ret)
258 		return ret;
259 
260 	/* Set the voltage based on vsel value and write protect level is 2 */
261 	ret = tps65217_set_bits(tps, tps->info[rid]->set_vout_reg,
262 				tps->info[rid]->set_vout_mask,
263 				*selector, TPS65217_PROTECT_L2);
264 
265 	/* Set GO bit for DCDCx to initiate voltage transistion */
266 	switch (rid) {
267 	case TPS65217_DCDC_1 ... TPS65217_DCDC_3:
268 		ret = tps65217_set_bits(tps, TPS65217_REG_DEFSLEW,
269 				       TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO,
270 				       TPS65217_PROTECT_L2);
271 		break;
272 	}
273 
274 	return ret;
275 }
276 
tps65217_pmic_list_voltage(struct regulator_dev * dev,unsigned selector)277 static int tps65217_pmic_list_voltage(struct regulator_dev *dev,
278 					unsigned selector)
279 {
280 	struct tps65217 *tps = rdev_get_drvdata(dev);
281 	unsigned int rid = rdev_get_id(dev);
282 
283 	if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
284 		return -EINVAL;
285 
286 	if (selector >= tps->info[rid]->table_len)
287 		return -EINVAL;
288 
289 	if (tps->info[rid]->table)
290 		return tps->info[rid]->table[selector];
291 
292 	return tps->info[rid]->vsel_to_uv(selector);
293 }
294 
295 /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */
296 static struct regulator_ops tps65217_pmic_ops = {
297 	.is_enabled		= tps65217_pmic_is_enabled,
298 	.enable			= tps65217_pmic_enable,
299 	.disable		= tps65217_pmic_disable,
300 	.get_voltage_sel	= tps65217_pmic_get_voltage_sel,
301 	.set_voltage		= tps65217_pmic_set_voltage,
302 	.list_voltage		= tps65217_pmic_list_voltage,
303 };
304 
305 /* Operations permitted on LDO1 */
306 static struct regulator_ops tps65217_pmic_ldo1_ops = {
307 	.is_enabled		= tps65217_pmic_is_enabled,
308 	.enable			= tps65217_pmic_enable,
309 	.disable		= tps65217_pmic_disable,
310 	.get_voltage_sel	= tps65217_pmic_get_voltage_sel,
311 	.set_voltage_sel	= tps65217_pmic_ldo1_set_voltage_sel,
312 	.list_voltage		= tps65217_pmic_list_voltage,
313 };
314 
315 static struct regulator_desc regulators[] = {
316 	TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64),
317 	TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64),
318 	TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64),
319 	TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16),
320 	TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64),
321 	TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32),
322 	TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32),
323 };
324 
tps65217_regulator_probe(struct platform_device * pdev)325 static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
326 {
327 	struct regulator_dev *rdev;
328 	struct tps65217 *tps;
329 	struct tps_info *info = &tps65217_pmic_regs[pdev->id];
330 
331 	/* Already set by core driver */
332 	tps = dev_to_tps65217(pdev->dev.parent);
333 	tps->info[pdev->id] = info;
334 
335 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
336 				  pdev->dev.platform_data, tps, NULL);
337 	if (IS_ERR(rdev))
338 		return PTR_ERR(rdev);
339 
340 	platform_set_drvdata(pdev, rdev);
341 
342 	return 0;
343 }
344 
tps65217_regulator_remove(struct platform_device * pdev)345 static int __devexit tps65217_regulator_remove(struct platform_device *pdev)
346 {
347 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
348 
349 	platform_set_drvdata(pdev, NULL);
350 	regulator_unregister(rdev);
351 
352 	return 0;
353 }
354 
355 static struct platform_driver tps65217_regulator_driver = {
356 	.driver = {
357 		.name = "tps65217-pmic",
358 	},
359 	.probe = tps65217_regulator_probe,
360 	.remove = __devexit_p(tps65217_regulator_remove),
361 };
362 
tps65217_regulator_init(void)363 static int __init tps65217_regulator_init(void)
364 {
365 	return platform_driver_register(&tps65217_regulator_driver);
366 }
367 subsys_initcall(tps65217_regulator_init);
368 
tps65217_regulator_exit(void)369 static void __exit tps65217_regulator_exit(void)
370 {
371 	platform_driver_unregister(&tps65217_regulator_driver);
372 }
373 module_exit(tps65217_regulator_exit);
374 
375 MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
376 MODULE_DESCRIPTION("TPS65217 voltage regulator driver");
377 MODULE_ALIAS("platform:tps65217-pmic");
378 MODULE_LICENSE("GPL v2");
379