162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/arch/arm/mach-omap1/board-ams-delta.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Modified from board-generic.c 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Board specific inits for the Amstrad E3 (codename Delta) videophone 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#include <linux/gpio/driver.h> 1262306a36Sopenharmony_ci#include <linux/gpio/machine.h> 1362306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/init.h> 1662306a36Sopenharmony_ci#include <linux/input.h> 1762306a36Sopenharmony_ci#include <linux/interrupt.h> 1862306a36Sopenharmony_ci#include <linux/leds.h> 1962306a36Sopenharmony_ci#include <linux/mtd/nand-gpio.h> 2062306a36Sopenharmony_ci#include <linux/mtd/partitions.h> 2162306a36Sopenharmony_ci#include <linux/platform_device.h> 2262306a36Sopenharmony_ci#include <linux/regulator/consumer.h> 2362306a36Sopenharmony_ci#include <linux/regulator/fixed.h> 2462306a36Sopenharmony_ci#include <linux/regulator/machine.h> 2562306a36Sopenharmony_ci#include <linux/serial_8250.h> 2662306a36Sopenharmony_ci#include <linux/export.h> 2762306a36Sopenharmony_ci#include <linux/omapfb.h> 2862306a36Sopenharmony_ci#include <linux/io.h> 2962306a36Sopenharmony_ci#include <linux/platform_data/gpio-omap.h> 3062306a36Sopenharmony_ci#include <linux/soc/ti/omap1-mux.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#include <asm/serial.h> 3362306a36Sopenharmony_ci#include <asm/mach-types.h> 3462306a36Sopenharmony_ci#include <asm/mach/arch.h> 3562306a36Sopenharmony_ci#include <asm/mach/map.h> 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#include <linux/platform_data/keypad-omap.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#include "hardware.h" 4062306a36Sopenharmony_ci#include "usb.h" 4162306a36Sopenharmony_ci#include "ams-delta-fiq.h" 4262306a36Sopenharmony_ci#include "board-ams-delta.h" 4362306a36Sopenharmony_ci#include "iomap.h" 4462306a36Sopenharmony_ci#include "common.h" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic const unsigned int ams_delta_keymap[] = { 4762306a36Sopenharmony_ci KEY(0, 0, KEY_F1), /* Advert */ 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci KEY(0, 3, KEY_COFFEE), /* Games */ 5062306a36Sopenharmony_ci KEY(0, 2, KEY_QUESTION), /* Directory */ 5162306a36Sopenharmony_ci KEY(2, 3, KEY_CONNECT), /* Internet */ 5262306a36Sopenharmony_ci KEY(1, 2, KEY_SHOP), /* Services */ 5362306a36Sopenharmony_ci KEY(1, 1, KEY_PHONE), /* VoiceMail */ 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci KEY(0, 1, KEY_DELETE), /* Delete */ 5662306a36Sopenharmony_ci KEY(2, 2, KEY_PLAY), /* Play */ 5762306a36Sopenharmony_ci KEY(1, 0, KEY_PAGEUP), /* Up */ 5862306a36Sopenharmony_ci KEY(1, 3, KEY_PAGEDOWN), /* Down */ 5962306a36Sopenharmony_ci KEY(2, 0, KEY_EMAIL), /* ReadEmail */ 6062306a36Sopenharmony_ci KEY(2, 1, KEY_STOP), /* Stop */ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* Numeric keypad portion */ 6362306a36Sopenharmony_ci KEY(0, 7, KEY_KP1), 6462306a36Sopenharmony_ci KEY(0, 6, KEY_KP2), 6562306a36Sopenharmony_ci KEY(0, 5, KEY_KP3), 6662306a36Sopenharmony_ci KEY(1, 7, KEY_KP4), 6762306a36Sopenharmony_ci KEY(1, 6, KEY_KP5), 6862306a36Sopenharmony_ci KEY(1, 5, KEY_KP6), 6962306a36Sopenharmony_ci KEY(2, 7, KEY_KP7), 7062306a36Sopenharmony_ci KEY(2, 6, KEY_KP8), 7162306a36Sopenharmony_ci KEY(2, 5, KEY_KP9), 7262306a36Sopenharmony_ci KEY(3, 6, KEY_KP0), 7362306a36Sopenharmony_ci KEY(3, 7, KEY_KPASTERISK), 7462306a36Sopenharmony_ci KEY(3, 5, KEY_KPDOT), /* # key */ 7562306a36Sopenharmony_ci KEY(7, 2, KEY_NUMLOCK), /* Mute */ 7662306a36Sopenharmony_ci KEY(7, 1, KEY_KPMINUS), /* Recall */ 7762306a36Sopenharmony_ci KEY(6, 1, KEY_KPPLUS), /* Redial */ 7862306a36Sopenharmony_ci KEY(7, 6, KEY_KPSLASH), /* Handsfree */ 7962306a36Sopenharmony_ci KEY(6, 0, KEY_ENTER), /* Video */ 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci KEY(7, 4, KEY_CAMERA), /* Photo */ 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci KEY(0, 4, KEY_F2), /* Home */ 8462306a36Sopenharmony_ci KEY(1, 4, KEY_F3), /* Office */ 8562306a36Sopenharmony_ci KEY(2, 4, KEY_F4), /* Mobile */ 8662306a36Sopenharmony_ci KEY(7, 7, KEY_F5), /* SMS */ 8762306a36Sopenharmony_ci KEY(7, 5, KEY_F6), /* Email */ 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci /* QWERTY portion of keypad */ 9062306a36Sopenharmony_ci KEY(3, 4, KEY_Q), 9162306a36Sopenharmony_ci KEY(3, 3, KEY_W), 9262306a36Sopenharmony_ci KEY(3, 2, KEY_E), 9362306a36Sopenharmony_ci KEY(3, 1, KEY_R), 9462306a36Sopenharmony_ci KEY(3, 0, KEY_T), 9562306a36Sopenharmony_ci KEY(4, 7, KEY_Y), 9662306a36Sopenharmony_ci KEY(4, 6, KEY_U), 9762306a36Sopenharmony_ci KEY(4, 5, KEY_I), 9862306a36Sopenharmony_ci KEY(4, 4, KEY_O), 9962306a36Sopenharmony_ci KEY(4, 3, KEY_P), 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci KEY(4, 2, KEY_A), 10262306a36Sopenharmony_ci KEY(4, 1, KEY_S), 10362306a36Sopenharmony_ci KEY(4, 0, KEY_D), 10462306a36Sopenharmony_ci KEY(5, 7, KEY_F), 10562306a36Sopenharmony_ci KEY(5, 6, KEY_G), 10662306a36Sopenharmony_ci KEY(5, 5, KEY_H), 10762306a36Sopenharmony_ci KEY(5, 4, KEY_J), 10862306a36Sopenharmony_ci KEY(5, 3, KEY_K), 10962306a36Sopenharmony_ci KEY(5, 2, KEY_L), 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci KEY(5, 1, KEY_Z), 11262306a36Sopenharmony_ci KEY(5, 0, KEY_X), 11362306a36Sopenharmony_ci KEY(6, 7, KEY_C), 11462306a36Sopenharmony_ci KEY(6, 6, KEY_V), 11562306a36Sopenharmony_ci KEY(6, 5, KEY_B), 11662306a36Sopenharmony_ci KEY(6, 4, KEY_N), 11762306a36Sopenharmony_ci KEY(6, 3, KEY_M), 11862306a36Sopenharmony_ci KEY(6, 2, KEY_SPACE), 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci KEY(7, 0, KEY_LEFTSHIFT), /* Vol up */ 12162306a36Sopenharmony_ci KEY(7, 3, KEY_LEFTCTRL), /* Vol down */ 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#define LATCH1_PHYS 0x01000000 12562306a36Sopenharmony_ci#define LATCH1_VIRT 0xEA000000 12662306a36Sopenharmony_ci#define MODEM_PHYS 0x04000000 12762306a36Sopenharmony_ci#define MODEM_VIRT 0xEB000000 12862306a36Sopenharmony_ci#define LATCH2_PHYS 0x08000000 12962306a36Sopenharmony_ci#define LATCH2_VIRT 0xEC000000 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic struct map_desc ams_delta_io_desc[] __initdata = { 13262306a36Sopenharmony_ci /* AMS_DELTA_LATCH1 */ 13362306a36Sopenharmony_ci { 13462306a36Sopenharmony_ci .virtual = LATCH1_VIRT, 13562306a36Sopenharmony_ci .pfn = __phys_to_pfn(LATCH1_PHYS), 13662306a36Sopenharmony_ci .length = 0x01000000, 13762306a36Sopenharmony_ci .type = MT_DEVICE 13862306a36Sopenharmony_ci }, 13962306a36Sopenharmony_ci /* AMS_DELTA_LATCH2 */ 14062306a36Sopenharmony_ci { 14162306a36Sopenharmony_ci .virtual = LATCH2_VIRT, 14262306a36Sopenharmony_ci .pfn = __phys_to_pfn(LATCH2_PHYS), 14362306a36Sopenharmony_ci .length = 0x01000000, 14462306a36Sopenharmony_ci .type = MT_DEVICE 14562306a36Sopenharmony_ci }, 14662306a36Sopenharmony_ci /* AMS_DELTA_MODEM */ 14762306a36Sopenharmony_ci { 14862306a36Sopenharmony_ci .virtual = MODEM_VIRT, 14962306a36Sopenharmony_ci .pfn = __phys_to_pfn(MODEM_PHYS), 15062306a36Sopenharmony_ci .length = 0x01000000, 15162306a36Sopenharmony_ci .type = MT_DEVICE 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic const struct omap_lcd_config ams_delta_lcd_config __initconst = { 15662306a36Sopenharmony_ci .ctrl_name = "internal", 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistatic struct omap_usb_config ams_delta_usb_config __initdata = { 16062306a36Sopenharmony_ci .register_host = 1, 16162306a36Sopenharmony_ci .hmc_mode = 16, 16262306a36Sopenharmony_ci .pins[0] = 2, 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#define LATCH1_NGPIO 8 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic struct resource latch1_resources[] = { 16862306a36Sopenharmony_ci [0] = { 16962306a36Sopenharmony_ci .name = "dat", 17062306a36Sopenharmony_ci .start = LATCH1_PHYS, 17162306a36Sopenharmony_ci .end = LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8, 17262306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 17362306a36Sopenharmony_ci }, 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci#define LATCH1_LABEL "latch1" 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic struct bgpio_pdata latch1_pdata = { 17962306a36Sopenharmony_ci .label = LATCH1_LABEL, 18062306a36Sopenharmony_ci .base = -1, 18162306a36Sopenharmony_ci .ngpio = LATCH1_NGPIO, 18262306a36Sopenharmony_ci}; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic struct platform_device latch1_gpio_device = { 18562306a36Sopenharmony_ci .name = "basic-mmio-gpio", 18662306a36Sopenharmony_ci .id = 0, 18762306a36Sopenharmony_ci .resource = latch1_resources, 18862306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(latch1_resources), 18962306a36Sopenharmony_ci .dev = { 19062306a36Sopenharmony_ci .platform_data = &latch1_pdata, 19162306a36Sopenharmony_ci }, 19262306a36Sopenharmony_ci}; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#define LATCH1_PIN_LED_CAMERA 0 19562306a36Sopenharmony_ci#define LATCH1_PIN_LED_ADVERT 1 19662306a36Sopenharmony_ci#define LATCH1_PIN_LED_MAIL 2 19762306a36Sopenharmony_ci#define LATCH1_PIN_LED_HANDSFREE 3 19862306a36Sopenharmony_ci#define LATCH1_PIN_LED_VOICEMAIL 4 19962306a36Sopenharmony_ci#define LATCH1_PIN_LED_VOICE 5 20062306a36Sopenharmony_ci#define LATCH1_PIN_DOCKIT1 6 20162306a36Sopenharmony_ci#define LATCH1_PIN_DOCKIT2 7 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#define LATCH2_NGPIO 16 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic struct resource latch2_resources[] = { 20662306a36Sopenharmony_ci [0] = { 20762306a36Sopenharmony_ci .name = "dat", 20862306a36Sopenharmony_ci .start = LATCH2_PHYS, 20962306a36Sopenharmony_ci .end = LATCH2_PHYS + (LATCH2_NGPIO - 1) / 8, 21062306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 21162306a36Sopenharmony_ci }, 21262306a36Sopenharmony_ci}; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#define LATCH2_LABEL "latch2" 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistatic struct bgpio_pdata latch2_pdata = { 21762306a36Sopenharmony_ci .label = LATCH2_LABEL, 21862306a36Sopenharmony_ci .base = -1, 21962306a36Sopenharmony_ci .ngpio = LATCH2_NGPIO, 22062306a36Sopenharmony_ci}; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistatic struct platform_device latch2_gpio_device = { 22362306a36Sopenharmony_ci .name = "basic-mmio-gpio", 22462306a36Sopenharmony_ci .id = 1, 22562306a36Sopenharmony_ci .resource = latch2_resources, 22662306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(latch2_resources), 22762306a36Sopenharmony_ci .dev = { 22862306a36Sopenharmony_ci .platform_data = &latch2_pdata, 22962306a36Sopenharmony_ci }, 23062306a36Sopenharmony_ci}; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci#define LATCH2_PIN_LCD_VBLEN 0 23362306a36Sopenharmony_ci#define LATCH2_PIN_LCD_NDISP 1 23462306a36Sopenharmony_ci#define LATCH2_PIN_NAND_NCE 2 23562306a36Sopenharmony_ci#define LATCH2_PIN_NAND_NRE 3 23662306a36Sopenharmony_ci#define LATCH2_PIN_NAND_NWP 4 23762306a36Sopenharmony_ci#define LATCH2_PIN_NAND_NWE 5 23862306a36Sopenharmony_ci#define LATCH2_PIN_NAND_ALE 6 23962306a36Sopenharmony_ci#define LATCH2_PIN_NAND_CLE 7 24062306a36Sopenharmony_ci#define LATCH2_PIN_KEYBRD_PWR 8 24162306a36Sopenharmony_ci#define LATCH2_PIN_KEYBRD_DATAOUT 9 24262306a36Sopenharmony_ci#define LATCH2_PIN_SCARD_RSTIN 10 24362306a36Sopenharmony_ci#define LATCH2_PIN_SCARD_CMDVCC 11 24462306a36Sopenharmony_ci#define LATCH2_PIN_MODEM_NRESET 12 24562306a36Sopenharmony_ci#define LATCH2_PIN_MODEM_CODEC 13 24662306a36Sopenharmony_ci#define LATCH2_PIN_HANDSFREE_MUTE 14 24762306a36Sopenharmony_ci#define LATCH2_PIN_HANDSET_MUTE 15 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic struct regulator_consumer_supply modem_nreset_consumers[] = { 25062306a36Sopenharmony_ci REGULATOR_SUPPLY("RESET#", "serial8250.1"), 25162306a36Sopenharmony_ci REGULATOR_SUPPLY("POR", "cx20442-codec"), 25262306a36Sopenharmony_ci}; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_cistatic struct regulator_init_data modem_nreset_data = { 25562306a36Sopenharmony_ci .constraints = { 25662306a36Sopenharmony_ci .valid_ops_mask = REGULATOR_CHANGE_STATUS, 25762306a36Sopenharmony_ci .boot_on = 1, 25862306a36Sopenharmony_ci }, 25962306a36Sopenharmony_ci .num_consumer_supplies = ARRAY_SIZE(modem_nreset_consumers), 26062306a36Sopenharmony_ci .consumer_supplies = modem_nreset_consumers, 26162306a36Sopenharmony_ci}; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cistatic struct fixed_voltage_config modem_nreset_config = { 26462306a36Sopenharmony_ci .supply_name = "modem_nreset", 26562306a36Sopenharmony_ci .microvolts = 3300000, 26662306a36Sopenharmony_ci .startup_delay = 25000, 26762306a36Sopenharmony_ci .enabled_at_boot = 1, 26862306a36Sopenharmony_ci .init_data = &modem_nreset_data, 26962306a36Sopenharmony_ci}; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistatic struct platform_device modem_nreset_device = { 27262306a36Sopenharmony_ci .name = "reg-fixed-voltage", 27362306a36Sopenharmony_ci .id = -1, 27462306a36Sopenharmony_ci .dev = { 27562306a36Sopenharmony_ci .platform_data = &modem_nreset_config, 27662306a36Sopenharmony_ci }, 27762306a36Sopenharmony_ci}; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_nreset_gpiod_table = { 28062306a36Sopenharmony_ci .dev_id = "reg-fixed-voltage", 28162306a36Sopenharmony_ci .table = { 28262306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_NRESET, 28362306a36Sopenharmony_ci NULL, GPIO_ACTIVE_HIGH), 28462306a36Sopenharmony_ci { }, 28562306a36Sopenharmony_ci }, 28662306a36Sopenharmony_ci}; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_cistruct modem_private_data { 28962306a36Sopenharmony_ci struct regulator *regulator; 29062306a36Sopenharmony_ci}; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cistatic struct modem_private_data modem_priv; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci/* 29562306a36Sopenharmony_ci * Define partitions for flash device 29662306a36Sopenharmony_ci */ 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_cistatic struct mtd_partition partition_info[] = { 29962306a36Sopenharmony_ci { .name = "Kernel", 30062306a36Sopenharmony_ci .offset = 0, 30162306a36Sopenharmony_ci .size = 3 * SZ_1M + SZ_512K }, 30262306a36Sopenharmony_ci { .name = "u-boot", 30362306a36Sopenharmony_ci .offset = 3 * SZ_1M + SZ_512K, 30462306a36Sopenharmony_ci .size = SZ_256K }, 30562306a36Sopenharmony_ci { .name = "u-boot params", 30662306a36Sopenharmony_ci .offset = 3 * SZ_1M + SZ_512K + SZ_256K, 30762306a36Sopenharmony_ci .size = SZ_256K }, 30862306a36Sopenharmony_ci { .name = "Amstrad LDR", 30962306a36Sopenharmony_ci .offset = 4 * SZ_1M, 31062306a36Sopenharmony_ci .size = SZ_256K }, 31162306a36Sopenharmony_ci { .name = "File system", 31262306a36Sopenharmony_ci .offset = 4 * SZ_1M + 1 * SZ_256K, 31362306a36Sopenharmony_ci .size = 27 * SZ_1M }, 31462306a36Sopenharmony_ci { .name = "PBL reserved", 31562306a36Sopenharmony_ci .offset = 32 * SZ_1M - 3 * SZ_256K, 31662306a36Sopenharmony_ci .size = 3 * SZ_256K }, 31762306a36Sopenharmony_ci}; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_cistatic struct gpio_nand_platdata nand_platdata = { 32062306a36Sopenharmony_ci .parts = partition_info, 32162306a36Sopenharmony_ci .num_parts = ARRAY_SIZE(partition_info), 32262306a36Sopenharmony_ci}; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistatic struct platform_device ams_delta_nand_device = { 32562306a36Sopenharmony_ci .name = "ams-delta-nand", 32662306a36Sopenharmony_ci .id = -1, 32762306a36Sopenharmony_ci .dev = { 32862306a36Sopenharmony_ci .platform_data = &nand_platdata, 32962306a36Sopenharmony_ci }, 33062306a36Sopenharmony_ci}; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci#define OMAP_GPIO_LABEL "gpio-0-15" 33362306a36Sopenharmony_ci#define OMAP_MPUIO_LABEL "mpuio" 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_nand_gpio_table = { 33662306a36Sopenharmony_ci .table = { 33762306a36Sopenharmony_ci GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_NAND_RB, "rdy", 33862306a36Sopenharmony_ci 0), 33962306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NCE, "nce", 34062306a36Sopenharmony_ci GPIO_ACTIVE_LOW), 34162306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NRE, "nre", 34262306a36Sopenharmony_ci GPIO_ACTIVE_LOW), 34362306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWP, "nwp", 34462306a36Sopenharmony_ci GPIO_ACTIVE_LOW), 34562306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 34662306a36Sopenharmony_ci GPIO_ACTIVE_LOW), 34762306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0), 34862306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0), 34962306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 0, "data", 0, 0), 35062306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 1, "data", 1, 0), 35162306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 2, "data", 2, 0), 35262306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 3, "data", 3, 0), 35362306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 4, "data", 4, 0), 35462306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 5, "data", 5, 0), 35562306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 6, "data", 6, 0), 35662306a36Sopenharmony_ci GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 7, "data", 7, 0), 35762306a36Sopenharmony_ci { }, 35862306a36Sopenharmony_ci }, 35962306a36Sopenharmony_ci}; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistatic struct resource ams_delta_kp_resources[] = { 36262306a36Sopenharmony_ci [0] = { 36362306a36Sopenharmony_ci .start = INT_KEYBOARD, 36462306a36Sopenharmony_ci .end = INT_KEYBOARD, 36562306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 36662306a36Sopenharmony_ci }, 36762306a36Sopenharmony_ci}; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistatic const struct matrix_keymap_data ams_delta_keymap_data = { 37062306a36Sopenharmony_ci .keymap = ams_delta_keymap, 37162306a36Sopenharmony_ci .keymap_size = ARRAY_SIZE(ams_delta_keymap), 37262306a36Sopenharmony_ci}; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_cistatic struct omap_kp_platform_data ams_delta_kp_data = { 37562306a36Sopenharmony_ci .rows = 8, 37662306a36Sopenharmony_ci .cols = 8, 37762306a36Sopenharmony_ci .keymap_data = &ams_delta_keymap_data, 37862306a36Sopenharmony_ci .delay = 9, 37962306a36Sopenharmony_ci}; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_cistatic struct platform_device ams_delta_kp_device = { 38262306a36Sopenharmony_ci .name = "omap-keypad", 38362306a36Sopenharmony_ci .id = -1, 38462306a36Sopenharmony_ci .dev = { 38562306a36Sopenharmony_ci .platform_data = &ams_delta_kp_data, 38662306a36Sopenharmony_ci }, 38762306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(ams_delta_kp_resources), 38862306a36Sopenharmony_ci .resource = ams_delta_kp_resources, 38962306a36Sopenharmony_ci}; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistatic struct platform_device ams_delta_lcd_device = { 39262306a36Sopenharmony_ci .name = "lcd_ams_delta", 39362306a36Sopenharmony_ci .id = -1, 39462306a36Sopenharmony_ci}; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_lcd_gpio_table = { 39762306a36Sopenharmony_ci .table = { 39862306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_VBLEN, "vblen", 0), 39962306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_NDISP, "ndisp", 0), 40062306a36Sopenharmony_ci { }, 40162306a36Sopenharmony_ci }, 40262306a36Sopenharmony_ci}; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cistatic struct gpio_led gpio_leds[] __initdata = { 40562306a36Sopenharmony_ci [LATCH1_PIN_LED_CAMERA] = { 40662306a36Sopenharmony_ci .name = "camera", 40762306a36Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 40862306a36Sopenharmony_ci }, 40962306a36Sopenharmony_ci [LATCH1_PIN_LED_ADVERT] = { 41062306a36Sopenharmony_ci .name = "advert", 41162306a36Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 41262306a36Sopenharmony_ci }, 41362306a36Sopenharmony_ci [LATCH1_PIN_LED_MAIL] = { 41462306a36Sopenharmony_ci .name = "email", 41562306a36Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 41662306a36Sopenharmony_ci }, 41762306a36Sopenharmony_ci [LATCH1_PIN_LED_HANDSFREE] = { 41862306a36Sopenharmony_ci .name = "handsfree", 41962306a36Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 42062306a36Sopenharmony_ci }, 42162306a36Sopenharmony_ci [LATCH1_PIN_LED_VOICEMAIL] = { 42262306a36Sopenharmony_ci .name = "voicemail", 42362306a36Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 42462306a36Sopenharmony_ci }, 42562306a36Sopenharmony_ci [LATCH1_PIN_LED_VOICE] = { 42662306a36Sopenharmony_ci .name = "voice", 42762306a36Sopenharmony_ci .default_state = LEDS_GPIO_DEFSTATE_OFF, 42862306a36Sopenharmony_ci }, 42962306a36Sopenharmony_ci}; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistatic const struct gpio_led_platform_data leds_pdata __initconst = { 43262306a36Sopenharmony_ci .leds = gpio_leds, 43362306a36Sopenharmony_ci .num_leds = ARRAY_SIZE(gpio_leds), 43462306a36Sopenharmony_ci}; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_cistatic struct gpiod_lookup_table leds_gpio_table = { 43762306a36Sopenharmony_ci .table = { 43862306a36Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_CAMERA, NULL, 43962306a36Sopenharmony_ci LATCH1_PIN_LED_CAMERA, 0), 44062306a36Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_ADVERT, NULL, 44162306a36Sopenharmony_ci LATCH1_PIN_LED_ADVERT, 0), 44262306a36Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_MAIL, NULL, 44362306a36Sopenharmony_ci LATCH1_PIN_LED_MAIL, 0), 44462306a36Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_HANDSFREE, NULL, 44562306a36Sopenharmony_ci LATCH1_PIN_LED_HANDSFREE, 0), 44662306a36Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_VOICEMAIL, NULL, 44762306a36Sopenharmony_ci LATCH1_PIN_LED_VOICEMAIL, 0), 44862306a36Sopenharmony_ci GPIO_LOOKUP_IDX(LATCH1_LABEL, LATCH1_PIN_LED_VOICE, NULL, 44962306a36Sopenharmony_ci LATCH1_PIN_LED_VOICE, 0), 45062306a36Sopenharmony_ci { }, 45162306a36Sopenharmony_ci }, 45262306a36Sopenharmony_ci}; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_cistatic struct platform_device ams_delta_audio_device = { 45562306a36Sopenharmony_ci .name = "ams-delta-audio", 45662306a36Sopenharmony_ci .id = -1, 45762306a36Sopenharmony_ci}; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_cistatic struct gpiod_lookup_table ams_delta_audio_gpio_table = { 46062306a36Sopenharmony_ci .table = { 46162306a36Sopenharmony_ci GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_HOOK_SWITCH, 46262306a36Sopenharmony_ci "hook_switch", 0), 46362306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_CODEC, 46462306a36Sopenharmony_ci "modem_codec", 0), 46562306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_HANDSFREE_MUTE, 46662306a36Sopenharmony_ci "handsfree_mute", 0), 46762306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_HANDSET_MUTE, 46862306a36Sopenharmony_ci "handset_mute", 0), 46962306a36Sopenharmony_ci { }, 47062306a36Sopenharmony_ci }, 47162306a36Sopenharmony_ci}; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_cistatic struct platform_device cx20442_codec_device = { 47462306a36Sopenharmony_ci .name = "cx20442-codec", 47562306a36Sopenharmony_ci .id = -1, 47662306a36Sopenharmony_ci}; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_cistatic struct resource ams_delta_serio_resources[] = { 47962306a36Sopenharmony_ci { 48062306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 48162306a36Sopenharmony_ci /* 48262306a36Sopenharmony_ci * Initialize IRQ resource with invalid IRQ number. 48362306a36Sopenharmony_ci * It will be replaced with dynamically allocated GPIO IRQ 48462306a36Sopenharmony_ci * obtained from GPIO chip as soon as the chip is available. 48562306a36Sopenharmony_ci */ 48662306a36Sopenharmony_ci .start = -EINVAL, 48762306a36Sopenharmony_ci .end = -EINVAL, 48862306a36Sopenharmony_ci }, 48962306a36Sopenharmony_ci}; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic struct platform_device ams_delta_serio_device = { 49262306a36Sopenharmony_ci .name = "ams-delta-serio", 49362306a36Sopenharmony_ci .id = PLATFORM_DEVID_NONE, 49462306a36Sopenharmony_ci .dev = { 49562306a36Sopenharmony_ci /* 49662306a36Sopenharmony_ci * Initialize .platform_data explicitly with NULL to 49762306a36Sopenharmony_ci * indicate it is going to be used. It will be replaced 49862306a36Sopenharmony_ci * with FIQ buffer address as soon as FIQ is initialized. 49962306a36Sopenharmony_ci */ 50062306a36Sopenharmony_ci .platform_data = NULL, 50162306a36Sopenharmony_ci }, 50262306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(ams_delta_serio_resources), 50362306a36Sopenharmony_ci .resource = ams_delta_serio_resources, 50462306a36Sopenharmony_ci}; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic struct regulator_consumer_supply keybrd_pwr_consumers[] = { 50762306a36Sopenharmony_ci /* 50862306a36Sopenharmony_ci * Initialize supply .dev_name with NULL. It will be replaced 50962306a36Sopenharmony_ci * with serio dev_name() as soon as the serio device is registered. 51062306a36Sopenharmony_ci */ 51162306a36Sopenharmony_ci REGULATOR_SUPPLY("vcc", NULL), 51262306a36Sopenharmony_ci}; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_cistatic struct regulator_init_data keybrd_pwr_initdata = { 51562306a36Sopenharmony_ci .constraints = { 51662306a36Sopenharmony_ci .valid_ops_mask = REGULATOR_CHANGE_STATUS, 51762306a36Sopenharmony_ci }, 51862306a36Sopenharmony_ci .num_consumer_supplies = ARRAY_SIZE(keybrd_pwr_consumers), 51962306a36Sopenharmony_ci .consumer_supplies = keybrd_pwr_consumers, 52062306a36Sopenharmony_ci}; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_cistatic struct fixed_voltage_config keybrd_pwr_config = { 52362306a36Sopenharmony_ci .supply_name = "keybrd_pwr", 52462306a36Sopenharmony_ci .microvolts = 5000000, 52562306a36Sopenharmony_ci .init_data = &keybrd_pwr_initdata, 52662306a36Sopenharmony_ci}; 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic struct platform_device keybrd_pwr_device = { 52962306a36Sopenharmony_ci .name = "reg-fixed-voltage", 53062306a36Sopenharmony_ci .id = PLATFORM_DEVID_AUTO, 53162306a36Sopenharmony_ci .dev = { 53262306a36Sopenharmony_ci .platform_data = &keybrd_pwr_config, 53362306a36Sopenharmony_ci }, 53462306a36Sopenharmony_ci}; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic struct gpiod_lookup_table keybrd_pwr_gpio_table = { 53762306a36Sopenharmony_ci .table = { 53862306a36Sopenharmony_ci GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR, NULL, 53962306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 54062306a36Sopenharmony_ci { }, 54162306a36Sopenharmony_ci }, 54262306a36Sopenharmony_ci}; 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_cistatic struct platform_device *ams_delta_devices[] __initdata = { 54562306a36Sopenharmony_ci &latch1_gpio_device, 54662306a36Sopenharmony_ci &latch2_gpio_device, 54762306a36Sopenharmony_ci &ams_delta_kp_device, 54862306a36Sopenharmony_ci &ams_delta_audio_device, 54962306a36Sopenharmony_ci &ams_delta_serio_device, 55062306a36Sopenharmony_ci &ams_delta_nand_device, 55162306a36Sopenharmony_ci &ams_delta_lcd_device, 55262306a36Sopenharmony_ci &cx20442_codec_device, 55362306a36Sopenharmony_ci &modem_nreset_device, 55462306a36Sopenharmony_ci}; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_cistatic struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = { 55762306a36Sopenharmony_ci &ams_delta_nreset_gpiod_table, 55862306a36Sopenharmony_ci &ams_delta_audio_gpio_table, 55962306a36Sopenharmony_ci &keybrd_pwr_gpio_table, 56062306a36Sopenharmony_ci &ams_delta_lcd_gpio_table, 56162306a36Sopenharmony_ci &ams_delta_nand_gpio_table, 56262306a36Sopenharmony_ci}; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci/* 56562306a36Sopenharmony_ci * Some drivers may not use GPIO lookup tables but need to be provided 56662306a36Sopenharmony_ci * with GPIO numbers. The same applies to GPIO based IRQ lines - some 56762306a36Sopenharmony_ci * drivers may even not use GPIO layer but expect just IRQ numbers. 56862306a36Sopenharmony_ci * We could either define GPIO lookup tables then use them on behalf 56962306a36Sopenharmony_ci * of those devices, or we can use GPIO driver level methods for 57062306a36Sopenharmony_ci * identification of GPIO and IRQ numbers. For the purpose of the latter, 57162306a36Sopenharmony_ci * defina a helper function which identifies GPIO chips by their labels. 57262306a36Sopenharmony_ci */ 57362306a36Sopenharmony_cistatic int gpiochip_match_by_label(struct gpio_chip *chip, void *data) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci char *label = data; 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci return !strcmp(label, chip->label); 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistatic struct gpiod_hog ams_delta_gpio_hogs[] = { 58162306a36Sopenharmony_ci GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT, "keybrd_dataout", 58262306a36Sopenharmony_ci GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW), 58362306a36Sopenharmony_ci {}, 58462306a36Sopenharmony_ci}; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_cistatic struct plat_serial8250_port ams_delta_modem_ports[]; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci/* 58962306a36Sopenharmony_ci * Obtain MODEM IRQ GPIO descriptor using its hardware pin 59062306a36Sopenharmony_ci * number and assign related IRQ number to the MODEM port. 59162306a36Sopenharmony_ci * Keep the GPIO descriptor open so nobody steps in. 59262306a36Sopenharmony_ci */ 59362306a36Sopenharmony_cistatic void __init modem_assign_irq(struct gpio_chip *chip) 59462306a36Sopenharmony_ci{ 59562306a36Sopenharmony_ci struct gpio_desc *gpiod; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci gpiod = gpiochip_request_own_desc(chip, AMS_DELTA_GPIO_PIN_MODEM_IRQ, 59862306a36Sopenharmony_ci "modem_irq", GPIO_ACTIVE_HIGH, 59962306a36Sopenharmony_ci GPIOD_IN); 60062306a36Sopenharmony_ci if (IS_ERR(gpiod)) { 60162306a36Sopenharmony_ci pr_err("%s: modem IRQ GPIO request failed (%ld)\n", __func__, 60262306a36Sopenharmony_ci PTR_ERR(gpiod)); 60362306a36Sopenharmony_ci } else { 60462306a36Sopenharmony_ci ams_delta_modem_ports[0].irq = gpiod_to_irq(gpiod); 60562306a36Sopenharmony_ci } 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci/* 60962306a36Sopenharmony_ci * The purpose of this function is to take care of proper initialization of 61062306a36Sopenharmony_ci * devices and data structures which depend on GPIO lines provided by OMAP GPIO 61162306a36Sopenharmony_ci * banks but their drivers don't use GPIO lookup tables or GPIO layer at all. 61262306a36Sopenharmony_ci * The function may be called as soon as OMAP GPIO devices are probed. 61362306a36Sopenharmony_ci * Since that happens at postcore_initcall, it can be called successfully 61462306a36Sopenharmony_ci * from init_machine or later. 61562306a36Sopenharmony_ci * Dependent devices may be registered from within this function or later. 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_cistatic void __init omap_gpio_deps_init(void) 61862306a36Sopenharmony_ci{ 61962306a36Sopenharmony_ci struct gpio_chip *chip; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci chip = gpiochip_find(OMAP_GPIO_LABEL, gpiochip_match_by_label); 62262306a36Sopenharmony_ci if (!chip) { 62362306a36Sopenharmony_ci pr_err("%s: OMAP GPIO chip not found\n", __func__); 62462306a36Sopenharmony_ci return; 62562306a36Sopenharmony_ci } 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci /* 62862306a36Sopenharmony_ci * Start with FIQ initialization as it may have to request 62962306a36Sopenharmony_ci * and release successfully each OMAP GPIO pin in turn. 63062306a36Sopenharmony_ci */ 63162306a36Sopenharmony_ci ams_delta_init_fiq(chip, &ams_delta_serio_device); 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci modem_assign_irq(chip); 63462306a36Sopenharmony_ci} 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci/* 63762306a36Sopenharmony_ci * Initialize latch2 pins with values which are safe for dependent on-board 63862306a36Sopenharmony_ci * devices or useful for their successull initialization even before GPIO 63962306a36Sopenharmony_ci * driver takes control over the latch pins: 64062306a36Sopenharmony_ci * - LATCH2_PIN_LCD_VBLEN = 0 64162306a36Sopenharmony_ci * - LATCH2_PIN_LCD_NDISP = 0 Keep LCD device powered off before its 64262306a36Sopenharmony_ci * driver takes control over it. 64362306a36Sopenharmony_ci * - LATCH2_PIN_NAND_NCE = 0 64462306a36Sopenharmony_ci * - LATCH2_PIN_NAND_NWP = 0 Keep NAND device down and write- 64562306a36Sopenharmony_ci * protected before its driver takes 64662306a36Sopenharmony_ci * control over it. 64762306a36Sopenharmony_ci * - LATCH2_PIN_KEYBRD_PWR = 0 Keep keyboard powered off before serio 64862306a36Sopenharmony_ci * driver takes control over it. 64962306a36Sopenharmony_ci * - LATCH2_PIN_KEYBRD_DATAOUT = 0 Keep low to avoid corruption of first 65062306a36Sopenharmony_ci * byte of data received from attached 65162306a36Sopenharmony_ci * keyboard when serio device is probed; 65262306a36Sopenharmony_ci * the pin is also hogged low by the latch2 65362306a36Sopenharmony_ci * GPIO driver as soon as it is ready. 65462306a36Sopenharmony_ci * - LATCH2_PIN_MODEM_NRESET = 1 Enable voice MODEM device, allowing for 65562306a36Sopenharmony_ci * its successful probe even before a 65662306a36Sopenharmony_ci * regulator it depends on, which in turn 65762306a36Sopenharmony_ci * takes control over the pin, is set up. 65862306a36Sopenharmony_ci * - LATCH2_PIN_MODEM_CODEC = 1 Attach voice MODEM CODEC data port 65962306a36Sopenharmony_ci * to the MODEM so the CODEC is under 66062306a36Sopenharmony_ci * control even if audio driver doesn't 66162306a36Sopenharmony_ci * take it over. 66262306a36Sopenharmony_ci */ 66362306a36Sopenharmony_cistatic void __init ams_delta_latch2_init(void) 66462306a36Sopenharmony_ci{ 66562306a36Sopenharmony_ci u16 latch2 = 1 << LATCH2_PIN_MODEM_NRESET | 1 << LATCH2_PIN_MODEM_CODEC; 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci __raw_writew(latch2, IOMEM(LATCH2_VIRT)); 66862306a36Sopenharmony_ci} 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_cistatic void __init ams_delta_init(void) 67162306a36Sopenharmony_ci{ 67262306a36Sopenharmony_ci struct platform_device *leds_pdev; 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci /* mux pins for uarts */ 67562306a36Sopenharmony_ci omap_cfg_reg(UART1_TX); 67662306a36Sopenharmony_ci omap_cfg_reg(UART1_RTS); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci /* parallel camera interface */ 67962306a36Sopenharmony_ci omap_cfg_reg(H19_1610_CAM_EXCLK); 68062306a36Sopenharmony_ci omap_cfg_reg(J15_1610_CAM_LCLK); 68162306a36Sopenharmony_ci omap_cfg_reg(L18_1610_CAM_VS); 68262306a36Sopenharmony_ci omap_cfg_reg(L15_1610_CAM_HS); 68362306a36Sopenharmony_ci omap_cfg_reg(L19_1610_CAM_D0); 68462306a36Sopenharmony_ci omap_cfg_reg(K14_1610_CAM_D1); 68562306a36Sopenharmony_ci omap_cfg_reg(K15_1610_CAM_D2); 68662306a36Sopenharmony_ci omap_cfg_reg(K19_1610_CAM_D3); 68762306a36Sopenharmony_ci omap_cfg_reg(K18_1610_CAM_D4); 68862306a36Sopenharmony_ci omap_cfg_reg(J14_1610_CAM_D5); 68962306a36Sopenharmony_ci omap_cfg_reg(J19_1610_CAM_D6); 69062306a36Sopenharmony_ci omap_cfg_reg(J18_1610_CAM_D7); 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci omap_gpio_deps_init(); 69362306a36Sopenharmony_ci ams_delta_latch2_init(); 69462306a36Sopenharmony_ci gpiod_add_hogs(ams_delta_gpio_hogs); 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci omap_serial_init(); 69762306a36Sopenharmony_ci omap_register_i2c_bus(1, 100, NULL, 0); 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci omap1_usb_init(&ams_delta_usb_config); 70062306a36Sopenharmony_ci platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci /* 70362306a36Sopenharmony_ci * As soon as regulator consumers have been registered, assign their 70462306a36Sopenharmony_ci * dev_names to consumer supply entries of respective regulators. 70562306a36Sopenharmony_ci */ 70662306a36Sopenharmony_ci keybrd_pwr_consumers[0].dev_name = 70762306a36Sopenharmony_ci dev_name(&ams_delta_serio_device.dev); 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci /* 71062306a36Sopenharmony_ci * Once consumer supply entries are populated with dev_names, 71162306a36Sopenharmony_ci * register regulator devices. At this stage only the keyboard 71262306a36Sopenharmony_ci * power regulator has its consumer supply table fully populated. 71362306a36Sopenharmony_ci */ 71462306a36Sopenharmony_ci platform_device_register(&keybrd_pwr_device); 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci /* 71762306a36Sopenharmony_ci * As soon as GPIO consumers have been registered, assign 71862306a36Sopenharmony_ci * their dev_names to respective GPIO lookup tables. 71962306a36Sopenharmony_ci */ 72062306a36Sopenharmony_ci ams_delta_audio_gpio_table.dev_id = 72162306a36Sopenharmony_ci dev_name(&ams_delta_audio_device.dev); 72262306a36Sopenharmony_ci keybrd_pwr_gpio_table.dev_id = dev_name(&keybrd_pwr_device.dev); 72362306a36Sopenharmony_ci ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev); 72462306a36Sopenharmony_ci ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev); 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci /* 72762306a36Sopenharmony_ci * Once GPIO lookup tables are populated with dev_names, register them. 72862306a36Sopenharmony_ci */ 72962306a36Sopenharmony_ci gpiod_add_lookup_tables(ams_delta_gpio_tables, 73062306a36Sopenharmony_ci ARRAY_SIZE(ams_delta_gpio_tables)); 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci leds_pdev = gpio_led_register_device(PLATFORM_DEVID_NONE, &leds_pdata); 73362306a36Sopenharmony_ci if (!IS_ERR_OR_NULL(leds_pdev)) { 73462306a36Sopenharmony_ci leds_gpio_table.dev_id = dev_name(&leds_pdev->dev); 73562306a36Sopenharmony_ci gpiod_add_lookup_table(&leds_gpio_table); 73662306a36Sopenharmony_ci } 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1); 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci omapfb_set_lcd_config(&ams_delta_lcd_config); 74162306a36Sopenharmony_ci} 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_cistatic void modem_pm(struct uart_port *port, unsigned int state, unsigned old) 74462306a36Sopenharmony_ci{ 74562306a36Sopenharmony_ci struct modem_private_data *priv = port->private_data; 74662306a36Sopenharmony_ci int ret; 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci if (!priv) 74962306a36Sopenharmony_ci return; 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci if (IS_ERR(priv->regulator)) 75262306a36Sopenharmony_ci return; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci if (state == old) 75562306a36Sopenharmony_ci return; 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci if (state == 0) 75862306a36Sopenharmony_ci ret = regulator_enable(priv->regulator); 75962306a36Sopenharmony_ci else if (old == 0) 76062306a36Sopenharmony_ci ret = regulator_disable(priv->regulator); 76162306a36Sopenharmony_ci else 76262306a36Sopenharmony_ci ret = 0; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci if (ret) 76562306a36Sopenharmony_ci dev_warn(port->dev, 76662306a36Sopenharmony_ci "ams_delta modem_pm: failed to %sable regulator: %d\n", 76762306a36Sopenharmony_ci state ? "dis" : "en", ret); 76862306a36Sopenharmony_ci} 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_cistatic struct plat_serial8250_port ams_delta_modem_ports[] = { 77162306a36Sopenharmony_ci { 77262306a36Sopenharmony_ci .membase = IOMEM(MODEM_VIRT), 77362306a36Sopenharmony_ci .mapbase = MODEM_PHYS, 77462306a36Sopenharmony_ci .irq = IRQ_NOTCONNECTED, /* changed later */ 77562306a36Sopenharmony_ci .flags = UPF_BOOT_AUTOCONF, 77662306a36Sopenharmony_ci .irqflags = IRQF_TRIGGER_RISING, 77762306a36Sopenharmony_ci .iotype = UPIO_MEM, 77862306a36Sopenharmony_ci .regshift = 1, 77962306a36Sopenharmony_ci .uartclk = BASE_BAUD * 16, 78062306a36Sopenharmony_ci .pm = modem_pm, 78162306a36Sopenharmony_ci .private_data = &modem_priv, 78262306a36Sopenharmony_ci }, 78362306a36Sopenharmony_ci { }, 78462306a36Sopenharmony_ci}; 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_cistatic int ams_delta_modem_pm_activate(struct device *dev) 78762306a36Sopenharmony_ci{ 78862306a36Sopenharmony_ci modem_priv.regulator = regulator_get(dev, "RESET#"); 78962306a36Sopenharmony_ci if (IS_ERR(modem_priv.regulator)) 79062306a36Sopenharmony_ci return -EPROBE_DEFER; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci return 0; 79362306a36Sopenharmony_ci} 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_cistatic struct dev_pm_domain ams_delta_modem_pm_domain = { 79662306a36Sopenharmony_ci .activate = ams_delta_modem_pm_activate, 79762306a36Sopenharmony_ci}; 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_cistatic struct platform_device ams_delta_modem_device = { 80062306a36Sopenharmony_ci .name = "serial8250", 80162306a36Sopenharmony_ci .id = PLAT8250_DEV_PLATFORM1, 80262306a36Sopenharmony_ci .dev = { 80362306a36Sopenharmony_ci .platform_data = ams_delta_modem_ports, 80462306a36Sopenharmony_ci .pm_domain = &ams_delta_modem_pm_domain, 80562306a36Sopenharmony_ci }, 80662306a36Sopenharmony_ci}; 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci/* 80962306a36Sopenharmony_ci * This function expects MODEM IRQ number already assigned to the port. 81062306a36Sopenharmony_ci * The MODEM device requires its RESET# pin kept high during probe. 81162306a36Sopenharmony_ci * That requirement can be fulfilled in several ways: 81262306a36Sopenharmony_ci * - with a descriptor of already functional modem_nreset regulator 81362306a36Sopenharmony_ci * assigned to the MODEM private data, 81462306a36Sopenharmony_ci * - with the regulator not yet controlled by modem_pm function but 81562306a36Sopenharmony_ci * already enabled by default on probe, 81662306a36Sopenharmony_ci * - before the modem_nreset regulator is probed, with the pin already 81762306a36Sopenharmony_ci * set high explicitly. 81862306a36Sopenharmony_ci * The last one is already guaranteed by ams_delta_latch2_init() called 81962306a36Sopenharmony_ci * from machine_init. 82062306a36Sopenharmony_ci * In order to avoid taking over ttyS0 device slot, the MODEM device 82162306a36Sopenharmony_ci * should be registered after OMAP serial ports. Since those ports 82262306a36Sopenharmony_ci * are registered at arch_initcall, this function can be called safely 82362306a36Sopenharmony_ci * at arch_initcall_sync earliest. 82462306a36Sopenharmony_ci */ 82562306a36Sopenharmony_cistatic int __init ams_delta_modem_init(void) 82662306a36Sopenharmony_ci{ 82762306a36Sopenharmony_ci if (!machine_is_ams_delta()) 82862306a36Sopenharmony_ci return -ENODEV; 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci omap_cfg_reg(M14_1510_GPIO2); 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci /* Initialize the modem_nreset regulator consumer before use */ 83362306a36Sopenharmony_ci modem_priv.regulator = ERR_PTR(-ENODEV); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci return platform_device_register(&ams_delta_modem_device); 83662306a36Sopenharmony_ci} 83762306a36Sopenharmony_ciarch_initcall_sync(ams_delta_modem_init); 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_cistatic void __init ams_delta_map_io(void) 84062306a36Sopenharmony_ci{ 84162306a36Sopenharmony_ci omap1_map_io(); 84262306a36Sopenharmony_ci iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); 84362306a36Sopenharmony_ci} 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ciMACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") 84662306a36Sopenharmony_ci /* Maintainer: Jonathan McDowell <noodles@earth.li> */ 84762306a36Sopenharmony_ci .atag_offset = 0x100, 84862306a36Sopenharmony_ci .map_io = ams_delta_map_io, 84962306a36Sopenharmony_ci .init_early = omap1_init_early, 85062306a36Sopenharmony_ci .init_irq = omap1_init_irq, 85162306a36Sopenharmony_ci .init_machine = ams_delta_init, 85262306a36Sopenharmony_ci .init_late = omap1_init_late, 85362306a36Sopenharmony_ci .init_time = omap1_timer_init, 85462306a36Sopenharmony_ci .restart = omap1_restart, 85562306a36Sopenharmony_ciMACHINE_END 856