2 * Support for the EGPIO capabilities on the HTC Apache phone. This
3 * is believed to be related to the CPLD chip present on the board.
5 * (c) Copyright 2006 Kevin O'Connor <kevin@koconnor.net>
7 * This file may be distributed under the terms of the GNU GPL license.
10 #include <linux/kernel.h>
11 #include <linux/errno.h> // ENODEV
12 #include <linux/list.h> // struct list_head
13 #include <linux/spinlock.h> // spinlock_t
14 #include <linux/module.h> // EXPORT_SYMBOL
16 #include <asm/arch/pxa-regs.h> // PXA_CS2_PHYS
17 #include <asm/irq.h> // IRQ_BOARD_START, IRQT_RISING
18 #include <asm/io.h> // ioremap_nocache
19 #include <asm/mach/irq.h> // struct irqchip
21 #include <asm/arch/htcapache-gpio.h> // IRQ_EGPIO
25 // Location of the egpio chip in physical ram.
26 EGPIO_BASE
= PXA_CS2_PHYS
+0x02000000,
27 // Number of egpio irq pins
31 // Base location of egpio registers.
32 static volatile u16
*egpio
;
35 /****************************************************************
37 ****************************************************************/
39 // There does not appear to be a way to mask interrupts on the egpio
40 // chip itself. It would be possible to do it in software by
41 // disabling the pxa gpio pin, however since no service currently
42 // needs enable/disable_irq there is no pressing need to implement
43 // this. It isn't necessary to worry about re-entrant irq handlers,
44 // because the egpio interrupt is checked from the pxa interrupt which
45 // is itself non re-entrant.
46 static void egpio_ack(unsigned int irq
)
49 static void egpio_mask(unsigned int irq
)
52 static void egpio_unmask(unsigned int irq
)
56 static struct irqchip egpio_muxed_chip
= {
59 .unmask
= egpio_unmask
,
63 egpio_handler(unsigned int irq
, struct irqdesc
*desc
, struct pt_regs
*regs
)
67 u16 readval
= egpio
[0];
68 // Process all set pins.
69 for (i
=0; i
<LAST_EGPIO
; i
++) {
71 if (!(readval
& (1<<irqpin
)))
73 // Ack/unmask current pin.
74 egpio
[0] = ~(1<<irqpin
);
77 desc
= &irq_desc
[irq
];
78 desc_handle_irq(irq
, desc
, regs
);
82 // Check an input pin to see if it is active.
84 htcapache_egpio_isset(int bit
)
86 u16 readval
= egpio
[0];
87 return readval
& (1<<bit
);
89 EXPORT_SYMBOL(htcapache_egpio_isset
);
92 /****************************************************************
94 ****************************************************************/
96 // Local copies of what is in the egpio registers
97 static u16 cached_out_egpio
[3];
98 static spinlock_t outLock
;
100 static inline int u16pos(int bit
) {
103 static inline int u16bit(int bit
) {
104 return 1<<(bit
& (16-1));
108 htcapache_egpio_set(int bit
)
110 int pos
= u16pos(bit
);
113 spin_lock_irqsave(&outLock
, flag
);
114 cached_out_egpio
[pos
] |= u16bit(bit
);
115 printk("egpio set: reg %d = 0x%04x\n", pos
, cached_out_egpio
[pos
]);
116 egpio
[pos
] = cached_out_egpio
[pos
];
117 spin_unlock_irqrestore(&outLock
, flag
);
119 EXPORT_SYMBOL(htcapache_egpio_set
);
122 htcapache_egpio_clear(int bit
)
124 int pos
= u16pos(bit
);
127 spin_lock_irqsave(&outLock
, flag
);
128 cached_out_egpio
[pos
] &= ~u16bit(bit
);
129 printk("egpio clear: reg %d = 0x%04x\n", pos
, cached_out_egpio
[pos
]);
130 egpio
[pos
] = cached_out_egpio
[pos
];
131 spin_unlock_irqrestore(&outLock
, flag
);
133 EXPORT_SYMBOL(htcapache_egpio_clear
);
136 /****************************************************************
138 ****************************************************************/
141 htcapache_egpio_init(void)
145 spin_lock_init(&outLock
);
147 // Map egpio chip into virtual address space.
148 egpio
= (volatile u16
*)ioremap_nocache(EGPIO_BASE
149 , sizeof(cached_out_egpio
));
153 printk(KERN_NOTICE
"EGPIO phys=%08x virt=%p\n"
154 , EGPIO_BASE
, egpio
);
156 // Setup irq handlers.
157 for (irq
= IRQ_EGPIO(0); irq
<= IRQ_EGPIO(LAST_EGPIO
); irq
++) {
158 set_irq_chip(irq
, &egpio_muxed_chip
);
159 set_irq_handler(irq
, do_simple_IRQ
);
160 set_irq_flags(irq
, IRQF_VALID
| IRQF_PROBE
);
162 set_irq_type(IRQ_GPIO(GPIO_NR_HTCAPACHE_EGPIO_IRQ
), IRQT_RISING
);
163 set_irq_chained_handler(IRQ_GPIO(GPIO_NR_HTCAPACHE_EGPIO_IRQ
)
166 // Setup initial output pin values.
167 cached_out_egpio
[2] = (1<<8); // Disable Charger
168 egpio
[1] = cached_out_egpio
[1];
169 egpio
[2] = cached_out_egpio
[2];
171 // Unmask all current irqs.