xref: /openbmc/linux/drivers/mfd/pcf50633-core.c (revision f5bf403a9dc944bf560f49dd029195e54fcbc41c)
1f52046b1SBalaji Rao /* NXP PCF50633 Power Management Unit (PMU) driver
2f52046b1SBalaji Rao  *
3f52046b1SBalaji Rao  * (C) 2006-2008 by Openmoko, Inc.
4f52046b1SBalaji Rao  * Author: Harald Welte <laforge@openmoko.org>
5f52046b1SBalaji Rao  * 	   Balaji Rao <balajirrao@openmoko.org>
6f52046b1SBalaji Rao  * All rights reserved.
7f52046b1SBalaji Rao  *
8f52046b1SBalaji Rao  *  This program is free software; you can redistribute  it and/or modify it
9f52046b1SBalaji Rao  *  under  the terms of  the GNU General  Public License as published by the
10f52046b1SBalaji Rao  *  Free Software Foundation;  either version 2 of the  License, or (at your
11f52046b1SBalaji Rao  *  option) any later version.
12f52046b1SBalaji Rao  *
13f52046b1SBalaji Rao  */
14f52046b1SBalaji Rao 
15f52046b1SBalaji Rao #include <linux/kernel.h>
16f52046b1SBalaji Rao #include <linux/device.h>
17f52046b1SBalaji Rao #include <linux/sysfs.h>
18f52046b1SBalaji Rao #include <linux/module.h>
19f52046b1SBalaji Rao #include <linux/types.h>
20f52046b1SBalaji Rao #include <linux/interrupt.h>
21f52046b1SBalaji Rao #include <linux/workqueue.h>
22f52046b1SBalaji Rao #include <linux/platform_device.h>
23f52046b1SBalaji Rao #include <linux/i2c.h>
24f52046b1SBalaji Rao #include <linux/irq.h>
255a0e3ad6STejun Heo #include <linux/slab.h>
26f52046b1SBalaji Rao 
27f52046b1SBalaji Rao #include <linux/mfd/pcf50633/core.h>
28f52046b1SBalaji Rao 
29f52046b1SBalaji Rao /* Two MBCS registers used during cold start */
30f52046b1SBalaji Rao #define PCF50633_REG_MBCS1		0x4b
31f52046b1SBalaji Rao #define PCF50633_REG_MBCS2		0x4c
32f52046b1SBalaji Rao #define PCF50633_MBCS1_USBPRES 		0x01
33f52046b1SBalaji Rao #define PCF50633_MBCS1_ADAPTPRES	0x01
34f52046b1SBalaji Rao 
35f52046b1SBalaji Rao static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
36f52046b1SBalaji Rao {
37f52046b1SBalaji Rao 	int ret;
38f52046b1SBalaji Rao 
39f52046b1SBalaji Rao 	ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
40f52046b1SBalaji Rao 				num, data);
41f52046b1SBalaji Rao 	if (ret < 0)
42f52046b1SBalaji Rao 		dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
43f52046b1SBalaji Rao 
44f52046b1SBalaji Rao 	return ret;
45f52046b1SBalaji Rao }
46f52046b1SBalaji Rao 
47f52046b1SBalaji Rao static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
48f52046b1SBalaji Rao {
49f52046b1SBalaji Rao 	int ret;
50f52046b1SBalaji Rao 
51f52046b1SBalaji Rao 	ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
52f52046b1SBalaji Rao 				num, data);
53f52046b1SBalaji Rao 	if (ret < 0)
54f52046b1SBalaji Rao 		dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
55f52046b1SBalaji Rao 
56f52046b1SBalaji Rao 	return ret;
57f52046b1SBalaji Rao 
58f52046b1SBalaji Rao }
59f52046b1SBalaji Rao 
60f52046b1SBalaji Rao /* Read a block of upto 32 regs  */
61f52046b1SBalaji Rao int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
62f52046b1SBalaji Rao 					int nr_regs, u8 *data)
63f52046b1SBalaji Rao {
64f52046b1SBalaji Rao 	int ret;
65f52046b1SBalaji Rao 
66f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
67f52046b1SBalaji Rao 	ret = __pcf50633_read(pcf, reg, nr_regs, data);
68f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
69f52046b1SBalaji Rao 
70f52046b1SBalaji Rao 	return ret;
71f52046b1SBalaji Rao }
72f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_read_block);
73f52046b1SBalaji Rao 
74f52046b1SBalaji Rao /* Write a block of upto 32 regs  */
75f52046b1SBalaji Rao int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
76f52046b1SBalaji Rao 					int nr_regs, u8 *data)
77f52046b1SBalaji Rao {
78f52046b1SBalaji Rao 	int ret;
79f52046b1SBalaji Rao 
80f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
81f52046b1SBalaji Rao 	ret = __pcf50633_write(pcf, reg, nr_regs, data);
82f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
83f52046b1SBalaji Rao 
84f52046b1SBalaji Rao 	return ret;
85f52046b1SBalaji Rao }
86f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_write_block);
87f52046b1SBalaji Rao 
88f52046b1SBalaji Rao u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
89f52046b1SBalaji Rao {
90f52046b1SBalaji Rao 	u8 val;
91f52046b1SBalaji Rao 
92f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
93f52046b1SBalaji Rao 	__pcf50633_read(pcf, reg, 1, &val);
94f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
95f52046b1SBalaji Rao 
96f52046b1SBalaji Rao 	return val;
97f52046b1SBalaji Rao }
98f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_reg_read);
99f52046b1SBalaji Rao 
100f52046b1SBalaji Rao int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
101f52046b1SBalaji Rao {
102f52046b1SBalaji Rao 	int ret;
103f52046b1SBalaji Rao 
104f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
105f52046b1SBalaji Rao 	ret = __pcf50633_write(pcf, reg, 1, &val);
106f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
107f52046b1SBalaji Rao 
108f52046b1SBalaji Rao 	return ret;
109f52046b1SBalaji Rao }
110f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_reg_write);
111f52046b1SBalaji Rao 
112f52046b1SBalaji Rao int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
113f52046b1SBalaji Rao {
114f52046b1SBalaji Rao 	int ret;
115f52046b1SBalaji Rao 	u8 tmp;
116f52046b1SBalaji Rao 
117f52046b1SBalaji Rao 	val &= mask;
118f52046b1SBalaji Rao 
119f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
120f52046b1SBalaji Rao 	ret = __pcf50633_read(pcf, reg, 1, &tmp);
121f52046b1SBalaji Rao 	if (ret < 0)
122f52046b1SBalaji Rao 		goto out;
123f52046b1SBalaji Rao 
124f52046b1SBalaji Rao 	tmp &= ~mask;
125f52046b1SBalaji Rao 	tmp |= val;
126f52046b1SBalaji Rao 	ret = __pcf50633_write(pcf, reg, 1, &tmp);
127f52046b1SBalaji Rao 
128f52046b1SBalaji Rao out:
129f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
130f52046b1SBalaji Rao 
131f52046b1SBalaji Rao 	return ret;
132f52046b1SBalaji Rao }
133f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
134f52046b1SBalaji Rao 
135f52046b1SBalaji Rao int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
136f52046b1SBalaji Rao {
137f52046b1SBalaji Rao 	int ret;
138f52046b1SBalaji Rao 	u8 tmp;
139f52046b1SBalaji Rao 
140f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
141f52046b1SBalaji Rao 	ret = __pcf50633_read(pcf, reg, 1, &tmp);
142f52046b1SBalaji Rao 	if (ret < 0)
143f52046b1SBalaji Rao 		goto out;
144f52046b1SBalaji Rao 
145f52046b1SBalaji Rao 	tmp &= ~val;
146f52046b1SBalaji Rao 	ret = __pcf50633_write(pcf, reg, 1, &tmp);
147f52046b1SBalaji Rao 
148f52046b1SBalaji Rao out:
149f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
150f52046b1SBalaji Rao 
151f52046b1SBalaji Rao 	return ret;
152f52046b1SBalaji Rao }
153f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
154f52046b1SBalaji Rao 
155f52046b1SBalaji Rao /* sysfs attributes */
156f52046b1SBalaji Rao static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr,
157f52046b1SBalaji Rao 			    char *buf)
158f52046b1SBalaji Rao {
159f52046b1SBalaji Rao 	struct pcf50633 *pcf = dev_get_drvdata(dev);
160f52046b1SBalaji Rao 	u8 dump[16];
161f52046b1SBalaji Rao 	int n, n1, idx = 0;
162f52046b1SBalaji Rao 	char *buf1 = buf;
163f52046b1SBalaji Rao 	static u8 address_no_read[] = { /* must be ascending */
164f52046b1SBalaji Rao 		PCF50633_REG_INT1,
165f52046b1SBalaji Rao 		PCF50633_REG_INT2,
166f52046b1SBalaji Rao 		PCF50633_REG_INT3,
167f52046b1SBalaji Rao 		PCF50633_REG_INT4,
168f52046b1SBalaji Rao 		PCF50633_REG_INT5,
169f52046b1SBalaji Rao 		0 /* terminator */
170f52046b1SBalaji Rao 	};
171f52046b1SBalaji Rao 
172f52046b1SBalaji Rao 	for (n = 0; n < 256; n += sizeof(dump)) {
173f52046b1SBalaji Rao 		for (n1 = 0; n1 < sizeof(dump); n1++)
174f52046b1SBalaji Rao 			if (n == address_no_read[idx]) {
175f52046b1SBalaji Rao 				idx++;
176f52046b1SBalaji Rao 				dump[n1] = 0x00;
177f52046b1SBalaji Rao 			} else
178f52046b1SBalaji Rao 				dump[n1] = pcf50633_reg_read(pcf, n + n1);
179f52046b1SBalaji Rao 
180f52046b1SBalaji Rao 		hex_dump_to_buffer(dump, sizeof(dump), 16, 1, buf1, 128, 0);
181f52046b1SBalaji Rao 		buf1 += strlen(buf1);
182f52046b1SBalaji Rao 		*buf1++ = '\n';
183f52046b1SBalaji Rao 		*buf1 = '\0';
184f52046b1SBalaji Rao 	}
185f52046b1SBalaji Rao 
186f52046b1SBalaji Rao 	return buf1 - buf;
187f52046b1SBalaji Rao }
188f52046b1SBalaji Rao static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL);
189f52046b1SBalaji Rao 
190f52046b1SBalaji Rao static ssize_t show_resume_reason(struct device *dev,
191f52046b1SBalaji Rao 				struct device_attribute *attr, char *buf)
192f52046b1SBalaji Rao {
193f52046b1SBalaji Rao 	struct pcf50633 *pcf = dev_get_drvdata(dev);
194f52046b1SBalaji Rao 	int n;
195f52046b1SBalaji Rao 
196f52046b1SBalaji Rao 	n = sprintf(buf, "%02x%02x%02x%02x%02x\n",
197f52046b1SBalaji Rao 				pcf->resume_reason[0],
198f52046b1SBalaji Rao 				pcf->resume_reason[1],
199f52046b1SBalaji Rao 				pcf->resume_reason[2],
200f52046b1SBalaji Rao 				pcf->resume_reason[3],
201f52046b1SBalaji Rao 				pcf->resume_reason[4]);
202f52046b1SBalaji Rao 
203f52046b1SBalaji Rao 	return n;
204f52046b1SBalaji Rao }
205f52046b1SBalaji Rao static DEVICE_ATTR(resume_reason, 0400, show_resume_reason, NULL);
206f52046b1SBalaji Rao 
207f52046b1SBalaji Rao static struct attribute *pcf_sysfs_entries[] = {
208f52046b1SBalaji Rao 	&dev_attr_dump_regs.attr,
209f52046b1SBalaji Rao 	&dev_attr_resume_reason.attr,
210f52046b1SBalaji Rao 	NULL,
211f52046b1SBalaji Rao };
212f52046b1SBalaji Rao 
213f52046b1SBalaji Rao static struct attribute_group pcf_attr_group = {
214f52046b1SBalaji Rao 	.name	= NULL,			/* put in device directory */
215f52046b1SBalaji Rao 	.attrs	= pcf_sysfs_entries,
216f52046b1SBalaji Rao };
217f52046b1SBalaji Rao 
218f52046b1SBalaji Rao int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
219f52046b1SBalaji Rao 			void (*handler) (int, void *), void *data)
220f52046b1SBalaji Rao {
221f52046b1SBalaji Rao 	if (irq < 0 || irq > PCF50633_NUM_IRQ || !handler)
222f52046b1SBalaji Rao 		return -EINVAL;
223f52046b1SBalaji Rao 
224f52046b1SBalaji Rao 	if (WARN_ON(pcf->irq_handler[irq].handler))
225f52046b1SBalaji Rao 		return -EBUSY;
226f52046b1SBalaji Rao 
227f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
228f52046b1SBalaji Rao 	pcf->irq_handler[irq].handler = handler;
229f52046b1SBalaji Rao 	pcf->irq_handler[irq].data = data;
230f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
231f52046b1SBalaji Rao 
232f52046b1SBalaji Rao 	return 0;
233f52046b1SBalaji Rao }
234f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_register_irq);
235f52046b1SBalaji Rao 
236f52046b1SBalaji Rao int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
237f52046b1SBalaji Rao {
238f52046b1SBalaji Rao 	if (irq < 0 || irq > PCF50633_NUM_IRQ)
239f52046b1SBalaji Rao 		return -EINVAL;
240f52046b1SBalaji Rao 
241f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
242f52046b1SBalaji Rao 	pcf->irq_handler[irq].handler = NULL;
243f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
244f52046b1SBalaji Rao 
245f52046b1SBalaji Rao 	return 0;
246f52046b1SBalaji Rao }
247f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_free_irq);
248f52046b1SBalaji Rao 
249f52046b1SBalaji Rao static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
250f52046b1SBalaji Rao {
251f52046b1SBalaji Rao 	u8 reg, bits, tmp;
252f52046b1SBalaji Rao 	int ret = 0, idx;
253f52046b1SBalaji Rao 
254f52046b1SBalaji Rao 	idx = irq >> 3;
255f52046b1SBalaji Rao 	reg =  PCF50633_REG_INT1M + idx;
256f52046b1SBalaji Rao 	bits = 1 << (irq & 0x07);
257f52046b1SBalaji Rao 
258f52046b1SBalaji Rao 	mutex_lock(&pcf->lock);
259f52046b1SBalaji Rao 
260f52046b1SBalaji Rao 	if (mask) {
261f52046b1SBalaji Rao 		ret = __pcf50633_read(pcf, reg, 1, &tmp);
262f52046b1SBalaji Rao 		if (ret < 0)
263f52046b1SBalaji Rao 			goto out;
264f52046b1SBalaji Rao 
265f52046b1SBalaji Rao 		tmp |= bits;
266f52046b1SBalaji Rao 
267f52046b1SBalaji Rao 		ret = __pcf50633_write(pcf, reg, 1, &tmp);
268f52046b1SBalaji Rao 		if (ret < 0)
269f52046b1SBalaji Rao 			goto out;
270f52046b1SBalaji Rao 
271f52046b1SBalaji Rao 		pcf->mask_regs[idx] &= ~bits;
272f52046b1SBalaji Rao 		pcf->mask_regs[idx] |= bits;
273f52046b1SBalaji Rao 	} else {
274f52046b1SBalaji Rao 		ret = __pcf50633_read(pcf, reg, 1, &tmp);
275f52046b1SBalaji Rao 		if (ret < 0)
276f52046b1SBalaji Rao 			goto out;
277f52046b1SBalaji Rao 
278f52046b1SBalaji Rao 		tmp &= ~bits;
279f52046b1SBalaji Rao 
280f52046b1SBalaji Rao 		ret = __pcf50633_write(pcf, reg, 1, &tmp);
281f52046b1SBalaji Rao 		if (ret < 0)
282f52046b1SBalaji Rao 			goto out;
283f52046b1SBalaji Rao 
284f52046b1SBalaji Rao 		pcf->mask_regs[idx] &= ~bits;
285f52046b1SBalaji Rao 	}
286f52046b1SBalaji Rao out:
287f52046b1SBalaji Rao 	mutex_unlock(&pcf->lock);
288f52046b1SBalaji Rao 
289f52046b1SBalaji Rao 	return ret;
290f52046b1SBalaji Rao }
291f52046b1SBalaji Rao 
292f52046b1SBalaji Rao int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
293f52046b1SBalaji Rao {
294b18fdc4bSArnaud Patard 	dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
295f52046b1SBalaji Rao 
296f52046b1SBalaji Rao 	return __pcf50633_irq_mask_set(pcf, irq, 1);
297f52046b1SBalaji Rao }
298f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
299f52046b1SBalaji Rao 
300f52046b1SBalaji Rao int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
301f52046b1SBalaji Rao {
302b18fdc4bSArnaud Patard 	dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
303f52046b1SBalaji Rao 
304f52046b1SBalaji Rao 	return __pcf50633_irq_mask_set(pcf, irq, 0);
305f52046b1SBalaji Rao }
306f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
307f52046b1SBalaji Rao 
308f52046b1SBalaji Rao int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
309f52046b1SBalaji Rao {
310f52046b1SBalaji Rao 	u8 reg, bits;
311f52046b1SBalaji Rao 
312f52046b1SBalaji Rao 	reg =  irq >> 3;
313f52046b1SBalaji Rao 	bits = 1 << (irq & 0x07);
314f52046b1SBalaji Rao 
315f52046b1SBalaji Rao 	return pcf->mask_regs[reg] & bits;
316f52046b1SBalaji Rao }
317f52046b1SBalaji Rao EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
318f52046b1SBalaji Rao 
319f52046b1SBalaji Rao static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
320f52046b1SBalaji Rao {
321f52046b1SBalaji Rao 	if (pcf->irq_handler[irq].handler)
322f52046b1SBalaji Rao 		pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
323f52046b1SBalaji Rao }
324f52046b1SBalaji Rao 
325f52046b1SBalaji Rao /* Maximum amount of time ONKEY is held before emergency action is taken */
326f52046b1SBalaji Rao #define PCF50633_ONKEY1S_TIMEOUT 8
327f52046b1SBalaji Rao 
328f52046b1SBalaji Rao static void pcf50633_irq_worker(struct work_struct *work)
329f52046b1SBalaji Rao {
330f52046b1SBalaji Rao 	struct pcf50633 *pcf;
331f52046b1SBalaji Rao 	int ret, i, j;
332f52046b1SBalaji Rao 	u8 pcf_int[5], chgstat;
333f52046b1SBalaji Rao 
334f52046b1SBalaji Rao 	pcf = container_of(work, struct pcf50633, irq_work);
335f52046b1SBalaji Rao 
336f52046b1SBalaji Rao 	/* Read the 5 INT regs in one transaction */
337f52046b1SBalaji Rao 	ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
338f52046b1SBalaji Rao 						ARRAY_SIZE(pcf_int), pcf_int);
339f52046b1SBalaji Rao 	if (ret != ARRAY_SIZE(pcf_int)) {
340f52046b1SBalaji Rao 		dev_err(pcf->dev, "Error reading INT registers\n");
341f52046b1SBalaji Rao 
342f52046b1SBalaji Rao 		/*
343f52046b1SBalaji Rao 		 * If this doesn't ACK the interrupt to the chip, we'll be
344f52046b1SBalaji Rao 		 * called once again as we're level triggered.
345f52046b1SBalaji Rao 		 */
346f52046b1SBalaji Rao 		goto out;
347f52046b1SBalaji Rao 	}
348f52046b1SBalaji Rao 
34906b1cc9cSPaul Fertser 	/* defeat 8s death from lowsys on A5 */
35006b1cc9cSPaul Fertser 	pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN,  0x04);
35106b1cc9cSPaul Fertser 
352f52046b1SBalaji Rao 	/* We immediately read the usb and adapter status. We thus make sure
353f52046b1SBalaji Rao 	 * only of USBINS/USBREM IRQ handlers are called */
354f52046b1SBalaji Rao 	if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
355f52046b1SBalaji Rao 		chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
356f52046b1SBalaji Rao 		if (chgstat & (0x3 << 4))
357f52046b1SBalaji Rao 			pcf_int[0] &= ~(1 << PCF50633_INT1_USBREM);
358f52046b1SBalaji Rao 		else
359f52046b1SBalaji Rao 			pcf_int[0] &= ~(1 << PCF50633_INT1_USBINS);
360f52046b1SBalaji Rao 	}
361f52046b1SBalaji Rao 
362f52046b1SBalaji Rao 	/* Make sure only one of ADPINS or ADPREM is set */
363f52046b1SBalaji Rao 	if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
364f52046b1SBalaji Rao 		chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
365f52046b1SBalaji Rao 		if (chgstat & (0x3 << 4))
366f52046b1SBalaji Rao 			pcf_int[0] &= ~(1 << PCF50633_INT1_ADPREM);
367f52046b1SBalaji Rao 		else
368f52046b1SBalaji Rao 			pcf_int[0] &= ~(1 << PCF50633_INT1_ADPINS);
369f52046b1SBalaji Rao 	}
370f52046b1SBalaji Rao 
371f52046b1SBalaji Rao 	dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
372f52046b1SBalaji Rao 			"INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
373f52046b1SBalaji Rao 			pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
374f52046b1SBalaji Rao 
375f52046b1SBalaji Rao 	/* Some revisions of the chip don't have a 8s standby mode on
376f52046b1SBalaji Rao 	 * ONKEY1S press. We try to manually do it in such cases. */
377f52046b1SBalaji Rao 	if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
378f52046b1SBalaji Rao 		dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
379f52046b1SBalaji Rao 							pcf->onkey1s_held);
380f52046b1SBalaji Rao 		if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
381f52046b1SBalaji Rao 			if (pcf->pdata->force_shutdown)
382f52046b1SBalaji Rao 				pcf->pdata->force_shutdown(pcf);
383f52046b1SBalaji Rao 	}
384f52046b1SBalaji Rao 
385f52046b1SBalaji Rao 	if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
386f52046b1SBalaji Rao 		dev_info(pcf->dev, "ONKEY1S held\n");
387f52046b1SBalaji Rao 		pcf->onkey1s_held = 1 ;
388f52046b1SBalaji Rao 
389f52046b1SBalaji Rao 		/* Unmask IRQ_SECOND */
390f52046b1SBalaji Rao 		pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
391f52046b1SBalaji Rao 						PCF50633_INT1_SECOND);
392f52046b1SBalaji Rao 
393f52046b1SBalaji Rao 		/* Unmask IRQ_ONKEYR */
394f52046b1SBalaji Rao 		pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
395f52046b1SBalaji Rao 						PCF50633_INT2_ONKEYR);
396f52046b1SBalaji Rao 	}
397f52046b1SBalaji Rao 
398f52046b1SBalaji Rao 	if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
399f52046b1SBalaji Rao 		pcf->onkey1s_held = 0;
400f52046b1SBalaji Rao 
401f52046b1SBalaji Rao 		/* Mask SECOND and ONKEYR interrupts */
402f52046b1SBalaji Rao 		if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
403f52046b1SBalaji Rao 			pcf50633_reg_set_bit_mask(pcf,
404f52046b1SBalaji Rao 					PCF50633_REG_INT1M,
405f52046b1SBalaji Rao 					PCF50633_INT1_SECOND,
406f52046b1SBalaji Rao 					PCF50633_INT1_SECOND);
407f52046b1SBalaji Rao 
408f52046b1SBalaji Rao 		if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
409f52046b1SBalaji Rao 			pcf50633_reg_set_bit_mask(pcf,
410f52046b1SBalaji Rao 					PCF50633_REG_INT2M,
411f52046b1SBalaji Rao 					PCF50633_INT2_ONKEYR,
412f52046b1SBalaji Rao 					PCF50633_INT2_ONKEYR);
413f52046b1SBalaji Rao 	}
414f52046b1SBalaji Rao 
415f52046b1SBalaji Rao 	/* Have we just resumed ? */
416f52046b1SBalaji Rao 	if (pcf->is_suspended) {
417f52046b1SBalaji Rao 		pcf->is_suspended = 0;
418f52046b1SBalaji Rao 
419f52046b1SBalaji Rao 		/* Set the resume reason filtering out non resumers */
420f52046b1SBalaji Rao 		for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
421f52046b1SBalaji Rao 			pcf->resume_reason[i] = pcf_int[i] &
422f52046b1SBalaji Rao 						pcf->pdata->resumers[i];
423f52046b1SBalaji Rao 
424f52046b1SBalaji Rao 		/* Make sure we don't pass on any ONKEY events to
425f52046b1SBalaji Rao 		 * userspace now */
426f52046b1SBalaji Rao 		pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
427f52046b1SBalaji Rao 	}
428f52046b1SBalaji Rao 
429f52046b1SBalaji Rao 	for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
430f52046b1SBalaji Rao 		/* Unset masked interrupts */
431f52046b1SBalaji Rao 		pcf_int[i] &= ~pcf->mask_regs[i];
432f52046b1SBalaji Rao 
433f52046b1SBalaji Rao 		for (j = 0; j < 8 ; j++)
434f52046b1SBalaji Rao 			if (pcf_int[i] & (1 << j))
435f52046b1SBalaji Rao 				pcf50633_irq_call_handler(pcf, (i * 8) + j);
436f52046b1SBalaji Rao 	}
437f52046b1SBalaji Rao 
438f52046b1SBalaji Rao out:
439f52046b1SBalaji Rao 	put_device(pcf->dev);
440f52046b1SBalaji Rao 	enable_irq(pcf->irq);
441f52046b1SBalaji Rao }
442f52046b1SBalaji Rao 
443f52046b1SBalaji Rao static irqreturn_t pcf50633_irq(int irq, void *data)
444f52046b1SBalaji Rao {
445f52046b1SBalaji Rao 	struct pcf50633 *pcf = data;
446f52046b1SBalaji Rao 
447f52046b1SBalaji Rao 	dev_dbg(pcf->dev, "pcf50633_irq\n");
448f52046b1SBalaji Rao 
449f52046b1SBalaji Rao 	get_device(pcf->dev);
450f43ab901SNelson Castillo 	disable_irq_nosync(pcf->irq);
451ed52e62eSPaul Fertser 	queue_work(pcf->work_queue, &pcf->irq_work);
452f52046b1SBalaji Rao 
453f52046b1SBalaji Rao 	return IRQ_HANDLED;
454f52046b1SBalaji Rao }
455f52046b1SBalaji Rao 
456f52046b1SBalaji Rao static void
457f52046b1SBalaji Rao pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
458f52046b1SBalaji Rao 						struct platform_device **pdev)
459f52046b1SBalaji Rao {
460f52046b1SBalaji Rao 	int ret;
461f52046b1SBalaji Rao 
462f52046b1SBalaji Rao 	*pdev = platform_device_alloc(name, -1);
463f52046b1SBalaji Rao 	if (!*pdev) {
464f52046b1SBalaji Rao 		dev_err(pcf->dev, "Falied to allocate %s\n", name);
465f52046b1SBalaji Rao 		return;
466f52046b1SBalaji Rao 	}
467f52046b1SBalaji Rao 
468f52046b1SBalaji Rao 	(*pdev)->dev.parent = pcf->dev;
469f52046b1SBalaji Rao 
470f52046b1SBalaji Rao 	ret = platform_device_add(*pdev);
471f52046b1SBalaji Rao 	if (ret) {
472f52046b1SBalaji Rao 		dev_err(pcf->dev, "Failed to register %s: %d\n", name, ret);
473f52046b1SBalaji Rao 		platform_device_put(*pdev);
474f52046b1SBalaji Rao 		*pdev = NULL;
475f52046b1SBalaji Rao 	}
476f52046b1SBalaji Rao }
477f52046b1SBalaji Rao 
478f52046b1SBalaji Rao #ifdef CONFIG_PM
47925993e4eSLars-Peter Clausen static int pcf50633_suspend(struct i2c_client *client, pm_message_t state)
480f52046b1SBalaji Rao {
481f52046b1SBalaji Rao 	struct pcf50633 *pcf;
482f52046b1SBalaji Rao 	int ret = 0, i;
483f52046b1SBalaji Rao 	u8 res[5];
484f52046b1SBalaji Rao 
48525993e4eSLars-Peter Clausen 	pcf = i2c_get_clientdata(client);
486f52046b1SBalaji Rao 
487f52046b1SBalaji Rao 	/* Make sure our interrupt handlers are not called
488f52046b1SBalaji Rao 	 * henceforth */
489f52046b1SBalaji Rao 	disable_irq(pcf->irq);
490f52046b1SBalaji Rao 
491f52046b1SBalaji Rao 	/* Make sure that any running IRQ worker has quit */
492f52046b1SBalaji Rao 	cancel_work_sync(&pcf->irq_work);
493f52046b1SBalaji Rao 
494f52046b1SBalaji Rao 	/* Save the masks */
495f52046b1SBalaji Rao 	ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
496f52046b1SBalaji Rao 				ARRAY_SIZE(pcf->suspend_irq_masks),
497f52046b1SBalaji Rao 					pcf->suspend_irq_masks);
498f52046b1SBalaji Rao 	if (ret < 0) {
499f52046b1SBalaji Rao 		dev_err(pcf->dev, "error saving irq masks\n");
500f52046b1SBalaji Rao 		goto out;
501f52046b1SBalaji Rao 	}
502f52046b1SBalaji Rao 
503f52046b1SBalaji Rao 	/* Write wakeup irq masks */
504f52046b1SBalaji Rao 	for (i = 0; i < ARRAY_SIZE(res); i++)
505f52046b1SBalaji Rao 		res[i] = ~pcf->pdata->resumers[i];
506f52046b1SBalaji Rao 
507f52046b1SBalaji Rao 	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
508f52046b1SBalaji Rao 					ARRAY_SIZE(res), &res[0]);
509f52046b1SBalaji Rao 	if (ret < 0) {
510f52046b1SBalaji Rao 		dev_err(pcf->dev, "error writing wakeup irq masks\n");
511f52046b1SBalaji Rao 		goto out;
512f52046b1SBalaji Rao 	}
513f52046b1SBalaji Rao 
514f52046b1SBalaji Rao 	pcf->is_suspended = 1;
515f52046b1SBalaji Rao 
516f52046b1SBalaji Rao out:
517f52046b1SBalaji Rao 	return ret;
518f52046b1SBalaji Rao }
519f52046b1SBalaji Rao 
52025993e4eSLars-Peter Clausen static int pcf50633_resume(struct i2c_client *client)
521f52046b1SBalaji Rao {
522f52046b1SBalaji Rao 	struct pcf50633 *pcf;
523f52046b1SBalaji Rao 	int ret;
524f52046b1SBalaji Rao 
52525993e4eSLars-Peter Clausen 	pcf = i2c_get_clientdata(client);
526f52046b1SBalaji Rao 
527f52046b1SBalaji Rao 	/* Write the saved mask registers */
528f52046b1SBalaji Rao 	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
529f52046b1SBalaji Rao 				ARRAY_SIZE(pcf->suspend_irq_masks),
530f52046b1SBalaji Rao 					pcf->suspend_irq_masks);
531f52046b1SBalaji Rao 	if (ret < 0)
532f52046b1SBalaji Rao 		dev_err(pcf->dev, "Error restoring saved suspend masks\n");
533f52046b1SBalaji Rao 
534f52046b1SBalaji Rao 	/* Restore regulators' state */
535f52046b1SBalaji Rao 
536f52046b1SBalaji Rao 
537f52046b1SBalaji Rao 	get_device(pcf->dev);
538f52046b1SBalaji Rao 
539f52046b1SBalaji Rao 	/*
540f52046b1SBalaji Rao 	 * Clear any pending interrupts and set resume reason if any.
541f52046b1SBalaji Rao 	 * This will leave with enable_irq()
542f52046b1SBalaji Rao 	 */
543f52046b1SBalaji Rao 	pcf50633_irq_worker(&pcf->irq_work);
544f52046b1SBalaji Rao 
545f52046b1SBalaji Rao 	return 0;
546f52046b1SBalaji Rao }
547f52046b1SBalaji Rao #else
548f52046b1SBalaji Rao #define pcf50633_suspend NULL
549f52046b1SBalaji Rao #define pcf50633_resume NULL
550f52046b1SBalaji Rao #endif
551f52046b1SBalaji Rao 
552f52046b1SBalaji Rao static int __devinit pcf50633_probe(struct i2c_client *client,
553f52046b1SBalaji Rao 				const struct i2c_device_id *ids)
554f52046b1SBalaji Rao {
555f52046b1SBalaji Rao 	struct pcf50633 *pcf;
556f52046b1SBalaji Rao 	struct pcf50633_platform_data *pdata = client->dev.platform_data;
55724213ae1SLars-Peter Clausen 	int i, ret;
558f52046b1SBalaji Rao 	int version, variant;
559f52046b1SBalaji Rao 
56024213ae1SLars-Peter Clausen 	if (!client->irq) {
56124213ae1SLars-Peter Clausen 		dev_err(&client->dev, "Missing IRQ\n");
56224213ae1SLars-Peter Clausen 		return -ENOENT;
56324213ae1SLars-Peter Clausen 	}
56424213ae1SLars-Peter Clausen 
565f52046b1SBalaji Rao 	pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
566f52046b1SBalaji Rao 	if (!pcf)
567f52046b1SBalaji Rao 		return -ENOMEM;
568f52046b1SBalaji Rao 
569f52046b1SBalaji Rao 	pcf->pdata = pdata;
570f52046b1SBalaji Rao 
571f52046b1SBalaji Rao 	mutex_init(&pcf->lock);
572f52046b1SBalaji Rao 
573f52046b1SBalaji Rao 	i2c_set_clientdata(client, pcf);
574f52046b1SBalaji Rao 	pcf->dev = &client->dev;
575f52046b1SBalaji Rao 	pcf->i2c_client = client;
576f52046b1SBalaji Rao 	pcf->irq = client->irq;
577ed52e62eSPaul Fertser 	pcf->work_queue = create_singlethread_workqueue("pcf50633");
578f52046b1SBalaji Rao 
57924213ae1SLars-Peter Clausen 	if (!pcf->work_queue) {
58024213ae1SLars-Peter Clausen 		dev_err(&client->dev, "Failed to alloc workqueue\n");
58124213ae1SLars-Peter Clausen 		ret = -ENOMEM;
58224213ae1SLars-Peter Clausen 		goto err_free;
58324213ae1SLars-Peter Clausen 	}
58424213ae1SLars-Peter Clausen 
585f52046b1SBalaji Rao 	INIT_WORK(&pcf->irq_work, pcf50633_irq_worker);
586f52046b1SBalaji Rao 
587f52046b1SBalaji Rao 	version = pcf50633_reg_read(pcf, 0);
588f52046b1SBalaji Rao 	variant = pcf50633_reg_read(pcf, 1);
589f52046b1SBalaji Rao 	if (version < 0 || variant < 0) {
590f52046b1SBalaji Rao 		dev_err(pcf->dev, "Unable to probe pcf50633\n");
591f52046b1SBalaji Rao 		ret = -ENODEV;
59224213ae1SLars-Peter Clausen 		goto err_destroy_workqueue;
593f52046b1SBalaji Rao 	}
594f52046b1SBalaji Rao 
595f52046b1SBalaji Rao 	dev_info(pcf->dev, "Probed device version %d variant %d\n",
596f52046b1SBalaji Rao 							version, variant);
597f52046b1SBalaji Rao 
598f52046b1SBalaji Rao 	/* Enable all interrupts except RTC SECOND */
599f52046b1SBalaji Rao 	pcf->mask_regs[0] = 0x80;
600f52046b1SBalaji Rao 	pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
601f52046b1SBalaji Rao 	pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
602f52046b1SBalaji Rao 	pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
603f52046b1SBalaji Rao 	pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
604f52046b1SBalaji Rao 	pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
605f52046b1SBalaji Rao 
60624213ae1SLars-Peter Clausen 	ret = request_irq(client->irq, pcf50633_irq,
60724213ae1SLars-Peter Clausen 					IRQF_TRIGGER_LOW, "pcf50633", pcf);
60824213ae1SLars-Peter Clausen 
60924213ae1SLars-Peter Clausen 	if (ret) {
61024213ae1SLars-Peter Clausen 		dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
61124213ae1SLars-Peter Clausen 		goto err_destroy_workqueue;
61224213ae1SLars-Peter Clausen 	}
61324213ae1SLars-Peter Clausen 
614f52046b1SBalaji Rao 	/* Create sub devices */
615f52046b1SBalaji Rao 	pcf50633_client_dev_register(pcf, "pcf50633-input",
616f52046b1SBalaji Rao 						&pcf->input_pdev);
617f52046b1SBalaji Rao 	pcf50633_client_dev_register(pcf, "pcf50633-rtc",
618f52046b1SBalaji Rao 						&pcf->rtc_pdev);
619f52046b1SBalaji Rao 	pcf50633_client_dev_register(pcf, "pcf50633-mbc",
620f52046b1SBalaji Rao 						&pcf->mbc_pdev);
621f52046b1SBalaji Rao 	pcf50633_client_dev_register(pcf, "pcf50633-adc",
622f52046b1SBalaji Rao 						&pcf->adc_pdev);
623*f5bf403aSLars-Peter Clausen 	pcf50633_client_dev_register(pcf, "pcf50633-backlight",
624*f5bf403aSLars-Peter Clausen 						&pcf->bl_pdev);
625*f5bf403aSLars-Peter Clausen 
626f52046b1SBalaji Rao 
627f52046b1SBalaji Rao 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
628f52046b1SBalaji Rao 		struct platform_device *pdev;
629f52046b1SBalaji Rao 
630f52046b1SBalaji Rao 		pdev = platform_device_alloc("pcf50633-regltr", i);
631f52046b1SBalaji Rao 		if (!pdev) {
63224213ae1SLars-Peter Clausen 			dev_err(pcf->dev, "Cannot create regulator %d\n", i);
633f52046b1SBalaji Rao 			continue;
634f52046b1SBalaji Rao 		}
635f52046b1SBalaji Rao 
636f52046b1SBalaji Rao 		pdev->dev.parent = pcf->dev;
637bbb2e496SLars-Peter Clausen 		platform_device_add_data(pdev, &pdata->reg_init_data[i],
638bbb2e496SLars-Peter Clausen 					sizeof(pdata->reg_init_data[i]));
639f52046b1SBalaji Rao 		pcf->regulator_pdev[i] = pdev;
640f52046b1SBalaji Rao 
641f52046b1SBalaji Rao 		platform_device_add(pdev);
642f52046b1SBalaji Rao 	}
643f52046b1SBalaji Rao 
644f52046b1SBalaji Rao 	if (enable_irq_wake(client->irq) < 0)
645f52046b1SBalaji Rao 		dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
646f52046b1SBalaji Rao 			"in this hardware revision", client->irq);
647f52046b1SBalaji Rao 
648f52046b1SBalaji Rao 	ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group);
649f52046b1SBalaji Rao 	if (ret)
650f52046b1SBalaji Rao 		dev_err(pcf->dev, "error creating sysfs entries\n");
651f52046b1SBalaji Rao 
652f52046b1SBalaji Rao 	if (pdata->probe_done)
653f52046b1SBalaji Rao 		pdata->probe_done(pcf);
654f52046b1SBalaji Rao 
655f52046b1SBalaji Rao 	return 0;
656f52046b1SBalaji Rao 
65724213ae1SLars-Peter Clausen err_destroy_workqueue:
658ed52e62eSPaul Fertser 	destroy_workqueue(pcf->work_queue);
65924213ae1SLars-Peter Clausen err_free:
66024213ae1SLars-Peter Clausen 	i2c_set_clientdata(client, NULL);
661f52046b1SBalaji Rao 	kfree(pcf);
66224213ae1SLars-Peter Clausen 
663f52046b1SBalaji Rao 	return ret;
664f52046b1SBalaji Rao }
665f52046b1SBalaji Rao 
666f52046b1SBalaji Rao static int __devexit pcf50633_remove(struct i2c_client *client)
667f52046b1SBalaji Rao {
668f52046b1SBalaji Rao 	struct pcf50633 *pcf = i2c_get_clientdata(client);
669f52046b1SBalaji Rao 	int i;
670f52046b1SBalaji Rao 
671f52046b1SBalaji Rao 	free_irq(pcf->irq, pcf);
672ed52e62eSPaul Fertser 	destroy_workqueue(pcf->work_queue);
673f52046b1SBalaji Rao 
674f52046b1SBalaji Rao 	platform_device_unregister(pcf->input_pdev);
675f52046b1SBalaji Rao 	platform_device_unregister(pcf->rtc_pdev);
676f52046b1SBalaji Rao 	platform_device_unregister(pcf->mbc_pdev);
677f52046b1SBalaji Rao 	platform_device_unregister(pcf->adc_pdev);
678f52046b1SBalaji Rao 
679f52046b1SBalaji Rao 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
680f52046b1SBalaji Rao 		platform_device_unregister(pcf->regulator_pdev[i]);
681f52046b1SBalaji Rao 
682f52046b1SBalaji Rao 	kfree(pcf);
683f52046b1SBalaji Rao 
684f52046b1SBalaji Rao 	return 0;
685f52046b1SBalaji Rao }
686f52046b1SBalaji Rao 
687f52046b1SBalaji Rao static struct i2c_device_id pcf50633_id_table[] = {
688f52046b1SBalaji Rao 	{"pcf50633", 0x73},
6898915e540SJean Delvare 	{/* end of list */}
690f52046b1SBalaji Rao };
691f52046b1SBalaji Rao 
692f52046b1SBalaji Rao static struct i2c_driver pcf50633_driver = {
693f52046b1SBalaji Rao 	.driver = {
694f52046b1SBalaji Rao 		.name	= "pcf50633",
695f52046b1SBalaji Rao 	},
696f52046b1SBalaji Rao 	.id_table = pcf50633_id_table,
697f52046b1SBalaji Rao 	.probe = pcf50633_probe,
698f52046b1SBalaji Rao 	.remove = __devexit_p(pcf50633_remove),
69925993e4eSLars-Peter Clausen 	.suspend = pcf50633_suspend,
70025993e4eSLars-Peter Clausen 	.resume	= pcf50633_resume,
701f52046b1SBalaji Rao };
702f52046b1SBalaji Rao 
703f52046b1SBalaji Rao static int __init pcf50633_init(void)
704f52046b1SBalaji Rao {
705f52046b1SBalaji Rao 	return i2c_add_driver(&pcf50633_driver);
706f52046b1SBalaji Rao }
707f52046b1SBalaji Rao 
708f52046b1SBalaji Rao static void __exit pcf50633_exit(void)
709f52046b1SBalaji Rao {
710f52046b1SBalaji Rao 	i2c_del_driver(&pcf50633_driver);
711f52046b1SBalaji Rao }
712f52046b1SBalaji Rao 
713f52046b1SBalaji Rao MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 PMU");
714f52046b1SBalaji Rao MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
715f52046b1SBalaji Rao MODULE_LICENSE("GPL");
716f52046b1SBalaji Rao 
7172021de87SSamuel Ortiz subsys_initcall(pcf50633_init);
718f52046b1SBalaji Rao module_exit(pcf50633_exit);
719