1 /* Core Hardware driver for x30 (ASIC3, EGPIOs)
3 * Authors: Giuseppe Zompatori <giuseppe_zompatori@yahoo.it>
5 * based on previews work, see below:
7 * Copyright (c) 2005 SDG Systems, LLC
9 * 2005-03-29 Todd Blumer Converted basic structure to support hx4700
12 #include <linux/module.h>
13 #include <linux/version.h>
14 #include <linux/config.h>
15 #include <linux/interrupt.h>
16 #include <linux/device.h>
20 #include <asm/mach/irq.h>
21 #include <asm/arch/pxa-regs.h>
22 #include <asm/arch/aximx30-gpio.h>
23 #include <asm/arch/aximx30-asic.h>
25 #include <linux/soc/asic3_base.h>
26 #include <asm/hardware/ipaq-asic3.h>
28 #include "aximx30_core.h"
30 #define EGPIO_OFFSET 0
31 #define EGPIO_BASE (PXA_CS5_PHYS+EGPIO_OFFSET)
32 #define WLAN_OFFSET 0x800000
33 #define WLAN_BASE (PXA_CS5_PHYS+WLAN_OFFSET)
34 #define PPSH_OFFSET 0x1000000
36 volatile u_int16_t
*egpios
;
40 * may make sense to put egpios elsewhere, but they're here now
41 * since they share some of the same address space with the TI WLAN
43 * EGPIO register is write-only
47 x30_egpio_enable( unsigned long bits
)
52 EXPORT_SYMBOL(x30_egpio_enable
);
55 x30_egpio_disable( unsigned long bits
)
60 EXPORT_SYMBOL(x30_egpio_disable
);
63 x30_udc_detect( void )
65 return (asic3_get_gpio_status_d(&x30_asic3
.dev
)
66 & (1 << GPIOD_USBC_DETECT_N
)) ? 0 : 1;
69 static unsigned int serial_irq
= 0xffffffff;
70 static unsigned int ac_irq
= 0xffffffff;
73 serial_isr(int irq
, void *dev_id
, struct pt_regs
*regs
)
78 if (irq
!= serial_irq
)
81 statusd
= asic3_get_gpio_status_d( &x30_asic3
.dev
);
82 connected
= (statusd
& (1<<GPIOD_COM_DCD
)) != 0;
83 printk( KERN_INFO
"serial_isr: com_dcd=%d\n", connected
);
84 SET_X30_GPIO( RS232_ON
, connected
);
89 ac_isr(int irq
, void *dev_id
, struct pt_regs
*regs
)
97 statusd
= asic3_get_gpio_status_d( &x30_asic3
.dev
);
98 connected
= (statusd
& (1<<GPIOD_AC_IN_N
)) == 0;
99 printk( KERN_INFO
"ac_isr: connected=%d\n", connected
);
101 set_irq_type( ac_irq
, IRQT_RISING
);
103 set_irq_type( ac_irq
, IRQT_FALLING
);
104 SET_X30_GPIO_N( CHARGE_EN
, connected
);
109 x30_core_probe( struct device
*dev
)
111 unsigned int statusd
;
113 struct x30_core_funcs
*funcs
= (struct x30_core_funcs
*) dev
->platform_data
;
114 printk( KERN_NOTICE
"X30 Core Hardware Driver\n" );
116 funcs
->udc_detect
= x30_udc_detect
;
119 egpios
= (volatile u_int16_t
*)ioremap_nocache( EGPIO_BASE
, sizeof *egpios
);
123 serial_irq
= asic3_irq_base( &x30_asic3
.dev
) + ASIC3_GPIOD_IRQ_BASE
125 if (request_irq( serial_irq
, serial_isr
, SA_INTERRUPT
,
126 "X30 Serial", NULL
) != 0) {
127 printk( KERN_ERR
"Unable to configure serial port interrupt.\n" );
130 set_irq_type( serial_irq
, IRQT_RISING
);
132 ac_irq
= asic3_irq_base( &x30_asic3
.dev
) + ASIC3_GPIOD_IRQ_BASE
135 statusd
= asic3_get_gpio_status_d( &x30_asic3
.dev
);
136 connected
= (statusd
& (1<<GPIOD_AC_IN_N
)) == 0;
137 printk( KERN_INFO
"AC: connected=%d\n", connected
);
139 set_irq_type( ac_irq
, IRQT_RISING
);
141 set_irq_type( ac_irq
, IRQT_FALLING
);
143 if (request_irq( ac_irq
, ac_isr
, SA_INTERRUPT
,
144 "X30 AC Detect", NULL
) != 0) {
145 printk( KERN_ERR
"Unable to configure AC detect interrupt.\n" );
146 free_irq( serial_irq
, NULL
);
149 SET_X30_GPIO_N( CHARGE_EN
, connected
);
154 x30_core_remove( struct device
*dev
)
158 irq
= asic3_irq_base( &x30_asic3
.dev
) + ASIC3_GPIOD_IRQ_BASE
161 iounmap( (void *)egpios
);
162 if (serial_irq
!= 0xffffffff)
163 free_irq( serial_irq
, NULL
);
164 if (ac_irq
!= 0xffffffff)
165 free_irq( ac_irq
, NULL
);
169 struct device_driver x30_core_driver
= {
171 .bus
= &platform_bus_type
,
172 .probe
= x30_core_probe
,
173 .remove
= x30_core_remove
,
177 x30_core_init( void )
179 return driver_register( &x30_core_driver
);
184 x30_core_exit( void )
186 driver_unregister( &x30_core_driver
);
189 module_init( x30_core_init
);
190 module_exit( x30_core_exit
);
192 MODULE_AUTHOR("Giuseppe Zompatori <giuseppe_zompatori@yahoo.it>");
193 MODULE_DESCRIPTION("Dell Axim X30 Core Hardware Driver");
194 MODULE_LICENSE("GPL");