2 * twl4030_core.c - driver for TWL4030 PM and audio CODEC device
4 * Copyright (C) 2005-2006 Texas Instruments, Inc.
6 * Modifications to defer interrupt handling to a kernel thread:
7 * Copyright (C) 2006 MontaVista Software, Inc.
9 * Based on tlv320aic23.c:
10 * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
12 * Code cleanup and modifications to IRQ handler.
13 * by syed khasim <x0khasim@ti.com>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <linux/module.h>
32 #include <linux/kernel_stat.h>
33 #include <linux/init.h>
34 #include <linux/time.h>
35 #include <linux/interrupt.h>
36 #include <linux/random.h>
37 #include <linux/syscalls.h>
38 #include <linux/kthread.h>
40 #include <linux/i2c.h>
41 #include <linux/slab.h>
42 #include <linux/clk.h>
43 #include <linux/device.h>
46 #include <asm/mach/irq.h>
48 #include <asm/arch/twl4030.h>
49 #include <asm/arch/gpio.h>
50 #include <asm/arch/mux.h>
52 #define DRIVER_NAME "twl4030"
54 #define pr_err(fmt, arg...) printk(KERN_ERR DRIVER_NAME ": " fmt, ##arg);
56 /**** Macro Definitions */
57 #define TWL_CLIENT_STRING "TWL4030-ID"
58 #define TWL_CLIENT_USED 1
59 #define TWL_CLIENT_FREE 0
65 /** Primary Interrupt Handler on TWL4030 Registers */
67 /**** Register Definitions */
69 #define REG_PIH_ISR_P1 (0x1)
70 #define REG_PIH_ISR_P2 (0x2)
71 #define REG_PIH_SIR (0x3)
73 /* Triton Core internal information (BEGIN) */
75 /* Last - for index max*/
76 #define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG
79 #define TWL4030_NUM_SLAVES 0x04
80 #define TWL4030_SLAVENUM_NUM0 0x00
81 #define TWL4030_SLAVENUM_NUM1 0x01
82 #define TWL4030_SLAVENUM_NUM2 0x02
83 #define TWL4030_SLAVENUM_NUM3 0x03
84 #define TWL4030_SLAVEID_ID0 0x48
85 #define TWL4030_SLAVEID_ID1 0x49
86 #define TWL4030_SLAVEID_ID2 0x4A
87 #define TWL4030_SLAVEID_ID3 0x4B
89 /* Base Address defns */
91 #define TWL4030_BASEADD_USB 0x0000
93 #define TWL4030_BASEADD_AUDIO_VOICE 0x0000
94 #define TWL4030_BASEADD_GPIO 0x0098
96 #define TWL4030_BASEADD_INTBR 0x0085
97 #define TWL4030_BASEADD_PIH 0x0080
98 #define TWL4030_BASEADD_TEST 0x004C
100 #define TWL4030_BASEADD_INTERRUPTS 0x00B9
101 #define TWL4030_BASEADD_LED 0x00EE
102 #define TWL4030_BASEADD_MADC 0x0000
103 #define TWL4030_BASEADD_MAIN_CHARGE 0x0074
104 #define TWL4030_BASEADD_PRECHARGE 0x00AA
105 #define TWL4030_BASEADD_PWM0 0x00F8
106 #define TWL4030_BASEADD_PWM1 0x00FB
107 #define TWL4030_BASEADD_PWMA 0x00EF
108 #define TWL4030_BASEADD_PWMB 0x00F1
109 #define TWL4030_BASEADD_KEYPAD 0x00D2
111 #define TWL4030_BASEADD_BACKUP 0x0014
112 #define TWL4030_BASEADD_INT 0x002E
113 #define TWL4030_BASEADD_PM_MASTER 0x0036
114 #define TWL4030_BASEADD_PM_RECIEVER 0x005B
115 #define TWL4030_BASEADD_RTC 0x001C
116 #define TWL4030_BASEADD_SECURED_REG 0x0000
118 /* Triton Core internal information (END) */
120 /* Few power values */
121 #define R_CFG_BOOT 0x05
122 #define R_PROTECT_KEY 0x0E
125 #define KEY_UNLOCK1 0xce
126 #define KEY_UNLOCK2 0xec
127 #define KEY_LOCK 0x00
129 #define HFCLK_FREQ_19p2_MHZ (1 << 0)
130 #define HFCLK_FREQ_26_MHZ (2 << 0)
131 #define HFCLK_FREQ_38p4_MHZ (3 << 0)
132 #define HIGH_PERF_SQ (1 << 3)
134 /* on I2C-1 for 2430SDP */
135 #define CONFIG_I2C_TWL4030_ID 1
137 /**** Helper functions */
139 twl4030_detect_client(struct i2c_adapter *adapter, unsigned char sid);
140 static int twl4030_attach_adapter(struct i2c_adapter *adapter);
141 static int twl4030_detach_client(struct i2c_client *client);
142 static void do_twl4030_irq(unsigned int irq, irq_desc_t *desc);
144 static void twl_init_irq(void);
146 /**** Data Structures */
147 /* To have info on T2 IRQ substem activated or not */
148 static unsigned char twl_irq_used = FREE;
149 static struct completion irq_event;
151 /* Structure to define on TWL4030 Slave ID */
152 struct twl4030_client {
153 struct i2c_client client;
154 const char client_name[sizeof(TWL_CLIENT_STRING) + 1];
155 const unsigned char address;
156 const char adapter_index;
159 /* max numb of i2c_msg required is for read =2 */
160 struct i2c_msg xfer_msg[2];
162 /* To lock access to xfer_msg */
163 struct semaphore xfer_lock;
167 struct twl4030mapping {
168 unsigned char sid; /* Slave ID */
169 unsigned char base; /* base address */
172 /* mapping the module id to slave id and base address */
173 static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
174 { TWL4030_SLAVENUM_NUM0, TWL4030_BASEADD_USB },
175 { TWL4030_SLAVENUM_NUM1, TWL4030_BASEADD_AUDIO_VOICE },
176 { TWL4030_SLAVENUM_NUM1, TWL4030_BASEADD_GPIO },
177 { TWL4030_SLAVENUM_NUM1, TWL4030_BASEADD_INTBR },
178 { TWL4030_SLAVENUM_NUM1, TWL4030_BASEADD_PIH },
179 { TWL4030_SLAVENUM_NUM1, TWL4030_BASEADD_TEST },
180 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_KEYPAD },
181 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_MADC },
182 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_INTERRUPTS },
183 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_LED },
184 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_MAIN_CHARGE },
185 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_PRECHARGE },
186 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_PWM0 },
187 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_PWM1 },
188 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_PWMA },
189 { TWL4030_SLAVENUM_NUM2, TWL4030_BASEADD_PWMB },
190 { TWL4030_SLAVENUM_NUM3, TWL4030_BASEADD_BACKUP },
191 { TWL4030_SLAVENUM_NUM3, TWL4030_BASEADD_INT },
192 { TWL4030_SLAVENUM_NUM3, TWL4030_BASEADD_PM_MASTER },
193 { TWL4030_SLAVENUM_NUM3, TWL4030_BASEADD_PM_RECIEVER },
194 { TWL4030_SLAVENUM_NUM3, TWL4030_BASEADD_RTC },
195 { TWL4030_SLAVENUM_NUM3, TWL4030_BASEADD_SECURED_REG },
198 static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES] = {
200 .address = TWL4030_SLAVEID_ID0,
201 .client_name = TWL_CLIENT_STRING "0",
202 .adapter_index = CONFIG_I2C_TWL4030_ID,
205 .address = TWL4030_SLAVEID_ID1,
206 .client_name = TWL_CLIENT_STRING "1",
207 .adapter_index = CONFIG_I2C_TWL4030_ID,
210 .address = TWL4030_SLAVEID_ID2,
211 .client_name = TWL_CLIENT_STRING "2",
212 .adapter_index = CONFIG_I2C_TWL4030_ID,
215 .address = TWL4030_SLAVEID_ID3,
216 .client_name = TWL_CLIENT_STRING "3",
217 .adapter_index = CONFIG_I2C_TWL4030_ID,
221 /* One Client Driver , 4 Clients */
222 static struct i2c_driver twl4030_driver = {
223 .driver.name = "TWL4030 I2C",
224 .attach_adapter = twl4030_attach_adapter,
225 .detach_client = twl4030_detach_client,
229 * TWL4030 doesn't have PIH mask, hence dummy function for mask
233 static void twl4030_i2c_ackirq(unsigned int irq) {}
234 static void twl4030_i2c_disableint(unsigned int irq) {}
235 static void twl4030_i2c_enableint(unsigned int irq) {}
237 /* information for processing in the Work Item */
238 static struct irq_chip twl4030_irq_chip = {
239 .ack = twl4030_i2c_ackirq,
240 .mask = twl4030_i2c_disableint,
241 .unmask = twl4030_i2c_enableint,
244 /* Global Functions */
246 * @brief twl4030_i2c_write - Writes a n bit register in TWL4030
248 * @param mod_no - module number
249 * @param *value - an array of num_bytes+1 containing data to write
250 * IMPORTANT - Allocate value num_bytes+1 and valid data starts at
252 * @param reg - register address (just offset will do)
253 * @param num_bytes - number of bytes to transfer
255 * @return result of operation - 0 is success
257 int twl4030_i2c_write(u8 mod_no, u8 * value, u8 reg, u8 num_bytes)
261 struct twl4030_client *client;
264 if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
265 pr_err("Invalid module Number\n");
268 sid = twl4030_map[mod_no].sid;
269 client = &(twl4030_modules[sid]);
271 if (unlikely(client->inuse != TWL_CLIENT_USED)) {
272 pr_err("I2C Client[%d] is not initialized[%d]\n",
276 down(&(client->xfer_lock));
278 * [MSG1]: fill the register address data
279 * fill the data Tx buffer
281 msg = &(client->xfer_msg[0]);
282 msg->addr = client->address;
283 msg->len = num_bytes + 1;
286 /* over write the first byte of buffer with the register address */
287 *value = twl4030_map[mod_no].base + reg;
288 ret = i2c_transfer(client->client.adapter, client->xfer_msg, 1);
289 up(&(client->xfer_lock));
291 /* i2cTransfer returns num messages.translate it pls.. */
298 * @brief twl4030_i2c_read - Reads a n bit register in TWL4030
300 * @param mod_no - module number
301 * @param *value - an array of num_bytes containing data to be read
302 * @param reg - register address (just offset will do)
303 * @param num_bytes - number of bytes to transfer
305 * @return result of operation - num_bytes is success else failure.
307 int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes)
312 struct twl4030_client *client;
315 if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
316 pr_err("Invalid module Number\n");
319 sid = twl4030_map[mod_no].sid;
320 client = &(twl4030_modules[sid]);
322 if (unlikely(client->inuse != TWL_CLIENT_USED)) {
323 pr_err("I2C Client[%d] is not initialized[%d]\n", sid,
327 down(&(client->xfer_lock));
328 /* [MSG1] fill the register address data */
329 msg = &(client->xfer_msg[0]);
330 msg->addr = client->address;
332 msg->flags = 0; /* Read the register value */
333 val = twl4030_map[mod_no].base + reg;
335 /* [MSG2] fill the data rx buffer */
336 msg = &(client->xfer_msg[1]);
337 msg->addr = client->address;
338 msg->flags = I2C_M_RD; /* Read the register value */
339 msg->len = num_bytes; /* only n bytes */
341 ret = i2c_transfer(client->client.adapter, client->xfer_msg, 2);
342 up(&(client->xfer_lock));
344 /* i2cTransfer returns num messages.translate it pls.. */
351 * @brief twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030
353 * @param mod_no - module number
354 * @param value - the value to be written 8 bit
355 * @param reg - register address (just offset will do)
357 * @return result of operation - 0 is success
359 int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
363 /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
364 u8 temp_buffer[2] = { 0 };
365 /* offset 1 contains the data */
366 temp_buffer[1] = value;
367 ret = twl4030_i2c_write(mod_no, temp_buffer, reg, 1);
372 * @brief twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030
374 * @param mod_no - module number
375 * @param *value - the value read 8 bit
376 * @param reg - register address (just offset will do)
378 * @return result of operation - 0 is success
380 int twl4030_i2c_read_u8(u8 mod_no, u8 * value, u8 reg)
384 ret = twl4030_i2c_read(mod_no, value, reg, 1);
388 /**** Helper Functions */
391 * do_twl4030_module_irq() is the desc->handle method for each of the twl4030
392 * module interrupts. It executes in kernel thread context.
393 * On entry, cpu interrupts are disabled.
395 static void do_twl4030_module_irq(unsigned int irq, irq_desc_t *desc)
397 struct irqaction *action;
398 const unsigned int cpu = smp_processor_id();
401 * Earlier this was desc->triggered = 1;
403 desc->status |= IRQ_LEVEL;
406 * The desc->handle method would normally call the desc->chip->ack
407 * method here, but we won't bother since our ack method is NULL.
411 kstat_cpu(cpu).irqs[irq]++;
413 action = desc->action;
422 /* Call the ISR with cpu interrupts enabled */
423 ret = action->handler(irq, action->dev_id);
424 if (ret == IRQ_HANDLED)
425 status |= action->flags;
427 action = action->next;
430 if (status & IRQF_SAMPLE_RANDOM)
431 add_interrupt_randomness(irq);
435 if (retval != IRQ_HANDLED)
436 printk(KERN_ERR "ISR for TWL4030 module"
437 " irq %d can't handle interrupt\n", irq);
440 * Here is where we should call the unmask method, but
441 * again we won't bother since it is NULL.
444 printk(KERN_CRIT "TWL4030 module irq %d has no ISR"
445 " but can't be masked!\n", irq);
447 printk(KERN_CRIT "TWL4030 module irq %d is disabled but can't"
448 " be masked!\n", irq);
452 * twl4030_irq_thread() runs as a kernel thread. It queries the twl4030
453 * interrupt controller to see which modules are generating interrupt requests
454 * and then calls the desc->handle method for each module requesting service.
456 static int twl4030_irq_thread(void *data)
459 irq_desc_t *desc = irq_desc + irq;
460 static unsigned i2c_errors;
461 const static unsigned max_i2c_errors = 100;
463 daemonize("twl4030-irq");
464 current->flags |= PF_NOFREEZE;
466 while (!kthread_should_stop()) {
471 wait_for_completion_interruptible(&irq_event);
473 ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
476 printk(KERN_WARNING "I2C error %d while reading TWL4030"
477 " PIH ISR register.\n", ret);
478 if (++i2c_errors >= max_i2c_errors) {
479 printk(KERN_ERR "Maximum I2C error count"
480 " exceeded. Terminating %s.\n",
487 for (module_irq = IH_TWL4030_BASE; 0 != pih_isr;
488 pih_isr >>= 1, module_irq++) {
490 irq_desc_t *d = irq_desc + module_irq;
494 d->handle_irq(module_irq, d);
500 desc->chip->unmask(irq);
507 * do_twl4030_irq() is the desc->handle method for the twl4030 interrupt.
508 * This is a chained interrupt, so there is no desc->action method for it.
509 * Now we need to query the interrupt controller in the twl4030 to determine
510 * which module is generating the interrupt request. However, we can't do i2c
511 * transactions in interrupt context, so we must defer that work to a kernel
512 * thread. All we do here is acknowledge and mask the interrupt and wakeup
515 static void do_twl4030_irq(unsigned int irq, irq_desc_t *desc)
517 const unsigned int cpu = smp_processor_id();
520 * Earlier this was desc->triggered = 1;
522 desc->status |= IRQ_LEVEL;
525 * Acknowledge, clear _AND_ disable the interrupt.
527 desc->chip->ack(irq);
530 kstat_cpu(cpu).irqs[irq]++;
532 complete(&irq_event);
536 /* attach a client to the adapter */
537 static int twl4030_detect_client(struct i2c_adapter *adapter, unsigned char sid)
540 struct twl4030_client *client;
542 if (unlikely(sid >= TWL4030_NUM_SLAVES)) {
543 pr_err("sid[%d] > MOD_LAST[%d]\n", sid, TWL4030_NUM_SLAVES);
547 /* Check basic functionality */
548 if (!(err = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA |
549 I2C_FUNC_SMBUS_WRITE_BYTE))) {
550 pr_err("SlaveID=%d functionality check failed\n", sid);
553 client = &(twl4030_modules[sid]);
554 if (unlikely(client->inuse)) {
555 pr_err("Client %s is already in use\n", client->client_name);
559 memset(&(client->client), 0, sizeof(struct i2c_client));
561 client->client.addr = client->address;
562 client->client.adapter = adapter;
563 client->client.driver = &twl4030_driver;
565 memcpy(&(client->client.name), client->client_name,
566 sizeof(TWL_CLIENT_STRING) + 1);
568 pr_info("TWL4030: TRY attach Slave %s on Adapter %s [%x]\n",
569 client->client_name, adapter->name, err);
571 if ((err = i2c_attach_client(&(client->client)))) {
572 pr_err("Couldn't attach Slave %s on Adapter"
573 "%s [%x]\n", client->client_name, adapter->name, err);
575 client->inuse = TWL_CLIENT_USED;
576 init_MUTEX(&client->xfer_lock);
582 /* adapter callback */
583 static int twl4030_attach_adapter(struct i2c_adapter *adapter)
587 static int twl_i2c_adapter = 1;
589 for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
590 /* Check if I need to hook on to this adapter or not */
591 if (twl4030_modules[i].adapter_index == twl_i2c_adapter) {
592 if ((ret = twl4030_detect_client(adapter, i)))
599 * Check if the PIH module is initialized, if yes, then init
600 * the T2 Interrupt subsystem
602 if ((twl4030_modules[twl4030_map[TWL4030_MODULE_PIH].sid].inuse ==
603 TWL_CLIENT_USED) && (twl_irq_used != USED)) {
610 pr_err("TWL_CLIENT(Idx=%d] registration failed[0x%x]\n",i,ret);
612 /* ignore current slave..it never got registered */
615 /* now remove all those from the current adapter... */
616 if (twl4030_modules[i].adapter_index == twl_i2c_adapter)
617 (void)twl4030_detach_client(&(twl4030_modules[i].client));
623 /* adapter's callback */
624 static int twl4030_detach_client(struct i2c_client *iclient)
627 if ((err = i2c_detach_client(iclient))) {
628 pr_err("Client detach failed\n");
634 struct task_struct *start_twl4030_irq_thread(int irq)
636 struct task_struct *thread;
638 init_completion(&irq_event);
639 thread = kthread_run(twl4030_irq_thread, (void *)irq,
640 "twl4030 irq %d", irq);
642 pr_err("%s: could not create twl4030 irq %d thread!\n",
649 * These three functions should be part of Voltage frame work
650 * added here to complete the functionality for now.
652 static int protect_pm_master(void)
656 e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK,
661 static int unprotect_pm_master(void)
665 e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1,
667 e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2,
672 int power_companion_init(void)
675 u32 rate, ctrl = HFCLK_FREQ_26_MHZ;
678 osc = clk_get(NULL,"osc_ck");
679 rate = clk_get_rate(osc);
683 case 19200000 : ctrl = HFCLK_FREQ_19p2_MHZ; break;
684 case 26000000 : ctrl = HFCLK_FREQ_26_MHZ; break;
685 case 38400000 : ctrl = HFCLK_FREQ_38p4_MHZ; break;
688 ctrl |= HIGH_PERF_SQ;
689 e |= unprotect_pm_master();
690 /* effect->MADC+USB ck en */
691 e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
692 e |= protect_pm_master();
697 static void twl_init_irq(void)
704 * We end up with interrupts from other modules before
705 * they get a chance to handle them...
708 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
715 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
722 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
729 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x3);
735 /* Clear off any other pending interrupts on power */
737 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
744 res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
749 /* POWER HACK (END) */
750 /* Slave address 0x4A */
753 res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x3);
760 res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
767 res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x7);
774 res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x8);
782 res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x62);
789 res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x64);
797 res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x12));
805 twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
806 twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
810 res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
816 /* Slave address 0x49 */
818 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
825 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1D));
832 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1E));
839 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x22));
846 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x23));
853 res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x24));
859 /* install an irq handler for each of the PIH modules */
860 for (i = IH_TWL4030_BASE; i < IH_TWL4030_END; i++) {
861 set_irq_chip(i, &twl4030_irq_chip);
862 set_irq_handler(i, do_twl4030_module_irq);
863 set_irq_flags(i, IRQF_VALID);
866 /* install an irq handler to demultiplex the TWL4030 interrupt */
867 set_irq_data(TWL4030_IRQNUM, start_twl4030_irq_thread(TWL4030_IRQNUM));
868 set_irq_type(TWL4030_IRQNUM, IRQT_FALLING);
869 set_irq_chained_handler(TWL4030_IRQNUM, do_twl4030_irq);
871 res = power_companion_init();
879 pr_err("Unable to register interrupt subsystem[%d][%d]\n",
883 static int __init twl4030_init(void)
887 if ((res = i2c_add_driver(&twl4030_driver))) {
888 printk(KERN_ERR "TWL4030: Driver registration failed \n");
892 pr_info(KERN_INFO "TWL4030: Driver registration complete.\n");
897 static void __exit twl4030_exit(void)
899 i2c_del_driver(&twl4030_driver);
903 subsys_initcall(twl4030_init);
904 module_exit(twl4030_exit);
906 EXPORT_SYMBOL(twl4030_i2c_write_u8);
907 EXPORT_SYMBOL(twl4030_i2c_read_u8);
908 EXPORT_SYMBOL(twl4030_i2c_read);
909 EXPORT_SYMBOL(twl4030_i2c_write);
911 MODULE_AUTHOR("Texas Instruments, Inc.");
912 MODULE_DESCRIPTION("I2C Core interface for TWL4030");
913 MODULE_LICENSE("GPL");