1 /* Core Hardware driver for Hx4700 (Serial, ASIC3, EGPIOs)
3 * Copyright (c) 2005 SDG Systems, LLC
5 * 2005-03-29 Todd Blumer Converted basic structure to support hx4700
6 * 2005-04-30 Todd Blumer Add IRDA code from H2200
9 #include <linux/module.h>
10 #include <linux/version.h>
11 #include <linux/interrupt.h>
12 #include <linux/platform_device.h>
13 #include <linux/delay.h>
15 #include <linux/irq.h>
18 #include <asm/mach/irq.h>
19 #include <asm/arch/pxa-regs.h>
20 #include <asm/arch/pxa-pm_ll.h>
21 #include <asm/arch/htcuniversal-gpio.h>
22 #include <asm/arch/htcuniversal-asic.h>
24 #include <linux/soc/asic3_base.h>
25 #include <asm/hardware/ipaq-asic3.h>
27 volatile u_int16_t
*egpios
;
30 static int htc_bootloader
= 0; /* Is the stock HTC bootloader installed? */
33 * may make sense to put egpios elsewhere, but they're here now
34 * since they share some of the same address space with the TI WLAN
36 * EGPIO register is write-only
40 htcuniversal_egpio_enable( u_int16_t bits
)
44 local_irq_save(flags
);
49 local_irq_restore(flags
);
51 EXPORT_SYMBOL(htcuniversal_egpio_enable
);
54 htcuniversal_egpio_disable( u_int16_t bits
)
58 local_irq_save(flags
);
63 local_irq_restore(flags
);
65 EXPORT_SYMBOL(htcuniversal_egpio_disable
);
69 void htcuniversal_ll_pm_init(void);
71 static int htcuniversal_suspend(struct platform_device
*dev
, pm_message_t state
)
73 /* Turn off external clocks here, because htcuniversal_power and asic3_mmc
74 * scared to do so to not hurt each other. (-5 mA) */
76 asic3_set_clock_cdex(&htcuniversal_asic3
.dev
,
77 CLOCK_CDEX_EX0
| CLOCK_CDEX_EX1
, 0 | 0);
79 /* 0x20c2 is HTC clock value
90 * CLOCK_CDEX_SD_HOST 0
94 * CLOCK_CDEX_CONTROL_CX 0
98 asic3_set_clock_cdex(&htcuniversal_asic3
.dev
, 0xffff, CLOCK_CDEX_SOURCE
105 *egpios
= 0; /* turn off all egpio power */
107 /* Wake up enable. */
109 | PWER_GPIO1
/* reset */
110 | PWER_GPIO9
/* USB */
111 | PWER_GPIO10
/* AC on USB */
112 | PWER_GPIO14
/* ASIC3 mux */
114 /* Wake up on falling edge. */
121 /* Wake up on rising edge. */
126 /* 3.6864 MHz oscillator power-down enable */
127 PCFR
= PCFR_OPDE
| PCFR_PI2CEN
| PCFR_GPROD
| PCFR_GPR_EN
;
138 * If we're using bootldr and not the stock HTC bootloader,
139 * we want to wake up periodically to see if the charge is full while
140 * it is suspended. We do this with the OS timer 4 in the pxa270.
142 if (!htc_bootloader
) {
143 OMCR4
= 0x4b; /* Periodic, self-resetting, 1-second timer */
144 OSMR4
= 5; /* Wake up bootldr after x seconds so it can
145 figure out what to do with the LEDs. */
146 OIER
|= 0x10; /* Enable interrupt source for Timer 4 */
147 OSCR4
= 0; /* This starts the timer */
151 asic3_set_extcf_select(&htcuniversal_asic3
.dev
, ASIC3_EXTCF_OWM_EN
, 0);
156 static int htcuniversal_resume(struct platform_device
*dev
)
158 htcuniversal_egpio_enable(0);
163 # define htcuniversal_suspend NULL
164 # define htcuniversal_resume NULL
168 htcuniversal_core_probe( struct platform_device
*dev
)
171 printk( KERN_NOTICE
"HTC Universal Core Hardware Driver\n" );
173 egpios
= (volatile u_int16_t
*)ioremap_nocache(HTCUNIVERSAL_EGPIO_BASE
, sizeof *egpios
);
177 printk( KERN_NOTICE
"HTC Universal Core: egpio at phy=0x%8.8x is at virt=0x%p\n",
178 HTCUNIVERSAL_EGPIO_BASE
, egpios
);
185 /* Is the stock HTC bootloader installed? */
187 bootldr
= (u32
*) ioremap(PXA_CS0_PHYS
, 1024 * 1024);
190 if (bootldr
[i
] == 0xe59f1360 && /* ldr r1, [pc, #864] ; power base */
191 bootldr
[i
+1] == 0xe5914008 && /* ldr r4, [r1, #8] ; PSPR */
192 bootldr
[i
+2] == 0xe1320004) { /* teq r2, r4 */
194 printk("Stock HTC bootloader detected\n");
196 pxa_pm_set_ll_ops(&htcuniversal_ll_pm_ops
);
202 printk("Using stock HTC first stage bootloader\n");
205 htcuniversal_ll_pm_init();
212 htcuniversal_core_remove( struct platform_device
*dev
)
216 iounmap( (void *)egpios
);
221 static struct platform_driver htcuniversal_core_driver
= {
223 .name
= "htcuniversal_core",
225 .probe
= htcuniversal_core_probe
,
226 .remove
= htcuniversal_core_remove
,
227 .suspend
= htcuniversal_suspend
,
228 .resume
= htcuniversal_resume
,
232 htcuniversal_core_init( void )
234 return platform_driver_register( &htcuniversal_core_driver
);
239 htcuniversal_core_exit( void )
241 platform_driver_unregister( &htcuniversal_core_driver
);
244 module_init( htcuniversal_core_init
);
245 module_exit( htcuniversal_core_exit
);
247 MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
248 MODULE_DESCRIPTION("HTC Universal Core Hardware Driver");
249 MODULE_LICENSE("GPL");
251 /* vim600: set noexpandtab sw=8 ts=8 :*/