/* * linux/arch/arm/mach-omap1/board-h6300.c * * Modified from board-innovator.c * * Board specific inits for OMAP-1510 based iPAQ h63xx series of mobile phones. * (h6315, h6340 and h6365) * * Copyright (C) 2009 Mika Laitio * Copyright (C) 2009 Husam Senussi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _h6300_KEY_CALENDAR 67 // xmodmap 75 aka F9 #define _H6300_KEY_TELEPHONE 68 // xmodmap 76 aka F10 #define _H6300_KEY_HOMEPAGE 87 // xmodmap 87 aka Num_Lock #define _H6300_KEY_MAIL 88 // xmodmap 88 aka Scroll_Lock /* * When joypad is pressed on h63xx to up, right, down or left direction, * it does not send keypress events directly from those directions. * Instead we receive multiple events from the keypresses on directions * up_right, down_right, down_left, up_left and ok. * Therefore we are summing those events in kernel level and then * making a decision which event is send to userspace. (up, right, down or left) */ #define _H6300_JOYPAD_UP_RIGHT 1 // 00001 #define _H6300_JOYPAD_DOWN_RIGHT 2 // 00010 #define _h6300_JOYPAD_DOWN_LEFT 4 // 00100 #define _h6300_JOYPAD_UP_LEFT 8 // 01000 #define _H6300_JOYPAD_KEY_OK 16 // 10000 static int h6300_keymap[] = { KEY(2, 0, _h6300_KEY_CALENDAR), // address button in the bottom left of iPAQ keypad KEY(2, 3, _H6300_KEY_TELEPHONE), // start call button in the bottom of iPAQ keypad KEY(3, 1, _H6300_KEY_HOMEPAGE), // stop call button in the bottom of iPAQ keypad KEY(3, 4, _H6300_KEY_MAIL), // messaging button in the bottom right of iPAQ keypad KEY(0, 0, KEY_VOLUMEUP), // volume up button in the right side of iPAQ keypad KEY(0, 1, KEY_VOLUMEDOWN), // volume down button in the right side of iPAQ keypad KEY(3, 2, KEY_RECORD), // record button in the left side of iPAQ keypad KEY(1, 0, _h6300_JOYPAD_UP_LEFT), KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT), KEY(1, 2, _H6300_JOYPAD_KEY_OK), KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT), KEY(1, 4, _H6300_JOYPAD_UP_RIGHT), KEY(4, 0, KEY_RIGHT), KEY(4, 1, KEY_DOWN), KEY(4, 2, KEY_LEFT), KEY(4, 3, KEY_UP), KEY(4, 4, KEY_ENTER), 0 }; static struct platform_device h6300_lcd_device = { .name = "lcd_h6300", .id = -1, }; static struct resource h6300_kp_resources[] = { [0] = { .start = INT_KEYBOARD, .end = INT_KEYBOARD, .flags = IORESOURCE_IRQ, }, }; static struct omap_kp_platform_data h6300_kp_data = { .rows = 8, .cols = 8, .keymap = h6300_keymap, .rep = 1, // turns repeat bit on }; static struct platform_device h6300_kp_device = { .name = "omap-keypad", .id = -1, .dev = { .platform_data = &h6300_kp_data, }, .num_resources = ARRAY_SIZE(h6300_kp_resources), .resource = h6300_kp_resources, }; /* * Bluetooth - Relies on h6300_bt module, * so make the calls indirectly through pointers. Requires that the * h6300_bt bluetooth module be loaded before any attempt to use * bluetooth (obviously). */ static struct platform_omap_serial_funcs h6300_omap_platform__uart_bt_funcs = { .configure = NULL, .set_txrx = NULL, .get_txrx = NULL, }; struct platform_device btuart_device = { .name = "h6300_bt", .id = 1, }; EXPORT_SYMBOL(btuart_device); static struct platform_device *h6300_devices[] __initdata = { &h6300_lcd_device, &h6300_kp_device, }; static struct omap_lcd_config h6300_lcd_config __initdata = { .ctrl_name = "internal", }; static struct omap_uart_config h6300_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; /* assume no Mini-AB port */ static struct omap_usb_config h6300_usb_config __initdata = { .hmc_mode = 0, .register_dev = 1, .pins[0] = 0, }; static struct omap_mmc_config h6300_mmc_config __initdata = { .mmc [0] = { .enabled = 1, .wire4 = 1, .wp_pin = OMAP_GPIO_IRQ(13), .power_pin = -1, // tps65010 ? .switch_pin = -1, // OMAP_MPUIO(1), // = -1, // ARMIO2? }, }; static struct omap_board_config_kernel h6300_config[] = { { OMAP_TAG_LCD, &h6300_lcd_config }, { OMAP_TAG_UART, &h6300_uart_config }, { OMAP_TAG_USB, &h6300_usb_config }, { OMAP_TAG_MMC, &h6300_mmc_config }, }; static void __init h6300_init_irq(void) { omap1_init_common_hw(); omap_init_irq(); omap_gpio_init(); /* touchscreen gpio setup is now done in the drivers/input/touschreen/omap/ts_hx.c omap_request_gpio(2); omap_set_gpio_direction(2, 0); omap_set_gpio_dataout(2, 1); */ } static void __init h6300_init(void) { int ret; ret = platform_add_devices(h6300_devices, ARRAY_SIZE(h6300_devices)); if (ret) { printk(KERN_WARNING "Unable to add h6300 platform devices."); } omap_board_config = h6300_config; omap_board_config_size = ARRAY_SIZE(h6300_config); omap_serial_init(); } static void __init h6300_map_io(void) { omap1_map_common_io(); h63xx_uart_bt_device.dev.platform_data = &h6300_omap_platform__uart_bt_funcs; } MACHINE_START(OMAP_H6300, "HP iPAQ h6300") /* MAINTAINER("Mika Laitio ") */ .phys_io = 0xfff00000, .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, .boot_params = 0x10000100, .map_io = h6300_map_io, .init_irq = h6300_init_irq, .init_machine = h6300_init, .timer = &omap_timer, MACHINE_END