code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Support for HTC Magician PDA phones:
 * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
 * and T-Mobile MDA Compact.
 *
 * Copyright (c) 2006-2007 Philipp Zabel
 *
 * Based on hx4700.c, spitz.c and others.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/mfd/htc-pasic3.h>
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/platform_data/gpio-htc-egpio.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/machine.h>
#include <linux/platform_data/i2c-pxa.h>

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

#include "pxa27x.h"
#include "addr-map.h"
#include "magician.h"
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>

#include <linux/regulator/max1586.h>

#include <linux/platform_data/pxa2xx_udc.h>

#include "udc.h"
#include "pxa27x-udc.h"
#include "devices.h"
#include "generic.h"

#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/spi/ads7846.h>
#include <sound/uda1380.h>

static unsigned long magician_pin_config[] __initdata = {

	/* SDRAM and Static Memory I/O Signals */
	GPIO20_nSDCS_2,
	GPIO21_nSDCS_3,
	GPIO15_nCS_1,
	GPIO78_nCS_2,	/* PASIC3 */
	GPIO79_nCS_3,	/* EGPIO CPLD */
	GPIO80_nCS_4,
	GPIO33_nCS_5,

	/* I2C UDA1380 + OV9640 */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

	/* PWM 0 - LCD backlight */
	GPIO16_PWM0_OUT,

	/* I2S UDA1380 capture */
	GPIO28_I2S_BITCLK_OUT,
	GPIO29_I2S_SDATA_IN,
	GPIO31_I2S_SYNC,
	GPIO113_I2S_SYSCLK,

	/* SSP 1 UDA1380 playback */
	GPIO23_SSP1_SCLK,
	GPIO24_SSP1_SFRM,
	GPIO25_SSP1_TXD,

	/* SSP 2 TSC2046 touchscreen */
	GPIO19_SSP2_SCLK,
	MFP_CFG_OUT(GPIO14, AF0, DRIVE_HIGH),	/* frame as GPIO */
	GPIO89_SSP2_TXD,
	GPIO88_SSP2_RXD,

	/* MMC/SD/SDHC slot */
	GPIO32_MMC_CLK,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	GPIO112_MMC_CMD,

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* QCI camera interface */
	GPIO12_CIF_DD_7,
	GPIO17_CIF_DD_6,
	GPIO50_CIF_DD_3,
	GPIO51_CIF_DD_2,
	GPIO52_CIF_DD_4,
	GPIO53_CIF_MCLK,
	GPIO54_CIF_PCLK,
	GPIO55_CIF_DD_1,
	GPIO81_CIF_DD_0,
	GPIO82_CIF_DD_5,
	GPIO84_CIF_FV,
	GPIO85_CIF_LV,

	/* Magician specific input GPIOs */
	GPIO9_GPIO,	/* unknown */
	GPIO10_GPIO,	/* GSM_IRQ */
	GPIO13_GPIO,	/* CPLD_IRQ */
	GPIO107_GPIO,	/* DS1WM_IRQ */
	GPIO108_GPIO,	/* GSM_READY */
	GPIO115_GPIO,	/* nPEN_IRQ */
};

/*
 * IrDA
 */

static struct pxaficp_platform_data magician_ficp_info = {
	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
	.gpio_pwdown_inverted	= 0,
};

/*
 * GPIO Keys
 */

#define INIT_KEY(_code, _gpio, _desc)	\
	{				\
		.code	= KEY_##_code,	\
		.gpio	= _gpio,	\
		.desc	= _desc,	\
		.type	= EV_KEY,	\
		.wakeup	= 1,		\
	}

static struct gpio_keys_button magician_button_table[] = {
	INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
	INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
	INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
	INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
	INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
	INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
	INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
	INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
	INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
	INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
	INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
	INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
	INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
	INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
	INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
};

static struct gpio_keys_platform_data gpio_keys_data = {
	.buttons	= magician_button_table,
	.nbuttons	= ARRAY_SIZE(magician_button_table),
};

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

/*
 * EGPIO (Xilinx CPLD)
 *
 * 32-bit aligned 8-bit registers
 * 16 possible registers (reg windows size), only 7 used:
 * 3x output, 1x irq, 3x input
 */

static struct resource egpio_resources[] = {
	[0] = {
		.start	= PXA_CS3_PHYS,
		.end	= PXA_CS3_PHYS + 0x20 - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
		.end	= PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
		.flags	= IORESOURCE_IRQ,
	},
};

static struct htc_egpio_chip egpio_chips[] = {
	[0] = {
		.reg_start	= 0,
		.gpio_base	= MAGICIAN_EGPIO(0, 0),
		.num_gpios	= 24,
		.direction	= HTC_EGPIO_OUTPUT,
		/*
		 * Depends on modules configuration
		 */
		.initial_values	= 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
	},
	[1] = {
		.reg_start	= 4,
		.gpio_base	= MAGICIAN_EGPIO(4, 0),
		.num_gpios	= 24,
		.direction	= HTC_EGPIO_INPUT,
	},
};

static struct htc_egpio_platform_data egpio_info = {
	.reg_width	= 8,
	.bus_width	= 32,
	.irq_base	= IRQ_BOARD_START,
	.num_irqs	= 4,
	.ack_register	= 3,
	.chip		= egpio_chips,
	.num_chips	= ARRAY_SIZE(egpio_chips),
};

static struct platform_device egpio = {
	.name		= "htc-egpio",
	.id		= -1,
	.resource	= egpio_resources,
	.num_resources	= ARRAY_SIZE(egpio_resources),
	.dev = {
		.platform_data = &egpio_info,
	},
};

/*
 * PXAFB LCD - Toppoly TD028STEB1 or Samsung LTP280QV
 */

static struct pxafb_mode_info toppoly_modes[] = {
	{
		.pixclock	= 96153,
		.bpp		= 16,
		.xres		= 240,
		.yres		= 320,
		.hsync_len	= 11,
		.vsync_len	= 3,
		.left_margin	= 19,
		.upper_margin	= 2,
		.right_margin	= 10,
		.lower_margin	= 2,
		.sync		= 0,
	},
};

static struct pxafb_mode_info samsung_modes[] = {
	{
		.pixclock	= 226469,
		.bpp		= 16,
		.xres		= 240,
		.yres		= 320,
		.hsync_len	= 8,
		.vsync_len	= 4,
		.left_margin	= 9,
		.upper_margin	= 4,
		.right_margin	= 9,
		.lower_margin	= 4,
		.sync	= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
	},
};

static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
{
	pr_debug("Toppoly LCD power: %s\n", on ? "on" : "off");

	if (on) {
		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
		udelay(2000);
		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
		udelay(2000);
		/* FIXME: enable LCDC here */
		udelay(2000);
		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
		udelay(2000);
		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
	} else {
		msleep(15);
		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
		udelay(500);
		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
		udelay(1000);
		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
	}
}

static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
{
	pr_debug("Samsung LCD power: %s\n", on ? "on" : "off");

	if (on) {
		if (system_rev < 3)
			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
		else
			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
		mdelay(6);
		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
		mdelay(6);	/* Avdd -> Voff >5ms */
		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
		mdelay(16);	/* Voff -> Von >(5+10)ms */
		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
	} else {
		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
		mdelay(16);
		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
		mdelay(6);
		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
		mdelay(6);
		if (system_rev < 3)
			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
		else
			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
	}
}

static struct pxafb_mach_info toppoly_info = {
	.modes			= toppoly_modes,
	.num_modes		= 1,
	.fixed_modes		= 1,
	.lcd_conn		= LCD_COLOR_TFT_16BPP,
	.pxafb_lcd_power	= toppoly_lcd_power,
};

static struct pxafb_mach_info samsung_info = {
	.modes			= samsung_modes,
	.num_modes		= 1,
	.fixed_modes		= 1,
	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
		LCD_ALTERNATE_MAPPING,
	.pxafb_lcd_power	= samsung_lcd_power,
};

/*
 * Backlight
 */

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

 /*
 * fixed regulator for pwm_backlight
 */

static struct regulator_consumer_supply pwm_backlight_supply[] = {
	REGULATOR_SUPPLY("power", "pwm_backlight"),
};

static struct gpio magician_bl_gpios[] = {
	{ EGPIO_MAGICIAN_BL_POWER,	GPIOF_DIR_OUT, "Backlight power" },
	{ EGPIO_MAGICIAN_BL_POWER2,	GPIOF_DIR_OUT, "Backlight power 2" },
};

static int magician_backlight_init(struct device *dev)
{
	return gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios));
}

static int magician_backlight_notify(struct device *dev, int brightness)
{
	pr_debug("Brightness = %i\n", brightness);
	gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
	if (brightness >= 200) {
		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
		return brightness - 72;
	} else {
		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
		return brightness;
	}
}

static void magician_backlight_exit(struct device *dev)
{
	gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
}

/*
 * LCD PWM backlight (main)
 *
 * MP1521 frequency should be:
 *	100-400 Hz = 2 .5*10^6 - 10 *10^6 ns
 */

static struct platform_pwm_backlight_data backlight_data = {
	.max_brightness	= 272,
	.dft_brightness	= 100,
	.init		= magician_backlight_init,
	.notify		= magician_backlight_notify,
	.exit		= magician_backlight_exit,
};

static struct platform_device backlight = {
	.name	= "pwm-backlight",
	.id	= -1,
	.dev	= {
		.parent		= &pxa27x_device_pwm0.dev,
		.platform_data	= &backlight_data,
	},
};

/*
 * GPIO LEDs, Phone keys backlight, vibra
 */

static struct gpio_led gpio_leds[] = {
	{
		.name = "magician::vibra",
		.default_trigger = "none",
		.gpio = GPIO22_MAGICIAN_VIBRA_EN,
	},
	{
		.name = "magician::phone_bl",
		.default_trigger = "backlight",
		.gpio = GPIO103_MAGICIAN_LED_KP,
	},
};

static struct gpio_led_platform_data gpio_led_info = {
	.leds = gpio_leds,
	.num_leds = ARRAY_SIZE(gpio_leds),
};

static struct platform_device leds_gpio = {
	.name	= "leds-gpio",
	.id	= -1,
	.dev	= {
		.platform_data = &gpio_led_info,
	},
};

/*
 * PASIC3 with DS1WM
 */

static struct resource pasic3_resources[] = {
	[0] = {
		.start	= PXA_CS2_PHYS,
		.end	= PXA_CS2_PHYS + 0x1b,
		.flags	= IORESOURCE_MEM,
	},
	/* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
	[1] = {
		.start	= PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
		.end	= PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
	}
};

static struct pasic3_platform_data pasic3_platform_data = {
	.clock_rate = 4000000,
};

static struct platform_device pasic3 = {
	.name		= "pasic3",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(pasic3_resources),
	.resource	= pasic3_resources,
	.dev = {
		.platform_data = &pasic3_platform_data,
	},
};

/*
 * PXA UDC
 */

static void magician_udc_command(int cmd)
{
	if (cmd == PXA2XX_UDC_CMD_CONNECT)
		UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
		UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
}

static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
	.udc_command	= magician_udc_command,
	.gpio_pullup	= GPIO27_MAGICIAN_USBC_PUEN,
};

/*
 * USB device VBus detection
 */

static struct resource gpio_vbus_resource = {
	.flags	= IORESOURCE_IRQ,
	.start	= IRQ_MAGICIAN_VBUS,
	.end	= IRQ_MAGICIAN_VBUS,
};

static struct gpiod_lookup_table gpio_vbus_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		/*
		 * EGPIO on register 4 index 1, the second EGPIO chip
		 * starts at register 4 so this will be at index 1 on that
		 * chip.
		 */
		GPIO_LOOKUP("htc-egpio-1", 1,
			    "vbus", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", GPIO27_MAGICIAN_USBC_PUEN,
			    "pullup", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct platform_device gpio_vbus = {
	.name		= "gpio-vbus",
	.id		= -1,
	.num_resources	= 1,
	.resource	= &gpio_vbus_resource,
};

/*
 * External power
 */

static int magician_supply_init(struct device *dev)
{
	int ret = -1;

	ret = gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "Cable is AC charger");
	if (ret) {
		pr_err("Cannot request AC/USB charger GPIO (%i)\n", ret);
		goto err_ac;
	}

	ret = gpio_request(EGPIO_MAGICIAN_CABLE_INSERTED, "Cable inserted");
	if (ret) {
		pr_err("Cannot request cable detection GPIO (%i)\n", ret);
		goto err_usb;
	}

	return 0;

err_usb:
	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
err_ac:
	return ret;
}

static void magician_set_charge(int flags)
{
	if (flags & PDA_POWER_CHARGE_AC) {
		pr_debug("Charging from AC\n");
		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
	} else if (flags & PDA_POWER_CHARGE_USB) {
		pr_debug("Charging from USB\n");
		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
	} else {
		pr_debug("Charging disabled\n");
		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 0);
	}
}

static int magician_is_ac_online(void)
{
	return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERTED) &&
		gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE); /* AC=1 */
}

static int magician_is_usb_online(void)
{
	return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERTED) &&
		(!gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE)); /* USB=0 */
}

static void magician_supply_exit(struct device *dev)
{
	gpio_free(EGPIO_MAGICIAN_CABLE_INSERTED);
	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
}

static char *magician_supplicants[] = {
	"ds2760-battery.0", "backup-battery"
};

static struct pda_power_pdata power_supply_info = {
	.init			= magician_supply_init,
	.exit			= magician_supply_exit,
	.is_ac_online		= magician_is_ac_online,
	.is_usb_online		= magician_is_usb_online,
	.set_charge		= magician_set_charge,
	.supplied_to		= magician_supplicants,
	.num_supplicants	= ARRAY_SIZE(magician_supplicants),
};

static struct resource power_supply_resources[] = {
	[0] = {
		.name	= "ac",
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
			IORESOURCE_IRQ_LOWEDGE,
		.start	= IRQ_MAGICIAN_VBUS,
		.end	= IRQ_MAGICIAN_VBUS,
	},
	[1] = {
		.name	= "usb",
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
			IORESOURCE_IRQ_LOWEDGE,
		.start	= IRQ_MAGICIAN_VBUS,
		.end	= IRQ_MAGICIAN_VBUS,
	},
};

static struct platform_device power_supply = {
	.name	= "pda-power",
	.id	= -1,
	.dev = {
		.platform_data = &power_supply_info,
	},
	.resource	= power_supply_resources,
	.num_resources	= ARRAY_SIZE(power_supply_resources),
};

/*
 * Battery charger
 */

static struct regulator_consumer_supply bq24022_consumers[] = {
	REGULATOR_SUPPLY("vbus_draw", NULL),
	REGULATOR_SUPPLY("ac_draw", NULL),
};

static struct regulator_init_data bq24022_init_data = {
	.constraints = {
		.max_uA		= 500000,
		.valid_ops_mask	= REGULATOR_CHANGE_CURRENT |
			REGULATOR_CHANGE_STATUS,
	},
	.num_consumer_supplies	= ARRAY_SIZE(bq24022_consumers),
	.consumer_supplies	= bq24022_consumers,
};

static enum gpiod_flags bq24022_gpiod_gflags[] = { GPIOD_OUT_LOW };

static struct gpio_regulator_state bq24022_states[] = {
	{ .value = 100000, .gpios = (0 << 0) },
	{ .value = 500000, .gpios = (1 << 0) },
};

static struct gpio_regulator_config bq24022_info = {
	.supply_name		= "bq24022",

	.enabled_at_boot	= 1,

	.gflags = bq24022_gpiod_gflags,
	.ngpios = ARRAY_SIZE(bq24022_gpiod_gflags),

	.states			= bq24022_states,
	.nr_states		= ARRAY_SIZE(bq24022_states),

	.type			= REGULATOR_CURRENT,
	.init_data		= &bq24022_init_data,
};

static struct platform_device bq24022 = {
	.name	= "gpio-regulator",
	.id	= -1,
	.dev	= {
		.platform_data = &bq24022_info,
	},
};

static struct gpiod_lookup_table bq24022_gpiod_table = {
	.dev_id = "gpio-regulator",
	.table = {
		GPIO_LOOKUP("htc-egpio-0", EGPIO_MAGICIAN_BQ24022_ISET2 - MAGICIAN_EGPIO_BASE,
			    NULL, GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
			    "enable", GPIO_ACTIVE_LOW),
		{ },
	},
};

/*
 * fixed regulator for ads7846
 */

static struct regulator_consumer_supply ads7846_supply =
	REGULATOR_SUPPLY("vcc", "spi2.0");

static struct regulator_init_data vads7846_regulator = {
	.constraints	= {
		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
	},
	.num_consumer_supplies	= 1,
	.consumer_supplies	= &ads7846_supply,
};

static struct fixed_voltage_config vads7846 = {
	.supply_name	= "vads7846",
	.microvolts	= 3300000, /* probably */
	.startup_delay	= 0,
	.init_data	= &vads7846_regulator,
};

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

/*
 * Vcore regulator MAX1587A
 */

static struct regulator_consumer_supply magician_max1587a_consumers[] = {
	REGULATOR_SUPPLY("vcc_core", NULL),
};

static struct regulator_init_data magician_max1587a_v3_info = {
	.constraints = {
		.name		= "vcc_core range",
		.min_uV		= 700000,
		.max_uV		= 1475000,
		.always_on	= 1,
		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
	},
	.consumer_supplies	= magician_max1587a_consumers,
	.num_consumer_supplies	= ARRAY_SIZE(magician_max1587a_consumers),
};

static struct max1586_subdev_data magician_max1587a_subdevs[] = {
	{
		.name		= "vcc_core",
		.id		= MAX1586_V3,
		.platform_data	= &magician_max1587a_v3_info,
	}
};

static struct max1586_platform_data magician_max1587a_info = {
	.subdevs     = magician_max1587a_subdevs,
	.num_subdevs = ARRAY_SIZE(magician_max1587a_subdevs),
	/*
	 * NOTICE measured directly on the PCB (board_id == 0x3a), but
	 * if R24 is present, it will boost the voltage
	 * (write 1.475V, get 1.645V and smoke)
	 */
	.v3_gain     = MAX1586_GAIN_NO_R24,
};

static struct i2c_board_info magician_pwr_i2c_board_info[] __initdata = {
	{
		I2C_BOARD_INFO("max1586", 0x14),
		.platform_data	= &magician_max1587a_info,
	},
};

/*
 * MMC/SD
 */

static int magician_mci_init(struct device *dev,
	irq_handler_t detect_irq, void *data)
{
	return request_irq(IRQ_MAGICIAN_SD, detect_irq, 0,
		"mmc card detect", data);
}

static void magician_mci_exit(struct device *dev, void *data)
{
	free_irq(IRQ_MAGICIAN_SD, data);
}

static struct pxamci_platform_data magician_mci_info = {
	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
	.init			= magician_mci_init,
	.exit			= magician_mci_exit,
	.gpio_card_ro_invert	= 1,
};

/*
 * Write protect on EGPIO register 5 index 4, this is on the second HTC
 * EGPIO chip which starts at register 4, so we need offset 8+4=12 on that
 * particular chip.
 */
#define EGPIO_MAGICIAN_nSD_READONLY_OFFSET 12
/*
 * Power on EGPIO register 2 index 0, so this is on the first HTC EGPIO chip
 * starting at register 0 so we need offset 2*8+0 = 16 on that chip.
 */
#define EGPIO_MAGICIAN_nSD_POWER_OFFSET 16

static struct gpiod_lookup_table magician_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("htc-egpio-1", EGPIO_MAGICIAN_nSD_READONLY_OFFSET,
			    "wp", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("htc-egpio-0", EGPIO_MAGICIAN_nSD_POWER_OFFSET,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

/*
 * USB OHCI
 */

static struct pxaohci_platform_data magician_ohci_info = {
	.port_mode	= PMM_PERPORT_MODE,
	/* port1: CSR Bluetooth, port2: OTG with UDC */
	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
	.power_budget	= 0,
	.power_on_delay = 100,
};

/*
 * StrataFlash
 */

static int magician_flash_init(struct platform_device *pdev)
{
	int ret = gpio_request(EGPIO_MAGICIAN_FLASH_VPP, "flash Vpp enable");

	if (ret) {
		pr_err("Cannot request flash enable GPIO (%i)\n", ret);
		return ret;
	}

	ret = gpio_direction_output(EGPIO_MAGICIAN_FLASH_VPP, 1);
	if (ret) {
		pr_err("Cannot set direction for flash enable (%i)\n", ret);
		gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
	}

	return ret;
}

static void magician_set_vpp(struct platform_device *pdev, int vpp)
{
	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
}

static void magician_flash_exit(struct platform_device *pdev)
{
	gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
}

static struct resource strataflash_resource = {
	.start	= PXA_CS0_PHYS,
	.end	= PXA_CS0_PHYS + SZ_64M - 1,
	.flags	= IORESOURCE_MEM,
};

static struct mtd_partition magician_flash_parts[] = {
	{
		.name		= "Bootloader",
		.offset		= 0x0,
		.size		= 0x40000,
		.mask_flags	= MTD_WRITEABLE, /* EXPERIMENTAL */
	},
	{
		.name		= "Linux Kernel",
		.offset		= 0x40000,
		.size		= MTDPART_SIZ_FULL,
	},
};

/*
 * physmap-flash driver
 */

static struct physmap_flash_data strataflash_data = {
	.width		= 4,
	.init		= magician_flash_init,
	.set_vpp	= magician_set_vpp,
	.exit		= magician_flash_exit,
	.parts		= magician_flash_parts,
	.nr_parts	= ARRAY_SIZE(magician_flash_parts),
};

static struct platform_device strataflash = {
	.name		= "physmap-flash",
	.id		= -1,
	.resource	= &strataflash_resource,
	.num_resources	= 1,
	.dev = {
		.platform_data = &strataflash_data,
	},
};

/*
 * audio support
 */
static struct uda1380_platform_data uda1380_info = {
	.gpio_power = EGPIO_MAGICIAN_CODEC_POWER,
	.gpio_reset = EGPIO_MAGICIAN_CODEC_RESET,
	.dac_clk    = UDA1380_DAC_CLK_WSPLL,
};

static struct i2c_board_info magician_audio_i2c_board_info[] = {
	{
		I2C_BOARD_INFO("uda1380", 0x18),
		.platform_data = &uda1380_info,
	},
};

static struct gpiod_lookup_table magician_audio_gpio_table = {
	.dev_id = "magician-audio",
	.table = {
		GPIO_LOOKUP("htc-egpio-0",
			    EGPIO_MAGICIAN_SPK_POWER - MAGICIAN_EGPIO_BASE,
			    "SPK_POWER", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("htc-egpio-0",
			    EGPIO_MAGICIAN_EP_POWER - MAGICIAN_EGPIO_BASE,
			    "EP_POWER", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("htc-egpio-0",
			    EGPIO_MAGICIAN_MIC_POWER - MAGICIAN_EGPIO_BASE,
			    "MIC_POWER", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("htc-egpio-0",
			    EGPIO_MAGICIAN_IN_SEL0 - MAGICIAN_EGPIO_BASE,
			    "IN_SEL0", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("htc-egpio-0",
			    EGPIO_MAGICIAN_IN_SEL1 - MAGICIAN_EGPIO_BASE,
			    "IN_SEL1", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static void magician_audio_init(void)
{
	i2c_register_board_info(0,
		ARRAY_AND_SIZE(magician_audio_i2c_board_info));

	gpiod_add_lookup_table(&magician_audio_gpio_table);
	platform_device_register_simple("magician-audio", -1, NULL, 0);
}

/*
 * PXA I2C main controller
 */

static struct i2c_pxa_platform_data i2c_info = {
	/* OV9640 I2C device doesn't support fast mode */
	.fast_mode	= 0,
};

/*
 * PXA I2C power controller
 */

static struct i2c_pxa_platform_data magician_i2c_power_info = {
	.fast_mode	= 1,
};

/*
 * Touchscreen
 */

static struct ads7846_platform_data ads7846_pdata = {
	.model		= 7846,
	.x_plate_ohms	= 317,
	.y_plate_ohms	= 500,
	.pressure_max	= 1023,	/* with x plate ohms it will overflow 255 */
	.debounce_max	= 3,	/* first readout is always bad */
	.debounce_tol	= 30,
	.debounce_rep	= 0,
	.gpio_pendown	= GPIO115_MAGICIAN_nPEN_IRQ,
	.keep_vref_on	= 1,
	.wakeup		= true,
	.vref_delay_usecs		= 100,
	.penirq_recheck_delay_usecs	= 100,
};

struct pxa2xx_spi_chip tsc2046_chip_info = {
	.tx_threshold	= 1,
	.rx_threshold	= 2,
	.timeout	= 64,
};

static struct pxa2xx_spi_controller magician_spi_info = {
	.num_chipselect	= 1,
	.enable_dma	= 1,
};

static struct gpiod_lookup_table magician_spi_gpio_table = {
	.dev_id = "spi2",
	.table = {
		/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
		GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct spi_board_info ads7846_spi_board_info[] __initdata = {
	{
		.modalias		= "ads7846",
		.bus_num		= 2,
		.max_speed_hz		= 2500000,
		.platform_data		= &ads7846_pdata,
		.controller_data	= &tsc2046_chip_info,
		.irq = PXA_GPIO_TO_IRQ(GPIO115_MAGICIAN_nPEN_IRQ),
	},
};

/*
 * Platform devices
 */

static struct platform_device *devices[] __initdata = {
	&gpio_keys,
	&egpio,
	&backlight,
	&pasic3,
	&bq24022,
	&gpio_vbus,
	&power_supply,
	&strataflash,
	&leds_gpio,
	&vads7846_device,
};

static struct gpio magician_global_gpios[] = {
	{ GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" },
	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },

	/* NOTICE valid LCD init sequence */
	{ GPIO106_MAGICIAN_LCD_DCDC_NRESET, GPIOF_OUT_INIT_LOW, "LCD DCDC nreset" },
	{ GPIO104_MAGICIAN_LCD_VOFF_EN, GPIOF_OUT_INIT_LOW, "LCD VOFF enable" },
	{ GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_LOW, "LCD VON enable" },
};

static void __init magician_init(void)
{
	void __iomem *cpld;
	int lcd_select;
	int err;

	pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
	err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
	if (err)
		pr_err("magician: Failed to request global GPIOs: %d\n", err);

	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);

	pwm_add_table(magician_pwm_lookup, ARRAY_SIZE(magician_pwm_lookup));

	pxa_set_ficp_info(&magician_ficp_info);
	pxa27x_set_i2c_power_info(&magician_i2c_power_info);
	pxa_set_i2c_info(&i2c_info);

	i2c_register_board_info(1,
		ARRAY_AND_SIZE(magician_pwr_i2c_board_info));

	gpiod_add_lookup_table(&magician_mci_gpio_table);
	pxa_set_mci_info(&magician_mci_info);
	pxa_set_ohci_info(&magician_ohci_info);
	pxa_set_udc_info(&magician_udc_info);

	/* Check LCD type we have */
	cpld = ioremap(PXA_CS3_PHYS, 0x1000);
	if (cpld) {
		u8 board_id = __raw_readb(cpld + 0x14);

		iounmap(cpld);
		system_rev = board_id & 0x7;
		lcd_select = board_id & 0x8;
		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
		if (lcd_select && (system_rev < 3))
			/* NOTICE valid LCD init sequence */
			gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
				GPIOF_OUT_INIT_LOW, "Samsung LCD Power");
		pxa_set_fb_info(NULL,
			lcd_select ? &samsung_info : &toppoly_info);
	} else
		pr_err("LCD detection: CPLD mapping failed\n");

	gpiod_add_lookup_table(&magician_spi_gpio_table);
	pxa2xx_set_spi_info(2, &magician_spi_info);
	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));

	regulator_register_always_on(0, "power", pwm_backlight_supply,
		ARRAY_SIZE(pwm_backlight_supply), 5000000);

	gpiod_add_lookup_table(&bq24022_gpiod_table);
	gpiod_add_lookup_table(&gpio_vbus_gpiod_table);
	platform_add_devices(ARRAY_AND_SIZE(devices));

	magician_audio_init();
}

MACHINE_START(MAGICIAN, "HTC Magician")
	.atag_offset	= 0x100,
	.map_io		= pxa27x_map_io,
	.nr_irqs	= MAGICIAN_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_machine	= magician_init,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIO and IRQ definitions for HTC Magician PDA phones
 *
 * Copyright (c) 2007 Philipp Zabel
 */

#ifndef _MAGICIAN_H_
#define _MAGICIAN_H_

#include <linux/gpio.h>
#include "irqs.h"

/*
 * PXA GPIOs
 */

#define GPIO0_MAGICIAN_KEY_POWER		0
#define GPIO9_MAGICIAN_UNKNOWN			9
#define GPIO10_MAGICIAN_GSM_IRQ			10
#define GPIO11_MAGICIAN_GSM_OUT1		11
#define GPIO13_MAGICIAN_CPLD_IRQ		13
#define GPIO14_MAGICIAN_TSC2046_CS		14
#define GPIO18_MAGICIAN_UNKNOWN			18
#define GPIO22_MAGICIAN_VIBRA_EN		22
#define GPIO26_MAGICIAN_GSM_POWER		26
#define GPIO27_MAGICIAN_USBC_PUEN		27
#define GPIO30_MAGICIAN_BQ24022_nCHARGE_EN	30
#define GPIO37_MAGICIAN_KEY_HANGUP		37
#define GPIO38_MAGICIAN_KEY_CONTACTS		38
#define GPIO40_MAGICIAN_GSM_OUT2		40
#define GPIO48_MAGICIAN_UNKNOWN			48
#define GPIO56_MAGICIAN_UNKNOWN			56
#define GPIO57_MAGICIAN_CAM_RESET		57
#define GPIO75_MAGICIAN_SAMSUNG_POWER		75
#define GPIO83_MAGICIAN_nIR_EN			83
#define GPIO86_MAGICIAN_GSM_RESET		86
#define GPIO87_MAGICIAN_GSM_SELECT		87
#define GPIO90_MAGICIAN_KEY_CALENDAR		90
#define GPIO91_MAGICIAN_KEY_CAMERA		91
#define GPIO93_MAGICIAN_KEY_UP			93
#define GPIO94_MAGICIAN_KEY_DOWN		94
#define GPIO95_MAGICIAN_KEY_LEFT		95
#define GPIO96_MAGICIAN_KEY_RIGHT		96
#define GPIO97_MAGICIAN_KEY_ENTER		97
#define GPIO98_MAGICIAN_KEY_RECORD		98
#define GPIO99_MAGICIAN_HEADPHONE_IN		99
#define GPIO100_MAGICIAN_KEY_VOL_UP		100
#define GPIO101_MAGICIAN_KEY_VOL_DOWN 		101
#define GPIO102_MAGICIAN_KEY_PHONE		102
#define GPIO103_MAGICIAN_LED_KP			103
#define GPIO104_MAGICIAN_LCD_VOFF_EN		104
#define GPIO105_MAGICIAN_LCD_VON_EN		105
#define GPIO106_MAGICIAN_LCD_DCDC_NRESET	106
#define GPIO107_MAGICIAN_DS1WM_IRQ		107
#define GPIO108_MAGICIAN_GSM_READY		108
#define GPIO114_MAGICIAN_UNKNOWN		114
#define GPIO115_MAGICIAN_nPEN_IRQ		115
#define GPIO116_MAGICIAN_nCAM_EN		116
#define GPIO119_MAGICIAN_UNKNOWN		119
#define GPIO120_MAGICIAN_UNKNOWN		120

/*
 * CPLD IRQs
 */

#define IRQ_MAGICIAN_SD		(IRQ_BOARD_START + 0)
#define IRQ_MAGICIAN_EP		(IRQ_BOARD_START + 1)
#define IRQ_MAGICIAN_BT		(IRQ_BOARD_START + 2)
#define IRQ_MAGICIAN_VBUS	(IRQ_BOARD_START + 3)

#define MAGICIAN_NR_IRQS	(IRQ_BOARD_START + 8)

/*
 * CPLD EGPIOs
 */

#define MAGICIAN_EGPIO_BASE		PXA_NR_BUILTIN_GPIO
#define MAGICIAN_EGPIO(reg,bit) \
	(MAGICIAN_EGPIO_BASE + 8*reg + bit)

/* output */

#define EGPIO_MAGICIAN_TOPPOLY_POWER	MAGICIAN_EGPIO(0, 2)
#define EGPIO_MAGICIAN_LED_POWER	MAGICIAN_EGPIO(0, 5)
#define EGPIO_MAGICIAN_GSM_RESET	MAGICIAN_EGPIO(0, 6)
#define EGPIO_MAGICIAN_LCD_POWER	MAGICIAN_EGPIO(0, 7)
#define EGPIO_MAGICIAN_SPK_POWER	MAGICIAN_EGPIO(1, 0)
#define EGPIO_MAGICIAN_EP_POWER		MAGICIAN_EGPIO(1, 1)
#define EGPIO_MAGICIAN_IN_SEL0		MAGICIAN_EGPIO(1, 2)
#define EGPIO_MAGICIAN_IN_SEL1		MAGICIAN_EGPIO(1, 3)
#define EGPIO_MAGICIAN_MIC_POWER	MAGICIAN_EGPIO(1, 4)
#define EGPIO_MAGICIAN_CODEC_RESET	MAGICIAN_EGPIO(1, 5)
#define EGPIO_MAGICIAN_CODEC_POWER	MAGICIAN_EGPIO(1, 6)
#define EGPIO_MAGICIAN_BL_POWER		MAGICIAN_EGPIO(1, 7)
#define EGPIO_MAGICIAN_SD_POWER		MAGICIAN_EGPIO(2, 0)
#define EGPIO_MAGICIAN_CARKIT_MIC	MAGICIAN_EGPIO(2, 1)
#define EGPIO_MAGICIAN_IR_RX_SHUTDOWN	MAGICIAN_EGPIO(2, 2)
#define EGPIO_MAGICIAN_FLASH_VPP	MAGICIAN_EGPIO(2, 3)
#define EGPIO_MAGICIAN_BL_POWER2	MAGICIAN_EGPIO(2, 4)
#define EGPIO_MAGICIAN_BQ24022_ISET2	MAGICIAN_EGPIO(2, 5)
#define EGPIO_MAGICIAN_NICD_CHARGE	MAGICIAN_EGPIO(2, 6)
#define EGPIO_MAGICIAN_GSM_POWER	MAGICIAN_EGPIO(2, 7)

/* input */

/* USB or AC charger type */
#define EGPIO_MAGICIAN_CABLE_TYPE	MAGICIAN_EGPIO(4, 0)
/*
 * Vbus is detected
 * FIXME behaves like (6,3), may differ for host/device
 */
#define EGPIO_MAGICIAN_CABLE_VBUS	MAGICIAN_EGPIO(4, 1)

#define EGPIO_MAGICIAN_BOARD_ID0	MAGICIAN_EGPIO(5, 0)
#define EGPIO_MAGICIAN_BOARD_ID1	MAGICIAN_EGPIO(5, 1)
#define EGPIO_MAGICIAN_BOARD_ID2	MAGICIAN_EGPIO(5, 2)
#define EGPIO_MAGICIAN_LCD_SELECT	MAGICIAN_EGPIO(5, 3)
#define EGPIO_MAGICIAN_nSD_READONLY	MAGICIAN_EGPIO(5, 4)

#define EGPIO_MAGICIAN_EP_INSERT	MAGICIAN_EGPIO(6, 1)
/* FIXME behaves like (4,1), may differ for host/device */
#define EGPIO_MAGICIAN_CABLE_INSERTED	MAGICIAN_EGPIO(6, 3)

#endif /* _MAGICIAN_H_ */

repo_name: angery/linux


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/mainstone.c
 *
 *  Support for the Intel HCDDBBVA0 Development Platform.
 *  (go figure how they came up with such name...)
 *
 *  Author:	Nicolas Pitre
 *  Created:	Nov 05, 2002
 *  Copyright:	MontaVista Software Inc.
 */
#include <linux/gpio.h>
#include <linux/gpio/gpio-reg.h>
#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/smc91x.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/slab.h>
#include <linux/leds.h>

#include <asm/types.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 "pxa27x.h"
#include "mainstone.h"
#include <linux/platform_data/asoc-pxa.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include "addr-map.h"
#include "smemc.h"

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

static unsigned long mainstone_pin_config[] = {
	/* Chip Select */
	GPIO15_nCS_1,

	/* LCD - 16bpp Active TFT */
	GPIOxx_LCD_TFT_16BPP,
	GPIO16_PWM0_OUT,	/* Backlight */

	/* MMC */
	GPIO32_MMC_CLK,
	GPIO112_MMC_CMD,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,

	/* USB Host Port 1 */
	GPIO88_USBH1_PWR,
	GPIO89_USBH1_PEN,

	/* PC Card */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO85_nPCE_1,
	GPIO54_nPCE_2,
	GPIO79_PSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,

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

	/* Keypad */
	GPIO93_KP_DKIN_0,
	GPIO94_KP_DKIN_1,
	GPIO95_KP_DKIN_2,
	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,
	GPIO99_KP_MKIN_5	| 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,
	GPIO96_KP_MKOUT_6,

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

	/* GPIO */
	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
};

static struct resource smc91x_resources[] = {
	[0] = {
		.start	= (MST_ETH_PHYS + 0x300),
		.end	= (MST_ETH_PHYS + 0xfffff),
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= MAINSTONE_IRQ(3),
		.end	= MAINSTONE_IRQ(3),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
	}
};

static struct smc91x_platdata mainstone_smc91x_info = {
	.flags	= SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
		  SMC91X_NOWAIT | SMC91X_USE_DMA,
	.pxa_u16_align4 = true,
};

static struct platform_device smc91x_device = {
	.name		= "smc91x",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(smc91x_resources),
	.resource	= smc91x_resources,
	.dev		= {
		.platform_data = &mainstone_smc91x_info,
	},
};

static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
{
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
	return 0;
}

static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
{
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
}

static long mst_audio_suspend_mask;

static void mst_audio_suspend(void *priv)
{
	mst_audio_suspend_mask = MST_MSCWR2;
	MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
}

static void mst_audio_resume(void *priv)
{
	MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
}

static pxa2xx_audio_ops_t mst_audio_ops = {
	.startup	= mst_audio_startup,
	.shutdown	= mst_audio_shutdown,
	.suspend	= mst_audio_suspend,
	.resume		= mst_audio_resume,
};

static struct resource flash_resources[] = {
	[0] = {
		.start	= PXA_CS0_PHYS,
		.end	= PXA_CS0_PHYS + SZ_64M - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= PXA_CS1_PHYS,
		.end	= PXA_CS1_PHYS + SZ_64M - 1,
		.flags	= IORESOURCE_MEM,
	},
};

static struct mtd_partition mainstoneflash0_partitions[] = {
	{
		.name =		"Bootloader",
		.size =		0x00040000,
		.offset =	0,
		.mask_flags =	MTD_WRITEABLE  /* force read-only */
	},{
		.name =		"Kernel",
		.size =		0x00400000,
		.offset =	0x00040000,
	},{
		.name =		"Filesystem",
		.size =		MTDPART_SIZ_FULL,
		.offset =	0x00440000
	}
};

static struct flash_platform_data mst_flash_data[2] = {
	{
		.map_name	= "cfi_probe",
		.parts		= mainstoneflash0_partitions,
		.nr_parts	= ARRAY_SIZE(mainstoneflash0_partitions),
	}, {
		.map_name	= "cfi_probe",
		.parts		= NULL,
		.nr_parts	= 0,
	}
};

static struct platform_device mst_flash_device[2] = {
	{
		.name		= "pxa2xx-flash",
		.id		= 0,
		.dev = {
			.platform_data = &mst_flash_data[0],
		},
		.resource = &flash_resources[0],
		.num_resources = 1,
	},
	{
		.name		= "pxa2xx-flash",
		.id		= 1,
		.dev = {
			.platform_data = &mst_flash_data[1],
		},
		.resource = &flash_resources[1],
		.num_resources = 1,
	},
};

#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static struct pwm_lookup mainstone_pwm_lookup[] = {
	PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
		   PWM_POLARITY_NORMAL),
};

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

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

static void __init mainstone_backlight_register(void)
{
	int ret;

	pwm_add_table(mainstone_pwm_lookup, ARRAY_SIZE(mainstone_pwm_lookup));

	ret = platform_device_register(&mainstone_backlight_device);
	if (ret) {
		printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret);
		pwm_remove_table(mainstone_pwm_lookup,
				 ARRAY_SIZE(mainstone_pwm_lookup));
	}
}
#else
#define mainstone_backlight_register()	do { } while (0)
#endif

static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
	.pixclock		= 50000,
	.xres			= 640,
	.yres			= 480,
	.bpp			= 16,
	.hsync_len		= 1,
	.left_margin		= 0x9f,
	.right_margin		= 1,
	.vsync_len		= 44,
	.upper_margin		= 0,
	.lower_margin		= 0,
	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
};

static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
	.pixclock		= 110000,
	.xres			= 240,
	.yres			= 320,
	.bpp			= 16,
	.hsync_len		= 4,
	.left_margin		= 8,
	.right_margin		= 20,
	.vsync_len		= 3,
	.upper_margin		= 1,
	.lower_margin		= 10,
	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
};

static struct pxafb_mach_info mainstone_pxafb_info = {
	.num_modes      	= 1,
	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};

static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
{
	int err;

	/* make sure SD/Memory Stick multiplexer's signals
	 * are routed to MMC controller
	 */
	MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;

	err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, 0,
			     "MMC card detect", data);
	if (err)
		printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");

	return err;
}

static int mainstone_mci_setpower(struct device *dev, unsigned int vdd)
{
	struct pxamci_platform_data* p_d = dev->platform_data;

	if (( 1 << vdd) & p_d->ocr_mask) {
		printk(KERN_DEBUG "%s: on\n", __func__);
		MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
		MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
	} else {
		printk(KERN_DEBUG "%s: off\n", __func__);
		MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
	}
	return 0;
}

static void mainstone_mci_exit(struct device *dev, void *data)
{
	free_irq(MAINSTONE_MMC_IRQ, data);
}

static struct pxamci_platform_data mainstone_mci_platform_data = {
	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
	.init 			= mainstone_mci_init,
	.setpower 		= mainstone_mci_setpower,
	.exit			= mainstone_mci_exit,
};

static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
{
	unsigned long flags;

	local_irq_save(flags);
	if (mode & IR_SIRMODE) {
		MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
	} else if (mode & IR_FIRMODE) {
		MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
	}
	pxa2xx_transceiver_mode(dev, mode);
	if (mode & IR_OFF) {
		MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
	} else {
		MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
	}
	local_irq_restore(flags);
}

static struct pxaficp_platform_data mainstone_ficp_platform_data = {
	.gpio_pwdown		= -1,
	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
	.transceiver_mode	= mainstone_irda_transceiver_mode,
};

static struct gpio_keys_button gpio_keys_button[] = {
	[0] = {
		.desc	= "wakeup",
		.code	= KEY_SUSPEND,
		.type	= EV_KEY,
		.gpio	= 1,
		.wakeup	= 1,
	},
};

static struct gpio_keys_platform_data mainstone_gpio_keys = {
	.buttons	= gpio_keys_button,
	.nbuttons	= 1,
};

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

static struct resource mst_cplds_resources[] = {
	[0] = {
		.start	= MST_FPGA_PHYS + 0xc0,
		.end	= MST_FPGA_PHYS + 0xe0 - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= PXA_GPIO_TO_IRQ(0),
		.end	= PXA_GPIO_TO_IRQ(0),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
	},
	[2] = {
		.start	= MAINSTONE_IRQ(0),
		.end	= MAINSTONE_IRQ(15),
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device mst_cplds_device = {
	.name		= "pxa_cplds_irqs",
	.id		= -1,
	.resource	= &mst_cplds_resources[0],
	.num_resources	= 3,
};

static struct platform_device *platform_devices[] __initdata = {
	&smc91x_device,
	&mst_flash_device[0],
	&mst_flash_device[1],
	&mst_gpio_keys_device,
	&mst_cplds_device,
};

static struct pxaohci_platform_data mainstone_ohci_platform_data = {
	.port_mode	= PMM_PERPORT_MODE,
	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
};

#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static const unsigned int mainstone_matrix_keys[] = {
	KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
	KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
	KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I),
	KEY(3, 1, KEY_J), KEY(4, 1, KEY_K), KEY(5, 1, KEY_L),
	KEY(0, 2, KEY_M), KEY(1, 2, KEY_N), KEY(2, 2, KEY_O),
	KEY(3, 2, KEY_P), KEY(4, 2, KEY_Q), KEY(5, 2, KEY_R),
	KEY(0, 3, KEY_S), KEY(1, 3, KEY_T), KEY(2, 3, KEY_U),
	KEY(3, 3, KEY_V), KEY(4, 3, KEY_W), KEY(5, 3, KEY_X),
	KEY(2, 4, KEY_Y), KEY(3, 4, KEY_Z),

	KEY(0, 4, KEY_DOT),	/* . */
	KEY(1, 4, KEY_CLOSE),	/* @ */
	KEY(4, 4, KEY_SLASH),
	KEY(5, 4, KEY_BACKSLASH),
	KEY(0, 5, KEY_HOME),
	KEY(1, 5, KEY_LEFTSHIFT),
	KEY(2, 5, KEY_SPACE),
	KEY(3, 5, KEY_SPACE),
	KEY(4, 5, KEY_ENTER),
	KEY(5, 5, KEY_BACKSPACE),

	KEY(0, 6, KEY_UP),
	KEY(1, 6, KEY_DOWN),
	KEY(2, 6, KEY_LEFT),
	KEY(3, 6, KEY_RIGHT),
	KEY(4, 6, KEY_SELECT),
};

static struct matrix_keymap_data mainstone_matrix_keymap_data = {
	.keymap			= mainstone_matrix_keys,
	.keymap_size		= ARRAY_SIZE(mainstone_matrix_keys),
};

struct pxa27x_keypad_platform_data mainstone_keypad_info = {
	.matrix_key_rows	= 6,
	.matrix_key_cols	= 7,
	.matrix_keymap_data	= &mainstone_matrix_keymap_data,

	.enable_rotary0		= 1,
	.rotary0_up_key		= KEY_UP,
	.rotary0_down_key	= KEY_DOWN,

	.debounce_interval	= 30,
};

static void __init mainstone_init_keypad(void)
{
	pxa_set_keypad_info(&mainstone_keypad_info);
}
#else
static inline void mainstone_init_keypad(void) {}
#endif

static int mst_pcmcia0_irqs[11] = {
	[0 ... 4] = -1,
	[5] = MAINSTONE_S0_CD_IRQ,
	[6 ... 7] = -1,
	[8] = MAINSTONE_S0_STSCHG_IRQ,
	[9] = -1,
	[10] = MAINSTONE_S0_IRQ,
};

static int mst_pcmcia1_irqs[11] = {
	[0 ... 4] = -1,
	[5] = MAINSTONE_S1_CD_IRQ,
	[6 ... 7] = -1,
	[8] = MAINSTONE_S1_STSCHG_IRQ,
	[9] = -1,
	[10] = MAINSTONE_S1_IRQ,
};

static struct gpiod_lookup_table mainstone_pcmcia_gpio_table = {
	.dev_id = "pxa2xx-pcmcia",
	.table = {
		GPIO_LOOKUP("mst-pcmcia0",  0, "a0vpp",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0",  1, "a1vpp",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0",  2, "a0vcc",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0",  3, "a1vcc",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0",  4, "areset",  GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0",  5, "adetect", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("mst-pcmcia0",  6, "avs1",    GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("mst-pcmcia0",  7, "avs2",    GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("mst-pcmcia0",  8, "abvd1",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0",  9, "abvd2",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia0", 10, "aready",  GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  0, "b0vpp",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  1, "b1vpp",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  2, "b0vcc",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  3, "b1vcc",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  4, "breset",  GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  5, "bdetect", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("mst-pcmcia1",  6, "bvs1",    GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("mst-pcmcia1",  7, "bvs2",    GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("mst-pcmcia1",  8, "bbvd1",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1",  9, "bbvd2",   GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("mst-pcmcia1", 10, "bready",  GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct gpiod_lookup_table mainstone_wm97xx_gpio_table = {
	.dev_id = "wm97xx-touch",
	.table = {
		GPIO_LOOKUP("gpio-pxa", 4, "touch", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static void __init mainstone_init(void)
{
	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */

	pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));

	/* Register board control register(s) as GPIOs */
	gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0, -1, 11,
		      "mst-pcmcia0", MST_PCMCIA_INPUTS, 0, NULL,
		      NULL, mst_pcmcia0_irqs);
	gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA1, -1, 11,
		      "mst-pcmcia1", MST_PCMCIA_INPUTS, 0, NULL,
		      NULL, mst_pcmcia1_irqs);
	gpiod_add_lookup_table(&mainstone_pcmcia_gpio_table);
	gpiod_add_lookup_table(&mainstone_wm97xx_gpio_table);

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

	mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
	mst_flash_data[1].width = 4;

	/* Compensate for SW7 which swaps the flash banks */
	mst_flash_data[SW7].name = "processor-flash";
	mst_flash_data[SW7 ^ 1].name = "mainboard-flash";

	printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
	       mst_flash_data[0].name);

	/* system bus arbiter setting
	 * - Core_Park
	 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
	 */
	ARB_CNTRL = ARB_CORE_PARK | 0x234;

	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));

	/* reading Mainstone's "Virtual Configuration Register"
	   might be handy to select LCD type here */
	if (0)
		mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
	else
		mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;

	pxa_set_fb_info(NULL, &mainstone_pxafb_info);
	mainstone_backlight_register();

	pxa_set_mci_info(&mainstone_mci_platform_data);
	pxa_set_ficp_info(&mainstone_ficp_platform_data);
	pxa_set_ohci_info(&mainstone_ohci_platform_data);
	pxa_set_i2c_info(NULL);
	pxa_set_ac97_info(&mst_audio_ops);

	mainstone_init_keypad();
}

static struct map_desc mainstone_io_desc[] __initdata = {
  	{	/* CPLD */
		.virtual	=  MST_FPGA_VIRT,
		.pfn		= __phys_to_pfn(MST_FPGA_PHYS),
		.length		= 0x00100000,
		.type		= MT_DEVICE
	}
};

static void __init mainstone_map_io(void)
{
	pxa27x_map_io();
	iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));

 	/*	for use I SRAM as framebuffer.	*/
 	PSLR |= 0xF04;
 	PCFR = 0x66;
}

/*
 * Driver for the 8 discrete LEDs available for general use:
 * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
 * so be sure to not monkey with them here.
 */

#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct mainstone_led {
	struct led_classdev	cdev;
	u8			mask;
};

/*
 * The triggers lines up below will only be used if the
 * LED triggers are compiled in.
 */
static const struct {
	const char *name;
	const char *trigger;
} mainstone_leds[] = {
	{ "mainstone:D28", "default-on", },
	{ "mainstone:D27", "cpu0", },
	{ "mainstone:D26", "heartbeat" },
	{ "mainstone:D25", },
	{ "mainstone:D24", },
	{ "mainstone:D23", },
	{ "mainstone:D22", },
	{ "mainstone:D21", },
};

static void mainstone_led_set(struct led_classdev *cdev,
			      enum led_brightness b)
{
	struct mainstone_led *led = container_of(cdev,
					 struct mainstone_led, cdev);
	u32 reg = MST_LEDCTRL;

	if (b != LED_OFF)
		reg |= led->mask;
	else
		reg &= ~led->mask;

	MST_LEDCTRL = reg;
}

static enum led_brightness mainstone_led_get(struct led_classdev *cdev)
{
	struct mainstone_led *led = container_of(cdev,
					 struct mainstone_led, cdev);
	u32 reg = MST_LEDCTRL;

	return (reg & led->mask) ? LED_FULL : LED_OFF;
}

static int __init mainstone_leds_init(void)
{
	int i;

	if (!machine_is_mainstone())
		return -ENODEV;

	/* All ON */
	MST_LEDCTRL |= 0xff;
	for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) {
		struct mainstone_led *led;

		led = kzalloc(sizeof(*led), GFP_KERNEL);
		if (!led)
			break;

		led->cdev.name = mainstone_leds[i].name;
		led->cdev.brightness_set = mainstone_led_set;
		led->cdev.brightness_get = mainstone_led_get;
		led->cdev.default_trigger = mainstone_leds[i].trigger;
		led->mask = BIT(i);

		if (led_classdev_register(NULL, &led->cdev) < 0) {
			kfree(led);
			break;
		}
	}

	return 0;
}

/*
 * Since we may have triggers on any subsystem, defer registration
 * until after subsystem_init.
 */
fs_initcall(mainstone_leds_init);
#endif

MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
	/* Maintainer: MontaVista Software Inc. */
	.atag_offset	= 0x100,	/* BLOB boot parameter setting */
	.map_io		= mainstone_map_io,
	.nr_irqs	= MAINSTONE_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= mainstone_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  Author:	Nicolas Pitre
 *  Created:	Nov 14, 2002
 *  Copyright:	MontaVista Software Inc.
 */

#ifndef ASM_ARCH_MAINSTONE_H
#define ASM_ARCH_MAINSTONE_H

#include "irqs.h"

#define MST_ETH_PHYS		PXA_CS4_PHYS

#define MST_FPGA_PHYS		PXA_CS2_PHYS
#define MST_FPGA_VIRT		(0xf0000000)
#define MST_P2V(x)		((x) - MST_FPGA_PHYS + MST_FPGA_VIRT)
#define MST_V2P(x)		((x) - MST_FPGA_VIRT + MST_FPGA_PHYS)

#ifndef __ASSEMBLY__
# define __MST_REG(x)		(*((volatile unsigned long *)MST_P2V(x)))
#else
# define __MST_REG(x)		MST_P2V(x)
#endif

/* board level registers in the FPGA */

#define MST_LEDDAT1		__MST_REG(0x08000010)
#define MST_LEDDAT2		__MST_REG(0x08000014)
#define MST_LEDCTRL		__MST_REG(0x08000040)
#define MST_GPSWR		__MST_REG(0x08000060)
#define MST_MSCWR1		__MST_REG(0x08000080)
#define MST_MSCWR2		__MST_REG(0x08000084)
#define MST_MSCWR3		__MST_REG(0x08000088)
#define MST_MSCRD		__MST_REG(0x08000090)
#define MST_INTMSKENA		__MST_REG(0x080000c0)
#define MST_INTSETCLR		__MST_REG(0x080000d0)
#define MST_PCMCIA0		__MST_REG(0x080000e0)
#define MST_PCMCIA1		__MST_REG(0x080000e4)

#define MST_MSCWR1_CAMERA_ON	(1 << 15)  /* Camera interface power control */
#define MST_MSCWR1_CAMERA_SEL	(1 << 14)  /* Camera interface mux control */
#define MST_MSCWR1_LCD_CTL	(1 << 13)  /* General-purpose LCD control */
#define MST_MSCWR1_MS_ON	(1 << 12)  /* Memory Stick power control */
#define MST_MSCWR1_MMC_ON	(1 << 11)  /* MultiMediaCard* power control */
#define MST_MSCWR1_MS_SEL	(1 << 10)  /* SD/MS multiplexer control */
#define MST_MSCWR1_BB_SEL	(1 << 9)   /* PCMCIA/Baseband multiplexer */
#define MST_MSCWR1_BT_ON	(1 << 8)   /* Bluetooth UART transceiver */
#define MST_MSCWR1_BTDTR	(1 << 7)   /* Bluetooth UART DTR */

#define MST_MSCWR1_IRDA_MASK	(3 << 5)   /* IrDA transceiver mode */
#define MST_MSCWR1_IRDA_FULL	(0 << 5)   /* full distance power */
#define MST_MSCWR1_IRDA_OFF	(1 << 5)   /* shutdown */
#define MST_MSCWR1_IRDA_MED	(2 << 5)   /* 2/3 distance power */
#define MST_MSCWR1_IRDA_LOW	(3 << 5)   /* 1/3 distance power */

#define MST_MSCWR1_IRDA_FIR	(1 << 4)   /* IrDA transceiver SIR/FIR */
#define MST_MSCWR1_GREENLED	(1 << 3)   /* LED D1 control */
#define MST_MSCWR1_PDC_CTL	(1 << 2)   /* reserved */
#define MST_MSCWR1_MTR_ON	(1 << 1)   /* Silent alert motor */
#define MST_MSCWR1_SYSRESET	(1 << 0)   /* System reset */

#define MST_MSCWR2_USB_OTG_RST	(1 << 6)   /* USB On The Go reset */
#define MST_MSCWR2_USB_OTG_SEL	(1 << 5)   /* USB On The Go control */
#define MST_MSCWR2_nUSBC_SC	(1 << 4)   /* USB client soft connect control */
#define MST_MSCWR2_I2S_SPKROFF	(1 << 3)   /* I2S CODEC amplifier control */
#define MST_MSCWR2_AC97_SPKROFF	(1 << 2)   /* AC97 CODEC amplifier control */
#define MST_MSCWR2_RADIO_PWR	(1 << 1)   /* Radio module power control */
#define MST_MSCWR2_RADIO_WAKE	(1 << 0)   /* Radio module wake-up signal */

#define MST_MSCWR3_GPIO_RESET_EN	(1 << 2) /* Enable GPIO Reset */
#define MST_MSCWR3_GPIO_RESET		(1 << 1) /* Initiate a GPIO Reset */
#define MST_MSCWR3_COMMS_SW_RESET	(1 << 0) /* Communications Processor Reset Control */

#define MST_MSCRD_nPENIRQ	(1 << 9)   /* ADI7873* nPENIRQ signal */
#define MST_MSCRD_nMEMSTK_CD	(1 << 8)   /* Memory Stick detection signal */
#define MST_MSCRD_nMMC_CD	(1 << 7)   /* SD/MMC card detection signal */
#define MST_MSCRD_nUSIM_CD	(1 << 6)   /* USIM card detection signal */
#define MST_MSCRD_USB_CBL	(1 << 5)   /* USB client cable status */
#define MST_MSCRD_TS_BUSY	(1 << 4)   /* ADI7873 busy */
#define MST_MSCRD_BTDSR		(1 << 3)   /* Bluetooth UART DSR */
#define MST_MSCRD_BTRI		(1 << 2)   /* Bluetooth UART Ring Indicator */
#define MST_MSCRD_BTDCD		(1 << 1)   /* Bluetooth UART DCD */
#define MST_MSCRD_nMMC_WP	(1 << 0)   /* SD/MMC write-protect status */

#define MST_INT_S1_IRQ		(1 << 15)  /* PCMCIA socket 1 IRQ */
#define MST_INT_S1_STSCHG	(1 << 14)  /* PCMCIA socket 1 status changed */
#define MST_INT_S1_CD		(1 << 13)  /* PCMCIA socket 1 card detection */
#define MST_INT_S0_IRQ		(1 << 11)  /* PCMCIA socket 0 IRQ */
#define MST_INT_S0_STSCHG	(1 << 10)  /* PCMCIA socket 0 status changed */
#define MST_INT_S0_CD		(1 << 9)   /* PCMCIA socket 0 card detection */
#define MST_INT_nEXBRD_INT	(1 << 7)   /* Expansion board IRQ */
#define MST_INT_MSINS		(1 << 6)   /* Memory Stick* detection */
#define MST_INT_PENIRQ		(1 << 5)   /* ADI7873* touch-screen IRQ */
#define MST_INT_AC97		(1 << 4)   /* AC'97 CODEC IRQ */
#define MST_INT_ETHERNET	(1 << 3)   /* Ethernet controller IRQ */
#define MST_INT_USBC		(1 << 2)   /* USB client cable detection IRQ */
#define MST_INT_USIM		(1 << 1)   /* USIM card detection IRQ */
#define MST_INT_MMC		(1 << 0)   /* MMC/SD card detection IRQ */

#define MST_PCMCIA_nIRQ		(1 << 10)  /* IRQ / ready signal */
#define MST_PCMCIA_nSPKR_BVD2	(1 << 9)   /* VDD sense / digital speaker */
#define MST_PCMCIA_nSTSCHG_BVD1	(1 << 8)   /* VDD sense / card status changed */
#define MST_PCMCIA_nVS2		(1 << 7)   /* VSS voltage sense */
#define MST_PCMCIA_nVS1		(1 << 6)   /* VSS voltage sense */
#define MST_PCMCIA_nCD		(1 << 5)   /* Card detection signal */
#define MST_PCMCIA_RESET	(1 << 4)   /* Card reset signal */
#define MST_PCMCIA_PWR_MASK	(0x000f)   /* MAX1602 power-supply controls */

#define MST_PCMCIA_PWR_VPP_0    0x0	   /* voltage VPP = 0V */
#define MST_PCMCIA_PWR_VPP_120  0x2 	   /* voltage VPP = 12V*/
#define MST_PCMCIA_PWR_VPP_VCC  0x1	   /* voltage VPP = VCC */
#define MST_PCMCIA_PWR_VCC_0    0x0	   /* voltage VCC = 0V */
#define MST_PCMCIA_PWR_VCC_33   0x8	   /* voltage VCC = 3.3V */
#define MST_PCMCIA_PWR_VCC_50   0x4	   /* voltage VCC = 5.0V */

#define MST_PCMCIA_INPUTS \
	(MST_PCMCIA_nIRQ | MST_PCMCIA_nSPKR_BVD2 | MST_PCMCIA_nSTSCHG_BVD1 | \
	 MST_PCMCIA_nVS2 | MST_PCMCIA_nVS1 | MST_PCMCIA_nCD)

/* board specific IRQs */
#define MAINSTONE_NR_IRQS	IRQ_BOARD_START

#define MAINSTONE_IRQ(x)	(MAINSTONE_NR_IRQS + (x))
#define MAINSTONE_MMC_IRQ	MAINSTONE_IRQ(0)
#define MAINSTONE_USIM_IRQ	MAINSTONE_IRQ(1)
#define MAINSTONE_USBC_IRQ	MAINSTONE_IRQ(2)
#define MAINSTONE_ETHERNET_IRQ	MAINSTONE_IRQ(3)
#define MAINSTONE_AC97_IRQ	MAINSTONE_IRQ(4)
#define MAINSTONE_PEN_IRQ	MAINSTONE_IRQ(5)
#define MAINSTONE_MSINS_IRQ	MAINSTONE_IRQ(6)
#define MAINSTONE_EXBRD_IRQ	MAINSTONE_IRQ(7)
#define MAINSTONE_S0_CD_IRQ	MAINSTONE_IRQ(9)
#define MAINSTONE_S0_STSCHG_IRQ	MAINSTONE_IRQ(10)
#define MAINSTONE_S0_IRQ	MAINSTONE_IRQ(11)
#define MAINSTONE_S1_CD_IRQ	MAINSTONE_IRQ(13)
#define MAINSTONE_S1_STSCHG_IRQ	MAINSTONE_IRQ(14)
#define MAINSTONE_S1_IRQ	MAINSTONE_IRQ(15)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARCH_MFP_PXA25X_H
#define __ASM_ARCH_MFP_PXA25X_H

#include "mfp-pxa2xx.h"

/* GPIO */
#define GPIO2_GPIO		MFP_CFG_IN(GPIO2, AF0)
#define GPIO3_GPIO		MFP_CFG_IN(GPIO3, AF0)
#define GPIO4_GPIO		MFP_CFG_IN(GPIO4, AF0)
#define GPIO5_GPIO		MFP_CFG_IN(GPIO5, AF0)
#define GPIO6_GPIO		MFP_CFG_IN(GPIO6, AF0)
#define GPIO7_GPIO		MFP_CFG_IN(GPIO7, AF0)
#define GPIO8_GPIO		MFP_CFG_IN(GPIO8, AF0)

#define GPIO1_RST		MFP_CFG_IN(GPIO1, AF1)

/* Crystal and Clock Signals */
#define GPIO10_RTCCLK		MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
#define GPIO70_RTCCLK		MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
#define GPIO7_48MHz		MFP_CFG_OUT(GPIO7,  AF1, DRIVE_LOW)
#define GPIO11_3_6MHz		MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
#define GPIO71_3_6MHz		MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW)
#define GPIO12_32KHz		MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
#define GPIO72_32kHz		MFP_CFG_OUT(GPIO72, AF1, DRIVE_LOW)

/* SDRAM and Static Memory I/O Signals */
#define GPIO15_nCS_1		MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
#define GPIO78_nCS_2		MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
#define GPIO79_nCS_3		MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
#define GPIO80_nCS_4		MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
#define GPIO33_nCS_5		MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)

/* Miscellaneous I/O and DMA Signals */
#define GPIO18_RDY		MFP_CFG_IN(GPIO18, AF1)
#define GPIO20_DREQ_0		MFP_CFG_IN(GPIO20, AF1)
#define GPIO19_DREQ_1		MFP_CFG_IN(GPIO19, AF1)

/* Alternate Bus Master Mode I/O Signals */
#define GPIO13_MBGNT		MFP_CFG_OUT(GPIO13, AF2, DRIVE_LOW)
#define GPIO73_MBGNT		MFP_CFG_OUT(GPIO73, AF1, DRIVE_LOW)
#define GPIO14_MBREQ		MFP_CFG_IN(GPIO14, AF1)
#define GPIO66_MBREQ		MFP_CFG_IN(GPIO66, AF1)

/* PC CARD */
#define GPIO52_nPCE_1		MFP_CFG_OUT(GPIO52, AF2, DRIVE_HIGH)
#define GPIO53_nPCE_2		MFP_CFG_OUT(GPIO53, AF2, DRIVE_HIGH)
#define GPIO55_nPREG		MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
#define GPIO50_nPIOR		MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
#define GPIO51_nPIOW		MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
#define GPIO49_nPWE		MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
#define GPIO48_nPOE		MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
#define GPIO57_nIOIS16		MFP_CFG_IN(GPIO57, AF1)
#define GPIO56_nPWAIT		MFP_CFG_IN(GPIO56, AF1)
#define GPIO54_nPSKTSEL		MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)

/* FFUART */
#define GPIO34_FFUART_RXD	MFP_CFG_IN(GPIO34, AF1)
#define GPIO35_FFUART_CTS	MFP_CFG_IN(GPIO35, AF1)
#define GPIO36_FFUART_DCD	MFP_CFG_IN(GPIO36, AF1)
#define GPIO37_FFUART_DSR	MFP_CFG_IN(GPIO37, AF1)
#define GPIO38_FFUART_RI	MFP_CFG_IN(GPIO38, AF1)
#define GPIO39_FFUART_TXD	MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
#define GPIO40_FFUART_DTR	MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
#define GPIO41_FFUART_RTS	MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)

/* BTUART */
#define GPIO42_BTUART_RXD	MFP_CFG_IN(GPIO42, AF1)
#define GPIO43_BTUART_TXD	MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
#define GPIO44_BTUART_CTS	MFP_CFG_IN(GPIO44, AF1)
#define GPIO45_BTUART_RTS	MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)

/* STUART */
#define GPIO46_STUART_RXD	MFP_CFG_IN(GPIO46, AF2)
#define GPIO47_STUART_TXD	MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)

/* HWUART */
#define GPIO42_HWUART_RXD	MFP_CFG_IN(GPIO42, AF3)
#define GPIO43_HWUART_TXD	MFP_CFG_OUT(GPIO43, AF3, DRIVE_HIGH)
#define GPIO44_HWUART_CTS	MFP_CFG_IN(GPIO44, AF3)
#define GPIO45_HWUART_RTS	MFP_CFG_OUT(GPIO45, AF3, DRIVE_HIGH)
#define GPIO48_HWUART_TXD	MFP_CFG_OUT(GPIO48, AF1, DRIVE_HIGH)
#define GPIO49_HWUART_RXD	MFP_CFG_IN(GPIO49, AF1)
#define GPIO50_HWUART_CTS	MFP_CFG_IN(GPIO50, AF1)
#define GPIO51_HWUART_RTS	MFP_CFG_OUT(GPIO51, AF1, DRIVE_HIGH)

/* FICP */
#define GPIO46_FICP_RXD		MFP_CFG_IN(GPIO46, AF1)
#define GPIO47_FICP_TXD		MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)

/* PWM 0/1 */
#define GPIO16_PWM0_OUT		MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
#define GPIO17_PWM1_OUT		MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)

/* AC97 */
#define GPIO28_AC97_BITCLK	MFP_CFG_IN(GPIO28, AF1)
#define GPIO29_AC97_SDATA_IN_0	MFP_CFG_IN(GPIO29, AF1)
#define GPIO30_AC97_SDATA_OUT	MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
#define GPIO31_AC97_SYNC	MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
#define GPIO32_AC97_SDATA_IN_1	MFP_CFG_IN(GPIO32, AF1)

/* I2S */
#define GPIO28_I2S_BITCLK_IN	MFP_CFG_IN(GPIO28, AF2)
#define GPIO28_I2S_BITCLK_OUT	MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
#define GPIO29_I2S_SDATA_IN	MFP_CFG_IN(GPIO29, AF2)
#define GPIO30_I2S_SDATA_OUT	MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
#define GPIO31_I2S_SYNC		MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
#define GPIO32_I2S_SYSCLK	MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)

/* SSP 1 */
#define GPIO23_SSP1_SCLK	MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
#define GPIO24_SSP1_SFRM	MFP_CFG_OUT(GPIO24, AF2, DRIVE_LOW)
#define GPIO25_SSP1_TXD		MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
#define GPIO26_SSP1_RXD		MFP_CFG_IN(GPIO26, AF1)
#define GPIO27_SSP1_EXTCLK	MFP_CFG_IN(GPIO27, AF1)

/* SSP 2 - NSSP */
#define GPIO81_SSP2_CLK_OUT 	MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
#define GPIO81_SSP2_CLK_IN  	MFP_CFG_IN(GPIO81, AF1)
#define GPIO82_SSP2_FRM_OUT 	MFP_CFG_OUT(GPIO82, AF1, DRIVE_LOW)
#define GPIO82_SSP2_FRM_IN  	MFP_CFG_IN(GPIO82, AF1)
#define GPIO83_SSP2_TXD      	MFP_CFG_OUT(GPIO83, AF1, DRIVE_LOW)
#define GPIO83_SSP2_RXD      	MFP_CFG_IN(GPIO83, AF2)
#define GPIO84_SSP2_TXD      	MFP_CFG_OUT(GPIO84, AF1, DRIVE_LOW)
#define GPIO84_SSP2_RXD      	MFP_CFG_IN(GPIO84, AF2)

/* MMC */
#define GPIO6_MMC_CLK		MFP_CFG_OUT(GPIO6, AF1, DRIVE_LOW)
#define GPIO8_MMC_CS0		MFP_CFG_OUT(GPIO8, AF1, DRIVE_LOW)
#define GPIO9_MMC_CS1		MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
#define GPIO34_MMC_CS0		MFP_CFG_OUT(GPIO34, AF2, DRIVE_LOW)
#define GPIO39_MMC_CS1		MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
#define GPIO53_MMC_CLK		MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
#define GPIO54_MMC_CLK		MFP_CFG_OUT(GPIO54, AF1, DRIVE_LOW)
#define GPIO69_MMC_CLK		MFP_CFG_OUT(GPIO69, AF1, DRIVE_LOW)
#define GPIO67_MMC_CS0		MFP_CFG_OUT(GPIO67, AF1, DRIVE_LOW)
#define GPIO68_MMC_CS1		MFP_CFG_OUT(GPIO68, AF1, DRIVE_LOW)

/* LCD */
#define GPIO58_LCD_LDD_0	MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
#define GPIO59_LCD_LDD_1	MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
#define GPIO60_LCD_LDD_2	MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
#define GPIO61_LCD_LDD_3	MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
#define GPIO62_LCD_LDD_4	MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
#define GPIO63_LCD_LDD_5	MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
#define GPIO64_LCD_LDD_6	MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
#define GPIO65_LCD_LDD_7	MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
#define GPIO66_LCD_LDD_8	MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
#define GPIO67_LCD_LDD_9	MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
#define GPIO68_LCD_LDD_10	MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
#define GPIO69_LCD_LDD_11	MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
#define GPIO70_LCD_LDD_12	MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
#define GPIO71_LCD_LDD_13	MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
#define GPIO72_LCD_LDD_14	MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
#define GPIO73_LCD_LDD_15	MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
#define GPIO74_LCD_FCLK		MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
#define GPIO75_LCD_LCLK		MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
#define GPIO76_LCD_PCLK		MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
#define GPIO77_LCD_BIAS		MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)

#ifdef CONFIG_CPU_PXA26x
/* GPIO */
#define GPIO85_GPIO		MFP_CFG_IN(GPIO85, AF0)
#define GPIO86_GPIO		MFP_CFG_IN(GPIO86, AF1)
#define GPIO87_GPIO		MFP_CFG_IN(GPIO87, AF1)
#define GPIO88_GPIO		MFP_CFG_IN(GPIO88, AF1)
#define GPIO89_GPIO		MFP_CFG_IN(GPIO89, AF1)

/* SDRAM */
#define GPIO86_nSDCS2		MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
#define GPIO87_nSDCS3		MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
#define GPIO88_RDnWR		MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)

/* USB */
#define GPIO9_USB_RCV		MFP_CFG_IN(GPIO9, AF1)
#define GPIO32_USB_VP		MFP_CFG_IN(GPIO32, AF2)
#define GPIO34_USB_VM		MFP_CFG_IN(GPIO34, AF2)
#define GPIO39_USB_VPO		MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
#define GPIO56_USB_VMO		MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
#define GPIO57_USB_nOE		MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)

/* ASSP */
#define GPIO28_ASSP_BITCLK_IN	MFP_CFG_IN(GPIO28, AF3)
#define GPIO28_ASSP_BITCLK_OUT	MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
#define GPIO29_ASSP_RXD		MFP_CFG_IN(GPIO29, AF3)
#define GPIO30_ASSP_TXD		MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
#define GPIO31_ASSP_SFRM_IN	MFP_CFG_IN(GPIO31, AF1)
#define GPIO31_ASSP_SFRM_OUT	MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)

/* AC97 */
#define GPIO89_AC97_nRESET	MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
#endif	/* CONFIG_CPU_PXA26x */

/* commonly used pin configurations */
#define GPIOxx_LCD_16BPP	\
	GPIO58_LCD_LDD_0,	\
	GPIO59_LCD_LDD_1,	\
	GPIO60_LCD_LDD_2,	\
	GPIO61_LCD_LDD_3,	\
	GPIO62_LCD_LDD_4,	\
	GPIO63_LCD_LDD_5,	\
	GPIO64_LCD_LDD_6,	\
	GPIO65_LCD_LDD_7,	\
	GPIO66_LCD_LDD_8,	\
	GPIO67_LCD_LDD_9,	\
	GPIO68_LCD_LDD_10,	\
	GPIO69_LCD_LDD_11,	\
	GPIO70_LCD_LDD_12,	\
	GPIO71_LCD_LDD_13,	\
	GPIO72_LCD_LDD_14,	\
	GPIO73_LCD_LDD_15

#define GPIOxx_LCD_DSTN_16BPP	\
	GPIOxx_LCD_16BPP,	\
	GPIO74_LCD_FCLK,	\
	GPIO75_LCD_LCLK,	\
	GPIO76_LCD_PCLK

#define GPIOxx_LCD_TFT_16BPP	\
	GPIOxx_LCD_16BPP,	\
	GPIO74_LCD_FCLK,	\
	GPIO75_LCD_LCLK,	\
	GPIO76_LCD_PCLK,	\
	GPIO77_LCD_BIAS

#endif /* __ASM_ARCH_MFP_PXA25X_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARCH_MFP_PXA27X_H
#define __ASM_ARCH_MFP_PXA27X_H

/*
 * NOTE:  for those special-function bidirectional GPIOs, as described
 * in the "PXA27x Developer's Manual" Section 24.4.2.1, only its input
 * alternative is preserved, the direction is actually selected by the
 * specific controller, and this should work in most cases.
 */

#include "mfp-pxa2xx.h"

/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
 * bit is set, regardless of the GPIO configuration
 */
#define GPIO3_GPIO		MFP_CFG_IN(GPIO3, AF0)
#define GPIO4_GPIO		MFP_CFG_IN(GPIO4, AF0)

/* GPIO */
#define GPIO85_GPIO		MFP_CFG_IN(GPIO85, AF0)
#define GPIO86_GPIO		MFP_CFG_IN(GPIO86, AF0)
#define GPIO87_GPIO		MFP_CFG_IN(GPIO87, AF0)
#define GPIO88_GPIO		MFP_CFG_IN(GPIO88, AF0)
#define GPIO89_GPIO		MFP_CFG_IN(GPIO89, AF0)
#define GPIO90_GPIO		MFP_CFG_IN(GPIO90, AF0)
#define GPIO91_GPIO		MFP_CFG_IN(GPIO91, AF0)
#define GPIO92_GPIO		MFP_CFG_IN(GPIO92, AF0)
#define GPIO93_GPIO		MFP_CFG_IN(GPIO93, AF0)
#define GPIO94_GPIO		MFP_CFG_IN(GPIO94, AF0)
#define GPIO95_GPIO		MFP_CFG_IN(GPIO95, AF0)
#define GPIO96_GPIO		MFP_CFG_IN(GPIO96, AF0)
#define GPIO97_GPIO		MFP_CFG_IN(GPIO97, AF0)
#define GPIO98_GPIO		MFP_CFG_IN(GPIO98, AF0)
#define GPIO99_GPIO		MFP_CFG_IN(GPIO99, AF0)
#define GPIO100_GPIO		MFP_CFG_IN(GPIO100, AF0)
#define GPIO101_GPIO		MFP_CFG_IN(GPIO101, AF0)
#define GPIO102_GPIO		MFP_CFG_IN(GPIO102, AF0)
#define GPIO103_GPIO		MFP_CFG_IN(GPIO103, AF0)
#define GPIO104_GPIO		MFP_CFG_IN(GPIO104, AF0)
#define GPIO105_GPIO		MFP_CFG_IN(GPIO105, AF0)
#define GPIO106_GPIO		MFP_CFG_IN(GPIO106, AF0)
#define GPIO107_GPIO		MFP_CFG_IN(GPIO107, AF0)
#define GPIO108_GPIO		MFP_CFG_IN(GPIO108, AF0)
#define GPIO109_GPIO		MFP_CFG_IN(GPIO109, AF0)
#define GPIO110_GPIO		MFP_CFG_IN(GPIO110, AF0)
#define GPIO111_GPIO		MFP_CFG_IN(GPIO111, AF0)
#define GPIO112_GPIO		MFP_CFG_IN(GPIO112, AF0)
#define GPIO113_GPIO		MFP_CFG_IN(GPIO113, AF0)
#define GPIO114_GPIO		MFP_CFG_IN(GPIO114, AF0)
#define GPIO115_GPIO		MFP_CFG_IN(GPIO115, AF0)
#define GPIO116_GPIO		MFP_CFG_IN(GPIO116, AF0)
#define GPIO117_GPIO		MFP_CFG_IN(GPIO117, AF0)
#define GPIO118_GPIO		MFP_CFG_IN(GPIO118, AF0)
#define GPIO119_GPIO		MFP_CFG_IN(GPIO119, AF0)
#define GPIO120_GPIO		MFP_CFG_IN(GPIO120, AF0)

/* Crystal and Clock Signals */
#define GPIO9_HZ_CLK		MFP_CFG_OUT(GPIO9,  AF1, DRIVE_LOW)
#define GPIO10_HZ_CLK		MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
#define GPIO11_48_MHz		MFP_CFG_OUT(GPIO11, AF3, DRIVE_LOW)
#define GPIO12_48_MHz		MFP_CFG_OUT(GPIO12, AF3, DRIVE_LOW)
#define GPIO13_CLK_EXT		MFP_CFG_IN(GPIO13, AF1)

/* OS Timer Signals */
#define GPIO11_EXT_SYNC_0	MFP_CFG_IN(GPIO11, AF1)
#define GPIO12_EXT_SYNC_1	MFP_CFG_IN(GPIO12, AF1)
#define GPIO9_CHOUT_0		MFP_CFG_OUT(GPIO9,  AF3, DRIVE_LOW)
#define GPIO10_CHOUT_1		MFP_CFG_OUT(GPIO10, AF3, DRIVE_LOW)
#define GPIO11_CHOUT_0		MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
#define GPIO12_CHOUT_1		MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)

/* SDRAM and Static Memory I/O Signals */
#define GPIO20_nSDCS_2		MFP_CFG_OUT(GPIO20, AF1, DRIVE_HIGH)
#define GPIO21_nSDCS_3		MFP_CFG_OUT(GPIO21, AF1, DRIVE_HIGH)
#define GPIO15_nCS_1		MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
#define GPIO78_nCS_2		MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
#define GPIO79_nCS_3		MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
#define GPIO80_nCS_4		MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
#define GPIO33_nCS_5		MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)

/* Miscellaneous I/O and DMA Signals */
#define GPIO21_DVAL_0		MFP_CFG_OUT(GPIO21, AF2, DRIVE_HIGH)
#define GPIO116_DVAL_0		MFP_CFG_OUT(GPIO116, AF1, DRIVE_HIGH)
#define GPIO33_DVAL_1		MFP_CFG_OUT(GPIO33, AF1, DRIVE_HIGH)
#define GPIO96_DVAL_1		MFP_CFG_OUT(GPIO96, AF2, DRIVE_HIGH)
#define GPIO18_RDY		MFP_CFG_IN(GPIO18, AF1)
#define GPIO20_DREQ_0		MFP_CFG_IN(GPIO20, AF1)
#define GPIO115_DREQ_0		MFP_CFG_IN(GPIO115, AF1)
#define GPIO80_DREQ_1		MFP_CFG_IN(GPIO80, AF1)
#define GPIO97_DREQ_1		MFP_CFG_IN(GPIO97, AF2)
#define GPIO85_DREQ_2		MFP_CFG_IN(GPIO85, AF2)
#define GPIO100_DREQ_2		MFP_CFG_IN(GPIO100, AF2)

/* Alternate Bus Master Mode I/O Signals */
#define GPIO20_MBREQ		MFP_CFG_IN(GPIO20, AF2)
#define GPIO80_MBREQ		MFP_CFG_IN(GPIO80, AF2)
#define GPIO96_MBREQ		MFP_CFG_IN(GPIO96, AF2)
#define GPIO115_MBREQ		MFP_CFG_IN(GPIO115, AF3)
#define GPIO21_MBGNT		MFP_CFG_OUT(GPIO21, AF3, DRIVE_LOW)
#define GPIO33_MBGNT		MFP_CFG_OUT(GPIO33, AF3, DRIVE_LOW)
#define GPIO97_MBGNT		MFP_CFG_OUT(GPIO97, AF2, DRIVE_LOW)
#define GPIO116_MBGNT		MFP_CFG_OUT(GPIO116, AF3, DRIVE_LOW)

/* PC CARD */
#define GPIO15_nPCE_1		MFP_CFG_OUT(GPIO15, AF1, DRIVE_HIGH)
#define GPIO85_nPCE_1		MFP_CFG_OUT(GPIO85, AF1, DRIVE_HIGH)
#define GPIO86_nPCE_1		MFP_CFG_OUT(GPIO86, AF1, DRIVE_HIGH)
#define GPIO102_nPCE_1		MFP_CFG_OUT(GPIO102, AF1, DRIVE_HIGH)
#define GPIO54_nPCE_2		MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
#define GPIO78_nPCE_2		MFP_CFG_OUT(GPIO78, AF1, DRIVE_HIGH)
#define GPIO87_nPCE_2		MFP_CFG_IN(GPIO87, AF1)
#define GPIO55_nPREG		MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
#define GPIO50_nPIOR		MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
#define GPIO51_nPIOW		MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
#define GPIO49_nPWE		MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
#define GPIO48_nPOE		MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
#define GPIO57_nIOIS16		MFP_CFG_IN(GPIO57, AF1)
#define GPIO56_nPWAIT		MFP_CFG_IN(GPIO56, AF1)
#define GPIO79_PSKTSEL		MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH)
#define GPIO104_PSKTSEL		MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH)

/* I2C */
#define GPIO117_I2C_SCL		MFP_CFG_IN(GPIO117, AF1)
#define GPIO118_I2C_SDA		MFP_CFG_IN(GPIO118, AF1)

/* FFUART */
#define GPIO9_FFUART_CTS	MFP_CFG_IN(GPIO9, AF3)
#define GPIO26_FFUART_CTS	MFP_CFG_IN(GPIO26, AF3)
#define GPIO35_FFUART_CTS	MFP_CFG_IN(GPIO35, AF1)
#define GPIO100_FFUART_CTS	MFP_CFG_IN(GPIO100, AF3)
#define GPIO10_FFUART_DCD	MFP_CFG_IN(GPIO10, AF1)
#define GPIO36_FFUART_DCD	MFP_CFG_IN(GPIO36, AF1)
#define GPIO33_FFUART_DSR	MFP_CFG_IN(GPIO33, AF2)
#define GPIO37_FFUART_DSR	MFP_CFG_IN(GPIO37, AF1)
#define GPIO38_FFUART_RI	MFP_CFG_IN(GPIO38, AF1)
#define GPIO89_FFUART_RI	MFP_CFG_IN(GPIO89, AF3)
#define GPIO19_FFUART_RXD	MFP_CFG_IN(GPIO19, AF3)
#define GPIO33_FFUART_RXD	MFP_CFG_IN(GPIO33, AF1)
#define GPIO34_FFUART_RXD	MFP_CFG_IN(GPIO34, AF1)
#define GPIO41_FFUART_RXD	MFP_CFG_IN(GPIO41, AF1)
#define GPIO53_FFUART_RXD	MFP_CFG_IN(GPIO53, AF1)
#define GPIO85_FFUART_RXD	MFP_CFG_IN(GPIO85, AF1)
#define GPIO96_FFUART_RXD	MFP_CFG_IN(GPIO96, AF3)
#define GPIO102_FFUART_RXD	MFP_CFG_IN(GPIO102, AF3)
#define GPIO16_FFUART_TXD	MFP_CFG_OUT(GPIO16, AF3, DRIVE_HIGH)
#define GPIO37_FFUART_TXD	MFP_CFG_OUT(GPIO37, AF3, DRIVE_HIGH)
#define GPIO39_FFUART_TXD	MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
#define GPIO83_FFUART_TXD	MFP_CFG_OUT(GPIO83, AF2, DRIVE_HIGH)
#define GPIO99_FFUART_TXD	MFP_CFG_OUT(GPIO99, AF3, DRIVE_HIGH)
#define GPIO27_FFUART_RTS	MFP_CFG_OUT(GPIO27, AF3, DRIVE_HIGH)
#define GPIO41_FFUART_RTS	MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
#define GPIO83_FFUART_RTS	MFP_CFG_OUT(GPIO83, AF3, DRIVE_HIGH)
#define GPIO98_FFUART_RTS	MFP_CFG_OUT(GPIO98, AF3, DRIVE_HIGH)
#define GPIO40_FFUART_DTR	MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
#define GPIO82_FFUART_DTR	MFP_CFG_OUT(GPIO82, AF3, DRIVE_HIGH)

/* BTUART */
#define GPIO44_BTUART_CTS	MFP_CFG_IN(GPIO44, AF1)
#define GPIO42_BTUART_RXD	MFP_CFG_IN(GPIO42, AF1)
#define GPIO45_BTUART_RTS	MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
#define GPIO45_BTUART_RTS_LPM_LOW	MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW)
#define GPIO43_BTUART_TXD	MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
#define GPIO43_BTUART_TXD_LPM_LOW	MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW)

/* STUART */
#define GPIO46_STUART_RXD	MFP_CFG_IN(GPIO46, AF2)
#define GPIO47_STUART_TXD	MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)

/* FICP */
#define GPIO42_FICP_RXD		MFP_CFG_IN(GPIO42, AF2)
#define GPIO46_FICP_RXD		MFP_CFG_IN(GPIO46, AF1)
#define GPIO43_FICP_TXD		MFP_CFG_OUT(GPIO43, AF1, DRIVE_HIGH)
#define GPIO47_FICP_TXD		MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)

/* PWM 0/1/2/3 */
#define GPIO11_PWM2_OUT		MFP_CFG_OUT(GPIO11, AF2, DRIVE_LOW)
#define GPIO12_PWM3_OUT		MFP_CFG_OUT(GPIO12, AF2, DRIVE_LOW)
#define GPIO16_PWM0_OUT		MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
#define GPIO17_PWM1_OUT		MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
#define GPIO38_PWM1_OUT		MFP_CFG_OUT(GPIO38, AF3, DRIVE_LOW)
#define GPIO46_PWM2_OUT		MFP_CFG_OUT(GPIO46, AF2, DRIVE_LOW)
#define GPIO47_PWM3_OUT		MFP_CFG_OUT(GPIO47, AF3, DRIVE_LOW)
#define GPIO79_PWM2_OUT		MFP_CFG_OUT(GPIO79, AF3, DRIVE_LOW)
#define GPIO80_PWM3_OUT		MFP_CFG_OUT(GPIO80, AF3, DRIVE_LOW)
#define GPIO115_PWM1_OUT	MFP_CFG_OUT(GPIO115, AF3, DRIVE_LOW)

/* AC97 */
#define GPIO31_AC97_SYNC	MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
#define GPIO94_AC97_SYNC	MFP_CFG_OUT(GPIO94, AF1, DRIVE_LOW)
#define GPIO30_AC97_SDATA_OUT	MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
#define GPIO93_AC97_SDATA_OUT	MFP_CFG_OUT(GPIO93, AF1, DRIVE_LOW)
#define GPIO45_AC97_SYSCLK	MFP_CFG_OUT(GPIO45, AF1, DRIVE_LOW)
#define GPIO89_AC97_SYSCLK	MFP_CFG_OUT(GPIO89, AF1, DRIVE_LOW)
#define GPIO98_AC97_SYSCLK	MFP_CFG_OUT(GPIO98, AF1, DRIVE_LOW)
#define GPIO95_AC97_nRESET	MFP_CFG_OUT(GPIO95, AF1, DRIVE_LOW)
#define GPIO113_AC97_nRESET	MFP_CFG_OUT(GPIO113, AF2, DRIVE_LOW)
#define GPIO28_AC97_BITCLK	MFP_CFG_IN(GPIO28, AF1)
#define GPIO29_AC97_SDATA_IN_0	MFP_CFG_IN(GPIO29, AF1)
#define GPIO116_AC97_SDATA_IN_0	MFP_CFG_IN(GPIO116, AF2)
#define GPIO99_AC97_SDATA_IN_1	MFP_CFG_IN(GPIO99, AF2)

/* I2S */
#define GPIO28_I2S_BITCLK_IN	MFP_CFG_IN(GPIO28, AF2)
#define GPIO28_I2S_BITCLK_OUT	MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
#define GPIO29_I2S_SDATA_IN	MFP_CFG_IN(GPIO29, AF2)
#define GPIO30_I2S_SDATA_OUT	MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
#define GPIO31_I2S_SYNC		MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
#define GPIO113_I2S_SYSCLK	MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW)

/* SSP 1 */
#define GPIO23_SSP1_SCLK_IN	MFP_CFG_IN(GPIO23, AF2)
#define GPIO23_SSP1_SCLK	MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
#define GPIO29_SSP1_SCLK	MFP_CFG_IN(GPIO29, AF3)
#define GPIO27_SSP1_SYSCLK	MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW)
#define GPIO53_SSP1_SYSCLK	MFP_CFG_OUT(GPIO53, AF3, DRIVE_LOW)
#define GPIO24_SSP1_SFRM	MFP_CFG_IN(GPIO24, AF2)
#define GPIO28_SSP1_SFRM	MFP_CFG_IN(GPIO28, AF3)
#define GPIO25_SSP1_TXD		MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
#define GPIO57_SSP1_TXD		MFP_CFG_OUT(GPIO57, AF3, DRIVE_LOW)
#define GPIO26_SSP1_RXD		MFP_CFG_IN(GPIO26, AF1)
#define GPIO27_SSP1_SCLKEN	MFP_CFG_IN(GPIO27, AF2)

/* SSP 2 */
#define GPIO19_SSP2_SCLK	MFP_CFG_IN(GPIO19, AF1)
#define GPIO22_SSP2_SCLK	MFP_CFG_IN(GPIO22, AF3)
#define GPIO29_SSP2_SCLK	MFP_CFG_OUT(GPIO29, AF3, DRIVE_LOW)
#define GPIO36_SSP2_SCLK	MFP_CFG_IN(GPIO36, AF2)
#define GPIO50_SSP2_SCLK	MFP_CFG_IN(GPIO50, AF3)
#define GPIO22_SSP2_SYSCLK	MFP_CFG_OUT(GPIO22, AF2, DRIVE_LOW)
#define GPIO14_SSP2_SFRM	MFP_CFG_IN(GPIO14, AF2)
#define GPIO37_SSP2_SFRM	MFP_CFG_IN(GPIO37, AF2)
#define GPIO87_SSP2_SFRM	MFP_CFG_OUT(GPIO87, AF3, DRIVE_LOW)
#define GPIO88_SSP2_SFRM	MFP_CFG_IN(GPIO88, AF3)
#define GPIO13_SSP2_TXD		MFP_CFG_OUT(GPIO13, AF1, DRIVE_LOW)
#define GPIO38_SSP2_TXD		MFP_CFG_OUT(GPIO38, AF2, DRIVE_LOW)
#define GPIO87_SSP2_TXD		MFP_CFG_OUT(GPIO87, AF1, DRIVE_LOW)
#define GPIO89_SSP2_TXD		MFP_CFG_OUT(GPIO89, AF3, DRIVE_LOW)
#define GPIO11_SSP2_RXD		MFP_CFG_IN(GPIO11, AF2)
#define GPIO29_SSP2_RXD		MFP_CFG_OUT(GPIO29, AF1, DRIVE_LOW)
#define GPIO40_SSP2_RXD		MFP_CFG_IN(GPIO40, AF1)
#define GPIO86_SSP2_RXD		MFP_CFG_IN(GPIO86, AF1)
#define GPIO88_SSP2_RXD		MFP_CFG_IN(GPIO88, AF2)
#define GPIO22_SSP2_EXTCLK	MFP_CFG_IN(GPIO22, AF1)
#define GPIO27_SSP2_EXTCLK	MFP_CFG_IN(GPIO27, AF1)
#define GPIO22_SSP2_SCLKEN	MFP_CFG_IN(GPIO22, AF2)
#define GPIO23_SSP2_SCLKEN	MFP_CFG_IN(GPIO23, AF2)

/* SSP 3 */
#define GPIO34_SSP3_SCLK	MFP_CFG_IN(GPIO34, AF3)
#define GPIO40_SSP3_SCLK	MFP_CFG_OUT(GPIO40, AF3, DRIVE_LOW)
#define GPIO52_SSP3_SCLK	MFP_CFG_IN(GPIO52, AF2)
#define GPIO84_SSP3_SCLK	MFP_CFG_IN(GPIO84, AF1)
#define GPIO45_SSP3_SYSCLK	MFP_CFG_OUT(GPIO45, AF3, DRIVE_LOW)
#define GPIO35_SSP3_SFRM	MFP_CFG_IN(GPIO35, AF3)
#define GPIO39_SSP3_SFRM	MFP_CFG_IN(GPIO39, AF3)
#define GPIO83_SSP3_SFRM	MFP_CFG_IN(GPIO83, AF1)
#define GPIO35_SSP3_TXD		MFP_CFG_OUT(GPIO35, AF3, DRIVE_LOW)
#define GPIO38_SSP3_TXD		MFP_CFG_OUT(GPIO38, AF1, DRIVE_LOW)
#define GPIO81_SSP3_TXD		MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
#define GPIO41_SSP3_RXD		MFP_CFG_IN(GPIO41, AF3)
#define GPIO82_SSP3_RXD		MFP_CFG_IN(GPIO82, AF1)
#define GPIO89_SSP3_RXD		MFP_CFG_IN(GPIO89, AF1)

/* MMC */
#define GPIO32_MMC_CLK		MFP_CFG_OUT(GPIO32, AF2, DRIVE_LOW)
#define GPIO92_MMC_DAT_0	MFP_CFG_IN(GPIO92, AF1)
#define GPIO109_MMC_DAT_1	MFP_CFG_IN(GPIO109, AF1)
#define GPIO110_MMC_DAT_2	MFP_CFG_IN(GPIO110, AF1)
#define GPIO111_MMC_DAT_3	MFP_CFG_IN(GPIO111, AF1)
#define GPIO112_MMC_CMD		MFP_CFG_IN(GPIO112, AF1)

/* LCD */
#define GPIO58_LCD_LDD_0	MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
#define GPIO59_LCD_LDD_1	MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
#define GPIO60_LCD_LDD_2	MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
#define GPIO61_LCD_LDD_3	MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
#define GPIO62_LCD_LDD_4	MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
#define GPIO63_LCD_LDD_5	MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
#define GPIO64_LCD_LDD_6	MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
#define GPIO65_LCD_LDD_7	MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
#define GPIO66_LCD_LDD_8	MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
#define GPIO67_LCD_LDD_9	MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
#define GPIO68_LCD_LDD_10	MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
#define GPIO69_LCD_LDD_11	MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
#define GPIO70_LCD_LDD_12	MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
#define GPIO71_LCD_LDD_13	MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
#define GPIO72_LCD_LDD_14	MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
#define GPIO73_LCD_LDD_15	MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
#define GPIO86_LCD_LDD_16	MFP_CFG_OUT(GPIO86, AF2, DRIVE_LOW)
#define GPIO87_LCD_LDD_17	MFP_CFG_OUT(GPIO87, AF2, DRIVE_LOW)
#define GPIO74_LCD_FCLK		MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
#define GPIO75_LCD_LCLK		MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
#define GPIO76_LCD_PCLK		MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
#define GPIO77_LCD_BIAS		MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
#define GPIO14_LCD_VSYNC	MFP_CFG_IN(GPIO14, AF1)
#define GPIO19_LCD_CS		MFP_CFG_OUT(GPIO19, AF2, DRIVE_LOW)

/* Keypad */
#define GPIO93_KP_DKIN_0	MFP_CFG_IN(GPIO93, AF1)
#define GPIO94_KP_DKIN_1	MFP_CFG_IN(GPIO94, AF1)
#define GPIO95_KP_DKIN_2	MFP_CFG_IN(GPIO95, AF1)
#define GPIO96_KP_DKIN_3	MFP_CFG_IN(GPIO96, AF1)
#define GPIO97_KP_DKIN_4	MFP_CFG_IN(GPIO97, AF1)
#define GPIO98_KP_DKIN_5	MFP_CFG_IN(GPIO98, AF1)
#define GPIO99_KP_DKIN_6	MFP_CFG_IN(GPIO99, AF1)
#define GPIO13_KP_KDIN_7	MFP_CFG_IN(GPIO13, AF2)
#define GPIO100_KP_MKIN_0	MFP_CFG_IN(GPIO100, AF1)
#define GPIO101_KP_MKIN_1	MFP_CFG_IN(GPIO101, AF1)
#define GPIO102_KP_MKIN_2	MFP_CFG_IN(GPIO102, AF1)
#define GPIO34_KP_MKIN_3	MFP_CFG_IN(GPIO34, AF2)
#define GPIO37_KP_MKIN_3	MFP_CFG_IN(GPIO37, AF3)
#define GPIO97_KP_MKIN_3	MFP_CFG_IN(GPIO97, AF3)
#define GPIO98_KP_MKIN_4	MFP_CFG_IN(GPIO98, AF3)
#define GPIO38_KP_MKIN_4	MFP_CFG_IN(GPIO38, AF2)
#define GPIO39_KP_MKIN_4	MFP_CFG_IN(GPIO39, AF1)
#define GPIO16_KP_MKIN_5	MFP_CFG_IN(GPIO16, AF1)
#define GPIO90_KP_MKIN_5	MFP_CFG_IN(GPIO90, AF1)
#define GPIO99_KP_MKIN_5	MFP_CFG_IN(GPIO99, AF3)
#define GPIO17_KP_MKIN_6	MFP_CFG_IN(GPIO17, AF1)
#define GPIO91_KP_MKIN_6	MFP_CFG_IN(GPIO91, AF1)
#define GPIO95_KP_MKIN_6	MFP_CFG_IN(GPIO95, AF3)
#define GPIO13_KP_MKIN_7	MFP_CFG_IN(GPIO13, AF3)
#define GPIO36_KP_MKIN_7	MFP_CFG_IN(GPIO36, AF3)
#define GPIO103_KP_MKOUT_0	MFP_CFG_OUT(GPIO103, AF2, DRIVE_HIGH)
#define GPIO104_KP_MKOUT_1	MFP_CFG_OUT(GPIO104, AF2, DRIVE_HIGH)
#define GPIO105_KP_MKOUT_2	MFP_CFG_OUT(GPIO105, AF2, DRIVE_HIGH)
#define GPIO106_KP_MKOUT_3	MFP_CFG_OUT(GPIO106, AF2, DRIVE_HIGH)
#define GPIO107_KP_MKOUT_4	MFP_CFG_OUT(GPIO107, AF2, DRIVE_HIGH)
#define GPIO108_KP_MKOUT_5	MFP_CFG_OUT(GPIO108, AF2, DRIVE_HIGH)
#define GPIO35_KP_MKOUT_6	MFP_CFG_OUT(GPIO35, AF2, DRIVE_HIGH)
#define GPIO22_KP_MKOUT_7	MFP_CFG_OUT(GPIO22, AF1, DRIVE_HIGH)
#define GPIO40_KP_MKOUT_6	MFP_CFG_OUT(GPIO40, AF1, DRIVE_HIGH)
#define GPIO41_KP_MKOUT_7	MFP_CFG_OUT(GPIO41, AF1, DRIVE_HIGH)
#define GPIO96_KP_MKOUT_6	MFP_CFG_OUT(GPIO96, AF3, DRIVE_HIGH)

/* USB P3 */
#define GPIO10_USB_P3_5		MFP_CFG_IN(GPIO10, AF3)
#define GPIO11_USB_P3_1		MFP_CFG_IN(GPIO11, AF3)
#define GPIO30_USB_P3_2		MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
#define GPIO31_USB_P3_6		MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
#define GPIO56_USB_P3_4		MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
#define GPIO86_USB_P3_5		MFP_CFG_IN(GPIO86, AF3)
#define GPIO87_USB_P3_1		MFP_CFG_IN(GPIO87, AF3)
#define GPIO90_USB_P3_5		MFP_CFG_IN(GPIO90, AF2)
#define GPIO91_USB_P3_1		MFP_CFG_IN(GPIO91, AF2)
#define GPIO113_USB_P3_3	MFP_CFG_IN(GPIO113, AF3)

/* USB P2 */
#define GPIO34_USB_P2_2		MFP_CFG_OUT(GPIO34, AF1, DRIVE_LOW)
#define GPIO35_USB_P2_1		MFP_CFG_IN(GPIO35, AF2)
#define GPIO36_USB_P2_4		MFP_CFG_OUT(GPIO36, AF1, DRIVE_LOW)
#define GPIO37_USB_P2_8		MFP_CFG_OUT(GPIO37, AF1, DRIVE_LOW)
#define GPIO38_USB_P2_3		MFP_CFG_IN(GPIO38, AF3)
#define GPIO39_USB_P2_6		MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
#define GPIO40_USB_P2_5		MFP_CFG_IN(GPIO40, AF3)
#define GPIO41_USB_P2_7		MFP_CFG_IN(GPIO41, AF2)
#define GPIO53_USB_P2_3		MFP_CFG_IN(GPIO53, AF2)

/* USB Host Port 1/2 */
#define GPIO88_USBH1_PWR	MFP_CFG_IN(GPIO88, AF1)
#define GPIO89_USBH1_PEN	MFP_CFG_OUT(GPIO89, AF2, DRIVE_LOW)
#define GPIO119_USBH2_PWR	MFP_CFG_IN(GPIO119, AF1)
#define GPIO120_USBH2_PEN	MFP_CFG_OUT(GPIO120, AF2, DRIVE_LOW)

/* QCI - default to Master Mode: CIF_FV/CIF_LV Direction In */
#define GPIO115_CIF_DD_3	MFP_CFG_IN(GPIO115, AF2)
#define GPIO116_CIF_DD_2	MFP_CFG_IN(GPIO116, AF1)
#define GPIO12_CIF_DD_7		MFP_CFG_IN(GPIO12, AF2)
#define GPIO17_CIF_DD_6		MFP_CFG_IN(GPIO17, AF2)
#define GPIO23_CIF_MCLK		MFP_CFG_OUT(GPIO23, AF1, DRIVE_LOW)
#define GPIO24_CIF_FV		MFP_CFG_IN(GPIO24, AF1)
#define GPIO25_CIF_LV		MFP_CFG_IN(GPIO25, AF1)
#define GPIO26_CIF_PCLK		MFP_CFG_IN(GPIO26, AF2)
#define GPIO27_CIF_DD_0		MFP_CFG_IN(GPIO27, AF3)
#define GPIO42_CIF_MCLK		MFP_CFG_OUT(GPIO42, AF3, DRIVE_LOW)
#define GPIO43_CIF_FV		MFP_CFG_IN(GPIO43, AF3)
#define GPIO44_CIF_LV		MFP_CFG_IN(GPIO44, AF3)
#define GPIO45_CIF_PCLK		MFP_CFG_IN(GPIO45, AF3)
#define GPIO47_CIF_DD_0		MFP_CFG_IN(GPIO47, AF1)
#define GPIO48_CIF_DD_5		MFP_CFG_IN(GPIO48, AF1)
#define GPIO50_CIF_DD_3		MFP_CFG_IN(GPIO50, AF1)
#define GPIO51_CIF_DD_2		MFP_CFG_IN(GPIO51, AF1)
#define GPIO52_CIF_DD_4		MFP_CFG_IN(GPIO52, AF1)
#define GPIO53_CIF_MCLK		MFP_CFG_OUT(GPIO53, AF2, DRIVE_LOW)
#define GPIO54_CIF_PCLK		MFP_CFG_IN(GPIO54, AF3)
#define GPIO55_CIF_DD_1		MFP_CFG_IN(GPIO55, AF1)
#define GPIO81_CIF_DD_0		MFP_CFG_IN(GPIO81, AF2)
#define GPIO82_CIF_DD_5		MFP_CFG_IN(GPIO82, AF3)
#define GPIO83_CIF_DD_4		MFP_CFG_IN(GPIO83, AF3)
#define GPIO84_CIF_FV		MFP_CFG_IN(GPIO84, AF3)
#define GPIO85_CIF_LV		MFP_CFG_IN(GPIO85, AF3)
#define GPIO90_CIF_DD_4		MFP_CFG_IN(GPIO90, AF3)
#define GPIO91_CIF_DD_5		MFP_CFG_IN(GPIO91, AF3)
#define GPIO93_CIF_DD_6		MFP_CFG_IN(GPIO93, AF2)
#define GPIO94_CIF_DD_5		MFP_CFG_IN(GPIO94, AF2)
#define GPIO95_CIF_DD_4		MFP_CFG_IN(GPIO95, AF2)
#define GPIO98_CIF_DD_0		MFP_CFG_IN(GPIO98, AF2)
#define GPIO103_CIF_DD_3	MFP_CFG_IN(GPIO103, AF1)
#define GPIO104_CIF_DD_2	MFP_CFG_IN(GPIO104, AF1)
#define GPIO105_CIF_DD_1	MFP_CFG_IN(GPIO105, AF1)
#define GPIO106_CIF_DD_9	MFP_CFG_IN(GPIO106, AF1)
#define GPIO107_CIF_DD_8	MFP_CFG_IN(GPIO107, AF1)
#define GPIO108_CIF_DD_7	MFP_CFG_IN(GPIO108, AF1)
#define GPIO114_CIF_DD_1	MFP_CFG_IN(GPIO114, AF1)

/* Universal Subscriber ID Interface */
#define GPIO114_UVS0		MFP_CFG_OUT(GPIO114, AF2, DRIVE_LOW)
#define GPIO115_nUVS1		MFP_CFG_OUT(GPIO115, AF2, DRIVE_LOW)
#define GPIO116_nUVS2		MFP_CFG_OUT(GPIO116, AF2, DRIVE_LOW)
#define GPIO14_UCLK		MFP_CFG_OUT(GPIO14, AF3, DRIVE_LOW)
#define GPIO91_UCLK		MFP_CFG_OUT(GPIO91, AF2, DRIVE_LOW)
#define GPIO19_nURST		MFP_CFG_OUT(GPIO19, AF3, DRIVE_LOW)
#define GPIO90_nURST		MFP_CFG_OUT(GPIO90, AF2, DRIVE_LOW)
#define GPIO116_UDET		MFP_CFG_IN(GPIO116, AF3)
#define GPIO114_UEN		MFP_CFG_OUT(GPIO114, AF1, DRIVE_LOW)
#define GPIO115_UEN		MFP_CFG_OUT(GPIO115, AF1, DRIVE_LOW)

/* Mobile Scalable Link (MSL) Interface */
#define GPIO81_BB_OB_DAT_0	MFP_CFG_OUT(GPIO81, AF2, DRIVE_LOW)
#define GPIO48_BB_OB_DAT_1	MFP_CFG_OUT(GPIO48, AF1, DRIVE_LOW)
#define GPIO50_BB_OB_DAT_2	MFP_CFG_OUT(GPIO50, AF1, DRIVE_LOW)
#define GPIO51_BB_OB_DAT_3	MFP_CFG_OUT(GPIO51, AF1, DRIVE_LOW)
#define GPIO52_BB_OB_CLK	MFP_CFG_OUT(GPIO52, AF1, DRIVE_LOW)
#define GPIO53_BB_OB_STB	MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
#define GPIO54_BB_OB_WAIT	MFP_CFG_IN(GPIO54, AF2)
#define GPIO82_BB_IB_DAT_0	MFP_CFG_IN(GPIO82, AF2)
#define GPIO55_BB_IB_DAT_1	MFP_CFG_IN(GPIO55, AF2)
#define GPIO56_BB_IB_DAT_2	MFP_CFG_IN(GPIO56, AF2)
#define GPIO57_BB_IB_DAT_3	MFP_CFG_IN(GPIO57, AF2)
#define GPIO83_BB_IB_CLK	MFP_CFG_IN(GPIO83, AF2)
#define GPIO84_BB_IB_STB	MFP_CFG_IN(GPIO84, AF2)
#define GPIO85_BB_IB_WAIT	MFP_CFG_OUT(GPIO85, AF2, DRIVE_LOW)

/* Memory Stick Host Controller */
#define GPIO92_MSBS		MFP_CFG_OUT(GPIO92, AF2, DRIVE_LOW)
#define GPIO109_MSSDIO		MFP_CFG_IN(GPIO109, AF2)
#define GPIO112_nMSINS		MFP_CFG_IN(GPIO112, AF2)
#define GPIO32_MSSCLK		MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)

/* commonly used pin configurations */
#define GPIOxx_LCD_16BPP	\
	GPIO58_LCD_LDD_0,	\
	GPIO59_LCD_LDD_1,	\
	GPIO60_LCD_LDD_2,	\
	GPIO61_LCD_LDD_3,	\
	GPIO62_LCD_LDD_4,	\
	GPIO63_LCD_LDD_5,	\
	GPIO64_LCD_LDD_6,	\
	GPIO65_LCD_LDD_7,	\
	GPIO66_LCD_LDD_8,	\
	GPIO67_LCD_LDD_9,	\
	GPIO68_LCD_LDD_10,	\
	GPIO69_LCD_LDD_11,	\
	GPIO70_LCD_LDD_12,	\
	GPIO71_LCD_LDD_13,	\
	GPIO72_LCD_LDD_14,	\
	GPIO73_LCD_LDD_15

#define GPIOxx_LCD_TFT_16BPP	\
	GPIOxx_LCD_16BPP,	\
	GPIO74_LCD_FCLK,	\
	GPIO75_LCD_LCLK,	\
	GPIO76_LCD_PCLK,	\
	GPIO77_LCD_BIAS

/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */
#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT)
#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT)

extern int keypad_set_wake(unsigned int on);
#endif /* __ASM_ARCH_MFP_PXA27X_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/mfp-pxa2xx.c
 *
 *  PXA2xx pin mux configuration support
 *
 *  The GPIOs on PXA2xx can be configured as one of many alternate
 *  functions, this is by concept samilar to the MFP configuration
 *  on PXA3xx,  what's more important, the low power pin state and
 *  wakeup detection are also supported by the same framework.
 */
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/syscore_ops.h>
#include <linux/soc/pxa/cpu.h>

#include "pxa2xx-regs.h"
#include "mfp-pxa2xx.h"

#include "generic.h"

#define PGSR(x)		__REG2(0x40F00020, (x) << 2)
#define __GAFR(u, x)	__REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
#define GAFR_L(x)	__GAFR(0, x)
#define GAFR_U(x)	__GAFR(1, x)

#define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
#define GPLR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5))
#define GPDR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c)
#define GPSR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18)
#define GPCR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24)

#define PWER_WE35	(1 << 24)

struct gpio_desc {
	unsigned	valid		: 1;
	unsigned	can_wakeup	: 1;
	unsigned	keypad_gpio	: 1;
	unsigned	dir_inverted	: 1;
	unsigned int	mask; /* bit mask in PWER or PKWR */
	unsigned int	mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */
	unsigned long	config;
};

static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];

static unsigned long gpdr_lpm[4];

static int __mfp_config_gpio(unsigned gpio, unsigned long c)
{
	unsigned long gafr, mask = GPIO_bit(gpio);
	int bank = gpio_to_bank(gpio);
	int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
	int shft = (gpio & 0xf) << 1;
	int fn = MFP_AF(c);
	int is_out = (c & MFP_DIR_OUT) ? 1 : 0;

	if (fn > 3)
		return -EINVAL;

	/* alternate function and direction at run-time */
	gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
	gafr = (gafr & ~(0x3 << shft)) | (fn << shft);

	if (uorl == 0)
		GAFR_L(bank) = gafr;
	else
		GAFR_U(bank) = gafr;

	if (is_out ^ gpio_desc[gpio].dir_inverted)
		GPDR(gpio) |= mask;
	else
		GPDR(gpio) &= ~mask;

	/* alternate function and direction at low power mode */
	switch (c & MFP_LPM_STATE_MASK) {
	case MFP_LPM_DRIVE_HIGH:
		PGSR(bank) |= mask;
		is_out = 1;
		break;
	case MFP_LPM_DRIVE_LOW:
		PGSR(bank) &= ~mask;
		is_out = 1;
		break;
	case MFP_LPM_INPUT:
	case MFP_LPM_DEFAULT:
		break;
	default:
		/* warning and fall through, treat as MFP_LPM_DEFAULT */
		pr_warn("%s: GPIO%d: unsupported low power mode\n",
			__func__, gpio);
		break;
	}

	if (is_out ^ gpio_desc[gpio].dir_inverted)
		gpdr_lpm[bank] |= mask;
	else
		gpdr_lpm[bank] &= ~mask;

	/* give early warning if MFP_LPM_CAN_WAKEUP is set on the
	 * configurations of those pins not able to wakeup
	 */
	if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
		pr_warn("%s: GPIO%d unable to wakeup\n", __func__, gpio);
		return -EINVAL;
	}

	if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
		pr_warn("%s: output GPIO%d unable to wakeup\n", __func__, gpio);
		return -EINVAL;
	}

	return 0;
}

static inline int __mfp_validate(int mfp)
{
	int gpio = mfp_to_gpio(mfp);

	if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
		pr_warn("%s: GPIO%d is invalid pin\n", __func__, gpio);
		return -1;
	}

	return gpio;
}

void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
{
	unsigned long flags;
	unsigned long *c;
	int i, gpio;

	for (i = 0, c = mfp_cfgs; i < num; i++, c++) {

		gpio = __mfp_validate(MFP_PIN(*c));
		if (gpio < 0)
			continue;

		local_irq_save(flags);

		gpio_desc[gpio].config = *c;
		__mfp_config_gpio(gpio, *c);

		local_irq_restore(flags);
	}
}

void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
{
	unsigned long flags, c;
	int gpio;

	gpio = __mfp_validate(mfp);
	if (gpio < 0)
		return;

	local_irq_save(flags);

	c = gpio_desc[gpio].config;
	c = (c & ~MFP_LPM_STATE_MASK) | lpm;
	__mfp_config_gpio(gpio, c);

	local_irq_restore(flags);
}

int gpio_set_wake(unsigned int gpio, unsigned int on)
{
	struct gpio_desc *d;
	unsigned long c, mux_taken;

	if (gpio > mfp_to_gpio(MFP_PIN_GPIO127))
		return -EINVAL;

	d = &gpio_desc[gpio];
	c = d->config;

	if (!d->valid)
		return -EINVAL;

	/* Allow keypad GPIOs to wakeup system when
	 * configured as generic GPIOs.
	 */
	if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&
	    (d->config & MFP_LPM_CAN_WAKEUP)) {
		if (on)
			PKWR |= d->mask;
		else
			PKWR &= ~d->mask;
		return 0;
	}

	mux_taken = (PWER & d->mux_mask) & (~d->mask);
	if (on && mux_taken)
		return -EBUSY;

	if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
		if (on) {
			PWER = (PWER & ~d->mux_mask) | d->mask;

			if (c & MFP_LPM_EDGE_RISE)
				PRER |= d->mask;
			else
				PRER &= ~d->mask;

			if (c & MFP_LPM_EDGE_FALL)
				PFER |= d->mask;
			else
				PFER &= ~d->mask;
		} else {
			PWER &= ~d->mask;
			PRER &= ~d->mask;
			PFER &= ~d->mask;
		}
	}
	return 0;
}

#ifdef CONFIG_PXA25x
static void __init pxa25x_mfp_init(void)
{
	int i;

	/* running before pxa_gpio_probe() */
#ifdef CONFIG_CPU_PXA26x
	pxa_last_gpio = 89;
#else
	pxa_last_gpio = 84;
#endif
	for (i = 0; i <= pxa_last_gpio; i++)
		gpio_desc[i].valid = 1;

	for (i = 0; i <= 15; i++) {
		gpio_desc[i].can_wakeup = 1;
		gpio_desc[i].mask = GPIO_bit(i);
	}

	/* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
	 * direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
	 */
	for (i = 86; i <= pxa_last_gpio; i++)
		gpio_desc[i].dir_inverted = 1;
}
#else
static inline void pxa25x_mfp_init(void) {}
#endif /* CONFIG_PXA25x */

#ifdef CONFIG_PXA27x
static int pxa27x_pkwr_gpio[] = {
	13, 16, 17, 34, 36, 37, 38, 39, 90, 91, 93, 94,
	95, 96, 97, 98, 99, 100, 101, 102
};

int keypad_set_wake(unsigned int on)
{
	unsigned int i, gpio, mask = 0;
	struct gpio_desc *d;

	for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {

		gpio = pxa27x_pkwr_gpio[i];
		d = &gpio_desc[gpio];

		/* skip if configured as generic GPIO */
		if (MFP_AF(d->config) == 0)
			continue;

		if (d->config & MFP_LPM_CAN_WAKEUP)
			mask |= gpio_desc[gpio].mask;
	}

	if (on)
		PKWR |= mask;
	else
		PKWR &= ~mask;
	return 0;
}

#define PWER_WEMUX2_GPIO38	(1 << 16)
#define PWER_WEMUX2_GPIO53	(2 << 16)
#define PWER_WEMUX2_GPIO40	(3 << 16)
#define PWER_WEMUX2_GPIO36	(4 << 16)
#define PWER_WEMUX2_MASK	(7 << 16)
#define PWER_WEMUX3_GPIO31	(1 << 19)
#define PWER_WEMUX3_GPIO113	(2 << 19)
#define PWER_WEMUX3_MASK	(3 << 19)

#define INIT_GPIO_DESC_MUXED(mux, gpio)				\
do {								\
	gpio_desc[(gpio)].can_wakeup = 1;			\
	gpio_desc[(gpio)].mask = PWER_ ## mux ## _GPIO ##gpio;	\
	gpio_desc[(gpio)].mux_mask = PWER_ ## mux ## _MASK;	\
} while (0)

static void __init pxa27x_mfp_init(void)
{
	int i, gpio;

	pxa_last_gpio = 120;	/* running before pxa_gpio_probe() */
	for (i = 0; i <= pxa_last_gpio; i++) {
		/* skip GPIO2, 5, 6, 7, 8, they are not
		 * valid pins allow configuration
		 */
		if (i == 2 || i == 5 || i == 6 || i == 7 || i == 8)
			continue;

		gpio_desc[i].valid = 1;
	}

	/* Keypad GPIOs */
	for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
		gpio = pxa27x_pkwr_gpio[i];
		gpio_desc[gpio].can_wakeup = 1;
		gpio_desc[gpio].keypad_gpio = 1;
		gpio_desc[gpio].mask = 1 << i;
	}

	/* Overwrite GPIO13 as a PWER wakeup source */
	for (i = 0; i <= 15; i++) {
		/* skip GPIO2, 5, 6, 7, 8 */
		if (GPIO_bit(i) & 0x1e4)
			continue;

		gpio_desc[i].can_wakeup = 1;
		gpio_desc[i].mask = GPIO_bit(i);
	}

	gpio_desc[35].can_wakeup = 1;
	gpio_desc[35].mask = PWER_WE35;

	INIT_GPIO_DESC_MUXED(WEMUX3, 31);
	INIT_GPIO_DESC_MUXED(WEMUX3, 113);
	INIT_GPIO_DESC_MUXED(WEMUX2, 38);
	INIT_GPIO_DESC_MUXED(WEMUX2, 53);
	INIT_GPIO_DESC_MUXED(WEMUX2, 40);
	INIT_GPIO_DESC_MUXED(WEMUX2, 36);
}
#else
static inline void pxa27x_mfp_init(void) {}
#endif /* CONFIG_PXA27x */

#ifdef CONFIG_PM
static unsigned long saved_gafr[2][4];
static unsigned long saved_gpdr[4];
static unsigned long saved_gplr[4];
static unsigned long saved_pgsr[4];

static int pxa2xx_mfp_suspend(void)
{
	int i;

	/* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
	for (i = 0; i < pxa_last_gpio; i++) {
		if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
		    (GPDR(i) & GPIO_bit(i))) {
			if (GPLR(i) & GPIO_bit(i))
				PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
			else
				PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
		}
	}

	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
		saved_gafr[0][i] = GAFR_L(i);
		saved_gafr[1][i] = GAFR_U(i);
		saved_gpdr[i] = GPDR(i * 32);
		saved_gplr[i] = GPLR(i * 32);
		saved_pgsr[i] = PGSR(i);

		GPSR(i * 32) = PGSR(i);
		GPCR(i * 32) = ~PGSR(i);
	}

	/* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */
	for (i = 0; i < pxa_last_gpio; i++) {
		if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) ||
		    ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
		     (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i))))
			GPDR(i) |= GPIO_bit(i);
		else
			GPDR(i) &= ~GPIO_bit(i);
	}

	return 0;
}

static void pxa2xx_mfp_resume(void)
{
	int i;

	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
		GAFR_L(i) = saved_gafr[0][i];
		GAFR_U(i) = saved_gafr[1][i];
		GPSR(i * 32) = saved_gplr[i];
		GPCR(i * 32) = ~saved_gplr[i];
		GPDR(i * 32) = saved_gpdr[i];
		PGSR(i) = saved_pgsr[i];
	}
	PSSR = PSSR_RDH | PSSR_PH;
}
#else
#define pxa2xx_mfp_suspend	NULL
#define pxa2xx_mfp_resume	NULL
#endif

struct syscore_ops pxa2xx_mfp_syscore_ops = {
	.suspend	= pxa2xx_mfp_suspend,
	.resume		= pxa2xx_mfp_resume,
};

static int __init pxa2xx_mfp_init(void)
{
	int i;

	if (!cpu_is_pxa2xx())
		return 0;

	if (cpu_is_pxa25x())
		pxa25x_mfp_init();

	if (cpu_is_pxa27x())
		pxa27x_mfp_init();

	/* clear RDH bit to enable GPIO receivers after reset/sleep exit */
	PSSR = PSSR_RDH;

	/* initialize gafr_run[], pgsr_lpm[] from existing values */
	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
		gpdr_lpm[i] = GPDR(i * 32);

	return 0;
}
postcore_initcall(pxa2xx_mfp_init);