mfd: New AB8500 driver

Add a new driver to support the AB8500 Power Management chip, replacing
the current AB4500. The new driver replaces the old one, instead of an
incremental modification, because this is a substantial overhaul
including:

- Split of the driver into -core and -spi portions, to allow another
interface layer to be added

- Addition of interrupt support

- Switch to MFD core API for handling subdevices

- Simplification of the APIs to remove a redundant block parameter

- Rename of the APIs and macros from ab4500_* to ab8500_*

- Rename of the files from ab4500* to ab8500*

- Change of the driver name from ab4500 to ab8500

Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Acked-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by Rabin Vincent and committed by Samuel Ortiz 62579266 75907a11

+712 -477
+1 -1
arch/arm/mach-ux500/board-mop500.c
··· 50 51 static struct spi_board_info u8500_spi_devices[] = { 52 { 53 - .modalias = "ab4500", 54 .controller_data = &ab4500_chip_info, 55 .max_speed_hz = 12000000, 56 .bus_num = 0,
··· 50 51 static struct spi_board_info u8500_spi_devices[] = { 52 { 53 + .modalias = "ab8500", 54 .controller_data = &ab4500_chip_info, 55 .max_speed_hz = 12000000, 56 .bus_num = 0,
+5 -4
drivers/mfd/Kconfig
··· 420 This enables the PCAP ASIC present on EZX Phones. This is 421 needed for MMC, TouchScreen, Sound, USB, etc.. 422 423 - config AB4500_CORE 424 - tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip" 425 - depends on SPI 426 help 427 - Select this option to enable access to AB4500 power management 428 chip. This connects to U8500 on the SSP/SPI bus and exports 429 read/write functions for the devices to get access to this chip. 430 This chip embeds various other multimedia funtionalities as well.
··· 420 This enables the PCAP ASIC present on EZX Phones. This is 421 needed for MMC, TouchScreen, Sound, USB, etc.. 422 423 + config AB8500_CORE 424 + bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" 425 + depends on SPI=y && GENERIC_HARDIRQS 426 + select MFD_CORE 427 help 428 + Select this option to enable access to AB8500 power management 429 chip. This connects to U8500 on the SSP/SPI bus and exports 430 read/write functions for the devices to get access to this chip. 431 This chip embeds various other multimedia funtionalities as well.
+1 -1
drivers/mfd/Makefile
··· 64 obj-$(CONFIG_ABX500_CORE) += abx500-core.o 65 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 66 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 67 - obj-$(CONFIG_AB4500_CORE) += ab4500-core.o 68 obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 69 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 70 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 71 obj-$(CONFIG_LPC_SCH) += lpc_sch.o
··· 64 obj-$(CONFIG_ABX500_CORE) += abx500-core.o 65 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 66 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 67 obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 68 + obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o 69 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 70 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 71 obj-$(CONFIG_LPC_SCH) += lpc_sch.o
-209
drivers/mfd/ab4500-core.c
··· 1 - /* 2 - * Copyright (C) 2009 ST-Ericsson 3 - * 4 - * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> 5 - * 6 - * This program is free software; you can redistribute it 7 - * and/or modify it under the terms of the GNU General Public 8 - * License version 2, as published by the Free Software Foundation. 9 - * 10 - * AB4500 is a companion power management chip used with U8500. 11 - * On this platform, this is interfaced with SSP0 controller 12 - * which is a ARM primecell pl022. 13 - * 14 - * At the moment the module just exports read/write features. 15 - * Interrupt management to be added - TODO. 16 - */ 17 - #include <linux/kernel.h> 18 - #include <linux/slab.h> 19 - #include <linux/init.h> 20 - #include <linux/module.h> 21 - #include <linux/platform_device.h> 22 - #include <linux/spi/spi.h> 23 - #include <linux/mfd/ab4500.h> 24 - 25 - /* just required if probe fails, we need to 26 - * unregister the device 27 - */ 28 - static struct spi_driver ab4500_driver; 29 - 30 - /* 31 - * This funtion writes to any AB4500 registers using 32 - * SPI protocol & before it writes it packs the data 33 - * in the below 24 bit frame format 34 - * 35 - * *|------------------------------------| 36 - * *| 23|22...18|17.......10|9|8|7......0| 37 - * *| r/w bank adr data | 38 - * * ------------------------------------ 39 - * 40 - * This function shouldn't be called from interrupt 41 - * context 42 - */ 43 - int ab4500_write(struct ab4500 *ab4500, unsigned char block, 44 - unsigned long addr, unsigned char data) 45 - { 46 - struct spi_transfer xfer; 47 - struct spi_message msg; 48 - int err; 49 - unsigned long spi_data = 50 - block << 18 | addr << 10 | data; 51 - 52 - mutex_lock(&ab4500->lock); 53 - ab4500->tx_buf[0] = spi_data; 54 - ab4500->rx_buf[0] = 0; 55 - 56 - xfer.tx_buf = ab4500->tx_buf; 57 - xfer.rx_buf = NULL; 58 - xfer.len = sizeof(unsigned long); 59 - 60 - spi_message_init(&msg); 61 - spi_message_add_tail(&xfer, &msg); 62 - 63 - err = spi_sync(ab4500->spi, &msg); 64 - mutex_unlock(&ab4500->lock); 65 - 66 - return err; 67 - } 68 - EXPORT_SYMBOL(ab4500_write); 69 - 70 - int ab4500_read(struct ab4500 *ab4500, unsigned char block, 71 - unsigned long addr) 72 - { 73 - struct spi_transfer xfer; 74 - struct spi_message msg; 75 - unsigned long spi_data = 76 - 1 << 23 | block << 18 | addr << 10; 77 - 78 - mutex_lock(&ab4500->lock); 79 - ab4500->tx_buf[0] = spi_data; 80 - ab4500->rx_buf[0] = 0; 81 - 82 - xfer.tx_buf = ab4500->tx_buf; 83 - xfer.rx_buf = ab4500->rx_buf; 84 - xfer.len = sizeof(unsigned long); 85 - 86 - spi_message_init(&msg); 87 - spi_message_add_tail(&xfer, &msg); 88 - 89 - spi_sync(ab4500->spi, &msg); 90 - mutex_unlock(&ab4500->lock); 91 - 92 - return ab4500->rx_buf[0]; 93 - } 94 - EXPORT_SYMBOL(ab4500_read); 95 - 96 - /* ref: ab3100 core */ 97 - #define AB4500_DEVICE(devname, devid) \ 98 - static struct platform_device ab4500_##devname##_device = { \ 99 - .name = devid, \ 100 - .id = -1, \ 101 - } 102 - 103 - /* list of childern devices of ab4500 - all are 104 - * not populated here - TODO 105 - */ 106 - AB4500_DEVICE(charger, "ab4500-charger"); 107 - AB4500_DEVICE(audio, "ab4500-audio"); 108 - AB4500_DEVICE(usb, "ab4500-usb"); 109 - AB4500_DEVICE(tvout, "ab4500-tvout"); 110 - AB4500_DEVICE(sim, "ab4500-sim"); 111 - AB4500_DEVICE(gpadc, "ab4500-gpadc"); 112 - AB4500_DEVICE(clkmgt, "ab4500-clkmgt"); 113 - AB4500_DEVICE(misc, "ab4500-misc"); 114 - 115 - static struct platform_device *ab4500_platform_devs[] = { 116 - &ab4500_charger_device, 117 - &ab4500_audio_device, 118 - &ab4500_usb_device, 119 - &ab4500_tvout_device, 120 - &ab4500_sim_device, 121 - &ab4500_gpadc_device, 122 - &ab4500_clkmgt_device, 123 - &ab4500_misc_device, 124 - }; 125 - 126 - static int __init ab4500_probe(struct spi_device *spi) 127 - { 128 - struct ab4500 *ab4500; 129 - unsigned char revision; 130 - int err = 0; 131 - int i; 132 - 133 - ab4500 = kzalloc(sizeof *ab4500, GFP_KERNEL); 134 - if (!ab4500) { 135 - dev_err(&spi->dev, "could not allocate AB4500\n"); 136 - err = -ENOMEM; 137 - goto not_detect; 138 - } 139 - 140 - ab4500->spi = spi; 141 - spi_set_drvdata(spi, ab4500); 142 - 143 - mutex_init(&ab4500->lock); 144 - 145 - /* read the revision register */ 146 - revision = ab4500_read(ab4500, AB4500_MISC, AB4500_REV_REG); 147 - 148 - /* revision id 0x0 is for early drop, 0x10 is for cut1.0 */ 149 - if (revision == 0x0 || revision == 0x10) 150 - dev_info(&spi->dev, "Detected chip: %s, revision = %x\n", 151 - ab4500_driver.driver.name, revision); 152 - else { 153 - dev_err(&spi->dev, "unknown chip: 0x%x\n", revision); 154 - goto not_detect; 155 - } 156 - 157 - for (i = 0; i < ARRAY_SIZE(ab4500_platform_devs); i++) { 158 - ab4500_platform_devs[i]->dev.parent = 159 - &spi->dev; 160 - platform_set_drvdata(ab4500_platform_devs[i], ab4500); 161 - } 162 - 163 - /* register the ab4500 platform devices */ 164 - platform_add_devices(ab4500_platform_devs, 165 - ARRAY_SIZE(ab4500_platform_devs)); 166 - 167 - return err; 168 - 169 - not_detect: 170 - spi_unregister_driver(&ab4500_driver); 171 - kfree(ab4500); 172 - return err; 173 - } 174 - 175 - static int __devexit ab4500_remove(struct spi_device *spi) 176 - { 177 - struct ab4500 *ab4500 = 178 - spi_get_drvdata(spi); 179 - 180 - kfree(ab4500); 181 - 182 - return 0; 183 - } 184 - 185 - static struct spi_driver ab4500_driver = { 186 - .driver = { 187 - .name = "ab4500", 188 - .owner = THIS_MODULE, 189 - }, 190 - .probe = ab4500_probe, 191 - .remove = __devexit_p(ab4500_remove) 192 - }; 193 - 194 - static int __devinit ab4500_init(void) 195 - { 196 - return spi_register_driver(&ab4500_driver); 197 - } 198 - 199 - static void __exit ab4500_exit(void) 200 - { 201 - spi_unregister_driver(&ab4500_driver); 202 - } 203 - 204 - subsys_initcall(ab4500_init); 205 - module_exit(ab4500_exit); 206 - 207 - MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com"); 208 - MODULE_DESCRIPTION("AB4500 core driver"); 209 - MODULE_LICENSE("GPL");
···
+444
drivers/mfd/ab8500-core.c
···
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 6 + * Author: Rabin Vincent <rabin.vincent@stericsson.com> 7 + */ 8 + 9 + #include <linux/kernel.h> 10 + #include <linux/slab.h> 11 + #include <linux/init.h> 12 + #include <linux/irq.h> 13 + #include <linux/delay.h> 14 + #include <linux/interrupt.h> 15 + #include <linux/module.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/mfd/core.h> 18 + #include <linux/mfd/ab8500.h> 19 + 20 + /* 21 + * Interrupt register offsets 22 + * Bank : 0x0E 23 + */ 24 + #define AB8500_IT_SOURCE1_REG 0x0E00 25 + #define AB8500_IT_SOURCE2_REG 0x0E01 26 + #define AB8500_IT_SOURCE3_REG 0x0E02 27 + #define AB8500_IT_SOURCE4_REG 0x0E03 28 + #define AB8500_IT_SOURCE5_REG 0x0E04 29 + #define AB8500_IT_SOURCE6_REG 0x0E05 30 + #define AB8500_IT_SOURCE7_REG 0x0E06 31 + #define AB8500_IT_SOURCE8_REG 0x0E07 32 + #define AB8500_IT_SOURCE19_REG 0x0E12 33 + #define AB8500_IT_SOURCE20_REG 0x0E13 34 + #define AB8500_IT_SOURCE21_REG 0x0E14 35 + #define AB8500_IT_SOURCE22_REG 0x0E15 36 + #define AB8500_IT_SOURCE23_REG 0x0E16 37 + #define AB8500_IT_SOURCE24_REG 0x0E17 38 + 39 + /* 40 + * latch registers 41 + */ 42 + #define AB8500_IT_LATCH1_REG 0x0E20 43 + #define AB8500_IT_LATCH2_REG 0x0E21 44 + #define AB8500_IT_LATCH3_REG 0x0E22 45 + #define AB8500_IT_LATCH4_REG 0x0E23 46 + #define AB8500_IT_LATCH5_REG 0x0E24 47 + #define AB8500_IT_LATCH6_REG 0x0E25 48 + #define AB8500_IT_LATCH7_REG 0x0E26 49 + #define AB8500_IT_LATCH8_REG 0x0E27 50 + #define AB8500_IT_LATCH9_REG 0x0E28 51 + #define AB8500_IT_LATCH10_REG 0x0E29 52 + #define AB8500_IT_LATCH19_REG 0x0E32 53 + #define AB8500_IT_LATCH20_REG 0x0E33 54 + #define AB8500_IT_LATCH21_REG 0x0E34 55 + #define AB8500_IT_LATCH22_REG 0x0E35 56 + #define AB8500_IT_LATCH23_REG 0x0E36 57 + #define AB8500_IT_LATCH24_REG 0x0E37 58 + 59 + /* 60 + * mask registers 61 + */ 62 + 63 + #define AB8500_IT_MASK1_REG 0x0E40 64 + #define AB8500_IT_MASK2_REG 0x0E41 65 + #define AB8500_IT_MASK3_REG 0x0E42 66 + #define AB8500_IT_MASK4_REG 0x0E43 67 + #define AB8500_IT_MASK5_REG 0x0E44 68 + #define AB8500_IT_MASK6_REG 0x0E45 69 + #define AB8500_IT_MASK7_REG 0x0E46 70 + #define AB8500_IT_MASK8_REG 0x0E47 71 + #define AB8500_IT_MASK9_REG 0x0E48 72 + #define AB8500_IT_MASK10_REG 0x0E49 73 + #define AB8500_IT_MASK11_REG 0x0E4A 74 + #define AB8500_IT_MASK12_REG 0x0E4B 75 + #define AB8500_IT_MASK13_REG 0x0E4C 76 + #define AB8500_IT_MASK14_REG 0x0E4D 77 + #define AB8500_IT_MASK15_REG 0x0E4E 78 + #define AB8500_IT_MASK16_REG 0x0E4F 79 + #define AB8500_IT_MASK17_REG 0x0E50 80 + #define AB8500_IT_MASK18_REG 0x0E51 81 + #define AB8500_IT_MASK19_REG 0x0E52 82 + #define AB8500_IT_MASK20_REG 0x0E53 83 + #define AB8500_IT_MASK21_REG 0x0E54 84 + #define AB8500_IT_MASK22_REG 0x0E55 85 + #define AB8500_IT_MASK23_REG 0x0E56 86 + #define AB8500_IT_MASK24_REG 0x0E57 87 + 88 + #define AB8500_REV_REG 0x1080 89 + 90 + /* 91 + * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt 92 + * numbers are indexed into this array with (num / 8). 93 + * 94 + * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at 95 + * offset 0. 96 + */ 97 + static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { 98 + 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, 99 + }; 100 + 101 + static int __ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data) 102 + { 103 + int ret; 104 + 105 + dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data); 106 + 107 + ret = ab8500->write(ab8500, addr, data); 108 + if (ret < 0) 109 + dev_err(ab8500->dev, "failed to write reg %#x: %d\n", 110 + addr, ret); 111 + 112 + return ret; 113 + } 114 + 115 + /** 116 + * ab8500_write() - write an AB8500 register 117 + * @ab8500: device to write to 118 + * @addr: address of the register 119 + * @data: value to write 120 + */ 121 + int ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data) 122 + { 123 + int ret; 124 + 125 + mutex_lock(&ab8500->lock); 126 + ret = __ab8500_write(ab8500, addr, data); 127 + mutex_unlock(&ab8500->lock); 128 + 129 + return ret; 130 + } 131 + EXPORT_SYMBOL_GPL(ab8500_write); 132 + 133 + static int __ab8500_read(struct ab8500 *ab8500, u16 addr) 134 + { 135 + int ret; 136 + 137 + ret = ab8500->read(ab8500, addr); 138 + if (ret < 0) 139 + dev_err(ab8500->dev, "failed to read reg %#x: %d\n", 140 + addr, ret); 141 + 142 + dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret); 143 + 144 + return ret; 145 + } 146 + 147 + /** 148 + * ab8500_read() - read an AB8500 register 149 + * @ab8500: device to read from 150 + * @addr: address of the register 151 + */ 152 + int ab8500_read(struct ab8500 *ab8500, u16 addr) 153 + { 154 + int ret; 155 + 156 + mutex_lock(&ab8500->lock); 157 + ret = __ab8500_read(ab8500, addr); 158 + mutex_unlock(&ab8500->lock); 159 + 160 + return ret; 161 + } 162 + EXPORT_SYMBOL_GPL(ab8500_read); 163 + 164 + /** 165 + * ab8500_set_bits() - set a bitfield in an AB8500 register 166 + * @ab8500: device to read from 167 + * @addr: address of the register 168 + * @mask: mask of the bitfield to modify 169 + * @data: value to set to the bitfield 170 + */ 171 + int ab8500_set_bits(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data) 172 + { 173 + int ret; 174 + 175 + mutex_lock(&ab8500->lock); 176 + 177 + ret = __ab8500_read(ab8500, addr); 178 + if (ret < 0) 179 + goto out; 180 + 181 + ret &= ~mask; 182 + ret |= data; 183 + 184 + ret = __ab8500_write(ab8500, addr, ret); 185 + 186 + out: 187 + mutex_unlock(&ab8500->lock); 188 + return ret; 189 + } 190 + EXPORT_SYMBOL_GPL(ab8500_set_bits); 191 + 192 + static void ab8500_irq_lock(unsigned int irq) 193 + { 194 + struct ab8500 *ab8500 = get_irq_chip_data(irq); 195 + 196 + mutex_lock(&ab8500->irq_lock); 197 + } 198 + 199 + static void ab8500_irq_sync_unlock(unsigned int irq) 200 + { 201 + struct ab8500 *ab8500 = get_irq_chip_data(irq); 202 + int i; 203 + 204 + for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { 205 + u8 old = ab8500->oldmask[i]; 206 + u8 new = ab8500->mask[i]; 207 + int reg; 208 + 209 + if (new == old) 210 + continue; 211 + 212 + ab8500->oldmask[i] = new; 213 + 214 + reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; 215 + ab8500_write(ab8500, reg, new); 216 + } 217 + 218 + mutex_unlock(&ab8500->irq_lock); 219 + } 220 + 221 + static void ab8500_irq_mask(unsigned int irq) 222 + { 223 + struct ab8500 *ab8500 = get_irq_chip_data(irq); 224 + int offset = irq - ab8500->irq_base; 225 + int index = offset / 8; 226 + int mask = 1 << (offset % 8); 227 + 228 + ab8500->mask[index] |= mask; 229 + } 230 + 231 + static void ab8500_irq_unmask(unsigned int irq) 232 + { 233 + struct ab8500 *ab8500 = get_irq_chip_data(irq); 234 + int offset = irq - ab8500->irq_base; 235 + int index = offset / 8; 236 + int mask = 1 << (offset % 8); 237 + 238 + ab8500->mask[index] &= ~mask; 239 + } 240 + 241 + static struct irq_chip ab8500_irq_chip = { 242 + .name = "ab8500", 243 + .bus_lock = ab8500_irq_lock, 244 + .bus_sync_unlock = ab8500_irq_sync_unlock, 245 + .mask = ab8500_irq_mask, 246 + .unmask = ab8500_irq_unmask, 247 + }; 248 + 249 + static irqreturn_t ab8500_irq(int irq, void *dev) 250 + { 251 + struct ab8500 *ab8500 = dev; 252 + int i; 253 + 254 + dev_vdbg(ab8500->dev, "interrupt\n"); 255 + 256 + for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { 257 + int regoffset = ab8500_irq_regoffset[i]; 258 + int status; 259 + 260 + status = ab8500_read(ab8500, AB8500_IT_LATCH1_REG + regoffset); 261 + if (status <= 0) 262 + continue; 263 + 264 + do { 265 + int bit = __ffs(status); 266 + int line = i * 8 + bit; 267 + 268 + handle_nested_irq(ab8500->irq_base + line); 269 + status &= ~(1 << bit); 270 + } while (status); 271 + } 272 + 273 + return IRQ_HANDLED; 274 + } 275 + 276 + static int ab8500_irq_init(struct ab8500 *ab8500) 277 + { 278 + int base = ab8500->irq_base; 279 + int irq; 280 + 281 + for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { 282 + set_irq_chip_data(irq, ab8500); 283 + set_irq_chip_and_handler(irq, &ab8500_irq_chip, 284 + handle_simple_irq); 285 + set_irq_nested_thread(irq, 1); 286 + #ifdef CONFIG_ARM 287 + set_irq_flags(irq, IRQF_VALID); 288 + #else 289 + set_irq_noprobe(irq); 290 + #endif 291 + } 292 + 293 + return 0; 294 + } 295 + 296 + static void ab8500_irq_remove(struct ab8500 *ab8500) 297 + { 298 + int base = ab8500->irq_base; 299 + int irq; 300 + 301 + for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { 302 + #ifdef CONFIG_ARM 303 + set_irq_flags(irq, 0); 304 + #endif 305 + set_irq_chip_and_handler(irq, NULL, NULL); 306 + set_irq_chip_data(irq, NULL); 307 + } 308 + } 309 + 310 + static struct resource ab8500_gpadc_resources[] = { 311 + { 312 + .name = "HW_CONV_END", 313 + .start = AB8500_INT_GP_HW_ADC_CONV_END, 314 + .end = AB8500_INT_GP_HW_ADC_CONV_END, 315 + .flags = IORESOURCE_IRQ, 316 + }, 317 + { 318 + .name = "SW_CONV_END", 319 + .start = AB8500_INT_GP_SW_ADC_CONV_END, 320 + .end = AB8500_INT_GP_SW_ADC_CONV_END, 321 + .flags = IORESOURCE_IRQ, 322 + }, 323 + }; 324 + 325 + static struct resource ab8500_rtc_resources[] = { 326 + { 327 + .name = "60S", 328 + .start = AB8500_INT_RTC_60S, 329 + .end = AB8500_INT_RTC_60S, 330 + .flags = IORESOURCE_IRQ, 331 + }, 332 + { 333 + .name = "ALARM", 334 + .start = AB8500_INT_RTC_ALARM, 335 + .end = AB8500_INT_RTC_ALARM, 336 + .flags = IORESOURCE_IRQ, 337 + }, 338 + }; 339 + 340 + static struct mfd_cell ab8500_devs[] = { 341 + { 342 + .name = "ab8500-gpadc", 343 + .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), 344 + .resources = ab8500_gpadc_resources, 345 + }, 346 + { 347 + .name = "ab8500-rtc", 348 + .num_resources = ARRAY_SIZE(ab8500_rtc_resources), 349 + .resources = ab8500_rtc_resources, 350 + }, 351 + { .name = "ab8500-charger", }, 352 + { .name = "ab8500-audio", }, 353 + { .name = "ab8500-usb", }, 354 + { .name = "ab8500-pwm", }, 355 + }; 356 + 357 + int __devinit ab8500_init(struct ab8500 *ab8500) 358 + { 359 + struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); 360 + int ret; 361 + int i; 362 + 363 + if (plat) 364 + ab8500->irq_base = plat->irq_base; 365 + 366 + mutex_init(&ab8500->lock); 367 + mutex_init(&ab8500->irq_lock); 368 + 369 + ret = ab8500_read(ab8500, AB8500_REV_REG); 370 + if (ret < 0) 371 + return ret; 372 + 373 + /* 374 + * 0x0 - Early Drop 375 + * 0x10 - Cut 1.0 376 + * 0x11 - Cut 1.1 377 + */ 378 + if (ret == 0x0 || ret == 0x10 || ret == 0x11) { 379 + ab8500->revision = ret; 380 + dev_info(ab8500->dev, "detected chip, revision: %#x\n", ret); 381 + } else { 382 + dev_err(ab8500->dev, "unknown chip, revision: %#x\n", ret); 383 + return -EINVAL; 384 + } 385 + 386 + if (plat && plat->init) 387 + plat->init(ab8500); 388 + 389 + /* Clear and mask all interrupts */ 390 + for (i = 0; i < 10; i++) { 391 + ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); 392 + ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); 393 + } 394 + 395 + for (i = 18; i < 24; i++) { 396 + ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); 397 + ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); 398 + } 399 + 400 + for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) 401 + ab8500->mask[i] = ab8500->oldmask[i] = 0xff; 402 + 403 + if (ab8500->irq_base) { 404 + ret = ab8500_irq_init(ab8500); 405 + if (ret) 406 + return ret; 407 + 408 + ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, 409 + IRQF_ONESHOT, "ab8500", ab8500); 410 + if (ret) 411 + goto out_removeirq; 412 + } 413 + 414 + ret = mfd_add_devices(ab8500->dev, -1, ab8500_devs, 415 + ARRAY_SIZE(ab8500_devs), NULL, 416 + ab8500->irq_base); 417 + if (ret) 418 + goto out_freeirq; 419 + 420 + return ret; 421 + 422 + out_freeirq: 423 + if (ab8500->irq_base) { 424 + free_irq(ab8500->irq, ab8500); 425 + out_removeirq: 426 + ab8500_irq_remove(ab8500); 427 + } 428 + return ret; 429 + } 430 + 431 + int __devexit ab8500_exit(struct ab8500 *ab8500) 432 + { 433 + mfd_remove_devices(ab8500->dev); 434 + if (ab8500->irq_base) { 435 + free_irq(ab8500->irq, ab8500); 436 + ab8500_irq_remove(ab8500); 437 + } 438 + 439 + return 0; 440 + } 441 + 442 + MODULE_AUTHOR("Srinidhi Kasagar, Rabin Vincent"); 443 + MODULE_DESCRIPTION("AB8500 MFD core"); 444 + MODULE_LICENSE("GPL v2");
+133
drivers/mfd/ab8500-spi.c
···
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/slab.h> 10 + #include <linux/init.h> 11 + #include <linux/module.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/spi/spi.h> 14 + #include <linux/mfd/ab8500.h> 15 + 16 + /* 17 + * This funtion writes to any AB8500 registers using 18 + * SPI protocol & before it writes it packs the data 19 + * in the below 24 bit frame format 20 + * 21 + * *|------------------------------------| 22 + * *| 23|22...18|17.......10|9|8|7......0| 23 + * *| r/w bank adr data | 24 + * * ------------------------------------ 25 + * 26 + * This function shouldn't be called from interrupt 27 + * context 28 + */ 29 + static int ab8500_spi_write(struct ab8500 *ab8500, u16 addr, u8 data) 30 + { 31 + struct spi_device *spi = container_of(ab8500->dev, struct spi_device, 32 + dev); 33 + unsigned long spi_data = addr << 10 | data; 34 + struct spi_transfer xfer; 35 + struct spi_message msg; 36 + 37 + ab8500->tx_buf[0] = spi_data; 38 + ab8500->rx_buf[0] = 0; 39 + 40 + xfer.tx_buf = ab8500->tx_buf; 41 + xfer.rx_buf = NULL; 42 + xfer.len = sizeof(unsigned long); 43 + 44 + spi_message_init(&msg); 45 + spi_message_add_tail(&xfer, &msg); 46 + 47 + return spi_sync(spi, &msg); 48 + } 49 + 50 + static int ab8500_spi_read(struct ab8500 *ab8500, u16 addr) 51 + { 52 + struct spi_device *spi = container_of(ab8500->dev, struct spi_device, 53 + dev); 54 + unsigned long spi_data = 1 << 23 | addr << 10; 55 + struct spi_transfer xfer; 56 + struct spi_message msg; 57 + int ret; 58 + 59 + ab8500->tx_buf[0] = spi_data; 60 + ab8500->rx_buf[0] = 0; 61 + 62 + xfer.tx_buf = ab8500->tx_buf; 63 + xfer.rx_buf = ab8500->rx_buf; 64 + xfer.len = sizeof(unsigned long); 65 + 66 + spi_message_init(&msg); 67 + spi_message_add_tail(&xfer, &msg); 68 + 69 + ret = spi_sync(spi, &msg); 70 + if (!ret) 71 + ret = ab8500->rx_buf[0]; 72 + 73 + return ret; 74 + } 75 + 76 + static int __devinit ab8500_spi_probe(struct spi_device *spi) 77 + { 78 + struct ab8500 *ab8500; 79 + int ret; 80 + 81 + ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); 82 + if (!ab8500) 83 + return -ENOMEM; 84 + 85 + ab8500->dev = &spi->dev; 86 + ab8500->irq = spi->irq; 87 + 88 + ab8500->read = ab8500_spi_read; 89 + ab8500->write = ab8500_spi_write; 90 + 91 + spi_set_drvdata(spi, ab8500); 92 + 93 + ret = ab8500_init(ab8500); 94 + if (ret) 95 + kfree(ab8500); 96 + 97 + return ret; 98 + } 99 + 100 + static int __devexit ab8500_spi_remove(struct spi_device *spi) 101 + { 102 + struct ab8500 *ab8500 = spi_get_drvdata(spi); 103 + 104 + ab8500_exit(ab8500); 105 + kfree(ab8500); 106 + 107 + return 0; 108 + } 109 + 110 + static struct spi_driver ab8500_spi_driver = { 111 + .driver = { 112 + .name = "ab8500", 113 + .owner = THIS_MODULE, 114 + }, 115 + .probe = ab8500_spi_probe, 116 + .remove = __devexit_p(ab8500_spi_remove) 117 + }; 118 + 119 + static int __init ab8500_spi_init(void) 120 + { 121 + return spi_register_driver(&ab8500_spi_driver); 122 + } 123 + subsys_initcall(ab8500_spi_init); 124 + 125 + static void __exit ab8500_spi_exit(void) 126 + { 127 + spi_unregister_driver(&ab8500_spi_driver); 128 + } 129 + module_exit(ab8500_spi_exit); 130 + 131 + MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com"); 132 + MODULE_DESCRIPTION("AB8500 SPI"); 133 + MODULE_LICENSE("GPL v2");
-262
include/linux/mfd/ab4500.h
··· 1 - /* 2 - * Copyright (C) 2009 ST-Ericsson 3 - * 4 - * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2, as 8 - * published by the Free Software Foundation. 9 - * 10 - * AB4500 device core funtions, for client access 11 - */ 12 - #ifndef MFD_AB4500_H 13 - #define MFD_AB4500_H 14 - 15 - #include <linux/device.h> 16 - 17 - /* 18 - * AB4500 bank addresses 19 - */ 20 - #define AB4500_SYS_CTRL1_BLOCK 0x1 21 - #define AB4500_SYS_CTRL2_BLOCK 0x2 22 - #define AB4500_REGU_CTRL1 0x3 23 - #define AB4500_REGU_CTRL2 0x4 24 - #define AB4500_USB 0x5 25 - #define AB4500_TVOUT 0x6 26 - #define AB4500_DBI 0x7 27 - #define AB4500_ECI_AV_ACC 0x8 28 - #define AB4500_RESERVED 0x9 29 - #define AB4500_GPADC 0xA 30 - #define AB4500_CHARGER 0xB 31 - #define AB4500_GAS_GAUGE 0xC 32 - #define AB4500_AUDIO 0xD 33 - #define AB4500_INTERRUPT 0xE 34 - #define AB4500_RTC 0xF 35 - #define AB4500_MISC 0x10 36 - #define AB4500_DEBUG 0x12 37 - #define AB4500_PROD_TEST 0x13 38 - #define AB4500_OTP_EMUL 0x15 39 - 40 - /* 41 - * System control 1 register offsets. 42 - * Bank = 0x01 43 - */ 44 - #define AB4500_TURNON_STAT_REG 0x0100 45 - #define AB4500_RESET_STAT_REG 0x0101 46 - #define AB4500_PONKEY1_PRESS_STAT_REG 0x0102 47 - 48 - #define AB4500_FSM_STAT1_REG 0x0140 49 - #define AB4500_FSM_STAT2_REG 0x0141 50 - #define AB4500_SYSCLK_REQ_STAT_REG 0x0142 51 - #define AB4500_USB_STAT1_REG 0x0143 52 - #define AB4500_USB_STAT2_REG 0x0144 53 - #define AB4500_STATUS_SPARE1_REG 0x0145 54 - #define AB4500_STATUS_SPARE2_REG 0x0146 55 - 56 - #define AB4500_CTRL1_REG 0x0180 57 - #define AB4500_CTRL2_REG 0x0181 58 - 59 - /* 60 - * System control 2 register offsets. 61 - * bank = 0x02 62 - */ 63 - #define AB4500_CTRL3_REG 0x0200 64 - #define AB4500_MAIN_WDOG_CTRL_REG 0x0201 65 - #define AB4500_MAIN_WDOG_TIMER_REG 0x0202 66 - #define AB4500_LOW_BAT_REG 0x0203 67 - #define AB4500_BATT_OK_REG 0x0204 68 - #define AB4500_SYSCLK_TIMER_REG 0x0205 69 - #define AB4500_SMPSCLK_CTRL_REG 0x0206 70 - #define AB4500_SMPSCLK_SEL1_REG 0x0207 71 - #define AB4500_SMPSCLK_SEL2_REG 0x0208 72 - #define AB4500_SMPSCLK_SEL3_REG 0x0209 73 - #define AB4500_SYSULPCLK_CONF_REG 0x020A 74 - #define AB4500_SYSULPCLK_CTRL1_REG 0x020B 75 - #define AB4500_SYSCLK_CTRL_REG 0x020C 76 - #define AB4500_SYSCLK_REQ1_VALID_REG 0x020D 77 - #define AB4500_SYSCLK_REQ_VALID_REG 0x020E 78 - #define AB4500_SYSCTRL_SPARE_REG 0x020F 79 - #define AB4500_PAD_CONF_REG 0x0210 80 - 81 - /* 82 - * Regu control1 register offsets 83 - * Bank = 0x03 84 - */ 85 - #define AB4500_REGU_SERIAL_CTRL1_REG 0x0300 86 - #define AB4500_REGU_SERIAL_CTRL2_REG 0x0301 87 - #define AB4500_REGU_SERIAL_CTRL3_REG 0x0302 88 - #define AB4500_REGU_REQ_CTRL1_REG 0x0303 89 - #define AB4500_REGU_REQ_CTRL2_REG 0x0304 90 - #define AB4500_REGU_REQ_CTRL3_REG 0x0305 91 - #define AB4500_REGU_REQ_CTRL4_REG 0x0306 92 - #define AB4500_REGU_MISC1_REG 0x0380 93 - #define AB4500_REGU_OTGSUPPLY_CTRL_REG 0x0381 94 - #define AB4500_REGU_VUSB_CTRL_REG 0x0382 95 - #define AB4500_REGU_VAUDIO_SUPPLY_REG 0x0383 96 - #define AB4500_REGU_CTRL1_SPARE_REG 0x0384 97 - 98 - /* 99 - * Regu control2 Vmod register offsets 100 - */ 101 - #define AB4500_REGU_VMOD_REGU_REG 0x0440 102 - #define AB4500_REGU_VMOD_SEL1_REG 0x0441 103 - #define AB4500_REGU_VMOD_SEL2_REG 0x0442 104 - #define AB4500_REGU_CTRL_DISCH_REG 0x0443 105 - #define AB4500_REGU_CTRL_DISCH2_REG 0x0444 106 - 107 - /* 108 - * USB/ULPI register offsets 109 - * Bank : 0x5 110 - */ 111 - #define AB4500_USB_LINE_STAT_REG 0x0580 112 - #define AB4500_USB_LINE_CTRL1_REG 0x0581 113 - #define AB4500_USB_LINE_CTRL2_REG 0x0582 114 - #define AB4500_USB_LINE_CTRL3_REG 0x0583 115 - #define AB4500_USB_LINE_CTRL4_REG 0x0584 116 - #define AB4500_USB_LINE_CTRL5_REG 0x0585 117 - #define AB4500_USB_OTG_CTRL_REG 0x0587 118 - #define AB4500_USB_OTG_STAT_REG 0x0588 119 - #define AB4500_USB_OTG_STAT_REG 0x0588 120 - #define AB4500_USB_CTRL_SPARE_REG 0x0589 121 - #define AB4500_USB_PHY_CTRL_REG 0x058A 122 - 123 - /* 124 - * TVOUT / CTRL register offsets 125 - * Bank : 0x06 126 - */ 127 - #define AB4500_TVOUT_CTRL_REG 0x0680 128 - 129 - /* 130 - * DBI register offsets 131 - * Bank : 0x07 132 - */ 133 - #define AB4500_DBI_REG1_REG 0x0700 134 - #define AB4500_DBI_REG2_REG 0x0701 135 - 136 - /* 137 - * ECI regsiter offsets 138 - * Bank : 0x08 139 - */ 140 - #define AB4500_ECI_CTRL_REG 0x0800 141 - #define AB4500_ECI_HOOKLEVEL_REG 0x0801 142 - #define AB4500_ECI_DATAOUT_REG 0x0802 143 - #define AB4500_ECI_DATAIN_REG 0x0803 144 - 145 - /* 146 - * AV Connector register offsets 147 - * Bank : 0x08 148 - */ 149 - #define AB4500_AV_CONN_REG 0x0840 150 - 151 - /* 152 - * Accessory detection register offsets 153 - * Bank : 0x08 154 - */ 155 - #define AB4500_ACC_DET_DB1_REG 0x0880 156 - #define AB4500_ACC_DET_DB2_REG 0x0881 157 - 158 - /* 159 - * GPADC register offsets 160 - * Bank : 0x0A 161 - */ 162 - #define AB4500_GPADC_CTRL1_REG 0x0A00 163 - #define AB4500_GPADC_CTRL2_REG 0x0A01 164 - #define AB4500_GPADC_CTRL3_REG 0x0A02 165 - #define AB4500_GPADC_AUTO_TIMER_REG 0x0A03 166 - #define AB4500_GPADC_STAT_REG 0x0A04 167 - #define AB4500_GPADC_MANDATAL_REG 0x0A05 168 - #define AB4500_GPADC_MANDATAH_REG 0x0A06 169 - #define AB4500_GPADC_AUTODATAL_REG 0x0A07 170 - #define AB4500_GPADC_AUTODATAH_REG 0x0A08 171 - #define AB4500_GPADC_MUX_CTRL_REG 0x0A09 172 - 173 - /* 174 - * Charger / status register offfsets 175 - * Bank : 0x0B 176 - */ 177 - #define AB4500_CH_STATUS1_REG 0x0B00 178 - #define AB4500_CH_STATUS2_REG 0x0B01 179 - #define AB4500_CH_USBCH_STAT1_REG 0x0B02 180 - #define AB4500_CH_USBCH_STAT2_REG 0x0B03 181 - #define AB4500_CH_FSM_STAT_REG 0x0B04 182 - #define AB4500_CH_STAT_REG 0x0B05 183 - 184 - /* 185 - * Charger / control register offfsets 186 - * Bank : 0x0B 187 - */ 188 - #define AB4500_CH_VOLT_LVL_REG 0x0B40 189 - 190 - /* 191 - * Charger / main control register offfsets 192 - * Bank : 0x0B 193 - */ 194 - #define AB4500_MCH_CTRL1 0x0B80 195 - #define AB4500_MCH_CTRL2 0x0B81 196 - #define AB4500_MCH_IPT_CURLVL_REG 0x0B82 197 - #define AB4500_CH_WD_REG 0x0B83 198 - 199 - /* 200 - * Charger / USB control register offsets 201 - * Bank : 0x0B 202 - */ 203 - #define AB4500_USBCH_CTRL1_REG 0x0BC0 204 - #define AB4500_USBCH_CTRL2_REG 0x0BC1 205 - #define AB4500_USBCH_IPT_CRNTLVL_REG 0x0BC2 206 - 207 - /* 208 - * RTC bank register offsets 209 - * Bank : 0xF 210 - */ 211 - #define AB4500_RTC_SOFF_STAT_REG 0x0F00 212 - #define AB4500_RTC_CC_CONF_REG 0x0F01 213 - #define AB4500_RTC_READ_REQ_REG 0x0F02 214 - #define AB4500_RTC_WATCH_TSECMID_REG 0x0F03 215 - #define AB4500_RTC_WATCH_TSECHI_REG 0x0F04 216 - #define AB4500_RTC_WATCH_TMIN_LOW_REG 0x0F05 217 - #define AB4500_RTC_WATCH_TMIN_MID_REG 0x0F06 218 - #define AB4500_RTC_WATCH_TMIN_HI_REG 0x0F07 219 - #define AB4500_RTC_ALRM_MIN_LOW_REG 0x0F08 220 - #define AB4500_RTC_ALRM_MIN_MID_REG 0x0F09 221 - #define AB4500_RTC_ALRM_MIN_HI_REG 0x0F0A 222 - #define AB4500_RTC_STAT_REG 0x0F0B 223 - #define AB4500_RTC_BKUP_CHG_REG 0x0F0C 224 - #define AB4500_RTC_FORCE_BKUP_REG 0x0F0D 225 - #define AB4500_RTC_CALIB_REG 0x0F0E 226 - #define AB4500_RTC_SWITCH_STAT_REG 0x0F0F 227 - 228 - /* 229 - * PWM Out generators 230 - * Bank: 0x10 231 - */ 232 - #define AB4500_PWM_OUT_CTRL1_REG 0x1060 233 - #define AB4500_PWM_OUT_CTRL2_REG 0x1061 234 - #define AB4500_PWM_OUT_CTRL3_REG 0x1062 235 - #define AB4500_PWM_OUT_CTRL4_REG 0x1063 236 - #define AB4500_PWM_OUT_CTRL5_REG 0x1064 237 - #define AB4500_PWM_OUT_CTRL6_REG 0x1065 238 - #define AB4500_PWM_OUT_CTRL7_REG 0x1066 239 - 240 - #define AB4500_I2C_PAD_CTRL_REG 0x1067 241 - #define AB4500_REV_REG 0x1080 242 - 243 - /** 244 - * struct ab4500 245 - * @spi: spi device structure 246 - * @tx_buf: transmit buffer 247 - * @rx_buf: receive buffer 248 - * @lock: sync primitive 249 - */ 250 - struct ab4500 { 251 - struct spi_device *spi; 252 - unsigned long tx_buf[4]; 253 - unsigned long rx_buf[4]; 254 - struct mutex lock; 255 - }; 256 - 257 - int ab4500_write(struct ab4500 *ab4500, unsigned char block, 258 - unsigned long addr, unsigned char data); 259 - int ab4500_read(struct ab4500 *ab4500, unsigned char block, 260 - unsigned long addr); 261 - 262 - #endif /* MFD_AB4500_H */
···
+128
include/linux/mfd/ab8500.h
···
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 6 + */ 7 + #ifndef MFD_AB8500_H 8 + #define MFD_AB8500_H 9 + 10 + #include <linux/device.h> 11 + 12 + /* 13 + * Interrupts 14 + */ 15 + 16 + #define AB8500_INT_MAIN_EXT_CH_NOT_OK 0 17 + #define AB8500_INT_UN_PLUG_TV_DET 1 18 + #define AB8500_INT_PLUG_TV_DET 2 19 + #define AB8500_INT_TEMP_WARM 3 20 + #define AB8500_INT_PON_KEY2DB_F 4 21 + #define AB8500_INT_PON_KEY2DB_R 5 22 + #define AB8500_INT_PON_KEY1DB_F 6 23 + #define AB8500_INT_PON_KEY1DB_R 7 24 + #define AB8500_INT_BATT_OVV 8 25 + #define AB8500_INT_MAIN_CH_UNPLUG_DET 10 26 + #define AB8500_INT_MAIN_CH_PLUG_DET 11 27 + #define AB8500_INT_USB_ID_DET_F 12 28 + #define AB8500_INT_USB_ID_DET_R 13 29 + #define AB8500_INT_VBUS_DET_F 14 30 + #define AB8500_INT_VBUS_DET_R 15 31 + #define AB8500_INT_VBUS_CH_DROP_END 16 32 + #define AB8500_INT_RTC_60S 17 33 + #define AB8500_INT_RTC_ALARM 18 34 + #define AB8500_INT_BAT_CTRL_INDB 20 35 + #define AB8500_INT_CH_WD_EXP 21 36 + #define AB8500_INT_VBUS_OVV 22 37 + #define AB8500_INT_MAIN_CH_DROP_END 23 38 + #define AB8500_INT_CCN_CONV_ACC 24 39 + #define AB8500_INT_INT_AUD 25 40 + #define AB8500_INT_CCEOC 26 41 + #define AB8500_INT_CC_INT_CALIB 27 42 + #define AB8500_INT_LOW_BAT_F 28 43 + #define AB8500_INT_LOW_BAT_R 29 44 + #define AB8500_INT_BUP_CHG_NOT_OK 30 45 + #define AB8500_INT_BUP_CHG_OK 31 46 + #define AB8500_INT_GP_HW_ADC_CONV_END 32 47 + #define AB8500_INT_ACC_DETECT_1DB_F 33 48 + #define AB8500_INT_ACC_DETECT_1DB_R 34 49 + #define AB8500_INT_ACC_DETECT_22DB_F 35 50 + #define AB8500_INT_ACC_DETECT_22DB_R 36 51 + #define AB8500_INT_ACC_DETECT_21DB_F 37 52 + #define AB8500_INT_ACC_DETECT_21DB_R 38 53 + #define AB8500_INT_GP_SW_ADC_CONV_END 39 54 + #define AB8500_INT_BTEMP_LOW 72 55 + #define AB8500_INT_BTEMP_LOW_MEDIUM 73 56 + #define AB8500_INT_BTEMP_MEDIUM_HIGH 74 57 + #define AB8500_INT_BTEMP_HIGH 75 58 + #define AB8500_INT_USB_CHARGER_NOT_OK 81 59 + #define AB8500_INT_ID_WAKEUP_R 82 60 + #define AB8500_INT_ID_DET_R1R 84 61 + #define AB8500_INT_ID_DET_R2R 85 62 + #define AB8500_INT_ID_DET_R3R 86 63 + #define AB8500_INT_ID_DET_R4R 87 64 + #define AB8500_INT_ID_WAKEUP_F 88 65 + #define AB8500_INT_ID_DET_R1F 90 66 + #define AB8500_INT_ID_DET_R2F 91 67 + #define AB8500_INT_ID_DET_R3F 92 68 + #define AB8500_INT_ID_DET_R4F 93 69 + #define AB8500_INT_USB_CHG_DET_DONE 94 70 + #define AB8500_INT_USB_CH_TH_PROT_F 96 71 + #define AB8500_INT_USB_CH_TH_PROP_R 97 72 + #define AB8500_INT_MAIN_CH_TH_PROP_F 98 73 + #define AB8500_INT_MAIN_CH_TH_PROT_R 99 74 + #define AB8500_INT_USB_CHARGER_NOT_OKF 103 75 + 76 + #define AB8500_NR_IRQS 104 77 + #define AB8500_NUM_IRQ_REGS 13 78 + 79 + /** 80 + * struct ab8500 - ab8500 internal structure 81 + * @dev: parent device 82 + * @lock: read/write operations lock 83 + * @irq_lock: genirq bus lock 84 + * @revision: chip revision 85 + * @irq: irq line 86 + * @write: register write 87 + * @read: register read 88 + * @rx_buf: rx buf for SPI 89 + * @tx_buf: tx buf for SPI 90 + * @mask: cache of IRQ regs for bus lock 91 + * @oldmask: cache of previous IRQ regs for bus lock 92 + */ 93 + struct ab8500 { 94 + struct device *dev; 95 + struct mutex lock; 96 + struct mutex irq_lock; 97 + int revision; 98 + int irq_base; 99 + int irq; 100 + 101 + int (*write) (struct ab8500 *a8500, u16 addr, u8 data); 102 + int (*read) (struct ab8500 *a8500, u16 addr); 103 + 104 + unsigned long tx_buf[4]; 105 + unsigned long rx_buf[4]; 106 + 107 + u8 mask[AB8500_NUM_IRQ_REGS]; 108 + u8 oldmask[AB8500_NUM_IRQ_REGS]; 109 + }; 110 + 111 + /** 112 + * struct ab8500_platform_data - AB8500 platform data 113 + * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used 114 + * @init: board-specific initialization after detection of ab8500 115 + */ 116 + struct ab8500_platform_data { 117 + int irq_base; 118 + void (*init) (struct ab8500 *); 119 + }; 120 + 121 + extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data); 122 + extern int ab8500_read(struct ab8500 *a8500, u16 addr); 123 + extern int ab8500_set_bits(struct ab8500 *a8500, u16 addr, u8 mask, u8 data); 124 + 125 + extern int __devinit ab8500_init(struct ab8500 *ab8500); 126 + extern int __devexit ab8500_exit(struct ab8500 *ab8500); 127 + 128 + #endif /* MFD_AB8500_H */