code:
/* SPDX-License-Identifier: GPL-2.0 */
#define PDMA_FILTER_PARAM(_prio, _requestor) (&(struct pxad_param) { \
	.prio = PXAD_PRIO_##_prio, .drcmr = _requestor })
struct mmp_dma_platdata;

extern struct platform_device pxa_device_pmu;
extern struct platform_device pxa_device_mci;
extern struct platform_device pxa3xx_device_mci2;
extern struct platform_device pxa3xx_device_mci3;
extern struct platform_device pxa25x_device_udc;
extern struct platform_device pxa27x_device_udc;
extern struct platform_device pxa3xx_device_u2d;
extern struct platform_device pxa_device_fb;
extern struct platform_device pxa_device_ffuart;
extern struct platform_device pxa_device_btuart;
extern struct platform_device pxa_device_stuart;
extern struct platform_device pxa_device_hwuart;
extern struct platform_device pxa_device_i2c;
extern struct platform_device pxa_device_i2s;
extern struct platform_device pxa_device_ficp;
extern struct platform_device sa1100_device_rtc;
extern struct platform_device pxa_device_rtc;
extern struct platform_device pxa_device_ac97;

extern struct platform_device pxa27x_device_i2c_power;
extern struct platform_device pxa27x_device_ohci;
extern struct platform_device pxa27x_device_keypad;

extern struct platform_device pxa25x_device_ssp;
extern struct platform_device pxa25x_device_nssp;
extern struct platform_device pxa25x_device_assp;
extern struct platform_device pxa27x_device_ssp1;
extern struct platform_device pxa27x_device_ssp2;
extern struct platform_device pxa27x_device_ssp3;
extern struct platform_device pxa3xx_device_ssp1;
extern struct platform_device pxa3xx_device_ssp2;
extern struct platform_device pxa3xx_device_ssp3;
extern struct platform_device pxa3xx_device_ssp4;

extern struct platform_device pxa25x_device_pwm0;
extern struct platform_device pxa25x_device_pwm1;
extern struct platform_device pxa27x_device_pwm0;
extern struct platform_device pxa27x_device_pwm1;

extern struct platform_device pxa3xx_device_nand;
extern struct platform_device pxa3xx_device_i2c_power;

extern struct platform_device pxa3xx_device_gcu;

extern struct platform_device pxa_device_asoc_platform;
extern struct platform_device pxa_device_asoc_ssp1;
extern struct platform_device pxa_device_asoc_ssp2;
extern struct platform_device pxa_device_asoc_ssp3;
extern struct platform_device pxa_device_asoc_ssp4;

extern struct platform_device pxa25x_device_gpio;
extern struct platform_device pxa27x_device_gpio;
extern struct platform_device pxa3xx_device_gpio;
extern struct platform_device pxa93x_device_gpio;

void __init pxa_register_device(struct platform_device *dev, void *data);
void __init pxa2xx_set_dmac_info(struct mmp_dma_platdata *dma_pdata);

struct i2c_pxa_platform_data;
extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
#ifdef CONFIG_PXA27x
extern void pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info);
#endif
#ifdef CONFIG_PXA3xx
extern void pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info);
#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Toshiba e740 PCMCIA specific routines.
 *
 * (c) 2004 Ian Molton <spyro@f2s.com>
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>

#include "eseries-gpio.h"

#include <asm/irq.h>
#include <asm/mach-types.h>

#include <pcmcia/soc_common.h>

static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
	if (skt->nr == 0) {
		skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0;
		skt->stat[SOC_STAT_CD].name = "CF card detect";
		skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0;
		skt->stat[SOC_STAT_RDY].name = "CF ready";
	} else {
		skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1;
		skt->stat[SOC_STAT_CD].name = "Wifi switch";
		skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1;
		skt->stat[SOC_STAT_RDY].name = "Wifi ready";
	}

	return 0;
}

static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
					struct pcmcia_state *state)
{
	state->vs_3v  = 1;
	state->vs_Xv  = 0;
}

static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
					const socket_state_t *state)
{
	if (state->flags & SS_RESET) {
		if (skt->nr == 0)
			gpio_set_value(GPIO_E740_PCMCIA_RST0, 1);
		else
			gpio_set_value(GPIO_E740_PCMCIA_RST1, 1);
	} else {
		if (skt->nr == 0)
			gpio_set_value(GPIO_E740_PCMCIA_RST0, 0);
		else
			gpio_set_value(GPIO_E740_PCMCIA_RST1, 0);
	}

	switch (state->Vcc) {
	case 0:	/* Socket off */
		if (skt->nr == 0)
			gpio_set_value(GPIO_E740_PCMCIA_PWR0, 0);
		else
			gpio_set_value(GPIO_E740_PCMCIA_PWR1, 1);
		break;
	case 50:
	case 33: /* socket on */
		if (skt->nr == 0)
			gpio_set_value(GPIO_E740_PCMCIA_PWR0, 1);
		else
			gpio_set_value(GPIO_E740_PCMCIA_PWR1, 0);
		break;
	default:
		printk(KERN_ERR "e740_cs: Unsupported Vcc: %d\n", state->Vcc);
	}

	return 0;
}

static struct pcmcia_low_level e740_pcmcia_ops = {
	.owner            = THIS_MODULE,
	.hw_init          = e740_pcmcia_hw_init,
	.socket_state     = e740_pcmcia_socket_state,
	.configure_socket = e740_pcmcia_configure_socket,
	.nr               = 2,
};

static struct platform_device *e740_pcmcia_device;

static int __init e740_pcmcia_init(void)
{
	int ret;

	if (!machine_is_e740())
		return -ENODEV;

	e740_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
	if (!e740_pcmcia_device)
		return -ENOMEM;

	ret = platform_device_add_data(e740_pcmcia_device, &e740_pcmcia_ops,
					sizeof(e740_pcmcia_ops));

	if (!ret)
		ret = platform_device_add(e740_pcmcia_device);

	if (ret)
		platform_device_put(e740_pcmcia_device);

	return ret;
}

static void __exit e740_pcmcia_exit(void)
{
	platform_device_unregister(e740_pcmcia_device);
}

module_init(e740_pcmcia_init);
module_exit(e740_pcmcia_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
MODULE_DESCRIPTION("e740 PCMCIA platform support");

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  eseries-gpio.h
 *
 *  Copyright (C) Ian Molton <spyro@f2s.com>
 */

/* e-series power button */
#define GPIO_ESERIES_POWERBTN     0

/* UDC GPIO definitions */
#define GPIO_E7XX_USB_DISC       13
#define GPIO_E7XX_USB_PULLUP      3

#define GPIO_E800_USB_DISC        4
#define GPIO_E800_USB_PULLUP     84

/* e740 PCMCIA GPIO definitions */
/* Note: PWR1 seems to be inverted */
#define GPIO_E740_PCMCIA_CD0      8
#define GPIO_E740_PCMCIA_CD1     44
#define GPIO_E740_PCMCIA_RDY0    11
#define GPIO_E740_PCMCIA_RDY1     6
#define GPIO_E740_PCMCIA_RST0    27
#define GPIO_E740_PCMCIA_RST1    24
#define GPIO_E740_PCMCIA_PWR0    20
#define GPIO_E740_PCMCIA_PWR1    23

/* e750 PCMCIA GPIO definitions */
#define GPIO_E750_PCMCIA_CD0      8
#define GPIO_E750_PCMCIA_RDY0    12
#define GPIO_E750_PCMCIA_RST0    27
#define GPIO_E750_PCMCIA_PWR0    20

/* e800 PCMCIA GPIO definitions */
#define GPIO_E800_PCMCIA_RST0    69
#define GPIO_E800_PCMCIA_RST1    72
#define GPIO_E800_PCMCIA_PWR0    20
#define GPIO_E800_PCMCIA_PWR1    73

/* e7xx IrDA power control */
#define GPIO_E7XX_IR_OFF         38

/* e740 audio control GPIOs */
#define GPIO_E740_WM9705_nAVDD2  16
#define GPIO_E740_MIC_ON         40
#define GPIO_E740_AMP_ON         41

/* e750 audio control GPIOs */
#define GPIO_E750_HP_AMP_OFF      4
#define GPIO_E750_SPK_AMP_OFF     7
#define GPIO_E750_HP_DETECT      37

/* e800 audio control GPIOs */
#define GPIO_E800_HP_DETECT      81
#define GPIO_E800_HP_AMP_OFF     82
#define GPIO_E800_SPK_AMP_ON     83

/* ASIC related GPIOs */
#define GPIO_ESERIES_TMIO_IRQ        5
#define GPIO_ESERIES_TMIO_PCLR      19
#define GPIO_ESERIES_TMIO_SUSPEND   45
#define GPIO_E800_ANGELX_IRQ      8


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  eseries-irq.h
 *
 *  Copyright (C) Ian Molton <spyro@f2s.com>
 */

#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8)
#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n))

#define ANGELX_RDY0_IRQ IRQ_ANGELX(0)
#define ANGELX_ST0_IRQ  IRQ_ANGELX(1)
#define ANGELX_CD0_IRQ  IRQ_ANGELX(2)
#define ANGELX_RDY1_IRQ IRQ_ANGELX(3)
#define ANGELX_ST1_IRQ  IRQ_ANGELX(4)
#define ANGELX_CD1_IRQ  IRQ_ANGELX(5)

#define TMIO_IRQ_BASE (IRQ_BOARD_START+0)
#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n))

#define TMIO_SD_IRQ     IRQ_TMIO(1)
#define TMIO_USB_IRQ    IRQ_TMIO(2)

#define ESERIES_NR_IRQS	(IRQ_BOARD_START + 16)


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for the Toshiba eseries PDAs
 *
 * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
 */

#include <linux/clkdev.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk-provider.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/mfd/tc6387xb.h>
#include <linux/mfd/tc6393xb.h>
#include <linux/mfd/t7l66xb.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/memblock.h>
#include <linux/gpio/machine.h>

#include <video/w100fb.h>

#include <asm/setup.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>

#include "pxa25x.h"
#include "eseries-gpio.h"
#include "eseries-irq.h"
#include <linux/platform_data/asoc-pxa.h>
#include <linux/platform_data/video-pxafb.h>
#include "udc.h"
#include <linux/platform_data/irda-pxaficp.h>

#include "devices.h"
#include "generic.h"

/* Only e800 has 128MB RAM */
void __init eseries_fixup(struct tag *tags, char **cmdline)
{
	if (machine_is_e800())
		memblock_add(0xa0000000, SZ_128M);
	else
		memblock_add(0xa0000000, SZ_64M);
}

static struct gpiod_lookup_table e7xx_gpio_vbus_gpiod_table __maybe_unused = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_E7XX_USB_DISC,
			    "vbus", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", GPIO_E7XX_USB_PULLUP,
			    "pullup", GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct platform_device e7xx_gpio_vbus __maybe_unused = {
	.name	= "gpio-vbus",
	.id	= -1,
};

struct pxaficp_platform_data e7xx_ficp_platform_data = {
	.gpio_pwdown		= GPIO_E7XX_IR_OFF,
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
};

int eseries_tmio_enable(struct platform_device *dev)
{
	/* Reset - bring SUSPEND high before PCLR */
	gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
	gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0);
	msleep(1);
	gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1);
	msleep(1);
	gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 1);
	msleep(1);
	return 0;
}

void eseries_tmio_disable(struct platform_device *dev)
{
	gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
	gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0);
}

int eseries_tmio_suspend(struct platform_device *dev)
{
	gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
	return 0;
}

int eseries_tmio_resume(struct platform_device *dev)
{
	gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1);
	msleep(1);
	return 0;
}

void eseries_get_tmio_gpios(void)
{
	gpio_request(GPIO_ESERIES_TMIO_SUSPEND, NULL);
	gpio_request(GPIO_ESERIES_TMIO_PCLR, NULL);
	gpio_direction_output(GPIO_ESERIES_TMIO_SUSPEND, 0);
	gpio_direction_output(GPIO_ESERIES_TMIO_PCLR, 0);
}

/* TMIO controller uses the same resources on all e-series machines. */
struct resource eseries_tmio_resources[] = {
	[0] = {
		.start  = PXA_CS4_PHYS,
		.end    = PXA_CS4_PHYS + 0x1fffff,
		.flags  = IORESOURCE_MEM,
	},
	[1] = {
		.start  = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ),
		.end    = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ),
		.flags  = IORESOURCE_IRQ,
	},
};

/* Some e-series hardware cannot control the 32K clock */
static void __init __maybe_unused eseries_register_clks(void)
{
	clk_register_fixed_rate(NULL, "CLK_CK32K", NULL, 0, 32768);
}

#ifdef CONFIG_MACH_E330
/* -------------------- e330 tc6387xb parameters -------------------- */

static struct tc6387xb_platform_data e330_tc6387xb_info = {
	.enable   = &eseries_tmio_enable,
	.suspend  = &eseries_tmio_suspend,
	.resume   = &eseries_tmio_resume,
};

static struct platform_device e330_tc6387xb_device = {
	.name           = "tc6387xb",
	.id             = -1,
	.dev            = {
		.platform_data = &e330_tc6387xb_info,
	},
	.num_resources = 2,
	.resource      = eseries_tmio_resources,
};

/* --------------------------------------------------------------- */

static struct platform_device *e330_devices[] __initdata = {
	&e330_tc6387xb_device,
	&e7xx_gpio_vbus,
};

static void __init e330_init(void)
{
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	eseries_register_clks();
	eseries_get_tmio_gpios();
	gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
	platform_add_devices(ARRAY_AND_SIZE(e330_devices));
}

MACHINE_START(E330, "Toshiba e330")
	/* Maintainer: Ian Molton (spyro@f2s.com) */
	.atag_offset	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= ESERIES_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.fixup		= eseries_fixup,
	.init_machine	= e330_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_E350
/* -------------------- e350 t7l66xb parameters -------------------- */

static struct t7l66xb_platform_data e350_t7l66xb_info = {
	.irq_base               = IRQ_BOARD_START,
	.enable                 = &eseries_tmio_enable,
	.suspend                = &eseries_tmio_suspend,
	.resume                 = &eseries_tmio_resume,
};

static struct platform_device e350_t7l66xb_device = {
	.name           = "t7l66xb",
	.id             = -1,
	.dev            = {
		.platform_data = &e350_t7l66xb_info,
	},
	.num_resources = 2,
	.resource      = eseries_tmio_resources,
};

/* ---------------------------------------------------------- */

static struct platform_device *e350_devices[] __initdata = {
	&e350_t7l66xb_device,
	&e7xx_gpio_vbus,
};

static void __init e350_init(void)
{
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	eseries_register_clks();
	eseries_get_tmio_gpios();
	gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
	platform_add_devices(ARRAY_AND_SIZE(e350_devices));
}

MACHINE_START(E350, "Toshiba e350")
	/* Maintainer: Ian Molton (spyro@f2s.com) */
	.atag_offset	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= ESERIES_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.fixup		= eseries_fixup,
	.init_machine	= e350_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_E400
/* ------------------------ E400 LCD definitions ------------------------ */

static struct pxafb_mode_info e400_pxafb_mode_info = {
	.pixclock       = 140703,
	.xres           = 240,
	.yres           = 320,
	.bpp            = 16,
	.hsync_len      = 4,
	.left_margin    = 28,
	.right_margin   = 8,
	.vsync_len      = 3,
	.upper_margin   = 5,
	.lower_margin   = 6,
	.sync           = 0,
};

static struct pxafb_mach_info e400_pxafb_mach_info = {
	.modes          = &e400_pxafb_mode_info,
	.num_modes      = 1,
	.lcd_conn	= LCD_COLOR_TFT_16BPP,
	.lccr3          = 0,
	.pxafb_backlight_power  = NULL,
};

/* ------------------------ E400 MFP config ----------------------------- */

static unsigned long e400_pin_config[] __initdata = {
	/* Chip selects */
	GPIO15_nCS_1,   /* CS1 - Flash */
	GPIO80_nCS_4,   /* CS4 - TMIO */

	/* Clocks */
	GPIO12_32KHz,

	/* BTUART */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,

	/* TMIO controller */
	GPIO19_GPIO, /* t7l66xb #PCLR */
	GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */

	/* wakeup */
	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
};

/* ---------------------------------------------------------------------- */

static struct mtd_partition partition_a = {
	.name = "Internal NAND flash",
	.offset =  0,
	.size =  MTDPART_SIZ_FULL,
};

static uint8_t scan_ff_pattern[] = { 0xff, 0xff };

static struct nand_bbt_descr e400_t7l66xb_nand_bbt = {
	.options = 0,
	.offs = 4,
	.len = 2,
	.pattern = scan_ff_pattern
};

static struct tmio_nand_data e400_t7l66xb_nand_config = {
	.num_partitions = 1,
	.partition = &partition_a,
	.badblock_pattern = &e400_t7l66xb_nand_bbt,
};

static struct t7l66xb_platform_data e400_t7l66xb_info = {
	.irq_base 		= IRQ_BOARD_START,
	.enable                 = &eseries_tmio_enable,
	.suspend                = &eseries_tmio_suspend,
	.resume                 = &eseries_tmio_resume,

	.nand_data              = &e400_t7l66xb_nand_config,
};

static struct platform_device e400_t7l66xb_device = {
	.name           = "t7l66xb",
	.id             = -1,
	.dev            = {
		.platform_data = &e400_t7l66xb_info,
	},
	.num_resources = 2,
	.resource      = eseries_tmio_resources,
};

/* ---------------------------------------------------------- */

static struct platform_device *e400_devices[] __initdata = {
	&e400_t7l66xb_device,
	&e7xx_gpio_vbus,
};

static void __init e400_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	/* Fixme - e400 may have a switched clock */
	eseries_register_clks();
	eseries_get_tmio_gpios();
	pxa_set_fb_info(NULL, &e400_pxafb_mach_info);
	gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
	platform_add_devices(ARRAY_AND_SIZE(e400_devices));
}

MACHINE_START(E400, "Toshiba e400")
	/* Maintainer: Ian Molton (spyro@f2s.com) */
	.atag_offset	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= ESERIES_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.fixup		= eseries_fixup,
	.init_machine	= e400_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_E740
/* ------------------------ e740 video support --------------------------- */

static struct w100_gen_regs e740_lcd_regs = {
	.lcd_format =            0x00008023,
	.lcdd_cntl1 =            0x0f000000,
	.lcdd_cntl2 =            0x0003ffff,
	.genlcd_cntl1 =          0x00ffff03,
	.genlcd_cntl2 =          0x003c0f03,
	.genlcd_cntl3 =          0x000143aa,
};

static struct w100_mode e740_lcd_mode = {
	.xres            = 240,
	.yres            = 320,
	.left_margin     = 20,
	.right_margin    = 28,
	.upper_margin    = 9,
	.lower_margin    = 8,
	.crtc_ss         = 0x80140013,
	.crtc_ls         = 0x81150110,
	.crtc_gs         = 0x80050005,
	.crtc_vpos_gs    = 0x000a0009,
	.crtc_rev        = 0x0040010a,
	.crtc_dclk       = 0xa906000a,
	.crtc_gclk       = 0x80050108,
	.crtc_goe        = 0x80050108,
	.pll_freq        = 57,
	.pixclk_divider         = 4,
	.pixclk_divider_rotated = 4,
	.pixclk_src     = CLK_SRC_XTAL,
	.sysclk_divider  = 1,
	.sysclk_src     = CLK_SRC_PLL,
	.crtc_ps1_active =       0x41060010,
};

static struct w100_gpio_regs e740_w100_gpio_info = {
	.init_data1 = 0x21002103,
	.gpio_dir1  = 0xffffdeff,
	.gpio_oe1   = 0x03c00643,
	.init_data2 = 0x003f003f,
	.gpio_dir2  = 0xffffffff,
	.gpio_oe2   = 0x000000ff,
};

static struct w100fb_mach_info e740_fb_info = {
	.modelist   = &e740_lcd_mode,
	.num_modes  = 1,
	.regs       = &e740_lcd_regs,
	.gpio       = &e740_w100_gpio_info,
	.xtal_freq = 14318000,
	.xtal_dbl   = 1,
};

static struct resource e740_fb_resources[] = {
	[0] = {
		.start          = 0x0c000000,
		.end            = 0x0cffffff,
		.flags          = IORESOURCE_MEM,
	},
};

static struct platform_device e740_fb_device = {
	.name           = "w100fb",
	.id             = -1,
	.dev            = {
		.platform_data  = &e740_fb_info,
	},
	.num_resources  = ARRAY_SIZE(e740_fb_resources),
	.resource       = e740_fb_resources,
};

/* --------------------------- MFP Pin config -------------------------- */

static unsigned long e740_pin_config[] __initdata = {
	/* Chip selects */
	GPIO15_nCS_1,   /* CS1 - Flash */
	GPIO79_nCS_3,   /* CS3 - IMAGEON */
	GPIO80_nCS_4,   /* CS4 - TMIO */

	/* Clocks */
	GPIO12_32KHz,

	/* BTUART */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,

	/* TMIO controller */
	GPIO19_GPIO, /* t7l66xb #PCLR */
	GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */

	/* UDC */
	GPIO13_GPIO,
	GPIO3_GPIO,

	/* IrDA */
	GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,

	/* AC97 */
	GPIO28_AC97_BITCLK,
	GPIO29_AC97_SDATA_IN_0,
	GPIO30_AC97_SDATA_OUT,
	GPIO31_AC97_SYNC,

	/* Audio power control */
	GPIO16_GPIO,  /* AC97 codec AVDD2 supply (analogue power) */
	GPIO40_GPIO,  /* Mic amp power */
	GPIO41_GPIO,  /* Headphone amp power */

	/* PC Card */
	GPIO8_GPIO,   /* CD0 */
	GPIO44_GPIO,  /* CD1 */
	GPIO11_GPIO,  /* IRQ0 */
	GPIO6_GPIO,   /* IRQ1 */
	GPIO27_GPIO,  /* RST0 */
	GPIO24_GPIO,  /* RST1 */
	GPIO20_GPIO,  /* PWR0 */
	GPIO23_GPIO,  /* PWR1 */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO52_nPCE_1,
	GPIO53_nPCE_2,
	GPIO54_nPSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,

	/* wakeup */
	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
};

/* -------------------- e740 t7l66xb parameters -------------------- */

static struct t7l66xb_platform_data e740_t7l66xb_info = {
	.irq_base 		= IRQ_BOARD_START,
	.enable                 = &eseries_tmio_enable,
	.suspend                = &eseries_tmio_suspend,
	.resume                 = &eseries_tmio_resume,
};

static struct platform_device e740_t7l66xb_device = {
	.name           = "t7l66xb",
	.id             = -1,
	.dev            = {
		.platform_data = &e740_t7l66xb_info,
	},
	.num_resources = 2,
	.resource      = eseries_tmio_resources,
};

static struct platform_device e740_audio_device = {
	.name		= "e740-audio",
	.id		= -1,
};

static struct gpiod_lookup_table e740_audio_gpio_table = {
	.dev_id = "e740-audio",
	.table = {
		GPIO_LOOKUP("gpio-pxa",  GPIO_E740_WM9705_nAVDD2, "Audio power",  GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa",  GPIO_E740_AMP_ON, "Output amp",  GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa",  GPIO_E740_MIC_ON, "Mic amp", GPIO_ACTIVE_HIGH),
		{ },
	},
};

/* ----------------------------------------------------------------------- */

static struct platform_device *e740_devices[] __initdata = {
	&e740_fb_device,
	&e740_t7l66xb_device,
	&e7xx_gpio_vbus,
	&e740_audio_device,
};

static void __init e740_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	eseries_register_clks();
	clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name,
			"UDCCLK", &pxa25x_device_udc.dev),
	eseries_get_tmio_gpios();
	gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
	gpiod_add_lookup_table(&e740_audio_gpio_table);
	platform_add_devices(ARRAY_AND_SIZE(e740_devices));
	pxa_set_ac97_info(NULL);
	pxa_set_ficp_info(&e7xx_ficp_platform_data);
}

MACHINE_START(E740, "Toshiba e740")
	/* Maintainer: Ian Molton (spyro@f2s.com) */
	.atag_offset	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= ESERIES_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.fixup		= eseries_fixup,
	.init_machine	= e740_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_E750
/* ---------------------- E750 LCD definitions -------------------- */

static struct w100_gen_regs e750_lcd_regs = {
	.lcd_format =            0x00008003,
	.lcdd_cntl1 =            0x00000000,
	.lcdd_cntl2 =            0x0003ffff,
	.genlcd_cntl1 =          0x00fff003,
	.genlcd_cntl2 =          0x003c0f03,
	.genlcd_cntl3 =          0x000143aa,
};

static struct w100_mode e750_lcd_mode = {
	.xres            = 240,
	.yres            = 320,
	.left_margin     = 21,
	.right_margin    = 22,
	.upper_margin    = 5,
	.lower_margin    = 4,
	.crtc_ss         = 0x80150014,
	.crtc_ls         = 0x8014000d,
	.crtc_gs         = 0xc1000005,
	.crtc_vpos_gs    = 0x00020147,
	.crtc_rev        = 0x0040010a,
	.crtc_dclk       = 0xa1700030,
	.crtc_gclk       = 0x80cc0015,
	.crtc_goe        = 0x80cc0015,
	.crtc_ps1_active = 0x61060017,
	.pll_freq        = 57,
	.pixclk_divider         = 4,
	.pixclk_divider_rotated = 4,
	.pixclk_src     = CLK_SRC_XTAL,
	.sysclk_divider  = 1,
	.sysclk_src     = CLK_SRC_PLL,
};

static struct w100_gpio_regs e750_w100_gpio_info = {
	.init_data1 = 0x01192f1b,
	.gpio_dir1  = 0xd5ffdeff,
	.gpio_oe1   = 0x000020bf,
	.init_data2 = 0x010f010f,
	.gpio_dir2  = 0xffffffff,
	.gpio_oe2   = 0x000001cf,
};

static struct w100fb_mach_info e750_fb_info = {
	.modelist   = &e750_lcd_mode,
	.num_modes  = 1,
	.regs       = &e750_lcd_regs,
	.gpio       = &e750_w100_gpio_info,
	.xtal_freq  = 14318000,
	.xtal_dbl   = 1,
};

static struct resource e750_fb_resources[] = {
	[0] = {
		.start          = 0x0c000000,
		.end            = 0x0cffffff,
		.flags          = IORESOURCE_MEM,
	},
};

static struct platform_device e750_fb_device = {
	.name           = "w100fb",
	.id             = -1,
	.dev            = {
		.platform_data  = &e750_fb_info,
	},
	.num_resources  = ARRAY_SIZE(e750_fb_resources),
	.resource       = e750_fb_resources,
};

/* -------------------- e750 MFP parameters -------------------- */

static unsigned long e750_pin_config[] __initdata = {
	/* Chip selects */
	GPIO15_nCS_1,   /* CS1 - Flash */
	GPIO79_nCS_3,   /* CS3 - IMAGEON */
	GPIO80_nCS_4,   /* CS4 - TMIO */

	/* Clocks */
	GPIO11_3_6MHz,

	/* BTUART */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,

	/* TMIO controller */
	GPIO19_GPIO, /* t7l66xb #PCLR */
	GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */

	/* UDC */
	GPIO13_GPIO,
	GPIO3_GPIO,

	/* IrDA */
	GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,

	/* AC97 */
	GPIO28_AC97_BITCLK,
	GPIO29_AC97_SDATA_IN_0,
	GPIO30_AC97_SDATA_OUT,
	GPIO31_AC97_SYNC,

	/* Audio power control */
	GPIO4_GPIO,  /* Headphone amp power */
	GPIO7_GPIO,  /* Speaker amp power */
	GPIO37_GPIO, /* Headphone detect */

	/* PC Card */
	GPIO8_GPIO,   /* CD0 */
	GPIO44_GPIO,  /* CD1 */
	/* GPIO11_GPIO,  IRQ0 */
	GPIO6_GPIO,   /* IRQ1 */
	GPIO27_GPIO,  /* RST0 */
	GPIO24_GPIO,  /* RST1 */
	GPIO20_GPIO,  /* PWR0 */
	GPIO23_GPIO,  /* PWR1 */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO52_nPCE_1,
	GPIO53_nPCE_2,
	GPIO54_nPSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,

	/* wakeup */
	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
};

/* ----------------- e750 tc6393xb parameters ------------------ */

static struct tc6393xb_platform_data e750_tc6393xb_info = {
	.irq_base       = IRQ_BOARD_START,
	.scr_pll2cr     = 0x0cc1,
	.scr_gper       = 0,
	.suspend        = &eseries_tmio_suspend,
	.resume         = &eseries_tmio_resume,
	.enable         = &eseries_tmio_enable,
	.disable        = &eseries_tmio_disable,
};

static struct platform_device e750_tc6393xb_device = {
	.name           = "tc6393xb",
	.id             = -1,
	.dev            = {
		.platform_data = &e750_tc6393xb_info,
	},
	.num_resources = 2,
	.resource      = eseries_tmio_resources,
};

static struct gpiod_lookup_table e750_audio_gpio_table = {
	.dev_id = "e750-audio",
	.table = {
		GPIO_LOOKUP("gpio-pxa",  GPIO_E750_HP_AMP_OFF, "Output amp",  GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa",  GPIO_E750_SPK_AMP_OFF, "Mic amp", GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct platform_device e750_audio_device = {
	.name		= "e750-audio",
	.id		= -1,
};

/* ------------------------------------------------------------- */

static struct platform_device *e750_devices[] __initdata = {
	&e750_fb_device,
	&e750_tc6393xb_device,
	&e7xx_gpio_vbus,
	&e750_audio_device,
};

static void __init e750_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e750_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name,
			"GPIO11_CLK", NULL),
	eseries_get_tmio_gpios();
	gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
	gpiod_add_lookup_table(&e750_audio_gpio_table);
	platform_add_devices(ARRAY_AND_SIZE(e750_devices));
	pxa_set_ac97_info(NULL);
	pxa_set_ficp_info(&e7xx_ficp_platform_data);
}

MACHINE_START(E750, "Toshiba e750")
	/* Maintainer: Ian Molton (spyro@f2s.com) */
	.atag_offset	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= ESERIES_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.fixup		= eseries_fixup,
	.init_machine	= e750_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_E800
/* ------------------------ e800 LCD definitions ------------------------- */

static unsigned long e800_pin_config[] __initdata = {
	/* AC97 */
	GPIO28_AC97_BITCLK,
	GPIO29_AC97_SDATA_IN_0,
	GPIO30_AC97_SDATA_OUT,
	GPIO31_AC97_SYNC,

	/* tc6393xb */
	GPIO11_3_6MHz,
};

static struct w100_gen_regs e800_lcd_regs = {
	.lcd_format =            0x00008003,
	.lcdd_cntl1 =            0x02a00000,
	.lcdd_cntl2 =            0x0003ffff,
	.genlcd_cntl1 =          0x000ff2a3,
	.genlcd_cntl2 =          0x000002a3,
	.genlcd_cntl3 =          0x000102aa,
};

static struct w100_mode e800_lcd_mode[2] = {
	[0] = {
		.xres            = 480,
		.yres            = 640,
		.left_margin     = 52,
		.right_margin    = 148,
		.upper_margin    = 2,
		.lower_margin    = 6,
		.crtc_ss         = 0x80350034,
		.crtc_ls         = 0x802b0026,
		.crtc_gs         = 0x80160016,
		.crtc_vpos_gs    = 0x00020003,
		.crtc_rev        = 0x0040001d,
		.crtc_dclk       = 0xe0000000,
		.crtc_gclk       = 0x82a50049,
		.crtc_goe        = 0x80ee001c,
		.crtc_ps1_active = 0x00000000,
		.pll_freq        = 128,
		.pixclk_divider         = 4,
		.pixclk_divider_rotated = 6,
		.pixclk_src     = CLK_SRC_PLL,
		.sysclk_divider  = 0,
		.sysclk_src     = CLK_SRC_PLL,
	},
	[1] = {
		.xres            = 240,
		.yres            = 320,
		.left_margin     = 15,
		.right_margin    = 88,
		.upper_margin    = 0,
		.lower_margin    = 7,
		.crtc_ss         = 0xd010000f,
		.crtc_ls         = 0x80070003,
		.crtc_gs         = 0x80000000,
		.crtc_vpos_gs    = 0x01460147,
		.crtc_rev        = 0x00400003,
		.crtc_dclk       = 0xa1700030,
		.crtc_gclk       = 0x814b0008,
		.crtc_goe        = 0x80cc0015,
		.crtc_ps1_active = 0x00000000,
		.pll_freq        = 100,
		.pixclk_divider         = 6, /* Wince uses 14 which gives a */
		.pixclk_divider_rotated = 6, /* 7MHz Pclk. We use a 14MHz one */
		.pixclk_src     = CLK_SRC_PLL,
		.sysclk_divider  = 0,
		.sysclk_src     = CLK_SRC_PLL,
	}
};

static struct w100_gpio_regs e800_w100_gpio_info = {
	.init_data1 = 0xc13fc019,
	.gpio_dir1  = 0x3e40df7f,
	.gpio_oe1   = 0x003c3000,
	.init_data2 = 0x00000000,
	.gpio_dir2  = 0x00000000,
	.gpio_oe2   = 0x00000000,
};

static struct w100_mem_info e800_w100_mem_info = {
	.ext_cntl        = 0x09640011,
	.sdram_mode_reg  = 0x00600021,
	.ext_timing_cntl = 0x10001545,
	.io_cntl         = 0x7ddd7333,
	.size            = 0x1fffff,
};

static void e800_tg_change(struct w100fb_par *par)
{
	unsigned long tmp;

	tmp = w100fb_gpio_read(W100_GPIO_PORT_A);
	if (par->mode->xres == 480)
		tmp |= 0x100;
	else
		tmp &= ~0x100;
	w100fb_gpio_write(W100_GPIO_PORT_A, tmp);
}

static struct w100_tg_info e800_tg_info = {
	.change = e800_tg_change,
};

static struct w100fb_mach_info e800_fb_info = {
	.modelist   = e800_lcd_mode,
	.num_modes  = 2,
	.regs       = &e800_lcd_regs,
	.gpio       = &e800_w100_gpio_info,
	.mem        = &e800_w100_mem_info,
	.tg         = &e800_tg_info,
	.xtal_freq  = 16000000,
};

static struct resource e800_fb_resources[] = {
	[0] = {
		.start          = 0x0c000000,
		.end            = 0x0cffffff,
		.flags          = IORESOURCE_MEM,
	},
};

static struct platform_device e800_fb_device = {
	.name           = "w100fb",
	.id             = -1,
	.dev            = {
		.platform_data  = &e800_fb_info,
	},
	.num_resources  = ARRAY_SIZE(e800_fb_resources),
	.resource       = e800_fb_resources,
};

/* --------------------------- UDC definitions --------------------------- */

static struct gpiod_lookup_table e800_gpio_vbus_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_E800_USB_DISC,
			    "vbus", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", GPIO_E800_USB_PULLUP,
			    "pullup", GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct platform_device e800_gpio_vbus = {
	.name	= "gpio-vbus",
	.id	= -1,
};

/* ----------------- e800 tc6393xb parameters ------------------ */

static struct tc6393xb_platform_data e800_tc6393xb_info = {
	.irq_base       = IRQ_BOARD_START,
	.scr_pll2cr     = 0x0cc1,
	.scr_gper       = 0,
	.suspend        = &eseries_tmio_suspend,
	.resume         = &eseries_tmio_resume,
	.enable         = &eseries_tmio_enable,
	.disable        = &eseries_tmio_disable,
};

static struct platform_device e800_tc6393xb_device = {
	.name           = "tc6393xb",
	.id             = -1,
	.dev            = {
		.platform_data = &e800_tc6393xb_info,
	},
	.num_resources = 2,
	.resource      = eseries_tmio_resources,
};

static struct gpiod_lookup_table e800_audio_gpio_table = {
	.dev_id = "e800-audio",
	.table = {
		GPIO_LOOKUP("gpio-pxa",  GPIO_E800_HP_AMP_OFF, "Output amp",  GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa",  GPIO_E800_SPK_AMP_ON, "Mic amp", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct platform_device e800_audio_device = {
	.name		= "e800-audio",
	.id		= -1,
};

/* ----------------------------------------------------------------------- */

static struct platform_device *e800_devices[] __initdata = {
	&e800_fb_device,
	&e800_tc6393xb_device,
	&e800_gpio_vbus,
	&e800_audio_device,
};

static void __init e800_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e800_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name,
			"GPIO11_CLK", NULL),
	eseries_get_tmio_gpios();
	gpiod_add_lookup_table(&e800_gpio_vbus_gpiod_table);
	gpiod_add_lookup_table(&e800_audio_gpio_table);
	platform_add_devices(ARRAY_AND_SIZE(e800_devices));
	pxa_set_ac97_info(NULL);
}

MACHINE_START(E800, "Toshiba e800")
	/* Maintainer: Ian Molton (spyro@f2s.com) */
	.atag_offset	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= ESERIES_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.fixup		= eseries_fixup,
	.init_machine	= e800_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END
#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  ezx.c - Common code for the EZX platform.
 *
 *  Copyright (C) 2005-2006 Harald Welte <laforge@openezx.org>,
 *		  2007-2008 Daniel Ribeiro <drwyrm@gmail.com>,
 *		  2007-2008 Stefan Schmidt <stefan@datenfreihafen.org>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/gpio_keys.h>
#include <linux/leds-lp3944.h>
#include <linux/platform_data/i2c-pxa.h>

#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>

#include "pxa27x.h"
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include <linux/platform_data/media/camera-pxa.h>

#include "devices.h"
#include "generic.h"

#define EZX_NR_IRQS			(IRQ_BOARD_START + 24)

#define GPIO12_A780_FLIP_LID 		12
#define GPIO15_A1200_FLIP_LID 		15
#define GPIO15_A910_FLIP_LID 		15
#define GPIO12_E680_LOCK_SWITCH 	12
#define GPIO15_E6_LOCK_SWITCH 		15
#define GPIO50_nCAM_EN			50
#define GPIO19_GEN1_CAM_RST		19
#define GPIO28_GEN2_CAM_RST		28

static struct pwm_lookup ezx_pwm_lookup[] __maybe_unused = {
	PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78700,
		   PWM_POLARITY_NORMAL),
};

static struct platform_pwm_backlight_data ezx_backlight_data = {
	.max_brightness	= 1023,
	.dft_brightness	= 1023,
};

static struct platform_device ezx_backlight_device = {
	.name		= "pwm-backlight",
	.dev		= {
		.parent	= &pxa27x_device_pwm0.dev,
		.platform_data = &ezx_backlight_data,
	},
};

static struct pxafb_mode_info mode_ezx_old = {
	.pixclock		= 150000,
	.xres			= 240,
	.yres			= 320,
	.bpp			= 16,
	.hsync_len		= 10,
	.left_margin		= 20,
	.right_margin		= 10,
	.vsync_len		= 2,
	.upper_margin		= 3,
	.lower_margin		= 2,
	.sync			= 0,
};

static struct pxafb_mach_info ezx_fb_info_1 __maybe_unused = {
	.modes		= &mode_ezx_old,
	.num_modes	= 1,
	.lcd_conn	= LCD_COLOR_TFT_16BPP,
};

static struct pxafb_mode_info mode_72r89803y01 = {
	.pixclock		= 192308,
	.xres			= 240,
	.yres			= 320,
	.bpp			= 32,
	.depth			= 18,
	.hsync_len		= 10,
	.left_margin		= 20,
	.right_margin		= 10,
	.vsync_len		= 2,
	.upper_margin		= 3,
	.lower_margin		= 2,
	.sync			= 0,
};

static struct pxafb_mach_info ezx_fb_info_2 __maybe_unused = {
	.modes		= &mode_72r89803y01,
	.num_modes	= 1,
	.lcd_conn	= LCD_COLOR_TFT_18BPP,
};

static struct platform_device *ezx_devices[] __initdata __maybe_unused = {
	&ezx_backlight_device,
};

static unsigned long ezx_pin_config[] __initdata __maybe_unused = {
	/* PWM backlight */
	GPIO16_PWM0_OUT,

	/* BTUART */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,
	GPIO45_BTUART_RTS,

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

	/* PCAP SSP */
	GPIO29_SSP1_SCLK,
	GPIO25_SSP1_TXD,
	GPIO26_SSP1_RXD,
	GPIO24_GPIO,				/* pcap chip select */
	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,	/* pcap interrupt */
	GPIO4_GPIO | MFP_LPM_DRIVE_HIGH,	/* WDI_AP */
	GPIO55_GPIO | MFP_LPM_DRIVE_HIGH,	/* SYS_RESTART */

	/* MMC */
	GPIO32_MMC_CLK,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	GPIO112_MMC_CMD,
	GPIO11_GPIO,				/* mmc detect */

	/* usb to external transceiver */
	GPIO34_USB_P2_2,
	GPIO35_USB_P2_1,
	GPIO36_USB_P2_4,
	GPIO39_USB_P2_6,
	GPIO40_USB_P2_5,
	GPIO53_USB_P2_3,

	/* usb to Neptune GSM chip */
	GPIO30_USB_P3_2,
	GPIO31_USB_P3_6,
	GPIO90_USB_P3_5,
	GPIO91_USB_P3_1,
	GPIO56_USB_P3_4,
	GPIO113_USB_P3_3,
};

#if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680)
static unsigned long gen1_pin_config[] __initdata = {
	/* flip / lockswitch */
	GPIO12_GPIO | WAKEUP_ON_EDGE_BOTH,

	/* bluetooth (bcm2035) */
	GPIO14_GPIO | WAKEUP_ON_EDGE_RISE,	/* HOSTWAKE */
	GPIO48_GPIO,				/* RESET */
	GPIO28_GPIO,				/* WAKEUP */

	/* Neptune handshake */
	GPIO0_GPIO | WAKEUP_ON_EDGE_FALL,	/* BP_RDY */
	GPIO57_GPIO | MFP_LPM_DRIVE_HIGH,	/* AP_RDY */
	GPIO13_GPIO | WAKEUP_ON_EDGE_BOTH,	/* WDI */
	GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH,	/* WDI2 */
	GPIO82_GPIO | MFP_LPM_DRIVE_HIGH,	/* RESET */
	GPIO99_GPIO | MFP_LPM_DRIVE_HIGH,	/* TC_MM_EN */

	/* sound */
	GPIO52_SSP3_SCLK,
	GPIO83_SSP3_SFRM,
	GPIO81_SSP3_TXD,
	GPIO89_SSP3_RXD,

	/* ssp2 pins to in */
	GPIO22_GPIO,				/* SSP2_SCLK */
	GPIO37_GPIO,				/* SSP2_SFRM */
	GPIO38_GPIO,				/* SSP2_TXD */
	GPIO88_GPIO,				/* SSP2_RXD */

	/* camera */
	GPIO23_CIF_MCLK,
	GPIO54_CIF_PCLK,
	GPIO85_CIF_LV,
	GPIO84_CIF_FV,
	GPIO27_CIF_DD_0,
	GPIO114_CIF_DD_1,
	GPIO51_CIF_DD_2,
	GPIO115_CIF_DD_3,
	GPIO95_CIF_DD_4,
	GPIO94_CIF_DD_5,
	GPIO17_CIF_DD_6,
	GPIO108_CIF_DD_7,
	GPIO50_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_EN */
	GPIO19_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_RST */

	/* EMU */
	GPIO120_GPIO,				/* EMU_MUX1 */
	GPIO119_GPIO,				/* EMU_MUX2 */
	GPIO86_GPIO,				/* SNP_INT_CTL */
	GPIO87_GPIO,				/* SNP_INT_IN */
};
#endif

#if defined(CONFIG_MACH_EZX_A1200) || defined(CONFIG_MACH_EZX_A910) || \
	defined(CONFIG_MACH_EZX_E2) || defined(CONFIG_MACH_EZX_E6)
static unsigned long gen2_pin_config[] __initdata = {
	/* flip / lockswitch */
	GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,

	/* EOC */
	GPIO10_GPIO | WAKEUP_ON_EDGE_RISE,

	/* bluetooth (bcm2045) */
	GPIO13_GPIO | WAKEUP_ON_EDGE_RISE,	/* HOSTWAKE */
	GPIO37_GPIO,				/* RESET */
	GPIO57_GPIO,				/* WAKEUP */

	/* Neptune handshake */
	GPIO0_GPIO | WAKEUP_ON_EDGE_FALL,	/* BP_RDY */
	GPIO96_GPIO | MFP_LPM_DRIVE_HIGH,	/* AP_RDY */
	GPIO3_GPIO | WAKEUP_ON_EDGE_FALL,	/* WDI */
	GPIO116_GPIO | MFP_LPM_DRIVE_HIGH,	/* RESET */
	GPIO41_GPIO,				/* BP_FLASH */

	/* sound */
	GPIO52_SSP3_SCLK,
	GPIO83_SSP3_SFRM,
	GPIO81_SSP3_TXD,
	GPIO82_SSP3_RXD,

	/* ssp2 pins to in */
	GPIO22_GPIO,				/* SSP2_SCLK */
	GPIO14_GPIO,				/* SSP2_SFRM */
	GPIO38_GPIO,				/* SSP2_TXD */
	GPIO88_GPIO,				/* SSP2_RXD */

	/* camera */
	GPIO23_CIF_MCLK,
	GPIO54_CIF_PCLK,
	GPIO85_CIF_LV,
	GPIO84_CIF_FV,
	GPIO27_CIF_DD_0,
	GPIO114_CIF_DD_1,
	GPIO51_CIF_DD_2,
	GPIO115_CIF_DD_3,
	GPIO95_CIF_DD_4,
	GPIO48_CIF_DD_5,
	GPIO93_CIF_DD_6,
	GPIO12_CIF_DD_7,
	GPIO50_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_EN */
	GPIO28_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_RST */
	GPIO17_GPIO,				/* CAM_FLASH */
};
#endif

#ifdef CONFIG_MACH_EZX_A780
static unsigned long a780_pin_config[] __initdata = {
	/* keypad */
	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,
	GPIO107_KP_MKOUT_4,

	/* attenuate sound */
	GPIO96_GPIO,
};
#endif

#ifdef CONFIG_MACH_EZX_E680
static unsigned long e680_pin_config[] __initdata = {
	/* keypad */
	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO96_KP_DKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_DKIN_4 | WAKEUP_ON_LEVEL_HIGH,
	GPIO98_KP_DKIN_5 | WAKEUP_ON_LEVEL_HIGH,
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,

	/* MIDI */
	GPIO79_GPIO,				/* VA_SEL_BUL */
	GPIO80_GPIO,				/* FLT_SEL_BUL */
	GPIO78_GPIO,				/* MIDI_RESET */
	GPIO33_GPIO,				/* MIDI_CS */
	GPIO15_GPIO,				/* MIDI_IRQ */
	GPIO49_GPIO,				/* MIDI_NPWE */
	GPIO18_GPIO,				/* MIDI_RDY */

	/* leds */
	GPIO46_GPIO,
	GPIO47_GPIO,
};
#endif

#ifdef CONFIG_MACH_EZX_A1200
static unsigned long a1200_pin_config[] __initdata = {
	/* keypad */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,
	GPIO107_KP_MKOUT_4,
	GPIO108_KP_MKOUT_5,
};
#endif

#ifdef CONFIG_MACH_EZX_A910
static unsigned long a910_pin_config[] __initdata = {
	/* keypad */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,
	GPIO107_KP_MKOUT_4,
	GPIO108_KP_MKOUT_5,

	/* WLAN */
	GPIO89_GPIO,				/* RESET */
	GPIO33_GPIO,				/* WAKEUP */
	GPIO94_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* HOSTWAKE */

	/* MMC CS */
	GPIO20_GPIO,
};
#endif

#ifdef CONFIG_MACH_EZX_E2
static unsigned long e2_pin_config[] __initdata = {
	/* keypad */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,
	GPIO107_KP_MKOUT_4,
	GPIO108_KP_MKOUT_5,
};
#endif

#ifdef CONFIG_MACH_EZX_E6
static unsigned long e6_pin_config[] __initdata = {
	/* keypad */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,
	GPIO107_KP_MKOUT_4,
	GPIO108_KP_MKOUT_5,
};
#endif

/* KEYPAD */
#ifdef CONFIG_MACH_EZX_A780
static const unsigned int a780_key_map[] = {
	KEY(0, 0, KEY_SEND),
	KEY(0, 1, KEY_BACK),
	KEY(0, 2, KEY_END),
	KEY(0, 3, KEY_PAGEUP),
	KEY(0, 4, KEY_UP),

	KEY(1, 0, KEY_NUMERIC_1),
	KEY(1, 1, KEY_NUMERIC_2),
	KEY(1, 2, KEY_NUMERIC_3),
	KEY(1, 3, KEY_SELECT),
	KEY(1, 4, KEY_KPENTER),

	KEY(2, 0, KEY_NUMERIC_4),
	KEY(2, 1, KEY_NUMERIC_5),
	KEY(2, 2, KEY_NUMERIC_6),
	KEY(2, 3, KEY_RECORD),
	KEY(2, 4, KEY_LEFT),

	KEY(3, 0, KEY_NUMERIC_7),
	KEY(3, 1, KEY_NUMERIC_8),
	KEY(3, 2, KEY_NUMERIC_9),
	KEY(3, 3, KEY_HOME),
	KEY(3, 4, KEY_RIGHT),

	KEY(4, 0, KEY_NUMERIC_STAR),
	KEY(4, 1, KEY_NUMERIC_0),
	KEY(4, 2, KEY_NUMERIC_POUND),
	KEY(4, 3, KEY_PAGEDOWN),
	KEY(4, 4, KEY_DOWN),
};

static struct matrix_keymap_data a780_matrix_keymap_data = {
	.keymap			= a780_key_map,
	.keymap_size		= ARRAY_SIZE(a780_key_map),
};

static struct pxa27x_keypad_platform_data a780_keypad_platform_data = {
	.matrix_key_rows = 5,
	.matrix_key_cols = 5,
	.matrix_keymap_data = &a780_matrix_keymap_data,

	.direct_key_map = { KEY_CAMERA },
	.direct_key_num = 1,

	.debounce_interval = 30,
};
#endif /* CONFIG_MACH_EZX_A780 */

#ifdef CONFIG_MACH_EZX_E680
static const unsigned int e680_key_map[] = {
	KEY(0, 0, KEY_UP),
	KEY(0, 1, KEY_RIGHT),
	KEY(0, 2, KEY_RESERVED),
	KEY(0, 3, KEY_SEND),

	KEY(1, 0, KEY_DOWN),
	KEY(1, 1, KEY_LEFT),
	KEY(1, 2, KEY_PAGEUP),
	KEY(1, 3, KEY_PAGEDOWN),

	KEY(2, 0, KEY_RESERVED),
	KEY(2, 1, KEY_RESERVED),
	KEY(2, 2, KEY_RESERVED),
	KEY(2, 3, KEY_KPENTER),
};

static struct matrix_keymap_data e680_matrix_keymap_data = {
	.keymap			= e680_key_map,
	.keymap_size		= ARRAY_SIZE(e680_key_map),
};

static struct pxa27x_keypad_platform_data e680_keypad_platform_data = {
	.matrix_key_rows = 3,
	.matrix_key_cols = 4,
	.matrix_keymap_data = &e680_matrix_keymap_data,

	.direct_key_map = {
		KEY_CAMERA,
		KEY_RESERVED,
		KEY_RESERVED,
		KEY_F1,
		KEY_CANCEL,
		KEY_F2,
	},
	.direct_key_num = 6,

	.debounce_interval = 30,
};
#endif /* CONFIG_MACH_EZX_E680 */

#ifdef CONFIG_MACH_EZX_A1200
static const unsigned int a1200_key_map[] = {
	KEY(0, 0, KEY_RESERVED),
	KEY(0, 1, KEY_RIGHT),
	KEY(0, 2, KEY_PAGEDOWN),
	KEY(0, 3, KEY_RESERVED),
	KEY(0, 4, KEY_RESERVED),
	KEY(0, 5, KEY_RESERVED),

	KEY(1, 0, KEY_RESERVED),
	KEY(1, 1, KEY_DOWN),
	KEY(1, 2, KEY_CAMERA),
	KEY(1, 3, KEY_RESERVED),
	KEY(1, 4, KEY_RESERVED),
	KEY(1, 5, KEY_RESERVED),

	KEY(2, 0, KEY_RESERVED),
	KEY(2, 1, KEY_KPENTER),
	KEY(2, 2, KEY_RECORD),
	KEY(2, 3, KEY_RESERVED),
	KEY(2, 4, KEY_RESERVED),
	KEY(2, 5, KEY_SELECT),

	KEY(3, 0, KEY_RESERVED),
	KEY(3, 1, KEY_UP),
	KEY(3, 2, KEY_SEND),
	KEY(3, 3, KEY_RESERVED),
	KEY(3, 4, KEY_RESERVED),
	KEY(3, 5, KEY_RESERVED),

	KEY(4, 0, KEY_RESERVED),
	KEY(4, 1, KEY_LEFT),
	KEY(4, 2, KEY_PAGEUP),
	KEY(4, 3, KEY_RESERVED),
	KEY(4, 4, KEY_RESERVED),
	KEY(4, 5, KEY_RESERVED),
};

static struct matrix_keymap_data a1200_matrix_keymap_data = {
	.keymap			= a1200_key_map,
	.keymap_size		= ARRAY_SIZE(a1200_key_map),
};

static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = {
	.matrix_key_rows = 5,
	.matrix_key_cols = 6,
	.matrix_keymap_data = &a1200_matrix_keymap_data,

	.debounce_interval = 30,
};
#endif /* CONFIG_MACH_EZX_A1200 */

#ifdef CONFIG_MACH_EZX_E6
static const unsigned int e6_key_map[] = {
	KEY(0, 0, KEY_RESERVED),
	KEY(0, 1, KEY_RIGHT),
	KEY(0, 2, KEY_PAGEDOWN),
	KEY(0, 3, KEY_RESERVED),
	KEY(0, 4, KEY_RESERVED),
	KEY(0, 5, KEY_NEXTSONG),

	KEY(1, 0, KEY_RESERVED),
	KEY(1, 1, KEY_DOWN),
	KEY(1, 2, KEY_PROG1),
	KEY(1, 3, KEY_RESERVED),
	KEY(1, 4, KEY_RESERVED),
	KEY(1, 5, KEY_RESERVED),

	KEY(2, 0, KEY_RESERVED),
	KEY(2, 1, KEY_ENTER),
	KEY(2, 2, KEY_CAMERA),
	KEY(2, 3, KEY_RESERVED),
	KEY(2, 4, KEY_RESERVED),
	KEY(2, 5, KEY_WWW),

	KEY(3, 0, KEY_RESERVED),
	KEY(3, 1, KEY_UP),
	KEY(3, 2, KEY_SEND),
	KEY(3, 3, KEY_RESERVED),
	KEY(3, 4, KEY_RESERVED),
	KEY(3, 5, KEY_PLAYPAUSE),

	KEY(4, 0, KEY_RESERVED),
	KEY(4, 1, KEY_LEFT),
	KEY(4, 2, KEY_PAGEUP),
	KEY(4, 3, KEY_RESERVED),
	KEY(4, 4, KEY_RESERVED),
	KEY(4, 5, KEY_PREVIOUSSONG),
};

static struct matrix_keymap_data e6_keymap_data = {
	.keymap			= e6_key_map,
	.keymap_size		= ARRAY_SIZE(e6_key_map),
};

static struct pxa27x_keypad_platform_data e6_keypad_platform_data = {
	.matrix_key_rows = 5,
	.matrix_key_cols = 6,
	.matrix_keymap_data = &e6_keymap_data,

	.debounce_interval = 30,
};
#endif /* CONFIG_MACH_EZX_E6 */

#ifdef CONFIG_MACH_EZX_A910
static const unsigned int a910_key_map[] = {
	KEY(0, 0, KEY_NUMERIC_6),
	KEY(0, 1, KEY_RIGHT),
	KEY(0, 2, KEY_PAGEDOWN),
	KEY(0, 3, KEY_KPENTER),
	KEY(0, 4, KEY_NUMERIC_5),
	KEY(0, 5, KEY_CAMERA),

	KEY(1, 0, KEY_NUMERIC_8),
	KEY(1, 1, KEY_DOWN),
	KEY(1, 2, KEY_RESERVED),
	KEY(1, 3, KEY_F1), /* Left SoftKey */
	KEY(1, 4, KEY_NUMERIC_STAR),
	KEY(1, 5, KEY_RESERVED),

	KEY(2, 0, KEY_NUMERIC_7),
	KEY(2, 1, KEY_NUMERIC_9),
	KEY(2, 2, KEY_RECORD),
	KEY(2, 3, KEY_F2), /* Right SoftKey */
	KEY(2, 4, KEY_BACK),
	KEY(2, 5, KEY_SELECT),

	KEY(3, 0, KEY_NUMERIC_2),
	KEY(3, 1, KEY_UP),
	KEY(3, 2, KEY_SEND),
	KEY(3, 3, KEY_NUMERIC_0),
	KEY(3, 4, KEY_NUMERIC_1),
	KEY(3, 5, KEY_RECORD),

	KEY(4, 0, KEY_NUMERIC_4),
	KEY(4, 1, KEY_LEFT),
	KEY(4, 2, KEY_PAGEUP),
	KEY(4, 3, KEY_NUMERIC_POUND),
	KEY(4, 4, KEY_NUMERIC_3),
	KEY(4, 5, KEY_RESERVED),
};

static struct matrix_keymap_data a910_matrix_keymap_data = {
	.keymap			= a910_key_map,
	.keymap_size		= ARRAY_SIZE(a910_key_map),
};

static struct pxa27x_keypad_platform_data a910_keypad_platform_data = {
	.matrix_key_rows = 5,
	.matrix_key_cols = 6,
	.matrix_keymap_data = &a910_matrix_keymap_data,

	.debounce_interval = 30,
};
#endif /* CONFIG_MACH_EZX_A910 */

#ifdef CONFIG_MACH_EZX_E2
static const unsigned int e2_key_map[] = {
	KEY(0, 0, KEY_NUMERIC_6),
	KEY(0, 1, KEY_RIGHT),
	KEY(0, 2, KEY_NUMERIC_9),
	KEY(0, 3, KEY_NEXTSONG),
	KEY(0, 4, KEY_NUMERIC_5),
	KEY(0, 5, KEY_F1), /* Left SoftKey */

	KEY(1, 0, KEY_NUMERIC_8),
	KEY(1, 1, KEY_DOWN),
	KEY(1, 2, KEY_RESERVED),
	KEY(1, 3, KEY_PAGEUP),
	KEY(1, 4, KEY_NUMERIC_STAR),
	KEY(1, 5, KEY_F2), /* Right SoftKey */

	KEY(2, 0, KEY_NUMERIC_7),
	KEY(2, 1, KEY_KPENTER),
	KEY(2, 2, KEY_RECORD),
	KEY(2, 3, KEY_PAGEDOWN),
	KEY(2, 4, KEY_BACK),
	KEY(2, 5, KEY_NUMERIC_0),

	KEY(3, 0, KEY_NUMERIC_2),
	KEY(3, 1, KEY_UP),
	KEY(3, 2, KEY_SEND),
	KEY(3, 3, KEY_PLAYPAUSE),
	KEY(3, 4, KEY_NUMERIC_1),
	KEY(3, 5, KEY_SOUND), /* Music SoftKey */

	KEY(4, 0, KEY_NUMERIC_4),
	KEY(4, 1, KEY_LEFT),
	KEY(4, 2, KEY_NUMERIC_POUND),
	KEY(4, 3, KEY_PREVIOUSSONG),
	KEY(4, 4, KEY_NUMERIC_3),
	KEY(4, 5, KEY_RESERVED),
};

static struct matrix_keymap_data e2_matrix_keymap_data = {
	.keymap			= e2_key_map,
	.keymap_size		= ARRAY_SIZE(e2_key_map),
};

static struct pxa27x_keypad_platform_data e2_keypad_platform_data = {
	.matrix_key_rows = 5,
	.matrix_key_cols = 6,
	.matrix_keymap_data = &e2_matrix_keymap_data,

	.debounce_interval = 30,
};
#endif /* CONFIG_MACH_EZX_E2 */

#if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_A910)
/* camera */
static struct regulator_consumer_supply camera_regulator_supplies[] = {
	REGULATOR_SUPPLY("vdd", "0-005d"),
};

static struct regulator_init_data camera_regulator_initdata = {
	.consumer_supplies = camera_regulator_supplies,
	.num_consumer_supplies = ARRAY_SIZE(camera_regulator_supplies),
	.constraints = {
		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
	},
};

static struct fixed_voltage_config camera_regulator_config = {
	.supply_name		= "camera_vdd",
	.microvolts		= 2800000,
	.init_data		= &camera_regulator_initdata,
};

static struct platform_device camera_supply_regulator_device = {
	.name	= "reg-fixed-voltage",
	.id	= 1,
	.dev	= {
		.platform_data = &camera_regulator_config,
	},
};

static struct gpiod_lookup_table camera_supply_gpiod_table = {
	.dev_id = "reg-fixed-voltage.1",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO50_nCAM_EN,
			    NULL, GPIO_ACTIVE_LOW),
		{ },
	},
};
#endif

#ifdef CONFIG_MACH_EZX_A780
/* gpio_keys */
static struct gpio_keys_button a780_buttons[] = {
	[0] = {
		.code       = SW_LID,
		.gpio       = GPIO12_A780_FLIP_LID,
		.active_low = 0,
		.desc       = "A780 flip lid",
		.type       = EV_SW,
		.wakeup     = 1,
	},
};

static struct gpio_keys_platform_data a780_gpio_keys_platform_data = {
	.buttons  = a780_buttons,
	.nbuttons = ARRAY_SIZE(a780_buttons),
};

static struct platform_device a780_gpio_keys = {
	.name = "gpio-keys",
	.id   = -1,
	.dev  = {
		.platform_data = &a780_gpio_keys_platform_data,
	},
};

/* camera */
static int a780_camera_reset(struct device *dev)
{
	gpio_set_value(GPIO19_GEN1_CAM_RST, 0);
	msleep(10);
	gpio_set_value(GPIO19_GEN1_CAM_RST, 1);

	return 0;
}

static int a780_camera_init(void)
{
	int err;

	/*
	 * GPIO50_nCAM_EN is active low
	 * GPIO19_GEN1_CAM_RST is active on rising edge
	 */
	err = gpio_request(GPIO19_GEN1_CAM_RST, "CAM_RST");
	if (err) {
		pr_err("%s: Failed to request CAM_RST\n", __func__);
		return err;
	}

	gpio_direction_output(GPIO19_GEN1_CAM_RST, 0);
	a780_camera_reset(NULL);

	return 0;
}

struct pxacamera_platform_data a780_pxacamera_platform_data = {
	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN |
		PXA_CAMERA_PCP,
	.mclk_10khz = 5000,
	.sensor_i2c_adapter_id = 0,
	.sensor_i2c_address = 0x5d,
};

static struct i2c_board_info a780_i2c_board_info[] = {
	{
		I2C_BOARD_INFO("mt9m111", 0x5d),
	},
};

static struct platform_device *a780_devices[] __initdata = {
	&a780_gpio_keys,
	&camera_supply_regulator_device,
};

static void __init a780_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(a780_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(a780_i2c_board_info));

	pxa_set_fb_info(NULL, &ezx_fb_info_1);

	pxa_set_keypad_info(&a780_keypad_platform_data);

	if (a780_camera_init() == 0)
		pxa_set_camera_info(&a780_pxacamera_platform_data);

	gpiod_add_lookup_table(&camera_supply_gpiod_table);
	pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
	platform_add_devices(ARRAY_AND_SIZE(a780_devices));
	regulator_has_full_constraints();
}

MACHINE_START(EZX_A780, "Motorola EZX A780")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.nr_irqs	= EZX_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = a780_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_EZX_E680
/* gpio_keys */
static struct gpio_keys_button e680_buttons[] = {
	[0] = {
		.code       = KEY_SCREENLOCK,
		.gpio       = GPIO12_E680_LOCK_SWITCH,
		.active_low = 0,
		.desc       = "E680 lock switch",
		.type       = EV_KEY,
		.wakeup     = 1,
	},
};

static struct gpio_keys_platform_data e680_gpio_keys_platform_data = {
	.buttons  = e680_buttons,
	.nbuttons = ARRAY_SIZE(e680_buttons),
};

static struct platform_device e680_gpio_keys = {
	.name = "gpio-keys",
	.id   = -1,
	.dev  = {
		.platform_data = &e680_gpio_keys_platform_data,
	},
};

static struct i2c_board_info __initdata e680_i2c_board_info[] = {
	{ I2C_BOARD_INFO("tea5767", 0x81) },
};

static struct platform_device *e680_devices[] __initdata = {
	&e680_gpio_keys,
};

static void __init e680_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e680_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));

	pxa_set_fb_info(NULL, &ezx_fb_info_1);

	pxa_set_keypad_info(&e680_keypad_platform_data);

	pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
	platform_add_devices(ARRAY_AND_SIZE(e680_devices));
}

MACHINE_START(EZX_E680, "Motorola EZX E680")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.nr_irqs	= EZX_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = e680_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_EZX_A1200
/* gpio_keys */
static struct gpio_keys_button a1200_buttons[] = {
	[0] = {
		.code       = SW_LID,
		.gpio       = GPIO15_A1200_FLIP_LID,
		.active_low = 0,
		.desc       = "A1200 flip lid",
		.type       = EV_SW,
		.wakeup     = 1,
	},
};

static struct gpio_keys_platform_data a1200_gpio_keys_platform_data = {
	.buttons  = a1200_buttons,
	.nbuttons = ARRAY_SIZE(a1200_buttons),
};

static struct platform_device a1200_gpio_keys = {
	.name = "gpio-keys",
	.id   = -1,
	.dev  = {
		.platform_data = &a1200_gpio_keys_platform_data,
	},
};

static struct i2c_board_info __initdata a1200_i2c_board_info[] = {
	{ I2C_BOARD_INFO("tea5767", 0x81) },
};

static struct platform_device *a1200_devices[] __initdata = {
	&a1200_gpio_keys,
};

static void __init a1200_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(a1200_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));

	pxa_set_fb_info(NULL, &ezx_fb_info_2);

	pxa_set_keypad_info(&a1200_keypad_platform_data);

	pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
	platform_add_devices(ARRAY_AND_SIZE(a1200_devices));
}

MACHINE_START(EZX_A1200, "Motorola EZX A1200")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.nr_irqs	= EZX_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = a1200_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_EZX_A910
/* gpio_keys */
static struct gpio_keys_button a910_buttons[] = {
	[0] = {
		.code       = SW_LID,
		.gpio       = GPIO15_A910_FLIP_LID,
		.active_low = 0,
		.desc       = "A910 flip lid",
		.type       = EV_SW,
		.wakeup     = 1,
	},
};

static struct gpio_keys_platform_data a910_gpio_keys_platform_data = {
	.buttons  = a910_buttons,
	.nbuttons = ARRAY_SIZE(a910_buttons),
};

static struct platform_device a910_gpio_keys = {
	.name = "gpio-keys",
	.id   = -1,
	.dev  = {
		.platform_data = &a910_gpio_keys_platform_data,
	},
};

/* camera */
static int a910_camera_reset(struct device *dev)
{
	gpio_set_value(GPIO28_GEN2_CAM_RST, 0);
	msleep(10);
	gpio_set_value(GPIO28_GEN2_CAM_RST, 1);

	return 0;
}

static int a910_camera_init(void)
{
	int err;

	/*
	 * GPIO50_nCAM_EN is active low
	 * GPIO28_GEN2_CAM_RST is active on rising edge
	 */
	err = gpio_request(GPIO28_GEN2_CAM_RST, "CAM_RST");
	if (err) {
		pr_err("%s: Failed to request CAM_RST\n", __func__);
		return err;
	}

	gpio_direction_output(GPIO28_GEN2_CAM_RST, 0);
	a910_camera_reset(NULL);

	return 0;
}

struct pxacamera_platform_data a910_pxacamera_platform_data = {
	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN |
		PXA_CAMERA_PCP,
	.mclk_10khz = 5000,
	.sensor_i2c_adapter_id = 0,
	.sensor_i2c_address = 0x5d,
};

/* leds-lp3944 */
static struct lp3944_platform_data a910_lp3944_leds = {
	.leds_size = LP3944_LEDS_MAX,
	.leds = {
		[0] = {
			.name = "a910:red:",
			.status = LP3944_LED_STATUS_OFF,
			.type = LP3944_LED_TYPE_LED,
		},
		[1] = {
			.name = "a910:green:",
			.status = LP3944_LED_STATUS_OFF,
			.type = LP3944_LED_TYPE_LED,
		},
		[2] {
			.name = "a910:blue:",
			.status = LP3944_LED_STATUS_OFF,
			.type = LP3944_LED_TYPE_LED,
		},
		/* Leds 3 and 4 are used as display power switches */
		[3] = {
			.name = "a910::cli_display",
			.status = LP3944_LED_STATUS_OFF,
			.type = LP3944_LED_TYPE_LED_INVERTED
		},
		[4] = {
			.name = "a910::main_display",
			.status = LP3944_LED_STATUS_ON,
			.type = LP3944_LED_TYPE_LED_INVERTED
		},
		[5] = { .type = LP3944_LED_TYPE_NONE },
		[6] = {
			.name = "a910::torch",
			.status = LP3944_LED_STATUS_OFF,
			.type = LP3944_LED_TYPE_LED,
		},
		[7] = {
			.name = "a910::flash",
			.status = LP3944_LED_STATUS_OFF,
			.type = LP3944_LED_TYPE_LED_INVERTED,
		},
	},
};

static struct i2c_board_info __initdata a910_i2c_board_info[] = {
	{
		I2C_BOARD_INFO("lp3944", 0x60),
		.platform_data = &a910_lp3944_leds,
	},
	{
		I2C_BOARD_INFO("mt9m111", 0x5d),
	},
};

static struct platform_device *a910_devices[] __initdata = {
	&a910_gpio_keys,
	&camera_supply_regulator_device,
};

static void __init a910_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(a910_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));

	pxa_set_fb_info(NULL, &ezx_fb_info_2);

	pxa_set_keypad_info(&a910_keypad_platform_data);

	if (a910_camera_init() == 0)
		pxa_set_camera_info(&a910_pxacamera_platform_data);

	gpiod_add_lookup_table(&camera_supply_gpiod_table);
	pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
	platform_add_devices(ARRAY_AND_SIZE(a910_devices));
	regulator_has_full_constraints();
}

MACHINE_START(EZX_A910, "Motorola EZX A910")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.nr_irqs	= EZX_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = a910_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_EZX_E6
/* gpio_keys */
static struct gpio_keys_button e6_buttons[] = {
	[0] = {
		.code       = KEY_SCREENLOCK,
		.gpio       = GPIO15_E6_LOCK_SWITCH,
		.active_low = 0,
		.desc       = "E6 lock switch",
		.type       = EV_KEY,
		.wakeup     = 1,
	},
};

static struct gpio_keys_platform_data e6_gpio_keys_platform_data = {
	.buttons  = e6_buttons,
	.nbuttons = ARRAY_SIZE(e6_buttons),
};

static struct platform_device e6_gpio_keys = {
	.name = "gpio-keys",
	.id   = -1,
	.dev  = {
		.platform_data = &e6_gpio_keys_platform_data,
	},
};

static struct i2c_board_info __initdata e6_i2c_board_info[] = {
	{ I2C_BOARD_INFO("tea5767", 0x81) },
};

static struct platform_device *e6_devices[] __initdata = {
	&e6_gpio_keys,
};

static void __init e6_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e6_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));

	pxa_set_fb_info(NULL, &ezx_fb_info_2);

	pxa_set_keypad_info(&e6_keypad_platform_data);

	pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
	platform_add_devices(ARRAY_AND_SIZE(e6_devices));
}

MACHINE_START(EZX_E6, "Motorola EZX E6")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.nr_irqs	= EZX_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = e6_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_EZX_E2
static struct i2c_board_info __initdata e2_i2c_board_info[] = {
	{ I2C_BOARD_INFO("tea5767", 0x81) },
};

static struct platform_device *e2_devices[] __initdata = {
};

static void __init e2_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
	pxa2xx_mfp_config(ARRAY_AND_SIZE(e2_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));

	pxa_set_fb_info(NULL, &ezx_fb_info_2);

	pxa_set_keypad_info(&e2_keypad_platform_data);

	pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
	platform_add_devices(ARRAY_AND_SIZE(e2_devices));
}

MACHINE_START(EZX_E2, "Motorola EZX E2")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.nr_irqs	= EZX_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = e2_init,
	.restart	= pxa_restart,
MACHINE_END
#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/generic.c
 *
 *  Author:	Nicolas Pitre
 *  Created:	Jun 15, 2001
 *  Copyright:	MontaVista Software Inc.
 *
 * Code common to all PXA machines.
 *
 * Since this file should be linked before any other machine specific file,
 * the __initcall() here will be executed first.  This serves as default
 * initialization stuff for PXA machines which can be overridden later if
 * need be.
 */
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/soc/pxa/cpu.h>
#include <linux/soc/pxa/smemc.h>
#include <linux/clk/pxa.h>

#include <asm/mach/map.h>
#include <asm/mach-types.h>

#include "addr-map.h"
#include "irqs.h"
#include "reset.h"
#include "smemc.h"
#include "pxa3xx-regs.h"

#include "generic.h"
#include <clocksource/pxa.h>

void clear_reset_status(unsigned int mask)
{
	if (cpu_is_pxa2xx())
		pxa2xx_clear_reset_status(mask);
	else {
		/* RESET_STATUS_* has a 1:1 mapping with ARSR */
		ARSR = mask;
	}
}

/*
 * For non device-tree builds, keep legacy timer init
 */
void __init pxa_timer_init(void)
{
	if (cpu_is_pxa25x())
		pxa25x_clocks_init(io_p2v(0x41300000));
	if (cpu_is_pxa27x())
		pxa27x_clocks_init(io_p2v(0x41300000));
	if (cpu_is_pxa3xx())
		pxa3xx_clocks_init(io_p2v(0x41340000), io_p2v(0x41350000));
	pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000));
}

void pxa_smemc_set_pcmcia_timing(int sock, u32 mcmem, u32 mcatt, u32 mcio)
{
	__raw_writel(mcmem, MCMEM(sock));
	__raw_writel(mcatt, MCATT(sock));
	__raw_writel(mcio, MCIO(sock));
}
EXPORT_SYMBOL_GPL(pxa_smemc_set_pcmcia_timing);

void pxa_smemc_set_pcmcia_socket(int nr)
{
	switch (nr) {
	case 0:
		__raw_writel(0, MECR);
		break;
	case 1:
		/*
		 * We have at least one socket, so set MECR:CIT
		 * (Card Is There)
		 */
		__raw_writel(MECR_CIT, MECR);
		break;
	case 2:
		/* Set CIT and MECR:NOS (Number Of Sockets) */
		__raw_writel(MECR_CIT | MECR_NOS, MECR);
		break;
	}
}
EXPORT_SYMBOL_GPL(pxa_smemc_set_pcmcia_socket);

void __iomem *pxa_smemc_get_mdrefr(void)
{
	return MDREFR;
}

/*
 * Intel PXA2xx internal register mapping.
 *
 * Note: virtual 0xfffe0000-0xffffffff is reserved for the vector table
 *       and cache flush area.
 */
static struct map_desc common_io_desc[] __initdata = {
  	{	/* Devs */
		.virtual	= (unsigned long)PERIPH_VIRT,
		.pfn		= __phys_to_pfn(PERIPH_PHYS),
		.length		= PERIPH_SIZE,
		.type		= MT_DEVICE
	}
};

void __init pxa_map_io(void)
{
	debug_ll_io_init();
	iotable_init(ARRAY_AND_SIZE(common_io_desc));
}


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  linux/arch/arm/mach-pxa/generic.h
 *
 * Author:	Nicolas Pitre
 * Copyright:	MontaVista Software Inc.
 */

#include <linux/reboot.h>

struct irq_data;

extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *,
					     unsigned int));
extern void __init pxa_map_io(void);
extern void pxa_timer_init(void);

#define SET_BANK(__nr,__start,__size) \
	mi->bank[__nr].start = (__start), \
	mi->bank[__nr].size = (__size)

#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)

#define pxa25x_handle_irq icip_handle_irq
extern void __init pxa25x_init_irq(void);
extern void __init pxa25x_map_io(void);
extern void __init pxa26x_init_irq(void);

#define pxa27x_handle_irq ichp_handle_irq
extern unsigned	pxa27x_get_clk_frequency_khz(int);
extern void __init pxa27x_init_irq(void);
extern void __init pxa27x_map_io(void);

#define pxa3xx_handle_irq ichp_handle_irq
extern void __init pxa3xx_init_irq(void);
extern void __init pxa3xx_map_io(void);

extern struct syscore_ops pxa_irq_syscore_ops;
extern struct syscore_ops pxa2xx_mfp_syscore_ops;
extern struct syscore_ops pxa3xx_mfp_syscore_ops;

void __init pxa_set_ffuart_info(void *info);
void __init pxa_set_btuart_info(void *info);
void __init pxa_set_stuart_info(void *info);
void __init pxa_set_hwuart_info(void *info);

void pxa_restart(enum reboot_mode, const char *);

#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
extern void pxa2xx_clear_reset_status(unsigned int);
#else
static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
#endif

/*
 * Once fully converted to the clock framework, all these functions should be
 * removed, and replaced with a clk_get(NULL, "core").
 */
#ifdef CONFIG_PXA25x
extern unsigned pxa25x_get_clk_frequency_khz(int);
#else
#define pxa25x_get_clk_frequency_khz(x)		(0)
#endif

#ifdef CONFIG_PXA27x
#else
#define pxa27x_get_clk_frequency_khz(x)		(0)
#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/gumstix.c
 *
 *  Support for the Gumstix motherboards.
 *
 *  Original Author:	Craig Hughes
 *  Created:	Feb 14, 2008
 *  Copyright:	Craig Hughes
 *
 *  Implemented based on lubbock.c by Nicolas Pitre and code from Craig
 *  Hughes
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/err.h>
#include <linux/clk.h>

#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <linux/sizes.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>

#include "pxa25x.h"
#include <linux/platform_data/mmc-pxamci.h>
#include "udc.h"
#include "gumstix.h"

#include "generic.h"

static struct resource flash_resource = {
	.start	= 0x00000000,
	.end	= SZ_64M - 1,
	.flags	= IORESOURCE_MEM,
};

static struct mtd_partition gumstix_partitions[] = {
	{
		.name =		"Bootloader",
		.size =		0x00040000,
		.offset =	0,
		.mask_flags =	MTD_WRITEABLE  /* force read-only */
	} , {
		.name =		"rootfs",
		.size =		MTDPART_SIZ_FULL,
		.offset =	MTDPART_OFS_APPEND
	}
};

static struct flash_platform_data gumstix_flash_data = {
	.map_name	= "cfi_probe",
	.parts		= gumstix_partitions,
	.nr_parts	= ARRAY_SIZE(gumstix_partitions),
	.width		= 2,
};

static struct platform_device gumstix_flash_device = {
	.name		= "pxa2xx-flash",
	.id		= 0,
	.dev = {
		.platform_data = &gumstix_flash_data,
	},
	.resource = &flash_resource,
	.num_resources = 1,
};

static struct platform_device *devices[] __initdata = {
	&gumstix_flash_device,
};

#ifdef CONFIG_MMC_PXA
static struct pxamci_platform_data gumstix_mci_platform_data = {
	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
};

static void __init gumstix_mmc_init(void)
{
	pxa_set_mci_info(&gumstix_mci_platform_data);
}
#else
static void __init gumstix_mmc_init(void)
{
	pr_debug("Gumstix mmc disabled\n");
}
#endif

#ifdef CONFIG_USB_PXA25X
static struct gpiod_lookup_table gumstix_gpio_vbus_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_GUMSTIX_USB_GPIOn,
			    "vbus", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", GPIO_GUMSTIX_USB_GPIOx,
			    "pullup", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct platform_device gumstix_gpio_vbus = {
	.name	= "gpio-vbus",
	.id	= -1,
};

static void __init gumstix_udc_init(void)
{
	gpiod_add_lookup_table(&gumstix_gpio_vbus_gpiod_table);
	platform_device_register(&gumstix_gpio_vbus);
}
#else
static void gumstix_udc_init(void)
{
	pr_debug("Gumstix udc is disabled\n");
}
#endif

#ifdef CONFIG_BT
/* Normally, the bootloader would have enabled this 32kHz clock but many
** boards still have u-boot 1.1.4 so we check if it has been turned on and
** if not, we turn it on with a warning message. */
static void gumstix_setup_bt_clock(void)
{
	int timeout = 500;

	if (!(readl(OSCC) & OSCC_OOK))
		pr_warn("32kHz clock was not on. Bootloader may need to be updated\n");
	else
		return;

	writel(readl(OSCC) | OSCC_OON, OSCC);
	do {
		if (readl(OSCC) & OSCC_OOK)
			break;
		udelay(1);
	} while (--timeout);
	if (!timeout)
		pr_err("Failed to start 32kHz clock\n");
}

static void __init gumstix_bluetooth_init(void)
{
	int err;

	gumstix_setup_bt_clock();

	err = gpio_request(GPIO_GUMSTIX_BTRESET, "BTRST");
	if (err) {
		pr_err("gumstix: failed request gpio for bluetooth reset\n");
		return;
	}

	err = gpio_direction_output(GPIO_GUMSTIX_BTRESET, 1);
	if (err) {
		pr_err("gumstix: can't reset bluetooth\n");
		return;
	}
	gpio_set_value(GPIO_GUMSTIX_BTRESET, 0);
	udelay(100);
	gpio_set_value(GPIO_GUMSTIX_BTRESET, 1);
}
#else
static void gumstix_bluetooth_init(void)
{
	pr_debug("Gumstix Bluetooth is disabled\n");
}
#endif

static unsigned long gumstix_pin_config[] __initdata = {
	GPIO12_32KHz,
	/* BTUART */
	GPIO42_HWUART_RXD,
	GPIO43_HWUART_TXD,
	GPIO44_HWUART_CTS,
	GPIO45_HWUART_RTS,
	/* MMC */
	GPIO6_MMC_CLK,
	GPIO53_MMC_CLK,
	GPIO8_MMC_CS0,
};

int __attribute__((weak)) am200_init(void)
{
	return 0;
}

int __attribute__((weak)) am300_init(void)
{
	return 0;
}

static void __init carrier_board_init(void)
{
	/*
	 * put carrier/expansion board init here if
	 * they cannot be detected programatically
	 */
	am200_init();
	am300_init();
}

static void __init gumstix_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config));

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	pxa_set_hwuart_info(NULL);

	gumstix_bluetooth_init();
	gumstix_udc_init();
	gumstix_mmc_init();
	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
	carrier_board_init();
}

MACHINE_START(GUMSTIX, "Gumstix")
	.atag_offset	= 0x100, /* match u-boot bi_boot_params */
	.map_io		= pxa25x_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= gumstix_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-pxa/include/mach/gumstix.h
 */

#include "irqs.h" /* PXA_GPIO_TO_IRQ */

/* BTRESET - Reset line to Bluetooth module, active low signal. */
#define GPIO_GUMSTIX_BTRESET          7
#define GPIO_GUMSTIX_BTRESET_MD		(GPIO_GUMSTIX_BTRESET | GPIO_OUT)

/*
GPIOn - Input from MAX823 (or equiv), normalizing USB +5V into a clean
interrupt signal for determining cable presence. On the gumstix F,
this moves to GPIO17 and GPIO37. */

/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn
has detected a cable insertion; driven low otherwise. */

#define GPIO_GUMSTIX_USB_GPIOn		35
#define GPIO_GUMSTIX_USB_GPIOx		41

/* usb state change */
#define GUMSTIX_USB_INTR_IRQ		PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_USB_GPIOn)

#define GPIO_GUMSTIX_USB_GPIOn_MD	(GPIO_GUMSTIX_USB_GPIOn | GPIO_IN)
#define GPIO_GUMSTIX_USB_GPIOx_CON_MD	(GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD	(GPIO_GUMSTIX_USB_GPIOx | GPIO_IN)

/*
 * SD/MMC definitions
 */
#define GUMSTIX_GPIO_nSD_WP		22 /* SD Write Protect */
#define GUMSTIX_GPIO_nSD_DETECT		11 /* MMC/SD Card Detect */
#define GUMSTIX_IRQ_GPIO_nSD_DETECT	PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT)

/*
 * SMC Ethernet definitions
 * ETH_RST provides a hardware reset line to the ethernet chip
 * ETH is the IRQ line in from the ethernet chip to the PXA
 */
#define GPIO_GUMSTIX_ETH0_RST		80
#define GPIO_GUMSTIX_ETH0_RST_MD	(GPIO_GUMSTIX_ETH0_RST | GPIO_OUT)
#define GPIO_GUMSTIX_ETH1_RST		52
#define GPIO_GUMSTIX_ETH1_RST_MD	(GPIO_GUMSTIX_ETH1_RST | GPIO_OUT)

#define GPIO_GUMSTIX_ETH0		36
#define GPIO_GUMSTIX_ETH0_MD		(GPIO_GUMSTIX_ETH0 | GPIO_IN)
#define GUMSTIX_ETH0_IRQ		PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0)
#define GPIO_GUMSTIX_ETH1		27
#define GPIO_GUMSTIX_ETH1_MD		(GPIO_GUMSTIX_ETH1 | GPIO_IN)
#define GUMSTIX_ETH1_IRQ		PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1)

/* CF reset line */
#define GPIO8_RESET			8

/* CF slot 0 */
#define GPIO4_nBVD1			4
#define GPIO4_nSTSCHG			GPIO4_nBVD1
#define GPIO11_nCD			11
#define GPIO26_PRDY_nBSY		26
#define GUMSTIX_S0_nSTSCHG_IRQ		PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG)
#define GUMSTIX_S0_nCD_IRQ		PXA_GPIO_TO_IRQ(GPIO11_nCD)
#define GUMSTIX_S0_PRDY_nBSY_IRQ	PXA_GPIO_TO_IRQ(GPIO26_PRDY_nBSY)

/* CF slot 1 */
#define GPIO18_nBVD1			18
#define GPIO18_nSTSCHG			GPIO18_nBVD1
#define GPIO36_nCD			36
#define GPIO27_PRDY_nBSY		27
#define GUMSTIX_S1_nSTSCHG_IRQ		PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG)
#define GUMSTIX_S1_nCD_IRQ		PXA_GPIO_TO_IRQ(GPIO36_nCD)
#define GUMSTIX_S1_PRDY_nBSY_IRQ	PXA_GPIO_TO_IRQ(GPIO27_PRDY_nBSY)

/* CF GPIO line modes */
#define GPIO4_nSTSCHG_MD		(GPIO4_nSTSCHG | GPIO_IN)
#define GPIO8_RESET_MD			(GPIO8_RESET | GPIO_OUT)
#define GPIO11_nCD_MD			(GPIO11_nCD | GPIO_IN)
#define GPIO18_nSTSCHG_MD		(GPIO18_nSTSCHG | GPIO_IN)
#define GPIO26_PRDY_nBSY_MD		(GPIO26_PRDY_nBSY | GPIO_IN)
#define GPIO27_PRDY_nBSY_MD		(GPIO27_PRDY_nBSY | GPIO_IN)
#define GPIO36_nCD_MD			(GPIO36_nCD | GPIO_IN)

/* for expansion boards that can't be programatically detected */
extern int am200_init(void);
extern int am300_init(void);


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Hardware definitions for HP iPAQ h5xxx Handheld Computers
 *
 * Copyright 2000-2003  Hewlett-Packard Company.
 * Copyright 2002       Jamey Hicks <jamey.hicks@hp.com>
 * Copyright 2004-2005  Phil Blundell <pb@handhelds.org>
 * Copyright 2007-2008  Anton Vorontsov <cbouatmailru@gmail.com>
 *
 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
 * FITNESS FOR ANY PARTICULAR PURPOSE.
 *
 * Author: Jamey Hicks.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/irq.h>

#include "pxa25x.h"
#include "h5000.h"
#include "udc.h"
#include "smemc.h"

#include "generic.h"

/*
 * Flash
 */

static struct mtd_partition h5000_flash0_partitions[] = {
	{
		.name = "bootldr",
		.size = 0x00040000,
		.offset = 0,
		.mask_flags = MTD_WRITEABLE,
	},
	{
		.name = "root",
		.size = MTDPART_SIZ_FULL,
		.offset = MTDPART_OFS_APPEND,
	},
};

static struct mtd_partition h5000_flash1_partitions[] = {
	{
		.name = "second root",
		.size = SZ_16M - 0x00040000,
		.offset = 0,
	},
	{
		.name = "asset",
		.size = MTDPART_SIZ_FULL,
		.offset = MTDPART_OFS_APPEND,
		.mask_flags = MTD_WRITEABLE,
	},
};

static struct physmap_flash_data h5000_flash0_data = {
	.width = 4,
	.parts = h5000_flash0_partitions,
	.nr_parts = ARRAY_SIZE(h5000_flash0_partitions),
};

static struct physmap_flash_data h5000_flash1_data = {
	.width = 4,
	.parts = h5000_flash1_partitions,
	.nr_parts = ARRAY_SIZE(h5000_flash1_partitions),
};

static struct resource h5000_flash0_resources = {
	.start = PXA_CS0_PHYS,
	.end = PXA_CS0_PHYS + SZ_32M - 1,
	.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
};

static struct resource h5000_flash1_resources = {
	.start = PXA_CS0_PHYS + SZ_32M,
	.end = PXA_CS0_PHYS + SZ_32M + SZ_16M - 1,
	.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
};

static struct platform_device h5000_flash[] = {
	{
		.name = "physmap-flash",
		.id = 0,
		.resource = &h5000_flash0_resources,
		.num_resources = 1,
		.dev = {
			.platform_data = &h5000_flash0_data,
		},
	},
	{
		.name = "physmap-flash",
		.id = 1,
		.resource = &h5000_flash1_resources,
		.num_resources = 1,
		.dev = {
			.platform_data = &h5000_flash1_data,
		},
	},
};

/*
 * USB Device Controller
 */

static struct pxa2xx_udc_mach_info h5000_udc_mach_info __initdata = {
	.gpio_pullup = H5000_GPIO_USB_PULLUP,
};

/*
 * GPIO setup
 */

static unsigned long h5000_pin_config[] __initdata = {
	/* Crystal and Clock Signals */
	GPIO12_32KHz,

	/* SDRAM and Static Memory I/O Signals */
	GPIO15_nCS_1,
	GPIO78_nCS_2,
	GPIO79_nCS_3,
	GPIO80_nCS_4,

	/* FFUART */
	GPIO34_FFUART_RXD,
	GPIO35_FFUART_CTS,
	GPIO36_FFUART_DCD,
	GPIO37_FFUART_DSR,
	GPIO38_FFUART_RI,
	GPIO39_FFUART_TXD,
	GPIO40_FFUART_DTR,
	GPIO41_FFUART_RTS,

	/* BTUART */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,
	GPIO45_BTUART_RTS,

	/* SSP1 */
	GPIO23_SSP1_SCLK,
	GPIO25_SSP1_TXD,
	GPIO26_SSP1_RXD,

	/* I2S */
	GPIO28_I2S_BITCLK_OUT,
	GPIO29_I2S_SDATA_IN,
	GPIO30_I2S_SDATA_OUT,
	GPIO31_I2S_SYNC,
	GPIO32_I2S_SYSCLK,
};

/*
 * Localbus setup:
 * CS0: Flash;
 * CS1: MediaQ chip, select 16-bit bus and vlio;
 * CS5: SAMCOP.
 */

static void fix_msc(void)
{
	__raw_writel(0x129c24f2, MSC0);
	__raw_writel(0x7ff424fa, MSC1);
	__raw_writel(0x7ff47ff4, MSC2);

	__raw_writel(__raw_readl(MDREFR) | 0x02080000, MDREFR);
}

/*
 * Platform devices
 */

static struct platform_device *devices[] __initdata = {
	&h5000_flash[0],
	&h5000_flash[1],
};

static void __init h5000_init(void)
{
	fix_msc();

	pxa2xx_mfp_config(ARRAY_AND_SIZE(h5000_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	pxa_set_udc_info(&h5000_udc_mach_info);
	platform_add_devices(ARRAY_AND_SIZE(devices));
}

MACHINE_START(H5400, "HP iPAQ H5000")
	.atag_offset = 0x100,
	.map_io = pxa25x_map_io,
	.nr_irqs = PXA_NR_IRQS,
	.init_irq = pxa25x_init_irq,
	.handle_irq = pxa25x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine = h5000_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Hardware definitions for HP iPAQ h5xxx Handheld Computers
 *
 * Copyright(20)02 Hewlett-Packard Company.
 *
 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
 * FITNESS FOR ANY PARTICULAR PURPOSE.
 *
 * Author: Jamey Hicks
 */

#ifndef __ASM_ARCH_H5000_H
#define __ASM_ARCH_H5000_H

#include "mfp-pxa25x.h"

/*
 * CPU GPIOs
 */

#define H5000_GPIO_POWER_BUTTON   (0)
#define H5000_GPIO_RESET_BUTTON_N (1)
#define H5000_GPIO_OPT_INT        (2)
#define H5000_GPIO_BACKUP_POWER   (3)
#define H5000_GPIO_ACTION_BUTTON  (4)
#define H5000_GPIO_COM_DCD_SOMETHING  (5) /* what is this really ? */
/* 6 not connected */
#define H5000_GPIO_RESET_BUTTON_AGAIN_N (7) /* connected to gpio 1 as well */
/* 8 not connected */
#define H5000_GPIO_RSO_N          (9)       /* reset output from max1702 which regulates 3.3 and 2.5 */
#define H5000_GPIO_ASIC_INT_N   (10)       /* from companion asic */
#define H5000_GPIO_BT_ENV_0     (11)       /* to LMX9814, set to 1 according to regdump */
/*(12) not connected */
#define H5000_GPIO_BT_ENV_1     (13)       /* to LMX9814, set to 1 according to regdump */
#define H5000_GPIO_BT_WU        (14)       /* from LMX9814, Defined as HOST_WAKEUP in the LMX9820 data sheet */
/*(15) is CS1# */
/*(16) not connected */
/*(17) not connected */
/*(18) is pcmcia ready */
/*(19) is dreq1 */
/*(20) is dreq0 */
#define H5000_GPIO_OE_RD_NWR	(21)       /* output enable on rd/nwr signal to companion asic */
/*(22) is not connected */
#define H5000_GPIO_OPT_SPI_CLK  (23)       /* to extension pack */
#define H5000_GPIO_OPT_SPI_CS_N (24)       /* to extension pack */
#define H5000_GPIO_OPT_SPI_DOUT (25)       /* to extension pack */
#define H5000_GPIO_OPT_SPI_DIN  (26)       /* to extension pack */
/*(27) not connected */
#define H5000_GPIO_I2S_BITCLK   (28)       /* connected to AC97 codec */
#define H5000_GPIO_I2S_DATAOUT  (29)       /* connected to AC97 codec */
#define H5000_GPIO_I2S_DATAIN   (30)       /* connected to AC97 codec */
#define H5000_GPIO_I2S_LRCLK    (31)       /* connected to AC97 codec */
#define H5000_GPIO_I2S_SYSCLK   (32)       /* connected to AC97 codec */
/*(33) is CS5# */
#define H5000_GPIO_COM_RXD      (34)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_CTS      (35)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_DCD      (36)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_DSR      (37)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_RI       (38)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_TXD      (39)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_DTR      (40)       /* connected to cradle/cable connector */
#define H5000_GPIO_COM_RTS      (41)       /* connected to cradle/cable connector */

#define H5000_GPIO_BT_RXD       (42)       /* connected to BT (LMX9814) */
#define H5000_GPIO_BT_TXD       (43)       /* connected to BT (LMX9814) */
#define H5000_GPIO_BT_CTS       (44)       /* connected to BT (LMX9814) */
#define H5000_GPIO_BT_RTS       (45)       /* connected to BT (LMX9814) */

#define H5000_GPIO_IRDA_RXD     (46)
#define H5000_GPIO_IRDA_TXD     (47)

#define H5000_GPIO_POE_N        (48)       /* used for pcmcia */
#define H5000_GPIO_PWE_N        (49)       /* used for pcmcia */
#define H5000_GPIO_PIOR_N       (50)       /* used for pcmcia */
#define H5000_GPIO_PIOW_N       (51)       /* used for pcmcia */
#define H5000_GPIO_PCE1_N       (52)       /* used for pcmcia */
#define H5000_GPIO_PCE2_N       (53)       /* used for pcmcia */
#define H5000_GPIO_PSKTSEL      (54)       /* used for pcmcia */
#define H5000_GPIO_PREG_N       (55)       /* used for pcmcia */
#define H5000_GPIO_PWAIT_N      (56)       /* used for pcmcia */
#define H5000_GPIO_IOIS16_N     (57)       /* used for pcmcia */

#define H5000_GPIO_IRDA_SD      (58)       /* to hsdl3002 sd */
/*(59) not connected */
#define H5000_GPIO_POWER_SD_N   (60)       /* controls power to SD */
#define H5000_GPIO_POWER_RS232_N	(61)       /* inverted FORCEON to rs232 transceiver */
#define H5000_GPIO_POWER_ACCEL_N	(62)       /* controls power to accel */
/*(63) is not connected */
#define H5000_GPIO_OPT_NVRAM    (64)       /* controls power to expansion pack */
#define H5000_GPIO_CHG_EN       (65)       /* to sc801 en */
#define H5000_GPIO_USB_PULLUP   (66)       /* USB d+ pullup via 1.5K resistor */
#define H5000_GPIO_BT_2V8_N     (67)       /* 2.8V used by bluetooth */
#define H5000_GPIO_EXT_CHG_RATE (68)       /* enables external charging rate */
/*(69) is not connected */
#define H5000_GPIO_CIR_RESET    (70)       /* consumer IR reset */
#define H5000_GPIO_POWER_LIGHT_SENSOR_N	(71)
#define H5000_GPIO_BT_M_RESET   (72)
#define H5000_GPIO_STD_CHG_RATE (73)
#define H5000_GPIO_SD_WP_N      (74)
#define H5000_GPIO_MOTOR_ON_N   (75)       /* external pullup on this */
#define H5000_GPIO_HEADPHONE_DETECT	(76)
#define H5000_GPIO_USB_CHG_RATE (77)       /* select rate for charging via usb */
/*(78) is CS2# */
/*(79) is CS3# */
/*(80) is CS4# */

#endif /* __ASM_ARCH_H5000_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-pxa/himalaya.c
 *
 * Hardware definitions for the HTC Himalaya
 *
 * Based on 2.6.21-hh20's himalaya.c and himalaya_lcd.c
 *
 * Copyright (c) 2008 Zbynek Michl <Zbynek.Michl@seznam.cz>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/platform_device.h>

#include <video/w100fb.h>

#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>

#include "pxa25x.h"

#include "generic.h"

/* ---------------------- Himalaya LCD definitions -------------------- */

static struct w100_gen_regs himalaya_lcd_regs = {
	.lcd_format =        0x00000003,
	.lcdd_cntl1 =        0x00000000,
	.lcdd_cntl2 =        0x0003ffff,
	.genlcd_cntl1 =      0x00fff003,
	.genlcd_cntl2 =      0x00000003,
	.genlcd_cntl3 =      0x000102aa,
};

static struct w100_mode himalaya4_lcd_mode = {
	.xres 		= 240,
	.yres 		= 320,
	.left_margin 	= 0,
	.right_margin 	= 31,
	.upper_margin 	= 15,
	.lower_margin 	= 0,
	.crtc_ss	= 0x80150014,
	.crtc_ls	= 0xa0fb00f7,
	.crtc_gs	= 0xc0080007,
	.crtc_vpos_gs	= 0x00080007,
	.crtc_rev	= 0x0000000a,
	.crtc_dclk	= 0x81700030,
	.crtc_gclk	= 0x8015010f,
	.crtc_goe	= 0x00000000,
	.pll_freq 	= 80,
	.pixclk_divider = 15,
	.pixclk_divider_rotated = 15,
	.pixclk_src     = CLK_SRC_PLL,
	.sysclk_divider = 0,
	.sysclk_src     = CLK_SRC_PLL,
};

static struct w100_mode himalaya6_lcd_mode = {
	.xres 		= 240,
	.yres 		= 320,
	.left_margin 	= 9,
	.right_margin 	= 8,
	.upper_margin 	= 5,
	.lower_margin 	= 4,
	.crtc_ss	= 0x80150014,
	.crtc_ls	= 0xa0fb00f7,
	.crtc_gs	= 0xc0080007,
	.crtc_vpos_gs	= 0x00080007,
	.crtc_rev	= 0x0000000a,
	.crtc_dclk	= 0xa1700030,
	.crtc_gclk	= 0x8015010f,
	.crtc_goe	= 0x00000000,
	.pll_freq 	= 95,
	.pixclk_divider = 0xb,
	.pixclk_divider_rotated = 4,
	.pixclk_src     = CLK_SRC_PLL,
	.sysclk_divider = 1,
	.sysclk_src     = CLK_SRC_PLL,
};

static struct w100_gpio_regs himalaya_w100_gpio_info = {
	.init_data1 = 0xffff0000,	/* GPIO_DATA  */
	.gpio_dir1  = 0x00000000,	/* GPIO_CNTL1 */
	.gpio_oe1   = 0x003c0000,	/* GPIO_CNTL2 */
	.init_data2 = 0x00000000,	/* GPIO_DATA2 */
	.gpio_dir2  = 0x00000000,	/* GPIO_CNTL3 */
	.gpio_oe2   = 0x00000000,	/* GPIO_CNTL4 */
};

static struct w100fb_mach_info himalaya_fb_info = {
	.num_modes  = 1,
	.regs       = &himalaya_lcd_regs,
	.gpio       = &himalaya_w100_gpio_info,
	.xtal_freq = 16000000,
};

static struct resource himalaya_fb_resources[] = {
	[0] = {
		.start	= 0x08000000,
		.end	= 0x08ffffff,
		.flags	= IORESOURCE_MEM,
	},
};

static struct platform_device himalaya_fb_device = {
	.name           = "w100fb",
	.id             = -1,
	.dev            = {
		.platform_data  = &himalaya_fb_info,
	},
	.num_resources  = ARRAY_SIZE(himalaya_fb_resources),
	.resource       = himalaya_fb_resources,
};

/* ----------------------------------------------------------------------- */

static struct platform_device *devices[] __initdata = {
	&himalaya_fb_device,
};

static void __init himalaya_lcd_init(void)
{
	int himalaya_boardid;

	himalaya_boardid = 0x4; /* hardcoded (detection needs ASIC3 functions) */
	printk(KERN_INFO "himalaya LCD Driver init. boardid=%d\n",
		himalaya_boardid);

	switch (himalaya_boardid) {
	case 0x4:
		himalaya_fb_info.modelist = &himalaya4_lcd_mode;
	break;
	case 0x6:
		himalaya_fb_info.modelist = &himalaya6_lcd_mode;
	break;
	default:
		printk(KERN_INFO "himalaya lcd_init: unknown boardid=%d. Using 0x4\n",
			himalaya_boardid);
		himalaya_fb_info.modelist = &himalaya4_lcd_mode;
	}
}

static void __init himalaya_init(void)
{
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	himalaya_lcd_init();
	platform_add_devices(devices, ARRAY_SIZE(devices));
}

MACHINE_START(HIMALAYA, "HTC Himalaya")
	.atag_offset = 0x100,
	.map_io = pxa25x_map_io,
	.nr_irqs = PXA_NR_IRQS,
	.init_irq = pxa25x_init_irq,
	.handle_irq = pxa25x_handle_irq,
	.init_machine = himalaya_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com>
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/irq.h>

#include <asm/mach-types.h>
#include "hx4700.h"

#include <pcmcia/soc_common.h>

static struct gpio gpios[] = {
	{ GPIO114_HX4700_CF_RESET,    GPIOF_OUT_INIT_LOW,   "CF reset"        },
	{ EGPIO4_CF_3V3_ON,           GPIOF_OUT_INIT_LOW,   "CF 3.3V enable"  },
};

static int hx4700_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
	int ret;

	ret = gpio_request_array(gpios, ARRAY_SIZE(gpios));
	if (ret)
		goto out;

	/*
	 * IRQ type must be set before soc_pcmcia_hw_init() calls request_irq().
	 * The asic3 default IRQ type is level trigger low level detect, exactly
	 * the the signal present on GPIOD4_CF_nCD when a CF card is inserted.
	 * If the IRQ type is not changed, the asic3 interrupt handler will loop
	 * repeatedly because it is unable to clear the level trigger interrupt.
	 */
	irq_set_irq_type(gpio_to_irq(GPIOD4_CF_nCD), IRQ_TYPE_EDGE_BOTH);

	skt->stat[SOC_STAT_CD].gpio = GPIOD4_CF_nCD;
	skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
	skt->stat[SOC_STAT_RDY].gpio = GPIO60_HX4700_CF_RNB;
	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";

out:
	return ret;
}

static void hx4700_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
	gpio_free_array(gpios, ARRAY_SIZE(gpios));
}

static void hx4700_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
	struct pcmcia_state *state)
{
	state->vs_3v = 1;
	state->vs_Xv = 0;
}

static int hx4700_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
	const socket_state_t *state)
{
	switch (state->Vcc) {
	case 0:
		gpio_set_value(EGPIO4_CF_3V3_ON, 0);
		break;
	case 33:
		gpio_set_value(EGPIO4_CF_3V3_ON, 1);
		break;
	default:
		printk(KERN_ERR "pcmcia: Unsupported Vcc: %d\n", state->Vcc);
		return -EINVAL;
	}

	gpio_set_value(GPIO114_HX4700_CF_RESET, (state->flags & SS_RESET) != 0);

	return 0;
}

static struct pcmcia_low_level hx4700_pcmcia_ops = {
	.owner          = THIS_MODULE,
	.nr             = 1,
	.hw_init        = hx4700_pcmcia_hw_init,
	.hw_shutdown    = hx4700_pcmcia_hw_shutdown,
	.socket_state   = hx4700_pcmcia_socket_state,
	.configure_socket = hx4700_pcmcia_configure_socket,
};

static struct platform_device *hx4700_pcmcia_device;

static int __init hx4700_pcmcia_init(void)
{
	struct platform_device *pdev;

	if (!machine_is_h4700())
		return -ENODEV;

	pdev = platform_device_register_data(NULL, "pxa2xx-pcmcia", -1,
		&hx4700_pcmcia_ops, sizeof(hx4700_pcmcia_ops));
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	hx4700_pcmcia_device = pdev;

	return 0;
}

static void __exit hx4700_pcmcia_exit(void)
{
	platform_device_unregister(hx4700_pcmcia_device);
}

module_init(hx4700_pcmcia_init);
module_exit(hx4700_pcmcia_exit);

MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
MODULE_DESCRIPTION("HP iPAQ hx4700 PCMCIA driver");
MODULE_LICENSE("GPL");