1/*
2* da9052-regulator.c: Regulator driver for DA9052
3*
4* Copyright(c) 2011 Dialog Semiconductor Ltd.
5*
6* Author: David Dajun Chen <dchen@diasemi.com>
7*
8* This program is free software; you can redistribute it and/or modify
9* it under the terms of the GNU General Public License as published by
10* the Free Software Foundation; either version 2 of the License, or
11* (at your option) any later version.
12*
13*/
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22
23#include <linux/mfd/da9052/da9052.h>
24#include <linux/mfd/da9052/reg.h>
25#include <linux/mfd/da9052/pdata.h>
26
27/* Buck step size */
28#define DA9052_BUCK_PERI_3uV_STEP		100000
29#define DA9052_BUCK_PERI_REG_MAP_UPTO_3uV	24
30#define DA9052_CONST_3uV			3000000
31
32#define DA9052_MIN_UA		0
33#define DA9052_MAX_UA		3
34#define DA9052_CURRENT_RANGE	4
35
36/* Bit masks */
37#define DA9052_BUCK_ILIM_MASK_EVEN	0x0c
38#define DA9052_BUCK_ILIM_MASK_ODD	0xc0
39
40static const u32 da9052_current_limits[3][4] = {
41	{700000, 800000, 1000000, 1200000},	/* DA9052-BC BUCKs */
42	{1600000, 2000000, 2400000, 3000000},	/* DA9053-AA/Bx BUCK-CORE */
43	{800000, 1000000, 1200000, 1500000},	/* DA9053-AA/Bx BUCK-PRO,
44						 * BUCK-MEM and BUCK-PERI
45						*/
46};
47
48struct da9052_regulator_info {
49	struct regulator_desc reg_desc;
50	int step_uV;
51	int min_uV;
52	int max_uV;
53	unsigned char volt_shift;
54	unsigned char en_bit;
55	unsigned char activate_bit;
56};
57
58struct da9052_regulator {
59	struct da9052 *da9052;
60	struct da9052_regulator_info *info;
61	struct regulator_dev *rdev;
62};
63
64static int verify_range(struct da9052_regulator_info *info,
65			 int min_uV, int max_uV)
66{
67	if (min_uV > info->max_uV || max_uV < info->min_uV)
68		return -EINVAL;
69
70	return 0;
71}
72
73static int da9052_regulator_enable(struct regulator_dev *rdev)
74{
75	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
76	struct da9052_regulator_info *info = regulator->info;
77	int offset = rdev_get_id(rdev);
78
79	return da9052_reg_update(regulator->da9052,
80				 DA9052_BUCKCORE_REG + offset,
81				 1 << info->en_bit, 1 << info->en_bit);
82}
83
84static int da9052_regulator_disable(struct regulator_dev *rdev)
85{
86	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
87	struct da9052_regulator_info *info = regulator->info;
88	int offset = rdev_get_id(rdev);
89
90	return da9052_reg_update(regulator->da9052,
91				 DA9052_BUCKCORE_REG + offset,
92				 1 << info->en_bit, 0);
93}
94
95static int da9052_regulator_is_enabled(struct regulator_dev *rdev)
96{
97	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
98	struct da9052_regulator_info *info = regulator->info;
99	int offset = rdev_get_id(rdev);
100	int ret;
101
102	ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
103	if (ret < 0)
104		return ret;
105
106	return ret & (1 << info->en_bit);
107}
108
109static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev)
110{
111	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
112	int offset = rdev_get_id(rdev);
113	int ret, row = 2;
114
115	ret = da9052_reg_read(regulator->da9052, DA9052_BUCKA_REG + offset/2);
116	if (ret < 0)
117		return ret;
118
119	/* Determine the even or odd position of the buck current limit
120	 * register field
121	*/
122	if (offset % 2 == 0)
123		ret = (ret & DA9052_BUCK_ILIM_MASK_EVEN) >> 2;
124	else
125		ret = (ret & DA9052_BUCK_ILIM_MASK_ODD) >> 6;
126
127	/* Select the appropriate current limit range */
128	if (regulator->da9052->chip_id == DA9052)
129		row = 0;
130	else if (offset == 0)
131		row = 1;
132
133	return da9052_current_limits[row][ret];
134}
135
136static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
137					  int max_uA)
138{
139	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
140	int offset = rdev_get_id(rdev);
141	int reg_val = 0;
142	int i, row = 2;
143
144	/* Select the appropriate current limit range */
145	if (regulator->da9052->chip_id == DA9052)
146		row = 0;
147	else if (offset == 0)
148		row = 1;
149
150	if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] ||
151	    max_uA < da9052_current_limits[row][DA9052_MIN_UA])
152		return -EINVAL;
153
154	for (i = 0; i < DA9052_CURRENT_RANGE; i++) {
155		if (min_uA <= da9052_current_limits[row][i]) {
156			reg_val = i;
157			break;
158		}
159	}
160
161	/* Determine the even or odd position of the buck current limit
162	 * register field
163	*/
164	if (offset % 2 == 0)
165		return da9052_reg_update(regulator->da9052,
166					 DA9052_BUCKA_REG + offset/2,
167					 DA9052_BUCK_ILIM_MASK_EVEN,
168					 reg_val << 2);
169	else
170		return da9052_reg_update(regulator->da9052,
171					 DA9052_BUCKA_REG + offset/2,
172					 DA9052_BUCK_ILIM_MASK_ODD,
173					 reg_val << 6);
174}
175
176static int da9052_list_buckperi_voltage(struct regulator_dev *rdev,
177					 unsigned int selector)
178{
179	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
180	struct da9052_regulator_info *info = regulator->info;
181	int volt_uV;
182
183	if ((regulator->da9052->chip_id == DA9052) &&
184	    (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
185		volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
186			    + info->min_uV);
187		volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
188			    * (DA9052_BUCK_PERI_3uV_STEP);
189	} else
190			volt_uV = (selector * info->step_uV) + info->min_uV;
191
192	if (volt_uV > info->max_uV)
193		return -EINVAL;
194
195	return volt_uV;
196}
197
198static int da9052_list_voltage(struct regulator_dev *rdev,
199				unsigned int selector)
200{
201	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
202	struct da9052_regulator_info *info = regulator->info;
203	int volt_uV;
204
205	volt_uV = info->min_uV + info->step_uV * selector;
206
207	if (volt_uV > info->max_uV)
208		return -EINVAL;
209
210	return volt_uV;
211}
212
213static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
214					     int min_uV, int max_uV,
215					     unsigned int *selector)
216{
217	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
218	struct da9052_regulator_info *info = regulator->info;
219	int offset = rdev_get_id(rdev);
220	int ret;
221
222	ret = verify_range(info, min_uV, max_uV);
223	if (ret < 0)
224		return ret;
225
226	if (min_uV < info->min_uV)
227		min_uV = info->min_uV;
228
229	*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
230
231	ret = da9052_list_voltage(rdev, *selector);
232	if (ret < 0)
233		return ret;
234
235	return da9052_reg_update(regulator->da9052,
236				 DA9052_BUCKCORE_REG + offset,
237				 (1 << info->volt_shift) - 1, *selector);
238}
239
240static int da9052_set_ldo_voltage(struct regulator_dev *rdev,
241				   int min_uV, int max_uV,
242				   unsigned int *selector)
243{
244	return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
245}
246
247static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev,
248				      int min_uV, int max_uV,
249				      unsigned int *selector)
250{
251	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
252	struct da9052_regulator_info *info = regulator->info;
253	int ret;
254
255	ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
256	if (ret < 0)
257		return ret;
258
259	/* Some LDOs are DVC controlled which requires enabling of
260	 * the LDO activate bit to implment the changes on the
261	 * LDO output.
262	*/
263	return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
264				 info->activate_bit, info->activate_bit);
265}
266
267static int da9052_set_dcdc_voltage(struct regulator_dev *rdev,
268				    int min_uV, int max_uV,
269				    unsigned int *selector)
270{
271	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
272	struct da9052_regulator_info *info = regulator->info;
273	int ret;
274
275	ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
276	if (ret < 0)
277		return ret;
278
279	/* Some DCDCs are DVC controlled which requires enabling of
280	 * the DCDC activate bit to implment the changes on the
281	 * DCDC output.
282	*/
283	return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
284				 info->activate_bit, info->activate_bit);
285}
286
287static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev)
288{
289	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
290	struct da9052_regulator_info *info = regulator->info;
291	int offset = rdev_get_id(rdev);
292	int ret;
293
294	ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
295	if (ret < 0)
296		return ret;
297
298	ret &= ((1 << info->volt_shift) - 1);
299
300	return ret;
301}
302
303static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV,
304					int max_uV, unsigned int *selector)
305{
306	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
307	struct da9052_regulator_info *info = regulator->info;
308	int offset = rdev_get_id(rdev);
309	int ret;
310
311	ret = verify_range(info, min_uV, max_uV);
312	if (ret < 0)
313		return ret;
314
315	if (min_uV < info->min_uV)
316		min_uV = info->min_uV;
317
318	if ((regulator->da9052->chip_id == DA9052) &&
319	    (min_uV >= DA9052_CONST_3uV))
320		*selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
321			    DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
322					 DA9052_BUCK_PERI_3uV_STEP);
323	else
324		*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
325
326	ret = da9052_list_buckperi_voltage(rdev, *selector);
327	if (ret < 0)
328		return ret;
329
330	return da9052_reg_update(regulator->da9052,
331				 DA9052_BUCKCORE_REG + offset,
332				 (1 << info->volt_shift) - 1, *selector);
333}
334
335static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev)
336{
337	struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
338	struct da9052_regulator_info *info = regulator->info;
339	int offset = rdev_get_id(rdev);
340	int ret;
341
342	ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
343	if (ret < 0)
344		return ret;
345
346	ret &= ((1 << info->volt_shift) - 1);
347
348	return ret;
349}
350
351static struct regulator_ops da9052_buckperi_ops = {
352	.list_voltage = da9052_list_buckperi_voltage,
353	.get_voltage_sel = da9052_get_buckperi_voltage_sel,
354	.set_voltage = da9052_set_buckperi_voltage,
355
356	.get_current_limit = da9052_dcdc_get_current_limit,
357	.set_current_limit = da9052_dcdc_set_current_limit,
358
359	.is_enabled = da9052_regulator_is_enabled,
360	.enable = da9052_regulator_enable,
361	.disable = da9052_regulator_disable,
362};
363
364static struct regulator_ops da9052_dcdc_ops = {
365	.set_voltage = da9052_set_dcdc_voltage,
366	.get_current_limit = da9052_dcdc_get_current_limit,
367	.set_current_limit = da9052_dcdc_set_current_limit,
368
369	.list_voltage = da9052_list_voltage,
370	.get_voltage_sel = da9052_get_regulator_voltage_sel,
371	.is_enabled = da9052_regulator_is_enabled,
372	.enable = da9052_regulator_enable,
373	.disable = da9052_regulator_disable,
374};
375
376static struct regulator_ops da9052_ldo5_6_ops = {
377	.set_voltage = da9052_set_ldo5_6_voltage,
378
379	.list_voltage = da9052_list_voltage,
380	.get_voltage_sel = da9052_get_regulator_voltage_sel,
381	.is_enabled = da9052_regulator_is_enabled,
382	.enable = da9052_regulator_enable,
383	.disable = da9052_regulator_disable,
384};
385
386static struct regulator_ops da9052_ldo_ops = {
387	.set_voltage = da9052_set_ldo_voltage,
388
389	.list_voltage = da9052_list_voltage,
390	.get_voltage_sel = da9052_get_regulator_voltage_sel,
391	.is_enabled = da9052_regulator_is_enabled,
392	.enable = da9052_regulator_enable,
393	.disable = da9052_regulator_disable,
394};
395
396#define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \
397{\
398	.reg_desc = {\
399		.name = "LDO" #_id,\
400		.ops = &da9052_ldo5_6_ops,\
401		.type = REGULATOR_VOLTAGE,\
402		.id = _id,\
403		.n_voltages = (max - min) / step + 1, \
404		.owner = THIS_MODULE,\
405	},\
406	.min_uV = (min) * 1000,\
407	.max_uV = (max) * 1000,\
408	.step_uV = (step) * 1000,\
409	.volt_shift = (sbits),\
410	.en_bit = (ebits),\
411	.activate_bit = (abits),\
412}
413
414#define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
415{\
416	.reg_desc = {\
417		.name = "LDO" #_id,\
418		.ops = &da9052_ldo_ops,\
419		.type = REGULATOR_VOLTAGE,\
420		.id = _id,\
421		.n_voltages = (max - min) / step + 1, \
422		.owner = THIS_MODULE,\
423	},\
424	.min_uV = (min) * 1000,\
425	.max_uV = (max) * 1000,\
426	.step_uV = (step) * 1000,\
427	.volt_shift = (sbits),\
428	.en_bit = (ebits),\
429	.activate_bit = (abits),\
430}
431
432#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
433{\
434	.reg_desc = {\
435		.name = "BUCK" #_id,\
436		.ops = &da9052_dcdc_ops,\
437		.type = REGULATOR_VOLTAGE,\
438		.id = _id,\
439		.n_voltages = (max - min) / step + 1, \
440		.owner = THIS_MODULE,\
441	},\
442	.min_uV = (min) * 1000,\
443	.max_uV = (max) * 1000,\
444	.step_uV = (step) * 1000,\
445	.volt_shift = (sbits),\
446	.en_bit = (ebits),\
447	.activate_bit = (abits),\
448}
449
450#define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
451{\
452	.reg_desc = {\
453		.name = "BUCK" #_id,\
454		.ops = &da9052_buckperi_ops,\
455		.type = REGULATOR_VOLTAGE,\
456		.id = _id,\
457		.n_voltages = (max - min) / step + 1, \
458		.owner = THIS_MODULE,\
459	},\
460	.min_uV = (min) * 1000,\
461	.max_uV = (max) * 1000,\
462	.step_uV = (step) * 1000,\
463	.volt_shift = (sbits),\
464	.en_bit = (ebits),\
465	.activate_bit = (abits),\
466}
467
468static struct da9052_regulator_info da9052_regulator_info[] = {
469	/* Buck1 - 4 */
470	DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
471	DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
472	DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
473	DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0),
474	/* LD01 - LDO10 */
475	DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
476	DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
477	DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
478	DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
479	DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
480	DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
481	DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
482	DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
483	DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
484	DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
485};
486
487static struct da9052_regulator_info da9053_regulator_info[] = {
488	/* Buck1 - 4 */
489	DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
490	DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
491	DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
492	DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0),
493	/* LD01 - LDO10 */
494	DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
495	DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
496	DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
497	DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
498	DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
499	DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
500	DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
501	DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
502	DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
503	DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
504};
505
506static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
507								 int id)
508{
509	struct da9052_regulator_info *info;
510	int i;
511
512	switch (chip_id) {
513	case DA9052:
514		for (i = 0; i < ARRAY_SIZE(da9052_regulator_info); i++) {
515			info = &da9052_regulator_info[i];
516			if (info->reg_desc.id == id)
517				return info;
518		}
519		break;
520	case DA9053_AA:
521	case DA9053_BA:
522	case DA9053_BB:
523		for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) {
524			info = &da9053_regulator_info[i];
525			if (info->reg_desc.id == id)
526				return info;
527		}
528		break;
529	}
530
531	return NULL;
532}
533
534static int __devinit da9052_regulator_probe(struct platform_device *pdev)
535{
536	struct da9052_regulator *regulator;
537	struct da9052 *da9052;
538	struct da9052_pdata *pdata;
539	int ret;
540
541	regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator),
542				 GFP_KERNEL);
543	if (!regulator)
544		return -ENOMEM;
545
546	da9052 = dev_get_drvdata(pdev->dev.parent);
547	pdata = da9052->dev->platform_data;
548	regulator->da9052 = da9052;
549
550	regulator->info = find_regulator_info(regulator->da9052->chip_id,
551					      pdev->id);
552	if (regulator->info == NULL) {
553		dev_err(&pdev->dev, "invalid regulator ID specified\n");
554		ret = -EINVAL;
555		goto err;
556	}
557	regulator->rdev = regulator_register(&regulator->info->reg_desc,
558					     &pdev->dev,
559					     pdata->regulators[pdev->id],
560					     regulator, NULL);
561	if (IS_ERR(regulator->rdev)) {
562		dev_err(&pdev->dev, "failed to register regulator %s\n",
563			regulator->info->reg_desc.name);
564		ret = PTR_ERR(regulator->rdev);
565		goto err;
566	}
567
568	platform_set_drvdata(pdev, regulator);
569
570	return 0;
571err:
572	devm_kfree(&pdev->dev, regulator);
573	return ret;
574}
575
576static int __devexit da9052_regulator_remove(struct platform_device *pdev)
577{
578	struct da9052_regulator *regulator = platform_get_drvdata(pdev);
579
580	regulator_unregister(regulator->rdev);
581	devm_kfree(&pdev->dev, regulator);
582
583	return 0;
584}
585
586static struct platform_driver da9052_regulator_driver = {
587	.probe = da9052_regulator_probe,
588	.remove = __devexit_p(da9052_regulator_remove),
589	.driver = {
590		.name = "da9052-regulator",
591		.owner = THIS_MODULE,
592	},
593};
594
595static int __init da9052_regulator_init(void)
596{
597	return platform_driver_register(&da9052_regulator_driver);
598}
599subsys_initcall(da9052_regulator_init);
600
601static void __exit da9052_regulator_exit(void)
602{
603	platform_driver_unregister(&da9052_regulator_driver);
604}
605module_exit(da9052_regulator_exit);
606
607MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
608MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9052 PMIC");
609MODULE_LICENSE("GPL");
610MODULE_ALIAS("platform:da9052-regulator");
611