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 50 51 51 static struct spi_board_info u8500_spi_devices[] = { 52 52 { 53 - .modalias = "ab4500", 53 + .modalias = "ab8500", 54 54 .controller_data = &ab4500_chip_info, 55 55 .max_speed_hz = 12000000, 56 56 .bus_num = 0,
+5 -4
drivers/mfd/Kconfig
··· 420 420 This enables the PCAP ASIC present on EZX Phones. This is 421 421 needed for MMC, TouchScreen, Sound, USB, etc.. 422 422 423 - config AB4500_CORE 424 - tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip" 425 - depends on SPI 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 426 427 help 427 - Select this option to enable access to AB4500 power management 428 + Select this option to enable access to AB8500 power management 428 429 chip. This connects to U8500 on the SSP/SPI bus and exports 429 430 read/write functions for the devices to get access to this chip. 430 431 This chip embeds various other multimedia funtionalities as well.
+1 -1
drivers/mfd/Makefile
··· 64 64 obj-$(CONFIG_ABX500_CORE) += abx500-core.o 65 65 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 66 66 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 67 - obj-$(CONFIG_AB4500_CORE) += ab4500-core.o 68 67 obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 68 + obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o 69 69 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 70 70 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 71 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 */