diff options
author | Mattias Wallin <mattias.wallin@stericsson.com> | 2010-12-07 05:20:47 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-01-14 06:38:18 -0500 |
commit | 92d50a4132977b932ed830fa58c05deeb5c524f0 (patch) | |
tree | 1ee4ca4b6126861e30d5ac79ad61b0884b4d8627 /drivers/mfd/ab8500-core.c | |
parent | 180e4f5f20ef2b03ce2b38634274dde5ccbd8951 (diff) |
mfd: ab8500-core chip version cut 2.0 support
This patch adds support for chip version 2.0 or cut 2.0.
One new interrupt latch register - latch 12 - is introduced.
Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/ab8500-core.c')
-rw-r--r-- | drivers/mfd/ab8500-core.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 86cc8874e6de..b6887014d687 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #define AB8500_IT_LATCH8_REG 0x27 | 52 | #define AB8500_IT_LATCH8_REG 0x27 |
53 | #define AB8500_IT_LATCH9_REG 0x28 | 53 | #define AB8500_IT_LATCH9_REG 0x28 |
54 | #define AB8500_IT_LATCH10_REG 0x29 | 54 | #define AB8500_IT_LATCH10_REG 0x29 |
55 | #define AB8500_IT_LATCH12_REG 0x2B | ||
55 | #define AB8500_IT_LATCH19_REG 0x32 | 56 | #define AB8500_IT_LATCH19_REG 0x32 |
56 | #define AB8500_IT_LATCH20_REG 0x33 | 57 | #define AB8500_IT_LATCH20_REG 0x33 |
57 | #define AB8500_IT_LATCH21_REG 0x34 | 58 | #define AB8500_IT_LATCH21_REG 0x34 |
@@ -98,7 +99,7 @@ | |||
98 | * offset 0. | 99 | * offset 0. |
99 | */ | 100 | */ |
100 | static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { | 101 | static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { |
101 | 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, | 102 | 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, |
102 | }; | 103 | }; |
103 | 104 | ||
104 | static int ab8500_get_chip_id(struct device *dev) | 105 | static int ab8500_get_chip_id(struct device *dev) |
@@ -252,6 +253,10 @@ static void ab8500_irq_sync_unlock(struct irq_data *data) | |||
252 | if (new == old) | 253 | if (new == old) |
253 | continue; | 254 | continue; |
254 | 255 | ||
256 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ | ||
257 | if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) | ||
258 | continue; | ||
259 | |||
255 | ab8500->oldmask[i] = new; | 260 | ab8500->oldmask[i] = new; |
256 | 261 | ||
257 | reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; | 262 | reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; |
@@ -301,6 +306,10 @@ static irqreturn_t ab8500_irq(int irq, void *dev) | |||
301 | int status; | 306 | int status; |
302 | u8 value; | 307 | u8 value; |
303 | 308 | ||
309 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ | ||
310 | if (regoffset == 11 && ab8500->chip_id < 0x20) | ||
311 | continue; | ||
312 | |||
304 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, | 313 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, |
305 | AB8500_IT_LATCH1_REG + regoffset, &value); | 314 | AB8500_IT_LATCH1_REG + regoffset, &value); |
306 | if (status < 0 || value == 0) | 315 | if (status < 0 || value == 0) |
@@ -554,6 +563,12 @@ static struct resource ab8500_usb_resources[] = { | |||
554 | .end = AB8500_INT_VBUS_DET_R, | 563 | .end = AB8500_INT_VBUS_DET_R, |
555 | .flags = IORESOURCE_IRQ, | 564 | .flags = IORESOURCE_IRQ, |
556 | }, | 565 | }, |
566 | { | ||
567 | .name = "USB_LINK_STATUS", | ||
568 | .start = AB8500_INT_USB_LINK_STATUS, | ||
569 | .end = AB8500_INT_USB_LINK_STATUS, | ||
570 | .flags = IORESOURCE_IRQ, | ||
571 | }, | ||
557 | }; | 572 | }; |
558 | 573 | ||
559 | static struct resource ab8500_temp_resources[] = { | 574 | static struct resource ab8500_temp_resources[] = { |
@@ -670,8 +685,9 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
670 | * 0x0 - Early Drop | 685 | * 0x0 - Early Drop |
671 | * 0x10 - Cut 1.0 | 686 | * 0x10 - Cut 1.0 |
672 | * 0x11 - Cut 1.1 | 687 | * 0x11 - Cut 1.1 |
688 | * 0x20 - Cut 2.0 | ||
673 | */ | 689 | */ |
674 | if (value == 0x0 || value == 0x10 || value == 0x11) { | 690 | if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { |
675 | ab8500->revision = value; | 691 | ab8500->revision = value; |
676 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); | 692 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); |
677 | } else { | 693 | } else { |
@@ -684,18 +700,16 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
684 | plat->init(ab8500); | 700 | plat->init(ab8500); |
685 | 701 | ||
686 | /* Clear and mask all interrupts */ | 702 | /* Clear and mask all interrupts */ |
687 | for (i = 0; i < 10; i++) { | 703 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { |
688 | get_register_interruptible(ab8500, AB8500_INTERRUPT, | 704 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ |
689 | AB8500_IT_LATCH1_REG + i, &value); | 705 | if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) |
690 | set_register_interruptible(ab8500, AB8500_INTERRUPT, | 706 | continue; |
691 | AB8500_IT_MASK1_REG + i, 0xff); | ||
692 | } | ||
693 | 707 | ||
694 | for (i = 18; i < 24; i++) { | ||
695 | get_register_interruptible(ab8500, AB8500_INTERRUPT, | 708 | get_register_interruptible(ab8500, AB8500_INTERRUPT, |
696 | AB8500_IT_LATCH1_REG + i, &value); | 709 | AB8500_IT_LATCH1_REG + ab8500_irq_regoffset[i], |
710 | &value); | ||
697 | set_register_interruptible(ab8500, AB8500_INTERRUPT, | 711 | set_register_interruptible(ab8500, AB8500_INTERRUPT, |
698 | AB8500_IT_MASK1_REG + i, 0xff); | 712 | AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i], 0xff); |
699 | } | 713 | } |
700 | 714 | ||
701 | ret = abx500_register_ops(ab8500->dev, &ab8500_ops); | 715 | ret = abx500_register_ops(ab8500->dev, &ab8500_ops); |