18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-sa1100/simpad.c 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/module.h> 78c2ecf20Sopenharmony_ci#include <linux/gpio/machine.h> 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/tty.h> 118c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 128c2ecf20Sopenharmony_ci#include <linux/string.h> 138c2ecf20Sopenharmony_ci#include <linux/pm.h> 148c2ecf20Sopenharmony_ci#include <linux/platform_data/sa11x0-serial.h> 158c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 168c2ecf20Sopenharmony_ci#include <linux/mfd/ucb1x00.h> 178c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 188c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h> 198c2ecf20Sopenharmony_ci#include <linux/io.h> 208c2ecf20Sopenharmony_ci#include <linux/gpio/driver.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <mach/hardware.h> 238c2ecf20Sopenharmony_ci#include <asm/setup.h> 248c2ecf20Sopenharmony_ci#include <asm/irq.h> 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 278c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 288c2ecf20Sopenharmony_ci#include <asm/mach/flash.h> 298c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 308c2ecf20Sopenharmony_ci#include <linux/platform_data/mfd-mcp-sa11x0.h> 318c2ecf20Sopenharmony_ci#include <mach/simpad.h> 328c2ecf20Sopenharmony_ci#include <mach/irqs.h> 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include <linux/serial_core.h> 358c2ecf20Sopenharmony_ci#include <linux/ioport.h> 368c2ecf20Sopenharmony_ci#include <linux/input.h> 378c2ecf20Sopenharmony_ci#include <linux/gpio_keys.h> 388c2ecf20Sopenharmony_ci#include <linux/leds.h> 398c2ecf20Sopenharmony_ci#include <linux/platform_data/i2c-gpio.h> 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#include "generic.h" 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* 448c2ecf20Sopenharmony_ci * CS3 support 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic long cs3_shadow; 488c2ecf20Sopenharmony_cistatic spinlock_t cs3_lock; 498c2ecf20Sopenharmony_cistatic struct gpio_chip cs3_gpio; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cilong simpad_get_cs3_ro(void) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci return readl(CS3_BASE); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ciEXPORT_SYMBOL(simpad_get_cs3_ro); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cilong simpad_get_cs3_shadow(void) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci return cs3_shadow; 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ciEXPORT_SYMBOL(simpad_get_cs3_shadow); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic void __simpad_write_cs3(void) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci writel(cs3_shadow, CS3_BASE); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_civoid simpad_set_cs3_bit(int value) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci unsigned long flags; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci spin_lock_irqsave(&cs3_lock, flags); 738c2ecf20Sopenharmony_ci cs3_shadow |= value; 748c2ecf20Sopenharmony_ci __simpad_write_cs3(); 758c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&cs3_lock, flags); 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ciEXPORT_SYMBOL(simpad_set_cs3_bit); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_civoid simpad_clear_cs3_bit(int value) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci unsigned long flags; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci spin_lock_irqsave(&cs3_lock, flags); 848c2ecf20Sopenharmony_ci cs3_shadow &= ~value; 858c2ecf20Sopenharmony_ci __simpad_write_cs3(); 868c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&cs3_lock, flags); 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ciEXPORT_SYMBOL(simpad_clear_cs3_bit); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci if (offset > 15) 938c2ecf20Sopenharmony_ci return; 948c2ecf20Sopenharmony_ci if (value) 958c2ecf20Sopenharmony_ci simpad_set_cs3_bit(1 << offset); 968c2ecf20Sopenharmony_ci else 978c2ecf20Sopenharmony_ci simpad_clear_cs3_bit(1 << offset); 988c2ecf20Sopenharmony_ci}; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic int cs3_gpio_get(struct gpio_chip *chip, unsigned offset) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci if (offset > 15) 1038c2ecf20Sopenharmony_ci return !!(simpad_get_cs3_ro() & (1 << (offset - 16))); 1048c2ecf20Sopenharmony_ci return !!(simpad_get_cs3_shadow() & (1 << offset)); 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci if (offset > 15) 1108c2ecf20Sopenharmony_ci return 0; 1118c2ecf20Sopenharmony_ci return -EINVAL; 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 1158c2ecf20Sopenharmony_ci int value) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci if (offset > 15) 1188c2ecf20Sopenharmony_ci return -EINVAL; 1198c2ecf20Sopenharmony_ci cs3_gpio_set(chip, offset, value); 1208c2ecf20Sopenharmony_ci return 0; 1218c2ecf20Sopenharmony_ci}; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic struct map_desc simpad_io_desc[] __initdata = { 1248c2ecf20Sopenharmony_ci { /* MQ200 */ 1258c2ecf20Sopenharmony_ci .virtual = 0xf2800000, 1268c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(0x4b800000), 1278c2ecf20Sopenharmony_ci .length = 0x00800000, 1288c2ecf20Sopenharmony_ci .type = MT_DEVICE 1298c2ecf20Sopenharmony_ci }, { /* Simpad CS3 */ 1308c2ecf20Sopenharmony_ci .virtual = (unsigned long)CS3_BASE, 1318c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(SA1100_CS3_PHYS), 1328c2ecf20Sopenharmony_ci .length = 0x00100000, 1338c2ecf20Sopenharmony_ci .type = MT_DEVICE 1348c2ecf20Sopenharmony_ci }, 1358c2ecf20Sopenharmony_ci}; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci if (port->mapbase == (u_int)&Ser1UTCR0) { 1418c2ecf20Sopenharmony_ci if (state) 1428c2ecf20Sopenharmony_ci { 1438c2ecf20Sopenharmony_ci simpad_clear_cs3_bit(RS232_ON); 1448c2ecf20Sopenharmony_ci simpad_clear_cs3_bit(DECT_POWER_ON); 1458c2ecf20Sopenharmony_ci }else 1468c2ecf20Sopenharmony_ci { 1478c2ecf20Sopenharmony_ci simpad_set_cs3_bit(RS232_ON); 1488c2ecf20Sopenharmony_ci simpad_set_cs3_bit(DECT_POWER_ON); 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci} 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistatic struct sa1100_port_fns simpad_port_fns __initdata = { 1548c2ecf20Sopenharmony_ci .pm = simpad_uart_pm, 1558c2ecf20Sopenharmony_ci}; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic struct mtd_partition simpad_partitions[] = { 1598c2ecf20Sopenharmony_ci { 1608c2ecf20Sopenharmony_ci .name = "SIMpad boot firmware", 1618c2ecf20Sopenharmony_ci .size = 0x00080000, 1628c2ecf20Sopenharmony_ci .offset = 0, 1638c2ecf20Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 1648c2ecf20Sopenharmony_ci }, { 1658c2ecf20Sopenharmony_ci .name = "SIMpad kernel", 1668c2ecf20Sopenharmony_ci .size = 0x0010000, 1678c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 1688c2ecf20Sopenharmony_ci }, { 1698c2ecf20Sopenharmony_ci .name = "SIMpad root jffs2", 1708c2ecf20Sopenharmony_ci .size = MTDPART_SIZ_FULL, 1718c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic struct flash_platform_data simpad_flash_data = { 1768c2ecf20Sopenharmony_ci .map_name = "cfi_probe", 1778c2ecf20Sopenharmony_ci .parts = simpad_partitions, 1788c2ecf20Sopenharmony_ci .nr_parts = ARRAY_SIZE(simpad_partitions), 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic struct resource simpad_flash_resources [] = { 1838c2ecf20Sopenharmony_ci DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M), 1848c2ecf20Sopenharmony_ci DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M), 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic struct ucb1x00_plat_data simpad_ucb1x00_data = { 1888c2ecf20Sopenharmony_ci .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic struct mcp_plat_data simpad_mcp_data = { 1928c2ecf20Sopenharmony_ci .mccr0 = MCCR0_ADM, 1938c2ecf20Sopenharmony_ci .sclk_rate = 11981000, 1948c2ecf20Sopenharmony_ci .codec_pdata = &simpad_ucb1x00_data, 1958c2ecf20Sopenharmony_ci}; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic void __init simpad_map_io(void) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci sa1100_map_io(); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc)); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci /* Initialize CS3 */ 2068c2ecf20Sopenharmony_ci cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | 2078c2ecf20Sopenharmony_ci RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON); 2088c2ecf20Sopenharmony_ci __simpad_write_cs3(); /* Spinlocks not yet initialized */ 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci sa1100_register_uart_fns(&simpad_port_fns); 2118c2ecf20Sopenharmony_ci sa1100_register_uart(0, 3); /* serial interface */ 2128c2ecf20Sopenharmony_ci sa1100_register_uart(1, 1); /* DECT */ 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci // Reassign UART 1 pins 2158c2ecf20Sopenharmony_ci GAFR |= GPIO_UART_TXD | GPIO_UART_RXD; 2168c2ecf20Sopenharmony_ci GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15; 2178c2ecf20Sopenharmony_ci GPDR &= ~GPIO_UART_RXD; 2188c2ecf20Sopenharmony_ci PPAR |= PPAR_UPR; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci /* 2218c2ecf20Sopenharmony_ci * Set up registers for sleep mode. 2228c2ecf20Sopenharmony_ci */ 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci PWER = PWER_GPIO0| PWER_RTC; 2268c2ecf20Sopenharmony_ci PGSR = 0x818; 2278c2ecf20Sopenharmony_ci PCFR = 0; 2288c2ecf20Sopenharmony_ci PSDR = 0; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic void simpad_power_off(void) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci local_irq_disable(); 2358c2ecf20Sopenharmony_ci cs3_shadow = SD_MEDIAQ; 2368c2ecf20Sopenharmony_ci __simpad_write_cs3(); /* Bypass spinlock here */ 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* disable internal oscillator, float CS lines */ 2398c2ecf20Sopenharmony_ci PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); 2408c2ecf20Sopenharmony_ci /* enable wake-up on GPIO0 */ 2418c2ecf20Sopenharmony_ci PWER = GFER = GRER = PWER_GPIO0; 2428c2ecf20Sopenharmony_ci /* 2438c2ecf20Sopenharmony_ci * set scratchpad to zero, just in case it is used as a 2448c2ecf20Sopenharmony_ci * restart address by the bootloader. 2458c2ecf20Sopenharmony_ci */ 2468c2ecf20Sopenharmony_ci PSPR = 0; 2478c2ecf20Sopenharmony_ci PGSR = 0; 2488c2ecf20Sopenharmony_ci /* enter sleep mode */ 2498c2ecf20Sopenharmony_ci PMCR = PMCR_SF; 2508c2ecf20Sopenharmony_ci while(1); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci local_irq_enable(); /* we won't ever call it */ 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci/* 2588c2ecf20Sopenharmony_ci * gpio_keys 2598c2ecf20Sopenharmony_ci*/ 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_cistatic struct gpio_keys_button simpad_button_table[] = { 2628c2ecf20Sopenharmony_ci { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" }, 2638c2ecf20Sopenharmony_ci}; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_cistatic struct gpio_keys_platform_data simpad_keys_data = { 2668c2ecf20Sopenharmony_ci .buttons = simpad_button_table, 2678c2ecf20Sopenharmony_ci .nbuttons = ARRAY_SIZE(simpad_button_table), 2688c2ecf20Sopenharmony_ci}; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic struct platform_device simpad_keys = { 2718c2ecf20Sopenharmony_ci .name = "gpio-keys", 2728c2ecf20Sopenharmony_ci .dev = { 2738c2ecf20Sopenharmony_ci .platform_data = &simpad_keys_data, 2748c2ecf20Sopenharmony_ci }, 2758c2ecf20Sopenharmony_ci}; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic struct gpio_keys_button simpad_polled_button_table[] = { 2788c2ecf20Sopenharmony_ci { KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" }, 2798c2ecf20Sopenharmony_ci { KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" }, 2808c2ecf20Sopenharmony_ci { KEY_UP, SIMPAD_UCB1X00_GPIO_UP, 1, "up button" }, 2818c2ecf20Sopenharmony_ci { KEY_DOWN, SIMPAD_UCB1X00_GPIO_DOWN, 1, "down button" }, 2828c2ecf20Sopenharmony_ci { KEY_LEFT, SIMPAD_UCB1X00_GPIO_LEFT, 1, "left button" }, 2838c2ecf20Sopenharmony_ci { KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" }, 2848c2ecf20Sopenharmony_ci}; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cistatic struct gpio_keys_platform_data simpad_polled_keys_data = { 2878c2ecf20Sopenharmony_ci .buttons = simpad_polled_button_table, 2888c2ecf20Sopenharmony_ci .nbuttons = ARRAY_SIZE(simpad_polled_button_table), 2898c2ecf20Sopenharmony_ci .poll_interval = 50, 2908c2ecf20Sopenharmony_ci}; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic struct platform_device simpad_polled_keys = { 2938c2ecf20Sopenharmony_ci .name = "gpio-keys-polled", 2948c2ecf20Sopenharmony_ci .dev = { 2958c2ecf20Sopenharmony_ci .platform_data = &simpad_polled_keys_data, 2968c2ecf20Sopenharmony_ci }, 2978c2ecf20Sopenharmony_ci}; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci/* 3008c2ecf20Sopenharmony_ci * GPIO LEDs 3018c2ecf20Sopenharmony_ci */ 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic struct gpio_led simpad_leds[] = { 3048c2ecf20Sopenharmony_ci { 3058c2ecf20Sopenharmony_ci .name = "simpad:power", 3068c2ecf20Sopenharmony_ci .gpio = SIMPAD_CS3_LED2_ON, 3078c2ecf20Sopenharmony_ci .active_low = 0, 3088c2ecf20Sopenharmony_ci .default_trigger = "default-on", 3098c2ecf20Sopenharmony_ci }, 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic struct gpio_led_platform_data simpad_led_data = { 3138c2ecf20Sopenharmony_ci .num_leds = ARRAY_SIZE(simpad_leds), 3148c2ecf20Sopenharmony_ci .leds = simpad_leds, 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic struct platform_device simpad_gpio_leds = { 3188c2ecf20Sopenharmony_ci .name = "leds-gpio", 3198c2ecf20Sopenharmony_ci .id = 0, 3208c2ecf20Sopenharmony_ci .dev = { 3218c2ecf20Sopenharmony_ci .platform_data = &simpad_led_data, 3228c2ecf20Sopenharmony_ci }, 3238c2ecf20Sopenharmony_ci}; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci/* 3268c2ecf20Sopenharmony_ci * i2c 3278c2ecf20Sopenharmony_ci */ 3288c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table simpad_i2c_gpiod_table = { 3298c2ecf20Sopenharmony_ci .dev_id = "i2c-gpio.0", 3308c2ecf20Sopenharmony_ci .table = { 3318c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX("gpio", 21, NULL, 0, 3328c2ecf20Sopenharmony_ci GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), 3338c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX("gpio", 25, NULL, 1, 3348c2ecf20Sopenharmony_ci GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), 3358c2ecf20Sopenharmony_ci }, 3368c2ecf20Sopenharmony_ci}; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_cistatic struct i2c_gpio_platform_data simpad_i2c_data = { 3398c2ecf20Sopenharmony_ci .udelay = 10, 3408c2ecf20Sopenharmony_ci .timeout = HZ, 3418c2ecf20Sopenharmony_ci}; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic struct platform_device simpad_i2c = { 3448c2ecf20Sopenharmony_ci .name = "i2c-gpio", 3458c2ecf20Sopenharmony_ci .id = 0, 3468c2ecf20Sopenharmony_ci .dev = { 3478c2ecf20Sopenharmony_ci .platform_data = &simpad_i2c_data, 3488c2ecf20Sopenharmony_ci }, 3498c2ecf20Sopenharmony_ci}; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci/* 3528c2ecf20Sopenharmony_ci * MediaQ Video Device 3538c2ecf20Sopenharmony_ci */ 3548c2ecf20Sopenharmony_cistatic struct platform_device simpad_mq200fb = { 3558c2ecf20Sopenharmony_ci .name = "simpad-mq200", 3568c2ecf20Sopenharmony_ci .id = 0, 3578c2ecf20Sopenharmony_ci}; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_cistatic struct platform_device *devices[] __initdata = { 3608c2ecf20Sopenharmony_ci &simpad_keys, 3618c2ecf20Sopenharmony_ci &simpad_polled_keys, 3628c2ecf20Sopenharmony_ci &simpad_mq200fb, 3638c2ecf20Sopenharmony_ci &simpad_gpio_leds, 3648c2ecf20Sopenharmony_ci &simpad_i2c, 3658c2ecf20Sopenharmony_ci}; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci/* Compact Flash */ 3688c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table simpad_cf_gpio_table = { 3698c2ecf20Sopenharmony_ci .dev_id = "sa11x0-pcmcia", 3708c2ecf20Sopenharmony_ci .table = { 3718c2ecf20Sopenharmony_ci GPIO_LOOKUP("gpio", GPIO_CF_IRQ, "cf-ready", GPIO_ACTIVE_HIGH), 3728c2ecf20Sopenharmony_ci GPIO_LOOKUP("gpio", GPIO_CF_CD, "cf-detect", GPIO_ACTIVE_HIGH), 3738c2ecf20Sopenharmony_ci { }, 3748c2ecf20Sopenharmony_ci }, 3758c2ecf20Sopenharmony_ci}; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_cistatic int __init simpad_init(void) 3798c2ecf20Sopenharmony_ci{ 3808c2ecf20Sopenharmony_ci int ret; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci spin_lock_init(&cs3_lock); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci cs3_gpio.label = "simpad_cs3"; 3858c2ecf20Sopenharmony_ci cs3_gpio.base = SIMPAD_CS3_GPIO_BASE; 3868c2ecf20Sopenharmony_ci cs3_gpio.ngpio = 24; 3878c2ecf20Sopenharmony_ci cs3_gpio.set = cs3_gpio_set; 3888c2ecf20Sopenharmony_ci cs3_gpio.get = cs3_gpio_get; 3898c2ecf20Sopenharmony_ci cs3_gpio.direction_input = cs3_gpio_direction_input; 3908c2ecf20Sopenharmony_ci cs3_gpio.direction_output = cs3_gpio_direction_output; 3918c2ecf20Sopenharmony_ci ret = gpiochip_add_data(&cs3_gpio, NULL); 3928c2ecf20Sopenharmony_ci if (ret) 3938c2ecf20Sopenharmony_ci printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device"); 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci pm_power_off = simpad_power_off; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci sa11x0_register_pcmcia(-1, &simpad_cf_gpio_table); 3988c2ecf20Sopenharmony_ci sa11x0_ppc_configure_mcp(); 3998c2ecf20Sopenharmony_ci sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, 4008c2ecf20Sopenharmony_ci ARRAY_SIZE(simpad_flash_resources)); 4018c2ecf20Sopenharmony_ci sa11x0_register_mcp(&simpad_mcp_data); 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci gpiod_add_lookup_table(&simpad_i2c_gpiod_table); 4048c2ecf20Sopenharmony_ci ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 4058c2ecf20Sopenharmony_ci if(ret) 4068c2ecf20Sopenharmony_ci printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device"); 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci return 0; 4098c2ecf20Sopenharmony_ci} 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ciarch_initcall(simpad_init); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ciMACHINE_START(SIMPAD, "Simpad") 4158c2ecf20Sopenharmony_ci /* Maintainer: Holger Freyther */ 4168c2ecf20Sopenharmony_ci .atag_offset = 0x100, 4178c2ecf20Sopenharmony_ci .map_io = simpad_map_io, 4188c2ecf20Sopenharmony_ci .nr_irqs = SA1100_NR_IRQS, 4198c2ecf20Sopenharmony_ci .init_irq = sa1100_init_irq, 4208c2ecf20Sopenharmony_ci .init_late = sa11x0_init_late, 4218c2ecf20Sopenharmony_ci .init_time = sa1100_timer_init, 4228c2ecf20Sopenharmony_ci .restart = sa11x0_restart, 4238c2ecf20Sopenharmony_ciMACHINE_END 424