xref: /openbmc/linux/drivers/regulator/max8649.c (revision 7490ca1e)
1 /*
2  * Regulators driver for Maxim max8649
3  *
4  * Copyright (C) 2009-2010 Marvell International Ltd.
5  *      Haojian Zhuang <haojian.zhuang@marvell.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/err.h>
14 #include <linux/i2c.h>
15 #include <linux/platform_device.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/slab.h>
18 #include <linux/regulator/max8649.h>
19 #include <linux/regmap.h>
20 
21 #define MAX8649_DCDC_VMIN	750000		/* uV */
22 #define MAX8649_DCDC_VMAX	1380000		/* uV */
23 #define MAX8649_DCDC_STEP	10000		/* uV */
24 #define MAX8649_VOL_MASK	0x3f
25 
26 /* Registers */
27 #define MAX8649_MODE0		0x00
28 #define MAX8649_MODE1		0x01
29 #define MAX8649_MODE2		0x02
30 #define MAX8649_MODE3		0x03
31 #define MAX8649_CONTROL		0x04
32 #define MAX8649_SYNC		0x05
33 #define MAX8649_RAMP		0x06
34 #define MAX8649_CHIP_ID1	0x08
35 #define MAX8649_CHIP_ID2	0x09
36 
37 /* Bits */
38 #define MAX8649_EN_PD		(1 << 7)
39 #define MAX8649_VID0_PD		(1 << 6)
40 #define MAX8649_VID1_PD		(1 << 5)
41 #define MAX8649_VID_MASK	(3 << 5)
42 
43 #define MAX8649_FORCE_PWM	(1 << 7)
44 #define MAX8649_SYNC_EXTCLK	(1 << 6)
45 
46 #define MAX8649_EXT_MASK	(3 << 6)
47 
48 #define MAX8649_RAMP_MASK	(7 << 5)
49 #define MAX8649_RAMP_DOWN	(1 << 1)
50 
51 struct max8649_regulator_info {
52 	struct regulator_dev	*regulator;
53 	struct device		*dev;
54 	struct regmap		*regmap;
55 
56 	int		vol_reg;
57 	unsigned	mode:2;	/* bit[1:0] = VID1, VID0 */
58 	unsigned	extclk_freq:2;
59 	unsigned	extclk:1;
60 	unsigned	ramp_timing:3;
61 	unsigned	ramp_down:1;
62 };
63 
64 /* I2C operations */
65 
66 static inline int check_range(int min_uV, int max_uV)
67 {
68 	if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX)
69 		|| (min_uV > max_uV))
70 		return -EINVAL;
71 	return 0;
72 }
73 
74 static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index)
75 {
76 	return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP);
77 }
78 
79 static int max8649_get_voltage(struct regulator_dev *rdev)
80 {
81 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
82 	unsigned int val;
83 	unsigned char data;
84 	int ret;
85 
86 	ret = regmap_read(info->regmap, info->vol_reg, &val);
87 	if (ret != 0)
88 		return ret;
89 	data = (unsigned char)val & MAX8649_VOL_MASK;
90 	return max8649_list_voltage(rdev, data);
91 }
92 
93 static int max8649_set_voltage(struct regulator_dev *rdev,
94 			       int min_uV, int max_uV, unsigned *selector)
95 {
96 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
97 	unsigned char data, mask;
98 
99 	if (check_range(min_uV, max_uV)) {
100 		dev_err(info->dev, "invalid voltage range (%d, %d) uV\n",
101 			min_uV, max_uV);
102 		return -EINVAL;
103 	}
104 	data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1)
105 		/ MAX8649_DCDC_STEP;
106 	mask = MAX8649_VOL_MASK;
107 	*selector = data & mask;
108 
109 	return regmap_update_bits(info->regmap, info->vol_reg, mask, data);
110 }
111 
112 /* EN_PD means pulldown on EN input */
113 static int max8649_enable(struct regulator_dev *rdev)
114 {
115 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
116 	return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 0);
117 }
118 
119 /*
120  * Applied internal pulldown resistor on EN input pin.
121  * If pulldown EN pin outside, it would be better.
122  */
123 static int max8649_disable(struct regulator_dev *rdev)
124 {
125 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
126 	return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD,
127 				MAX8649_EN_PD);
128 }
129 
130 static int max8649_is_enabled(struct regulator_dev *rdev)
131 {
132 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
133 	unsigned int val;
134 	int ret;
135 
136 	ret = regmap_read(info->regmap, MAX8649_CONTROL, &val);
137 	if (ret != 0)
138 		return ret;
139 	return !((unsigned char)val & MAX8649_EN_PD);
140 }
141 
142 static int max8649_enable_time(struct regulator_dev *rdev)
143 {
144 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
145 	int voltage, rate, ret;
146 	unsigned int val;
147 
148 	/* get voltage */
149 	ret = regmap_read(info->regmap, info->vol_reg, &val);
150 	if (ret != 0)
151 		return ret;
152 	val &= MAX8649_VOL_MASK;
153 	voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */
154 
155 	/* get rate */
156 	ret = regmap_read(info->regmap, MAX8649_RAMP, &val);
157 	if (ret != 0)
158 		return ret;
159 	ret = (val & MAX8649_RAMP_MASK) >> 5;
160 	rate = (32 * 1000) >> ret;	/* uV/uS */
161 
162 	return DIV_ROUND_UP(voltage, rate);
163 }
164 
165 static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
166 {
167 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
168 
169 	switch (mode) {
170 	case REGULATOR_MODE_FAST:
171 		regmap_update_bits(info->regmap, info->vol_reg, MAX8649_FORCE_PWM,
172 				   MAX8649_FORCE_PWM);
173 		break;
174 	case REGULATOR_MODE_NORMAL:
175 		regmap_update_bits(info->regmap, info->vol_reg,
176 				   MAX8649_FORCE_PWM, 0);
177 		break;
178 	default:
179 		return -EINVAL;
180 	}
181 	return 0;
182 }
183 
184 static unsigned int max8649_get_mode(struct regulator_dev *rdev)
185 {
186 	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
187 	unsigned int val;
188 	int ret;
189 
190 	ret = regmap_read(info->regmap, info->vol_reg, &val);
191 	if (ret != 0)
192 		return ret;
193 	if (val & MAX8649_FORCE_PWM)
194 		return REGULATOR_MODE_FAST;
195 	return REGULATOR_MODE_NORMAL;
196 }
197 
198 static struct regulator_ops max8649_dcdc_ops = {
199 	.set_voltage	= max8649_set_voltage,
200 	.get_voltage	= max8649_get_voltage,
201 	.list_voltage	= max8649_list_voltage,
202 	.enable		= max8649_enable,
203 	.disable	= max8649_disable,
204 	.is_enabled	= max8649_is_enabled,
205 	.enable_time	= max8649_enable_time,
206 	.set_mode	= max8649_set_mode,
207 	.get_mode	= max8649_get_mode,
208 
209 };
210 
211 static struct regulator_desc dcdc_desc = {
212 	.name		= "max8649",
213 	.ops		= &max8649_dcdc_ops,
214 	.type		= REGULATOR_VOLTAGE,
215 	.n_voltages	= 1 << 6,
216 	.owner		= THIS_MODULE,
217 };
218 
219 static struct regmap_config max8649_regmap_config = {
220 	.reg_bits = 8,
221 	.val_bits = 8,
222 };
223 
224 static int __devinit max8649_regulator_probe(struct i2c_client *client,
225 					     const struct i2c_device_id *id)
226 {
227 	struct max8649_platform_data *pdata = client->dev.platform_data;
228 	struct max8649_regulator_info *info = NULL;
229 	unsigned int val;
230 	unsigned char data;
231 	int ret;
232 
233 	info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL);
234 	if (!info) {
235 		dev_err(&client->dev, "No enough memory\n");
236 		return -ENOMEM;
237 	}
238 
239 	info->regmap = regmap_init_i2c(client, &max8649_regmap_config);
240 	if (IS_ERR(info->regmap)) {
241 		ret = PTR_ERR(info->regmap);
242 		dev_err(&client->dev, "Failed to allocate register map: %d\n", ret);
243 		goto fail;
244 	}
245 
246 	info->dev = &client->dev;
247 	i2c_set_clientdata(client, info);
248 
249 	info->mode = pdata->mode;
250 	switch (info->mode) {
251 	case 0:
252 		info->vol_reg = MAX8649_MODE0;
253 		break;
254 	case 1:
255 		info->vol_reg = MAX8649_MODE1;
256 		break;
257 	case 2:
258 		info->vol_reg = MAX8649_MODE2;
259 		break;
260 	case 3:
261 		info->vol_reg = MAX8649_MODE3;
262 		break;
263 	default:
264 		break;
265 	}
266 
267 	ret = regmap_read(info->regmap, MAX8649_CHIP_ID1, &val);
268 	if (ret != 0) {
269 		dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
270 			ret);
271 		goto out;
272 	}
273 	dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret);
274 
275 	/* enable VID0 & VID1 */
276 	regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
277 
278 	/* enable/disable external clock synchronization */
279 	info->extclk = pdata->extclk;
280 	data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0;
281 	regmap_update_bits(info->regmap, info->vol_reg, MAX8649_SYNC_EXTCLK, data);
282 	if (info->extclk) {
283 		/* set external clock frequency */
284 		info->extclk_freq = pdata->extclk_freq;
285 		regmap_update_bits(info->regmap, MAX8649_SYNC, MAX8649_EXT_MASK,
286 				   info->extclk_freq << 6);
287 	}
288 
289 	if (pdata->ramp_timing) {
290 		info->ramp_timing = pdata->ramp_timing;
291 		regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_MASK,
292 				   info->ramp_timing << 5);
293 	}
294 
295 	info->ramp_down = pdata->ramp_down;
296 	if (info->ramp_down) {
297 		regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_DOWN,
298 				   MAX8649_RAMP_DOWN);
299 	}
300 
301 	info->regulator = regulator_register(&dcdc_desc, &client->dev,
302 					     pdata->regulator, info, NULL);
303 	if (IS_ERR(info->regulator)) {
304 		dev_err(info->dev, "failed to register regulator %s\n",
305 			dcdc_desc.name);
306 		ret = PTR_ERR(info->regulator);
307 		goto out;
308 	}
309 
310 	dev_info(info->dev, "Max8649 regulator device is detected.\n");
311 	return 0;
312 out:
313 	regmap_exit(info->regmap);
314 fail:
315 	kfree(info);
316 	return ret;
317 }
318 
319 static int __devexit max8649_regulator_remove(struct i2c_client *client)
320 {
321 	struct max8649_regulator_info *info = i2c_get_clientdata(client);
322 
323 	if (info) {
324 		if (info->regulator)
325 			regulator_unregister(info->regulator);
326 		regmap_exit(info->regmap);
327 		kfree(info);
328 	}
329 
330 	return 0;
331 }
332 
333 static const struct i2c_device_id max8649_id[] = {
334 	{ "max8649", 0 },
335 	{ }
336 };
337 MODULE_DEVICE_TABLE(i2c, max8649_id);
338 
339 static struct i2c_driver max8649_driver = {
340 	.probe		= max8649_regulator_probe,
341 	.remove		= __devexit_p(max8649_regulator_remove),
342 	.driver		= {
343 		.name	= "max8649",
344 	},
345 	.id_table	= max8649_id,
346 };
347 
348 static int __init max8649_init(void)
349 {
350 	return i2c_add_driver(&max8649_driver);
351 }
352 subsys_initcall(max8649_init);
353 
354 static void __exit max8649_exit(void)
355 {
356 	i2c_del_driver(&max8649_driver);
357 }
358 module_exit(max8649_exit);
359 
360 /* Module information */
361 MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver");
362 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
363 MODULE_LICENSE("GPL");
364 
365