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