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