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