Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * s5m8767.c
  3 *
  4 * Copyright (c) 2011 Samsung Electronics Co., Ltd
  5 *              http://www.samsung.com
  6 *
  7 *  This program is free software; you can redistribute  it and/or modify it
  8 *  under  the terms of  the GNU General  Public License as published by the
  9 *  Free Software Foundation;  either version 2 of the  License, or (at your
 10 *  option) any later version.
 11 *
 12 */
 13
 14#include <linux/bug.h>
 15#include <linux/err.h>
 16#include <linux/gpio.h>
 17#include <linux/slab.h>
 18#include <linux/module.h>
 19#include <linux/platform_device.h>
 20#include <linux/regulator/driver.h>
 21#include <linux/regulator/machine.h>
 22#include <linux/mfd/s5m87xx/s5m-core.h>
 23#include <linux/mfd/s5m87xx/s5m-pmic.h>
 24
 25struct s5m8767_info {
 26	struct device *dev;
 27	struct s5m87xx_dev *iodev;
 28	int num_regulators;
 29	struct regulator_dev **rdev;
 30	struct s5m_opmode_data *opmode;
 31
 32	int ramp_delay;
 33	bool buck2_ramp;
 34	bool buck3_ramp;
 35	bool buck4_ramp;
 36
 37	bool buck2_gpiodvs;
 38	bool buck3_gpiodvs;
 39	bool buck4_gpiodvs;
 40	u8 buck2_vol[8];
 41	u8 buck3_vol[8];
 42	u8 buck4_vol[8];
 43	int buck_gpios[3];
 44	int buck_gpioindex;
 45};
 46
 47struct s5m_voltage_desc {
 48	int max;
 49	int min;
 50	int step;
 51};
 52
 53static const struct s5m_voltage_desc buck_voltage_val1 = {
 54	.max = 2225000,
 55	.min =  650000,
 56	.step =   6250,
 57};
 58
 59static const struct s5m_voltage_desc buck_voltage_val2 = {
 60	.max = 1600000,
 61	.min =  600000,
 62	.step =   6250,
 63};
 64
 65static const struct s5m_voltage_desc buck_voltage_val3 = {
 66	.max = 3000000,
 67	.min =  750000,
 68	.step =  12500,
 69};
 70
 71static const struct s5m_voltage_desc ldo_voltage_val1 = {
 72	.max = 3950000,
 73	.min =  800000,
 74	.step =  50000,
 75};
 76
 77static const struct s5m_voltage_desc ldo_voltage_val2 = {
 78	.max = 2375000,
 79	.min =  800000,
 80	.step =  25000,
 81};
 82
 83static const struct s5m_voltage_desc *reg_voltage_map[] = {
 84	[S5M8767_LDO1] = &ldo_voltage_val2,
 85	[S5M8767_LDO2] = &ldo_voltage_val2,
 86	[S5M8767_LDO3] = &ldo_voltage_val1,
 87	[S5M8767_LDO4] = &ldo_voltage_val1,
 88	[S5M8767_LDO5] = &ldo_voltage_val1,
 89	[S5M8767_LDO6] = &ldo_voltage_val2,
 90	[S5M8767_LDO7] = &ldo_voltage_val2,
 91	[S5M8767_LDO8] = &ldo_voltage_val2,
 92	[S5M8767_LDO9] = &ldo_voltage_val1,
 93	[S5M8767_LDO10] = &ldo_voltage_val1,
 94	[S5M8767_LDO11] = &ldo_voltage_val1,
 95	[S5M8767_LDO12] = &ldo_voltage_val1,
 96	[S5M8767_LDO13] = &ldo_voltage_val1,
 97	[S5M8767_LDO14] = &ldo_voltage_val1,
 98	[S5M8767_LDO15] = &ldo_voltage_val2,
 99	[S5M8767_LDO16] = &ldo_voltage_val1,
100	[S5M8767_LDO17] = &ldo_voltage_val1,
101	[S5M8767_LDO18] = &ldo_voltage_val1,
102	[S5M8767_LDO19] = &ldo_voltage_val1,
103	[S5M8767_LDO20] = &ldo_voltage_val1,
104	[S5M8767_LDO21] = &ldo_voltage_val1,
105	[S5M8767_LDO22] = &ldo_voltage_val1,
106	[S5M8767_LDO23] = &ldo_voltage_val1,
107	[S5M8767_LDO24] = &ldo_voltage_val1,
108	[S5M8767_LDO25] = &ldo_voltage_val1,
109	[S5M8767_LDO26] = &ldo_voltage_val1,
110	[S5M8767_LDO27] = &ldo_voltage_val1,
111	[S5M8767_LDO28] = &ldo_voltage_val1,
112	[S5M8767_BUCK1] = &buck_voltage_val1,
113	[S5M8767_BUCK2] = &buck_voltage_val2,
114	[S5M8767_BUCK3] = &buck_voltage_val2,
115	[S5M8767_BUCK4] = &buck_voltage_val2,
116	[S5M8767_BUCK5] = &buck_voltage_val1,
117	[S5M8767_BUCK6] = &buck_voltage_val1,
118	[S5M8767_BUCK7] = NULL,
119	[S5M8767_BUCK8] = NULL,
120	[S5M8767_BUCK9] = &buck_voltage_val3,
121};
122
123static int s5m8767_list_voltage(struct regulator_dev *rdev,
124				unsigned int selector)
125{
126	const struct s5m_voltage_desc *desc;
127	int reg_id = rdev_get_id(rdev);
128	int val;
129
130	if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0)
131		return -EINVAL;
132
133	desc = reg_voltage_map[reg_id];
134	if (desc == NULL)
135		return -EINVAL;
136
137	val = desc->min + desc->step * selector;
138	if (val > desc->max)
139		return -EINVAL;
140
141	return val;
142}
143
144static unsigned int s5m8767_opmode_reg[][4] = {
145	/* {OFF, ON, LOWPOWER, SUSPEND} */
146	/* LDO1 ... LDO28 */
147	{0x0, 0x3, 0x2, 0x1}, /* LDO1 */
148	{0x0, 0x3, 0x2, 0x1},
149	{0x0, 0x3, 0x2, 0x1},
150	{0x0, 0x0, 0x0, 0x0},
151	{0x0, 0x3, 0x2, 0x1}, /* LDO5 */
152	{0x0, 0x3, 0x2, 0x1},
153	{0x0, 0x3, 0x2, 0x1},
154	{0x0, 0x3, 0x2, 0x1},
155	{0x0, 0x3, 0x2, 0x1},
156	{0x0, 0x3, 0x2, 0x1}, /* LDO10 */
157	{0x0, 0x3, 0x2, 0x1},
158	{0x0, 0x3, 0x2, 0x1},
159	{0x0, 0x3, 0x2, 0x1},
160	{0x0, 0x3, 0x2, 0x1},
161	{0x0, 0x3, 0x2, 0x1}, /* LDO15 */
162	{0x0, 0x3, 0x2, 0x1},
163	{0x0, 0x3, 0x2, 0x1},
164	{0x0, 0x0, 0x0, 0x0},
165	{0x0, 0x3, 0x2, 0x1},
166	{0x0, 0x3, 0x2, 0x1}, /* LDO20 */
167	{0x0, 0x3, 0x2, 0x1},
168	{0x0, 0x3, 0x2, 0x1},
169	{0x0, 0x0, 0x0, 0x0},
170	{0x0, 0x3, 0x2, 0x1},
171	{0x0, 0x3, 0x2, 0x1}, /* LDO25 */
172	{0x0, 0x3, 0x2, 0x1},
173	{0x0, 0x3, 0x2, 0x1},
174	{0x0, 0x3, 0x2, 0x1}, /* LDO28 */
175
176	/* BUCK1 ... BUCK9 */
177	{0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
178	{0x0, 0x3, 0x1, 0x1},
179	{0x0, 0x3, 0x1, 0x1},
180	{0x0, 0x3, 0x1, 0x1},
181	{0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
182	{0x0, 0x3, 0x1, 0x1},
183	{0x0, 0x3, 0x1, 0x1},
184	{0x0, 0x3, 0x1, 0x1},
185	{0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
186};
187
188static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
189				int *enable_ctrl)
190{
191	int reg_id = rdev_get_id(rdev);
192	unsigned int mode;
193	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
194
195	switch (reg_id) {
196	case S5M8767_LDO1 ... S5M8767_LDO2:
197		*reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
198		break;
199	case S5M8767_LDO3 ... S5M8767_LDO28:
200		*reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
201		break;
202	case S5M8767_BUCK1:
203		*reg = S5M8767_REG_BUCK1CTRL1;
204		break;
205	case S5M8767_BUCK2 ... S5M8767_BUCK4:
206		*reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9;
207		break;
208	case S5M8767_BUCK5:
209		*reg = S5M8767_REG_BUCK5CTRL1;
210		break;
211	case S5M8767_BUCK6 ... S5M8767_BUCK9:
212		*reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2;
213		break;
214	default:
215		return -EINVAL;
216	}
217
218	mode = s5m8767->opmode[reg_id].mode;
219	*enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
220	return 0;
221}
222
223static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
224{
225	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
226	int ret, reg;
227	int mask = 0xc0, enable_ctrl;
228	u8 val;
229
230	ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
231	if (ret == -EINVAL)
232		return 1;
233	else if (ret)
234		return ret;
235
236	ret = s5m_reg_read(s5m8767->iodev, reg, &val);
237	if (ret)
238		return ret;
239
240	return (val & mask) == enable_ctrl;
241}
242
243static int s5m8767_reg_enable(struct regulator_dev *rdev)
244{
245	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
246	int ret, reg;
247	int mask = 0xc0, enable_ctrl;
248
249	ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
250	if (ret)
251		return ret;
252
253	return s5m_reg_update(s5m8767->iodev, reg, enable_ctrl, mask);
254}
255
256static int s5m8767_reg_disable(struct regulator_dev *rdev)
257{
258	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
259	int ret, reg;
260	int  mask = 0xc0, enable_ctrl;
261
262	ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
263	if (ret)
264		return ret;
265
266	return s5m_reg_update(s5m8767->iodev, reg, ~mask, mask);
267}
268
269static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
270{
271	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
272	int reg_id = rdev_get_id(rdev);
273	int reg;
274
275	switch (reg_id) {
276	case S5M8767_LDO1 ... S5M8767_LDO2:
277		reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
278		break;
279	case S5M8767_LDO3 ... S5M8767_LDO28:
280		reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
281		break;
282	case S5M8767_BUCK1:
283		reg = S5M8767_REG_BUCK1CTRL2;
284		break;
285	case S5M8767_BUCK2:
286		reg = S5M8767_REG_BUCK2DVS1;
287		if (s5m8767->buck2_gpiodvs)
288			reg += s5m8767->buck_gpioindex;
289		break;
290	case S5M8767_BUCK3:
291		reg = S5M8767_REG_BUCK3DVS1;
292		if (s5m8767->buck3_gpiodvs)
293			reg += s5m8767->buck_gpioindex;
294		break;
295	case S5M8767_BUCK4:
296		reg = S5M8767_REG_BUCK4DVS1;
297		if (s5m8767->buck4_gpiodvs)
298			reg += s5m8767->buck_gpioindex;
299		break;
300	case S5M8767_BUCK5:
301		reg = S5M8767_REG_BUCK5CTRL2;
302		break;
303	case S5M8767_BUCK6 ... S5M8767_BUCK9:
304		reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2;
305		break;
306	default:
307		return -EINVAL;
308	}
309
310	*_reg = reg;
311
312	return 0;
313}
314
315static int s5m8767_get_voltage_sel(struct regulator_dev *rdev)
316{
317	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
318	int reg, mask, ret;
319	int reg_id = rdev_get_id(rdev);
320	u8 val;
321
322	ret = s5m8767_get_voltage_register(rdev, &reg);
323	if (ret)
324		return ret;
325
326	mask = (reg_id < S5M8767_BUCK1) ? 0x3f : 0xff;
327
328	ret = s5m_reg_read(s5m8767->iodev, reg, &val);
329	if (ret)
330		return ret;
331
332	val &= mask;
333
334	return val;
335}
336
337static int s5m8767_convert_voltage_to_sel(
338		const struct s5m_voltage_desc *desc,
339		int min_vol, int max_vol)
340{
341	int selector = 0;
342
343	if (desc == NULL)
344		return -EINVAL;
345
346	if (max_vol < desc->min || min_vol > desc->max)
347		return -EINVAL;
348
349	if (min_vol < desc->min)
350		min_vol = desc->min;
351
352	selector = DIV_ROUND_UP(min_vol - desc->min, desc->step);
353
354	if (desc->min + desc->step * selector > max_vol)
355		return -EINVAL;
356
357	return selector;
358}
359
360static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
361{
362	int temp_index = s5m8767->buck_gpioindex;
363
364	gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
365	gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
366	gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
367}
368
369static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
370{
371	int temp_index = s5m8767->buck_gpioindex;
372
373	gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
374	gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
375	gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
376}
377
378static int s5m8767_set_voltage(struct regulator_dev *rdev,
379				int min_uV, int max_uV, unsigned *selector)
380{
381	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
382	const struct s5m_voltage_desc *desc;
383	int reg_id = rdev_get_id(rdev);
384	int sel, reg, mask, ret = 0, old_index, index = 0;
385	u8 val;
386	u8 *buck234_vol = NULL;
387
388	switch (reg_id) {
389	case S5M8767_LDO1 ... S5M8767_LDO28:
390		mask = 0x3f;
391		break;
392	case S5M8767_BUCK1 ... S5M8767_BUCK6:
393		mask = 0xff;
394		if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
395			buck234_vol = &s5m8767->buck2_vol[0];
396		else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
397			buck234_vol = &s5m8767->buck3_vol[0];
398		else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
399			buck234_vol = &s5m8767->buck4_vol[0];
400		break;
401	case S5M8767_BUCK7 ... S5M8767_BUCK8:
402		return -EINVAL;
403	case S5M8767_BUCK9:
404		mask = 0xff;
405		break;
406	default:
407		return -EINVAL;
408	}
409
410	desc = reg_voltage_map[reg_id];
411
412	sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
413	if (sel < 0)
414		return sel;
415
416	/* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
417	if (buck234_vol) {
418		while (*buck234_vol != sel) {
419			buck234_vol++;
420			index++;
421		}
422		old_index = s5m8767->buck_gpioindex;
423		s5m8767->buck_gpioindex = index;
424
425		if (index > old_index)
426			s5m8767_set_high(s5m8767);
427		else
428			s5m8767_set_low(s5m8767);
429	} else {
430		ret = s5m8767_get_voltage_register(rdev, &reg);
431		if (ret)
432			return ret;
433
434		s5m_reg_read(s5m8767->iodev, reg, &val);
435		val = (val & ~mask) | sel;
436
437		ret = s5m_reg_write(s5m8767->iodev, reg, val);
438	}
439
440	*selector = sel;
441	return ret;
442}
443
444static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
445					     unsigned int old_sel,
446					     unsigned int new_sel)
447{
448	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
449	const struct s5m_voltage_desc *desc;
450	int reg_id = rdev_get_id(rdev);
451
452	desc = reg_voltage_map[reg_id];
453
454	if ((old_sel < new_sel) && s5m8767->ramp_delay)
455		return DIV_ROUND_UP(desc->step * (new_sel - old_sel),
456					s5m8767->ramp_delay * 1000);
457	return 0;
458}
459
460static struct regulator_ops s5m8767_ops = {
461	.list_voltage		= s5m8767_list_voltage,
462	.is_enabled		= s5m8767_reg_is_enabled,
463	.enable			= s5m8767_reg_enable,
464	.disable		= s5m8767_reg_disable,
465	.get_voltage_sel	= s5m8767_get_voltage_sel,
466	.set_voltage		= s5m8767_set_voltage,
467	.set_voltage_time_sel	= s5m8767_set_voltage_time_sel,
468};
469
470#define s5m8767_regulator_desc(_name) {		\
471	.name		= #_name,		\
472	.id		= S5M8767_##_name,	\
473	.ops		= &s5m8767_ops,		\
474	.type		= REGULATOR_VOLTAGE,	\
475	.owner		= THIS_MODULE,		\
476}
477
478static struct regulator_desc regulators[] = {
479	s5m8767_regulator_desc(LDO1),
480	s5m8767_regulator_desc(LDO2),
481	s5m8767_regulator_desc(LDO3),
482	s5m8767_regulator_desc(LDO4),
483	s5m8767_regulator_desc(LDO5),
484	s5m8767_regulator_desc(LDO6),
485	s5m8767_regulator_desc(LDO7),
486	s5m8767_regulator_desc(LDO8),
487	s5m8767_regulator_desc(LDO9),
488	s5m8767_regulator_desc(LDO10),
489	s5m8767_regulator_desc(LDO11),
490	s5m8767_regulator_desc(LDO12),
491	s5m8767_regulator_desc(LDO13),
492	s5m8767_regulator_desc(LDO14),
493	s5m8767_regulator_desc(LDO15),
494	s5m8767_regulator_desc(LDO16),
495	s5m8767_regulator_desc(LDO17),
496	s5m8767_regulator_desc(LDO18),
497	s5m8767_regulator_desc(LDO19),
498	s5m8767_regulator_desc(LDO20),
499	s5m8767_regulator_desc(LDO21),
500	s5m8767_regulator_desc(LDO22),
501	s5m8767_regulator_desc(LDO23),
502	s5m8767_regulator_desc(LDO24),
503	s5m8767_regulator_desc(LDO25),
504	s5m8767_regulator_desc(LDO26),
505	s5m8767_regulator_desc(LDO27),
506	s5m8767_regulator_desc(LDO28),
507	s5m8767_regulator_desc(BUCK1),
508	s5m8767_regulator_desc(BUCK2),
509	s5m8767_regulator_desc(BUCK3),
510	s5m8767_regulator_desc(BUCK4),
511	s5m8767_regulator_desc(BUCK5),
512	s5m8767_regulator_desc(BUCK6),
513	s5m8767_regulator_desc(BUCK7),
514	s5m8767_regulator_desc(BUCK8),
515	s5m8767_regulator_desc(BUCK9),
516};
517
518static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
519{
520	struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent);
521	struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev);
522	struct regulator_config config = { };
523	struct regulator_dev **rdev;
524	struct s5m8767_info *s5m8767;
525	int i, ret, size;
526
527	if (!pdata) {
528		dev_err(pdev->dev.parent, "Platform data not supplied\n");
529		return -ENODEV;
530	}
531
532	if (pdata->buck2_gpiodvs) {
533		if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) {
534			dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
535			return -EINVAL;
536		}
537	}
538
539	if (pdata->buck3_gpiodvs) {
540		if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) {
541			dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
542			return -EINVAL;
543		}
544	}
545
546	if (pdata->buck4_gpiodvs) {
547		if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) {
548			dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
549			return -EINVAL;
550		}
551	}
552
553	s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info),
554				GFP_KERNEL);
555	if (!s5m8767)
556		return -ENOMEM;
557
558	size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2);
559	s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
560	if (!s5m8767->rdev)
561		return -ENOMEM;
562
563	rdev = s5m8767->rdev;
564	s5m8767->dev = &pdev->dev;
565	s5m8767->iodev = iodev;
566	s5m8767->num_regulators = S5M8767_REG_MAX - 2;
567	platform_set_drvdata(pdev, s5m8767);
568
569	s5m8767->buck_gpioindex = pdata->buck_default_idx;
570	s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs;
571	s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs;
572	s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs;
573	s5m8767->buck_gpios[0] = pdata->buck_gpios[0];
574	s5m8767->buck_gpios[1] = pdata->buck_gpios[1];
575	s5m8767->buck_gpios[2] = pdata->buck_gpios[2];
576	s5m8767->ramp_delay = pdata->buck_ramp_delay;
577	s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
578	s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
579	s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
580	s5m8767->opmode = pdata->opmode;
581
582	for (i = 0; i < 8; i++) {
583		if (s5m8767->buck2_gpiodvs) {
584			s5m8767->buck2_vol[i] =
585				s5m8767_convert_voltage_to_sel(
586						&buck_voltage_val2,
587						pdata->buck2_voltage[i],
588						pdata->buck2_voltage[i] +
589						buck_voltage_val2.step);
590		}
591
592		if (s5m8767->buck3_gpiodvs) {
593			s5m8767->buck3_vol[i] =
594				s5m8767_convert_voltage_to_sel(
595						&buck_voltage_val2,
596						pdata->buck3_voltage[i],
597						pdata->buck3_voltage[i] +
598						buck_voltage_val2.step);
599		}
600
601		if (s5m8767->buck4_gpiodvs) {
602			s5m8767->buck4_vol[i] =
603				s5m8767_convert_voltage_to_sel(
604						&buck_voltage_val2,
605						pdata->buck4_voltage[i],
606						pdata->buck4_voltage[i] +
607						buck_voltage_val2.step);
608		}
609	}
610
611	if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
612		pdata->buck4_gpiodvs) {
613		if (gpio_is_valid(pdata->buck_gpios[0]) &&
614			gpio_is_valid(pdata->buck_gpios[1]) &&
615			gpio_is_valid(pdata->buck_gpios[2])) {
616			ret = gpio_request(pdata->buck_gpios[0],
617						"S5M8767 SET1");
618			if (ret == -EBUSY)
619				dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n");
620
621			ret = gpio_request(pdata->buck_gpios[1],
622					   "S5M8767 SET2");
623			if (ret == -EBUSY)
624				dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n");
625
626			ret = gpio_request(pdata->buck_gpios[2],
627					   "S5M8767 SET3");
628			if (ret == -EBUSY)
629				dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n");
630			/* SET1 GPIO */
631			gpio_direction_output(pdata->buck_gpios[0],
632					(s5m8767->buck_gpioindex >> 2) & 0x1);
633			/* SET2 GPIO */
634			gpio_direction_output(pdata->buck_gpios[1],
635					(s5m8767->buck_gpioindex >> 1) & 0x1);
636			/* SET3 GPIO */
637			gpio_direction_output(pdata->buck_gpios[2],
638					(s5m8767->buck_gpioindex >> 0) & 0x1);
639			ret = 0;
640		} else {
641			dev_err(&pdev->dev, "GPIO NOT VALID\n");
642			ret = -EINVAL;
643			return ret;
644		}
645	}
646
647	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL,
648			(pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1);
649	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL,
650			(pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1);
651	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL,
652			(pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1);
653
654	/* Initialize GPIO DVS registers */
655	for (i = 0; i < 8; i++) {
656		if (s5m8767->buck2_gpiodvs) {
657			s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i,
658					   s5m8767->buck2_vol[i]);
659		}
660
661		if (s5m8767->buck3_gpiodvs) {
662			s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i,
663					   s5m8767->buck3_vol[i]);
664		}
665
666		if (s5m8767->buck4_gpiodvs) {
667			s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i,
668					   s5m8767->buck4_vol[i]);
669		}
670	}
671	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff);
672	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff);
673	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff);
674
675	if (s5m8767->buck2_ramp)
676		s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08);
677
678	if (s5m8767->buck3_ramp)
679		s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04);
680
681	if (s5m8767->buck4_ramp)
682		s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02);
683
684	if (s5m8767->buck2_ramp || s5m8767->buck3_ramp
685		|| s5m8767->buck4_ramp) {
686		switch (s5m8767->ramp_delay) {
687		case 15:
688			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
689					0xc0, 0xf0);
690			break;
691		case 25:
692			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
693					0xd0, 0xf0);
694			break;
695		case 50:
696			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
697					0xe0, 0xf0);
698			break;
699		case 100:
700			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
701					0xf0, 0xf0);
702			break;
703		default:
704			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
705					0x90, 0xf0);
706		}
707	}
708
709	for (i = 0; i < pdata->num_regulators; i++) {
710		const struct s5m_voltage_desc *desc;
711		int id = pdata->regulators[i].id;
712
713		desc = reg_voltage_map[id];
714		if (desc)
715			regulators[id].n_voltages =
716				(desc->max - desc->min) / desc->step + 1;
717
718		config.dev = s5m8767->dev;
719		config.init_data = pdata->regulators[i].initdata;
720		config.driver_data = s5m8767;
721
722		rdev[i] = regulator_register(&regulators[id], &config);
723		if (IS_ERR(rdev[i])) {
724			ret = PTR_ERR(rdev[i]);
725			dev_err(s5m8767->dev, "regulator init failed for %d\n",
726					id);
727			rdev[i] = NULL;
728			goto err;
729		}
730	}
731
732	return 0;
733err:
734	for (i = 0; i < s5m8767->num_regulators; i++)
735		if (rdev[i])
736			regulator_unregister(rdev[i]);
737
738	return ret;
739}
740
741static int __devexit s5m8767_pmic_remove(struct platform_device *pdev)
742{
743	struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev);
744	struct regulator_dev **rdev = s5m8767->rdev;
745	int i;
746
747	for (i = 0; i < s5m8767->num_regulators; i++)
748		if (rdev[i])
749			regulator_unregister(rdev[i]);
750
751	return 0;
752}
753
754static const struct platform_device_id s5m8767_pmic_id[] = {
755	{ "s5m8767-pmic", 0},
756	{ },
757};
758MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
759
760static struct platform_driver s5m8767_pmic_driver = {
761	.driver = {
762		.name = "s5m8767-pmic",
763		.owner = THIS_MODULE,
764	},
765	.probe = s5m8767_pmic_probe,
766	.remove = __devexit_p(s5m8767_pmic_remove),
767	.id_table = s5m8767_pmic_id,
768};
769
770static int __init s5m8767_pmic_init(void)
771{
772	return platform_driver_register(&s5m8767_pmic_driver);
773}
774subsys_initcall(s5m8767_pmic_init);
775
776static void __exit s5m8767_pmic_exit(void)
777{
778	platform_driver_unregister(&s5m8767_pmic_driver);
779}
780module_exit(s5m8767_pmic_exit);
781
782/* Module information */
783MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
784MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
785MODULE_LICENSE("GPL");