mfd: ab5500 chip register access
[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/debugfs.h>
25 #include <linux/seq_file.h>
26 #include <linux/uaccess.h>
27 #include <linux/mfd/ab5500/ab5500.h>
28 #include <linux/mfd/abx500.h>
29 #include <linux/list.h>
30 #include <linux/bitops.h>
31 #include <linux/spinlock.h>
32 #include <linux/mfd/core.h>
33 #include <linux/version.h>
34 #include <linux/mfd/db5500-prcmu.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 /* Read/write operation values. */
41 #define AB5500_PERM_RD (0x01)
42 #define AB5500_PERM_WR (0x02)
43
44 /* Read/write permissions. */
45 #define AB5500_PERM_RO (AB5500_PERM_RD)
46 #define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR)
47
48 #define AB5500_MASK_BASE (0x60)
49 #define AB5500_MASK_END (0x79)
50 #define AB5500_CHIP_ID (0x20)
51
52 /**
53  * struct ab5500_bank
54  * @slave_addr: I2C slave_addr found in AB5500 specification
55  * @name: Documentation name of the bank. For reference
56  */
57 struct ab5500_bank {
58         u8 slave_addr;
59         const char *name;
60 };
61
62 static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = {
63         [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
64                 AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"},
65         [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
66                 AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"},
67         [AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"},
68         [AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"},
69         [AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"},
70         [AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"},
71         [AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"},
72         [AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"},
73         [AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"},
74         [AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"},
75         [AB5500_BANK_FG_BATTCOM_ACC] = {
76                 AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"},
77         [AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"},
78         [AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"},
79         [AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"},
80         [AB5500_BANK_AUDIO_HEADSETUSB] = {
81                 AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"},
82 };
83
84 /**
85  * struct ab5500_reg_range
86  * @first: the first address of the range
87  * @last: the last address of the range
88  * @perm: access permissions for the range
89  */
90 struct ab5500_reg_range {
91         u8 first;
92         u8 last;
93         u8 perm;
94 };
95
96 /**
97  * struct ab5500_i2c_ranges
98  * @count: the number of ranges in the list
99  * @range: the list of register ranges
100  */
101 struct ab5500_i2c_ranges {
102         u8 nranges;
103         u8 bankid;
104         const struct ab5500_reg_range *range;
105 };
106
107 /**
108  * struct ab5500_i2c_banks
109  * @count: the number of ranges in the list
110  * @range: the list of register ranges
111  */
112 struct ab5500_i2c_banks {
113         u8 nbanks;
114         const struct ab5500_i2c_ranges *bank;
115 };
116
117 /*
118  * Permissible register ranges for reading and writing per device and bank.
119  *
120  * The ranges must be listed in increasing address order, and no overlaps are
121  * allowed. It is assumed that write permission implies read permission
122  * (i.e. only RO and RW permissions should be used).  Ranges with write
123  * permission must not be split up.
124  */
125
126 #define NO_RANGE {.count = 0, .range = NULL,}
127 static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = {
128         [AB5500_DEVID_USB] =  {
129                 .nbanks = 1,
130                 .bank = (struct ab5500_i2c_ranges []) {
131                         {
132                                 .bankid = AB5500_BANK_USB,
133                                 .nranges = 12,
134                                 .range = (struct ab5500_reg_range[]) {
135                                         {
136                                                 .first = 0x01,
137                                                 .last = 0x01,
138                                                 .perm = AB5500_PERM_RW,
139                                         },
140                                         {
141                                                 .first = 0x80,
142                                                 .last = 0x83,
143                                                 .perm = AB5500_PERM_RW,
144                                         },
145                                         {
146                                                 .first = 0x87,
147                                                 .last = 0x8A,
148                                                 .perm = AB5500_PERM_RW,
149                                         },
150                                         {
151                                                 .first = 0x8B,
152                                                 .last = 0x8B,
153                                                 .perm = AB5500_PERM_RO,
154                                         },
155                                         {
156                                                 .first = 0x91,
157                                                 .last = 0x92,
158                                                 .perm = AB5500_PERM_RO,
159                                         },
160                                         {
161                                                 .first = 0x93,
162                                                 .last = 0x93,
163                                                 .perm = AB5500_PERM_RW,
164                                         },
165                                         {
166                                                 .first = 0x94,
167                                                 .last = 0x94,
168                                                 .perm = AB5500_PERM_RO,
169                                         },
170                                         {
171                                                 .first = 0xA8,
172                                                 .last = 0xB0,
173                                                 .perm = AB5500_PERM_RO,
174                                         },
175                                         {
176                                                 .first = 0xB2,
177                                                 .last = 0xB2,
178                                                 .perm = AB5500_PERM_RO,
179                                         },
180                                         {
181                                                 .first = 0xB4,
182                                                 .last = 0xBC,
183                                                 .perm = AB5500_PERM_RO,
184                                         },
185                                         {
186                                                 .first = 0xBF,
187                                                 .last = 0xBF,
188                                                 .perm = AB5500_PERM_RO,
189                                         },
190                                         {
191                                                 .first = 0xC1,
192                                                 .last = 0xC5,
193                                                 .perm = AB5500_PERM_RO,
194                                         },
195                                 },
196                         },
197                 },
198         },
199         [AB5500_DEVID_ADC] =  {
200                 .nbanks = 1,
201                 .bank = (struct ab5500_i2c_ranges []) {
202                         {
203                                 .bankid = AB5500_BANK_ADC,
204                                 .nranges = 6,
205                                 .range = (struct ab5500_reg_range[]) {
206                                         {
207                                                 .first = 0x1F,
208                                                 .last = 0x22,
209                                                 .perm = AB5500_PERM_RO,
210                                         },
211                                         {
212                                                 .first = 0x23,
213                                                 .last = 0x24,
214                                                 .perm = AB5500_PERM_RW,
215                                         },
216                                         {
217                                                 .first = 0x26,
218                                                 .last = 0x2D,
219                                                 .perm = AB5500_PERM_RO,
220                                         },
221                                         {
222                                                 .first = 0x2F,
223                                                 .last = 0x34,
224                                                 .perm = AB5500_PERM_RW,
225                                         },
226                                         {
227                                                 .first = 0x37,
228                                                 .last = 0x57,
229                                                 .perm = AB5500_PERM_RW,
230                                         },
231                                         {
232                                                 .first = 0x58,
233                                                 .last = 0x58,
234                                                 .perm = AB5500_PERM_RO,
235                                         },
236                                 },
237                         },
238                 },
239         },
240         [AB5500_DEVID_LEDS] =  {
241                 .nbanks = 1,
242                 .bank = (struct ab5500_i2c_ranges []) {
243                         {
244                                 .bankid = AB5500_BANK_LED,
245                                 .nranges = 1,
246                                 .range = (struct ab5500_reg_range[]) {
247                                         {
248                                                 .first = 0x00,
249                                                 .last = 0x0C,
250                                                 .perm = AB5500_PERM_RW,
251                                         },
252                                 },
253                         },
254                 },
255         },
256         [AB5500_DEVID_VIDEO] =   {
257                 .nbanks = 1,
258                 .bank = (struct ab5500_i2c_ranges []) {
259                         {
260                                 .bankid = AB5500_BANK_VDENC,
261                                 .nranges = 12,
262                                 .range = (struct ab5500_reg_range[]) {
263                                         {
264                                                 .first = 0x00,
265                                                 .last = 0x08,
266                                                 .perm = AB5500_PERM_RW,
267                                         },
268                                         {
269                                                 .first = 0x09,
270                                                 .last = 0x09,
271                                                 .perm = AB5500_PERM_RO,
272                                         },
273                                         {
274                                                 .first = 0x0A,
275                                                 .last = 0x12,
276                                                 .perm = AB5500_PERM_RW,
277                                         },
278                                         {
279                                                 .first = 0x15,
280                                                 .last = 0x19,
281                                                 .perm = AB5500_PERM_RW,
282                                         },
283                                         {
284                                                 .first = 0x1B,
285                                                 .last = 0x21,
286                                                 .perm = AB5500_PERM_RW,
287                                         },
288                                         {
289                                                 .first = 0x27,
290                                                 .last = 0x2C,
291                                                 .perm = AB5500_PERM_RW,
292                                         },
293                                         {
294                                                 .first = 0x41,
295                                                 .last = 0x41,
296                                                 .perm = AB5500_PERM_RW,
297                                         },
298                                         {
299                                                 .first = 0x45,
300                                                 .last = 0x5B,
301                                                 .perm = AB5500_PERM_RW,
302                                         },
303                                         {
304                                                 .first = 0x5D,
305                                                 .last = 0x5D,
306                                                 .perm = AB5500_PERM_RW,
307                                         },
308                                         {
309                                                 .first = 0x69,
310                                                 .last = 0x69,
311                                                 .perm = AB5500_PERM_RW,
312                                         },
313                                         {
314                                                 .first = 0x6C,
315                                                 .last = 0x6D,
316                                                 .perm = AB5500_PERM_RW,
317                                         },
318                                         {
319                                                 .first = 0x80,
320                                                 .last = 0x81,
321                                                 .perm = AB5500_PERM_RW,
322                                         },
323                                 },
324                         },
325                 },
326         },
327         [AB5500_DEVID_REGULATORS] =   {
328                 .nbanks = 2,
329                 .bank =  (struct ab5500_i2c_ranges []) {
330                         {
331                                 .bankid = AB5500_BANK_STARTUP,
332                                 .nranges = 12,
333                                 .range = (struct ab5500_reg_range[]) {
334                                         {
335                                                 .first = 0x00,
336                                                 .last = 0x01,
337                                                 .perm = AB5500_PERM_RW,
338                                         },
339                                         {
340                                                 .first = 0x1F,
341                                                 .last = 0x1F,
342                                                 .perm = AB5500_PERM_RW,
343                                         },
344                                         {
345                                                 .first = 0x2E,
346                                                 .last = 0x2E,
347                                                 .perm = AB5500_PERM_RO,
348                                         },
349                                         {
350                                                 .first = 0x2F,
351                                                 .last = 0x30,
352                                                 .perm = AB5500_PERM_RW,
353                                         },
354                                         {
355                                                 .first = 0x50,
356                                                 .last = 0x51,
357                                                 .perm = AB5500_PERM_RW,
358                                         },
359                                         {
360                                                 .first = 0x60,
361                                                 .last = 0x61,
362                                                 .perm = AB5500_PERM_RW,
363                                         },
364                                         {
365                                                 .first = 0x66,
366                                                 .last = 0x8A,
367                                                 .perm = AB5500_PERM_RW,
368                                         },
369                                         {
370                                                 .first = 0x8C,
371                                                 .last = 0x96,
372                                                 .perm = AB5500_PERM_RW,
373                                         },
374                                         {
375                                                 .first = 0xAA,
376                                                 .last = 0xB4,
377                                                 .perm = AB5500_PERM_RW,
378                                         },
379                                         {
380                                                 .first = 0xB7,
381                                                 .last = 0xBF,
382                                                 .perm = AB5500_PERM_RW,
383                                         },
384                                         {
385                                                 .first = 0xC1,
386                                                 .last = 0xCA,
387                                                 .perm = AB5500_PERM_RW,
388                                         },
389                                         {
390                                                 .first = 0xD3,
391                                                 .last = 0xE0,
392                                                 .perm = AB5500_PERM_RW,
393                                         },
394                                 },
395                         },
396                         {
397                                 .bankid = AB5500_BANK_SIM_USBSIM,
398                                 .nranges = 1,
399                                 .range = (struct ab5500_reg_range[]) {
400                                         {
401                                                 .first = 0x13,
402                                                 .last = 0x19,
403                                                 .perm = AB5500_PERM_RW,
404                                         },
405                                 },
406                         },
407                 },
408         },
409         [AB5500_DEVID_SIM] =   {
410                 .nbanks = 1,
411                 .bank = (struct ab5500_i2c_ranges []) {
412                         {
413                                 .bankid = AB5500_BANK_SIM_USBSIM,
414                                 .nranges = 1,
415                                 .range = (struct ab5500_reg_range[]) {
416                                         {
417                                                 .first = 0x13,
418                                                 .last = 0x19,
419                                                 .perm = AB5500_PERM_RW,
420                                         },
421                                 },
422                         },
423                 },
424         },
425         [AB5500_DEVID_RTC] =   {
426                 .nbanks = 1,
427                 .bank = (struct ab5500_i2c_ranges []) {
428                         {
429                                 .bankid = AB5500_BANK_RTC,
430                                 .nranges = 2,
431                                 .range = (struct ab5500_reg_range[]) {
432                                         {
433                                                 .first = 0x00,
434                                                 .last = 0x04,
435                                                 .perm = AB5500_PERM_RW,
436                                         },
437                                         {
438                                                 .first = 0x06,
439                                                 .last = 0x0C,
440                                                 .perm = AB5500_PERM_RW,
441                                         },
442                                 },
443                         },
444                 },
445         },
446         [AB5500_DEVID_CHARGER] =   {
447                 .nbanks = 1,
448                 .bank = (struct ab5500_i2c_ranges []) {
449                         {
450                                 .bankid = AB5500_BANK_CHG,
451                                 .nranges = 2,
452                                 .range = (struct ab5500_reg_range[]) {
453                                         {
454                                                 .first = 0x11,
455                                                 .last = 0x11,
456                                                 .perm = AB5500_PERM_RO,
457                                         },
458                                         {
459                                                 .first = 0x12,
460                                                 .last = 0x1B,
461                                                 .perm = AB5500_PERM_RW,
462                                         },
463                                 },
464                         },
465                 },
466         },
467         [AB5500_DEVID_FUELGAUGE] =   {
468                 .nbanks = 1,
469                 .bank = (struct ab5500_i2c_ranges []) {
470                         {
471                                 .bankid = AB5500_BANK_FG_BATTCOM_ACC,
472                                 .nranges = 2,
473                                 .range = (struct ab5500_reg_range[]) {
474                                         {
475                                                 .first = 0x00,
476                                                 .last = 0x0B,
477                                                 .perm = AB5500_PERM_RO,
478                                         },
479                                         {
480                                                 .first = 0x0C,
481                                                 .last = 0x10,
482                                                 .perm = AB5500_PERM_RW,
483                                         },
484                                 },
485                         },
486                 },
487         },
488         [AB5500_DEVID_VIBRATOR] =   {
489                 .nbanks = 1,
490                 .bank = (struct ab5500_i2c_ranges []) {
491                         {
492                                 .bankid = AB5500_BANK_VIBRA,
493                                 .nranges = 2,
494                                 .range = (struct ab5500_reg_range[]) {
495                                         {
496                                                 .first = 0x10,
497                                                 .last = 0x13,
498                                                 .perm = AB5500_PERM_RW,
499                                         },
500                                         {
501                                                 .first = 0xFE,
502                                                 .last = 0xFE,
503                                                 .perm = AB5500_PERM_RW,
504                                         },
505                                 },
506                         },
507                 },
508         },
509         [AB5500_DEVID_CODEC] =   {
510                 .nbanks = 1,
511                 .bank = (struct ab5500_i2c_ranges []) {
512                         {
513                                 .bankid = AB5500_BANK_AUDIO_HEADSETUSB,
514                                 .nranges = 2,
515                                 .range = (struct ab5500_reg_range[]) {
516                                         {
517                                                 .first = 0x00,
518                                                 .last = 0x48,
519                                                 .perm = AB5500_PERM_RW,
520                                         },
521                                         {
522                                                 .first = 0xEB,
523                                                 .last = 0xFB,
524                                                 .perm = AB5500_PERM_RW,
525                                         },
526                                 },
527                         },
528                 },
529         },
530         [AB5500_DEVID_POWER] = {
531                 .nbanks = 2,
532                 .bank   = (struct ab5500_i2c_ranges []) {
533                         {
534                                 .bankid = AB5500_BANK_STARTUP,
535                                 .nranges = 1,
536                                 .range = (struct ab5500_reg_range[]) {
537                                         {
538                                                 .first = 0x30,
539                                                 .last = 0x30,
540                                                 .perm = AB5500_PERM_RW,
541                                         },
542                                 },
543                         },
544                         {
545                                 .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
546                                 .nranges = 1,
547                                 .range = (struct ab5500_reg_range[]) {
548                                         {
549                                                 .first = 0x01,
550                                                 .last = 0x01,
551                                                 .perm = AB5500_PERM_RW,
552                                         },
553                                 },
554                         },
555                 },
556         },
557 };
558
559 #define AB5500_IRQ(bank, bit)   ((bank) * 8 + (bit))
560
561 /* I appologize for the resource names beeing a mix of upper case
562  * and lower case but I want them to be exact as the documentation */
563 static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = {
564         [AB5500_DEVID_LEDS] = {
565                 .name = "ab5500-leds",
566                 .id = AB5500_DEVID_LEDS,
567         },
568         [AB5500_DEVID_POWER] = {
569                 .name = "ab5500-power",
570                 .id = AB5500_DEVID_POWER,
571         },
572         [AB5500_DEVID_REGULATORS] = {
573                 .name = "ab5500-regulator",
574                 .id = AB5500_DEVID_REGULATORS,
575         },
576         [AB5500_DEVID_SIM] = {
577                 .name = "ab5500-sim",
578                 .id = AB5500_DEVID_SIM,
579                 .num_resources = 1,
580                 .resources = (struct resource[]) {
581                         {
582                                 .name = "SIMOFF",
583                                 .flags = IORESOURCE_IRQ,
584                                 .start = AB5500_IRQ(2, 0), /*rising*/
585                                 .end = AB5500_IRQ(2, 1), /*falling*/
586                         },
587                 },
588         },
589         [AB5500_DEVID_RTC] = {
590                 .name = "ab5500-rtc",
591                 .id = AB5500_DEVID_RTC,
592                 .num_resources = 1,
593                 .resources = (struct resource[]) {
594                         {
595                                 .name   = "RTC_Alarm",
596                                 .flags  = IORESOURCE_IRQ,
597                                 .start  = AB5500_IRQ(1, 7),
598                                 .end    = AB5500_IRQ(1, 7),
599                         }
600                 },
601         },
602         [AB5500_DEVID_CHARGER] = {
603                 .name = "ab5500-charger",
604                 .id = AB5500_DEVID_CHARGER,
605         },
606         [AB5500_DEVID_ADC] = {
607                 .name = "ab5500-adc",
608                 .id = AB5500_DEVID_ADC,
609                 .num_resources = 10,
610                 .resources = (struct resource[]) {
611                         {
612                                 .name = "TRIGGER-0",
613                                 .flags = IORESOURCE_IRQ,
614                                 .start = AB5500_IRQ(0, 0),
615                                 .end = AB5500_IRQ(0, 0),
616                         },
617                         {
618                                 .name = "TRIGGER-1",
619                                 .flags = IORESOURCE_IRQ,
620                                 .start = AB5500_IRQ(0, 1),
621                                 .end = AB5500_IRQ(0, 1),
622                         },
623                         {
624                                 .name = "TRIGGER-2",
625                                 .flags = IORESOURCE_IRQ,
626                                 .start = AB5500_IRQ(0, 2),
627                                 .end = AB5500_IRQ(0, 2),
628                         },
629                         {
630                                 .name = "TRIGGER-3",
631                                 .flags = IORESOURCE_IRQ,
632                                 .start = AB5500_IRQ(0, 3),
633                                 .end = AB5500_IRQ(0, 3),
634                         },
635                         {
636                                 .name = "TRIGGER-4",
637                                 .flags = IORESOURCE_IRQ,
638                                 .start = AB5500_IRQ(0, 4),
639                                 .end = AB5500_IRQ(0, 4),
640                         },
641                         {
642                                 .name = "TRIGGER-5",
643                                 .flags = IORESOURCE_IRQ,
644                                 .start = AB5500_IRQ(0, 5),
645                                 .end = AB5500_IRQ(0, 5),
646                         },
647                         {
648                                 .name = "TRIGGER-6",
649                                 .flags = IORESOURCE_IRQ,
650                                 .start = AB5500_IRQ(0, 6),
651                                 .end = AB5500_IRQ(0, 6),
652                         },
653                         {
654                                 .name = "TRIGGER-7",
655                                 .flags = IORESOURCE_IRQ,
656                                 .start = AB5500_IRQ(0, 7),
657                                 .end = AB5500_IRQ(0, 7),
658                         },
659                         {
660                                 .name = "TRIGGER-VBAT",
661                                 .flags = IORESOURCE_IRQ,
662                                 .start = AB5500_IRQ(0, 8),
663                                 .end = AB5500_IRQ(0, 8),
664                         },
665                         {
666                                 .name = "TRIGGER-VBAT-TXON",
667                                 .flags = IORESOURCE_IRQ,
668                                 .start = AB5500_IRQ(0, 9),
669                                 .end = AB5500_IRQ(0, 9),
670                         },
671                 },
672         },
673         [AB5500_DEVID_FUELGAUGE] = {
674                 .name = "ab5500-fuelgauge",
675                 .id = AB5500_DEVID_FUELGAUGE,
676                 .num_resources = 6,
677                 .resources = (struct resource[]) {
678                         {
679                                 .name = "Batt_attach",
680                                 .flags = IORESOURCE_IRQ,
681                                 .start = AB5500_IRQ(7, 5),
682                                 .end = AB5500_IRQ(7, 5),
683                         },
684                         {
685                                 .name = "Batt_removal",
686                                 .flags = IORESOURCE_IRQ,
687                                 .start = AB5500_IRQ(7, 6),
688                                 .end = AB5500_IRQ(7, 6),
689                         },
690                         {
691                                 .name = "UART_framing",
692                                 .flags = IORESOURCE_IRQ,
693                                 .start = AB5500_IRQ(7, 7),
694                                 .end = AB5500_IRQ(7, 7),
695                         },
696                         {
697                                 .name = "UART_overrun",
698                                 .flags = IORESOURCE_IRQ,
699                                 .start = AB5500_IRQ(8, 0),
700                                 .end = AB5500_IRQ(8, 0),
701                         },
702                         {
703                                 .name = "UART_Rdy_RX",
704                                 .flags = IORESOURCE_IRQ,
705                                 .start = AB5500_IRQ(8, 1),
706                                 .end = AB5500_IRQ(8, 1),
707                         },
708                         {
709                                 .name = "UART_Rdy_TX",
710                                 .flags = IORESOURCE_IRQ,
711                                 .start = AB5500_IRQ(8, 2),
712                                 .end = AB5500_IRQ(8, 2),
713                         },
714                 },
715         },
716         [AB5500_DEVID_VIBRATOR] = {
717                 .name = "ab5500-vibrator",
718                 .id = AB5500_DEVID_VIBRATOR,
719         },
720         [AB5500_DEVID_CODEC] = {
721                 .name = "ab5500-codec",
722                 .id = AB5500_DEVID_CODEC,
723                 .num_resources = 3,
724                 .resources = (struct resource[]) {
725                         {
726                                 .name = "audio_spkr1_ovc",
727                                 .flags = IORESOURCE_IRQ,
728                                 .start = AB5500_IRQ(9, 5),
729                                 .end = AB5500_IRQ(9, 5),
730                         },
731                         {
732                                 .name = "audio_plllocked",
733                                 .flags = IORESOURCE_IRQ,
734                                 .start = AB5500_IRQ(9, 6),
735                                 .end = AB5500_IRQ(9, 6),
736                         },
737                         {
738                                 .name = "audio_spkr2_ovc",
739                                 .flags = IORESOURCE_IRQ,
740                                 .start = AB5500_IRQ(17, 4),
741                                 .end = AB5500_IRQ(17, 4),
742                         },
743                 },
744         },
745         [AB5500_DEVID_USB] = {
746                 .name = "ab5500-usb",
747                 .id = AB5500_DEVID_USB,
748                 .num_resources = 36,
749                 .resources = (struct resource[]) {
750                         {
751                                 .name = "Link_Update",
752                                 .flags = IORESOURCE_IRQ,
753                                 .start = AB5500_IRQ(22, 1),
754                                 .end = AB5500_IRQ(22, 1),
755                         },
756                         {
757                                 .name = "DCIO",
758                                 .flags = IORESOURCE_IRQ,
759                                 .start = AB5500_IRQ(8, 3),
760                                 .end = AB5500_IRQ(8, 4),
761                         },
762                         {
763                                 .name = "VBUS_R",
764                                 .flags = IORESOURCE_IRQ,
765                                 .start = AB5500_IRQ(8, 5),
766                                 .end = AB5500_IRQ(8, 5),
767                         },
768                         {
769                                 .name = "VBUS_F",
770                                 .flags = IORESOURCE_IRQ,
771                                 .start = AB5500_IRQ(8, 6),
772                                 .end = AB5500_IRQ(8, 6),
773                         },
774                         {
775                                 .name = "CHGstate_10_PCVBUSchg",
776                                 .flags = IORESOURCE_IRQ,
777                                 .start = AB5500_IRQ(8, 7),
778                                 .end = AB5500_IRQ(8, 7),
779                         },
780                         {
781                                 .name = "DCIOreverse_ovc",
782                                 .flags = IORESOURCE_IRQ,
783                                 .start = AB5500_IRQ(9, 0),
784                                 .end = AB5500_IRQ(9, 0),
785                         },
786                         {
787                                 .name = "USBCharDetDone",
788                                 .flags = IORESOURCE_IRQ,
789                                 .start = AB5500_IRQ(9, 1),
790                                 .end = AB5500_IRQ(9, 1),
791                         },
792                         {
793                                 .name = "DCIO_no_limit",
794                                 .flags = IORESOURCE_IRQ,
795                                 .start = AB5500_IRQ(9, 2),
796                                 .end = AB5500_IRQ(9, 2),
797                         },
798                         {
799                                 .name = "USB_suspend",
800                                 .flags = IORESOURCE_IRQ,
801                                 .start = AB5500_IRQ(9, 3),
802                                 .end = AB5500_IRQ(9, 3),
803                         },
804                         {
805                                 .name = "DCIOreverse_fwdcurrent",
806                                 .flags = IORESOURCE_IRQ,
807                                 .start = AB5500_IRQ(9, 4),
808                                 .end = AB5500_IRQ(9, 4),
809                         },
810                         {
811                                 .name = "Vbus_Imeasmax_change",
812                                 .flags = IORESOURCE_IRQ,
813                                 .start = AB5500_IRQ(9, 5),
814                                 .end = AB5500_IRQ(9, 6),
815                         },
816                         {
817                                 .name = "OVV",
818                                 .flags = IORESOURCE_IRQ,
819                                 .start = AB5500_IRQ(14, 5),
820                                 .end = AB5500_IRQ(14, 5),
821                         },
822                         {
823                                 .name = "USBcharging_NOTok",
824                                 .flags = IORESOURCE_IRQ,
825                                 .start = AB5500_IRQ(15, 3),
826                                 .end = AB5500_IRQ(15, 3),
827                         },
828                         {
829                                 .name = "usb_adp_sensoroff",
830                                 .flags = IORESOURCE_IRQ,
831                                 .start = AB5500_IRQ(15, 6),
832                                 .end = AB5500_IRQ(15, 6),
833                         },
834                         {
835                                 .name = "usb_adp_probeplug",
836                                 .flags = IORESOURCE_IRQ,
837                                 .start = AB5500_IRQ(15, 7),
838                                 .end = AB5500_IRQ(15, 7),
839                         },
840                         {
841                                 .name = "usb_adp_sinkerror",
842                                 .flags = IORESOURCE_IRQ,
843                                 .start = AB5500_IRQ(16, 0),
844                                 .end = AB5500_IRQ(16, 6),
845                         },
846                         {
847                                 .name = "usb_adp_sourceerror",
848                                 .flags = IORESOURCE_IRQ,
849                                 .start = AB5500_IRQ(16, 1),
850                                 .end = AB5500_IRQ(16, 1),
851                         },
852                         {
853                                 .name = "usb_idgnd_r",
854                                 .flags = IORESOURCE_IRQ,
855                                 .start = AB5500_IRQ(16, 2),
856                                 .end = AB5500_IRQ(16, 2),
857                         },
858                         {
859                                 .name = "usb_idgnd_f",
860                                 .flags = IORESOURCE_IRQ,
861                                 .start = AB5500_IRQ(16, 3),
862                                 .end = AB5500_IRQ(16, 3),
863                         },
864                         {
865                                 .name = "usb_iddetR1",
866                                 .flags = IORESOURCE_IRQ,
867                                 .start = AB5500_IRQ(16, 4),
868                                 .end = AB5500_IRQ(16, 5),
869                         },
870                         {
871                                 .name = "usb_iddetR2",
872                                 .flags = IORESOURCE_IRQ,
873                                 .start = AB5500_IRQ(16, 6),
874                                 .end = AB5500_IRQ(16, 7),
875                         },
876                         {
877                                 .name = "usb_iddetR3",
878                                 .flags = IORESOURCE_IRQ,
879                                 .start = AB5500_IRQ(17, 0),
880                                 .end = AB5500_IRQ(17, 1),
881                         },
882                         {
883                                 .name = "usb_iddetR4",
884                                 .flags = IORESOURCE_IRQ,
885                                 .start = AB5500_IRQ(17, 2),
886                                 .end = AB5500_IRQ(17, 3),
887                         },
888                         {
889                                 .name = "CharTempWindowOk",
890                                 .flags = IORESOURCE_IRQ,
891                                 .start = AB5500_IRQ(17, 7),
892                                 .end = AB5500_IRQ(18, 0),
893                         },
894                         {
895                                 .name = "USB_SprDetect",
896                                 .flags = IORESOURCE_IRQ,
897                                 .start = AB5500_IRQ(18, 1),
898                                 .end = AB5500_IRQ(18, 1),
899                         },
900                         {
901                                 .name = "usb_adp_probe_unplug",
902                                 .flags = IORESOURCE_IRQ,
903                                 .start = AB5500_IRQ(18, 2),
904                                 .end = AB5500_IRQ(18, 2),
905                         },
906                         {
907                                 .name = "VBUSChDrop",
908                                 .flags = IORESOURCE_IRQ,
909                                 .start = AB5500_IRQ(18, 3),
910                                 .end = AB5500_IRQ(18, 4),
911                         },
912                         {
913                                 .name = "dcio_char_rec_done",
914                                 .flags = IORESOURCE_IRQ,
915                                 .start = AB5500_IRQ(18, 5),
916                                 .end = AB5500_IRQ(18, 5),
917                         },
918                         {
919                                 .name = "Charging_stopped_by_temp",
920                                 .flags = IORESOURCE_IRQ,
921                                 .start = AB5500_IRQ(18, 6),
922                                 .end = AB5500_IRQ(18, 6),
923                         },
924                         {
925                                 .name = "CHGstate_11_SafeModeVBUS",
926                                 .flags = IORESOURCE_IRQ,
927                                 .start = AB5500_IRQ(21, 1),
928                                 .end = AB5500_IRQ(21, 2),
929                         },
930                         {
931                                 .name = "CHGstate_12_comletedVBUS",
932                                 .flags = IORESOURCE_IRQ,
933                                 .start = AB5500_IRQ(21, 2),
934                                 .end = AB5500_IRQ(21, 2),
935                         },
936                         {
937                                 .name = "CHGstate_13_completedVBUS",
938                                 .flags = IORESOURCE_IRQ,
939                                 .start = AB5500_IRQ(21, 3),
940                                 .end = AB5500_IRQ(21, 3),
941                         },
942                         {
943                                 .name = "CHGstate_14_FullChgDCIO",
944                                 .flags = IORESOURCE_IRQ,
945                                 .start = AB5500_IRQ(21, 4),
946                                 .end = AB5500_IRQ(21, 4),
947                         },
948                         {
949                                 .name = "CHGstate_15_SafeModeDCIO",
950                                 .flags = IORESOURCE_IRQ,
951                                 .start = AB5500_IRQ(21, 5),
952                                 .end = AB5500_IRQ(21, 5),
953                         },
954                         {
955                                 .name = "CHGstate_16_OFFsuspendDCIO",
956                                 .flags = IORESOURCE_IRQ,
957                                 .start = AB5500_IRQ(21, 6),
958                                 .end = AB5500_IRQ(21, 6),
959                         },
960                         {
961                                 .name = "CHGstate_17_completedDCIO",
962                                 .flags = IORESOURCE_IRQ,
963                                 .start = AB5500_IRQ(21, 7),
964                                 .end = AB5500_IRQ(21, 7),
965                         },
966                 },
967         },
968         [AB5500_DEVID_OTP] = {
969                 .name = "ab5500-otp",
970                 .id = AB5500_DEVID_OTP,
971         },
972         [AB5500_DEVID_VIDEO] = {
973                 .name = "ab5500-video",
974                 .id = AB5500_DEVID_VIDEO,
975                 .num_resources = 1,
976                 .resources = (struct resource[]) {
977                         {
978                                 .name = "plugTVdet",
979                                 .flags = IORESOURCE_IRQ,
980                                 .start = AB5500_IRQ(22, 2),
981                                 .end = AB5500_IRQ(22, 2),
982                         },
983                 },
984         },
985         [AB5500_DEVID_DBIECI] = {
986                 .name = "ab5500-dbieci",
987                 .id = AB5500_DEVID_DBIECI,
988                 .num_resources = 10,
989                 .resources = (struct resource[]) {
990                         {
991                                 .name = "COLL",
992                                 .flags = IORESOURCE_IRQ,
993                                 .start = AB5500_IRQ(14, 0),
994                                 .end = AB5500_IRQ(14, 0),
995                         },
996                         {
997                                 .name = "RESERR",
998                                 .flags = IORESOURCE_IRQ,
999                                 .start = AB5500_IRQ(14, 1),
1000                                 .end = AB5500_IRQ(14, 1),
1001                         },
1002                         {
1003                                 .name = "FRAERR",
1004                                 .flags = IORESOURCE_IRQ,
1005                                 .start = AB5500_IRQ(14, 2),
1006                                 .end = AB5500_IRQ(14, 2),
1007                         },
1008                         {
1009                                 .name = "COMERR",
1010                                 .flags = IORESOURCE_IRQ,
1011                                 .start = AB5500_IRQ(14, 3),
1012                                 .end = AB5500_IRQ(14, 3),
1013                         },
1014                         {
1015                                 .name = "BSI_indicator",
1016                                 .flags = IORESOURCE_IRQ,
1017                                 .start = AB5500_IRQ(14, 4),
1018                                 .end = AB5500_IRQ(14, 4),
1019                         },
1020                         {
1021                                 .name = "SPDSET",
1022                                 .flags = IORESOURCE_IRQ,
1023                                 .start = AB5500_IRQ(14, 6),
1024                                 .end = AB5500_IRQ(14, 6),
1025                         },
1026                         {
1027                                 .name = "DSENT",
1028                                 .flags = IORESOURCE_IRQ,
1029                                 .start = AB5500_IRQ(14, 7),
1030                                 .end = AB5500_IRQ(14, 7),
1031                         },
1032                         {
1033                                 .name = "DREC",
1034                                 .flags = IORESOURCE_IRQ,
1035                                 .start = AB5500_IRQ(15, 0),
1036                                 .end = AB5500_IRQ(15, 0),
1037                         },
1038                         {
1039                                 .name = "ACCINT",
1040                                 .flags = IORESOURCE_IRQ,
1041                                 .start = AB5500_IRQ(15, 1),
1042                                 .end = AB5500_IRQ(15, 1),
1043                         },
1044                         {
1045                                 .name = "NOPINT",
1046                                 .flags = IORESOURCE_IRQ,
1047                                 .start = AB5500_IRQ(15, 2),
1048                                 .end = AB5500_IRQ(15, 2),
1049                         },
1050                 },
1051         },
1052         [AB5500_DEVID_ONSWA] = {
1053                 .name = "ab5500-onswa",
1054                 .id = AB5500_DEVID_ONSWA,
1055                 .num_resources = 2,
1056                 .resources = (struct resource[]) {
1057                         {
1058                                 .name   = "ONSWAn_rising",
1059                                 .flags  = IORESOURCE_IRQ,
1060                                 .start  = AB5500_IRQ(1, 3),
1061                                 .end    = AB5500_IRQ(1, 3),
1062                         },
1063                         {
1064                                 .name   = "ONSWAn_falling",
1065                                 .flags  = IORESOURCE_IRQ,
1066                                 .start  = AB5500_IRQ(1, 4),
1067                                 .end    = AB5500_IRQ(1, 4),
1068                         },
1069                 },
1070         },
1071 };
1072
1073 /*
1074  * Functionality for getting/setting register values.
1075  */
1076 static int get_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg,
1077         u8 *value)
1078 {
1079         int err;
1080
1081         if (bank >= AB5500_NUM_BANKS)
1082                 return -EINVAL;
1083
1084         err = mutex_lock_interruptible(&ab->access_mutex);
1085         if (err)
1086                 return err;
1087         err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1);
1088
1089         mutex_unlock(&ab->access_mutex);
1090         return err;
1091 }
1092
1093 static int get_register_page_interruptible(struct ab5500 *ab, u8 bank,
1094         u8 first_reg, u8 *regvals, u8 numregs)
1095 {
1096         int err;
1097
1098         if (bank >= AB5500_NUM_BANKS)
1099                 return -EINVAL;
1100
1101         err = mutex_lock_interruptible(&ab->access_mutex);
1102         if (err)
1103                 return err;
1104
1105         while (numregs) {
1106                 /* The hardware limit for get page is 4 */
1107                 u8 curnum = min_t(u8, numregs, 4u);
1108
1109                 err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr,
1110                                             first_reg, regvals, curnum);
1111                 if (err)
1112                         goto out;
1113
1114                 numregs -= curnum;
1115                 first_reg += curnum;
1116                 regvals += curnum;
1117         }
1118
1119 out:
1120         mutex_unlock(&ab->access_mutex);
1121         return err;
1122 }
1123
1124 static int mask_and_set_register_interruptible(struct ab5500 *ab, u8 bank,
1125         u8 reg, u8 bitmask, u8 bitvalues)
1126 {
1127         int err = 0;
1128
1129         if (bank >= AB5500_NUM_BANKS)
1130                 return -EINVAL;
1131
1132         if (bitmask) {
1133                 u8 buf;
1134
1135                 err = mutex_lock_interruptible(&ab->access_mutex);
1136                 if (err)
1137                         return err;
1138
1139                 if (bitmask == 0xFF) /* No need to read in this case. */
1140                         buf = bitvalues;
1141                 else { /* Read and modify the register value. */
1142                         err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr,
1143                                 reg, &buf, 1);
1144                         if (err)
1145                                 return err;
1146
1147                         buf = ((~bitmask & buf) | (bitmask & bitvalues));
1148                 }
1149                 /* Write the new value. */
1150                 err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg,
1151                                              &buf, 1);
1152
1153                 mutex_unlock(&ab->access_mutex);
1154         }
1155         return err;
1156 }
1157
1158 static int
1159 set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value)
1160 {
1161         return mask_and_set_register_interruptible(ab, bank, reg, 0xff, value);
1162 }
1163
1164 /*
1165  * Read/write permission checking functions.
1166  */
1167 static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank)
1168 {
1169         u8 i;
1170
1171         if (devid < AB5500_NUM_DEVICES) {
1172                 for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) {
1173                         if (ab5500_bank_ranges[devid].bank[i].bankid == bank)
1174                                 return &ab5500_bank_ranges[devid].bank[i];
1175                 }
1176         }
1177         return NULL;
1178 }
1179
1180 static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg)
1181 {
1182         u8 i; /* range loop index */
1183         const struct ab5500_i2c_ranges *bankref;
1184
1185         bankref = get_bankref(devid, bank);
1186         if (bankref == NULL || last_reg < first_reg)
1187                 return false;
1188
1189         for (i = 0; i < bankref->nranges; i++) {
1190                 if (first_reg < bankref->range[i].first)
1191                         break;
1192                 if ((last_reg <= bankref->range[i].last) &&
1193                         (bankref->range[i].perm & AB5500_PERM_WR))
1194                         return true;
1195         }
1196         return false;
1197 }
1198
1199 static bool reg_write_allowed(u8 devid, u8 bank, u8 reg)
1200 {
1201         return page_write_allowed(devid, bank, reg, reg);
1202 }
1203
1204 static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg)
1205 {
1206         u8 i;
1207         const struct ab5500_i2c_ranges *bankref;
1208
1209         bankref = get_bankref(devid, bank);
1210         if (bankref == NULL || last_reg < first_reg)
1211                 return false;
1212
1213
1214         /* Find the range (if it exists in the list) that includes first_reg. */
1215         for (i = 0; i < bankref->nranges; i++) {
1216                 if (first_reg < bankref->range[i].first)
1217                         return false;
1218                 if (first_reg <= bankref->range[i].last)
1219                         break;
1220         }
1221         /* Make sure that the entire range up to and including last_reg is
1222          * readable. This may span several of the ranges in the list.
1223          */
1224         while ((i < bankref->nranges) &&
1225                 (bankref->range[i].perm & AB5500_PERM_RD)) {
1226                 if (last_reg <= bankref->range[i].last)
1227                         return true;
1228                 if ((++i >= bankref->nranges) ||
1229                         (bankref->range[i].first !=
1230                                 (bankref->range[i - 1].last + 1))) {
1231                         break;
1232                 }
1233         }
1234         return false;
1235 }
1236
1237 static bool reg_read_allowed(u8 devid, u8 bank, u8 reg)
1238 {
1239         return page_read_allowed(devid, bank, reg, reg);
1240 }
1241
1242
1243 /*
1244  * The exported register access functionality.
1245  */
1246 static int ab5500_get_chip_id(struct device *dev)
1247 {
1248         struct ab5500 *ab = dev_get_drvdata(dev->parent);
1249
1250         return (int)ab->chip_id;
1251 }
1252
1253 static int ab5500_mask_and_set_register_interruptible(struct device *dev,
1254                 u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
1255 {
1256         struct ab5500 *ab;
1257         struct platform_device *pdev = to_platform_device(dev);
1258
1259         if ((AB5500_NUM_BANKS <= bank) ||
1260                 !reg_write_allowed(pdev->id, bank, reg))
1261                 return -EINVAL;
1262
1263         ab = dev_get_drvdata(dev->parent);
1264         return mask_and_set_register_interruptible(ab, bank, reg,
1265                 bitmask, bitvalues);
1266 }
1267
1268 static int ab5500_set_register_interruptible(struct device *dev, u8 bank,
1269         u8 reg, u8 value)
1270 {
1271         return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF,
1272                 value);
1273 }
1274
1275 static int ab5500_get_register_interruptible(struct device *dev, u8 bank,
1276                 u8 reg, u8 *value)
1277 {
1278         struct ab5500 *ab;
1279         struct platform_device *pdev = to_platform_device(dev);
1280
1281         if ((AB5500_NUM_BANKS <= bank) ||
1282                 !reg_read_allowed(pdev->id, bank, reg))
1283                 return -EINVAL;
1284
1285         ab = dev_get_drvdata(dev->parent);
1286         return get_register_interruptible(ab, bank, reg, value);
1287 }
1288
1289 static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank,
1290                 u8 first_reg, u8 *regvals, u8 numregs)
1291 {
1292         struct ab5500 *ab;
1293         struct platform_device *pdev = to_platform_device(dev);
1294
1295         if ((AB5500_NUM_BANKS <= bank) ||
1296                 !page_read_allowed(pdev->id, bank,
1297                         first_reg, (first_reg + numregs - 1)))
1298                 return -EINVAL;
1299
1300         ab = dev_get_drvdata(dev->parent);
1301         return get_register_page_interruptible(ab, bank, first_reg, regvals,
1302                 numregs);
1303 }
1304
1305 static int
1306 ab5500_event_registers_startup_state_get(struct device *dev, u8 *event)
1307 {
1308         struct ab5500 *ab;
1309
1310         ab = dev_get_drvdata(dev->parent);
1311         if (!ab->startup_events_read)
1312                 return -EAGAIN; /* Try again later */
1313
1314         memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG);
1315         return 0;
1316 }
1317
1318 static struct abx500_ops ab5500_ops = {
1319         .get_chip_id = ab5500_get_chip_id,
1320         .get_register = ab5500_get_register_interruptible,
1321         .set_register = ab5500_set_register_interruptible,
1322         .get_register_page = ab5500_get_register_page_interruptible,
1323         .set_register_page = NULL,
1324         .mask_and_set_register = ab5500_mask_and_set_register_interruptible,
1325         .event_registers_startup_state_get =
1326                 ab5500_event_registers_startup_state_get,
1327         .startup_irq_enabled = NULL,
1328 };
1329
1330 #ifdef CONFIG_DEBUG_FS
1331 static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = {
1332         [AB5500_BANK_LED] = {
1333                 .bankid = AB5500_BANK_LED,
1334                 .nranges = 1,
1335                 .range = (struct ab5500_reg_range[]) {
1336                         {
1337                                 .first = 0x00,
1338                                 .last = 0x0C,
1339                                 .perm = AB5500_PERM_RW,
1340                         },
1341                 },
1342         },
1343         [AB5500_BANK_ADC] = {
1344                 .bankid = AB5500_BANK_ADC,
1345                 .nranges = 6,
1346                 .range = (struct ab5500_reg_range[]) {
1347                         {
1348                                 .first = 0x1F,
1349                                 .last = 0x22,
1350                                 .perm = AB5500_PERM_RO,
1351                         },
1352                         {
1353                                 .first = 0x23,
1354                                 .last = 0x24,
1355                                 .perm = AB5500_PERM_RW,
1356                         },
1357                         {
1358                                 .first = 0x26,
1359                                 .last = 0x2D,
1360                                 .perm = AB5500_PERM_RO,
1361                         },
1362                         {
1363                                 .first = 0x2F,
1364                                 .last = 0x34,
1365                                 .perm = AB5500_PERM_RW,
1366                         },
1367                         {
1368                                 .first = 0x37,
1369                                 .last = 0x57,
1370                                 .perm = AB5500_PERM_RW,
1371                         },
1372                         {
1373                                 .first = 0x58,
1374                                 .last = 0x58,
1375                                 .perm = AB5500_PERM_RO,
1376                         },
1377                 },
1378         },
1379         [AB5500_BANK_RTC] = {
1380                 .bankid = AB5500_BANK_RTC,
1381                 .nranges = 2,
1382                 .range = (struct ab5500_reg_range[]) {
1383                         {
1384                                 .first = 0x00,
1385                                 .last = 0x04,
1386                                 .perm = AB5500_PERM_RW,
1387                         },
1388                         {
1389                                 .first = 0x06,
1390                                 .last = 0x0C,
1391                                 .perm = AB5500_PERM_RW,
1392                         },
1393                 },
1394         },
1395         [AB5500_BANK_STARTUP] = {
1396                 .bankid = AB5500_BANK_STARTUP,
1397                 .nranges = 12,
1398                 .range = (struct ab5500_reg_range[]) {
1399                         {
1400                                 .first = 0x00,
1401                                 .last = 0x01,
1402                                 .perm = AB5500_PERM_RW,
1403                         },
1404                         {
1405                                 .first = 0x1F,
1406                                 .last = 0x1F,
1407                                 .perm = AB5500_PERM_RW,
1408                         },
1409                         {
1410                                 .first = 0x2E,
1411                                 .last = 0x2E,
1412                                 .perm = AB5500_PERM_RO,
1413                         },
1414                         {
1415                                 .first = 0x2F,
1416                                 .last = 0x30,
1417                                 .perm = AB5500_PERM_RW,
1418                         },
1419                         {
1420                                 .first = 0x50,
1421                                 .last = 0x51,
1422                                 .perm = AB5500_PERM_RW,
1423                         },
1424                         {
1425                                 .first = 0x60,
1426                                 .last = 0x61,
1427                                 .perm = AB5500_PERM_RW,
1428                         },
1429                         {
1430                                 .first = 0x66,
1431                                 .last = 0x8A,
1432                                 .perm = AB5500_PERM_RW,
1433                         },
1434                         {
1435                                 .first = 0x8C,
1436                                 .last = 0x96,
1437                                 .perm = AB5500_PERM_RW,
1438                         },
1439                         {
1440                                 .first = 0xAA,
1441                                 .last = 0xB4,
1442                                 .perm = AB5500_PERM_RW,
1443                         },
1444                         {
1445                                 .first = 0xB7,
1446                                 .last = 0xBF,
1447                                 .perm = AB5500_PERM_RW,
1448                         },
1449                         {
1450                                 .first = 0xC1,
1451                                 .last = 0xCA,
1452                                 .perm = AB5500_PERM_RW,
1453                         },
1454                         {
1455                                 .first = 0xD3,
1456                                 .last = 0xE0,
1457                                 .perm = AB5500_PERM_RW,
1458                         },
1459                 },
1460         },
1461         [AB5500_BANK_DBI_ECI] = {
1462                 .bankid = AB5500_BANK_DBI_ECI,
1463                 .nranges = 3,
1464                 .range = (struct ab5500_reg_range[]) {
1465                         {
1466                                 .first = 0x00,
1467                                 .last = 0x07,
1468                                 .perm = AB5500_PERM_RW,
1469                         },
1470                         {
1471                                 .first = 0x10,
1472                                 .last = 0x10,
1473                                 .perm = AB5500_PERM_RW,
1474                         },
1475                         {
1476                                 .first = 0x13,
1477                                 .last = 0x13,
1478                                 .perm = AB5500_PERM_RW,
1479                         },
1480                 },
1481         },
1482         [AB5500_BANK_CHG] = {
1483                 .bankid = AB5500_BANK_CHG,
1484                 .nranges = 2,
1485                 .range = (struct ab5500_reg_range[]) {
1486                         {
1487                                 .first = 0x11,
1488                                 .last = 0x11,
1489                                 .perm = AB5500_PERM_RO,
1490                         },
1491                         {
1492                                 .first = 0x12,
1493                                 .last = 0x1B,
1494                                 .perm = AB5500_PERM_RW,
1495                         },
1496                 },
1497         },
1498         [AB5500_BANK_FG_BATTCOM_ACC] = {
1499                 .bankid = AB5500_BANK_FG_BATTCOM_ACC,
1500                 .nranges = 2,
1501                 .range = (struct ab5500_reg_range[]) {
1502                         {
1503                                 .first = 0x00,
1504                                 .last = 0x0B,
1505                                 .perm = AB5500_PERM_RO,
1506                         },
1507                         {
1508                                 .first = 0x0C,
1509                                 .last = 0x10,
1510                                 .perm = AB5500_PERM_RW,
1511                         },
1512                 },
1513         },
1514         [AB5500_BANK_USB] = {
1515                 .bankid = AB5500_BANK_USB,
1516                 .nranges = 12,
1517                 .range = (struct ab5500_reg_range[]) {
1518                         {
1519                                 .first = 0x01,
1520                                 .last = 0x01,
1521                                 .perm = AB5500_PERM_RW,
1522                         },
1523                         {
1524                                 .first = 0x80,
1525                                 .last = 0x83,
1526                                 .perm = AB5500_PERM_RW,
1527                         },
1528                         {
1529                                 .first = 0x87,
1530                                 .last = 0x8A,
1531                                 .perm = AB5500_PERM_RW,
1532                         },
1533                         {
1534                                 .first = 0x8B,
1535                                 .last = 0x8B,
1536                                 .perm = AB5500_PERM_RO,
1537                         },
1538                         {
1539                                 .first = 0x91,
1540                                 .last = 0x92,
1541                                 .perm = AB5500_PERM_RO,
1542                         },
1543                         {
1544                                 .first = 0x93,
1545                                 .last = 0x93,
1546                                 .perm = AB5500_PERM_RW,
1547                         },
1548                         {
1549                                 .first = 0x94,
1550                                 .last = 0x94,
1551                                 .perm = AB5500_PERM_RO,
1552                         },
1553                         {
1554                                 .first = 0xA8,
1555                                 .last = 0xB0,
1556                                 .perm = AB5500_PERM_RO,
1557                         },
1558                         {
1559                                 .first = 0xB2,
1560                                 .last = 0xB2,
1561                                 .perm = AB5500_PERM_RO,
1562                         },
1563                         {
1564                                 .first = 0xB4,
1565                                 .last = 0xBC,
1566                                 .perm = AB5500_PERM_RO,
1567                         },
1568                         {
1569                                 .first = 0xBF,
1570                                 .last = 0xBF,
1571                                 .perm = AB5500_PERM_RO,
1572                         },
1573                         {
1574                                 .first = 0xC1,
1575                                 .last = 0xC5,
1576                                 .perm = AB5500_PERM_RO,
1577                         },
1578                 },
1579         },
1580         [AB5500_BANK_IT] = {
1581                 .bankid = AB5500_BANK_IT,
1582                 .nranges = 4,
1583                 .range = (struct ab5500_reg_range[]) {
1584                         {
1585                                 .first = 0x00,
1586                                 .last = 0x02,
1587                                 .perm = AB5500_PERM_RO,
1588                         },
1589                         {
1590                                 .first = 0x20,
1591                                 .last = 0x36,
1592                                 .perm = AB5500_PERM_RO,
1593                         },
1594                         {
1595                                 .first = 0x40,
1596                                 .last = 0x56,
1597                                 .perm = AB5500_PERM_RO,
1598                         },
1599                         {
1600                                 .first = 0x60,
1601                                 .last = 0x76,
1602                                 .perm = AB5500_PERM_RO,
1603                         },
1604                 },
1605         },
1606         [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
1607                 .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST,
1608                 .nranges = 7,
1609                 .range = (struct ab5500_reg_range[]) {
1610                         {
1611                                 .first = 0x02,
1612                                 .last = 0x02,
1613                                 .perm = AB5500_PERM_RW,
1614                         },
1615                         {
1616                                 .first = 0x12,
1617                                 .last = 0x12,
1618                                 .perm = AB5500_PERM_RW,
1619                         },
1620                         {
1621                                 .first = 0x30,
1622                                 .last = 0x34,
1623                                 .perm = AB5500_PERM_RW,
1624                         },
1625                         {
1626                                 .first = 0x40,
1627                                 .last = 0x44,
1628                                 .perm = AB5500_PERM_RW,
1629                         },
1630                         {
1631                                 .first = 0x50,
1632                                 .last = 0x54,
1633                                 .perm = AB5500_PERM_RW,
1634                         },
1635                         {
1636                                 .first = 0x60,
1637                                 .last = 0x64,
1638                                 .perm = AB5500_PERM_RW,
1639                         },
1640                         {
1641                                 .first = 0x70,
1642                                 .last = 0x74,
1643                                 .perm = AB5500_PERM_RW,
1644                         },
1645                 },
1646         },
1647         [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
1648                 .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
1649                 .nranges = 13,
1650                 .range = (struct ab5500_reg_range[]) {
1651                         {
1652                                 .first = 0x01,
1653                                 .last = 0x01,
1654                                 .perm = AB5500_PERM_RW,
1655                         },
1656                         {
1657                                 .first = 0x02,
1658                                 .last = 0x02,
1659                                 .perm = AB5500_PERM_RO,
1660                         },
1661                         {
1662                                 .first = 0x0D,
1663                                 .last = 0x0F,
1664                                 .perm = AB5500_PERM_RW,
1665                         },
1666                         {
1667                                 .first = 0x1C,
1668                                 .last = 0x1C,
1669                                 .perm = AB5500_PERM_RW,
1670                         },
1671                         {
1672                                 .first = 0x1E,
1673                                 .last = 0x1E,
1674                                 .perm = AB5500_PERM_RW,
1675                         },
1676                         {
1677                                 .first = 0x20,
1678                                 .last = 0x21,
1679                                 .perm = AB5500_PERM_RW,
1680                         },
1681                         {
1682                                 .first = 0x25,
1683                                 .last = 0x25,
1684                                 .perm = AB5500_PERM_RW,
1685                         },
1686                         {
1687                                 .first = 0x28,
1688                                 .last = 0x2A,
1689                                 .perm = AB5500_PERM_RW,
1690                         },
1691                         {
1692                                 .first = 0x30,
1693                                 .last = 0x33,
1694                                 .perm = AB5500_PERM_RW,
1695                         },
1696                         {
1697                                 .first = 0x40,
1698                                 .last = 0x43,
1699                                 .perm = AB5500_PERM_RW,
1700                         },
1701                         {
1702                                 .first = 0x50,
1703                                 .last = 0x53,
1704                                 .perm = AB5500_PERM_RW,
1705                         },
1706                         {
1707                                 .first = 0x60,
1708                                 .last = 0x63,
1709                                 .perm = AB5500_PERM_RW,
1710                         },
1711                         {
1712                                 .first = 0x70,
1713                                 .last = 0x73,
1714                                 .perm = AB5500_PERM_RW,
1715                         },
1716                 },
1717         },
1718         [AB5500_BANK_VIBRA] = {
1719                 .bankid = AB5500_BANK_VIBRA,
1720                 .nranges = 2,
1721                 .range = (struct ab5500_reg_range[]) {
1722                         {
1723                                 .first = 0x10,
1724                                 .last = 0x13,
1725                                 .perm = AB5500_PERM_RW,
1726                         },
1727                         {
1728                                 .first = 0xFE,
1729                                 .last = 0xFE,
1730                                 .perm = AB5500_PERM_RW,
1731                         },
1732                 },
1733         },
1734         [AB5500_BANK_AUDIO_HEADSETUSB] = {
1735                 .bankid = AB5500_BANK_AUDIO_HEADSETUSB,
1736                 .nranges = 2,
1737                 .range = (struct ab5500_reg_range[]) {
1738                         {
1739                                 .first = 0x00,
1740                                 .last = 0x48,
1741                                 .perm = AB5500_PERM_RW,
1742                         },
1743                         {
1744                                 .first = 0xEB,
1745                                 .last = 0xFB,
1746                                 .perm = AB5500_PERM_RW,
1747                         },
1748                 },
1749         },
1750         [AB5500_BANK_SIM_USBSIM] = {
1751                 .bankid = AB5500_BANK_SIM_USBSIM,
1752                 .nranges = 1,
1753                 .range = (struct ab5500_reg_range[]) {
1754                         {
1755                                 .first = 0x13,
1756                                 .last = 0x19,
1757                                 .perm = AB5500_PERM_RW,
1758                         },
1759                 },
1760         },
1761         [AB5500_BANK_VDENC] = {
1762                 .bankid = AB5500_BANK_VDENC,
1763                 .nranges = 12,
1764                 .range = (struct ab5500_reg_range[]) {
1765                         {
1766                                 .first = 0x00,
1767                                 .last = 0x08,
1768                                 .perm = AB5500_PERM_RW,
1769                         },
1770                         {
1771                                 .first = 0x09,
1772                                 .last = 0x09,
1773                                 .perm = AB5500_PERM_RO,
1774                         },
1775                         {
1776                                 .first = 0x0A,
1777                                 .last = 0x12,
1778                                 .perm = AB5500_PERM_RW,
1779                         },
1780                         {
1781                                 .first = 0x15,
1782                                 .last = 0x19,
1783                                 .perm = AB5500_PERM_RW,
1784                         },
1785                         {
1786                                 .first = 0x1B,
1787                                 .last = 0x21,
1788                                 .perm = AB5500_PERM_RW,
1789                         },
1790                         {
1791                                 .first = 0x27,
1792                                 .last = 0x2C,
1793                                 .perm = AB5500_PERM_RW,
1794                         },
1795                         {
1796                                 .first = 0x41,
1797                                 .last = 0x41,
1798                                 .perm = AB5500_PERM_RW,
1799                         },
1800                         {
1801                                 .first = 0x45,
1802                                 .last = 0x5B,
1803                                 .perm = AB5500_PERM_RW,
1804                         },
1805                         {
1806                                 .first = 0x5D,
1807                                 .last = 0x5D,
1808                                 .perm = AB5500_PERM_RW,
1809                         },
1810                         {
1811                                 .first = 0x69,
1812                                 .last = 0x69,
1813                                 .perm = AB5500_PERM_RW,
1814                         },
1815                         {
1816                                 .first = 0x6C,
1817                                 .last = 0x6D,
1818                                 .perm = AB5500_PERM_RW,
1819                         },
1820                         {
1821                                 .first = 0x80,
1822                                 .last = 0x81,
1823                                 .perm = AB5500_PERM_RW,
1824                         },
1825                 },
1826         },
1827 };
1828 static int ab5500_registers_print(struct seq_file *s, void *p)
1829 {
1830         struct ab5500 *ab = s->private;
1831         unsigned int i;
1832         u8 bank = (u8)ab->debug_bank;
1833
1834         seq_printf(s, "ab5500 register values:\n");
1835         for (bank = 0; bank < AB5500_NUM_BANKS; bank++) {
1836                 seq_printf(s, " bank %u, %s (0x%x):\n", bank,
1837                                 bankinfo[bank].name,
1838                                 bankinfo[bank].slave_addr);
1839                 for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) {
1840                         u8 reg;
1841                         int err;
1842
1843                         for (reg = ab5500_reg_ranges[bank].range[i].first;
1844                                 reg <= ab5500_reg_ranges[bank].range[i].last;
1845                                 reg++) {
1846                                 u8 value;
1847
1848                                 err = get_register_interruptible(ab, bank, reg,
1849                                                 &value);
1850                                 if (err < 0) {
1851                                         dev_err(ab->dev, "get_reg failed %d"
1852                                                 "bank 0x%x reg 0x%x\n",
1853                                                 err, bank, reg);
1854                                         return err;
1855                                 }
1856
1857                                 err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n",
1858                                                 bank, reg, value);
1859                                 if (err < 0) {
1860                                         dev_err(ab->dev,
1861                                                 "seq_printf overflow\n");
1862                                         /*
1863                                          * Error is not returned here since
1864                                          * the output is wanted in any case
1865                                          */
1866                                         return 0;
1867                                 }
1868                         }
1869                 }
1870         }
1871         return 0;
1872 }
1873
1874 static int ab5500_registers_open(struct inode *inode, struct file *file)
1875 {
1876         return single_open(file, ab5500_registers_print, inode->i_private);
1877 }
1878
1879 static const struct file_operations ab5500_registers_fops = {
1880         .open = ab5500_registers_open,
1881         .read = seq_read,
1882         .llseek = seq_lseek,
1883         .release = single_release,
1884         .owner = THIS_MODULE,
1885 };
1886
1887 static int ab5500_bank_print(struct seq_file *s, void *p)
1888 {
1889         struct ab5500 *ab = s->private;
1890
1891         seq_printf(s, "%d\n", ab->debug_bank);
1892         return 0;
1893 }
1894
1895 static int ab5500_bank_open(struct inode *inode, struct file *file)
1896 {
1897         return single_open(file, ab5500_bank_print, inode->i_private);
1898 }
1899
1900 static ssize_t ab5500_bank_write(struct file *file,
1901         const char __user *user_buf,
1902         size_t count, loff_t *ppos)
1903 {
1904         struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
1905         char buf[32];
1906         int buf_size;
1907         unsigned long user_bank;
1908         int err;
1909
1910         /* Get userspace string and assure termination */
1911         buf_size = min(count, (sizeof(buf) - 1));
1912         if (copy_from_user(buf, user_buf, buf_size))
1913                 return -EFAULT;
1914         buf[buf_size] = 0;
1915
1916         err = strict_strtoul(buf, 0, &user_bank);
1917         if (err)
1918                 return -EINVAL;
1919
1920         if (user_bank >= AB5500_NUM_BANKS) {
1921                 dev_err(ab->dev,
1922                         "debugfs error input > number of banks\n");
1923                 return -EINVAL;
1924         }
1925
1926         ab->debug_bank = user_bank;
1927
1928         return buf_size;
1929 }
1930
1931 static int ab5500_address_print(struct seq_file *s, void *p)
1932 {
1933         struct ab5500 *ab = s->private;
1934
1935         seq_printf(s, "0x%02X\n", ab->debug_address);
1936         return 0;
1937 }
1938
1939 static int ab5500_address_open(struct inode *inode, struct file *file)
1940 {
1941         return single_open(file, ab5500_address_print, inode->i_private);
1942 }
1943
1944 static ssize_t ab5500_address_write(struct file *file,
1945         const char __user *user_buf,
1946         size_t count, loff_t *ppos)
1947 {
1948         struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
1949         char buf[32];
1950         int buf_size;
1951         unsigned long user_address;
1952         int err;
1953
1954         /* Get userspace string and assure termination */
1955         buf_size = min(count, (sizeof(buf) - 1));
1956         if (copy_from_user(buf, user_buf, buf_size))
1957                 return -EFAULT;
1958         buf[buf_size] = 0;
1959
1960         err = strict_strtoul(buf, 0, &user_address);
1961         if (err)
1962                 return -EINVAL;
1963         if (user_address > 0xff) {
1964                 dev_err(ab->dev,
1965                         "debugfs error input > 0xff\n");
1966                 return -EINVAL;
1967         }
1968         ab->debug_address = user_address;
1969         return buf_size;
1970 }
1971
1972 static int ab5500_val_print(struct seq_file *s, void *p)
1973 {
1974         struct ab5500 *ab = s->private;
1975         int err;
1976         u8 regvalue;
1977
1978         err = get_register_interruptible(ab, (u8)ab->debug_bank,
1979                 (u8)ab->debug_address, &regvalue);
1980         if (err) {
1981                 dev_err(ab->dev, "get_reg failed %d, bank 0x%x"
1982                         ", reg 0x%x\n", err, ab->debug_bank,
1983                         ab->debug_address);
1984                 return -EINVAL;
1985         }
1986         seq_printf(s, "0x%02X\n", regvalue);
1987
1988         return 0;
1989 }
1990
1991 static int ab5500_val_open(struct inode *inode, struct file *file)
1992 {
1993         return single_open(file, ab5500_val_print, inode->i_private);
1994 }
1995
1996 static ssize_t ab5500_val_write(struct file *file,
1997         const char __user *user_buf,
1998         size_t count, loff_t *ppos)
1999 {
2000         struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
2001         char buf[32];
2002         int buf_size;
2003         unsigned long user_val;
2004         int err;
2005         u8 regvalue;
2006
2007         /* Get userspace string and assure termination */
2008         buf_size = min(count, (sizeof(buf)-1));
2009         if (copy_from_user(buf, user_buf, buf_size))
2010                 return -EFAULT;
2011         buf[buf_size] = 0;
2012
2013         err = strict_strtoul(buf, 0, &user_val);
2014         if (err)
2015                 return -EINVAL;
2016         if (user_val > 0xff) {
2017                 dev_err(ab->dev,
2018                         "debugfs error input > 0xff\n");
2019                 return -EINVAL;
2020         }
2021         err = mask_and_set_register_interruptible(
2022                 ab, (u8)ab->debug_bank,
2023                 (u8)ab->debug_address, 0xFF, (u8)user_val);
2024         if (err)
2025                 return -EINVAL;
2026
2027         get_register_interruptible(ab, (u8)ab->debug_bank,
2028                 (u8)ab->debug_address, &regvalue);
2029         if (err)
2030                 return -EINVAL;
2031
2032         return buf_size;
2033 }
2034
2035 static const struct file_operations ab5500_bank_fops = {
2036         .open = ab5500_bank_open,
2037         .write = ab5500_bank_write,
2038         .read = seq_read,
2039         .llseek = seq_lseek,
2040         .release = single_release,
2041         .owner = THIS_MODULE,
2042 };
2043
2044 static const struct file_operations ab5500_address_fops = {
2045         .open = ab5500_address_open,
2046         .write = ab5500_address_write,
2047         .read = seq_read,
2048         .llseek = seq_lseek,
2049         .release = single_release,
2050         .owner = THIS_MODULE,
2051 };
2052
2053 static const struct file_operations ab5500_val_fops = {
2054         .open = ab5500_val_open,
2055         .write = ab5500_val_write,
2056         .read = seq_read,
2057         .llseek = seq_lseek,
2058         .release = single_release,
2059         .owner = THIS_MODULE,
2060 };
2061
2062 static struct dentry *ab5500_dir;
2063 static struct dentry *ab5500_reg_file;
2064 static struct dentry *ab5500_bank_file;
2065 static struct dentry *ab5500_address_file;
2066 static struct dentry *ab5500_val_file;
2067
2068 static inline void ab5500_setup_debugfs(struct ab5500 *ab)
2069 {
2070         ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP;
2071         ab->debug_address = AB5500_CHIP_ID;
2072
2073         ab5500_dir = debugfs_create_dir("ab5500", NULL);
2074         if (!ab5500_dir)
2075                 goto exit_no_debugfs;
2076
2077         ab5500_reg_file = debugfs_create_file("all-bank-registers",
2078                 S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops);
2079         if (!ab5500_reg_file)
2080                 goto exit_destroy_dir;
2081
2082         ab5500_bank_file = debugfs_create_file("register-bank",
2083                 (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops);
2084         if (!ab5500_bank_file)
2085                 goto exit_destroy_reg;
2086
2087         ab5500_address_file = debugfs_create_file("register-address",
2088                 (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops);
2089         if (!ab5500_address_file)
2090                 goto exit_destroy_bank;
2091
2092         ab5500_val_file = debugfs_create_file("register-value",
2093                 (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops);
2094         if (!ab5500_val_file)
2095                 goto exit_destroy_address;
2096
2097         return;
2098
2099 exit_destroy_address:
2100         debugfs_remove(ab5500_address_file);
2101 exit_destroy_bank:
2102         debugfs_remove(ab5500_bank_file);
2103 exit_destroy_reg:
2104         debugfs_remove(ab5500_reg_file);
2105 exit_destroy_dir:
2106         debugfs_remove(ab5500_dir);
2107 exit_no_debugfs:
2108         dev_err(ab->dev, "failed to create debugfs entries.\n");
2109         return;
2110 }
2111
2112 static inline void ab5500_remove_debugfs(void)
2113 {
2114         debugfs_remove(ab5500_val_file);
2115         debugfs_remove(ab5500_address_file);
2116         debugfs_remove(ab5500_bank_file);
2117         debugfs_remove(ab5500_reg_file);
2118         debugfs_remove(ab5500_dir);
2119 }
2120
2121 #else /* !CONFIG_DEBUG_FS */
2122 static inline void ab5500_setup_debugfs(struct ab5500 *ab)
2123 {
2124 }
2125 static inline void ab5500_remove_debugfs(void)
2126 {
2127 }
2128 #endif
2129
2130 /*
2131  * ab5500_setup : Basic set-up, datastructure creation/destruction
2132  *                and I2C interface.This sets up a default config
2133  *                in the AB5500 chip so that it will work as expected.
2134  * @ab :          Pointer to ab5500 structure
2135  * @settings :    Pointer to struct abx500_init_settings
2136  * @size :        Size of init data
2137  */
2138 static int __init ab5500_setup(struct ab5500 *ab,
2139         struct abx500_init_settings *settings, unsigned int size)
2140 {
2141         int err = 0;
2142         int i;
2143
2144         for (i = 0; i < size; i++) {
2145                 err = mask_and_set_register_interruptible(ab,
2146                         settings[i].bank,
2147                         settings[i].reg,
2148                         0xFF, settings[i].setting);
2149                 if (err)
2150                         goto exit_no_setup;
2151
2152                 /* If event mask register update the event mask in ab5500 */
2153                 if ((settings[i].bank == AB5500_BANK_IT) &&
2154                         (AB5500_MASK_BASE <= settings[i].reg) &&
2155                         (settings[i].reg <= AB5500_MASK_END)) {
2156                         ab->mask[settings[i].reg - AB5500_MASK_BASE] =
2157                                 settings[i].setting;
2158                 }
2159         }
2160 exit_no_setup:
2161         return err;
2162 }
2163
2164 struct ab_family_id {
2165         u8      id;
2166         char    *name;
2167 };
2168
2169 static const struct ab_family_id ids[] __initdata = {
2170         /* AB5500 */
2171         {
2172                 .id = AB5500_1_0,
2173                 .name = "1.0"
2174         },
2175         {
2176                 .id = AB5500_1_1,
2177                 .name = "1.1"
2178         },
2179         /* Terminator */
2180         {
2181                 .id = 0x00,
2182         }
2183 };
2184
2185 static int __init ab5500_probe(struct platform_device *pdev)
2186 {
2187         struct ab5500 *ab;
2188         struct ab5500_platform_data *ab5500_plf_data =
2189                 pdev->dev.platform_data;
2190         int err;
2191         int i;
2192
2193         ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL);
2194         if (!ab) {
2195                 dev_err(&pdev->dev,
2196                         "could not allocate ab5500 device\n");
2197                 return -ENOMEM;
2198         }
2199
2200         /* Initialize data structure */
2201         mutex_init(&ab->access_mutex);
2202         mutex_init(&ab->irq_lock);
2203         ab->dev = &pdev->dev;
2204
2205         platform_set_drvdata(pdev, ab);
2206
2207         /* Read chip ID register */
2208         err = get_register_interruptible(ab, AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
2209                 AB5500_CHIP_ID, &ab->chip_id);
2210         if (err) {
2211                 dev_err(&pdev->dev, "could not communicate with the analog "
2212                         "baseband chip\n");
2213                 goto exit_no_detect;
2214         }
2215
2216         for (i = 0; ids[i].id != 0x0; i++) {
2217                 if (ids[i].id == ab->chip_id) {
2218                         snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1,
2219                                 "AB5500 %s", ids[i].name);
2220                         break;
2221                 }
2222         }
2223         if (ids[i].id == 0x0) {
2224                 dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n",
2225                         ab->chip_id);
2226                 dev_err(&pdev->dev, "driver not started!\n");
2227                 goto exit_no_detect;
2228         }
2229
2230         /* Clear and mask all interrupts */
2231         for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) {
2232                 u8 latchreg = AB5500_IT_LATCH0_REG + i;
2233                 u8 maskreg = AB5500_IT_MASK0_REG + i;
2234                 u8 val;
2235
2236                 get_register_interruptible(ab, AB5500_BANK_IT, latchreg, &val);
2237                 set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff);
2238                 ab->mask[i] = ab->oldmask[i] = 0xff;
2239         }
2240
2241         err = abx500_register_ops(&pdev->dev, &ab5500_ops);
2242         if (err) {
2243                 dev_err(&pdev->dev, "ab5500_register ops error\n");
2244                 goto exit_no_detect;
2245         }
2246
2247         /* Set up and register the platform devices. */
2248         for (i = 0; i < AB5500_NUM_DEVICES; i++) {
2249                 ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i];
2250                 ab5500_devs[i].pdata_size =
2251                         sizeof(ab5500_plf_data->dev_data[i]);
2252         }
2253
2254         err = mfd_add_devices(&pdev->dev, 0, ab5500_devs,
2255                 ARRAY_SIZE(ab5500_devs), NULL,
2256                 ab5500_plf_data->irq.base);
2257         if (err) {
2258                 dev_err(&pdev->dev, "ab5500_mfd_add_device error\n");
2259                 goto exit_no_detect;
2260         }
2261
2262         err = ab5500_setup(ab, ab5500_plf_data->init_settings,
2263                 ab5500_plf_data->init_settings_sz);
2264         if (err) {
2265                 dev_err(&pdev->dev, "ab5500_setup error\n");
2266                 goto exit_no_detect;
2267         }
2268
2269         ab5500_setup_debugfs(ab);
2270
2271         dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]);
2272         return 0;
2273
2274 exit_no_detect:
2275         kfree(ab);
2276         return err;
2277 }
2278
2279 static int __exit ab5500_remove(struct platform_device *pdev)
2280 {
2281         struct ab5500 *ab = platform_get_drvdata(pdev);
2282
2283         ab5500_remove_debugfs();
2284         mfd_remove_devices(&pdev->dev);
2285         kfree(ab);
2286         return 0;
2287 }
2288
2289 static struct platform_driver ab5500_driver = {
2290         .driver = {
2291                 .name = "ab5500-core",
2292                 .owner = THIS_MODULE,
2293         },
2294         .remove  = __exit_p(ab5500_remove),
2295 };
2296
2297 static int __init ab5500_core_init(void)
2298 {
2299         return platform_driver_probe(&ab5500_driver, ab5500_probe);
2300 }
2301
2302 static void __exit ab5500_core_exit(void)
2303 {
2304         platform_driver_unregister(&ab5500_driver);
2305 }
2306
2307 subsys_initcall(ab5500_core_init);
2308 module_exit(ab5500_core_exit);
2309
2310 MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
2311 MODULE_DESCRIPTION("AB5500 core driver");
2312 MODULE_LICENSE("GPL");