xref: /linux/drivers/mfd/pcf50633-core.c (revision 60e13231561b3a4c5269bfa1ef6c0569ad6f28ec)
1 /* NXP PCF50633 Power Management Unit (PMU) driver
2  *
3  * (C) 2006-2008 by Openmoko, Inc.
4  * Author: Harald Welte <laforge@openmoko.org>
5  * 	   Balaji Rao <balajirrao@openmoko.org>
6  * All rights reserved.
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  */
14 
15 #include <linux/kernel.h>
16 #include <linux/device.h>
17 #include <linux/sysfs.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/interrupt.h>
21 #include <linux/workqueue.h>
22 #include <linux/platform_device.h>
23 #include <linux/i2c.h>
24 #include <linux/pm.h>
25 #include <linux/slab.h>
26 
27 #include <linux/mfd/pcf50633/core.h>
28 
29 static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
30 {
31 	int ret;
32 
33 	ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
34 				num, data);
35 	if (ret < 0)
36 		dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
37 
38 	return ret;
39 }
40 
41 static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
42 {
43 	int ret;
44 
45 	ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
46 				num, data);
47 	if (ret < 0)
48 		dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
49 
50 	return ret;
51 
52 }
53 
54 /* Read a block of up to 32 regs  */
55 int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
56 					int nr_regs, u8 *data)
57 {
58 	int ret;
59 
60 	mutex_lock(&pcf->lock);
61 	ret = __pcf50633_read(pcf, reg, nr_regs, data);
62 	mutex_unlock(&pcf->lock);
63 
64 	return ret;
65 }
66 EXPORT_SYMBOL_GPL(pcf50633_read_block);
67 
68 /* Write a block of up to 32 regs  */
69 int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
70 					int nr_regs, u8 *data)
71 {
72 	int ret;
73 
74 	mutex_lock(&pcf->lock);
75 	ret = __pcf50633_write(pcf, reg, nr_regs, data);
76 	mutex_unlock(&pcf->lock);
77 
78 	return ret;
79 }
80 EXPORT_SYMBOL_GPL(pcf50633_write_block);
81 
82 u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
83 {
84 	u8 val;
85 
86 	mutex_lock(&pcf->lock);
87 	__pcf50633_read(pcf, reg, 1, &val);
88 	mutex_unlock(&pcf->lock);
89 
90 	return val;
91 }
92 EXPORT_SYMBOL_GPL(pcf50633_reg_read);
93 
94 int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
95 {
96 	int ret;
97 
98 	mutex_lock(&pcf->lock);
99 	ret = __pcf50633_write(pcf, reg, 1, &val);
100 	mutex_unlock(&pcf->lock);
101 
102 	return ret;
103 }
104 EXPORT_SYMBOL_GPL(pcf50633_reg_write);
105 
106 int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
107 {
108 	int ret;
109 	u8 tmp;
110 
111 	val &= mask;
112 
113 	mutex_lock(&pcf->lock);
114 	ret = __pcf50633_read(pcf, reg, 1, &tmp);
115 	if (ret < 0)
116 		goto out;
117 
118 	tmp &= ~mask;
119 	tmp |= val;
120 	ret = __pcf50633_write(pcf, reg, 1, &tmp);
121 
122 out:
123 	mutex_unlock(&pcf->lock);
124 
125 	return ret;
126 }
127 EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
128 
129 int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
130 {
131 	int ret;
132 	u8 tmp;
133 
134 	mutex_lock(&pcf->lock);
135 	ret = __pcf50633_read(pcf, reg, 1, &tmp);
136 	if (ret < 0)
137 		goto out;
138 
139 	tmp &= ~val;
140 	ret = __pcf50633_write(pcf, reg, 1, &tmp);
141 
142 out:
143 	mutex_unlock(&pcf->lock);
144 
145 	return ret;
146 }
147 EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
148 
149 /* sysfs attributes */
150 static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr,
151 			    char *buf)
152 {
153 	struct pcf50633 *pcf = dev_get_drvdata(dev);
154 	u8 dump[16];
155 	int n, n1, idx = 0;
156 	char *buf1 = buf;
157 	static u8 address_no_read[] = { /* must be ascending */
158 		PCF50633_REG_INT1,
159 		PCF50633_REG_INT2,
160 		PCF50633_REG_INT3,
161 		PCF50633_REG_INT4,
162 		PCF50633_REG_INT5,
163 		0 /* terminator */
164 	};
165 
166 	for (n = 0; n < 256; n += sizeof(dump)) {
167 		for (n1 = 0; n1 < sizeof(dump); n1++)
168 			if (n == address_no_read[idx]) {
169 				idx++;
170 				dump[n1] = 0x00;
171 			} else
172 				dump[n1] = pcf50633_reg_read(pcf, n + n1);
173 
174 		hex_dump_to_buffer(dump, sizeof(dump), 16, 1, buf1, 128, 0);
175 		buf1 += strlen(buf1);
176 		*buf1++ = '\n';
177 		*buf1 = '\0';
178 	}
179 
180 	return buf1 - buf;
181 }
182 static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL);
183 
184 static ssize_t show_resume_reason(struct device *dev,
185 				struct device_attribute *attr, char *buf)
186 {
187 	struct pcf50633 *pcf = dev_get_drvdata(dev);
188 	int n;
189 
190 	n = sprintf(buf, "%02x%02x%02x%02x%02x\n",
191 				pcf->resume_reason[0],
192 				pcf->resume_reason[1],
193 				pcf->resume_reason[2],
194 				pcf->resume_reason[3],
195 				pcf->resume_reason[4]);
196 
197 	return n;
198 }
199 static DEVICE_ATTR(resume_reason, 0400, show_resume_reason, NULL);
200 
201 static struct attribute *pcf_sysfs_entries[] = {
202 	&dev_attr_dump_regs.attr,
203 	&dev_attr_resume_reason.attr,
204 	NULL,
205 };
206 
207 static struct attribute_group pcf_attr_group = {
208 	.name	= NULL,			/* put in device directory */
209 	.attrs	= pcf_sysfs_entries,
210 };
211 
212 static void
213 pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
214 						struct platform_device **pdev)
215 {
216 	int ret;
217 
218 	*pdev = platform_device_alloc(name, -1);
219 	if (!*pdev) {
220 		dev_err(pcf->dev, "Falied to allocate %s\n", name);
221 		return;
222 	}
223 
224 	(*pdev)->dev.parent = pcf->dev;
225 
226 	ret = platform_device_add(*pdev);
227 	if (ret) {
228 		dev_err(pcf->dev, "Failed to register %s: %d\n", name, ret);
229 		platform_device_put(*pdev);
230 		*pdev = NULL;
231 	}
232 }
233 
234 #ifdef CONFIG_PM_SLEEP
235 static int pcf50633_suspend(struct device *dev)
236 {
237 	struct i2c_client *client = to_i2c_client(dev);
238 	struct pcf50633 *pcf = i2c_get_clientdata(client);
239 
240 	return pcf50633_irq_suspend(pcf);
241 }
242 
243 static int pcf50633_resume(struct device *dev)
244 {
245 	struct i2c_client *client = to_i2c_client(dev);
246 	struct pcf50633 *pcf = i2c_get_clientdata(client);
247 
248 	return pcf50633_irq_resume(pcf);
249 }
250 #endif
251 
252 static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
253 
254 static int __devinit pcf50633_probe(struct i2c_client *client,
255 				const struct i2c_device_id *ids)
256 {
257 	struct pcf50633 *pcf;
258 	struct pcf50633_platform_data *pdata = client->dev.platform_data;
259 	int i, ret;
260 	int version, variant;
261 
262 	if (!client->irq) {
263 		dev_err(&client->dev, "Missing IRQ\n");
264 		return -ENOENT;
265 	}
266 
267 	pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
268 	if (!pcf)
269 		return -ENOMEM;
270 
271 	pcf->pdata = pdata;
272 
273 	mutex_init(&pcf->lock);
274 
275 	i2c_set_clientdata(client, pcf);
276 	pcf->dev = &client->dev;
277 	pcf->i2c_client = client;
278 
279 	version = pcf50633_reg_read(pcf, 0);
280 	variant = pcf50633_reg_read(pcf, 1);
281 	if (version < 0 || variant < 0) {
282 		dev_err(pcf->dev, "Unable to probe pcf50633\n");
283 		ret = -ENODEV;
284 		goto err_free;
285 	}
286 
287 	dev_info(pcf->dev, "Probed device version %d variant %d\n",
288 							version, variant);
289 
290 	pcf50633_irq_init(pcf, client->irq);
291 
292 	/* Create sub devices */
293 	pcf50633_client_dev_register(pcf, "pcf50633-input",
294 						&pcf->input_pdev);
295 	pcf50633_client_dev_register(pcf, "pcf50633-rtc",
296 						&pcf->rtc_pdev);
297 	pcf50633_client_dev_register(pcf, "pcf50633-mbc",
298 						&pcf->mbc_pdev);
299 	pcf50633_client_dev_register(pcf, "pcf50633-adc",
300 						&pcf->adc_pdev);
301 	pcf50633_client_dev_register(pcf, "pcf50633-backlight",
302 						&pcf->bl_pdev);
303 
304 
305 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
306 		struct platform_device *pdev;
307 
308 		pdev = platform_device_alloc("pcf50633-regltr", i);
309 		if (!pdev) {
310 			dev_err(pcf->dev, "Cannot create regulator %d\n", i);
311 			continue;
312 		}
313 
314 		pdev->dev.parent = pcf->dev;
315 		platform_device_add_data(pdev, &pdata->reg_init_data[i],
316 					sizeof(pdata->reg_init_data[i]));
317 		pcf->regulator_pdev[i] = pdev;
318 
319 		platform_device_add(pdev);
320 	}
321 
322 	ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group);
323 	if (ret)
324 		dev_err(pcf->dev, "error creating sysfs entries\n");
325 
326 	if (pdata->probe_done)
327 		pdata->probe_done(pcf);
328 
329 	return 0;
330 
331 err_free:
332 	kfree(pcf);
333 
334 	return ret;
335 }
336 
337 static int __devexit pcf50633_remove(struct i2c_client *client)
338 {
339 	struct pcf50633 *pcf = i2c_get_clientdata(client);
340 	int i;
341 
342 	sysfs_remove_group(&client->dev.kobj, &pcf_attr_group);
343 	pcf50633_irq_free(pcf);
344 
345 	platform_device_unregister(pcf->input_pdev);
346 	platform_device_unregister(pcf->rtc_pdev);
347 	platform_device_unregister(pcf->mbc_pdev);
348 	platform_device_unregister(pcf->adc_pdev);
349 	platform_device_unregister(pcf->bl_pdev);
350 
351 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
352 		platform_device_unregister(pcf->regulator_pdev[i]);
353 
354 	kfree(pcf);
355 
356 	return 0;
357 }
358 
359 static const struct i2c_device_id pcf50633_id_table[] = {
360 	{"pcf50633", 0x73},
361 	{/* end of list */}
362 };
363 MODULE_DEVICE_TABLE(i2c, pcf50633_id_table);
364 
365 static struct i2c_driver pcf50633_driver = {
366 	.driver = {
367 		.name	= "pcf50633",
368 		.pm	= &pcf50633_pm,
369 	},
370 	.id_table = pcf50633_id_table,
371 	.probe = pcf50633_probe,
372 	.remove = __devexit_p(pcf50633_remove),
373 };
374 
375 static int __init pcf50633_init(void)
376 {
377 	return i2c_add_driver(&pcf50633_driver);
378 }
379 
380 static void __exit pcf50633_exit(void)
381 {
382 	i2c_del_driver(&pcf50633_driver);
383 }
384 
385 MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 PMU");
386 MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
387 MODULE_LICENSE("GPL");
388 
389 subsys_initcall(pcf50633_init);
390 module_exit(pcf50633_exit);
391