hh.org updates
[hh.org.git] / arch / arm / mach-pxa / htcapache / htcapache.c
blob714683066d22f1fbe4c8d068a251ece6e2e369a0
1 /*
2 * linux/arch/arm/mach-pxa/htcapache/htcapache.c
4 * Support for HTC Apache phones.
6 * Based on code from: Alex Osborne <bobofdoom@gmail.com>
8 */
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/device.h>
13 #include <linux/fb.h>
14 #include <linux/platform_device.h>
15 #include <linux/delay.h> // mdelay
16 #include <linux/input.h>
17 #include <linux/irq.h> // set_irq_type
19 #include <asm/mach-types.h>
20 #include <asm/mach/arch.h>
22 #include <asm/arch/hardware.h>
23 #include <asm/arch/pxafb.h>
24 #include <asm/arch/pxa-regs.h>
25 #include <asm/arch/udc.h>
26 #include <asm/arch/htcapache-gpio.h>
27 #include <asm/arch/mmc.h>
28 #include <asm/arch/serial.h>
29 #include <asm/arch/pxa27x_keyboard.h>
30 #include <asm/hardware/gpio_keys.h>
31 #include <asm/arch/irda.h> // struct pxaficp_platform_data
33 #include "../generic.h"
34 #include "../../../../drivers/net/wireless/acx/acx_hw.h"
36 #define GPSR_BIT(n) (GPSR((n)) = GPIO_bit((n)))
37 #define GPCR_BIT(n) (GPCR((n)) = GPIO_bit((n)))
40 /****************************************************************
41 * Backlight
42 ****************************************************************/
44 static void htcapache_backlight_power(int on)
46 /**
47 * TODO: check which particular PWM controls the backlight on the LifeDrive
48 * and enable and disable it here. It's PWM1 on the Tungsten T3. Quite
49 * likely to be the same.
54 /****************************************************************
55 * Frame buffer
56 ****************************************************************/
58 static struct pxafb_mach_info htcapache_lcd __initdata = {
59 .pixclock = 192307,
60 .xres = 240,
61 .yres = 320,
62 .bpp = 16,
63 .hsync_len = 11,
64 .vsync_len = 3,
66 // These margins are from WinCE
67 .left_margin = 19,
68 .right_margin = 10,
69 .upper_margin = 2,
70 .lower_margin = 2,
72 .lccr0 = LCCR0_LDDALT | LCCR0_Act,
73 .pxafb_backlight_power = htcapache_backlight_power,
77 /****************************************************************
78 * Touchscreen
79 ****************************************************************/
81 static struct platform_device htcapache_ts = {
82 .name = "htcapache-ad7877",
86 /****************************************************************
87 * Bluetooth
88 ****************************************************************/
90 static void btuart_configure(int state)
92 int tries;
93 switch (state) {
94 case PXA_UART_CFG_POST_STARTUP:
95 pxa_gpio_mode(GPIO42_BTRXD_MD);
96 pxa_gpio_mode(GPIO43_BTTXD_MD);
97 pxa_gpio_mode(GPIO44_BTCTS_MD);
98 pxa_gpio_mode(GPIO45_BTRTS_MD);
100 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_BT_POWER);
101 mdelay(5);
102 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_BT_RESET);
104 * BRF6150's RTS goes low when firmware is ready
105 * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
107 tries = 0;
108 do {
109 mdelay(10);
110 } while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
111 printk("btuart: post_startup (%d)\n", tries);
112 break;
113 case PXA_UART_CFG_PRE_SHUTDOWN:
114 htcapache_egpio_clear(EGPIO_NR_HTCAPACHE_BT_POWER);
115 htcapache_egpio_clear(EGPIO_NR_HTCAPACHE_BT_RESET);
116 printk("btuart: pre_shutdown\n");
117 break;
121 static struct platform_pxa_serial_funcs btuart_funcs = {
122 .configure = btuart_configure,
126 /****************************************************************
127 * Irda
128 ****************************************************************/
130 static void irda_transceiver_mode(struct device *dev, int mode)
132 printk("irda: transceiver_mode=%d\n", mode);
133 // XXX - don't know transceiver enable/disable pins.
134 // XXX - don't know if FIR supported or how to enable.
137 static struct pxaficp_platform_data apache_ficp_platform_data = {
138 .transceiver_cap = IR_SIRMODE | IR_OFF,
139 .transceiver_mode = irda_transceiver_mode,
143 /****************************************************************
144 * Wifi
145 ****************************************************************/
147 static int
148 wlan_start(void)
150 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_WIFI_POWER1);
151 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_WIFI_POWER2);
152 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_WIFI_POWER3);
153 mdelay(250);
154 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_WIFI_RESET);
155 mdelay(100);
156 return 0;
159 static int
160 wlan_stop(void)
162 htcapache_egpio_clear(EGPIO_NR_HTCAPACHE_WIFI_POWER1);
163 htcapache_egpio_clear(EGPIO_NR_HTCAPACHE_WIFI_POWER2);
164 htcapache_egpio_clear(EGPIO_NR_HTCAPACHE_WIFI_POWER3);
165 htcapache_egpio_clear(EGPIO_NR_HTCAPACHE_WIFI_RESET);
166 return 0;
169 enum {
170 WLAN_BASE = PXA_CS2_PHYS,
173 static struct resource acx_resources[] = {
174 [0] = {
175 .start = WLAN_BASE,
176 .end = WLAN_BASE + 0x20,
177 .flags = IORESOURCE_MEM,
179 [1] = {
180 .start = IRQ_EGPIO(EGPIO_NR_HTCAPACHE_WIFI_IN_IRQ),
181 .end = IRQ_EGPIO(EGPIO_NR_HTCAPACHE_WIFI_IN_IRQ),
182 .flags = IORESOURCE_IRQ,
186 static struct acx_hardware_data acx_data = {
187 .start_hw = wlan_start,
188 .stop_hw = wlan_stop,
191 static struct platform_device acx_device = {
192 .name = "acx-mem",
193 .dev = {
194 .platform_data = &acx_data,
196 .num_resources = ARRAY_SIZE(acx_resources),
197 .resource = acx_resources,
201 /****************************************************************
202 * Pull out keyboard
203 ****************************************************************/
205 static struct pxa27x_keyboard_platform_data htcapache_kbd = {
206 .nr_rows = 7,
207 .nr_cols = 7,
208 .keycodes = {
210 /* row 0 */
211 -1, // Unused
212 KEY_LEFTSHIFT, // Left Shift
213 -1, // Unused
214 KEY_Q, // Q
215 KEY_W, // W
216 KEY_E, // E
217 KEY_R, // R
218 }, { /* row 1 */
219 -1, // Unused
220 -1, // Unused
221 KEY_LEFTALT, // Red Dot
222 KEY_T, // T
223 KEY_Y, // Y
224 KEY_U, // U
225 KEY_I, // I
226 }, { /* row 2 */
227 -1, // Unused
228 KEY_LEFTMETA, // Windows Key
229 -1, // Unused
230 KEY_ENTER, // Return
231 KEY_SPACE, // Space
232 KEY_BACKSPACE, // Backspace
233 KEY_A, // A
234 }, { /* row 3 */
235 -1, // Unused
236 KEY_S, // S
237 KEY_D, // D
238 KEY_F, // F
239 KEY_G, // G
240 KEY_H, // H
241 KEY_J, // J
242 }, { /* row 4 */
243 KEY_LEFTCTRL, // Left Menu
244 KEY_K, // K
245 KEY_Z, // Z
246 KEY_X, // X
247 KEY_C, // C
248 KEY_V, // V
249 KEY_B, // B
250 }, { /* row 5 */
251 KEY_RIGHTCTRL, // Right Menu
252 KEY_N, // N
253 KEY_M, // M
254 KEY_O, // O
255 KEY_L, // L
256 KEY_P, // P
257 KEY_DOT, // .
258 }, { /* row 6 */
259 -1, // Unused
260 KEY_LEFT, // Left Arrow
261 KEY_DOWN, // Down Arrow
262 KEY_UP, // Up Arrow
263 KEY_ESC, // OK button
264 KEY_TAB, // Tab
265 KEY_RIGHT, // Right Arrow
268 .gpio_modes = {
269 GPIO_NR_HTCAPACHE_KP_MKIN0_MD,
270 GPIO_NR_HTCAPACHE_KP_MKIN1_MD,
271 GPIO_NR_HTCAPACHE_KP_MKIN2_MD,
272 GPIO_NR_HTCAPACHE_KP_MKIN3_MD,
273 GPIO_NR_HTCAPACHE_KP_MKIN4_MD,
274 GPIO_NR_HTCAPACHE_KP_MKIN5_MD,
275 GPIO_NR_HTCAPACHE_KP_MKIN6_MD,
276 GPIO_NR_HTCAPACHE_KP_MKOUT0_MD,
277 GPIO_NR_HTCAPACHE_KP_MKOUT1_MD,
278 GPIO_NR_HTCAPACHE_KP_MKOUT2_MD,
279 GPIO_NR_HTCAPACHE_KP_MKOUT3_MD,
280 GPIO_NR_HTCAPACHE_KP_MKOUT4_MD,
281 GPIO_NR_HTCAPACHE_KP_MKOUT5_MD,
282 GPIO_NR_HTCAPACHE_KP_MKOUT6_MD,
286 static struct platform_device htcapache_keyboard = {
287 .name = "pxa27x-keyboard",
288 .id = -1,
289 .dev = {
290 .platform_data = &htcapache_kbd,
295 /****************************************************************
296 * Buttons on side
297 ****************************************************************/
299 static struct gpio_keys_button htcapache_button_list[] = {
300 { .gpio = GPIO_NR_HTCAPACHE_BUTTON_POWER, .keycode = KEY_POWER},
301 { .gpio = GPIO_NR_HTCAPACHE_BUTTON_RECORD, .keycode = KEY_RECORD},
302 { .gpio = GPIO_NR_HTCAPACHE_BUTTON_VOLUP, .keycode = KEY_VOLUMEUP},
303 { .gpio = GPIO_NR_HTCAPACHE_BUTTON_VOLDOWN, .keycode = KEY_VOLUMEDOWN},
304 { .gpio = GPIO_NR_HTCAPACHE_BUTTON_BROWSER, .keycode = KEY_WWW},
305 { .gpio = GPIO_NR_HTCAPACHE_BUTTON_CAMERA, .keycode = KEY_CAMERA},
308 static struct gpio_keys_platform_data htcapache_buttons_data = {
309 .buttons = htcapache_button_list,
310 .nbuttons = ARRAY_SIZE(htcapache_button_list),
313 static struct platform_device htcapache_buttons = {
314 .name = "gpio-keys",
315 .id = -1,
316 .dev = {
317 .platform_data = &htcapache_buttons_data,
322 /****************************************************************
323 * USB client controller
324 ****************************************************************/
326 static void udc_command(int cmd)
328 switch (cmd)
330 case PXA2XX_UDC_CMD_DISCONNECT:
331 printk(KERN_NOTICE "USB cmd disconnect\n");
332 GPSR_BIT(GPIO_NR_HTCAPACHE_USB_PUEN);
333 break;
334 case PXA2XX_UDC_CMD_CONNECT:
335 printk(KERN_NOTICE "USB cmd connect\n");
336 GPCR_BIT(GPIO_NR_HTCAPACHE_USB_PUEN);
337 break;
341 static struct pxa2xx_udc_mach_info htcapache_udc_mach_info = {
342 .udc_command = udc_command,
346 /****************************************************************
347 * Mini-SD card
348 ****************************************************************/
350 static int
351 htcapache_mci_init(struct device *dev
352 , irqreturn_t (*ih)(int, void *, struct pt_regs *)
353 , void *data)
355 int err = request_irq(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N)
356 , ih, SA_INTERRUPT
357 , "MMC/SD card detect", data);
358 set_irq_type(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N)
359 , IRQT_BOTHEDGE);
360 if (err) {
361 printk(KERN_ERR "htcapache_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
362 return -1;
365 return 0;
368 static void htcapache_mci_setpower(struct device *dev, unsigned int vdd)
370 struct pxamci_platform_data* p_d = dev->platform_data;
372 // XXX - No idea if this is correct for apache..
373 if ((1 << vdd) & p_d->ocr_mask) {
374 printk(KERN_NOTICE "MMC power up (vdd=%d mask=%08x)\n"
375 , vdd, p_d->ocr_mask);
376 GPSR_BIT(GPIO_NR_HTCAPACHE_SD_POWER_N);
377 } else {
378 printk(KERN_NOTICE "MMC power down (vdd=%d mask=%08x)\n"
379 , vdd, p_d->ocr_mask);
380 GPCR_BIT(GPIO_NR_HTCAPACHE_SD_POWER_N);
384 static void htcapache_mci_exit(struct device *dev, void *data)
386 free_irq(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N), data);
389 static struct pxamci_platform_data htcapache_mci_platform_data = {
390 .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
391 .init = htcapache_mci_init,
392 .setpower = htcapache_mci_setpower,
393 .exit = htcapache_mci_exit,
397 /****************************************************************
398 * Init
399 ****************************************************************/
401 extern struct platform_device htcapache_bl;
403 static struct platform_device *devices[] __initdata = {
404 &htcapache_keyboard,
405 &htcapache_buttons,
406 &htcapache_ts,
407 &htcapache_bl,
408 &acx_device,
411 static void __init htcapache_init(void)
413 htcapache_egpio_init();
414 btuart_device.dev.platform_data = &btuart_funcs;
415 set_pxa_fb_info(&htcapache_lcd);
416 pxa_set_udc_info(&htcapache_udc_mach_info);
417 pxa_set_mci_info(&htcapache_mci_platform_data);
418 pxa_set_ficp_info(&apache_ficp_platform_data);
419 platform_add_devices(devices, ARRAY_SIZE(devices));
420 htcapache_power_init();
423 MACHINE_START(HTCAPACHE, "HTC Apache")
424 .phys_io = 0x40000000,
425 .io_pg_offst = io_p2v(0x40000000),
426 .boot_params = 0xa0000100,
427 .map_io = pxa_map_io,
428 .init_irq = pxa_init_irq,
429 .timer = &pxa_timer,
430 .init_machine = htcapache_init,
431 MACHINE_END