Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[pandora-kernel.git] / drivers / mfd / ab5500-core.c
1 /*
2  * Copyright (C) 2007-2011 ST-Ericsson
3  * License terms: GNU General Public License (GPL) version 2
4  * Low-level core for exclusive access to the AB5500 IC on the I2C bus
5  * and some basic chip-configuration.
6  * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
7  * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
8  * Author: Mattias Wallin <mattias.wallin@stericsson.com>
9  * Author: Rickard Andersson <rickard.andersson@stericsson.com>
10  * Author: Karl Komierowski  <karl.komierowski@stericsson.com>
11  * Author: Bibek Basu <bibek.basu@stericsson.com>
12  *
13  * TODO: Event handling with irq_chip. Waiting for PRCMU fw support.
14  */
15
16 #include <linux/mutex.h>
17 #include <linux/err.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 #include <linux/device.h>
21 #include <linux/irq.h>
22 #include <linux/interrupt.h>
23 #include <linux/random.h>
24 #include <linux/mfd/ab5500/ab5500.h>
25 #include <linux/mfd/abx500.h>
26 #include <linux/list.h>
27 #include <linux/bitops.h>
28 #include <linux/spinlock.h>
29 #include <linux/mfd/core.h>
30 #include <linux/version.h>
31 #include <linux/mfd/db5500-prcmu.h>
32
33 #include "ab5500-core.h"
34 #include "ab5500-debugfs.h"
35
36 #define AB5500_NUM_EVENT_REG 23
37 #define AB5500_IT_LATCH0_REG 0x40
38 #define AB5500_IT_MASK0_REG 0x60
39
40 /*
41  * Permissible register ranges for reading and writing per device and bank.
42  *
43  * The ranges must be listed in increasing address order, and no overlaps are
44  * allowed. It is assumed that write permission implies read permission
45  * (i.e. only RO and RW permissions should be used).  Ranges with write
46  * permission must not be split up.
47  */
48
49 #define NO_RANGE {.count = 0, .range = NULL,}
50 static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = {
51         [AB5500_DEVID_USB] =  {
52                 .nbanks = 1,
53                 .bank = (struct ab5500_i2c_ranges []) {
54                         {
55                                 .bankid = AB5500_BANK_USB,
56                                 .nranges = 12,
57                                 .range = (struct ab5500_reg_range[]) {
58                                         {
59                                                 .first = 0x01,
60                                                 .last = 0x01,
61                                                 .perm = AB5500_PERM_RW,
62                                         },
63                                         {
64                                                 .first = 0x80,
65                                                 .last = 0x83,
66                                                 .perm = AB5500_PERM_RW,
67                                         },
68                                         {
69                                                 .first = 0x87,
70                                                 .last = 0x8A,
71                                                 .perm = AB5500_PERM_RW,
72                                         },
73                                         {
74                                                 .first = 0x8B,
75                                                 .last = 0x8B,
76                                                 .perm = AB5500_PERM_RO,
77                                         },
78                                         {
79                                                 .first = 0x91,
80                                                 .last = 0x92,
81                                                 .perm = AB5500_PERM_RO,
82                                         },
83                                         {
84                                                 .first = 0x93,
85                                                 .last = 0x93,
86                                                 .perm = AB5500_PERM_RW,
87                                         },
88                                         {
89                                                 .first = 0x94,
90                                                 .last = 0x94,
91                                                 .perm = AB5500_PERM_RO,
92                                         },
93                                         {
94                                                 .first = 0xA8,
95                                                 .last = 0xB0,
96                                                 .perm = AB5500_PERM_RO,
97                                         },
98                                         {
99                                                 .first = 0xB2,
100                                                 .last = 0xB2,
101                                                 .perm = AB5500_PERM_RO,
102                                         },
103                                         {
104                                                 .first = 0xB4,
105                                                 .last = 0xBC,
106                                                 .perm = AB5500_PERM_RO,
107                                         },
108                                         {
109                                                 .first = 0xBF,
110                                                 .last = 0xBF,
111                                                 .perm = AB5500_PERM_RO,
112                                         },
113                                         {
114                                                 .first = 0xC1,
115                                                 .last = 0xC5,
116                                                 .perm = AB5500_PERM_RO,
117                                         },
118                                 },
119                         },
120                 },
121         },
122         [AB5500_DEVID_ADC] =  {
123                 .nbanks = 1,
124                 .bank = (struct ab5500_i2c_ranges []) {
125                         {
126                                 .bankid = AB5500_BANK_ADC,
127                                 .nranges = 6,
128                                 .range = (struct ab5500_reg_range[]) {
129                                         {
130                                                 .first = 0x1F,
131                                                 .last = 0x22,
132                                                 .perm = AB5500_PERM_RO,
133                                         },
134                                         {
135                                                 .first = 0x23,
136                                                 .last = 0x24,
137                                                 .perm = AB5500_PERM_RW,
138                                         },
139                                         {
140                                                 .first = 0x26,
141                                                 .last = 0x2D,
142                                                 .perm = AB5500_PERM_RO,
143                                         },
144                                         {
145                                                 .first = 0x2F,
146                                                 .last = 0x34,
147                                                 .perm = AB5500_PERM_RW,
148                                         },
149                                         {
150                                                 .first = 0x37,
151                                                 .last = 0x57,
152                                                 .perm = AB5500_PERM_RW,
153                                         },
154                                         {
155                                                 .first = 0x58,
156                                                 .last = 0x58,
157                                                 .perm = AB5500_PERM_RO,
158                                         },
159                                 },
160                         },
161                 },
162         },
163         [AB5500_DEVID_LEDS] =  {
164                 .nbanks = 1,
165                 .bank = (struct ab5500_i2c_ranges []) {
166                         {
167                                 .bankid = AB5500_BANK_LED,
168                                 .nranges = 1,
169                                 .range = (struct ab5500_reg_range[]) {
170                                         {
171                                                 .first = 0x00,
172                                                 .last = 0x0C,
173                                                 .perm = AB5500_PERM_RW,
174                                         },
175                                 },
176                         },
177                 },
178         },
179         [AB5500_DEVID_VIDEO] =   {
180                 .nbanks = 1,
181                 .bank = (struct ab5500_i2c_ranges []) {
182                         {
183                                 .bankid = AB5500_BANK_VDENC,
184                                 .nranges = 12,
185                                 .range = (struct ab5500_reg_range[]) {
186                                         {
187                                                 .first = 0x00,
188                                                 .last = 0x08,
189                                                 .perm = AB5500_PERM_RW,
190                                         },
191                                         {
192                                                 .first = 0x09,
193                                                 .last = 0x09,
194                                                 .perm = AB5500_PERM_RO,
195                                         },
196                                         {
197                                                 .first = 0x0A,
198                                                 .last = 0x12,
199                                                 .perm = AB5500_PERM_RW,
200                                         },
201                                         {
202                                                 .first = 0x15,
203                                                 .last = 0x19,
204                                                 .perm = AB5500_PERM_RW,
205                                         },
206                                         {
207                                                 .first = 0x1B,
208                                                 .last = 0x21,
209                                                 .perm = AB5500_PERM_RW,
210                                         },
211                                         {
212                                                 .first = 0x27,
213                                                 .last = 0x2C,
214                                                 .perm = AB5500_PERM_RW,
215                                         },
216                                         {
217                                                 .first = 0x41,
218                                                 .last = 0x41,
219                                                 .perm = AB5500_PERM_RW,
220                                         },
221                                         {
222                                                 .first = 0x45,
223                                                 .last = 0x5B,
224                                                 .perm = AB5500_PERM_RW,
225                                         },
226                                         {
227                                                 .first = 0x5D,
228                                                 .last = 0x5D,
229                                                 .perm = AB5500_PERM_RW,
230                                         },
231                                         {
232                                                 .first = 0x69,
233                                                 .last = 0x69,
234                                                 .perm = AB5500_PERM_RW,
235                                         },
236                                         {
237                                                 .first = 0x6C,
238                                                 .last = 0x6D,
239                                                 .perm = AB5500_PERM_RW,
240                                         },
241                                         {
242                                                 .first = 0x80,
243                                                 .last = 0x81,
244                                                 .perm = AB5500_PERM_RW,
245                                         },
246                                 },
247                         },
248                 },
249         },
250         [AB5500_DEVID_REGULATORS] =   {
251                 .nbanks = 2,
252                 .bank =  (struct ab5500_i2c_ranges []) {
253                         {
254                                 .bankid = AB5500_BANK_STARTUP,
255                                 .nranges = 12,
256                                 .range = (struct ab5500_reg_range[]) {
257                                         {
258                                                 .first = 0x00,
259                                                 .last = 0x01,
260                                                 .perm = AB5500_PERM_RW,
261                                         },
262                                         {
263                                                 .first = 0x1F,
264                                                 .last = 0x1F,
265                                                 .perm = AB5500_PERM_RW,
266                                         },
267                                         {
268                                                 .first = 0x2E,
269                                                 .last = 0x2E,
270                                                 .perm = AB5500_PERM_RO,
271                                         },
272                                         {
273                                                 .first = 0x2F,
274                                                 .last = 0x30,
275                                                 .perm = AB5500_PERM_RW,
276                                         },
277                                         {
278                                                 .first = 0x50,
279                                                 .last = 0x51,
280                                                 .perm = AB5500_PERM_RW,
281                                         },
282                                         {
283                                                 .first = 0x60,
284                                                 .last = 0x61,
285                                                 .perm = AB5500_PERM_RW,
286                                         },
287                                         {
288                                                 .first = 0x66,
289                                                 .last = 0x8A,
290                                                 .perm = AB5500_PERM_RW,
291                                         },
292                                         {
293                                                 .first = 0x8C,
294                                                 .last = 0x96,
295                                                 .perm = AB5500_PERM_RW,
296                                         },
297                                         {
298                                                 .first = 0xAA,
299                                                 .last = 0xB4,
300                                                 .perm = AB5500_PERM_RW,
301                                         },
302                                         {
303                                                 .first = 0xB7,
304                                                 .last = 0xBF,
305                                                 .perm = AB5500_PERM_RW,
306                                         },
307                                         {
308                                                 .first = 0xC1,
309                                                 .last = 0xCA,
310                                                 .perm = AB5500_PERM_RW,
311                                         },
312                                         {
313                                                 .first = 0xD3,
314                                                 .last = 0xE0,
315                                                 .perm = AB5500_PERM_RW,
316                                         },
317                                 },
318                         },
319                         {
320                                 .bankid = AB5500_BANK_SIM_USBSIM,
321                                 .nranges = 1,
322                                 .range = (struct ab5500_reg_range[]) {
323                                         {
324                                                 .first = 0x13,
325                                                 .last = 0x19,
326                                                 .perm = AB5500_PERM_RW,
327                                         },
328                                 },
329                         },
330                 },
331         },
332         [AB5500_DEVID_SIM] =   {
333                 .nbanks = 1,
334                 .bank = (struct ab5500_i2c_ranges []) {
335                         {
336                                 .bankid = AB5500_BANK_SIM_USBSIM,
337                                 .nranges = 1,
338                                 .range = (struct ab5500_reg_range[]) {
339                                         {
340                                                 .first = 0x13,
341                                                 .last = 0x19,
342                                                 .perm = AB5500_PERM_RW,
343                                         },
344                                 },
345                         },
346                 },
347         },
348         [AB5500_DEVID_RTC] =   {
349                 .nbanks = 1,
350                 .bank = (struct ab5500_i2c_ranges []) {
351                         {
352                                 .bankid = AB5500_BANK_RTC,
353                                 .nranges = 2,
354                                 .range = (struct ab5500_reg_range[]) {
355                                         {
356                                                 .first = 0x00,
357                                                 .last = 0x04,
358                                                 .perm = AB5500_PERM_RW,
359                                         },
360                                         {
361                                                 .first = 0x06,
362                                                 .last = 0x0C,
363                                                 .perm = AB5500_PERM_RW,
364                                         },
365                                 },
366                         },
367                 },
368         },
369         [AB5500_DEVID_CHARGER] =   {
370                 .nbanks = 1,
371                 .bank = (struct ab5500_i2c_ranges []) {
372                         {
373                                 .bankid = AB5500_BANK_CHG,
374                                 .nranges = 2,
375                                 .range = (struct ab5500_reg_range[]) {
376                                         {
377                                                 .first = 0x11,
378                                                 .last = 0x11,
379                                                 .perm = AB5500_PERM_RO,
380                                         },
381                                         {
382                                                 .first = 0x12,
383                                                 .last = 0x1B,
384                                                 .perm = AB5500_PERM_RW,
385                                         },
386                                 },
387                         },
388                 },
389         },
390         [AB5500_DEVID_FUELGAUGE] =   {
391                 .nbanks = 1,
392                 .bank = (struct ab5500_i2c_ranges []) {
393                         {
394                                 .bankid = AB5500_BANK_FG_BATTCOM_ACC,
395                                 .nranges = 2,
396                                 .range = (struct ab5500_reg_range[]) {
397                                         {
398                                                 .first = 0x00,
399                                                 .last = 0x0B,
400                                                 .perm = AB5500_PERM_RO,
401                                         },
402                                         {
403                                                 .first = 0x0C,
404                                                 .last = 0x10,
405                                                 .perm = AB5500_PERM_RW,
406                                         },
407                                 },
408                         },
409                 },
410         },
411         [AB5500_DEVID_VIBRATOR] =   {
412                 .nbanks = 1,
413                 .bank = (struct ab5500_i2c_ranges []) {
414                         {
415                                 .bankid = AB5500_BANK_VIBRA,
416                                 .nranges = 2,
417                                 .range = (struct ab5500_reg_range[]) {
418                                         {
419                                                 .first = 0x10,
420                                                 .last = 0x13,
421                                                 .perm = AB5500_PERM_RW,
422                                         },
423                                         {
424                                                 .first = 0xFE,
425                                                 .last = 0xFE,
426                                                 .perm = AB5500_PERM_RW,
427                                         },
428                                 },
429                         },
430                 },
431         },
432         [AB5500_DEVID_CODEC] =   {
433                 .nbanks = 1,
434                 .bank = (struct ab5500_i2c_ranges []) {
435                         {
436                                 .bankid = AB5500_BANK_AUDIO_HEADSETUSB,
437                                 .nranges = 2,
438                                 .range = (struct ab5500_reg_range[]) {
439                                         {
440                                                 .first = 0x00,
441                                                 .last = 0x48,
442                                                 .perm = AB5500_PERM_RW,
443                                         },
444                                         {
445                                                 .first = 0xEB,
446                                                 .last = 0xFB,
447                                                 .perm = AB5500_PERM_RW,
448                                         },
449                                 },
450                         },
451                 },
452         },
453         [AB5500_DEVID_POWER] = {
454                 .nbanks = 2,
455                 .bank   = (struct ab5500_i2c_ranges []) {
456                         {
457                                 .bankid = AB5500_BANK_STARTUP,
458                                 .nranges = 1,
459                                 .range = (struct ab5500_reg_range[]) {
460                                         {
461                                                 .first = 0x30,
462                                                 .last = 0x30,
463                                                 .perm = AB5500_PERM_RW,
464                                         },
465                                 },
466                         },
467                         {
468                                 .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
469                                 .nranges = 1,
470                                 .range = (struct ab5500_reg_range[]) {
471                                         {
472                                                 .first = 0x01,
473                                                 .last = 0x01,
474                                                 .perm = AB5500_PERM_RW,
475                                         },
476                                 },
477                         },
478                 },
479         },
480 };
481
482 #define AB5500_IRQ(bank, bit)   ((bank) * 8 + (bit))
483
484 /* I appologize for the resource names beeing a mix of upper case
485  * and lower case but I want them to be exact as the documentation */
486 static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = {
487         [AB5500_DEVID_LEDS] = {
488                 .name = "ab5500-leds",
489                 .id = AB5500_DEVID_LEDS,
490         },
491         [AB5500_DEVID_POWER] = {
492                 .name = "ab5500-power",
493                 .id = AB5500_DEVID_POWER,
494         },
495         [AB5500_DEVID_REGULATORS] = {
496                 .name = "ab5500-regulator",
497                 .id = AB5500_DEVID_REGULATORS,
498         },
499         [AB5500_DEVID_SIM] = {
500                 .name = "ab5500-sim",
501                 .id = AB5500_DEVID_SIM,
502                 .num_resources = 1,
503                 .resources = (struct resource[]) {
504                         {
505                                 .name = "SIMOFF",
506                                 .flags = IORESOURCE_IRQ,
507                                 .start = AB5500_IRQ(2, 0), /*rising*/
508                                 .end = AB5500_IRQ(2, 1), /*falling*/
509                         },
510                 },
511         },
512         [AB5500_DEVID_RTC] = {
513                 .name = "ab5500-rtc",
514                 .id = AB5500_DEVID_RTC,
515                 .num_resources = 1,
516                 .resources = (struct resource[]) {
517                         {
518                                 .name   = "RTC_Alarm",
519                                 .flags  = IORESOURCE_IRQ,
520                                 .start  = AB5500_IRQ(1, 7),
521                                 .end    = AB5500_IRQ(1, 7),
522                         }
523                 },
524         },
525         [AB5500_DEVID_CHARGER] = {
526                 .name = "ab5500-charger",
527                 .id = AB5500_DEVID_CHARGER,
528         },
529         [AB5500_DEVID_ADC] = {
530                 .name = "ab5500-adc",
531                 .id = AB5500_DEVID_ADC,
532                 .num_resources = 10,
533                 .resources = (struct resource[]) {
534                         {
535                                 .name = "TRIGGER-0",
536                                 .flags = IORESOURCE_IRQ,
537                                 .start = AB5500_IRQ(0, 0),
538                                 .end = AB5500_IRQ(0, 0),
539                         },
540                         {
541                                 .name = "TRIGGER-1",
542                                 .flags = IORESOURCE_IRQ,
543                                 .start = AB5500_IRQ(0, 1),
544                                 .end = AB5500_IRQ(0, 1),
545                         },
546                         {
547                                 .name = "TRIGGER-2",
548                                 .flags = IORESOURCE_IRQ,
549                                 .start = AB5500_IRQ(0, 2),
550                                 .end = AB5500_IRQ(0, 2),
551                         },
552                         {
553                                 .name = "TRIGGER-3",
554                                 .flags = IORESOURCE_IRQ,
555                                 .start = AB5500_IRQ(0, 3),
556                                 .end = AB5500_IRQ(0, 3),
557                         },
558                         {
559                                 .name = "TRIGGER-4",
560                                 .flags = IORESOURCE_IRQ,
561                                 .start = AB5500_IRQ(0, 4),
562                                 .end = AB5500_IRQ(0, 4),
563                         },
564                         {
565                                 .name = "TRIGGER-5",
566                                 .flags = IORESOURCE_IRQ,
567                                 .start = AB5500_IRQ(0, 5),
568                                 .end = AB5500_IRQ(0, 5),
569                         },
570                         {
571                                 .name = "TRIGGER-6",
572                                 .flags = IORESOURCE_IRQ,
573                                 .start = AB5500_IRQ(0, 6),
574                                 .end = AB5500_IRQ(0, 6),
575                         },
576                         {
577                                 .name = "TRIGGER-7",
578                                 .flags = IORESOURCE_IRQ,
579                                 .start = AB5500_IRQ(0, 7),
580                                 .end = AB5500_IRQ(0, 7),
581                         },
582                         {
583                                 .name = "TRIGGER-VBAT",
584                                 .flags = IORESOURCE_IRQ,
585                                 .start = AB5500_IRQ(0, 8),
586                                 .end = AB5500_IRQ(0, 8),
587                         },
588                         {
589                                 .name = "TRIGGER-VBAT-TXON",
590                                 .flags = IORESOURCE_IRQ,
591                                 .start = AB5500_IRQ(0, 9),
592                                 .end = AB5500_IRQ(0, 9),
593                         },
594                 },
595         },
596         [AB5500_DEVID_FUELGAUGE] = {
597                 .name = "ab5500-fuelgauge",
598                 .id = AB5500_DEVID_FUELGAUGE,
599                 .num_resources = 6,
600                 .resources = (struct resource[]) {
601                         {
602                                 .name = "Batt_attach",
603                                 .flags = IORESOURCE_IRQ,
604                                 .start = AB5500_IRQ(7, 5),
605                                 .end = AB5500_IRQ(7, 5),
606                         },
607                         {
608                                 .name = "Batt_removal",
609                                 .flags = IORESOURCE_IRQ,
610                                 .start = AB5500_IRQ(7, 6),
611                                 .end = AB5500_IRQ(7, 6),
612                         },
613                         {
614                                 .name = "UART_framing",
615                                 .flags = IORESOURCE_IRQ,
616                                 .start = AB5500_IRQ(7, 7),
617                                 .end = AB5500_IRQ(7, 7),
618                         },
619                         {
620                                 .name = "UART_overrun",
621                                 .flags = IORESOURCE_IRQ,
622                                 .start = AB5500_IRQ(8, 0),
623                                 .end = AB5500_IRQ(8, 0),
624                         },
625                         {
626                                 .name = "UART_Rdy_RX",
627                                 .flags = IORESOURCE_IRQ,
628                                 .start = AB5500_IRQ(8, 1),
629                                 .end = AB5500_IRQ(8, 1),
630                         },
631                         {
632                                 .name = "UART_Rdy_TX",
633                                 .flags = IORESOURCE_IRQ,
634                                 .start = AB5500_IRQ(8, 2),
635                                 .end = AB5500_IRQ(8, 2),
636                         },
637                 },
638         },
639         [AB5500_DEVID_VIBRATOR] = {
640                 .name = "ab5500-vibrator",
641                 .id = AB5500_DEVID_VIBRATOR,
642         },
643         [AB5500_DEVID_CODEC] = {
644                 .name = "ab5500-codec",
645                 .id = AB5500_DEVID_CODEC,
646                 .num_resources = 3,
647                 .resources = (struct resource[]) {
648                         {
649                                 .name = "audio_spkr1_ovc",
650                                 .flags = IORESOURCE_IRQ,
651                                 .start = AB5500_IRQ(9, 5),
652                                 .end = AB5500_IRQ(9, 5),
653                         },
654                         {
655                                 .name = "audio_plllocked",
656                                 .flags = IORESOURCE_IRQ,
657                                 .start = AB5500_IRQ(9, 6),
658                                 .end = AB5500_IRQ(9, 6),
659                         },
660                         {
661                                 .name = "audio_spkr2_ovc",
662                                 .flags = IORESOURCE_IRQ,
663                                 .start = AB5500_IRQ(17, 4),
664                                 .end = AB5500_IRQ(17, 4),
665                         },
666                 },
667         },
668         [AB5500_DEVID_USB] = {
669                 .name = "ab5500-usb",
670                 .id = AB5500_DEVID_USB,
671                 .num_resources = 36,
672                 .resources = (struct resource[]) {
673                         {
674                                 .name = "Link_Update",
675                                 .flags = IORESOURCE_IRQ,
676                                 .start = AB5500_IRQ(22, 1),
677                                 .end = AB5500_IRQ(22, 1),
678                         },
679                         {
680                                 .name = "DCIO",
681                                 .flags = IORESOURCE_IRQ,
682                                 .start = AB5500_IRQ(8, 3),
683                                 .end = AB5500_IRQ(8, 4),
684                         },
685                         {
686                                 .name = "VBUS_R",
687                                 .flags = IORESOURCE_IRQ,
688                                 .start = AB5500_IRQ(8, 5),
689                                 .end = AB5500_IRQ(8, 5),
690                         },
691                         {
692                                 .name = "VBUS_F",
693                                 .flags = IORESOURCE_IRQ,
694                                 .start = AB5500_IRQ(8, 6),
695                                 .end = AB5500_IRQ(8, 6),
696                         },
697                         {
698                                 .name = "CHGstate_10_PCVBUSchg",
699                                 .flags = IORESOURCE_IRQ,
700                                 .start = AB5500_IRQ(8, 7),
701                                 .end = AB5500_IRQ(8, 7),
702                         },
703                         {
704                                 .name = "DCIOreverse_ovc",
705                                 .flags = IORESOURCE_IRQ,
706                                 .start = AB5500_IRQ(9, 0),
707                                 .end = AB5500_IRQ(9, 0),
708                         },
709                         {
710                                 .name = "USBCharDetDone",
711                                 .flags = IORESOURCE_IRQ,
712                                 .start = AB5500_IRQ(9, 1),
713                                 .end = AB5500_IRQ(9, 1),
714                         },
715                         {
716                                 .name = "DCIO_no_limit",
717                                 .flags = IORESOURCE_IRQ,
718                                 .start = AB5500_IRQ(9, 2),
719                                 .end = AB5500_IRQ(9, 2),
720                         },
721                         {
722                                 .name = "USB_suspend",
723                                 .flags = IORESOURCE_IRQ,
724                                 .start = AB5500_IRQ(9, 3),
725                                 .end = AB5500_IRQ(9, 3),
726                         },
727                         {
728                                 .name = "DCIOreverse_fwdcurrent",
729                                 .flags = IORESOURCE_IRQ,
730                                 .start = AB5500_IRQ(9, 4),
731                                 .end = AB5500_IRQ(9, 4),
732                         },
733                         {
734                                 .name = "Vbus_Imeasmax_change",
735                                 .flags = IORESOURCE_IRQ,
736                                 .start = AB5500_IRQ(9, 5),
737                                 .end = AB5500_IRQ(9, 6),
738                         },
739                         {
740                                 .name = "OVV",
741                                 .flags = IORESOURCE_IRQ,
742                                 .start = AB5500_IRQ(14, 5),
743                                 .end = AB5500_IRQ(14, 5),
744                         },
745                         {
746                                 .name = "USBcharging_NOTok",
747                                 .flags = IORESOURCE_IRQ,
748                                 .start = AB5500_IRQ(15, 3),
749                                 .end = AB5500_IRQ(15, 3),
750                         },
751                         {
752                                 .name = "usb_adp_sensoroff",
753                                 .flags = IORESOURCE_IRQ,
754                                 .start = AB5500_IRQ(15, 6),
755                                 .end = AB5500_IRQ(15, 6),
756                         },
757                         {
758                                 .name = "usb_adp_probeplug",
759                                 .flags = IORESOURCE_IRQ,
760                                 .start = AB5500_IRQ(15, 7),
761                                 .end = AB5500_IRQ(15, 7),
762                         },
763                         {
764                                 .name = "usb_adp_sinkerror",
765                                 .flags = IORESOURCE_IRQ,
766                                 .start = AB5500_IRQ(16, 0),
767                                 .end = AB5500_IRQ(16, 6),
768                         },
769                         {
770                                 .name = "usb_adp_sourceerror",
771                                 .flags = IORESOURCE_IRQ,
772                                 .start = AB5500_IRQ(16, 1),
773                                 .end = AB5500_IRQ(16, 1),
774                         },
775                         {
776                                 .name = "usb_idgnd_r",
777                                 .flags = IORESOURCE_IRQ,
778                                 .start = AB5500_IRQ(16, 2),
779                                 .end = AB5500_IRQ(16, 2),
780                         },
781                         {
782                                 .name = "usb_idgnd_f",
783                                 .flags = IORESOURCE_IRQ,
784                                 .start = AB5500_IRQ(16, 3),
785                                 .end = AB5500_IRQ(16, 3),
786                         },
787                         {
788                                 .name = "usb_iddetR1",
789                                 .flags = IORESOURCE_IRQ,
790                                 .start = AB5500_IRQ(16, 4),
791                                 .end = AB5500_IRQ(16, 5),
792                         },
793                         {
794                                 .name = "usb_iddetR2",
795                                 .flags = IORESOURCE_IRQ,
796                                 .start = AB5500_IRQ(16, 6),
797                                 .end = AB5500_IRQ(16, 7),
798                         },
799                         {
800                                 .name = "usb_iddetR3",
801                                 .flags = IORESOURCE_IRQ,
802                                 .start = AB5500_IRQ(17, 0),
803                                 .end = AB5500_IRQ(17, 1),
804                         },
805                         {
806                                 .name = "usb_iddetR4",
807                                 .flags = IORESOURCE_IRQ,
808                                 .start = AB5500_IRQ(17, 2),
809                                 .end = AB5500_IRQ(17, 3),
810                         },
811                         {
812                                 .name = "CharTempWindowOk",
813                                 .flags = IORESOURCE_IRQ,
814                                 .start = AB5500_IRQ(17, 7),
815                                 .end = AB5500_IRQ(18, 0),
816                         },
817                         {
818                                 .name = "USB_SprDetect",
819                                 .flags = IORESOURCE_IRQ,
820                                 .start = AB5500_IRQ(18, 1),
821                                 .end = AB5500_IRQ(18, 1),
822                         },
823                         {
824                                 .name = "usb_adp_probe_unplug",
825                                 .flags = IORESOURCE_IRQ,
826                                 .start = AB5500_IRQ(18, 2),
827                                 .end = AB5500_IRQ(18, 2),
828                         },
829                         {
830                                 .name = "VBUSChDrop",
831                                 .flags = IORESOURCE_IRQ,
832                                 .start = AB5500_IRQ(18, 3),
833                                 .end = AB5500_IRQ(18, 4),
834                         },
835                         {
836                                 .name = "dcio_char_rec_done",
837                                 .flags = IORESOURCE_IRQ,
838                                 .start = AB5500_IRQ(18, 5),
839                                 .end = AB5500_IRQ(18, 5),
840                         },
841                         {
842                                 .name = "Charging_stopped_by_temp",
843                                 .flags = IORESOURCE_IRQ,
844                                 .start = AB5500_IRQ(18, 6),
845                                 .end = AB5500_IRQ(18, 6),
846                         },
847                         {
848                                 .name = "CHGstate_11_SafeModeVBUS",
849                                 .flags = IORESOURCE_IRQ,
850                                 .start = AB5500_IRQ(21, 1),
851                                 .end = AB5500_IRQ(21, 2),
852                         },
853                         {
854                                 .name = "CHGstate_12_comletedVBUS",
855                                 .flags = IORESOURCE_IRQ,
856                                 .start = AB5500_IRQ(21, 2),
857                                 .end = AB5500_IRQ(21, 2),
858                         },
859                         {
860                                 .name = "CHGstate_13_completedVBUS",
861                                 .flags = IORESOURCE_IRQ,
862                                 .start = AB5500_IRQ(21, 3),
863                                 .end = AB5500_IRQ(21, 3),
864                         },
865                         {
866                                 .name = "CHGstate_14_FullChgDCIO",
867                                 .flags = IORESOURCE_IRQ,
868                                 .start = AB5500_IRQ(21, 4),
869                                 .end = AB5500_IRQ(21, 4),
870                         },
871                         {
872                                 .name = "CHGstate_15_SafeModeDCIO",
873                                 .flags = IORESOURCE_IRQ,
874                                 .start = AB5500_IRQ(21, 5),
875                                 .end = AB5500_IRQ(21, 5),
876                         },
877                         {
878                                 .name = "CHGstate_16_OFFsuspendDCIO",
879                                 .flags = IORESOURCE_IRQ,
880                                 .start = AB5500_IRQ(21, 6),
881                                 .end = AB5500_IRQ(21, 6),
882                         },
883                         {
884                                 .name = "CHGstate_17_completedDCIO",
885                                 .flags = IORESOURCE_IRQ,
886                                 .start = AB5500_IRQ(21, 7),
887                                 .end = AB5500_IRQ(21, 7),
888                         },
889                 },
890         },
891         [AB5500_DEVID_OTP] = {
892                 .name = "ab5500-otp",
893                 .id = AB5500_DEVID_OTP,
894         },
895         [AB5500_DEVID_VIDEO] = {
896                 .name = "ab5500-video",
897                 .id = AB5500_DEVID_VIDEO,
898                 .num_resources = 1,
899                 .resources = (struct resource[]) {
900                         {
901                                 .name = "plugTVdet",
902                                 .flags = IORESOURCE_IRQ,
903                                 .start = AB5500_IRQ(22, 2),
904                                 .end = AB5500_IRQ(22, 2),
905                         },
906                 },
907         },
908         [AB5500_DEVID_DBIECI] = {
909                 .name = "ab5500-dbieci",
910                 .id = AB5500_DEVID_DBIECI,
911                 .num_resources = 10,
912                 .resources = (struct resource[]) {
913                         {
914                                 .name = "COLL",
915                                 .flags = IORESOURCE_IRQ,
916                                 .start = AB5500_IRQ(14, 0),
917                                 .end = AB5500_IRQ(14, 0),
918                         },
919                         {
920                                 .name = "RESERR",
921                                 .flags = IORESOURCE_IRQ,
922                                 .start = AB5500_IRQ(14, 1),
923                                 .end = AB5500_IRQ(14, 1),
924                         },
925                         {
926                                 .name = "FRAERR",
927                                 .flags = IORESOURCE_IRQ,
928                                 .start = AB5500_IRQ(14, 2),
929                                 .end = AB5500_IRQ(14, 2),
930                         },
931                         {
932                                 .name = "COMERR",
933                                 .flags = IORESOURCE_IRQ,
934                                 .start = AB5500_IRQ(14, 3),
935                                 .end = AB5500_IRQ(14, 3),
936                         },
937                         {
938                                 .name = "BSI_indicator",
939                                 .flags = IORESOURCE_IRQ,
940                                 .start = AB5500_IRQ(14, 4),
941                                 .end = AB5500_IRQ(14, 4),
942                         },
943                         {
944                                 .name = "SPDSET",
945                                 .flags = IORESOURCE_IRQ,
946                                 .start = AB5500_IRQ(14, 6),
947                                 .end = AB5500_IRQ(14, 6),
948                         },
949                         {
950                                 .name = "DSENT",
951                                 .flags = IORESOURCE_IRQ,
952                                 .start = AB5500_IRQ(14, 7),
953                                 .end = AB5500_IRQ(14, 7),
954                         },
955                         {
956                                 .name = "DREC",
957                                 .flags = IORESOURCE_IRQ,
958                                 .start = AB5500_IRQ(15, 0),
959                                 .end = AB5500_IRQ(15, 0),
960                         },
961                         {
962                                 .name = "ACCINT",
963                                 .flags = IORESOURCE_IRQ,
964                                 .start = AB5500_IRQ(15, 1),
965                                 .end = AB5500_IRQ(15, 1),
966                         },
967                         {
968                                 .name = "NOPINT",
969                                 .flags = IORESOURCE_IRQ,
970                                 .start = AB5500_IRQ(15, 2),
971                                 .end = AB5500_IRQ(15, 2),
972                         },
973                 },
974         },
975         [AB5500_DEVID_ONSWA] = {
976                 .name = "ab5500-onswa",
977                 .id = AB5500_DEVID_ONSWA,
978                 .num_resources = 2,
979                 .resources = (struct resource[]) {
980                         {
981                                 .name   = "ONSWAn_rising",
982                                 .flags  = IORESOURCE_IRQ,
983                                 .start  = AB5500_IRQ(1, 3),
984                                 .end    = AB5500_IRQ(1, 3),
985                         },
986                         {
987                                 .name   = "ONSWAn_falling",
988                                 .flags  = IORESOURCE_IRQ,
989                                 .start  = AB5500_IRQ(1, 4),
990                                 .end    = AB5500_IRQ(1, 4),
991                         },
992                 },
993         },
994 };
995
996 /*
997  * Functionality for getting/setting register values.
998  */
999 int ab5500_get_register_interruptible_raw(struct ab5500 *ab,
1000                                           u8 bank, u8 reg,
1001                                           u8 *value)
1002 {
1003         int err;
1004
1005         if (bank >= AB5500_NUM_BANKS)
1006                 return -EINVAL;
1007
1008         err = mutex_lock_interruptible(&ab->access_mutex);
1009         if (err)
1010                 return err;
1011         err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1);
1012
1013         mutex_unlock(&ab->access_mutex);
1014         return err;
1015 }
1016
1017 static int get_register_page_interruptible(struct ab5500 *ab, u8 bank,
1018         u8 first_reg, u8 *regvals, u8 numregs)
1019 {
1020         int err;
1021
1022         if (bank >= AB5500_NUM_BANKS)
1023                 return -EINVAL;
1024
1025         err = mutex_lock_interruptible(&ab->access_mutex);
1026         if (err)
1027                 return err;
1028
1029         while (numregs) {
1030                 /* The hardware limit for get page is 4 */
1031                 u8 curnum = min_t(u8, numregs, 4u);
1032
1033                 err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr,
1034                                             first_reg, regvals, curnum);
1035                 if (err)
1036                         goto out;
1037
1038                 numregs -= curnum;
1039                 first_reg += curnum;
1040                 regvals += curnum;
1041         }
1042
1043 out:
1044         mutex_unlock(&ab->access_mutex);
1045         return err;
1046 }
1047
1048 int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank,
1049         u8 reg, u8 bitmask, u8 bitvalues)
1050 {
1051         int err = 0;
1052
1053         if (bank >= AB5500_NUM_BANKS)
1054                 return -EINVAL;
1055
1056         if (bitmask) {
1057                 u8 buf;
1058
1059                 err = mutex_lock_interruptible(&ab->access_mutex);
1060                 if (err)
1061                         return err;
1062
1063                 if (bitmask == 0xFF) /* No need to read in this case. */
1064                         buf = bitvalues;
1065                 else { /* Read and modify the register value. */
1066                         err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr,
1067                                 reg, &buf, 1);
1068                         if (err)
1069                                 return err;
1070
1071                         buf = ((~bitmask & buf) | (bitmask & bitvalues));
1072                 }
1073                 /* Write the new value. */
1074                 err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg,
1075                                              &buf, 1);
1076
1077                 mutex_unlock(&ab->access_mutex);
1078         }
1079         return err;
1080 }
1081
1082 static int
1083 set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value)
1084 {
1085         return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg,
1086                                                               0xff, value);
1087 }
1088
1089 /*
1090  * Read/write permission checking functions.
1091  */
1092 static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank)
1093 {
1094         u8 i;
1095
1096         if (devid < AB5500_NUM_DEVICES) {
1097                 for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) {
1098                         if (ab5500_bank_ranges[devid].bank[i].bankid == bank)
1099                                 return &ab5500_bank_ranges[devid].bank[i];
1100                 }
1101         }
1102         return NULL;
1103 }
1104
1105 static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg)
1106 {
1107         u8 i; /* range loop index */
1108         const struct ab5500_i2c_ranges *bankref;
1109
1110         bankref = get_bankref(devid, bank);
1111         if (bankref == NULL || last_reg < first_reg)
1112                 return false;
1113
1114         for (i = 0; i < bankref->nranges; i++) {
1115                 if (first_reg < bankref->range[i].first)
1116                         break;
1117                 if ((last_reg <= bankref->range[i].last) &&
1118                         (bankref->range[i].perm & AB5500_PERM_WR))
1119                         return true;
1120         }
1121         return false;
1122 }
1123
1124 static bool reg_write_allowed(u8 devid, u8 bank, u8 reg)
1125 {
1126         return page_write_allowed(devid, bank, reg, reg);
1127 }
1128
1129 static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg)
1130 {
1131         u8 i;
1132         const struct ab5500_i2c_ranges *bankref;
1133
1134         bankref = get_bankref(devid, bank);
1135         if (bankref == NULL || last_reg < first_reg)
1136                 return false;
1137
1138
1139         /* Find the range (if it exists in the list) that includes first_reg. */
1140         for (i = 0; i < bankref->nranges; i++) {
1141                 if (first_reg < bankref->range[i].first)
1142                         return false;
1143                 if (first_reg <= bankref->range[i].last)
1144                         break;
1145         }
1146         /* Make sure that the entire range up to and including last_reg is
1147          * readable. This may span several of the ranges in the list.
1148          */
1149         while ((i < bankref->nranges) &&
1150                 (bankref->range[i].perm & AB5500_PERM_RD)) {
1151                 if (last_reg <= bankref->range[i].last)
1152                         return true;
1153                 if ((++i >= bankref->nranges) ||
1154                         (bankref->range[i].first !=
1155                                 (bankref->range[i - 1].last + 1))) {
1156                         break;
1157                 }
1158         }
1159         return false;
1160 }
1161
1162 static bool reg_read_allowed(u8 devid, u8 bank, u8 reg)
1163 {
1164         return page_read_allowed(devid, bank, reg, reg);
1165 }
1166
1167
1168 /*
1169  * The exported register access functionality.
1170  */
1171 static int ab5500_get_chip_id(struct device *dev)
1172 {
1173         struct ab5500 *ab = dev_get_drvdata(dev->parent);
1174
1175         return (int)ab->chip_id;
1176 }
1177
1178 static int ab5500_mask_and_set_register_interruptible(struct device *dev,
1179                 u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
1180 {
1181         struct ab5500 *ab;
1182         struct platform_device *pdev = to_platform_device(dev);
1183
1184         if ((AB5500_NUM_BANKS <= bank) ||
1185                 !reg_write_allowed(pdev->id, bank, reg))
1186                 return -EINVAL;
1187
1188         ab = dev_get_drvdata(dev->parent);
1189         return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg,
1190                 bitmask, bitvalues);
1191 }
1192
1193 static int ab5500_set_register_interruptible(struct device *dev, u8 bank,
1194         u8 reg, u8 value)
1195 {
1196         return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF,
1197                 value);
1198 }
1199
1200 static int ab5500_get_register_interruptible(struct device *dev, u8 bank,
1201                 u8 reg, u8 *value)
1202 {
1203         struct ab5500 *ab;
1204         struct platform_device *pdev = to_platform_device(dev);
1205
1206         if ((AB5500_NUM_BANKS <= bank) ||
1207                 !reg_read_allowed(pdev->id, bank, reg))
1208                 return -EINVAL;
1209
1210         ab = dev_get_drvdata(dev->parent);
1211         return ab5500_get_register_interruptible_raw(ab, bank, reg, value);
1212 }
1213
1214 static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank,
1215                 u8 first_reg, u8 *regvals, u8 numregs)
1216 {
1217         struct ab5500 *ab;
1218         struct platform_device *pdev = to_platform_device(dev);
1219
1220         if ((AB5500_NUM_BANKS <= bank) ||
1221                 !page_read_allowed(pdev->id, bank,
1222                         first_reg, (first_reg + numregs - 1)))
1223                 return -EINVAL;
1224
1225         ab = dev_get_drvdata(dev->parent);
1226         return get_register_page_interruptible(ab, bank, first_reg, regvals,
1227                 numregs);
1228 }
1229
1230 static int
1231 ab5500_event_registers_startup_state_get(struct device *dev, u8 *event)
1232 {
1233         struct ab5500 *ab;
1234
1235         ab = dev_get_drvdata(dev->parent);
1236         if (!ab->startup_events_read)
1237                 return -EAGAIN; /* Try again later */
1238
1239         memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG);
1240         return 0;
1241 }
1242
1243 static struct abx500_ops ab5500_ops = {
1244         .get_chip_id = ab5500_get_chip_id,
1245         .get_register = ab5500_get_register_interruptible,
1246         .set_register = ab5500_set_register_interruptible,
1247         .get_register_page = ab5500_get_register_page_interruptible,
1248         .set_register_page = NULL,
1249         .mask_and_set_register = ab5500_mask_and_set_register_interruptible,
1250         .event_registers_startup_state_get =
1251                 ab5500_event_registers_startup_state_get,
1252         .startup_irq_enabled = NULL,
1253 };
1254
1255 /*
1256  * ab5500_setup : Basic set-up, datastructure creation/destruction
1257  *                and I2C interface.This sets up a default config
1258  *                in the AB5500 chip so that it will work as expected.
1259  * @ab :          Pointer to ab5500 structure
1260  * @settings :    Pointer to struct abx500_init_settings
1261  * @size :        Size of init data
1262  */
1263 static int __init ab5500_setup(struct ab5500 *ab,
1264         struct abx500_init_settings *settings, unsigned int size)
1265 {
1266         int err = 0;
1267         int i;
1268
1269         for (i = 0; i < size; i++) {
1270                 err = ab5500_mask_and_set_register_interruptible_raw(ab,
1271                         settings[i].bank,
1272                         settings[i].reg,
1273                         0xFF, settings[i].setting);
1274                 if (err)
1275                         goto exit_no_setup;
1276
1277                 /* If event mask register update the event mask in ab5500 */
1278                 if ((settings[i].bank == AB5500_BANK_IT) &&
1279                         (AB5500_MASK_BASE <= settings[i].reg) &&
1280                         (settings[i].reg <= AB5500_MASK_END)) {
1281                         ab->mask[settings[i].reg - AB5500_MASK_BASE] =
1282                                 settings[i].setting;
1283                 }
1284         }
1285 exit_no_setup:
1286         return err;
1287 }
1288
1289 struct ab_family_id {
1290         u8      id;
1291         char    *name;
1292 };
1293
1294 static const struct ab_family_id ids[] __initdata = {
1295         /* AB5500 */
1296         {
1297                 .id = AB5500_1_0,
1298                 .name = "1.0"
1299         },
1300         {
1301                 .id = AB5500_1_1,
1302                 .name = "1.1"
1303         },
1304         /* Terminator */
1305         {
1306                 .id = 0x00,
1307         }
1308 };
1309
1310 static int __init ab5500_probe(struct platform_device *pdev)
1311 {
1312         struct ab5500 *ab;
1313         struct ab5500_platform_data *ab5500_plf_data =
1314                 pdev->dev.platform_data;
1315         int err;
1316         int i;
1317
1318         ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL);
1319         if (!ab) {
1320                 dev_err(&pdev->dev,
1321                         "could not allocate ab5500 device\n");
1322                 return -ENOMEM;
1323         }
1324
1325         /* Initialize data structure */
1326         mutex_init(&ab->access_mutex);
1327         mutex_init(&ab->irq_lock);
1328         ab->dev = &pdev->dev;
1329
1330         platform_set_drvdata(pdev, ab);
1331
1332         /* Read chip ID register */
1333         err = ab5500_get_register_interruptible_raw(ab,
1334                                         AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
1335                                         AB5500_CHIP_ID, &ab->chip_id);
1336         if (err) {
1337                 dev_err(&pdev->dev, "could not communicate with the analog "
1338                         "baseband chip\n");
1339                 goto exit_no_detect;
1340         }
1341
1342         for (i = 0; ids[i].id != 0x0; i++) {
1343                 if (ids[i].id == ab->chip_id) {
1344                         snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1,
1345                                 "AB5500 %s", ids[i].name);
1346                         break;
1347                 }
1348         }
1349         if (ids[i].id == 0x0) {
1350                 dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n",
1351                         ab->chip_id);
1352                 dev_err(&pdev->dev, "driver not started!\n");
1353                 goto exit_no_detect;
1354         }
1355
1356         /* Clear and mask all interrupts */
1357         for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) {
1358                 u8 latchreg = AB5500_IT_LATCH0_REG + i;
1359                 u8 maskreg = AB5500_IT_MASK0_REG + i;
1360                 u8 val;
1361
1362                 ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT,
1363                                                       latchreg, &val);
1364                 set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff);
1365                 ab->mask[i] = ab->oldmask[i] = 0xff;
1366         }
1367
1368         err = abx500_register_ops(&pdev->dev, &ab5500_ops);
1369         if (err) {
1370                 dev_err(&pdev->dev, "ab5500_register ops error\n");
1371                 goto exit_no_detect;
1372         }
1373
1374         /* Set up and register the platform devices. */
1375         for (i = 0; i < AB5500_NUM_DEVICES; i++) {
1376                 ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i];
1377                 ab5500_devs[i].pdata_size =
1378                         sizeof(ab5500_plf_data->dev_data[i]);
1379         }
1380
1381         err = mfd_add_devices(&pdev->dev, 0, ab5500_devs,
1382                 ARRAY_SIZE(ab5500_devs), NULL,
1383                 ab5500_plf_data->irq.base);
1384         if (err) {
1385                 dev_err(&pdev->dev, "ab5500_mfd_add_device error\n");
1386                 goto exit_no_detect;
1387         }
1388
1389         err = ab5500_setup(ab, ab5500_plf_data->init_settings,
1390                 ab5500_plf_data->init_settings_sz);
1391         if (err) {
1392                 dev_err(&pdev->dev, "ab5500_setup error\n");
1393                 goto exit_no_detect;
1394         }
1395
1396         ab5500_setup_debugfs(ab);
1397
1398         dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]);
1399         return 0;
1400
1401 exit_no_detect:
1402         kfree(ab);
1403         return err;
1404 }
1405
1406 static int __exit ab5500_remove(struct platform_device *pdev)
1407 {
1408         struct ab5500 *ab = platform_get_drvdata(pdev);
1409
1410         ab5500_remove_debugfs();
1411         mfd_remove_devices(&pdev->dev);
1412         kfree(ab);
1413         return 0;
1414 }
1415
1416 static struct platform_driver ab5500_driver = {
1417         .driver = {
1418                 .name = "ab5500-core",
1419                 .owner = THIS_MODULE,
1420         },
1421         .remove  = __exit_p(ab5500_remove),
1422 };
1423
1424 static int __init ab5500_core_init(void)
1425 {
1426         return platform_driver_probe(&ab5500_driver, ab5500_probe);
1427 }
1428
1429 static void __exit ab5500_core_exit(void)
1430 {
1431         platform_driver_unregister(&ab5500_driver);
1432 }
1433
1434 subsys_initcall(ab5500_core_init);
1435 module_exit(ab5500_core_exit);
1436
1437 MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
1438 MODULE_DESCRIPTION("AB5500 core driver");
1439 MODULE_LICENSE("GPL");