code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Handles the Mitac Mio A701 Board
 *
 * Copyright (C) 2008 Robert Jarzmik
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/gpio_keys.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/rtc.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/pda_power.h>
#include <linux/power_supply.h>
#include <linux/wm97xx.h>
#include <linux/mtd/physmap.h>
#include <linux/reboot.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/max1586.h>
#include <linux/slab.h>
#include <linux/platform_data/i2c-pxa.h>

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

#include "pxa27x.h"
#include "regs-rtc.h"
#include <linux/platform_data/keypad-pxa27x.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
#include "udc.h"
#include "pxa27x-udc.h"
#include <linux/platform_data/media/camera-pxa.h>
#include <linux/platform_data/asoc-pxa.h>
#include "smemc.h"

#include "mioa701.h"

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

static unsigned long mioa701_pin_config[] = {
	/* Mio global */
	MIO_CFG_OUT(GPIO9_CHARGE_EN, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO18_POWEROFF, AF0, DRIVE_LOW),
	MFP_CFG_OUT(GPIO3, AF0, DRIVE_HIGH),
	MFP_CFG_OUT(GPIO4, AF0, DRIVE_HIGH),
	MIO_CFG_IN(GPIO80_MAYBE_CHARGE_VDROP, AF0),

	/* Backlight PWM 0 */
	GPIO16_PWM0_OUT,

	/* MMC */
	GPIO32_MMC_CLK,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	GPIO112_MMC_CMD,
	MIO_CFG_IN(GPIO78_SDIO_RO, AF0),
	MIO_CFG_IN(GPIO15_SDIO_INSERT, AF0),
	MIO_CFG_OUT(GPIO91_SDIO_EN, AF0, DRIVE_LOW),

	/* USB */
	MIO_CFG_IN(GPIO13_nUSB_DETECT, AF0),
	MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW),

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* QCI */
	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,
	MIO_CFG_OUT(GPIO56_MT9M111_nOE, AF0, DRIVE_LOW),

	/* Bluetooth */
	MIO_CFG_IN(GPIO14_BT_nACTIVITY, AF0),
	GPIO44_BTUART_CTS,
	GPIO42_BTUART_RXD,
	GPIO45_BTUART_RTS,
	GPIO43_BTUART_TXD,
	MIO_CFG_OUT(GPIO83_BT_ON, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO77_BT_UNKNOWN1, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO86_BT_MAYBE_nRESET, AF0, DRIVE_HIGH),

	/* GPS */
	MIO_CFG_OUT(GPIO23_GPS_UNKNOWN1, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO26_GPS_ON, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO27_GPS_RESET, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO106_GPS_UNKNOWN2, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO107_GPS_UNKNOWN3, AF0, DRIVE_LOW),
	GPIO46_STUART_RXD,
	GPIO47_STUART_TXD,

	/* GSM */
	MIO_CFG_OUT(GPIO24_GSM_MOD_RESET_CMD, AF0, DRIVE_LOW),
	MIO_CFG_OUT(GPIO88_GSM_nMOD_ON_CMD, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO90_GSM_nMOD_OFF_CMD, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO114_GSM_nMOD_DTE_UART_STATE, AF0, DRIVE_HIGH),
	MIO_CFG_IN(GPIO25_GSM_MOD_ON_STATE, AF0),
	MIO_CFG_IN(GPIO113_GSM_EVENT, AF0) | WAKEUP_ON_EDGE_BOTH,
	GPIO34_FFUART_RXD,
	GPIO35_FFUART_CTS,
	GPIO36_FFUART_DCD,
	GPIO37_FFUART_DSR,
	GPIO39_FFUART_TXD,
	GPIO40_FFUART_DTR,
	GPIO41_FFUART_RTS,

	/* Sound */
	GPIO28_AC97_BITCLK,
	GPIO29_AC97_SDATA_IN_0,
	GPIO30_AC97_SDATA_OUT,
	GPIO31_AC97_SYNC,
	GPIO89_AC97_SYSCLK,
	MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0),

	/* Leds */
	MIO_CFG_OUT(GPIO10_LED_nCharging, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO97_LED_nBlue, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO98_LED_nOrange, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO82_LED_nVibra, AF0, DRIVE_HIGH),
	MIO_CFG_OUT(GPIO115_LED_nKeyboard, AF0, DRIVE_HIGH),

	/* Keyboard */
	MIO_CFG_IN(GPIO0_KEY_POWER, AF0) | WAKEUP_ON_EDGE_BOTH,
	MIO_CFG_IN(GPIO93_KEY_VOLUME_UP, AF0),
	MIO_CFG_IN(GPIO94_KEY_VOLUME_DOWN, AF0),
	GPIO100_KP_MKIN_0,
	GPIO101_KP_MKIN_1,
	GPIO102_KP_MKIN_2,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

	/* Unknown */
	MFP_CFG_IN(GPIO20, AF0),
	MFP_CFG_IN(GPIO21, AF0),
	MFP_CFG_IN(GPIO33, AF0),
	MFP_CFG_OUT(GPIO49, AF0, DRIVE_HIGH),
	MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH),
	MFP_CFG_IN(GPIO96, AF0),
	MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),
};

static struct pwm_lookup mioa701_pwm_lookup[] = {
	PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 4000 * 1024,
		   PWM_POLARITY_NORMAL),
};

/* LCD Screen and Backlight */
static struct platform_pwm_backlight_data mioa701_backlight_data = {
	.max_brightness	= 100,
	.dft_brightness	= 50,
};

/*
 * LTM0305A776C LCD panel timings
 *
 * see:
 *  - the LTM0305A776C datasheet,
 *  - and the PXA27x Programmers' manual
 */
static struct pxafb_mode_info mioa701_ltm0305a776c = {
	.pixclock		= 220000,	/* CLK=4.545 MHz */
	.xres			= 240,
	.yres			= 320,
	.bpp			= 16,
	.hsync_len		= 4,
	.vsync_len		= 2,
	.left_margin		= 6,
	.right_margin		= 4,
	.upper_margin		= 5,
	.lower_margin		= 3,
};

static void mioa701_lcd_power(int on, struct fb_var_screeninfo *si)
{
	gpio_set_value(GPIO87_LCD_POWER, on);
}

static struct pxafb_mach_info mioa701_pxafb_info = {
	.modes			= &mioa701_ltm0305a776c,
	.num_modes		= 1,
	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
	.pxafb_lcd_power	= mioa701_lcd_power,
};

/*
 * Keyboard configuration
 */
static const unsigned int mioa701_matrix_keys[] = {
	KEY(0, 0, KEY_UP),
	KEY(0, 1, KEY_RIGHT),
	KEY(0, 2, KEY_MEDIA),
	KEY(1, 0, KEY_DOWN),
	KEY(1, 1, KEY_ENTER),
	KEY(1, 2, KEY_CONNECT),	/* GPS key */
	KEY(2, 0, KEY_LEFT),
	KEY(2, 1, KEY_PHONE),	/* Phone Green key */
	KEY(2, 2, KEY_CAMERA)	/* Camera key */
};

static struct matrix_keymap_data mioa701_matrix_keymap_data = {
	.keymap			= mioa701_matrix_keys,
	.keymap_size		= ARRAY_SIZE(mioa701_matrix_keys),
};

static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
	.matrix_key_rows = 3,
	.matrix_key_cols = 3,
	.matrix_keymap_data = &mioa701_matrix_keymap_data,
};

/*
 * GPIO Key Configuration
 */
#define MIO_KEY(key, _gpio, _desc, _wakeup) \
	{ .code = (key), .gpio = (_gpio), .active_low = 0, \
	.desc = (_desc), .type = EV_KEY, .wakeup = (_wakeup) }
static struct gpio_keys_button mioa701_button_table[] = {
	MIO_KEY(KEY_EXIT, GPIO0_KEY_POWER, "Power button", 1),
	MIO_KEY(KEY_VOLUMEUP, GPIO93_KEY_VOLUME_UP, "Volume up", 0),
	MIO_KEY(KEY_VOLUMEDOWN, GPIO94_KEY_VOLUME_DOWN, "Volume down", 0),
	MIO_KEY(KEY_HP, GPIO12_HPJACK_INSERT, "HP jack detect", 0)
};

static struct gpio_keys_platform_data mioa701_gpio_keys_data = {
	.buttons  = mioa701_button_table,
	.nbuttons = ARRAY_SIZE(mioa701_button_table),
};

/*
 * Leds and vibrator
 */
#define ONE_LED(_gpio, _name) \
{ .gpio = (_gpio), .name = (_name), .active_low = true }
static struct gpio_led gpio_leds[] = {
	ONE_LED(GPIO10_LED_nCharging, "mioa701:charging"),
	ONE_LED(GPIO97_LED_nBlue, "mioa701:blue"),
	ONE_LED(GPIO98_LED_nOrange, "mioa701:orange"),
	ONE_LED(GPIO82_LED_nVibra, "mioa701:vibra"),
	ONE_LED(GPIO115_LED_nKeyboard, "mioa701:keyboard")
};

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

/*
 * GSM Sagem XS200 chip
 *
 * GSM handling was purged from kernel. For history, this is the way to go :
 *   - init : GPIO24_GSM_MOD_RESET_CMD = 0, GPIO114_GSM_nMOD_DTE_UART_STATE = 1
 *            GPIO88_GSM_nMOD_ON_CMD = 1, GPIO90_GSM_nMOD_OFF_CMD = 1
 *   - reset : GPIO24_GSM_MOD_RESET_CMD = 1, msleep(100),
 *             GPIO24_GSM_MOD_RESET_CMD = 0
 *   - turn on  : GPIO88_GSM_nMOD_ON_CMD = 0, msleep(1000),
 *                GPIO88_GSM_nMOD_ON_CMD = 1
 *   - turn off : GPIO90_GSM_nMOD_OFF_CMD = 0, msleep(1000),
 *                GPIO90_GSM_nMOD_OFF_CMD = 1
 */
static int is_gsm_on(void)
{
	int is_on;

	is_on = !!gpio_get_value(GPIO25_GSM_MOD_ON_STATE);
	return is_on;
}

irqreturn_t gsm_on_irq(int irq, void *p)
{
	printk(KERN_DEBUG "Mioa701: GSM status changed to %s\n",
	       is_gsm_on() ? "on" : "off");
	return IRQ_HANDLED;
}

static struct gpio gsm_gpios[] = {
	{ GPIO25_GSM_MOD_ON_STATE, GPIOF_IN, "GSM state" },
	{ GPIO113_GSM_EVENT, GPIOF_IN, "GSM event" },
};

static int __init gsm_init(void)
{
	int rc;

	rc = gpio_request_array(ARRAY_AND_SIZE(gsm_gpios));
	if (rc)
		goto err_gpio;
	rc = request_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), gsm_on_irq,
			 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
			 "GSM XS200 Power Irq", NULL);
	if (rc)
		goto err_irq;

	gpio_set_wake(GPIO113_GSM_EVENT, 1);
	return 0;

err_irq:
	printk(KERN_ERR "Mioa701: Can't request GSM_ON irq\n");
	gpio_free_array(ARRAY_AND_SIZE(gsm_gpios));
err_gpio:
	printk(KERN_ERR "Mioa701: gsm not available\n");
	return rc;
}

static void gsm_exit(void)
{
	free_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), NULL);
	gpio_free_array(ARRAY_AND_SIZE(gsm_gpios));
}

/*
 * Bluetooth BRF6150 chip
 *
 * BT handling was purged from kernel. For history, this is the way to go :
 * - turn on  : GPIO83_BT_ON = 1
 * - turn off : GPIO83_BT_ON = 0
 */

/*
 * GPS Sirf Star III chip
 *
 * GPS handling was purged from kernel. For history, this is the way to go :
 * - init : GPIO23_GPS_UNKNOWN1 = 1, GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
 *          GPIO106_GPS_UNKNOWN2 = 0, GPIO107_GPS_UNKNOWN3 = 0
 * - turn on  : GPIO27_GPS_RESET = 1, GPIO26_GPS_ON = 1
 * - turn off : GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
 */

/*
 * USB UDC
 */
static int is_usb_connected(void)
{
	return !gpio_get_value(GPIO13_nUSB_DETECT);
}

static struct pxa2xx_udc_mach_info mioa701_udc_info = {
	.udc_is_connected = is_usb_connected,
	.gpio_pullup	  = GPIO22_USB_ENABLE,
};

static struct gpiod_lookup_table gpio_vbus_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO13_nUSB_DETECT,
			    "vbus", GPIO_ACTIVE_LOW),
		{ },
	},
};

/*
 * SDIO/MMC Card controller
 */
/**
 * The card detect interrupt isn't debounced so we delay it by 250ms
 * to give the card a chance to fully insert/eject.
 */
static struct pxamci_platform_data mioa701_mci_info = {
	.detect_delay_ms	= 250,
	.ocr_mask 		= MMC_VDD_32_33 | MMC_VDD_33_34,
};

static struct gpiod_lookup_table mioa701_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		/* Card detect on GPIO 15 */
		GPIO_LOOKUP("gpio-pxa", GPIO15_SDIO_INSERT,
			    "cd", GPIO_ACTIVE_LOW),
		/* Write protect on GPIO 78 */
		GPIO_LOOKUP("gpio-pxa", GPIO78_SDIO_RO,
			    "wp", GPIO_ACTIVE_LOW),
		/* Power on GPIO 91 */
		GPIO_LOOKUP("gpio-pxa", GPIO91_SDIO_EN,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

/* FlashRAM */
static struct resource docg3_resource = {
	.start = PXA_CS0_PHYS,
	.end   = PXA_CS0_PHYS + SZ_8K - 1,
	.flags = IORESOURCE_MEM,
};

static struct platform_device docg3 = {
	.name	       = "docg3",
	.id	       = -1,
	.resource      = &docg3_resource,
	.num_resources = 1,
	.dev = {
		.platform_data = NULL,
	},
};

/*
 * Suspend/Resume bootstrap management
 *
 * MIO A701 reboot sequence is highly ROM dependent. From the one dissassembled,
 * this sequence is as follows :
 *   - disables interrupts
 *   - initialize SDRAM (self refresh RAM into active RAM)
 *   - initialize GPIOs (depends on value at 0xa020b020)
 *   - initialize coprossessors
 *   - if edge detect on PWR_SCL(GPIO3), then proceed to cold start
 *   - or if value at 0xa020b000 not equal to 0x0f0f0f0f, proceed to cold start
 *   - else do a resume, ie. jump to addr 0xa0100000
 */
#define RESUME_ENABLE_ADDR	0xa020b000
#define RESUME_ENABLE_VAL	0x0f0f0f0f
#define RESUME_BT_ADDR		0xa020b020
#define RESUME_UNKNOWN_ADDR	0xa020b024
#define RESUME_VECTOR_ADDR	0xa0100000
#define BOOTSTRAP_WORDS		mioa701_bootstrap_lg/4

static u32 *save_buffer;

static void install_bootstrap(void)
{
	int i;
	u32 *rom_bootstrap  = phys_to_virt(RESUME_VECTOR_ADDR);
	u32 *src = &mioa701_bootstrap;

	for (i = 0; i < BOOTSTRAP_WORDS; i++)
		rom_bootstrap[i] = src[i];
}

static int mioa701_sys_suspend(void)
{
	int i = 0, is_bt_on;
	u32 *mem_resume_vector	= phys_to_virt(RESUME_VECTOR_ADDR);
	u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
	u32 *mem_resume_bt	= phys_to_virt(RESUME_BT_ADDR);
	u32 *mem_resume_unknown	= phys_to_virt(RESUME_UNKNOWN_ADDR);

	/* Devices prepare suspend */
	is_bt_on = !!gpio_get_value(GPIO83_BT_ON);
	pxa2xx_mfp_set_lpm(GPIO83_BT_ON,
			   is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW);

	for (i = 0; i < BOOTSTRAP_WORDS; i++)
		save_buffer[i] = mem_resume_vector[i];
	save_buffer[i++] = *mem_resume_enabler;
	save_buffer[i++] = *mem_resume_bt;
	save_buffer[i++] = *mem_resume_unknown;

	*mem_resume_enabler = RESUME_ENABLE_VAL;
	*mem_resume_bt	    = is_bt_on;

	install_bootstrap();
	return 0;
}

static void mioa701_sys_resume(void)
{
	int i = 0;
	u32 *mem_resume_vector	= phys_to_virt(RESUME_VECTOR_ADDR);
	u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
	u32 *mem_resume_bt	= phys_to_virt(RESUME_BT_ADDR);
	u32 *mem_resume_unknown	= phys_to_virt(RESUME_UNKNOWN_ADDR);

	for (i = 0; i < BOOTSTRAP_WORDS; i++)
		mem_resume_vector[i] = save_buffer[i];
	*mem_resume_enabler = save_buffer[i++];
	*mem_resume_bt	    = save_buffer[i++];
	*mem_resume_unknown = save_buffer[i++];
}

static struct syscore_ops mioa701_syscore_ops = {
	.suspend	= mioa701_sys_suspend,
	.resume		= mioa701_sys_resume,
};

static int __init bootstrap_init(void)
{
	int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3);

	register_syscore_ops(&mioa701_syscore_ops);

	save_buffer = kmalloc(save_size, GFP_KERNEL);
	if (!save_buffer)
		return -ENOMEM;
	printk(KERN_INFO "MioA701: allocated %d bytes for bootstrap\n",
	       save_size);
	return 0;
}

static void bootstrap_exit(void)
{
	kfree(save_buffer);
	unregister_syscore_ops(&mioa701_syscore_ops);

	printk(KERN_CRIT "Unregistering mioa701 suspend will hang next"
	       "resume !!!\n");
}

/*
 * Power Supply
 */
static char *supplicants[] = {
	"mioa701_battery"
};

static int is_ac_connected(void)
{
	return gpio_get_value(GPIO96_AC_DETECT);
}

static void mioa701_set_charge(int flags)
{
	gpio_set_value(GPIO9_CHARGE_EN, (flags == PDA_POWER_CHARGE_USB));
}

static struct pda_power_pdata power_pdata = {
	.is_ac_online	= is_ac_connected,
	.is_usb_online	= is_usb_connected,
	.set_charge = mioa701_set_charge,
	.supplied_to = supplicants,
	.num_supplicants = ARRAY_SIZE(supplicants),
};

static struct resource power_resources[] = {
	[0] = {
		.name	= "ac",
		.start	= PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT),
		.end	= PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
		IORESOURCE_IRQ_LOWEDGE,
	},
	[1] = {
		.name	= "usb",
		.start	= PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT),
		.end	= PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
		IORESOURCE_IRQ_LOWEDGE,
	},
};

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

static struct wm97xx_batt_pdata mioa701_battery_data = {
	.batt_aux	= WM97XX_AUX_ID1,
	.temp_aux	= -1,
	.min_voltage	= 0xc00,
	.max_voltage	= 0xfc0,
	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LION,
	.batt_div	= 1,
	.batt_mult	= 1,
	.batt_name	= "mioa701_battery",
};

static struct wm97xx_pdata mioa701_wm97xx_pdata = {
	.batt_pdata	= &mioa701_battery_data,
};

/*
 * Voltage regulation
 */
static struct regulator_consumer_supply max1586_consumers[] = {
	REGULATOR_SUPPLY("vcc_core", NULL),
};

static struct regulator_init_data max1586_v3_info = {
	.constraints = {
		.name = "vcc_core range",
		.min_uV = 1000000,
		.max_uV = 1705000,
		.always_on = 1,
		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies = ARRAY_SIZE(max1586_consumers),
	.consumer_supplies = max1586_consumers,
};

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

static struct max1586_platform_data max1586_info = {
	.subdevs = max1586_subdevs,
	.num_subdevs = ARRAY_SIZE(max1586_subdevs),
	.v3_gain = MAX1586_GAIN_NO_R24, /* 700..1475 mV */
};

/*
 * Camera interface
 */
struct pxacamera_platform_data mioa701_pxacamera_platform_data = {
	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
	.mclk_10khz = 5000,
	.sensor_i2c_adapter_id = 0,
	.sensor_i2c_address = 0x5d,
};

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

/* Board I2C devices. */
static struct i2c_board_info mioa701_i2c_devices[] = {
	{
		I2C_BOARD_INFO("mt9m111", 0x5d),
	},
};

struct i2c_pxa_platform_data i2c_pdata = {
	.fast_mode = 1,
};

static pxa2xx_audio_ops_t mioa701_ac97_info = {
	.reset_gpio = 95,
	.codec_pdata = { &mioa701_wm97xx_pdata, },
};

/*
 * Mio global
 */

/* Devices */
#define MIO_PARENT_DEV(var, strname, tparent, pdata)	\
static struct platform_device var = {			\
	.name		= strname,			\
	.id		= -1,				\
	.dev		= {				\
		.platform_data = pdata,			\
		.parent	= tparent,			\
	},						\
};
#define MIO_SIMPLE_DEV(var, strname, pdata)	\
	MIO_PARENT_DEV(var, strname, NULL, pdata)

MIO_SIMPLE_DEV(mioa701_gpio_keys, "gpio-keys",	    &mioa701_gpio_keys_data)
MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight",  &pxa27x_device_pwm0.dev,
		&mioa701_backlight_data);
MIO_SIMPLE_DEV(mioa701_led,	  "leds-gpio",	    &gpio_led_info)
MIO_SIMPLE_DEV(pxa2xx_pcm,	  "pxa2xx-pcm",	    NULL)
MIO_SIMPLE_DEV(mioa701_sound,	  "mioa701-wm9713", NULL)
MIO_SIMPLE_DEV(mioa701_board,	  "mioa701-board",  NULL)
MIO_SIMPLE_DEV(gpio_vbus,	  "gpio-vbus",      NULL);

static struct platform_device *devices[] __initdata = {
	&mioa701_gpio_keys,
	&mioa701_backlight,
	&mioa701_led,
	&pxa2xx_pcm,
	&mioa701_sound,
	&power_dev,
	&docg3,
	&gpio_vbus,
	&mioa701_board,
};

static void mioa701_machine_exit(void);

static void mioa701_poweroff(void)
{
	mioa701_machine_exit();
	pxa_restart(REBOOT_SOFT, NULL);
}

static void mioa701_restart(enum reboot_mode c, const char *cmd)
{
	mioa701_machine_exit();
	pxa_restart(REBOOT_SOFT, cmd);
}

static struct gpio global_gpios[] = {
	{ GPIO9_CHARGE_EN, GPIOF_OUT_INIT_HIGH, "Charger enable" },
	{ GPIO18_POWEROFF, GPIOF_OUT_INIT_LOW, "Power Off" },
	{ GPIO87_LCD_POWER, GPIOF_OUT_INIT_LOW, "LCD Power" },
	{ GPIO56_MT9M111_nOE, GPIOF_OUT_INIT_LOW, "Camera nOE" },
};

static struct regulator_consumer_supply fixed_5v0_consumers[] = {
	REGULATOR_SUPPLY("power", "pwm-backlight"),
};

static void __init mioa701_machine_init(void)
{
	int rc;

	PSLR  = 0xff100000; /* SYSDEL=125ms, PWRDEL=125ms, PSLR_SL_ROD=1 */
	PCFR = PCFR_DC_EN | PCFR_GPR_EN | PCFR_OPDE;
	RTTR = 32768 - 1; /* Reset crazy WinCE value */
	UP2OCR = UP2OCR_HXOE;

	/*
	 * Set up the flash memory : DiskOnChip G3 on first static memory bank
	 */
	__raw_writel(0x7ff02dd8, MSC0);
	__raw_writel(0x0001c391, MCMEM0);
	__raw_writel(0x0001c391, MCATT0);
	__raw_writel(0x0001c391, MCIO0);

	pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	rc = gpio_request_array(ARRAY_AND_SIZE(global_gpios));
	if (rc)
		pr_err("MioA701: Failed to request GPIOs: %d", rc);
	bootstrap_init();
	pxa_set_fb_info(NULL, &mioa701_pxafb_info);
	gpiod_add_lookup_table(&mioa701_mci_gpio_table);
	pxa_set_mci_info(&mioa701_mci_info);
	pxa_set_keypad_info(&mioa701_keypad_info);
	pxa_set_udc_info(&mioa701_udc_info);
	pxa_set_ac97_info(&mioa701_ac97_info);
	pm_power_off = mioa701_poweroff;
	pwm_add_table(mioa701_pwm_lookup, ARRAY_SIZE(mioa701_pwm_lookup));
	gpiod_add_lookup_table(&gpio_vbus_gpiod_table);
	platform_add_devices(devices, ARRAY_SIZE(devices));
	gsm_init();

	i2c_register_board_info(0, ARRAY_AND_SIZE(mioa701_i2c_devices));
	i2c_register_board_info(1, ARRAY_AND_SIZE(mioa701_pi2c_devices));
	pxa_set_i2c_info(&i2c_pdata);
	pxa27x_set_i2c_power_info(NULL);
	pxa_set_camera_info(&mioa701_pxacamera_platform_data);

	regulator_register_always_on(0, "fixed-5.0V", fixed_5v0_consumers,
				     ARRAY_SIZE(fixed_5v0_consumers),
				     5000000);
	regulator_has_full_constraints();
}

static void mioa701_machine_exit(void)
{
	bootstrap_exit();
	gsm_exit();
}

MACHINE_START(MIOA701, "MIO A701")
	.atag_offset	= 0x100,
	.map_io		= &pxa27x_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= &pxa27x_init_irq,
	.handle_irq	= &pxa27x_handle_irq,
	.init_machine	= mioa701_machine_init,
	.init_time	= pxa_timer_init,
	.restart	= mioa701_restart,
MACHINE_END


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

#define MIO_CFG_IN(pin, af)		\
	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
	 (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN))

#define MIO_CFG_OUT(pin, af, state)	\
	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
	 (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))

/* Global GPIOs */
#define GPIO9_CHARGE_EN				9
#define GPIO18_POWEROFF				18
#define GPIO87_LCD_POWER			87
#define GPIO96_AC_DETECT			96
#define GPIO80_MAYBE_CHARGE_VDROP		80	/* Drop of 88mV */

/* USB */
#define GPIO13_nUSB_DETECT			13
#define GPIO22_USB_ENABLE			22

/* SDIO bits */
#define GPIO78_SDIO_RO				78
#define GPIO15_SDIO_INSERT			15
#define GPIO91_SDIO_EN				91

/* Bluetooth */
#define GPIO14_BT_nACTIVITY			14
#define GPIO83_BT_ON				83
#define GPIO77_BT_UNKNOWN1			77
#define GPIO86_BT_MAYBE_nRESET			86

/* GPS */
#define GPIO23_GPS_UNKNOWN1			23
#define GPIO26_GPS_ON				26
#define GPIO27_GPS_RESET			27
#define GPIO106_GPS_UNKNOWN2			106
#define GPIO107_GPS_UNKNOWN3			107

/* GSM */
#define GPIO24_GSM_MOD_RESET_CMD		24
#define GPIO88_GSM_nMOD_ON_CMD			88
#define GPIO90_GSM_nMOD_OFF_CMD			90
#define GPIO114_GSM_nMOD_DTE_UART_STATE 	114
#define GPIO25_GSM_MOD_ON_STATE			25
#define GPIO113_GSM_EVENT			113

/* SOUND */
#define GPIO12_HPJACK_INSERT			12

/* LEDS */
#define GPIO10_LED_nCharging			10
#define GPIO97_LED_nBlue			97
#define GPIO98_LED_nOrange			98
#define GPIO82_LED_nVibra			82
#define GPIO115_LED_nKeyboard			115

/* Keyboard */
#define GPIO0_KEY_POWER				0
#define GPIO93_KEY_VOLUME_UP			93
#define GPIO94_KEY_VOLUME_DOWN			94

/* Camera */
#define GPIO56_MT9M111_nOE			56

extern struct input_dev *mioa701_evdev;
extern void mioa701_gpio_lpm_set(unsigned long mfp_pin);

/* Assembler externals mioa701_bootresume.S */
extern u32 mioa701_bootstrap;
extern u32 mioa701_jumpaddr;
extern u32 mioa701_bootstrap_lg;

#endif /* _MIOA701_H */

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/* Bootloader to resume MIO A701
 *
 * 2007-1-12 Robert Jarzmik
*/

#include <linux/linkage.h>
#include <asm/assembler.h>

/*
 * Note: Yes, part of the following code is located into the .data section.
 *       This is to allow jumpaddr to be accessed with a relative load
 *       while we can't rely on any MMU translation.  We could have put
 *       sleep_save_sp in the .text section as well, but some setups might
 *       insist on it to be truly read-only.
 */
	.data
	.align	2
ENTRY(mioa701_bootstrap)
0:
	b	1f
ENTRY(mioa701_jumpaddr)
	.word	0x40f00008		@ PSPR in no-MMU mode
1:
	mov	r0,     #0xa0000000	@ Don't suppose memory access works
	orr	r0, r0, #0x00200000	@ even if it's supposed to
	orr	r0, r0, #0x0000b000
	mov	r1, #0
	str	r1, [r0]		@ Early disable resume for next boot
	ldr	r0, mioa701_jumpaddr	@ (Murphy's Law)
	ldr	r0, [r0]
	ret	r0
2:

ENTRY(mioa701_bootstrap_lg)
	.data
	.align	2
	.word	2b-0b


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/mp900.c
 *
 *  Support for the NEC MobilePro900/C platform
 *
 *  Based on mach-pxa/gumstix.c
 *
 *  2007, 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com>
 *  2007, 2008 Michael Petchkovsky <mkpetch@internode.on.net>
 */

#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/usb/isp116x.h>

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

#include "pxa25x.h"
#include "generic.h"

static void isp116x_pfm_delay(struct device *dev, int delay)
{

	/* 400MHz PXA2 = 2.5ns / instruction */

	int cyc = delay / 10;

	/* 4 Instructions = 4 x 2.5ns = 10ns */
	__asm__ volatile ("0:\n"
		"subs %0, %1, #1\n"
		"bge 0b\n"
		:"=r" (cyc)
		:"0"(cyc)
	);
}

static struct isp116x_platform_data isp116x_pfm_data = {
	.remote_wakeup_enable = 1,
	.delay = isp116x_pfm_delay,
};

static struct resource isp116x_pfm_resources[] = {
	[0] =	{
		.start	= 0x0d000000,
		.end	= 0x0d000000 + 1,
		.flags	= IORESOURCE_MEM,
		},
	[1] =	{
		.start  = 0x0d000000 + 4,
		.end	= 0x0d000000 + 5,
		.flags  = IORESOURCE_MEM,
		},
	[2] =	{
		.start	= 61,
		.end	= 61,
		.flags	= IORESOURCE_IRQ,
		},
};

static struct platform_device mp900c_dummy_device = {
	.name		= "mp900c_dummy",
	.id		= -1,
};

static struct platform_device mp900c_usb = {
	.name		= "isp116x-hcd",
	.num_resources	= ARRAY_SIZE(isp116x_pfm_resources),
	.resource	= isp116x_pfm_resources,
	.dev.platform_data = &isp116x_pfm_data,
};

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

static void __init mp900c_init(void)
{
	printk(KERN_INFO "MobilePro 900/C machine init\n");
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	platform_add_devices(devices, ARRAY_SIZE(devices));
}

/* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */
MACHINE_START(NEC_MP900, "MobilePro900/C")
	.atag_offset	= 0x220100,
	.init_time	= pxa_timer_init,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.init_machine	= mp900c_init,
	.restart	= pxa_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-pxa/mxm8x10.c
 *
 * Support for the Embedian MXM-8x10 Computer on Module
 *
 * Copyright (C) 2006 Marvell International Ltd.
 * Copyright (C) 2009 Embedian Inc.
 * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
 *
 * 2007-09-04: eric miao <eric.y.miao@gmail.com>
 *             rewrite to align with latest kernel
 *
 * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
 * 	       Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
 *             rework for upstream merge
 */

#include <linux/serial_8250.h>
#include <linux/dm9000.h>
#include <linux/gpio/machine.h>
#include <linux/platform_data/i2c-pxa.h>

#include <linux/platform_data/mtd-nand-pxa3xx.h>

#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/asoc-pxa.h>
#include "pxa320.h"

#include "mxm8x10.h"

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

/* GPIO pin definition

External device stuff   - Leave unconfigured for now...
---------------------
GPIO0   -   DREQ    (External DMA Request)
GPIO3   -   nGCS2   (External Chip Select) Where is nGCS0; nGCS1; nGCS4; nGCS5 ?
GPIO4   -   nGCS3
GPIO15  -   EXT_GPIO1
GPIO16  -   EXT_GPIO2
GPIO17  -   EXT_GPIO3
GPIO24  -   EXT_GPIO4
GPIO25  -   EXT_GPIO5
GPIO26  -   EXT_GPIO6
GPIO27  -   EXT_GPIO7
GPIO28  -   EXT_GPIO8
GPIO29  -   EXT_GPIO9
GPIO30  -   EXT_GPIO10
GPIO31  -   EXT_GPIO11
GPIO57  -   EXT_GPIO12
GPIO74  -   EXT_IRQ1
GPIO75  -   EXT_IRQ2
GPIO76  -   EXT_IRQ3
GPIO77  -   EXT_IRQ4
GPIO78  -   EXT_IRQ5
GPIO79  -   EXT_IRQ6
GPIO80  -   EXT_IRQ7
GPIO81  -   EXT_IRQ8
GPIO87  -   VCCIO_PWREN (External Device PWREN)

Dallas 1-Wire   - Leave unconfigured for now...
-------------
GPIO0_2 -   DS - 1Wire

Ethernet
--------
GPIO1   -   DM9000 PWR
GPIO9   -   DM9K_nIRQ
GPIO36  -   DM9K_RESET

Keypad  - Leave unconfigured by for now...
------
GPIO1_2 -   KP_DKIN0
GPIO5_2 -   KP_MKOUT7
GPIO82  -   KP_DKIN1
GPIO85  -   KP_DKIN2
GPIO86  -   KP_DKIN3
GPIO113 -   KP_MKIN0
GPIO114 -   KP_MKIN1
GPIO115 -   KP_MKIN2
GPIO116 -   KP_MKIN3
GPIO117 -   KP_MKIN4
GPIO118 -   KP_MKIN5
GPIO119 -   KP_MKIN6
GPIO120 -   KP_MKIN7
GPIO121 -   KP_MKOUT0
GPIO122 -   KP_MKOUT1
GPIO122 -   KP_MKOUT2
GPIO123 -   KP_MKOUT3
GPIO124 -   KP_MKOUT4
GPIO125 -   KP_MKOUT5
GPIO127 -   KP_MKOUT6

Data Bus    - Leave unconfigured for now...
--------
GPIO2   -   nWait (Data Bus)

USB Device
----------
GPIO4_2 -   USBD_PULLUP
GPIO10  -   UTM_CLK (USB Device UTM Clk)
GPIO49  -   USB 2.0 Device UTM_DATA0
GPIO50  -   USB 2.0 Device UTM_DATA1
GPIO51  -   USB 2.0 Device UTM_DATA2
GPIO52  -   USB 2.0 Device UTM_DATA3
GPIO53  -   USB 2.0 Device UTM_DATA4
GPIO54  -   USB 2.0 Device UTM_DATA5
GPIO55  -   USB 2.0 Device UTM_DATA6
GPIO56  -   USB 2.0 Device UTM_DATA7
GPIO58  -   UTM_RXVALID (USB 2.0 Device)
GPIO59  -   UTM_RXACTIVE (USB 2.0 Device)
GPIO60  -   UTM_RXERROR
GPIO61  -   UTM_OPMODE0
GPIO62  -   UTM_OPMODE1
GPIO71  -   USBD_INT    (USB Device?)
GPIO73  -   UTM_TXREADY (USB 2.0 Device)
GPIO83  -   UTM_TXVALID (USB 2.0 Device)
GPIO98  -   UTM_RESET   (USB 2.0 device)
GPIO99  -   UTM_XCVR_SELECT
GPIO100 -   UTM_TERM_SELECT
GPIO101 -   UTM_SUSPENDM_X
GPIO102 -   UTM_LINESTATE0
GPIO103 -   UTM_LINESTATE1

Card-Bus Interface  - Leave unconfigured for now...
------------------
GPIO5   -   nPIOR (I/O space output enable)
GPIO6   -   nPIOW (I/O space write enable)
GPIO7   -   nIOS16 (Input from I/O space telling size of data bus)
GPIO8   -   nPWAIT (Input for inserting wait states)

LCD
---
GPIO6_2     -   LDD0
GPIO7_2     -   LDD1
GPIO8_2     -   LDD2
GPIO9_2     -   LDD3
GPIO11_2    -   LDD5
GPIO12_2    -   LDD6
GPIO13_2    -   LDD7
GPIO14_2    -   VSYNC
GPIO15_2    -   HSYNC
GPIO16_2    -   VCLK
GPIO17_2    -   HCLK
GPIO18_2    -   VDEN
GPIO63      -   LDD8    (CPU LCD)
GPIO64      -   LDD9    (CPU LCD)
GPIO65      -   LDD10   (CPU LCD)
GPIO66      -   LDD11   (CPU LCD)
GPIO67      -   LDD12   (CPU LCD)
GPIO68      -   LDD13   (CPU LCD)
GPIO69      -   LDD14   (CPU LCD)
GPIO70      -   LDD15   (CPU LCD)
GPIO88      -   VCCLCD_PWREN (LCD Panel PWREN)
GPIO97      -   BACKLIGHT_EN
GPIO104     -   LCD_PWREN

PWM   - Leave unconfigured for now...
---
GPIO11  -   PWM0
GPIO12  -   PWM1
GPIO13  -   PWM2
GPIO14  -   PWM3

SD-CARD
-------
GPIO18  -   SDDATA0
GPIO19  -   SDDATA1
GPIO20  -   SDDATA2
GPIO21  -   SDDATA3
GPIO22  -   SDCLK
GPIO23  -   SDCMD
GPIO72  -   SD_WP
GPIO84  -   SD_nIRQ_CD  (SD-Card)

I2C
---
GPIO32  -   I2CSCL
GPIO33  -   I2CSDA

AC97
----
GPIO35  -   AC97_SDATA_IN
GPIO37  -   AC97_SDATA_OUT
GPIO38  -   AC97_SYNC
GPIO39  -   AC97_BITCLK
GPIO40  -   AC97_nRESET

UART1
-----
GPIO41  -   UART_RXD1
GPIO42  -   UART_TXD1
GPIO43  -   UART_CTS1
GPIO44  -   UART_DCD1
GPIO45  -   UART_DSR1
GPIO46  -   UART_nRI1
GPIO47  -   UART_DTR1
GPIO48  -   UART_RTS1

UART2
-----
GPIO109 -   RTS2
GPIO110 -   RXD2
GPIO111 -   TXD2
GPIO112 -   nCTS2

UART3
-----
GPIO105 -   nCTS3
GPIO106 -   nRTS3
GPIO107 -   TXD3
GPIO108 -   RXD3

SSP3    - Leave unconfigured for now...
----
GPIO89  -   SSP3_CLK
GPIO90  -   SSP3_SFRM
GPIO91  -   SSP3_TXD
GPIO92  -   SSP3_RXD

SSP4
GPIO93  -   SSP4_CLK
GPIO94  -   SSP4_SFRM
GPIO95  -   SSP4_TXD
GPIO96  -   SSP4_RXD
*/

static mfp_cfg_t mfp_cfg[] __initdata = {
	/* USB */
	GPIO10_UTM_CLK,
	GPIO49_U2D_PHYDATA_0,
	GPIO50_U2D_PHYDATA_1,
	GPIO51_U2D_PHYDATA_2,
	GPIO52_U2D_PHYDATA_3,
	GPIO53_U2D_PHYDATA_4,
	GPIO54_U2D_PHYDATA_5,
	GPIO55_U2D_PHYDATA_6,
	GPIO56_U2D_PHYDATA_7,
	GPIO58_UTM_RXVALID,
	GPIO59_UTM_RXACTIVE,
	GPIO60_U2D_RXERROR,
	GPIO61_U2D_OPMODE0,
	GPIO62_U2D_OPMODE1,
	GPIO71_GPIO, /* USBD_INT */
	GPIO73_UTM_TXREADY,
	GPIO83_U2D_TXVALID,
	GPIO98_U2D_RESET,
	GPIO99_U2D_XCVR_SEL,
	GPIO100_U2D_TERM_SEL,
	GPIO101_U2D_SUSPEND,
	GPIO102_UTM_LINESTATE_0,
	GPIO103_UTM_LINESTATE_1,
	GPIO4_2_GPIO | MFP_PULL_HIGH, /* UTM_PULLUP */

	/* DM9000 */
	GPIO1_GPIO,
	GPIO9_GPIO,
	GPIO36_GPIO,

	/* AC97 */
	GPIO35_AC97_SDATA_IN_0,
	GPIO37_AC97_SDATA_OUT,
	GPIO38_AC97_SYNC,
	GPIO39_AC97_BITCLK,
	GPIO40_AC97_nACRESET,

	/* UARTS */
	GPIO41_UART1_RXD,
	GPIO42_UART1_TXD,
	GPIO43_UART1_CTS,
	GPIO44_UART1_DCD,
	GPIO45_UART1_DSR,
	GPIO46_UART1_RI,
	GPIO47_UART1_DTR,
	GPIO48_UART1_RTS,

	GPIO109_UART2_RTS,
	GPIO110_UART2_RXD,
	GPIO111_UART2_TXD,
	GPIO112_UART2_CTS,

	GPIO105_UART3_CTS,
	GPIO106_UART3_RTS,
	GPIO107_UART3_TXD,
	GPIO108_UART3_RXD,

	GPIO78_GPIO,
	GPIO79_GPIO,
	GPIO80_GPIO,
	GPIO81_GPIO,

	/* I2C */
	GPIO32_I2C_SCL,
	GPIO33_I2C_SDA,

	/* MMC */
	GPIO18_MMC1_DAT0,
	GPIO19_MMC1_DAT1,
	GPIO20_MMC1_DAT2,
	GPIO21_MMC1_DAT3,
	GPIO22_MMC1_CLK,
	GPIO23_MMC1_CMD,
	GPIO72_GPIO | MFP_PULL_HIGH, /* Card Detect */
	GPIO84_GPIO | MFP_PULL_LOW, /* Write Protect */

	/* IRQ */
	GPIO74_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ1 */
	GPIO75_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ2 */
	GPIO76_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ3 */
	GPIO77_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ4 */
	GPIO78_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ5 */
	GPIO79_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ6 */
	GPIO80_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ7 */
	GPIO81_GPIO | MFP_LPM_EDGE_RISE  /* EXT_IRQ8 */
};

/* MMC/MCI Support */
#if defined(CONFIG_MMC)
static struct pxamci_platform_data mxm_8x10_mci_platform_data = {
	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
	.detect_delay_ms = 10,
};

static struct gpiod_lookup_table mxm_8x10_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		/* Card detect on GPIO 72 */
		GPIO_LOOKUP("gpio-pxa", MXM_8X10_SD_nCD,
			    "cd", GPIO_ACTIVE_LOW),
		/* Write protect on GPIO 84 */
		GPIO_LOOKUP("gpio-pxa", MXM_8X10_SD_WP,
			    "wp", GPIO_ACTIVE_LOW),
		{ },
	},
};

void __init mxm_8x10_mmc_init(void)
{
	gpiod_add_lookup_table(&mxm_8x10_mci_gpio_table);
	pxa_set_mci_info(&mxm_8x10_mci_platform_data);
}
#endif

/* USB Open Host Controller Interface */
static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = {
	.port_mode = PMM_NPS_MODE,
	.flags = ENABLE_PORT_ALL
};

void __init mxm_8x10_usb_host_init(void)
{
	pxa_set_ohci_info(&mxm_8x10_ohci_platform_data);
}

void __init mxm_8x10_ac97_init(void)
{
	pxa_set_ac97_info(NULL);
}

/* NAND flash Support */
#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
#define NAND_BLOCK_SIZE SZ_128K
#define NB(x)           (NAND_BLOCK_SIZE * (x))
static struct mtd_partition mxm_8x10_nand_partitions[] = {
	[0] = {
	       .name = "boot",
	       .size = NB(0x002),
	       .offset = NB(0x000),
	       .mask_flags = MTD_WRITEABLE
	},
	[1] = {
	       .name = "kernel",
	       .size = NB(0x010),
	       .offset = NB(0x002),
	       .mask_flags = MTD_WRITEABLE
	},
	[2] = {
	       .name = "root",
	       .size = NB(0x36c),
	       .offset = NB(0x012)
	},
	[3] = {
	       .name = "bbt",
	       .size = NB(0x082),
	       .offset = NB(0x37e),
	       .mask_flags = MTD_WRITEABLE
	}
};

static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
	.keep_config	= 1,
	.parts		= mxm_8x10_nand_partitions,
	.nr_parts	= ARRAY_SIZE(mxm_8x10_nand_partitions)
};

static void __init mxm_8x10_nand_init(void)
{
	pxa3xx_set_nand_info(&mxm_8x10_nand_info);
}
#else
static inline void mxm_8x10_nand_init(void) {}
#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */

/* Ethernet support: Davicom DM9000 */
static struct resource dm9k_resources[] = {
	[0] = {
	       .start = MXM_8X10_ETH_PHYS + 0x300,
	       .end = MXM_8X10_ETH_PHYS + 0x300,
	       .flags = IORESOURCE_MEM
	},
	[1] = {
	       .start = MXM_8X10_ETH_PHYS + 0x308,
	       .end = MXM_8X10_ETH_PHYS + 0x308,
	       .flags = IORESOURCE_MEM
	},
	[2] = {
	       .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)),
	       .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)),
	       .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE
	}
};

static struct dm9000_plat_data dm9k_plat_data = {
	.flags = DM9000_PLATF_16BITONLY
};

static struct platform_device dm9k_device = {
	.name = "dm9000",
	.id = 0,
	.num_resources = ARRAY_SIZE(dm9k_resources),
	.resource = dm9k_resources,
	.dev = {
		.platform_data = &dm9k_plat_data
	}
};

static void __init mxm_8x10_ethernet_init(void)
{
	platform_device_register(&dm9k_device);
}

/* PXA UARTs */
static void __init mxm_8x10_uarts_init(void)
{
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
}

/* I2C and Real Time Clock */
static struct i2c_board_info __initdata mxm_8x10_i2c_devices[] = {
	{
		I2C_BOARD_INFO("ds1337", 0x68)
	}
};

static void __init mxm_8x10_i2c_init(void)
{
	i2c_register_board_info(0, mxm_8x10_i2c_devices,
				ARRAY_SIZE(mxm_8x10_i2c_devices));
	pxa_set_i2c_info(NULL);
}

void __init mxm_8x10_barebones_init(void)
{
	pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));

	mxm_8x10_uarts_init();
	mxm_8x10_nand_init();
	mxm_8x10_i2c_init();
	mxm_8x10_ethernet_init();
}


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

#define MXM_8X10_ETH_PHYS	0x13000000

#if defined(CONFIG_MMC)

#define MXM_8X10_SD_nCD (72)
#define MXM_8X10_SD_WP (84)

extern void mxm_8x10_mmc_init(void);
#else
static inline void mxm_8x10_mmc_init(void) {}
#endif

extern void mxm_8x10_usb_host_init(void);
extern void mxm_8x10_ac97_init(void);

extern void mxm_8x10_barebones_init(void);

#endif /* __MACH_MXM_8X10_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Common code for Palm LD, T5, TX, Z72
 *
 * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
 */

#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/pda_power.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/regulator/max1586.h>
#include <linux/platform_data/i2c-pxa.h>

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

#include "pxa27x.h"
#include <linux/platform_data/asoc-pxa.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/irda-pxaficp.h>
#include "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
#include "palm27x.h"

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

/******************************************************************************
 * SD/MMC card controller
 ******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
static struct pxamci_platform_data palm27x_mci_platform_data = {
	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
	.detect_delay_ms	= 200,
};

void __init palm27x_mmc_init(struct gpiod_lookup_table *gtable)
{
	if (gtable)
		gpiod_add_lookup_table(gtable);
	pxa_set_mci_info(&palm27x_mci_platform_data);
}
#endif

/******************************************************************************
 * Power management - standby
 ******************************************************************************/
#if defined(CONFIG_SUSPEND)
void __init palm27x_pm_init(unsigned long str_base)
{
	static const unsigned long resume[] = {
		0xe3a00101,	/* mov	r0,	#0x40000000 */
		0xe380060f,	/* orr	r0, r0, #0x00f00000 */
		0xe590f008,	/* ldr	pc, [r0, #0x08] */
	};

	/*
	 * Copy the bootloader.
	 * NOTE: PalmZ72 uses a different wakeup method!
	 */
	memcpy(phys_to_virt(str_base), resume, sizeof(resume));
}
#endif

/******************************************************************************
 * Framebuffer
 ******************************************************************************/
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
struct pxafb_mode_info palm_320x480_lcd_mode = {
	.pixclock	= 57692,
	.xres		= 320,
	.yres		= 480,
	.bpp		= 16,

	.left_margin	= 32,
	.right_margin	= 1,
	.upper_margin	= 7,
	.lower_margin	= 1,

	.hsync_len	= 4,
	.vsync_len	= 1,
};

struct pxafb_mode_info palm_320x320_lcd_mode = {
	.pixclock	= 115384,
	.xres		= 320,
	.yres		= 320,
	.bpp		= 16,

	.left_margin	= 27,
	.right_margin	= 7,
	.upper_margin	= 7,
	.lower_margin	= 8,

	.hsync_len	= 6,
	.vsync_len	= 1,
};

struct pxafb_mode_info palm_320x320_new_lcd_mode = {
	.pixclock	= 86538,
	.xres		= 320,
	.yres		= 320,
	.bpp		= 16,

	.left_margin	= 20,
	.right_margin	= 8,
	.upper_margin	= 8,
	.lower_margin	= 5,

	.hsync_len	= 4,
	.vsync_len	= 1,
};

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

static int palm27x_lcd_power;
static void palm27x_lcd_ctl(int on, struct fb_var_screeninfo *info)
{
	gpio_set_value(palm27x_lcd_power, on);
}

void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
{
	palm27x_lcd_screen.modes = mode;

	if (gpio_is_valid(power)) {
		if (!gpio_request(power, "LCD power")) {
			pr_err("Palm27x: failed to claim lcd power gpio!\n");
			return;
		}
		if (!gpio_direction_output(power, 1)) {
			pr_err("Palm27x: lcd power configuration failed!\n");
			return;
		}
		palm27x_lcd_power = power;
		palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl;
	}

	pxa_set_fb_info(NULL, &palm27x_lcd_screen);
}
#endif

/******************************************************************************
 * USB Gadget
 ******************************************************************************/
#if	defined(CONFIG_USB_PXA27X) || \
	defined(CONFIG_USB_PXA27X_MODULE)

/* The actual GPIO offsets get filled in in the palm27x_udc_init() call */
static struct gpiod_lookup_table palm27x_udc_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", 0,
			    "vbus", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", 0,
			    "pullup", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

void __init palm27x_udc_init(int vbus, int pullup, int vbus_inverted)
{
	palm27x_udc_gpiod_table.table[0].chip_hwnum = vbus;
	palm27x_udc_gpiod_table.table[1].chip_hwnum = pullup;
	if (vbus_inverted)
		palm27x_udc_gpiod_table.table[0].flags = GPIO_ACTIVE_LOW;

	gpiod_add_lookup_table(&palm27x_udc_gpiod_table);
	platform_device_register(&palm27x_gpio_vbus);
}
#endif

/******************************************************************************
 * IrDA
 ******************************************************************************/
#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
static struct pxaficp_platform_data palm27x_ficp_platform_data = {
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
};

void __init palm27x_irda_init(int pwdn)
{
	palm27x_ficp_platform_data.gpio_pwdown = pwdn;
	pxa_set_ficp_info(&palm27x_ficp_platform_data);
}
#endif

/******************************************************************************
 * WM97xx audio, battery
 ******************************************************************************/
#if	defined(CONFIG_TOUCHSCREEN_WM97XX) || \
	defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE)
static struct wm97xx_batt_pdata palm27x_batt_pdata = {
	.batt_aux	= WM97XX_AUX_ID3,
	.temp_aux	= WM97XX_AUX_ID2,
	.batt_mult	= 1000,
	.batt_div	= 414,
	.temp_mult	= 1,
	.temp_div	= 1,
	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LIPO,
	.batt_name	= "main-batt",
};

static struct wm97xx_pdata palm27x_wm97xx_pdata = {
	.batt_pdata	= &palm27x_batt_pdata,
};

static pxa2xx_audio_ops_t palm27x_ac97_pdata = {
	.codec_pdata	= { &palm27x_wm97xx_pdata, },
};

static struct palm27x_asoc_info palm27x_asoc_pdata = {
	.jack_gpio	= -1,
};

static struct platform_device palm27x_asoc = {
	.name = "palm27x-asoc",
	.id   = -1,
	.dev  = {
		.platform_data = &palm27x_asoc_pdata,
	},
};

void __init palm27x_ac97_init(int minv, int maxv, int jack, int reset)
{
	palm27x_ac97_pdata.reset_gpio	= reset;
	palm27x_asoc_pdata.jack_gpio	= jack;

	if (minv < 0 || maxv < 0) {
		palm27x_ac97_pdata.codec_pdata[0] = NULL;
		pxa_set_ac97_info(&palm27x_ac97_pdata);
	} else {
		palm27x_batt_pdata.min_voltage	= minv,
		palm27x_batt_pdata.max_voltage	= maxv,

		pxa_set_ac97_info(&palm27x_ac97_pdata);
		platform_device_register(&palm27x_asoc);
	}
}
#endif

/******************************************************************************
 * Backlight
 ******************************************************************************/
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
static struct pwm_lookup palm27x_pwm_lookup[] = {
	PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 3500 * 1024,
		   PWM_POLARITY_NORMAL),
};

static int palm_bl_power;
static int palm_lcd_power;

static int palm27x_backlight_init(struct device *dev)
{
	int ret;

	ret = gpio_request(palm_bl_power, "BL POWER");
	if (ret)
		goto err;
	ret = gpio_direction_output(palm_bl_power, 0);
	if (ret)
		goto err2;

	if (gpio_is_valid(palm_lcd_power)) {
		ret = gpio_request(palm_lcd_power, "LCD POWER");
		if (ret)
			goto err2;
		ret = gpio_direction_output(palm_lcd_power, 0);
		if (ret)
			goto err3;
	}

	return 0;
err3:
	gpio_free(palm_lcd_power);
err2:
	gpio_free(palm_bl_power);
err:
	return ret;
}

static int palm27x_backlight_notify(struct device *dev, int brightness)
{
	gpio_set_value(palm_bl_power, brightness);
	if (gpio_is_valid(palm_lcd_power))
		gpio_set_value(palm_lcd_power, brightness);
	return brightness;
}

static void palm27x_backlight_exit(struct device *dev)
{
	gpio_free(palm_bl_power);
	if (gpio_is_valid(palm_lcd_power))
		gpio_free(palm_lcd_power);
}

static struct platform_pwm_backlight_data palm27x_backlight_data = {
	.max_brightness	= 0xfe,
	.dft_brightness	= 0x7e,
	.init		= palm27x_backlight_init,
	.notify		= palm27x_backlight_notify,
	.exit		= palm27x_backlight_exit,
};

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

void __init palm27x_pwm_init(int bl, int lcd)
{
	palm_bl_power	= bl;
	palm_lcd_power	= lcd;
	pwm_add_table(palm27x_pwm_lookup, ARRAY_SIZE(palm27x_pwm_lookup));
	platform_device_register(&palm27x_backlight);
}
#endif

/******************************************************************************
 * Power supply
 ******************************************************************************/
#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE)
static int palm_ac_state;
static int palm_usb_state;

static int palm27x_power_supply_init(struct device *dev)
{
	int ret;

	ret = gpio_request(palm_ac_state, "AC state");
	if (ret)
		goto err1;
	ret = gpio_direction_input(palm_ac_state);
	if (ret)
		goto err2;

	if (gpio_is_valid(palm_usb_state)) {
		ret = gpio_request(palm_usb_state, "USB state");
		if (ret)
			goto err2;
		ret = gpio_direction_input(palm_usb_state);
		if (ret)
			goto err3;
	}

	return 0;
err3:
	gpio_free(palm_usb_state);
err2:
	gpio_free(palm_ac_state);
err1:
	return ret;
}

static void palm27x_power_supply_exit(struct device *dev)
{
	gpio_free(palm_usb_state);
	gpio_free(palm_ac_state);
}

static int palm27x_is_ac_online(void)
{
	return gpio_get_value(palm_ac_state);
}

static int palm27x_is_usb_online(void)
{
	return !gpio_get_value(palm_usb_state);
}
static char *palm27x_supplicants[] = {
	"main-battery",
};

static struct pda_power_pdata palm27x_ps_info = {
	.init			= palm27x_power_supply_init,
	.exit			= palm27x_power_supply_exit,
	.is_ac_online		= palm27x_is_ac_online,
	.is_usb_online		= palm27x_is_usb_online,
	.supplied_to		= palm27x_supplicants,
	.num_supplicants	= ARRAY_SIZE(palm27x_supplicants),
};

static struct platform_device palm27x_power_supply = {
	.name = "pda-power",
	.id   = -1,
	.dev  = {
		.platform_data = &palm27x_ps_info,
	},
};

void __init palm27x_power_init(int ac, int usb)
{
	palm_ac_state	= ac;
	palm_usb_state	= usb;
	platform_device_register(&palm27x_power_supply);
}
#endif

/******************************************************************************
 * Core power regulator
 ******************************************************************************/
#if defined(CONFIG_REGULATOR_MAX1586) || \
    defined(CONFIG_REGULATOR_MAX1586_MODULE)
static struct regulator_consumer_supply palm27x_max1587a_consumers[] = {
	REGULATOR_SUPPLY("vcc_core", NULL),
};

static struct regulator_init_data palm27x_max1587a_v3_info = {
	.constraints = {
		.name		= "vcc_core range",
		.min_uV		= 900000,
		.max_uV		= 1705000,
		.always_on	= 1,
		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
	},
	.consumer_supplies	= palm27x_max1587a_consumers,
	.num_consumer_supplies	= ARRAY_SIZE(palm27x_max1587a_consumers),
};

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

static struct max1586_platform_data palm27x_max1587a_info = {
	.subdevs     = palm27x_max1587a_subdevs,
	.num_subdevs = ARRAY_SIZE(palm27x_max1587a_subdevs),
	.v3_gain     = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
};

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

static struct i2c_pxa_platform_data palm27x_i2c_power_info = {
	.use_pio	= 1,
};

void __init palm27x_pmic_init(void)
{
	i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info));
	pxa27x_set_i2c_power_info(&palm27x_i2c_power_info);
}
#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Common functions for Palm LD, T5, TX, Z72
 *
 * Copyright (C) 2010
 * Marek Vasut <marek.vasut@gmail.com>
 */
#ifndef	__INCLUDE_MACH_PALM27X__
#define	__INCLUDE_MACH_PALM27X__

#include <linux/gpio/machine.h>

#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
extern void __init palm27x_mmc_init(struct gpiod_lookup_table *gtable);
#else
static inline void palm27x_mmc_init(struct gpiod_lookup_table *gtable)
{}
#endif

#if defined(CONFIG_SUSPEND)
extern void __init palm27x_pm_init(unsigned long str_base);
#else
static inline void palm27x_pm_init(unsigned long str_base) {}
#endif

#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
extern struct pxafb_mode_info palm_320x480_lcd_mode;
extern struct pxafb_mode_info palm_320x320_lcd_mode;
extern struct pxafb_mode_info palm_320x320_new_lcd_mode;
extern void __init palm27x_lcd_init(int power,
					struct pxafb_mode_info *mode);
#else
#define palm27x_lcd_init(power, mode)	do {} while (0)
#endif

#if	defined(CONFIG_USB_PXA27X) || \
	defined(CONFIG_USB_PXA27X_MODULE)
extern void __init palm27x_udc_init(int vbus, int pullup,
					int vbus_inverted);
#else
static inline void palm27x_udc_init(int vbus, int pullup, int vbus_inverted) {}
#endif

#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
extern void __init palm27x_irda_init(int pwdn);
#else
static inline void palm27x_irda_init(int pwdn) {}
#endif

#if	defined(CONFIG_TOUCHSCREEN_WM97XX) || \
	defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE)
extern void __init palm27x_ac97_init(int minv, int maxv, int jack,
					int reset);
#else
static inline void palm27x_ac97_init(int minv, int maxv, int jack, int reset) {}
#endif

#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
extern void __init palm27x_pwm_init(int bl, int lcd);
#else
static inline void palm27x_pwm_init(int bl, int lcd) {}
#endif

#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE)
extern void __init palm27x_power_init(int ac, int usb);
#else
static inline void palm27x_power_init(int ac, int usb) {}
#endif

#if defined(CONFIG_REGULATOR_MAX1586) || \
    defined(CONFIG_REGULATOR_MAX1586_MODULE)
extern void __init palm27x_pmic_init(void);
#else
static inline void palm27x_pmic_init(void) {}
#endif

#endif	/* __INCLUDE_MACH_PALM27X__ */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/drivers/pcmcia/pxa2xx_palmld.c
 *
 * Driver for Palm LifeDrive PCMCIA
 *
 * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
 * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
 */

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

#include <asm/mach-types.h>
#include <pcmcia/soc_common.h>

#include "palmld.h"

static struct gpio palmld_pcmcia_gpios[] = {
	{ GPIO_NR_PALMLD_PCMCIA_POWER,	GPIOF_INIT_LOW,	"PCMCIA Power" },
	{ GPIO_NR_PALMLD_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
};

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

	ret = gpio_request_array(palmld_pcmcia_gpios,
				ARRAY_SIZE(palmld_pcmcia_gpios));

	skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY;
	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";

	return ret;
}

static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
	gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios));
}

static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
					struct pcmcia_state *state)
{
	state->detect = 1; /* always inserted */
	state->vs_3v  = 1;
	state->vs_Xv  = 0;
}

static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
					const socket_state_t *state)
{
	gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
	gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
			!!(state->flags & SS_RESET));

	return 0;
}

static struct pcmcia_low_level palmld_pcmcia_ops = {
	.owner			= THIS_MODULE,

	.first			= 1,
	.nr			= 1,

	.hw_init		= palmld_pcmcia_hw_init,
	.hw_shutdown		= palmld_pcmcia_hw_shutdown,

	.socket_state		= palmld_pcmcia_socket_state,
	.configure_socket	= palmld_pcmcia_configure_socket,
};

static struct platform_device *palmld_pcmcia_device;

static int __init palmld_pcmcia_init(void)
{
	int ret;

	if (!machine_is_palmld())
		return -ENODEV;

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

	ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
					sizeof(palmld_pcmcia_ops));

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

	if (ret)
		platform_device_put(palmld_pcmcia_device);

	return ret;
}

static void __exit palmld_pcmcia_exit(void)
{
	platform_device_unregister(palmld_pcmcia_device);
}

module_init(palmld_pcmcia_init);
module_exit(palmld_pcmcia_exit);

MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
	    " Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
MODULE_LICENSE("GPL");


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for Palm LifeDrive
 *
 * Author:     Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on work of:
 *		Alex Osborne <ato@meshy.org>
 *
 * (find more info at www.hackndev.com)
 */

#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>

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

#include "pxa27x.h"
#include "palmld.h"
#include <linux/platform_data/asoc-pxa.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include <linux/platform_data/asoc-palm27x.h>
#include "palm27x.h"

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

/******************************************************************************
 * Pin configuration
 ******************************************************************************/
static unsigned long palmld_pin_config[] __initdata = {
	/* MMC */
	GPIO32_MMC_CLK,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	GPIO112_MMC_CMD,
	GPIO14_GPIO,	/* SD detect */
	GPIO114_GPIO,	/* SD power */
	GPIO116_GPIO,	/* SD r/o switch */

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

	/* IrDA */
	GPIO108_GPIO,	/* ir disable */
	GPIO46_FICP_RXD,
	GPIO47_FICP_TXD,

	/* MATRIX KEYPAD */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* PWM */
	GPIO16_PWM0_OUT,

	/* GPIO KEYS */
	GPIO10_GPIO,	/* hotsync button */
	GPIO12_GPIO,	/* power switch */
	GPIO15_GPIO,	/* lock switch */

	/* LEDs */
	GPIO52_GPIO,	/* green led */
	GPIO94_GPIO,	/* orange led */

	/* PCMCIA */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO85_nPCE_1,
	GPIO54_nPCE_2,
	GPIO79_PSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,
	GPIO36_GPIO,	/* wifi power */
	GPIO38_GPIO,	/* wifi ready */
	GPIO81_GPIO,	/* wifi reset */

	/* FFUART */
	GPIO34_FFUART_RXD,
	GPIO39_FFUART_TXD,

	/* HDD */
	GPIO98_GPIO,	/* HDD reset */
	GPIO115_GPIO,	/* HDD power */

	/* MISC */
	GPIO13_GPIO,	/* earphone detect */
};

/******************************************************************************
 * NOR Flash
 ******************************************************************************/
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
static struct mtd_partition palmld_partitions[] = {
	{
		.name		= "Flash",
		.offset		= 0x00000000,
		.size		= MTDPART_SIZ_FULL,
		.mask_flags	= 0
	}
};

static struct physmap_flash_data palmld_flash_data[] = {
	{
		.width		= 2,			/* bankwidth in bytes */
		.parts		= palmld_partitions,
		.nr_parts	= ARRAY_SIZE(palmld_partitions)
	}
};

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

static struct platform_device palmld_flash = {
	.name		= "physmap-flash",
	.id		= 0,
	.resource	= &palmld_flash_resource,
	.num_resources	= 1,
	.dev 		= {
		.platform_data = palmld_flash_data,
	},
};

static void __init palmld_nor_init(void)
{
	platform_device_register(&palmld_flash);
}
#else
static inline void palmld_nor_init(void) {}
#endif

/******************************************************************************
 * GPIO keyboard
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static const unsigned int palmld_matrix_keys[] = {
	KEY(0, 1, KEY_F2),
	KEY(0, 2, KEY_UP),

	KEY(1, 0, KEY_F3),
	KEY(1, 1, KEY_F4),
	KEY(1, 2, KEY_RIGHT),

	KEY(2, 0, KEY_F1),
	KEY(2, 1, KEY_F5),
	KEY(2, 2, KEY_DOWN),

	KEY(3, 0, KEY_F6),
	KEY(3, 1, KEY_ENTER),
	KEY(3, 2, KEY_LEFT),
};

static struct matrix_keymap_data palmld_matrix_keymap_data = {
	.keymap			= palmld_matrix_keys,
	.keymap_size		= ARRAY_SIZE(palmld_matrix_keys),
};

static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
	.matrix_key_rows	= 4,
	.matrix_key_cols	= 3,
	.matrix_keymap_data	= &palmld_matrix_keymap_data,

	.debounce_interval	= 30,
};

static void __init palmld_kpc_init(void)
{
	pxa_set_keypad_info(&palmld_keypad_platform_data);
}
#else
static inline void palmld_kpc_init(void) {}
#endif

/******************************************************************************
 * GPIO keys
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button palmld_pxa_buttons[] = {
	{KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
	{KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" },
	{KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" },
};

static struct gpio_keys_platform_data palmld_pxa_keys_data = {
	.buttons	= palmld_pxa_buttons,
	.nbuttons	= ARRAY_SIZE(palmld_pxa_buttons),
};

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

static void __init palmld_keys_init(void)
{
	platform_device_register(&palmld_pxa_keys);
}
#else
static inline void palmld_keys_init(void) {}
#endif

/******************************************************************************
 * LEDs
 ******************************************************************************/
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
struct gpio_led gpio_leds[] = {
{
	.name			= "palmld:green:led",
	.default_trigger	= "none",
	.gpio			= GPIO_NR_PALMLD_LED_GREEN,
}, {
	.name			= "palmld:amber:led",
	.default_trigger	= "none",
	.gpio			= GPIO_NR_PALMLD_LED_AMBER,
},
};

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

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

static void __init palmld_leds_init(void)
{
	platform_device_register(&palmld_leds);
}
#else
static inline void palmld_leds_init(void) {}
#endif

/******************************************************************************
 * HDD
 ******************************************************************************/
#if defined(CONFIG_PATA_PALMLD) || defined(CONFIG_PATA_PALMLD_MODULE)
static struct resource palmld_ide_resources[] = {
	DEFINE_RES_MEM(PALMLD_IDE_PHYS, 0x1000),
};

static struct platform_device palmld_ide_device = {
	.name		= "pata_palmld",
	.id		= -1,
	.resource	= palmld_ide_resources,
	.num_resources	= ARRAY_SIZE(palmld_ide_resources),
};

static struct gpiod_lookup_table palmld_ide_gpio_table = {
	.dev_id = "pata_palmld",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_IDE_PWEN,
			    "power", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_IDE_RESET,
			    "reset", GPIO_ACTIVE_LOW),
		{ },
	},
};

static void __init palmld_ide_init(void)
{
	gpiod_add_lookup_table(&palmld_ide_gpio_table);
	platform_device_register(&palmld_ide_device);
}
#else
static inline void palmld_ide_init(void) {}
#endif

/******************************************************************************
 * Machine init
 ******************************************************************************/
static struct map_desc palmld_io_desc[] __initdata = {
{
	.virtual	= PALMLD_IDE_VIRT,
	.pfn		= __phys_to_pfn(PALMLD_IDE_PHYS),
	.length		= PALMLD_IDE_SIZE,
	.type		= MT_DEVICE
},
{
	.virtual	= PALMLD_USB_VIRT,
	.pfn		= __phys_to_pfn(PALMLD_USB_PHYS),
	.length		= PALMLD_USB_SIZE,
	.type		= MT_DEVICE
},
};

static void __init palmld_map_io(void)
{
	pxa27x_map_io();
	iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
}

static struct gpiod_lookup_table palmld_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_SD_READONLY,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMLD_SD_POWER,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

static void __init palmld_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	palm27x_mmc_init(&palmld_mci_gpio_table);
	gpiod_add_lookup_table(&palmld_wm97xx_touch_gpio_table);
	palm27x_pm_init(PALMLD_STR_BASE);
	palm27x_lcd_init(-1, &palm_320x480_lcd_mode);
	palm27x_irda_init(GPIO_NR_PALMLD_IR_DISABLE);
	palm27x_ac97_init(PALMLD_BAT_MIN_VOLTAGE, PALMLD_BAT_MAX_VOLTAGE,
			GPIO_NR_PALMLD_EARPHONE_DETECT, 95);
	palm27x_pwm_init(GPIO_NR_PALMLD_BL_POWER, GPIO_NR_PALMLD_LCD_POWER);
	palm27x_power_init(GPIO_NR_PALMLD_POWER_DETECT,
			GPIO_NR_PALMLD_USB_DETECT_N);
	palm27x_pmic_init();
	palmld_kpc_init();
	palmld_keys_init();
	palmld_nor_init();
	palmld_leds_init();
	palmld_ide_init();
}

MACHINE_START(PALMLD, "Palm LifeDrive")
	.atag_offset	= 0x100,
	.map_io		= palmld_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= palmld_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIOs and interrupts for Palm LifeDrive Handheld Computer
 *
 * Authors:	Alex Osborne <ato@meshy.org>
 *		Marek Vasut <marek.vasut@gmail.com>
 */

#ifndef _INCLUDE_PALMLD_H_
#define _INCLUDE_PALMLD_H_

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

/** HERE ARE GPIOs **/

/* GPIOs */
#define GPIO_NR_PALMLD_GPIO_RESET	1
#define GPIO_NR_PALMLD_POWER_DETECT	4
#define GPIO_NR_PALMLD_HOTSYNC_BUTTON_N	10
#define GPIO_NR_PALMLD_POWER_SWITCH	12
#define GPIO_NR_PALMLD_EARPHONE_DETECT 	13
#define GPIO_NR_PALMLD_LOCK_SWITCH	15

/* SD/MMC */
#define GPIO_NR_PALMLD_SD_DETECT_N	14
#define GPIO_NR_PALMLD_SD_POWER		114
#define GPIO_NR_PALMLD_SD_READONLY	116

/* TOUCHSCREEN */
#define GPIO_NR_PALMLD_WM9712_IRQ	27

/* IRDA */
#define GPIO_NR_PALMLD_IR_DISABLE	108

/* LCD/BACKLIGHT */
#define GPIO_NR_PALMLD_BL_POWER		19
#define GPIO_NR_PALMLD_LCD_POWER	96

/* LCD BORDER */
#define GPIO_NR_PALMLD_BORDER_SWITCH	21
#define GPIO_NR_PALMLD_BORDER_SELECT	22

/* BLUETOOTH */
#define GPIO_NR_PALMLD_BT_POWER		17
#define GPIO_NR_PALMLD_BT_RESET		83

/* PCMCIA (WiFi) */
#define GPIO_NR_PALMLD_PCMCIA_READY	38
#define GPIO_NR_PALMLD_PCMCIA_POWER	36
#define GPIO_NR_PALMLD_PCMCIA_RESET	81

/* LEDs */
#define GPIO_NR_PALMLD_LED_GREEN	52
#define GPIO_NR_PALMLD_LED_AMBER	94

/* IDE */
#define GPIO_NR_PALMLD_IDE_RESET	98
#define GPIO_NR_PALMLD_IDE_PWEN		115

/* USB */
#define GPIO_NR_PALMLD_USB_DETECT_N	3
#define GPIO_NR_PALMLD_USB_READY	86
#define GPIO_NR_PALMLD_USB_RESET	88
#define GPIO_NR_PALMLD_USB_INT		106
#define GPIO_NR_PALMLD_USB_POWER	118
/* 20, 53 and 86 are usb related too */

/* INTERRUPTS */
#define IRQ_GPIO_PALMLD_GPIO_RESET	PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_GPIO_RESET)
#define IRQ_GPIO_PALMLD_SD_DETECT_N	PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_SD_DETECT_N)
#define IRQ_GPIO_PALMLD_WM9712_IRQ	PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_WM9712_IRQ)
#define IRQ_GPIO_PALMLD_IDE_IRQ		PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_IDE_IRQ)

/** HERE ARE INIT VALUES **/

/* IO mappings */
#define PALMLD_USB_PHYS		PXA_CS2_PHYS
#define PALMLD_USB_VIRT		0xf0000000
#define PALMLD_USB_SIZE		0x00100000

#define PALMLD_IDE_PHYS		0x20000000
#define PALMLD_IDE_VIRT		0xf1000000
#define PALMLD_IDE_SIZE		0x00100000

#define PALMLD_PHYS_IO_START	0x40000000
#define PALMLD_STR_BASE		0xa0200000

/* BATTERY */
#define PALMLD_BAT_MAX_VOLTAGE		4000	/* 4.00V maximum voltage */
#define PALMLD_BAT_MIN_VOLTAGE		3550	/* 3.55V critical voltage */
#define PALMLD_BAT_MAX_CURRENT		0	/* unknown */
#define PALMLD_BAT_MIN_CURRENT		0	/* unknown */
#define PALMLD_BAT_MAX_CHARGE		1	/* unknown */
#define PALMLD_BAT_MIN_CHARGE		1	/* unknown */
#define PALMLD_MAX_LIFE_MINS		240	/* on-life in minutes */

#define PALMLD_BAT_MEASURE_DELAY	(HZ * 1)

/* BACKLIGHT */
#define PALMLD_MAX_INTENSITY		0xFE
#define PALMLD_DEFAULT_INTENSITY	0x7E
#define PALMLD_LIMIT_MASK		0x7F
#define PALMLD_PRESCALER		0x3F
#define PALMLD_PERIOD_NS		3500

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for Palm Tungsten|T5
 *
 * Author:	Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on work of:
 *		Ales Snuparek <snuparek@atlas.cz>
 *		Justin Kendrick <twilightsentry@gmail.com>
 *		RichardT5 <richard_t5@users.sourceforge.net>
 *
 * (find more info at www.hackndev.com)
 */

#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/memblock.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>

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

#include "pxa27x.h"
#include <linux/platform_data/asoc-pxa.h>
#include "palmt5.h"
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
#include "palm27x.h"

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

/******************************************************************************
 * Pin configuration
 ******************************************************************************/
static unsigned long palmt5_pin_config[] __initdata = {
	/* MMC */
	GPIO32_MMC_CLK,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	GPIO112_MMC_CMD,
	GPIO14_GPIO,	/* SD detect */
	GPIO114_GPIO,	/* SD power */
	GPIO115_GPIO,	/* SD r/o switch */

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

	/* IrDA */
	GPIO40_GPIO,	/* ir disable */
	GPIO46_FICP_RXD,
	GPIO47_FICP_TXD,

	/* USB */
	GPIO15_GPIO,	/* usb detect */
	GPIO93_GPIO,	/* usb power */

	/* MATRIX KEYPAD */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
	GPIO103_KP_MKOUT_0,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* PWM */
	GPIO16_PWM0_OUT,

	/* FFUART */
	GPIO34_FFUART_RXD,
	GPIO39_FFUART_TXD,

	/* MISC */
	GPIO10_GPIO,	/* hotsync button */
	GPIO90_GPIO,	/* power detect */
	GPIO107_GPIO,	/* earphone detect */
};

/******************************************************************************
 * GPIO keyboard
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static const unsigned int palmt5_matrix_keys[] = {
	KEY(0, 0, KEY_POWER),
	KEY(0, 1, KEY_F1),
	KEY(0, 2, KEY_ENTER),

	KEY(1, 0, KEY_F2),
	KEY(1, 1, KEY_F3),
	KEY(1, 2, KEY_F4),

	KEY(2, 0, KEY_UP),
	KEY(2, 2, KEY_DOWN),

	KEY(3, 0, KEY_RIGHT),
	KEY(3, 2, KEY_LEFT),
};

static struct matrix_keymap_data palmt5_matrix_keymap_data = {
	.keymap			= palmt5_matrix_keys,
	.keymap_size		= ARRAY_SIZE(palmt5_matrix_keys),
};

static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
	.matrix_key_rows	= 4,
	.matrix_key_cols	= 3,
	.matrix_keymap_data	= &palmt5_matrix_keymap_data,

	.debounce_interval	= 30,
};

static void __init palmt5_kpc_init(void)
{
	pxa_set_keypad_info(&palmt5_keypad_platform_data);
}
#else
static inline void palmt5_kpc_init(void) {}
#endif

/******************************************************************************
 * GPIO keys
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button palmt5_pxa_buttons[] = {
	{KEY_F8, GPIO_NR_PALMT5_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
};

static struct gpio_keys_platform_data palmt5_pxa_keys_data = {
	.buttons	= palmt5_pxa_buttons,
	.nbuttons	= ARRAY_SIZE(palmt5_pxa_buttons),
};

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

static void __init palmt5_keys_init(void)
{
	platform_device_register(&palmt5_pxa_keys);
}
#else
static inline void palmt5_keys_init(void) {}
#endif

/******************************************************************************
 * Machine init
 ******************************************************************************/
static void __init palmt5_reserve(void)
{
	memblock_reserve(0xa0200000, 0x1000);
}

static struct gpiod_lookup_table palmt5_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMT5_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMT5_SD_READONLY,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMT5_SD_POWER,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

static void __init palmt5_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	palm27x_mmc_init(&palmt5_mci_gpio_table);
	gpiod_add_lookup_table(&palmt5_wm97xx_touch_gpio_table);
	palm27x_pm_init(PALMT5_STR_BASE);
	palm27x_lcd_init(-1, &palm_320x480_lcd_mode);
	palm27x_udc_init(GPIO_NR_PALMT5_USB_DETECT_N,
			GPIO_NR_PALMT5_USB_PULLUP, 1);
	palm27x_irda_init(GPIO_NR_PALMT5_IR_DISABLE);
	palm27x_ac97_init(PALMT5_BAT_MIN_VOLTAGE, PALMT5_BAT_MAX_VOLTAGE,
			GPIO_NR_PALMT5_EARPHONE_DETECT, 95);
	palm27x_pwm_init(GPIO_NR_PALMT5_BL_POWER, GPIO_NR_PALMT5_LCD_POWER);
	palm27x_power_init(GPIO_NR_PALMT5_POWER_DETECT, -1);
	palm27x_pmic_init();
	palmt5_kpc_init();
	palmt5_keys_init();
}

MACHINE_START(PALMT5, "Palm Tungsten|T5")
	.atag_offset	= 0x100,
	.map_io		= pxa27x_map_io,
	.reserve	= palmt5_reserve,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= palmt5_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer
 *
 * Authors:	Ales Snuparek <snuparek@atlas.cz>
 *		Marek Vasut <marek.vasut@gmail.com>
 *		Justin Kendrick <twilightsentry@gmail.com>
 *		RichardT5 <richard_t5@users.sourceforge.net>
 */

#ifndef _INCLUDE_PALMT5_H_
#define _INCLUDE_PALMT5_H_

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

/** HERE ARE GPIOs **/

/* GPIOs */
#define GPIO_NR_PALMT5_GPIO_RESET		1

#define GPIO_NR_PALMT5_POWER_DETECT		90
#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N		10
#define GPIO_NR_PALMT5_EARPHONE_DETECT		107

/* SD/MMC */
#define GPIO_NR_PALMT5_SD_DETECT_N		14
#define GPIO_NR_PALMT5_SD_POWER			114
#define GPIO_NR_PALMT5_SD_READONLY		115

/* TOUCHSCREEN */
#define GPIO_NR_PALMT5_WM9712_IRQ		27

/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
#define GPIO_NR_PALMT5_IR_DISABLE		40

/* USB */
#define GPIO_NR_PALMT5_USB_DETECT_N		15
#define GPIO_NR_PALMT5_USB_PULLUP		93

/* LCD/BACKLIGHT */
#define GPIO_NR_PALMT5_BL_POWER			84
#define GPIO_NR_PALMT5_LCD_POWER		96

/* BLUETOOTH */
#define GPIO_NR_PALMT5_BT_POWER			17
#define GPIO_NR_PALMT5_BT_RESET			83

/* INTERRUPTS */
#define IRQ_GPIO_PALMT5_SD_DETECT_N	PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N)
#define IRQ_GPIO_PALMT5_WM9712_IRQ	PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ)
#define IRQ_GPIO_PALMT5_USB_DETECT	PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT)
#define IRQ_GPIO_PALMT5_GPIO_RESET	PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_GPIO_RESET)

/** HERE ARE INIT VALUES **/

/* Various addresses  */
#define PALMT5_PHYS_RAM_START	0xa0000000
#define PALMT5_PHYS_IO_START	0x40000000
#define PALMT5_STR_BASE		0xa0200000

/* TOUCHSCREEN */
#define AC97_LINK_FRAME		21

/* BATTERY */
#define PALMT5_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
#define PALMT5_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
#define PALMT5_BAT_MAX_CURRENT		0	/* unknown */
#define PALMT5_BAT_MIN_CURRENT		0	/* unknown */
#define PALMT5_BAT_MAX_CHARGE		1	/* unknown */
#define PALMT5_BAT_MIN_CHARGE		1	/* unknown */
#define PALMT5_MAX_LIFE_MINS		360    /* on-life in minutes */

#define PALMT5_BAT_MEASURE_DELAY	(HZ * 1)

/* BACKLIGHT */
#define PALMT5_MAX_INTENSITY		0xFE
#define PALMT5_DEFAULT_INTENSITY	0x7E
#define PALMT5_LIMIT_MASK		0x7F
#define PALMT5_PRESCALER		0x3F
#define PALMT5_PERIOD_NS		3500

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/drivers/pcmcia/pxa2xx_palmtc.c
 *
 * Driver for Palm Tungsten|C PCMCIA
 *
 * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
 * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com>
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>

#include <asm/mach-types.h>
#include "palmtc.h"
#include <pcmcia/soc_common.h>

static struct gpio palmtc_pcmcia_gpios[] = {
	{ GPIO_NR_PALMTC_PCMCIA_POWER1,	GPIOF_INIT_LOW,	"PCMCIA Power 1" },
	{ GPIO_NR_PALMTC_PCMCIA_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },
	{ GPIO_NR_PALMTC_PCMCIA_POWER3,	GPIOF_INIT_LOW,	"PCMCIA Power 3" },
	{ GPIO_NR_PALMTC_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
	{ GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN,	"PCMCIA Power Ready" },
};

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

	ret = gpio_request_array(palmtc_pcmcia_gpios,
				ARRAY_SIZE(palmtc_pcmcia_gpios));

	skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY;
	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";

	return ret;
}

static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
	gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios));
}

static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
					struct pcmcia_state *state)
{
	state->detect = 1; /* always inserted */
	state->vs_3v  = 1;
	state->vs_Xv  = 0;
}

static int palmtc_wifi_powerdown(void)
{
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
	mdelay(40);
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
	return 0;
}

static int palmtc_wifi_powerup(void)
{
	int timeout = 50;

	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 1);
	mdelay(50);

	/* Power up the card, 1.8V first, after a while 3.3V */
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 1);
	mdelay(100);
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 1);

	/* Wait till the card is ready */
	while (!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_PWRREADY) &&
		timeout) {
		mdelay(1);
		timeout--;
	}

	/* Power down the WiFi in case of error */
	if (!timeout) {
		palmtc_wifi_powerdown();
		return 1;
	}

	/* Reset the card */
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
	mdelay(20);
	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 0);
	mdelay(25);

	gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);

	return 0;
}

static int palmtc_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
					const socket_state_t *state)
{
	int ret = 1;

	if (state->Vcc == 0)
		ret = palmtc_wifi_powerdown();
	else if (state->Vcc == 33)
		ret = palmtc_wifi_powerup();

	return ret;
}

static struct pcmcia_low_level palmtc_pcmcia_ops = {
	.owner			= THIS_MODULE,

	.first			= 0,
	.nr			= 1,

	.hw_init		= palmtc_pcmcia_hw_init,
	.hw_shutdown		= palmtc_pcmcia_hw_shutdown,

	.socket_state		= palmtc_pcmcia_socket_state,
	.configure_socket	= palmtc_pcmcia_configure_socket,
};

static struct platform_device *palmtc_pcmcia_device;

static int __init palmtc_pcmcia_init(void)
{
	int ret;

	if (!machine_is_palmtc())
		return -ENODEV;

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

	ret = platform_device_add_data(palmtc_pcmcia_device, &palmtc_pcmcia_ops,
					sizeof(palmtc_pcmcia_ops));

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

	if (ret)
		platform_device_put(palmtc_pcmcia_device);

	return ret;
}

static void __exit palmtc_pcmcia_exit(void)
{
	platform_device_unregister(palmtc_pcmcia_device);
}

module_init(palmtc_pcmcia_init);
module_exit(palmtc_pcmcia_exit);

MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
	    " Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("PCMCIA support for Palm Tungsten|C");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
MODULE_LICENSE("GPL");


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-pxa/palmtc.c
 *
 * Support for the Palm Tungsten|C
 *
 * Author:	Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on work of:
 *		Petr Blaha <p3t3@centrum.cz>
 *		Chetan S. Kumar <shivakumar.chetan@gmail.com>
 */

#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/input.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio/machine.h>
#include <linux/input/matrix_keypad.h>
#include <linux/ucb1400.h>
#include <linux/power_supply.h>
#include <linux/gpio_keys.h>
#include <linux/mtd/physmap.h>

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

#include "pxa25x.h"
#include <linux/platform_data/asoc-pxa.h>
#include "palmtc.h"
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/irda-pxaficp.h>
#include "udc.h"

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

/******************************************************************************
 * Pin configuration
 ******************************************************************************/
static unsigned long palmtc_pin_config[] __initdata = {
	/* MMC */
	GPIO6_MMC_CLK,
	GPIO8_MMC_CS0,
	GPIO12_GPIO,	/* detect */
	GPIO32_GPIO,	/* power */
	GPIO54_GPIO,	/* r/o switch */

	/* PCMCIA */
	GPIO52_nPCE_1,
	GPIO53_nPCE_2,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO49_nPWE,
	GPIO48_nPOE,
	GPIO52_nPCE_1,
	GPIO53_nPCE_2,
	GPIO57_nIOIS16,
	GPIO56_nPWAIT,

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

	/* IrDA */
	GPIO45_GPIO,	/* ir disable */
	GPIO46_FICP_RXD,
	GPIO47_FICP_TXD,

	/* PWM */
	GPIO17_PWM1_OUT,

	/* USB */
	GPIO4_GPIO,	/* detect */
	GPIO36_GPIO,	/* pullup */

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* MATRIX KEYPAD */
	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* in 0 */
	GPIO9_GPIO | WAKEUP_ON_EDGE_BOTH,	/* in 1 */
	GPIO10_GPIO | WAKEUP_ON_EDGE_BOTH,	/* in 2 */
	GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,	/* in 3 */
	GPIO18_GPIO | MFP_LPM_DRIVE_LOW,	/* out 0 */
	GPIO19_GPIO | MFP_LPM_DRIVE_LOW,	/* out 1 */
	GPIO20_GPIO | MFP_LPM_DRIVE_LOW,	/* out 2 */
	GPIO21_GPIO | MFP_LPM_DRIVE_LOW,	/* out 3 */
	GPIO22_GPIO | MFP_LPM_DRIVE_LOW,	/* out 4 */
	GPIO23_GPIO | MFP_LPM_DRIVE_LOW,	/* out 5 */
	GPIO24_GPIO | MFP_LPM_DRIVE_LOW,	/* out 6 */
	GPIO25_GPIO | MFP_LPM_DRIVE_LOW,	/* out 7 */
	GPIO26_GPIO | MFP_LPM_DRIVE_LOW,	/* out 8 */
	GPIO27_GPIO | MFP_LPM_DRIVE_LOW,	/* out 9 */
	GPIO79_GPIO | MFP_LPM_DRIVE_LOW,	/* out 10 */
	GPIO80_GPIO | MFP_LPM_DRIVE_LOW,	/* out 11 */

	/* PXA GPIO KEYS */
	GPIO7_GPIO | WAKEUP_ON_EDGE_BOTH,	/* hotsync button on cradle */

	/* MISC */
	GPIO1_RST,	/* reset */
	GPIO2_GPIO,	/* earphone detect */
	GPIO16_GPIO,	/* backlight switch */
};

/******************************************************************************
 * SD/MMC card controller
 ******************************************************************************/
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
static struct pxamci_platform_data palmtc_mci_platform_data = {
	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
	.detect_delay_ms	= 200,
};

static struct gpiod_lookup_table palmtc_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_SD_READONLY,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_SD_POWER,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static void __init palmtc_mmc_init(void)
{
	gpiod_add_lookup_table(&palmtc_mci_gpio_table);
	pxa_set_mci_info(&palmtc_mci_platform_data);
}
#else
static inline void palmtc_mmc_init(void) {}
#endif

/******************************************************************************
 * GPIO keys
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button palmtc_pxa_buttons[] = {
	{KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1},
};

static struct gpio_keys_platform_data palmtc_pxa_keys_data = {
	.buttons	= palmtc_pxa_buttons,
	.nbuttons	= ARRAY_SIZE(palmtc_pxa_buttons),
};

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

static void __init palmtc_keys_init(void)
{
	platform_device_register(&palmtc_pxa_keys);
}
#else
static inline void palmtc_keys_init(void) {}
#endif

/******************************************************************************
 * Backlight
 ******************************************************************************/
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)

static struct gpiod_lookup_table palmtc_pwm_bl_gpio_table = {
	.dev_id = "pwm-backlight.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_BL_POWER,
			    "enable", GPIO_ACTIVE_HIGH),
	},
};

static struct pwm_lookup palmtc_pwm_lookup[] = {
	PWM_LOOKUP("pxa25x-pwm.1", 0, "pwm-backlight.0", NULL, PALMTC_PERIOD_NS,
		   PWM_POLARITY_NORMAL),
};

static struct platform_pwm_backlight_data palmtc_backlight_data = {
	.max_brightness	= PALMTC_MAX_INTENSITY,
	.dft_brightness	= PALMTC_MAX_INTENSITY,
};

static struct platform_device palmtc_backlight = {
	.name	= "pwm-backlight",
	.dev	= {
		.parent		= &pxa25x_device_pwm1.dev,
		.platform_data	= &palmtc_backlight_data,
	},
};

static void __init palmtc_pwm_init(void)
{
	gpiod_add_lookup_table(&palmtc_pwm_bl_gpio_table);
	pwm_add_table(palmtc_pwm_lookup, ARRAY_SIZE(palmtc_pwm_lookup));
	platform_device_register(&palmtc_backlight);
}
#else
static inline void palmtc_pwm_init(void) {}
#endif

/******************************************************************************
 * IrDA
 ******************************************************************************/
#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
static struct pxaficp_platform_data palmtc_ficp_platform_data = {
	.gpio_pwdown		= GPIO_NR_PALMTC_IR_DISABLE,
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
};

static void __init palmtc_irda_init(void)
{
	pxa_set_ficp_info(&palmtc_ficp_platform_data);
}
#else
static inline void palmtc_irda_init(void) {}
#endif

/******************************************************************************
 * Keyboard
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
static const uint32_t palmtc_matrix_keys[] = {
	KEY(0, 0, KEY_F1),
	KEY(0, 1, KEY_X),
	KEY(0, 2, KEY_POWER),
	KEY(0, 3, KEY_TAB),
	KEY(0, 4, KEY_A),
	KEY(0, 5, KEY_Q),
	KEY(0, 6, KEY_LEFTSHIFT),
	KEY(0, 7, KEY_Z),
	KEY(0, 8, KEY_S),
	KEY(0, 9, KEY_W),
	KEY(0, 10, KEY_E),
	KEY(0, 11, KEY_UP),

	KEY(1, 0, KEY_F2),
	KEY(1, 1, KEY_DOWN),
	KEY(1, 3, KEY_D),
	KEY(1, 4, KEY_C),
	KEY(1, 5, KEY_F),
	KEY(1, 6, KEY_R),
	KEY(1, 7, KEY_SPACE),
	KEY(1, 8, KEY_V),
	KEY(1, 9, KEY_G),
	KEY(1, 10, KEY_T),
	KEY(1, 11, KEY_LEFT),

	KEY(2, 0, KEY_F3),
	KEY(2, 1, KEY_LEFTCTRL),
	KEY(2, 3, KEY_H),
	KEY(2, 4, KEY_Y),
	KEY(2, 5, KEY_N),
	KEY(2, 6, KEY_J),
	KEY(2, 7, KEY_U),
	KEY(2, 8, KEY_M),
	KEY(2, 9, KEY_K),
	KEY(2, 10, KEY_I),
	KEY(2, 11, KEY_RIGHT),

	KEY(3, 0, KEY_F4),
	KEY(3, 1, KEY_ENTER),
	KEY(3, 3, KEY_DOT),
	KEY(3, 4, KEY_L),
	KEY(3, 5, KEY_O),
	KEY(3, 6, KEY_LEFTALT),
	KEY(3, 7, KEY_ENTER),
	KEY(3, 8, KEY_BACKSPACE),
	KEY(3, 9, KEY_P),
	KEY(3, 10, KEY_B),
	KEY(3, 11, KEY_FN),
};

const struct matrix_keymap_data palmtc_keymap_data = {
	.keymap			= palmtc_matrix_keys,
	.keymap_size		= ARRAY_SIZE(palmtc_matrix_keys),
};

static const unsigned int palmtc_keypad_row_gpios[] = {
	0, 9, 10, 11
};

static const unsigned int palmtc_keypad_col_gpios[] = {
	18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80
};

static struct matrix_keypad_platform_data palmtc_keypad_platform_data = {
	.keymap_data	= &palmtc_keymap_data,
	.row_gpios	= palmtc_keypad_row_gpios,
	.num_row_gpios	= ARRAY_SIZE(palmtc_keypad_row_gpios),
	.col_gpios	= palmtc_keypad_col_gpios,
	.num_col_gpios	= ARRAY_SIZE(palmtc_keypad_col_gpios),
	.active_low	= 1,

	.debounce_ms		= 20,
	.col_scan_delay_us	= 5,
};

static struct platform_device palmtc_keyboard = {
	.name	= "matrix-keypad",
	.id	= -1,
	.dev	= {
		.platform_data = &palmtc_keypad_platform_data,
	},
};
static void __init palmtc_mkp_init(void)
{
	platform_device_register(&palmtc_keyboard);
}
#else
static inline void palmtc_mkp_init(void) {}
#endif

/******************************************************************************
 * UDC
 ******************************************************************************/
#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE)
static struct gpiod_lookup_table palmtc_udc_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_USB_DETECT_N,
			    "vbus", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_USB_POWER,
			    "pullup", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

static void __init palmtc_udc_init(void)
{
	gpiod_add_lookup_table(&palmtc_udc_gpiod_table);
	platform_device_register(&palmtc_gpio_vbus);
};
#else
static inline void palmtc_udc_init(void) {}
#endif

/******************************************************************************
 * Touchscreen / Battery / GPIO-extender
 ******************************************************************************/
#if	defined(CONFIG_TOUCHSCREEN_UCB1400) || \
	defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
static struct platform_device palmtc_ucb1400_device = {
	.name	= "ucb1400_core",
	.id	= -1,
};

static void __init palmtc_ts_init(void)
{
	pxa_set_ac97_info(NULL);
	platform_device_register(&palmtc_ucb1400_device);
}
#else
static inline void palmtc_ts_init(void) {}
#endif

/******************************************************************************
 * LEDs
 ******************************************************************************/
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
struct gpio_led palmtc_gpio_leds[] = {
{
	.name			= "palmtc:green:user",
	.default_trigger	= "none",
	.gpio			= GPIO_NR_PALMTC_LED_POWER,
	.active_low		= 1,
}, {
	.name			= "palmtc:vibra:vibra",
	.default_trigger	= "none",
	.gpio			= GPIO_NR_PALMTC_VIBRA_POWER,
	.active_low		= 1,
}

};

static struct gpio_led_platform_data palmtc_gpio_led_info = {
	.leds		= palmtc_gpio_leds,
	.num_leds	= ARRAY_SIZE(palmtc_gpio_leds),
};

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

static void __init palmtc_leds_init(void)
{
	platform_device_register(&palmtc_leds);
}
#else
static inline void palmtc_leds_init(void) {}
#endif

/******************************************************************************
 * NOR Flash
 ******************************************************************************/
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
static struct resource palmtc_flash_resource = {
	.start	= PXA_CS0_PHYS,
	.end	= PXA_CS0_PHYS + SZ_16M - 1,
	.flags	= IORESOURCE_MEM,
};

static struct mtd_partition palmtc_flash_parts[] = {
	{
		.name	= "U-Boot Bootloader",
		.offset	= 0x0,
		.size	= 0x40000,
	},
	{
		.name	= "Linux Kernel",
		.offset	= 0x40000,
		.size	= 0x2c0000,
	},
	{
		.name	= "Filesystem",
		.offset	= 0x300000,
		.size	= 0xcc0000,
	},
	{
		.name	= "U-Boot Environment",
		.offset	= 0xfc0000,
		.size	= MTDPART_SIZ_FULL,
	},
};

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

static struct platform_device palmtc_flash = {
	.name		= "physmap-flash",
	.id		= -1,
	.resource	= &palmtc_flash_resource,
	.num_resources	= 1,
	.dev = {
		.platform_data	= &palmtc_flash_data,
	},
};

static void __init palmtc_nor_init(void)
{
	platform_device_register(&palmtc_flash);
}
#else
static inline void palmtc_nor_init(void) {}
#endif

/******************************************************************************
 * Framebuffer
 ******************************************************************************/
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static struct pxafb_mode_info palmtc_lcd_modes[] = {
	{
		.pixclock	= 115384,
		.xres		= 320,
		.yres		= 320,
		.bpp		= 16,

		.left_margin	= 27,
		.right_margin	= 7,
		.upper_margin	= 7,
		.lower_margin	= 8,

		.hsync_len	= 6,
		.vsync_len	= 1,
	},
};

static struct pxafb_mach_info palmtc_lcd_screen = {
	.modes			= palmtc_lcd_modes,
	.num_modes		= ARRAY_SIZE(palmtc_lcd_modes),
	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};

static void __init palmtc_lcd_init(void)
{
	pxa_set_fb_info(NULL, &palmtc_lcd_screen);
}
#else
static inline void palmtc_lcd_init(void) {}
#endif

/******************************************************************************
 * Machine init
 ******************************************************************************/
static void __init palmtc_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config));

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

	palmtc_mmc_init();
	palmtc_keys_init();
	palmtc_pwm_init();
	palmtc_irda_init();
	palmtc_mkp_init();
	palmtc_udc_init();
	palmtc_ts_init();
	palmtc_nor_init();
	palmtc_lcd_init();
	palmtc_leds_init();
};

MACHINE_START(PALMTC, "Palm Tungsten|C")
	.atag_offset 	= 0x100,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= palmtc_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * linux/include/asm-arm/arch-pxa/palmtc-gpio.h
 *
 * GPIOs and interrupts for Palm Tungsten|C Handheld Computer
 *
 * Authors:	Alex Osborne <bobofdoom@gmail.com>
 *		Marek Vasut <marek.vasut@gmail.com>
 *		Holger Bocklet <bitz.email@gmx.net>
 */

#ifndef _INCLUDE_PALMTC_H_
#define _INCLUDE_PALMTC_H_

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

/** HERE ARE GPIOs **/

/* GPIOs */
#define GPIO_NR_PALMTC_EARPHONE_DETECT	2
#define GPIO_NR_PALMTC_CRADLE_DETECT	5
#define GPIO_NR_PALMTC_HOTSYNC_BUTTON	7

/* SD/MMC */
#define GPIO_NR_PALMTC_SD_DETECT_N	12
#define GPIO_NR_PALMTC_SD_POWER		32
#define GPIO_NR_PALMTC_SD_READONLY	54

/* WLAN */
#define GPIO_NR_PALMTC_PCMCIA_READY	13
#define GPIO_NR_PALMTC_PCMCIA_PWRREADY	14
#define GPIO_NR_PALMTC_PCMCIA_POWER1	15
#define GPIO_NR_PALMTC_PCMCIA_POWER2	33
#define GPIO_NR_PALMTC_PCMCIA_POWER3	55
#define GPIO_NR_PALMTC_PCMCIA_RESET	78

/* UDC */
#define GPIO_NR_PALMTC_USB_DETECT_N	4
#define GPIO_NR_PALMTC_USB_POWER	36

/* LCD/BACKLIGHT */
#define GPIO_NR_PALMTC_BL_POWER		16
#define GPIO_NR_PALMTC_LCD_POWER	44
#define GPIO_NR_PALMTC_LCD_BLANK	38

/* UART */
#define GPIO_NR_PALMTC_RS232_POWER	37

/* IRDA */
#define GPIO_NR_PALMTC_IR_DISABLE	45

/* IRQs */
#define IRQ_GPIO_PALMTC_SD_DETECT_N	PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_SD_DETECT_N)
#define IRQ_GPIO_PALMTC_WLAN_READY	PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_WLAN_READY)

/* UCB1400 GPIOs */
#define GPIO_NR_PALMTC_POWER_DETECT	(0x80 | 0x00)
#define GPIO_NR_PALMTC_HEADPHONE_DETECT	(0x80 | 0x01)
#define GPIO_NR_PALMTC_SPEAKER_ENABLE	(0x80 | 0x03)
#define GPIO_NR_PALMTC_VIBRA_POWER	(0x80 | 0x05)
#define GPIO_NR_PALMTC_LED_POWER	(0x80 | 0x07)

/** HERE ARE INIT VALUES **/
#define PALMTC_UCB1400_GPIO_OFFSET	0x80

/* BATTERY */
#define PALMTC_BAT_MAX_VOLTAGE		4000	/* 4.00V maximum voltage */
#define PALMTC_BAT_MIN_VOLTAGE		3550	/* 3.55V critical voltage */
#define PALMTC_BAT_MAX_CURRENT		0	/* unknown */
#define PALMTC_BAT_MIN_CURRENT		0	/* unknown */
#define PALMTC_BAT_MAX_CHARGE		1	/* unknown */
#define PALMTC_BAT_MIN_CHARGE		1	/* unknown */
#define PALMTC_MAX_LIFE_MINS		240	/* on-life in minutes */

#define PALMTC_BAT_MEASURE_DELAY	(HZ * 1)

/* BACKLIGHT */
#define PALMTC_MAX_INTENSITY		0xFE
#define PALMTC_DEFAULT_INTENSITY	0x7E
#define PALMTC_LIMIT_MASK		0x7F
#define PALMTC_PRESCALER		0x3F
#define PALMTC_PERIOD_NS		3500

#endif