aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMattias Wallin <mattias.wallin@stericsson.com>2011-09-22 02:22:18 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-10-24 08:09:16 -0400
commit3d5e2cabf11a65685e5067382ba4c4a76f18fcb7 (patch)
tree361913524dfa8e74003a39c8691306974a3ca9df /drivers/mfd
parent677df0c9012ca3a6e0081f29f81506e5578d74f3 (diff)
mfd: ab5500 chip register access
The analog baseband chip ab5500 is a multi functional chip containing regulators, charging, gpio, USB and accessory detect. It also contain various multimedia functionalities like digital encoder and audio codec. The core driver added with this patch provides register access via i2c via PRCMU. Event handling implemented as irq_chip will come in future patches since it depends on PRCMU functionality not yet implemented. Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig9
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/ab5500-core.c2312
3 files changed, 2322 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b01fbe27822d..8594de8b86a0 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -563,6 +563,15 @@ config EZX_PCAP
563 This enables the PCAP ASIC present on EZX Phones. This is 563 This enables the PCAP ASIC present on EZX Phones. This is
564 needed for MMC, TouchScreen, Sound, USB, etc.. 564 needed for MMC, TouchScreen, Sound, USB, etc..
565 565
566config AB5500_CORE
567 bool "ST-Ericsson AB5500 Mixed Signal Power Management chip"
568 depends on ABX500_CORE && MFD_DB5500_PRCMU
569 select MFD_CORE
570 help
571 Select this option to enable access to AB5500 power management
572 chip. This connects to the db5500 chip via the I2C bus via PRCMU.
573 This chip embeds various other multimedia funtionalities as well.
574
566config AB8500_CORE 575config AB8500_CORE
567 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" 576 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
568 depends on GENERIC_HARDIRQS && ABX500_CORE 577 depends on GENERIC_HARDIRQS && ABX500_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 7d53a7c530c8..457fed8474cf 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o
80obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 80obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
81obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 81obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
82obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 82obj-$(CONFIG_AB3550_CORE) += ab3550-core.o
83obj-$(CONFIG_AB5500_CORE) += ab5500-core.o
83obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 84obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
84obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 85obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
85obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o 86obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c
new file mode 100644
index 000000000000..afec0f2ede42
--- /dev/null
+++ b/drivers/mfd/ab5500-core.c
@@ -0,0 +1,2312 @@
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 */
57struct ab5500_bank {
58 u8 slave_addr;
59 const char *name;
60};
61
62static 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 */
90struct 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 */
101struct 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 */
112struct 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,}
127static 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 */
563static 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 */
1076static 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
1093static 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
1119out:
1120 mutex_unlock(&ab->access_mutex);
1121 return err;
1122}
1123
1124static 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
1158static int
1159set_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 */
1167static 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
1180static 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
1199static bool reg_write_allowed(u8 devid, u8 bank, u8 reg)
1200{
1201 return page_write_allowed(devid, bank, reg, reg);
1202}
1203
1204static 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
1237static 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 */
1246static 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
1253static 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
1268static 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
1275static 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
1289static 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
1305static int
1306ab5500_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
1318static 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
1331static 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};
1828static 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
1874static int ab5500_registers_open(struct inode *inode, struct file *file)
1875{
1876 return single_open(file, ab5500_registers_print, inode->i_private);
1877}
1878
1879static 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
1887static 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
1895static int ab5500_bank_open(struct inode *inode, struct file *file)
1896{
1897 return single_open(file, ab5500_bank_print, inode->i_private);
1898}
1899
1900static 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
1931static 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
1939static int ab5500_address_open(struct inode *inode, struct file *file)
1940{
1941 return single_open(file, ab5500_address_print, inode->i_private);
1942}
1943
1944static 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
1972static 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
1991static int ab5500_val_open(struct inode *inode, struct file *file)
1992{
1993 return single_open(file, ab5500_val_print, inode->i_private);
1994}
1995
1996static 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
2035static 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
2044static 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
2053static 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
2062static struct dentry *ab5500_dir;
2063static struct dentry *ab5500_reg_file;
2064static struct dentry *ab5500_bank_file;
2065static struct dentry *ab5500_address_file;
2066static struct dentry *ab5500_val_file;
2067
2068static 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
2099exit_destroy_address:
2100 debugfs_remove(ab5500_address_file);
2101exit_destroy_bank:
2102 debugfs_remove(ab5500_bank_file);
2103exit_destroy_reg:
2104 debugfs_remove(ab5500_reg_file);
2105exit_destroy_dir:
2106 debugfs_remove(ab5500_dir);
2107exit_no_debugfs:
2108 dev_err(ab->dev, "failed to create debugfs entries.\n");
2109 return;
2110}
2111
2112static 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 */
2122static inline void ab5500_setup_debugfs(struct ab5500 *ab)
2123{
2124}
2125static 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 */
2138static 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 }
2160exit_no_setup:
2161 return err;
2162}
2163
2164struct ab_family_id {
2165 u8 id;
2166 char *name;
2167};
2168
2169static 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
2185static 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
2274exit_no_detect:
2275 kfree(ab);
2276 return err;
2277}
2278
2279static 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
2289static struct platform_driver ab5500_driver = {
2290 .driver = {
2291 .name = "ab5500-core",
2292 .owner = THIS_MODULE,
2293 },
2294 .remove = __exit_p(ab5500_remove),
2295};
2296
2297static int __init ab5500_core_init(void)
2298{
2299 return platform_driver_probe(&ab5500_driver, ab5500_probe);
2300}
2301
2302static void __exit ab5500_core_exit(void)
2303{
2304 platform_driver_unregister(&ab5500_driver);
2305}
2306
2307subsys_initcall(ab5500_core_init);
2308module_exit(ab5500_core_exit);
2309
2310MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
2311MODULE_DESCRIPTION("AB5500 core driver");
2312MODULE_LICENSE("GPL");