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>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/device.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 /****************************************************************
42 ****************************************************************/
44 static void htcapache_backlight_power(int on
)
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 /****************************************************************
56 ****************************************************************/
58 static struct pxafb_mach_info htcapache_lcd __initdata
= {
66 // These margins are from WinCE
72 .lccr0
= LCCR0_LDDALT
| LCCR0_Act
,
73 .pxafb_backlight_power
= htcapache_backlight_power
,
77 /****************************************************************
79 ****************************************************************/
81 static struct platform_device htcapache_ts
= {
82 .name
= "htcapache-ad7877",
86 /****************************************************************
88 ****************************************************************/
90 static void btuart_configure(int 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
);
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
110 } while ((BTMSR
& MSR_CTS
) == 0 && tries
++ < 50);
111 printk("btuart: post_startup (%d)\n", tries
);
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");
121 static struct platform_pxa_serial_funcs btuart_funcs
= {
122 .configure
= btuart_configure
,
126 /****************************************************************
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 /****************************************************************
145 ****************************************************************/
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
);
154 htcapache_egpio_set(EGPIO_NR_HTCAPACHE_WIFI_RESET
);
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
);
170 WLAN_BASE
= PXA_CS2_PHYS
,
173 static struct resource acx_resources
[] = {
176 .end
= WLAN_BASE
+ 0x20,
177 .flags
= IORESOURCE_MEM
,
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
= {
194 .platform_data
= &acx_data
,
196 .num_resources
= ARRAY_SIZE(acx_resources
),
197 .resource
= acx_resources
,
201 /****************************************************************
203 ****************************************************************/
205 static struct pxa27x_keyboard_platform_data htcapache_kbd
= {
212 KEY_LEFTSHIFT
, // Left Shift
221 KEY_LEFTALT
, // Red Dot
228 KEY_LEFTMETA
, // Windows Key
232 KEY_BACKSPACE
, // Backspace
243 KEY_LEFTCTRL
, // Left Menu
251 KEY_RIGHTCTRL
, // Right Menu
260 KEY_LEFT
, // Left Arrow
261 KEY_DOWN
, // Down Arrow
263 KEY_ESC
, // OK button
265 KEY_RIGHT
, // Right Arrow
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",
290 .platform_data
= &htcapache_kbd
,
295 /****************************************************************
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
= {
317 .platform_data
= &htcapache_buttons_data
,
322 /****************************************************************
323 * USB client controller
324 ****************************************************************/
326 static void udc_command(int cmd
)
330 case PXA2XX_UDC_CMD_DISCONNECT
:
331 printk(KERN_NOTICE
"USB cmd disconnect\n");
332 GPSR_BIT(GPIO_NR_HTCAPACHE_USB_PUEN
);
334 case PXA2XX_UDC_CMD_CONNECT
:
335 printk(KERN_NOTICE
"USB cmd connect\n");
336 GPCR_BIT(GPIO_NR_HTCAPACHE_USB_PUEN
);
341 static struct pxa2xx_udc_mach_info htcapache_udc_mach_info
= {
342 .udc_command
= udc_command
,
346 /****************************************************************
348 ****************************************************************/
351 htcapache_mci_init(struct device
*dev
352 , irqreturn_t (*ih
)(int, void *, struct pt_regs
*)
355 int err
= request_irq(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N
)
357 , "MMC/SD card detect", data
);
358 set_irq_type(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N
)
361 printk(KERN_ERR
"htcapache_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
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
);
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 /****************************************************************
399 ****************************************************************/
401 extern struct platform_device htcapache_bl
;
403 static struct platform_device
*devices
[] __initdata
= {
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
,
430 .init_machine
= htcapache_init
,