mfd: Add subdevs in max8925
[linux-2.6.git] / drivers / mfd / max8925-core.c
1 /*
2  * Base driver for Maxim MAX8925
3  *
4  * Copyright (C) 2009 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
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/i2c.h>
15 #include <linux/interrupt.h>
16 #include <linux/platform_device.h>
17 #include <linux/mfd/core.h>
18 #include <linux/mfd/max8925.h>
19
20 #define IRQ_MODE_STATUS         0
21 #define IRQ_MODE_MASK           1
22
23 static struct resource backlight_resources[] = {
24         {
25                 .name   = "max8925-backlight",
26                 .start  = MAX8925_WLED_MODE_CNTL,
27                 .end    = MAX8925_WLED_CNTL,
28                 .flags  = IORESOURCE_IO,
29         },
30 };
31
32 static struct mfd_cell backlight_devs[] = {
33         {
34                 .name           = "max8925-backlight",
35                 .num_resources  = 1,
36                 .resources      = &backlight_resources[0],
37                 .id             = -1,
38         },
39 };
40
41 static struct resource touch_resources[] = {
42         {
43                 .name   = "max8925-tsc",
44                 .start  = MAX8925_TSC_IRQ,
45                 .end    = MAX8925_ADC_RES_END,
46                 .flags  = IORESOURCE_IO,
47         },
48 };
49
50 static struct mfd_cell touch_devs[] = {
51         {
52                 .name           = "max8925-touch",
53                 .num_resources  = 1,
54                 .resources      = &touch_resources[0],
55                 .id             = -1,
56         },
57 };
58
59 #define MAX8925_REG_RESOURCE(_start, _end)      \
60 {                                               \
61         .start  = MAX8925_##_start,             \
62         .end    = MAX8925_##_end,               \
63         .flags  = IORESOURCE_IO,                \
64 }
65
66 static struct resource regulator_resources[] = {
67         MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
68         MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
69         MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
70         MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
71         MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
72         MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
73         MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
74         MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
75         MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
76         MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
77         MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
78         MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
79         MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
80         MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
81         MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
82         MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
83         MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
84         MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
85         MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
86         MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
87         MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
88         MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
89         MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
90 };
91
92 #define MAX8925_REG_DEVS(_id)                                           \
93 {                                                                       \
94         .name           = "max8925-regulator",                          \
95         .num_resources  = 1,                                            \
96         .resources      = &regulator_resources[MAX8925_ID_##_id],       \
97         .id             = MAX8925_ID_##_id,                             \
98 }
99
100 static struct mfd_cell regulator_devs[] = {
101         MAX8925_REG_DEVS(SD1),
102         MAX8925_REG_DEVS(SD2),
103         MAX8925_REG_DEVS(SD3),
104         MAX8925_REG_DEVS(LDO1),
105         MAX8925_REG_DEVS(LDO2),
106         MAX8925_REG_DEVS(LDO3),
107         MAX8925_REG_DEVS(LDO4),
108         MAX8925_REG_DEVS(LDO5),
109         MAX8925_REG_DEVS(LDO6),
110         MAX8925_REG_DEVS(LDO7),
111         MAX8925_REG_DEVS(LDO8),
112         MAX8925_REG_DEVS(LDO9),
113         MAX8925_REG_DEVS(LDO10),
114         MAX8925_REG_DEVS(LDO11),
115         MAX8925_REG_DEVS(LDO12),
116         MAX8925_REG_DEVS(LDO13),
117         MAX8925_REG_DEVS(LDO14),
118         MAX8925_REG_DEVS(LDO15),
119         MAX8925_REG_DEVS(LDO16),
120         MAX8925_REG_DEVS(LDO17),
121         MAX8925_REG_DEVS(LDO18),
122         MAX8925_REG_DEVS(LDO19),
123         MAX8925_REG_DEVS(LDO20),
124 };
125
126 static int __get_irq_offset(struct max8925_chip *chip, int irq, int mode,
127                             int *offset, int *bit)
128 {
129         if (!offset || !bit)
130                 return -EINVAL;
131
132         switch (chip->chip_id) {
133         case MAX8925_GPM:
134                 *bit = irq % BITS_PER_BYTE;
135                 if (irq < (BITS_PER_BYTE << 1)) {       /* irq = [0,15] */
136                         *offset = (mode) ? MAX8925_CHG_IRQ1_MASK
137                                 : MAX8925_CHG_IRQ1;
138                         if (irq >= BITS_PER_BYTE)
139                                 (*offset)++;
140                 } else {                                /* irq = [16,31] */
141                         *offset = (mode) ? MAX8925_ON_OFF_IRQ1_MASK
142                                 : MAX8925_ON_OFF_IRQ1;
143                         if (irq >= (BITS_PER_BYTE * 3))
144                                 (*offset)++;
145                 }
146                 break;
147         case MAX8925_ADC:
148                 *bit = irq % BITS_PER_BYTE;
149                 *offset = (mode) ? MAX8925_TSC_IRQ_MASK : MAX8925_TSC_IRQ;
150                 break;
151         default:
152                 goto out;
153         }
154         return 0;
155 out:
156         dev_err(chip->dev, "Wrong irq #%d is assigned\n", irq);
157         return -EINVAL;
158 }
159
160 static int __check_irq(int irq)
161 {
162         if ((irq < 0) || (irq >= MAX8925_NUM_IRQ))
163                 return -EINVAL;
164         return 0;
165 }
166
167 int max8925_mask_irq(struct max8925_chip *chip, int irq)
168 {
169         int offset, bit, ret;
170
171         ret = __get_irq_offset(chip, irq, IRQ_MODE_MASK, &offset, &bit);
172         if (ret < 0)
173                 return ret;
174         ret = max8925_set_bits(chip->i2c, offset, 1 << bit, 1 << bit);
175         return ret;
176 }
177
178 int max8925_unmask_irq(struct max8925_chip *chip, int irq)
179 {
180         int offset, bit, ret;
181
182         ret = __get_irq_offset(chip, irq, IRQ_MODE_MASK, &offset, &bit);
183         if (ret < 0)
184                 return ret;
185         ret = max8925_set_bits(chip->i2c, offset, 1 << bit, 0);
186         return ret;
187 }
188
189 #define INT_STATUS_NUM          (MAX8925_NUM_IRQ / BITS_PER_BYTE)
190
191 static irqreturn_t max8925_irq_thread(int irq, void *data)
192 {
193         struct max8925_chip *chip = data;
194         unsigned long irq_status[INT_STATUS_NUM];
195         unsigned char status_buf[INT_STATUS_NUM << 1];
196         int i, ret;
197
198         memset(irq_status, 0, sizeof(unsigned long) * INT_STATUS_NUM);
199
200         /* all these interrupt status registers are read-only */
201         switch (chip->chip_id) {
202         case MAX8925_GPM:
203                 ret = max8925_bulk_read(chip->i2c, MAX8925_CHG_IRQ1,
204                                         4, status_buf);
205                 if (ret < 0)
206                         goto out;
207                 ret = max8925_bulk_read(chip->i2c, MAX8925_ON_OFF_IRQ1,
208                                         2, &status_buf[4]);
209                 if (ret < 0)
210                         goto out;
211                 ret = max8925_bulk_read(chip->i2c, MAX8925_ON_OFF_IRQ2,
212                                         2, &status_buf[6]);
213                 if (ret < 0)
214                         goto out;
215                 /* clear masked interrupt status */
216                 status_buf[0] &= (~status_buf[2] & CHG_IRQ1_MASK);
217                 irq_status[0] |= status_buf[0];
218                 status_buf[1] &= (~status_buf[3] & CHG_IRQ2_MASK);
219                 irq_status[0] |= (status_buf[1] << BITS_PER_BYTE);
220                 status_buf[4] &= (~status_buf[5] & ON_OFF_IRQ1_MASK);
221                 irq_status[0] |= (status_buf[4] << (BITS_PER_BYTE * 2));
222                 status_buf[6] &= (~status_buf[7] & ON_OFF_IRQ2_MASK);
223                 irq_status[0] |= (status_buf[6] << (BITS_PER_BYTE * 3));
224                 break;
225         case MAX8925_ADC:
226                 ret = max8925_bulk_read(chip->i2c, MAX8925_TSC_IRQ,
227                                         2, status_buf);
228                 if (ret < 0)
229                         goto out;
230                 /* clear masked interrupt status */
231                 status_buf[0] &= (~status_buf[1] & TSC_IRQ_MASK);
232                 irq_status[0] |= status_buf[0];
233                 break;
234         default:
235                 goto out;
236         }
237
238         for_each_bit(i, &irq_status[0], MAX8925_NUM_IRQ) {
239                 clear_bit(i, irq_status);
240                 dev_dbg(chip->dev, "Servicing IRQ #%d in %s\n", i, chip->name);
241
242                 mutex_lock(&chip->irq_lock);
243                 if (chip->irq[i].handler)
244                         chip->irq[i].handler(i, chip->irq[i].data);
245                 else {
246                         max8925_mask_irq(chip, i);
247                         dev_err(chip->dev, "Noboday cares IRQ #%d in %s. "
248                                 "Now mask it.\n", i, chip->name);
249                 }
250                 mutex_unlock(&chip->irq_lock);
251         }
252 out:
253         return IRQ_HANDLED;
254 }
255
256 int max8925_request_irq(struct max8925_chip *chip, int irq,
257                         irq_handler_t handler, void *data)
258 {
259         if ((__check_irq(irq) < 0) || !handler)
260                 return -EINVAL;
261
262         mutex_lock(&chip->irq_lock);
263         chip->irq[irq].handler = handler;
264         chip->irq[irq].data = data;
265         mutex_unlock(&chip->irq_lock);
266         return 0;
267 }
268 EXPORT_SYMBOL(max8925_request_irq);
269
270 int max8925_free_irq(struct max8925_chip *chip, int irq)
271 {
272         if (__check_irq(irq) < 0)
273                 return -EINVAL;
274
275         mutex_lock(&chip->irq_lock);
276         chip->irq[irq].handler = NULL;
277         chip->irq[irq].data = NULL;
278         mutex_unlock(&chip->irq_lock);
279         return 0;
280 }
281 EXPORT_SYMBOL(max8925_free_irq);
282
283 static int __devinit device_gpm_init(struct max8925_chip *chip,
284                                       struct i2c_client *i2c,
285                                       struct max8925_platform_data *pdata)
286 {
287         int ret;
288
289         /* mask all IRQs */
290         ret = max8925_set_bits(i2c, MAX8925_CHG_IRQ1_MASK, 0x7, 0x7);
291         if (ret < 0)
292                 goto out;
293         ret = max8925_set_bits(i2c, MAX8925_CHG_IRQ2_MASK, 0xff, 0xff);
294         if (ret < 0)
295                 goto out;
296         ret = max8925_set_bits(i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff, 0xff);
297         if (ret < 0)
298                 goto out;
299         ret = max8925_set_bits(i2c, MAX8925_ON_OFF_IRQ2_MASK, 0x3, 0x3);
300         if (ret < 0)
301                 goto out;
302
303         chip->name = "GPM";
304         memset(chip->irq, 0, sizeof(struct max8925_irq) * MAX8925_NUM_IRQ);
305         ret = request_threaded_irq(i2c->irq, NULL, max8925_irq_thread,
306                                 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
307                                 "max8925-gpm", chip);
308         if (ret < 0) {
309                 dev_err(chip->dev, "Failed to request IRQ #%d.\n", i2c->irq);
310                 goto out;
311         }
312         chip->chip_irq = i2c->irq;
313
314         /* enable hard-reset for ONKEY power-off */
315         max8925_set_bits(i2c, MAX8925_SYSENSEL, 0x80, 0x80);
316
317         ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
318                               ARRAY_SIZE(regulator_devs),
319                               &regulator_resources[0], 0);
320         if (ret < 0) {
321                 dev_err(chip->dev, "Failed to add regulator subdev\n");
322                 goto out_irq;
323         }
324
325         if (pdata && pdata->backlight) {
326                 ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
327                                       ARRAY_SIZE(backlight_devs),
328                                       &backlight_resources[0], 0);
329                 if (ret < 0) {
330                         dev_err(chip->dev, "Failed to add backlight subdev\n");
331                         goto out_dev;
332                 }
333         }
334         return 0;
335 out_dev:
336         mfd_remove_devices(chip->dev);
337 out_irq:
338         if (chip->chip_irq)
339                 free_irq(chip->chip_irq, chip);
340 out:
341         return ret;
342 }
343
344 static int __devinit device_adc_init(struct max8925_chip *chip,
345                                      struct i2c_client *i2c,
346                                      struct max8925_platform_data *pdata)
347 {
348         int ret;
349
350         /* mask all IRQs */
351         ret = max8925_set_bits(i2c, MAX8925_TSC_IRQ_MASK, 3, 3);
352
353         chip->name = "ADC";
354         memset(chip->irq, 0, sizeof(struct max8925_irq) * MAX8925_NUM_IRQ);
355         ret = request_threaded_irq(i2c->irq, NULL, max8925_irq_thread,
356                                 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
357                                 "max8925-adc", chip);
358         if (ret < 0) {
359                 dev_err(chip->dev, "Failed to request IRQ #%d.\n", i2c->irq);
360                 goto out;
361         }
362         chip->chip_irq = i2c->irq;
363
364         if (pdata && pdata->touch) {
365                 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
366                                       ARRAY_SIZE(touch_devs),
367                                       &touch_resources[0], 0);
368                 if (ret < 0) {
369                         dev_err(chip->dev, "Failed to add touch subdev\n");
370                         goto out_irq;
371                 }
372         }
373         return 0;
374 out_irq:
375         if (chip->chip_irq)
376                 free_irq(chip->chip_irq, chip);
377 out:
378         return ret;
379 }
380
381 int __devinit max8925_device_init(struct max8925_chip *chip,
382                                   struct max8925_platform_data *pdata)
383 {
384         switch (chip->chip_id) {
385         case MAX8925_GPM:
386                 device_gpm_init(chip, chip->i2c, pdata);
387                 break;
388         case MAX8925_ADC:
389                 device_adc_init(chip, chip->i2c, pdata);
390                 break;
391         }
392         return 0;
393 }
394
395 void max8925_device_exit(struct max8925_chip *chip)
396 {
397         if (chip->chip_irq >= 0)
398                 free_irq(chip->chip_irq, chip);
399         mfd_remove_devices(chip->dev);
400 }
401
402 MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
403 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
404 MODULE_LICENSE("GPL");