18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-omap1/board-ams-delta.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Modified from board-generic.c 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Board specific inits for the Amstrad E3 (codename Delta) videophone 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include <linux/gpio/driver.h> 128c2ecf20Sopenharmony_ci#include <linux/gpio/machine.h> 138c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 148c2ecf20Sopenharmony_ci#include <linux/gpio.h> 158c2ecf20Sopenharmony_ci#include <linux/kernel.h> 168c2ecf20Sopenharmony_ci#include <linux/init.h> 178c2ecf20Sopenharmony_ci#include <linux/input.h> 188c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 198c2ecf20Sopenharmony_ci#include <linux/leds.h> 208c2ecf20Sopenharmony_ci#include <linux/mtd/nand-gpio.h> 218c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h> 228c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 238c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h> 248c2ecf20Sopenharmony_ci#include <linux/regulator/fixed.h> 258c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h> 268c2ecf20Sopenharmony_ci#include <linux/serial_8250.h> 278c2ecf20Sopenharmony_ci#include <linux/export.h> 288c2ecf20Sopenharmony_ci#include <linux/omapfb.h> 298c2ecf20Sopenharmony_ci#include <linux/io.h> 308c2ecf20Sopenharmony_ci#include <linux/platform_data/gpio-omap.h> 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include <asm/serial.h> 338c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 348c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 358c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include <linux/platform_data/keypad-omap.h> 388c2ecf20Sopenharmony_ci#include <mach/mux.h> 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#include <mach/hardware.h> 418c2ecf20Sopenharmony_ci#include <mach/usb.h> 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#include "ams-delta-fiq.h" 448c2ecf20Sopenharmony_ci#include "board-ams-delta.h" 458c2ecf20Sopenharmony_ci#include "iomap.h" 468c2ecf20Sopenharmony_ci#include "common.h" 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic const unsigned int ams_delta_keymap[] = { 498c2ecf20Sopenharmony_ci KEY(0, 0, KEY_F1), /* Advert */ 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci KEY(0, 3, KEY_COFFEE), /* Games */ 528c2ecf20Sopenharmony_ci KEY(0, 2, KEY_QUESTION), /* Directory */ 538c2ecf20Sopenharmony_ci KEY(2, 3, KEY_CONNECT), /* Internet */ 548c2ecf20Sopenharmony_ci KEY(1, 2, KEY_SHOP), /* Services */ 558c2ecf20Sopenharmony_ci KEY(1, 1, KEY_PHONE), /* VoiceMail */ 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci KEY(0, 1, KEY_DELETE), /* Delete */ 588c2ecf20Sopenharmony_ci KEY(2, 2, KEY_PLAY), /* Play */ 598c2ecf20Sopenharmony_ci KEY(1, 0, KEY_PAGEUP), /* Up */ 608c2ecf20Sopenharmony_ci KEY(1, 3, KEY_PAGEDOWN), /* Down */ 618c2ecf20Sopenharmony_ci KEY(2, 0, KEY_EMAIL), /* ReadEmail */ 628c2ecf20Sopenharmony_ci KEY(2, 1, KEY_STOP), /* Stop */ 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* Numeric keypad portion */ 658c2ecf20Sopenharmony_ci KEY(0, 7, KEY_KP1), 668c2ecf20Sopenharmony_ci KEY(0, 6, KEY_KP2), 678c2ecf20Sopenharmony_ci KEY(0, 5, KEY_KP3), 688c2ecf20Sopenharmony_ci KEY(1, 7, KEY_KP4), 698c2ecf20Sopenharmony_ci KEY(1, 6, KEY_KP5), 708c2ecf20Sopenharmony_ci KEY(1, 5, KEY_KP6), 718c2ecf20Sopenharmony_ci KEY(2, 7, KEY_KP7), 728c2ecf20Sopenharmony_ci KEY(2, 6, KEY_KP8), 738c2ecf20Sopenharmony_ci KEY(2, 5, KEY_KP9), 748c2ecf20Sopenharmony_ci KEY(3, 6, KEY_KP0), 758c2ecf20Sopenharmony_ci KEY(3, 7, KEY_KPASTERISK), 768c2ecf20Sopenharmony_ci KEY(3, 5, KEY_KPDOT), /* # key */ 778c2ecf20Sopenharmony_ci KEY(7, 2, KEY_NUMLOCK), /* Mute */ 788c2ecf20Sopenharmony_ci KEY(7, 1, KEY_KPMINUS), /* Recall */ 798c2ecf20Sopenharmony_ci KEY(6, 1, KEY_KPPLUS), /* Redial */ 808c2ecf20Sopenharmony_ci KEY(7, 6, KEY_KPSLASH), /* Handsfree */ 818c2ecf20Sopenharmony_ci KEY(6, 0, KEY_ENTER), /* Video */ 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci KEY(7, 4, KEY_CAMERA), /* Photo */ 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci KEY(0, 4, KEY_F2), /* Home */ 868c2ecf20Sopenharmony_ci KEY(1, 4, KEY_F3), /* Office */ 878c2ecf20Sopenharmony_ci KEY(2, 4, KEY_F4), /* Mobile */ 888c2ecf20Sopenharmony_ci KEY(7, 7, KEY_F5), /* SMS */ 898c2ecf20Sopenharmony_ci KEY(7, 5, KEY_F6), /* Email */ 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* QWERTY portion of keypad */ 928c2ecf20Sopenharmony_ci KEY(3, 4, KEY_Q), 938c2ecf20Sopenharmony_ci KEY(3, 3, KEY_W), 948c2ecf20Sopenharmony_ci KEY(3, 2, KEY_E), 958c2ecf20Sopenharmony_ci KEY(3, 1, KEY_R), 968c2ecf20Sopenharmony_ci KEY(3, 0, KEY_T), 978c2ecf20Sopenharmony_ci KEY(4, 7, KEY_Y), 988c2ecf20Sopenharmony_ci KEY(4, 6, KEY_U), 998c2ecf20Sopenharmony_ci KEY(4, 5, KEY_I), 1008c2ecf20Sopenharmony_ci KEY(4, 4, KEY_O), 1018c2ecf20Sopenharmony_ci KEY(4, 3, KEY_P), 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci KEY(4, 2, KEY_A), 1048c2ecf20Sopenharmony_ci KEY(4, 1, KEY_S), 1058c2ecf20Sopenharmony_ci KEY(4, 0, KEY_D), 1068c2ecf20Sopenharmony_ci KEY(5, 7, KEY_F), 1078c2ecf20Sopenharmony_ci KEY(5, 6, KEY_G), 1088c2ecf20Sopenharmony_ci KEY(5, 5, KEY_H), 1098c2ecf20Sopenharmony_ci KEY(5, 4, KEY_J), 1108c2ecf20Sopenharmony_ci KEY(5, 3, KEY_K), 1118c2ecf20Sopenharmony_ci KEY(5, 2, KEY_L), 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci KEY(5, 1, KEY_Z), 1148c2ecf20Sopenharmony_ci KEY(5, 0, KEY_X), 1158c2ecf20Sopenharmony_ci KEY(6, 7, KEY_C), 1168c2ecf20Sopenharmony_ci KEY(6, 6, KEY_V), 1178c2ecf20Sopenharmony_ci KEY(6, 5, KEY_B), 1188c2ecf20Sopenharmony_ci KEY(6, 4, KEY_N), 1198c2ecf20Sopenharmony_ci KEY(6, 3, KEY_M), 1208c2ecf20Sopenharmony_ci KEY(6, 2, KEY_SPACE), 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci KEY(7, 0, KEY_LEFTSHIFT), /* Vol up */ 1238c2ecf20Sopenharmony_ci KEY(7, 3, KEY_LEFTCTRL), /* Vol down */ 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#define LATCH1_PHYS 0x01000000 1278c2ecf20Sopenharmony_ci#define LATCH1_VIRT 0xEA000000 1288c2ecf20Sopenharmony_ci#define MODEM_PHYS 0x04000000 1298c2ecf20Sopenharmony_ci#define MODEM_VIRT 0xEB000000 1308c2ecf20Sopenharmony_ci#define LATCH2_PHYS 0x08000000 1318c2ecf20Sopenharmony_ci#define LATCH2_VIRT 0xEC000000 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic struct map_desc ams_delta_io_desc[] __initdata = { 1348c2ecf20Sopenharmony_ci /* AMS_DELTA_LATCH1 */ 1358c2ecf20Sopenharmony_ci { 1368c2ecf20Sopenharmony_ci .virtual = LATCH1_VIRT, 1378c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(LATCH1_PHYS), 1388c2ecf20Sopenharmony_ci .length = 0x01000000, 1398c2ecf20Sopenharmony_ci .type = MT_DEVICE 1408c2ecf20Sopenharmony_ci }, 1418c2ecf20Sopenharmony_ci /* AMS_DELTA_LATCH2 */ 1428c2ecf20Sopenharmony_ci { 1438c2ecf20Sopenharmony_ci .virtual = LATCH2_VIRT, 1448c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(LATCH2_PHYS), 1458c2ecf20Sopenharmony_ci .length = 0x01000000, 1468c2ecf20Sopenharmony_ci .type = MT_DEVICE 1478c2ecf20Sopenharmony_ci }, 1488c2ecf20Sopenharmony_ci /* AMS_DELTA_MODEM */ 1498c2ecf20Sopenharmony_ci { 1508c2ecf20Sopenharmony_ci .virtual = MODEM_VIRT, 1518c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(MODEM_PHYS), 1528c2ecf20Sopenharmony_ci .length = 0x01000000, 1538c2ecf20Sopenharmony_ci .type = MT_DEVICE 1548c2ecf20Sopenharmony_ci } 1558c2ecf20Sopenharmony_ci}; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic const struct omap_lcd_config ams_delta_lcd_config __initconst = { 1588c2ecf20Sopenharmony_ci .ctrl_name = "internal", 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic struct omap_usb_config ams_delta_usb_config __initdata = { 1628c2ecf20Sopenharmony_ci .register_host = 1, 1638c2ecf20Sopenharmony_ci .hmc_mode = 16, 1648c2ecf20Sopenharmony_ci .pins[0] = 2, 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#define LATCH1_NGPIO 8 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic struct resource latch1_resources[] = { 1708c2ecf20Sopenharmony_ci [0] = { 1718c2ecf20Sopenharmony_ci .name = "dat", 1728c2ecf20Sopenharmony_ci .start = LATCH1_PHYS, 1738c2ecf20Sopenharmony_ci .end = LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8, 1748c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1758c2ecf20Sopenharmony_ci }, 1768c2ecf20Sopenharmony_ci}; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci#define LATCH1_LABEL "latch1" 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic struct bgpio_pdata latch1_pdata = { 1818c2ecf20Sopenharmony_ci .label = LATCH1_LABEL, 1828c2ecf20Sopenharmony_ci .base = -1, 1838c2ecf20Sopenharmony_ci .ngpio = LATCH1_NGPIO, 1848c2ecf20Sopenharmony_ci}; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistatic struct platform_device latch1_gpio_device = { 1878c2ecf20Sopenharmony_ci .name = "basic-mmio-gpio", 1888c2ecf20Sopenharmony_ci .id = 0, 1898c2ecf20Sopenharmony_ci .resource = latch1_resources, 1908c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(latch1_resources), 1918c2ecf20Sopenharmony_ci .dev = { 1928c2ecf20Sopenharmony_ci .platform_data = &latch1_pdata, 1938c2ecf20Sopenharmony_ci }, 1948c2ecf20Sopenharmony_ci}; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci#define LATCH1_PIN_LED_CAMERA 0 1978c2ecf20Sopenharmony_ci#define LATCH1_PIN_LED_ADVERT 1 1988c2ecf20Sopenharmony_ci#define LATCH1_PIN_LED_MAIL 2 1998c2ecf20Sopenharmony_ci#define LATCH1_PIN_LED_HANDSFREE 3 2008c2ecf20Sopenharmony_ci#define LATCH1_PIN_LED_VOICEMAIL 4 2018c2ecf20Sopenharmony_ci#define LATCH1_PIN_LED_VOICE 5 2028c2ecf20Sopenharmony_ci#define LATCH1_PIN_DOCKIT1 6 2038c2ecf20Sopenharmony_ci#define LATCH1_PIN_DOCKIT2 7 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#define LATCH2_NGPIO 16 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistatic struct resource latch2_resources[] = { 2088c2ecf20Sopenharmony_ci [0] = { 2098c2ecf20Sopenharmony_ci .name = "dat", 2108c2ecf20Sopenharmony_ci .start = LATCH2_PHYS, 2118c2ecf20Sopenharmony_ci .end = LATCH2_PHYS + (LATCH2_NGPIO - 1) / 8, 2128c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 2138c2ecf20Sopenharmony_ci }, 2148c2ecf20Sopenharmony_ci}; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci#define LATCH2_LABEL "latch2" 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cistatic struct bgpio_pdata latch2_pdata = { 2198c2ecf20Sopenharmony_ci .label = LATCH2_LABEL, 2208c2ecf20Sopenharmony_ci .base = -1, 2218c2ecf20Sopenharmony_ci .ngpio = LATCH2_NGPIO, 2228c2ecf20Sopenharmony_ci}; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic struct platform_device latch2_gpio_device = { 2258c2ecf20Sopenharmony_ci .name = "basic-mmio-gpio", 2268c2ecf20Sopenharmony_ci .id = 1, 2278c2ecf20Sopenharmony_ci .resource = latch2_resources, 2288c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(latch2_resources), 2298c2ecf20Sopenharmony_ci .dev = { 2308c2ecf20Sopenharmony_ci .platform_data = &latch2_pdata, 2318c2ecf20Sopenharmony_ci }, 2328c2ecf20Sopenharmony_ci}; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci#define LATCH2_PIN_LCD_VBLEN 0 2358c2ecf20Sopenharmony_ci#define LATCH2_PIN_LCD_NDISP 1 2368c2ecf20Sopenharmony_ci#define LATCH2_PIN_NAND_NCE 2 2378c2ecf20Sopenharmony_ci#define LATCH2_PIN_NAND_NRE 3 2388c2ecf20Sopenharmony_ci#define LATCH2_PIN_NAND_NWP 4 2398c2ecf20Sopenharmony_ci#define LATCH2_PIN_NAND_NWE 5 2408c2ecf20Sopenharmony_ci#define LATCH2_PIN_NAND_ALE 6 2418c2ecf20Sopenharmony_ci#define LATCH2_PIN_NAND_CLE 7 2428c2ecf20Sopenharmony_ci#define LATCH2_PIN_KEYBRD_PWR 8 2438c2ecf20Sopenharmony_ci#define LATCH2_PIN_KEYBRD_DATAOUT 9 2448c2ecf20Sopenharmony_ci#define LATCH2_PIN_SCARD_RSTIN 10 2458c2ecf20Sopenharmony_ci#define LATCH2_PIN_SCARD_CMDVCC 11 2468c2ecf20Sopenharmony_ci#define LATCH2_PIN_MODEM_NRESET 12 2478c2ecf20Sopenharmony_ci#define LATCH2_PIN_MODEM_CODEC 13 2488c2ecf20Sopenharmony_ci#define LATCH2_PIN_HANDSFREE_MUTE 14 2498c2ecf20Sopenharmony_ci#define LATCH2_PIN_HANDSET_MUTE 15 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic struct regulator_consumer_supply modem_nreset_consumers[] = { 2528c2ecf20Sopenharmony_ci REGULATOR_SUPPLY("RESET#", "serial8250.1"), 2538c2ecf20Sopenharmony_ci REGULATOR_SUPPLY("POR", "cx20442-codec"), 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_cistatic struct regulator_init_data modem_nreset_data = { 2578c2ecf20Sopenharmony_ci .constraints = { 2588c2ecf20Sopenharmony_ci .valid_ops_mask = REGULATOR_CHANGE_STATUS, 2598c2ecf20Sopenharmony_ci .boot_on = 1, 2608c2ecf20Sopenharmony_ci }, 2618c2ecf20Sopenharmony_ci .num_consumer_supplies = ARRAY_SIZE(modem_nreset_consumers), 2628c2ecf20Sopenharmony_ci .consumer_supplies = modem_nreset_consumers, 2638c2ecf20Sopenharmony_ci}; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_cistatic struct fixed_voltage_config modem_nreset_config = { 2668c2ecf20Sopenharmony_ci .supply_name = "modem_nreset", 2678c2ecf20Sopenharmony_ci .microvolts = 3300000, 2688c2ecf20Sopenharmony_ci .startup_delay = 25000, 2698c2ecf20Sopenharmony_ci .enabled_at_boot = 1, 2708c2ecf20Sopenharmony_ci .init_data = &modem_nreset_data, 2718c2ecf20Sopenharmony_ci}; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_cistatic struct platform_device modem_nreset_device = { 2748c2ecf20Sopenharmony_ci .name = "reg-fixed-voltage", 2758c2ecf20Sopenharmony_ci .id = -1, 2768c2ecf20Sopenharmony_ci .dev = { 2778c2ecf20Sopenharmony_ci .platform_data = &modem_nreset_config, 2788c2ecf20Sopenharmony_ci }, 2798c2ecf20Sopenharmony_ci}; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_nreset_gpiod_table = { 2828c2ecf20Sopenharmony_ci .dev_id = "reg-fixed-voltage", 2838c2ecf20Sopenharmony_ci .table = { 2848c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_NRESET, 2858c2ecf20Sopenharmony_ci NULL, GPIO_ACTIVE_HIGH), 2868c2ecf20Sopenharmony_ci { }, 2878c2ecf20Sopenharmony_ci }, 2888c2ecf20Sopenharmony_ci}; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cistruct modem_private_data { 2918c2ecf20Sopenharmony_ci struct regulator *regulator; 2928c2ecf20Sopenharmony_ci}; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic struct modem_private_data modem_priv; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* 2978c2ecf20Sopenharmony_ci * Define partitions for flash device 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic struct mtd_partition partition_info[] = { 3018c2ecf20Sopenharmony_ci { .name = "Kernel", 3028c2ecf20Sopenharmony_ci .offset = 0, 3038c2ecf20Sopenharmony_ci .size = 3 * SZ_1M + SZ_512K }, 3048c2ecf20Sopenharmony_ci { .name = "u-boot", 3058c2ecf20Sopenharmony_ci .offset = 3 * SZ_1M + SZ_512K, 3068c2ecf20Sopenharmony_ci .size = SZ_256K }, 3078c2ecf20Sopenharmony_ci { .name = "u-boot params", 3088c2ecf20Sopenharmony_ci .offset = 3 * SZ_1M + SZ_512K + SZ_256K, 3098c2ecf20Sopenharmony_ci .size = SZ_256K }, 3108c2ecf20Sopenharmony_ci { .name = "Amstrad LDR", 3118c2ecf20Sopenharmony_ci .offset = 4 * SZ_1M, 3128c2ecf20Sopenharmony_ci .size = SZ_256K }, 3138c2ecf20Sopenharmony_ci { .name = "File system", 3148c2ecf20Sopenharmony_ci .offset = 4 * SZ_1M + 1 * SZ_256K, 3158c2ecf20Sopenharmony_ci .size = 27 * SZ_1M }, 3168c2ecf20Sopenharmony_ci { .name = "PBL reserved", 3178c2ecf20Sopenharmony_ci .offset = 32 * SZ_1M - 3 * SZ_256K, 3188c2ecf20Sopenharmony_ci .size = 3 * SZ_256K }, 3198c2ecf20Sopenharmony_ci}; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic struct gpio_nand_platdata nand_platdata = { 3228c2ecf20Sopenharmony_ci .parts = partition_info, 3238c2ecf20Sopenharmony_ci .num_parts = ARRAY_SIZE(partition_info), 3248c2ecf20Sopenharmony_ci}; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic struct platform_device ams_delta_nand_device = { 3278c2ecf20Sopenharmony_ci .name = "ams-delta-nand", 3288c2ecf20Sopenharmony_ci .id = -1, 3298c2ecf20Sopenharmony_ci .dev = { 3308c2ecf20Sopenharmony_ci .platform_data = &nand_platdata, 3318c2ecf20Sopenharmony_ci }, 3328c2ecf20Sopenharmony_ci}; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci#define OMAP_GPIO_LABEL "gpio-0-15" 3358c2ecf20Sopenharmony_ci#define OMAP_MPUIO_LABEL "mpuio" 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_nand_gpio_table = { 3388c2ecf20Sopenharmony_ci .table = { 3398c2ecf20Sopenharmony_ci GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_NAND_RB, "rdy", 3408c2ecf20Sopenharmony_ci 0), 3418c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NCE, "nce", 3428c2ecf20Sopenharmony_ci GPIO_ACTIVE_LOW), 3438c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NRE, "nre", 3448c2ecf20Sopenharmony_ci GPIO_ACTIVE_LOW), 3458c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWP, "nwp", 3468c2ecf20Sopenharmony_ci GPIO_ACTIVE_LOW), 3478c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 3488c2ecf20Sopenharmony_ci GPIO_ACTIVE_LOW), 3498c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0), 3508c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0), 3518c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 0, "data", 0, 0), 3528c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 1, "data", 1, 0), 3538c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 2, "data", 2, 0), 3548c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 3, "data", 3, 0), 3558c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 4, "data", 4, 0), 3568c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 5, "data", 5, 0), 3578c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 6, "data", 6, 0), 3588c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 7, "data", 7, 0), 3598c2ecf20Sopenharmony_ci { }, 3608c2ecf20Sopenharmony_ci }, 3618c2ecf20Sopenharmony_ci}; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistatic struct resource ams_delta_kp_resources[] = { 3648c2ecf20Sopenharmony_ci [0] = { 3658c2ecf20Sopenharmony_ci .start = INT_KEYBOARD, 3668c2ecf20Sopenharmony_ci .end = INT_KEYBOARD, 3678c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 3688c2ecf20Sopenharmony_ci }, 3698c2ecf20Sopenharmony_ci}; 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_cistatic const struct matrix_keymap_data ams_delta_keymap_data = { 3728c2ecf20Sopenharmony_ci .keymap = ams_delta_keymap, 3738c2ecf20Sopenharmony_ci .keymap_size = ARRAY_SIZE(ams_delta_keymap), 3748c2ecf20Sopenharmony_ci}; 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_cistatic struct omap_kp_platform_data ams_delta_kp_data = { 3778c2ecf20Sopenharmony_ci .rows = 8, 3788c2ecf20Sopenharmony_ci .cols = 8, 3798c2ecf20Sopenharmony_ci .keymap_data = &ams_delta_keymap_data, 3808c2ecf20Sopenharmony_ci .delay = 9, 3818c2ecf20Sopenharmony_ci}; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cistatic struct platform_device ams_delta_kp_device = { 3848c2ecf20Sopenharmony_ci .name = "omap-keypad", 3858c2ecf20Sopenharmony_ci .id = -1, 3868c2ecf20Sopenharmony_ci .dev = { 3878c2ecf20Sopenharmony_ci .platform_data = &ams_delta_kp_data, 3888c2ecf20Sopenharmony_ci }, 3898c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(ams_delta_kp_resources), 3908c2ecf20Sopenharmony_ci .resource = ams_delta_kp_resources, 3918c2ecf20Sopenharmony_ci}; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_cistatic struct platform_device ams_delta_lcd_device = { 3948c2ecf20Sopenharmony_ci .name = "lcd_ams_delta", 3958c2ecf20Sopenharmony_ci .id = -1, 3968c2ecf20Sopenharmony_ci}; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_lcd_gpio_table = { 3998c2ecf20Sopenharmony_ci .table = { 4008c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_VBLEN, "vblen", 0), 4018c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_NDISP, "ndisp", 0), 4028c2ecf20Sopenharmony_ci { }, 4038c2ecf20Sopenharmony_ci }, 4048c2ecf20Sopenharmony_ci}; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_cistatic struct gpio_led gpio_leds[] __initdata = { 4078c2ecf20Sopenharmony_ci [LATCH1_PIN_LED_CAMERA] = { 4088c2ecf20Sopenharmony_ci .name = "camera", 4098c2ecf20Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 4108c2ecf20Sopenharmony_ci#ifdef CONFIG_LEDS_TRIGGERS 4118c2ecf20Sopenharmony_ci .default_trigger = "ams_delta_camera", 4128c2ecf20Sopenharmony_ci#endif 4138c2ecf20Sopenharmony_ci }, 4148c2ecf20Sopenharmony_ci [LATCH1_PIN_LED_ADVERT] = { 4158c2ecf20Sopenharmony_ci .name = "advert", 4168c2ecf20Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 4178c2ecf20Sopenharmony_ci }, 4188c2ecf20Sopenharmony_ci [LATCH1_PIN_LED_MAIL] = { 4198c2ecf20Sopenharmony_ci .name = "email", 4208c2ecf20Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 4218c2ecf20Sopenharmony_ci }, 4228c2ecf20Sopenharmony_ci [LATCH1_PIN_LED_HANDSFREE] = { 4238c2ecf20Sopenharmony_ci .name = "handsfree", 4248c2ecf20Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 4258c2ecf20Sopenharmony_ci }, 4268c2ecf20Sopenharmony_ci [LATCH1_PIN_LED_VOICEMAIL] = { 4278c2ecf20Sopenharmony_ci .name = "voicemail", 4288c2ecf20Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 4298c2ecf20Sopenharmony_ci }, 4308c2ecf20Sopenharmony_ci [LATCH1_PIN_LED_VOICE] = { 4318c2ecf20Sopenharmony_ci .name = "voice", 4328c2ecf20Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 4338c2ecf20Sopenharmony_ci }, 4348c2ecf20Sopenharmony_ci}; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_cistatic const struct gpio_led_platform_data leds_pdata __initconst = { 4378c2ecf20Sopenharmony_ci .leds = gpio_leds, 4388c2ecf20Sopenharmony_ci .num_leds = ARRAY_SIZE(gpio_leds), 4398c2ecf20Sopenharmony_ci}; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table leds_gpio_table = { 4428c2ecf20Sopenharmony_ci .table = { 4438c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_CAMERA, NULL, 4448c2ecf20Sopenharmony_ci LATCH1_PIN_LED_CAMERA, 0), 4458c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_ADVERT, NULL, 4468c2ecf20Sopenharmony_ci LATCH1_PIN_LED_ADVERT, 0), 4478c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_MAIL, NULL, 4488c2ecf20Sopenharmony_ci LATCH1_PIN_LED_MAIL, 0), 4498c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_HANDSFREE, NULL, 4508c2ecf20Sopenharmony_ci LATCH1_PIN_LED_HANDSFREE, 0), 4518c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_VOICEMAIL, NULL, 4528c2ecf20Sopenharmony_ci LATCH1_PIN_LED_VOICEMAIL, 0), 4538c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_VOICE, NULL, 4548c2ecf20Sopenharmony_ci LATCH1_PIN_LED_VOICE, 0), 4558c2ecf20Sopenharmony_ci { }, 4568c2ecf20Sopenharmony_ci }, 4578c2ecf20Sopenharmony_ci}; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci#ifdef CONFIG_LEDS_TRIGGERS 4608c2ecf20Sopenharmony_ciDEFINE_LED_TRIGGER(ams_delta_camera_led_trigger); 4618c2ecf20Sopenharmony_ci#endif 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic struct platform_device ams_delta_audio_device = { 4648c2ecf20Sopenharmony_ci .name = "ams-delta-audio", 4658c2ecf20Sopenharmony_ci .id = -1, 4668c2ecf20Sopenharmony_ci}; 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_audio_gpio_table = { 4698c2ecf20Sopenharmony_ci .table = { 4708c2ecf20Sopenharmony_ci GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_HOOK_SWITCH, 4718c2ecf20Sopenharmony_ci "hook_switch", 0), 4728c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_CODEC, 4738c2ecf20Sopenharmony_ci "modem_codec", 0), 4748c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_HANDSFREE_MUTE, 4758c2ecf20Sopenharmony_ci "handsfree_mute", 0), 4768c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_HANDSET_MUTE, 4778c2ecf20Sopenharmony_ci "handset_mute", 0), 4788c2ecf20Sopenharmony_ci { }, 4798c2ecf20Sopenharmony_ci }, 4808c2ecf20Sopenharmony_ci}; 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_cistatic struct platform_device cx20442_codec_device = { 4838c2ecf20Sopenharmony_ci .name = "cx20442-codec", 4848c2ecf20Sopenharmony_ci .id = -1, 4858c2ecf20Sopenharmony_ci}; 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic struct resource ams_delta_serio_resources[] = { 4888c2ecf20Sopenharmony_ci { 4898c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 4908c2ecf20Sopenharmony_ci /* 4918c2ecf20Sopenharmony_ci * Initialize IRQ resource with invalid IRQ number. 4928c2ecf20Sopenharmony_ci * It will be replaced with dynamically allocated GPIO IRQ 4938c2ecf20Sopenharmony_ci * obtained from GPIO chip as soon as the chip is available. 4948c2ecf20Sopenharmony_ci */ 4958c2ecf20Sopenharmony_ci .start = -EINVAL, 4968c2ecf20Sopenharmony_ci .end = -EINVAL, 4978c2ecf20Sopenharmony_ci }, 4988c2ecf20Sopenharmony_ci}; 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_cistatic struct platform_device ams_delta_serio_device = { 5018c2ecf20Sopenharmony_ci .name = "ams-delta-serio", 5028c2ecf20Sopenharmony_ci .id = PLATFORM_DEVID_NONE, 5038c2ecf20Sopenharmony_ci .dev = { 5048c2ecf20Sopenharmony_ci /* 5058c2ecf20Sopenharmony_ci * Initialize .platform_data explicitly with NULL to 5068c2ecf20Sopenharmony_ci * indicate it is going to be used. It will be replaced 5078c2ecf20Sopenharmony_ci * with FIQ buffer address as soon as FIQ is initialized. 5088c2ecf20Sopenharmony_ci */ 5098c2ecf20Sopenharmony_ci .platform_data = NULL, 5108c2ecf20Sopenharmony_ci }, 5118c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(ams_delta_serio_resources), 5128c2ecf20Sopenharmony_ci .resource = ams_delta_serio_resources, 5138c2ecf20Sopenharmony_ci}; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_cistatic struct regulator_consumer_supply keybrd_pwr_consumers[] = { 5168c2ecf20Sopenharmony_ci /* 5178c2ecf20Sopenharmony_ci * Initialize supply .dev_name with NULL. It will be replaced 5188c2ecf20Sopenharmony_ci * with serio dev_name() as soon as the serio device is registered. 5198c2ecf20Sopenharmony_ci */ 5208c2ecf20Sopenharmony_ci REGULATOR_SUPPLY("vcc", NULL), 5218c2ecf20Sopenharmony_ci}; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_cistatic struct regulator_init_data keybrd_pwr_initdata = { 5248c2ecf20Sopenharmony_ci .constraints = { 5258c2ecf20Sopenharmony_ci .valid_ops_mask = REGULATOR_CHANGE_STATUS, 5268c2ecf20Sopenharmony_ci }, 5278c2ecf20Sopenharmony_ci .num_consumer_supplies = ARRAY_SIZE(keybrd_pwr_consumers), 5288c2ecf20Sopenharmony_ci .consumer_supplies = keybrd_pwr_consumers, 5298c2ecf20Sopenharmony_ci}; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_cistatic struct fixed_voltage_config keybrd_pwr_config = { 5328c2ecf20Sopenharmony_ci .supply_name = "keybrd_pwr", 5338c2ecf20Sopenharmony_ci .microvolts = 5000000, 5348c2ecf20Sopenharmony_ci .init_data = &keybrd_pwr_initdata, 5358c2ecf20Sopenharmony_ci}; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_cistatic struct platform_device keybrd_pwr_device = { 5388c2ecf20Sopenharmony_ci .name = "reg-fixed-voltage", 5398c2ecf20Sopenharmony_ci .id = PLATFORM_DEVID_AUTO, 5408c2ecf20Sopenharmony_ci .dev = { 5418c2ecf20Sopenharmony_ci .platform_data = &keybrd_pwr_config, 5428c2ecf20Sopenharmony_ci }, 5438c2ecf20Sopenharmony_ci}; 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table keybrd_pwr_gpio_table = { 5468c2ecf20Sopenharmony_ci .table = { 5478c2ecf20Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR, NULL, 5488c2ecf20Sopenharmony_ci GPIO_ACTIVE_HIGH), 5498c2ecf20Sopenharmony_ci { }, 5508c2ecf20Sopenharmony_ci }, 5518c2ecf20Sopenharmony_ci}; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic struct platform_device *ams_delta_devices[] __initdata = { 5548c2ecf20Sopenharmony_ci &latch1_gpio_device, 5558c2ecf20Sopenharmony_ci &latch2_gpio_device, 5568c2ecf20Sopenharmony_ci &ams_delta_kp_device, 5578c2ecf20Sopenharmony_ci &ams_delta_audio_device, 5588c2ecf20Sopenharmony_ci &ams_delta_serio_device, 5598c2ecf20Sopenharmony_ci &ams_delta_nand_device, 5608c2ecf20Sopenharmony_ci &ams_delta_lcd_device, 5618c2ecf20Sopenharmony_ci &cx20442_codec_device, 5628c2ecf20Sopenharmony_ci}; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = { 5658c2ecf20Sopenharmony_ci &ams_delta_nreset_gpiod_table, 5668c2ecf20Sopenharmony_ci &ams_delta_audio_gpio_table, 5678c2ecf20Sopenharmony_ci &keybrd_pwr_gpio_table, 5688c2ecf20Sopenharmony_ci &ams_delta_lcd_gpio_table, 5698c2ecf20Sopenharmony_ci &ams_delta_nand_gpio_table, 5708c2ecf20Sopenharmony_ci}; 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci/* 5738c2ecf20Sopenharmony_ci * Some drivers may not use GPIO lookup tables but need to be provided 5748c2ecf20Sopenharmony_ci * with GPIO numbers. The same applies to GPIO based IRQ lines - some 5758c2ecf20Sopenharmony_ci * drivers may even not use GPIO layer but expect just IRQ numbers. 5768c2ecf20Sopenharmony_ci * We could either define GPIO lookup tables then use them on behalf 5778c2ecf20Sopenharmony_ci * of those devices, or we can use GPIO driver level methods for 5788c2ecf20Sopenharmony_ci * identification of GPIO and IRQ numbers. For the purpose of the latter, 5798c2ecf20Sopenharmony_ci * defina a helper function which identifies GPIO chips by their labels. 5808c2ecf20Sopenharmony_ci */ 5818c2ecf20Sopenharmony_cistatic int gpiochip_match_by_label(struct gpio_chip *chip, void *data) 5828c2ecf20Sopenharmony_ci{ 5838c2ecf20Sopenharmony_ci char *label = data; 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci return !strcmp(label, chip->label); 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic struct gpiod_hog ams_delta_gpio_hogs[] = { 5898c2ecf20Sopenharmony_ci GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT, "keybrd_dataout", 5908c2ecf20Sopenharmony_ci GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW), 5918c2ecf20Sopenharmony_ci {}, 5928c2ecf20Sopenharmony_ci}; 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_cistatic struct plat_serial8250_port ams_delta_modem_ports[]; 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci/* 5978c2ecf20Sopenharmony_ci * Obtain MODEM IRQ GPIO descriptor using its hardware pin 5988c2ecf20Sopenharmony_ci * number and assign related IRQ number to the MODEM port. 5998c2ecf20Sopenharmony_ci * Keep the GPIO descriptor open so nobody steps in. 6008c2ecf20Sopenharmony_ci */ 6018c2ecf20Sopenharmony_cistatic void __init modem_assign_irq(struct gpio_chip *chip) 6028c2ecf20Sopenharmony_ci{ 6038c2ecf20Sopenharmony_ci struct gpio_desc *gpiod; 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci gpiod = gpiochip_request_own_desc(chip, AMS_DELTA_GPIO_PIN_MODEM_IRQ, 6068c2ecf20Sopenharmony_ci "modem_irq", GPIO_ACTIVE_HIGH, 6078c2ecf20Sopenharmony_ci GPIOD_IN); 6088c2ecf20Sopenharmony_ci if (IS_ERR(gpiod)) { 6098c2ecf20Sopenharmony_ci pr_err("%s: modem IRQ GPIO request failed (%ld)\n", __func__, 6108c2ecf20Sopenharmony_ci PTR_ERR(gpiod)); 6118c2ecf20Sopenharmony_ci } else { 6128c2ecf20Sopenharmony_ci ams_delta_modem_ports[0].irq = gpiod_to_irq(gpiod); 6138c2ecf20Sopenharmony_ci } 6148c2ecf20Sopenharmony_ci} 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci/* 6178c2ecf20Sopenharmony_ci * The purpose of this function is to take care of proper initialization of 6188c2ecf20Sopenharmony_ci * devices and data structures which depend on GPIO lines provided by OMAP GPIO 6198c2ecf20Sopenharmony_ci * banks but their drivers don't use GPIO lookup tables or GPIO layer at all. 6208c2ecf20Sopenharmony_ci * The function may be called as soon as OMAP GPIO devices are probed. 6218c2ecf20Sopenharmony_ci * Since that happens at postcore_initcall, it can be called successfully 6228c2ecf20Sopenharmony_ci * from init_machine or later. 6238c2ecf20Sopenharmony_ci * Dependent devices may be registered from within this function or later. 6248c2ecf20Sopenharmony_ci */ 6258c2ecf20Sopenharmony_cistatic void __init omap_gpio_deps_init(void) 6268c2ecf20Sopenharmony_ci{ 6278c2ecf20Sopenharmony_ci struct gpio_chip *chip; 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci chip = gpiochip_find(OMAP_GPIO_LABEL, gpiochip_match_by_label); 6308c2ecf20Sopenharmony_ci if (!chip) { 6318c2ecf20Sopenharmony_ci pr_err("%s: OMAP GPIO chip not found\n", __func__); 6328c2ecf20Sopenharmony_ci return; 6338c2ecf20Sopenharmony_ci } 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci /* 6368c2ecf20Sopenharmony_ci * Start with FIQ initialization as it may have to request 6378c2ecf20Sopenharmony_ci * and release successfully each OMAP GPIO pin in turn. 6388c2ecf20Sopenharmony_ci */ 6398c2ecf20Sopenharmony_ci ams_delta_init_fiq(chip, &ams_delta_serio_device); 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci modem_assign_irq(chip); 6428c2ecf20Sopenharmony_ci} 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci/* 6458c2ecf20Sopenharmony_ci * Initialize latch2 pins with values which are safe for dependent on-board 6468c2ecf20Sopenharmony_ci * devices or useful for their successull initialization even before GPIO 6478c2ecf20Sopenharmony_ci * driver takes control over the latch pins: 6488c2ecf20Sopenharmony_ci * - LATCH2_PIN_LCD_VBLEN = 0 6498c2ecf20Sopenharmony_ci * - LATCH2_PIN_LCD_NDISP = 0 Keep LCD device powered off before its 6508c2ecf20Sopenharmony_ci * driver takes control over it. 6518c2ecf20Sopenharmony_ci * - LATCH2_PIN_NAND_NCE = 0 6528c2ecf20Sopenharmony_ci * - LATCH2_PIN_NAND_NWP = 0 Keep NAND device down and write- 6538c2ecf20Sopenharmony_ci * protected before its driver takes 6548c2ecf20Sopenharmony_ci * control over it. 6558c2ecf20Sopenharmony_ci * - LATCH2_PIN_KEYBRD_PWR = 0 Keep keyboard powered off before serio 6568c2ecf20Sopenharmony_ci * driver takes control over it. 6578c2ecf20Sopenharmony_ci * - LATCH2_PIN_KEYBRD_DATAOUT = 0 Keep low to avoid corruption of first 6588c2ecf20Sopenharmony_ci * byte of data received from attached 6598c2ecf20Sopenharmony_ci * keyboard when serio device is probed; 6608c2ecf20Sopenharmony_ci * the pin is also hogged low by the latch2 6618c2ecf20Sopenharmony_ci * GPIO driver as soon as it is ready. 6628c2ecf20Sopenharmony_ci * - LATCH2_PIN_MODEM_NRESET = 1 Enable voice MODEM device, allowing for 6638c2ecf20Sopenharmony_ci * its successful probe even before a 6648c2ecf20Sopenharmony_ci * regulator it depends on, which in turn 6658c2ecf20Sopenharmony_ci * takes control over the pin, is set up. 6668c2ecf20Sopenharmony_ci * - LATCH2_PIN_MODEM_CODEC = 1 Attach voice MODEM CODEC data port 6678c2ecf20Sopenharmony_ci * to the MODEM so the CODEC is under 6688c2ecf20Sopenharmony_ci * control even if audio driver doesn't 6698c2ecf20Sopenharmony_ci * take it over. 6708c2ecf20Sopenharmony_ci */ 6718c2ecf20Sopenharmony_cistatic void __init ams_delta_latch2_init(void) 6728c2ecf20Sopenharmony_ci{ 6738c2ecf20Sopenharmony_ci u16 latch2 = 1 << LATCH2_PIN_MODEM_NRESET | 1 << LATCH2_PIN_MODEM_CODEC; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci __raw_writew(latch2, LATCH2_VIRT); 6768c2ecf20Sopenharmony_ci} 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_cistatic void __init ams_delta_init(void) 6798c2ecf20Sopenharmony_ci{ 6808c2ecf20Sopenharmony_ci struct platform_device *leds_pdev; 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_ci /* mux pins for uarts */ 6838c2ecf20Sopenharmony_ci omap_cfg_reg(UART1_TX); 6848c2ecf20Sopenharmony_ci omap_cfg_reg(UART1_RTS); 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ci /* parallel camera interface */ 6878c2ecf20Sopenharmony_ci omap_cfg_reg(H19_1610_CAM_EXCLK); 6888c2ecf20Sopenharmony_ci omap_cfg_reg(J15_1610_CAM_LCLK); 6898c2ecf20Sopenharmony_ci omap_cfg_reg(L18_1610_CAM_VS); 6908c2ecf20Sopenharmony_ci omap_cfg_reg(L15_1610_CAM_HS); 6918c2ecf20Sopenharmony_ci omap_cfg_reg(L19_1610_CAM_D0); 6928c2ecf20Sopenharmony_ci omap_cfg_reg(K14_1610_CAM_D1); 6938c2ecf20Sopenharmony_ci omap_cfg_reg(K15_1610_CAM_D2); 6948c2ecf20Sopenharmony_ci omap_cfg_reg(K19_1610_CAM_D3); 6958c2ecf20Sopenharmony_ci omap_cfg_reg(K18_1610_CAM_D4); 6968c2ecf20Sopenharmony_ci omap_cfg_reg(J14_1610_CAM_D5); 6978c2ecf20Sopenharmony_ci omap_cfg_reg(J19_1610_CAM_D6); 6988c2ecf20Sopenharmony_ci omap_cfg_reg(J18_1610_CAM_D7); 6998c2ecf20Sopenharmony_ci 7008c2ecf20Sopenharmony_ci omap_gpio_deps_init(); 7018c2ecf20Sopenharmony_ci ams_delta_latch2_init(); 7028c2ecf20Sopenharmony_ci gpiod_add_hogs(ams_delta_gpio_hogs); 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci omap_serial_init(); 7058c2ecf20Sopenharmony_ci omap_register_i2c_bus(1, 100, NULL, 0); 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_ci omap1_usb_init(&ams_delta_usb_config); 7088c2ecf20Sopenharmony_ci#ifdef CONFIG_LEDS_TRIGGERS 7098c2ecf20Sopenharmony_ci led_trigger_register_simple("ams_delta_camera", 7108c2ecf20Sopenharmony_ci &ams_delta_camera_led_trigger); 7118c2ecf20Sopenharmony_ci#endif 7128c2ecf20Sopenharmony_ci platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci /* 7158c2ecf20Sopenharmony_ci * As soon as regulator consumers have been registered, assign their 7168c2ecf20Sopenharmony_ci * dev_names to consumer supply entries of respective regulators. 7178c2ecf20Sopenharmony_ci */ 7188c2ecf20Sopenharmony_ci keybrd_pwr_consumers[0].dev_name = 7198c2ecf20Sopenharmony_ci dev_name(&ams_delta_serio_device.dev); 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci /* 7228c2ecf20Sopenharmony_ci * Once consumer supply entries are populated with dev_names, 7238c2ecf20Sopenharmony_ci * register regulator devices. At this stage only the keyboard 7248c2ecf20Sopenharmony_ci * power regulator has its consumer supply table fully populated. 7258c2ecf20Sopenharmony_ci */ 7268c2ecf20Sopenharmony_ci platform_device_register(&keybrd_pwr_device); 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci /* 7298c2ecf20Sopenharmony_ci * As soon as GPIO consumers have been registered, assign 7308c2ecf20Sopenharmony_ci * their dev_names to respective GPIO lookup tables. 7318c2ecf20Sopenharmony_ci */ 7328c2ecf20Sopenharmony_ci ams_delta_audio_gpio_table.dev_id = 7338c2ecf20Sopenharmony_ci dev_name(&ams_delta_audio_device.dev); 7348c2ecf20Sopenharmony_ci keybrd_pwr_gpio_table.dev_id = dev_name(&keybrd_pwr_device.dev); 7358c2ecf20Sopenharmony_ci ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev); 7368c2ecf20Sopenharmony_ci ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev); 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci /* 7398c2ecf20Sopenharmony_ci * Once GPIO lookup tables are populated with dev_names, register them. 7408c2ecf20Sopenharmony_ci */ 7418c2ecf20Sopenharmony_ci gpiod_add_lookup_tables(ams_delta_gpio_tables, 7428c2ecf20Sopenharmony_ci ARRAY_SIZE(ams_delta_gpio_tables)); 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci leds_pdev = gpio_led_register_device(PLATFORM_DEVID_NONE, &leds_pdata); 7458c2ecf20Sopenharmony_ci if (!IS_ERR_OR_NULL(leds_pdev)) { 7468c2ecf20Sopenharmony_ci leds_gpio_table.dev_id = dev_name(&leds_pdev->dev); 7478c2ecf20Sopenharmony_ci gpiod_add_lookup_table(&leds_gpio_table); 7488c2ecf20Sopenharmony_ci } 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci omapfb_set_lcd_config(&ams_delta_lcd_config); 7538c2ecf20Sopenharmony_ci} 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_cistatic void modem_pm(struct uart_port *port, unsigned int state, unsigned old) 7568c2ecf20Sopenharmony_ci{ 7578c2ecf20Sopenharmony_ci struct modem_private_data *priv = port->private_data; 7588c2ecf20Sopenharmony_ci int ret; 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci if (!priv) 7618c2ecf20Sopenharmony_ci return; 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci if (IS_ERR(priv->regulator)) 7648c2ecf20Sopenharmony_ci return; 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci if (state == old) 7678c2ecf20Sopenharmony_ci return; 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_ci if (state == 0) 7708c2ecf20Sopenharmony_ci ret = regulator_enable(priv->regulator); 7718c2ecf20Sopenharmony_ci else if (old == 0) 7728c2ecf20Sopenharmony_ci ret = regulator_disable(priv->regulator); 7738c2ecf20Sopenharmony_ci else 7748c2ecf20Sopenharmony_ci ret = 0; 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci if (ret) 7778c2ecf20Sopenharmony_ci dev_warn(port->dev, 7788c2ecf20Sopenharmony_ci "ams_delta modem_pm: failed to %sable regulator: %d\n", 7798c2ecf20Sopenharmony_ci state ? "dis" : "en", ret); 7808c2ecf20Sopenharmony_ci} 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_cistatic struct plat_serial8250_port ams_delta_modem_ports[] = { 7838c2ecf20Sopenharmony_ci { 7848c2ecf20Sopenharmony_ci .membase = IOMEM(MODEM_VIRT), 7858c2ecf20Sopenharmony_ci .mapbase = MODEM_PHYS, 7868c2ecf20Sopenharmony_ci .irq = IRQ_NOTCONNECTED, /* changed later */ 7878c2ecf20Sopenharmony_ci .flags = UPF_BOOT_AUTOCONF, 7888c2ecf20Sopenharmony_ci .irqflags = IRQF_TRIGGER_RISING, 7898c2ecf20Sopenharmony_ci .iotype = UPIO_MEM, 7908c2ecf20Sopenharmony_ci .regshift = 1, 7918c2ecf20Sopenharmony_ci .uartclk = BASE_BAUD * 16, 7928c2ecf20Sopenharmony_ci .pm = modem_pm, 7938c2ecf20Sopenharmony_ci .private_data = &modem_priv, 7948c2ecf20Sopenharmony_ci }, 7958c2ecf20Sopenharmony_ci { }, 7968c2ecf20Sopenharmony_ci}; 7978c2ecf20Sopenharmony_ci 7988c2ecf20Sopenharmony_cistatic struct platform_device ams_delta_modem_device = { 7998c2ecf20Sopenharmony_ci .name = "serial8250", 8008c2ecf20Sopenharmony_ci .id = PLAT8250_DEV_PLATFORM1, 8018c2ecf20Sopenharmony_ci .dev = { 8028c2ecf20Sopenharmony_ci .platform_data = ams_delta_modem_ports, 8038c2ecf20Sopenharmony_ci }, 8048c2ecf20Sopenharmony_ci}; 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_cistatic int __init modem_nreset_init(void) 8078c2ecf20Sopenharmony_ci{ 8088c2ecf20Sopenharmony_ci int err; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci err = platform_device_register(&modem_nreset_device); 8118c2ecf20Sopenharmony_ci if (err) 8128c2ecf20Sopenharmony_ci pr_err("Couldn't register the modem regulator device\n"); 8138c2ecf20Sopenharmony_ci 8148c2ecf20Sopenharmony_ci return err; 8158c2ecf20Sopenharmony_ci} 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci/* 8198c2ecf20Sopenharmony_ci * This function expects MODEM IRQ number already assigned to the port. 8208c2ecf20Sopenharmony_ci * The MODEM device requires its RESET# pin kept high during probe. 8218c2ecf20Sopenharmony_ci * That requirement can be fulfilled in several ways: 8228c2ecf20Sopenharmony_ci * - with a descriptor of already functional modem_nreset regulator 8238c2ecf20Sopenharmony_ci * assigned to the MODEM private data, 8248c2ecf20Sopenharmony_ci * - with the regulator not yet controlled by modem_pm function but 8258c2ecf20Sopenharmony_ci * already enabled by default on probe, 8268c2ecf20Sopenharmony_ci * - before the modem_nreset regulator is probed, with the pin already 8278c2ecf20Sopenharmony_ci * set high explicitly. 8288c2ecf20Sopenharmony_ci * The last one is already guaranteed by ams_delta_latch2_init() called 8298c2ecf20Sopenharmony_ci * from machine_init. 8308c2ecf20Sopenharmony_ci * In order to avoid taking over ttyS0 device slot, the MODEM device 8318c2ecf20Sopenharmony_ci * should be registered after OMAP serial ports. Since those ports 8328c2ecf20Sopenharmony_ci * are registered at arch_initcall, this function can be called safely 8338c2ecf20Sopenharmony_ci * at arch_initcall_sync earliest. 8348c2ecf20Sopenharmony_ci */ 8358c2ecf20Sopenharmony_cistatic int __init ams_delta_modem_init(void) 8368c2ecf20Sopenharmony_ci{ 8378c2ecf20Sopenharmony_ci int err; 8388c2ecf20Sopenharmony_ci 8398c2ecf20Sopenharmony_ci if (!machine_is_ams_delta()) 8408c2ecf20Sopenharmony_ci return -ENODEV; 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci omap_cfg_reg(M14_1510_GPIO2); 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci /* Initialize the modem_nreset regulator consumer before use */ 8458c2ecf20Sopenharmony_ci modem_priv.regulator = ERR_PTR(-ENODEV); 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci err = platform_device_register(&ams_delta_modem_device); 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci return err; 8508c2ecf20Sopenharmony_ci} 8518c2ecf20Sopenharmony_ciarch_initcall_sync(ams_delta_modem_init); 8528c2ecf20Sopenharmony_ci 8538c2ecf20Sopenharmony_cistatic int __init late_init(void) 8548c2ecf20Sopenharmony_ci{ 8558c2ecf20Sopenharmony_ci int err; 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci err = modem_nreset_init(); 8588c2ecf20Sopenharmony_ci if (err) 8598c2ecf20Sopenharmony_ci return err; 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci /* 8628c2ecf20Sopenharmony_ci * Once the modem device is registered, the modem_nreset 8638c2ecf20Sopenharmony_ci * regulator can be requested on behalf of that device. 8648c2ecf20Sopenharmony_ci */ 8658c2ecf20Sopenharmony_ci modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev, 8668c2ecf20Sopenharmony_ci "RESET#"); 8678c2ecf20Sopenharmony_ci if (IS_ERR(modem_priv.regulator)) { 8688c2ecf20Sopenharmony_ci err = PTR_ERR(modem_priv.regulator); 8698c2ecf20Sopenharmony_ci goto unregister; 8708c2ecf20Sopenharmony_ci } 8718c2ecf20Sopenharmony_ci return 0; 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ciunregister: 8748c2ecf20Sopenharmony_ci platform_device_unregister(&ams_delta_modem_device); 8758c2ecf20Sopenharmony_ci return err; 8768c2ecf20Sopenharmony_ci} 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_cistatic void __init ams_delta_init_late(void) 8798c2ecf20Sopenharmony_ci{ 8808c2ecf20Sopenharmony_ci omap1_init_late(); 8818c2ecf20Sopenharmony_ci late_init(); 8828c2ecf20Sopenharmony_ci} 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_cistatic void __init ams_delta_map_io(void) 8858c2ecf20Sopenharmony_ci{ 8868c2ecf20Sopenharmony_ci omap15xx_map_io(); 8878c2ecf20Sopenharmony_ci iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); 8888c2ecf20Sopenharmony_ci} 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ciMACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") 8918c2ecf20Sopenharmony_ci /* Maintainer: Jonathan McDowell <noodles@earth.li> */ 8928c2ecf20Sopenharmony_ci .atag_offset = 0x100, 8938c2ecf20Sopenharmony_ci .map_io = ams_delta_map_io, 8948c2ecf20Sopenharmony_ci .init_early = omap1_init_early, 8958c2ecf20Sopenharmony_ci .init_irq = omap1_init_irq, 8968c2ecf20Sopenharmony_ci .handle_irq = omap1_handle_irq, 8978c2ecf20Sopenharmony_ci .init_machine = ams_delta_init, 8988c2ecf20Sopenharmony_ci .init_late = ams_delta_init_late, 8998c2ecf20Sopenharmony_ci .init_time = omap1_timer_init, 9008c2ecf20Sopenharmony_ci .restart = omap1_restart, 9018c2ecf20Sopenharmony_ciMACHINE_END 902