code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for Palm Tungsten|E2
 *
 * Author:
 *	Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com>
 *
 * Rewrite for mainline:
 *	Marek Vasut <marek.vasut@gmail.com>
 *
 * (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/gpio/machine.h>
#include <linux/input.h>
#include <linux/pda_power.h>
#include <linux/pwm.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 "pxa25x.h"
#include <linux/platform_data/asoc-pxa.h>
#include "palmte2.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 "generic.h"
#include "devices.h"

/******************************************************************************
 * Pin configuration
 ******************************************************************************/
static unsigned long palmte2_pin_config[] __initdata = {
	/* MMC */
	GPIO6_MMC_CLK,
	GPIO8_MMC_CS0,
	GPIO10_GPIO,	/* SD detect */
	GPIO55_GPIO,	/* SD power */
	GPIO51_GPIO,	/* SD r/o switch */

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

	/* PWM */
	GPIO16_PWM0_OUT,

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

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

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* GPIO KEYS */
	GPIO5_GPIO,	/* notes */
	GPIO7_GPIO,	/* tasks */
	GPIO11_GPIO,	/* calendar */
	GPIO13_GPIO,	/* contacts */
	GPIO14_GPIO,	/* center */
	GPIO19_GPIO,	/* left */
	GPIO20_GPIO,	/* right */
	GPIO21_GPIO,	/* down */
	GPIO22_GPIO,	/* up */

	/* MISC */
	GPIO1_RST,	/* reset */
	GPIO4_GPIO,	/* Hotsync button */
	GPIO9_GPIO,	/* power detect */
	GPIO15_GPIO,	/* earphone detect */
	GPIO37_GPIO,	/* LCD power */
	GPIO56_GPIO,	/* Backlight power */
};

/******************************************************************************
 * SD/MMC card controller
 ******************************************************************************/
static struct pxamci_platform_data palmte2_mci_platform_data = {
	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
};

static struct gpiod_lookup_table palmte2_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_SD_READONLY,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_SD_POWER,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
/******************************************************************************
 * GPIO keys
 ******************************************************************************/
static struct gpio_keys_button palmte2_pxa_buttons[] = {
	{KEY_F1,	GPIO_NR_PALMTE2_KEY_CONTACTS,	1, "Contacts" },
	{KEY_F2,	GPIO_NR_PALMTE2_KEY_CALENDAR,	1, "Calendar" },
	{KEY_F3,	GPIO_NR_PALMTE2_KEY_TASKS,	1, "Tasks" },
	{KEY_F4,	GPIO_NR_PALMTE2_KEY_NOTES,	1, "Notes" },
	{KEY_ENTER,	GPIO_NR_PALMTE2_KEY_CENTER,	1, "Center" },
	{KEY_LEFT,	GPIO_NR_PALMTE2_KEY_LEFT,	1, "Left" },
	{KEY_RIGHT,	GPIO_NR_PALMTE2_KEY_RIGHT,	1, "Right" },
	{KEY_DOWN,	GPIO_NR_PALMTE2_KEY_DOWN,	1, "Down" },
	{KEY_UP,	GPIO_NR_PALMTE2_KEY_UP,		1, "Up" },
};

static struct gpio_keys_platform_data palmte2_pxa_keys_data = {
	.buttons	= palmte2_pxa_buttons,
	.nbuttons	= ARRAY_SIZE(palmte2_pxa_buttons),
};

static struct platform_device palmte2_pxa_keys = {
	.name	= "gpio-keys",
	.id	= -1,
	.dev	= {
		.platform_data = &palmte2_pxa_keys_data,
	},
};
#endif

/******************************************************************************
 * Backlight
 ******************************************************************************/
static struct pwm_lookup palmte2_pwm_lookup[] = {
	PWM_LOOKUP("pxa25x-pwm.0", 0, "pwm-backlight.0", NULL,
		   PALMTE2_PERIOD_NS, PWM_POLARITY_NORMAL),
};

static struct gpio palmte_bl_gpios[] = {
	{ GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" },
	{ GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" },
};

static int palmte2_backlight_init(struct device *dev)
{
	return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios));
}

static int palmte2_backlight_notify(struct device *dev, int brightness)
{
	gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness);
	gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness);
	return brightness;
}

static void palmte2_backlight_exit(struct device *dev)
{
	gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios));
}

static struct platform_pwm_backlight_data palmte2_backlight_data = {
	.max_brightness	= PALMTE2_MAX_INTENSITY,
	.dft_brightness	= PALMTE2_MAX_INTENSITY,
	.init		= palmte2_backlight_init,
	.notify		= palmte2_backlight_notify,
	.exit		= palmte2_backlight_exit,
};

static struct platform_device palmte2_backlight = {
	.name	= "pwm-backlight",
	.dev	= {
		.parent		= &pxa25x_device_pwm0.dev,
		.platform_data	= &palmte2_backlight_data,
	},
};

/******************************************************************************
 * IrDA
 ******************************************************************************/
static struct pxaficp_platform_data palmte2_ficp_platform_data = {
	.gpio_pwdown		= GPIO_NR_PALMTE2_IR_DISABLE,
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
};

/******************************************************************************
 * UDC
 ******************************************************************************/
static struct gpiod_lookup_table palmte2_udc_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_USB_DETECT_N,
			    "vbus", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_USB_PULLUP,
			    "pullup", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

/******************************************************************************
 * Power supply
 ******************************************************************************/
static int power_supply_init(struct device *dev)
{
	int ret;

	ret = gpio_request(GPIO_NR_PALMTE2_POWER_DETECT, "CABLE_STATE_AC");
	if (ret)
		goto err1;
	ret = gpio_direction_input(GPIO_NR_PALMTE2_POWER_DETECT);
	if (ret)
		goto err2;

	return 0;

err2:
	gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
err1:
	return ret;
}

static int palmte2_is_ac_online(void)
{
	return gpio_get_value(GPIO_NR_PALMTE2_POWER_DETECT);
}

static void power_supply_exit(struct device *dev)
{
	gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
}

static char *palmte2_supplicants[] = {
	"main-battery",
};

static struct pda_power_pdata power_supply_info = {
	.init            = power_supply_init,
	.is_ac_online    = palmte2_is_ac_online,
	.exit            = power_supply_exit,
	.supplied_to     = palmte2_supplicants,
	.num_supplicants = ARRAY_SIZE(palmte2_supplicants),
};

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

/******************************************************************************
 * WM97xx audio, battery
 ******************************************************************************/
static struct wm97xx_batt_pdata palmte2_batt_pdata = {
	.batt_aux	= WM97XX_AUX_ID3,
	.temp_aux	= WM97XX_AUX_ID2,
	.max_voltage	= PALMTE2_BAT_MAX_VOLTAGE,
	.min_voltage	= PALMTE2_BAT_MIN_VOLTAGE,
	.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 palmte2_wm97xx_pdata = {
	.batt_pdata	= &palmte2_batt_pdata,
};

static pxa2xx_audio_ops_t palmte2_ac97_pdata = {
	.codec_pdata	= { &palmte2_wm97xx_pdata, },
};

static struct palm27x_asoc_info palmte2_asoc_pdata = {
	.jack_gpio	= GPIO_NR_PALMTE2_EARPHONE_DETECT,
};

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

/******************************************************************************
 * Framebuffer
 ******************************************************************************/
static struct pxafb_mode_info palmte2_lcd_modes[] = {
{
	.pixclock	= 77757,
	.xres		= 320,
	.yres		= 320,
	.bpp		= 16,

	.left_margin	= 28,
	.right_margin	= 7,
	.upper_margin	= 7,
	.lower_margin	= 5,

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

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

/******************************************************************************
 * Machine init
 ******************************************************************************/
static struct platform_device *devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
	&palmte2_pxa_keys,
#endif
	&palmte2_backlight,
	&power_supply,
	&palmte2_asoc,
	&palmte2_gpio_vbus,
};

/* setup udc GPIOs initial state */
static void __init palmte2_udc_init(void)
{
	if (!gpio_request(GPIO_NR_PALMTE2_USB_PULLUP, "UDC Vbus")) {
		gpio_direction_output(GPIO_NR_PALMTE2_USB_PULLUP, 1);
		gpio_free(GPIO_NR_PALMTE2_USB_PULLUP);
	}
}

static void __init palmte2_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config));

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

	pxa_set_fb_info(NULL, &palmte2_lcd_screen);
	gpiod_add_lookup_table(&palmte2_mci_gpio_table);
	pxa_set_mci_info(&palmte2_mci_platform_data);
	palmte2_udc_init();
	pxa_set_ac97_info(&palmte2_ac97_pdata);
	pxa_set_ficp_info(&palmte2_ficp_platform_data);

	pwm_add_table(palmte2_pwm_lookup, ARRAY_SIZE(palmte2_pwm_lookup));
	gpiod_add_lookup_table(&palmte2_udc_gpiod_table);
	platform_add_devices(devices, ARRAY_SIZE(devices));
}

MACHINE_START(PALMTE2, "Palm Tungsten|E2")
	.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	= palmte2_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer
 *
 * Author:
 *		Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com>
 */

#ifndef _INCLUDE_PALMTE2_H_
#define _INCLUDE_PALMTE2_H_

/** HERE ARE GPIOs **/

/* GPIOs */
#define GPIO_NR_PALMTE2_POWER_DETECT		9
#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N	4
#define GPIO_NR_PALMTE2_EARPHONE_DETECT		15

/* SD/MMC */
#define GPIO_NR_PALMTE2_SD_DETECT_N		10
#define GPIO_NR_PALMTE2_SD_POWER		55
#define GPIO_NR_PALMTE2_SD_READONLY		51

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

/* USB */
#define GPIO_NR_PALMTE2_USB_DETECT_N		35
#define GPIO_NR_PALMTE2_USB_PULLUP		53

/* LCD/BACKLIGHT */
#define GPIO_NR_PALMTE2_BL_POWER		56
#define GPIO_NR_PALMTE2_LCD_POWER		37

/* KEYS */
#define GPIO_NR_PALMTE2_KEY_NOTES	5
#define GPIO_NR_PALMTE2_KEY_TASKS	7
#define GPIO_NR_PALMTE2_KEY_CALENDAR	11
#define GPIO_NR_PALMTE2_KEY_CONTACTS	13
#define GPIO_NR_PALMTE2_KEY_CENTER	14
#define GPIO_NR_PALMTE2_KEY_LEFT	19
#define GPIO_NR_PALMTE2_KEY_RIGHT	20
#define GPIO_NR_PALMTE2_KEY_DOWN	21
#define GPIO_NR_PALMTE2_KEY_UP		22

/** HERE ARE INIT VALUES **/

/* BACKLIGHT */
#define PALMTE2_MAX_INTENSITY		0xFE
#define PALMTE2_DEFAULT_INTENSITY	0x7E
#define PALMTE2_LIMIT_MASK		0x7F
#define PALMTE2_PRESCALER		0x3F
#define PALMTE2_PERIOD_NS		3500

/* BATTERY */
#define PALMTE2_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
#define PALMTE2_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
#define PALMTE2_BAT_MAX_CURRENT		0	/* unknown */
#define PALMTE2_BAT_MIN_CURRENT		0	/* unknown */
#define PALMTE2_BAT_MAX_CHARGE		1	/* unknown */
#define PALMTE2_BAT_MIN_CHARGE		1	/* unknown */
#define PALMTE2_MAX_LIFE_MINS		360	/* on-life in minutes */

#endif

repo_name: angery/linux


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for Palm Treo smartphones
 *
 * currently supported:
 *     Palm Treo 680 (GSM)
 *     Palm Centro 685 (GSM)
 *
 * Author:     Tomas Cech <sleep_walker@suse.cz>
 *
 * (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/power_supply.h>
#include <linux/w1-gpio.h>

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

#include "pxa27x.h"
#include "pxa27x-udc.h"
#include <linux/platform_data/asoc-pxa.h>
#include "palmtreo.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/usb-ohci-pxa27x.h>
#include "pxa2xx-regs.h"
#include <linux/platform_data/asoc-palm27x.h>
#include <linux/platform_data/media/camera-pxa.h>
#include "palm27x.h"

#include <sound/pxa2xx-lib.h>

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

/******************************************************************************
 * Pin configuration
 ******************************************************************************/
static unsigned long treo_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,
	GPIO113_GPIO,				/* SD detect */

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

	/* IrDA */
	GPIO46_FICP_RXD,
	GPIO47_FICP_TXD,

	/* PWM */
	GPIO16_PWM0_OUT,

	/* USB */
	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,	/* usb detect */

	/* MATRIX KEYPAD */
	GPIO101_KP_MKIN_1,
	GPIO102_KP_MKIN_2,
	GPIO97_KP_MKIN_3,
	GPIO98_KP_MKIN_4,
	GPIO91_KP_MKIN_6,
	GPIO13_KP_MKIN_7,
	GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
	GPIO104_KP_MKOUT_1,
	GPIO105_KP_MKOUT_2,
	GPIO106_KP_MKOUT_3,
	GPIO107_KP_MKOUT_4,
	GPIO108_KP_MKOUT_5,
	GPIO96_KP_MKOUT_6,
	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,	/* Hotsync button */

	/* Quick Capture Interface */
	GPIO84_CIF_FV,
	GPIO85_CIF_LV,
	GPIO53_CIF_MCLK,
	GPIO54_CIF_PCLK,
	GPIO81_CIF_DD_0,
	GPIO55_CIF_DD_1,
	GPIO51_CIF_DD_2,
	GPIO50_CIF_DD_3,
	GPIO52_CIF_DD_4,
	GPIO48_CIF_DD_5,
	GPIO17_CIF_DD_6,
	GPIO12_CIF_DD_7,

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

	/* GSM */
	GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH,	/* GSM host wake up */
	GPIO34_FFUART_RXD,
	GPIO35_FFUART_CTS,
	GPIO39_FFUART_TXD,
	GPIO41_FFUART_RTS,

	/* MISC. */
	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* external power detect */
	GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,	/* silent switch */
	GPIO116_GPIO,				/* headphone detect */
	GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,	/* bluetooth host wake up */
};

#ifdef CONFIG_MACH_TREO680
static unsigned long treo680_pin_config[] __initdata = {
	GPIO33_GPIO,    /* SD read only */

	/* MATRIX KEYPAD - different wake up source */
	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
	GPIO99_KP_MKIN_5,

	/* LCD... L_BIAS alt fn not configured on Treo680; is GPIO instead */
	GPIOxx_LCD_16BPP,
	GPIO74_LCD_FCLK,
	GPIO75_LCD_LCLK,
	GPIO76_LCD_PCLK,
};
#endif /* CONFIG_MACH_TREO680 */

#ifdef CONFIG_MACH_CENTRO
static unsigned long centro685_pin_config[] __initdata = {
	/* Bluetooth attached to BT UART*/
	MFP_CFG_OUT(GPIO80, AF0, DRIVE_LOW),    /* power: LOW = off */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,
	GPIO45_BTUART_RTS,

	/* MATRIX KEYPAD - different wake up source */
	GPIO100_KP_MKIN_0,
	GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,
};
#endif /* CONFIG_MACH_CENTRO */

/******************************************************************************
 * GPIO keyboard
 ******************************************************************************/
#if IS_ENABLED(CONFIG_KEYBOARD_PXA27x)
static const unsigned int treo680_matrix_keys[] = {
	KEY(0, 0, KEY_F8),		/* Red/Off/Power */
	KEY(0, 1, KEY_LEFT),
	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
	KEY(0, 3, KEY_L),
	KEY(0, 4, KEY_A),
	KEY(0, 5, KEY_Q),
	KEY(0, 6, KEY_P),

	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
	KEY(1, 1, KEY_RIGHT),
	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
	KEY(1, 3, KEY_Z),
	KEY(1, 4, KEY_S),
	KEY(1, 5, KEY_W),

	KEY(2, 0, KEY_F1),		/* Phone */
	KEY(2, 1, KEY_UP),
	KEY(2, 2, KEY_0),
	KEY(2, 3, KEY_X),
	KEY(2, 4, KEY_D),
	KEY(2, 5, KEY_E),

	KEY(3, 0, KEY_F10),		/* Calendar */
	KEY(3, 1, KEY_DOWN),
	KEY(3, 2, KEY_SPACE),
	KEY(3, 3, KEY_C),
	KEY(3, 4, KEY_F),
	KEY(3, 5, KEY_R),

	KEY(4, 0, KEY_F12),		/* Mail */
	KEY(4, 1, KEY_KPENTER),
	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
	KEY(4, 3, KEY_V),
	KEY(4, 4, KEY_G),
	KEY(4, 5, KEY_T),

	KEY(5, 0, KEY_F9),		/* Home */
	KEY(5, 1, KEY_PAGEUP),		/* Side up */
	KEY(5, 2, KEY_DOT),
	KEY(5, 3, KEY_B),
	KEY(5, 4, KEY_H),
	KEY(5, 5, KEY_Y),

	KEY(6, 0, KEY_TAB),		/* Side Activate */
	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
	KEY(6, 2, KEY_ENTER),
	KEY(6, 3, KEY_N),
	KEY(6, 4, KEY_J),
	KEY(6, 5, KEY_U),

	KEY(7, 0, KEY_F6),		/* Green/Call */
	KEY(7, 1, KEY_O),
	KEY(7, 2, KEY_BACKSPACE),
	KEY(7, 3, KEY_M),
	KEY(7, 4, KEY_K),
	KEY(7, 5, KEY_I),
};

static const unsigned int centro_matrix_keys[] = {
	KEY(0, 0, KEY_F9),		/* Home */
	KEY(0, 1, KEY_LEFT),
	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
	KEY(0, 3, KEY_L),
	KEY(0, 4, KEY_A),
	KEY(0, 5, KEY_Q),
	KEY(0, 6, KEY_P),

	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
	KEY(1, 1, KEY_RIGHT),
	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
	KEY(1, 3, KEY_Z),
	KEY(1, 4, KEY_S),
	KEY(1, 5, KEY_W),

	KEY(2, 0, KEY_F1),		/* Phone */
	KEY(2, 1, KEY_UP),
	KEY(2, 2, KEY_0),
	KEY(2, 3, KEY_X),
	KEY(2, 4, KEY_D),
	KEY(2, 5, KEY_E),

	KEY(3, 0, KEY_F10),		/* Calendar */
	KEY(3, 1, KEY_DOWN),
	KEY(3, 2, KEY_SPACE),
	KEY(3, 3, KEY_C),
	KEY(3, 4, KEY_F),
	KEY(3, 5, KEY_R),

	KEY(4, 0, KEY_F12),		/* Mail */
	KEY(4, 1, KEY_KPENTER),
	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
	KEY(4, 3, KEY_V),
	KEY(4, 4, KEY_G),
	KEY(4, 5, KEY_T),

	KEY(5, 0, KEY_F8),		/* Red/Off/Power */
	KEY(5, 1, KEY_PAGEUP),		/* Side up */
	KEY(5, 2, KEY_DOT),
	KEY(5, 3, KEY_B),
	KEY(5, 4, KEY_H),
	KEY(5, 5, KEY_Y),

	KEY(6, 0, KEY_TAB),		/* Side Activate */
	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
	KEY(6, 2, KEY_ENTER),
	KEY(6, 3, KEY_N),
	KEY(6, 4, KEY_J),
	KEY(6, 5, KEY_U),

	KEY(7, 0, KEY_F6),		/* Green/Call */
	KEY(7, 1, KEY_O),
	KEY(7, 2, KEY_BACKSPACE),
	KEY(7, 3, KEY_M),
	KEY(7, 4, KEY_K),
	KEY(7, 5, KEY_I),
};

static struct matrix_keymap_data treo680_matrix_keymap_data = {
	.keymap			= treo680_matrix_keys,
	.keymap_size		= ARRAY_SIZE(treo680_matrix_keys),
};

static struct matrix_keymap_data centro_matrix_keymap_data = {
	.keymap			= centro_matrix_keys,
	.keymap_size		= ARRAY_SIZE(centro_matrix_keys),
};

static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
	.matrix_key_rows	= 8,
	.matrix_key_cols	= 7,
	.matrix_keymap_data	= &treo680_matrix_keymap_data,
	.direct_key_map		= { KEY_CONNECT },
	.direct_key_num		= 1,

	.debounce_interval	= 30,
};

static void __init palmtreo_kpc_init(void)
{
	static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata;

	if (machine_is_centro())
		data->matrix_keymap_data = &centro_matrix_keymap_data;

	pxa_set_keypad_info(&treo680_keypad_pdata);
}
#else
static inline void palmtreo_kpc_init(void) {}
#endif

/******************************************************************************
 * USB host
 ******************************************************************************/
#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
static struct pxaohci_platform_data treo680_ohci_info = {
	.port_mode    = PMM_PERPORT_MODE,
	.flags        = ENABLE_PORT1 | ENABLE_PORT3,
	.power_budget = 0,
};

static void __init palmtreo_uhc_init(void)
{
	if (machine_is_treo680())
		pxa_set_ohci_info(&treo680_ohci_info);
}
#else
static inline void palmtreo_uhc_init(void) {}
#endif

/******************************************************************************
 * Vibra and LEDs
 ******************************************************************************/
static struct gpio_led treo680_gpio_leds[] = {
	{
		.name			= "treo680:vibra:vibra",
		.default_trigger	= "none",
		.gpio			= GPIO_NR_TREO680_VIBRATE_EN,
	},
	{
		.name			= "treo680:green:led",
		.default_trigger	= "mmc0",
		.gpio			= GPIO_NR_TREO_GREEN_LED,
	},
	{
		.name			= "treo680:white:keybbl",
		.default_trigger	= "none",
		.gpio			= GPIO_NR_TREO680_KEYB_BL,
	},
};

static struct gpio_led_platform_data treo680_gpio_led_info = {
	.leds		= treo680_gpio_leds,
	.num_leds	= ARRAY_SIZE(treo680_gpio_leds),
};

static struct gpio_led centro_gpio_leds[] = {
	{
		.name			= "centro:vibra:vibra",
		.default_trigger	= "none",
		.gpio			= GPIO_NR_CENTRO_VIBRATE_EN,
	},
	{
		.name			= "centro:green:led",
		.default_trigger	= "mmc0",
		.gpio			= GPIO_NR_TREO_GREEN_LED,
	},
	{
		.name			= "centro:white:keybbl",
		.default_trigger	= "none",
		.active_low		= 1,
		.gpio			= GPIO_NR_CENTRO_KEYB_BL,
	},
};

static struct gpio_led_platform_data centro_gpio_led_info = {
	.leds		= centro_gpio_leds,
	.num_leds	= ARRAY_SIZE(centro_gpio_leds),
};

static struct platform_device palmtreo_leds = {
	.name   = "leds-gpio",
	.id     = -1,
};

static void __init palmtreo_leds_init(void)
{
	if (machine_is_centro())
		palmtreo_leds.dev.platform_data = &centro_gpio_led_info;
	else if (machine_is_treo680())
		palmtreo_leds.dev.platform_data = &treo680_gpio_led_info;

	platform_device_register(&palmtreo_leds);
}

/******************************************************************************
 * Machine init
 ******************************************************************************/
static void __init treo_reserve(void)
{
	memblock_reserve(0xa0000000, 0x1000);
	memblock_reserve(0xa2000000, 0x1000);
}

static void __init palmphone_common_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);
	palm27x_pm_init(TREO_STR_BASE);
	palm27x_lcd_init(GPIO_NR_TREO_BL_POWER, &palm_320x320_new_lcd_mode);
	palm27x_udc_init(GPIO_NR_TREO_USB_DETECT, GPIO_NR_TREO_USB_PULLUP, 1);
	palm27x_irda_init(GPIO_NR_TREO_IR_EN);
	palm27x_ac97_init(-1, -1, -1, 95);
	palm27x_pwm_init(GPIO_NR_TREO_BL_POWER, -1);
	palm27x_power_init(GPIO_NR_TREO_POWER_DETECT, -1);
	palm27x_pmic_init();
	palmtreo_kpc_init();
	palmtreo_uhc_init();
	palmtreo_leds_init();
}

#ifdef CONFIG_MACH_TREO680
void __init treo680_gpio_init(void)
{
	unsigned int gpio;

	/* drive all three lcd gpios high initially */
	const unsigned long lcd_flags = GPIOF_INIT_HIGH | GPIOF_DIR_OUT;

	/*
	 * LCD GPIO initialization...
	 */

	/*
	 * This is likely the power to the lcd.  Toggling it low/high appears to
	 * turn the lcd off/on.  Can be toggled after lcd is initialized without
	 * any apparent adverse effects to the lcd operation.  Note that this
	 * gpio line is used by the lcd controller as the L_BIAS signal, but
	 * treo680 configures it as gpio.
	 */
	gpio = GPIO_NR_TREO680_LCD_POWER;
	if (gpio_request_one(gpio, lcd_flags, "LCD power") < 0)
		goto fail;

	/*
	 * These two are called "enables", for lack of a better understanding.
	 * If either of these are toggled after the lcd is initialized, the
	 * image becomes degraded.  N.B. The IPL shipped with the treo
	 * configures GPIO_NR_TREO680_LCD_EN_N as output and drives it high.  If
	 * the IPL is ever reprogrammed, this initialization may be need to be
	 * revisited.
	 */
	gpio = GPIO_NR_TREO680_LCD_EN;
	if (gpio_request_one(gpio, lcd_flags, "LCD enable") < 0)
		goto fail;
	gpio = GPIO_NR_TREO680_LCD_EN_N;
	if (gpio_request_one(gpio, lcd_flags, "LCD enable_n") < 0)
		goto fail;

	/* driving this low turns LCD on */
	gpio_set_value(GPIO_NR_TREO680_LCD_EN_N, 0);

	return;
 fail:
	pr_err("gpio %d initialization failed\n", gpio);
	gpio_free(GPIO_NR_TREO680_LCD_POWER);
	gpio_free(GPIO_NR_TREO680_LCD_EN);
	gpio_free(GPIO_NR_TREO680_LCD_EN_N);
}

static struct gpiod_lookup_table treo680_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO680_SD_READONLY,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO680_SD_POWER,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static void __init treo680_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
	palmphone_common_init();
	treo680_gpio_init();
	palm27x_mmc_init(&treo680_mci_gpio_table);
}
#endif

#ifdef CONFIG_MACH_CENTRO

static struct gpiod_lookup_table centro685_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_CENTRO_SD_POWER,
			    "power", GPIO_ACTIVE_LOW),
		{ },
	},
};

static void __init centro_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config));
	palmphone_common_init();
	palm27x_mmc_init(&centro685_mci_gpio_table);
}
#endif

#ifdef CONFIG_MACH_TREO680
MACHINE_START(TREO680, "Palm Treo 680")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.reserve	= treo_reserve,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = treo680_init,
	.restart	= pxa_restart,
MACHINE_END
#endif

#ifdef CONFIG_MACH_CENTRO
MACHINE_START(CENTRO, "Palm Centro 685")
	.atag_offset    = 0x100,
	.map_io         = pxa27x_map_io,
	.reserve	= treo_reserve,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq       = pxa27x_init_irq,
	.handle_irq       = pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= centro_init,
	.restart	= pxa_restart,
MACHINE_END
#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIOs and interrupts for Palm Treo smartphones
 *
 * currently supported:
 *     Palm Treo 680 (GSM)
 *     Palm Centro 685 (GSM)
 *
 * Author:     Tomas Cech <sleep_walker@suse.cz>
 *
 * find more info at www.hackndev.com
 */

#ifndef _INCLUDE_TREO_H_
#define _INCLUDE_TREO_H_

/* GPIOs */
#define GPIO_NR_TREO_POWER_DETECT	0
#define GPIO_NR_TREO_AMP_EN		27
#define GPIO_NR_TREO_GREEN_LED	20
#define GPIO_NR_TREO_RED_LED		79
#define GPIO_NR_TREO_SD_DETECT_N	113
#define GPIO_NR_TREO_EP_DETECT_N	116
#define GPIO_NR_TREO_USB_DETECT	1
#define GPIO_NR_TREO_USB_PULLUP	114
#define GPIO_NR_TREO_GSM_POWER	40
#define GPIO_NR_TREO_GSM_RESET	87
#define GPIO_NR_TREO_GSM_WAKE	57
#define GPIO_NR_TREO_GSM_HOST_WAKE	14
#define GPIO_NR_TREO_GSM_TRIGGER	10
#define GPIO_NR_TREO_IR_EN		115
#define GPIO_NR_TREO_IR_TXD		47
#define GPIO_NR_TREO_BL_POWER	38
#define GPIO_NR_TREO_LCD_POWER	25

/* Treo680 specific GPIOs */
#define GPIO_NR_TREO680_SD_READONLY	33
#define GPIO_NR_TREO680_SD_POWER	42
#define GPIO_NR_TREO680_VIBRATE_EN	44
#define GPIO_NR_TREO680_KEYB_BL		24
#define GPIO_NR_TREO680_BT_EN		43
#define GPIO_NR_TREO680_LCD_POWER	77
#define GPIO_NR_TREO680_LCD_EN		86
#define GPIO_NR_TREO680_LCD_EN_N	25

/* Centro685 specific GPIOs */
#define GPIO_NR_CENTRO_SD_POWER		21
#define GPIO_NR_CENTRO_VIBRATE_EN	22
#define GPIO_NR_CENTRO_KEYB_BL		33
#define GPIO_NR_CENTRO_BT_EN		80

/* Various addresses  */
#define TREO_PHYS_RAM_START	0xa0000000
#define TREO_PHYS_IO_START	0x40000000
#define TREO_STR_BASE	0xa2000000

/* BACKLIGHT */
#define TREO_MAX_INTENSITY		254
#define TREO_DEFAULT_INTENSITY	160
#define TREO_LIMIT_MASK		0x7F
#define TREO_PRESCALER		63
#define TREO_PERIOD_NS		3500

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/drivers/pcmcia/pxa2xx_palmtx.c
 *
 * Driver for Palm T|X PCMCIA
 *
 * 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 "palmtx.h"
#include <pcmcia/soc_common.h>

static struct gpio palmtx_pcmcia_gpios[] = {
	{ GPIO_NR_PALMTX_PCMCIA_POWER1,	GPIOF_INIT_LOW,	"PCMCIA Power 1" },
	{ GPIO_NR_PALMTX_PCMCIA_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },
	{ GPIO_NR_PALMTX_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
};

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

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

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

	return ret;
}

static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
	gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios));
}

static void palmtx_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
palmtx_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
				const socket_state_t *state)
{
	gpio_set_value(GPIO_NR_PALMTX_PCMCIA_POWER1, 1);
	gpio_set_value(GPIO_NR_PALMTX_PCMCIA_POWER2, 1);
	gpio_set_value(GPIO_NR_PALMTX_PCMCIA_RESET,
			!!(state->flags & SS_RESET));

	return 0;
}

static struct pcmcia_low_level palmtx_pcmcia_ops = {
	.owner			= THIS_MODULE,

	.first			= 0,
	.nr			= 1,

	.hw_init		= palmtx_pcmcia_hw_init,
	.hw_shutdown		= palmtx_pcmcia_hw_shutdown,

	.socket_state		= palmtx_pcmcia_socket_state,
	.configure_socket	= palmtx_pcmcia_configure_socket,
};

static struct platform_device *palmtx_pcmcia_device;

static int __init palmtx_pcmcia_init(void)
{
	int ret;

	if (!machine_is_palmtx())
		return -ENODEV;

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

	ret = platform_device_add_data(palmtx_pcmcia_device, &palmtx_pcmcia_ops,
					sizeof(palmtx_pcmcia_ops));

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

	if (ret)
		platform_device_put(palmtx_pcmcia_device);

	return ret;
}

static void __exit palmtx_pcmcia_exit(void)
{
	platform_device_unregister(palmtx_pcmcia_device);
}

module_init(palmtx_pcmcia_init);
module_exit(palmtx_pcmcia_exit);

MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("PCMCIA support for Palm T|X");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
MODULE_LICENSE("GPL");


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for PalmTX
 *
 * Author:     Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on work of:
 *		Alex Osborne <ato@meshy.org>
 *		Cristiano P. <cristianop@users.sourceforge.net>
 *		Jan Herman <2hp@seznam.cz>
 *		Michal Hrusecky
 *
 * (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/platnand.h>
#include <linux/mtd/mtd.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 <linux/platform_data/asoc-pxa.h>
#include "palmtx.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 palmtx_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,

	/* PWM */
	GPIO16_PWM0_OUT,

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

	/* PCMCIA */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO85_nPCE_1,
	GPIO54_nPCE_2,
	GPIO79_PSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,
	GPIO94_GPIO,	/* wifi power 1 */
	GPIO108_GPIO,	/* wifi power 2 */
	GPIO116_GPIO,	/* wifi ready */

	/* 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,

	/* FFUART */
	GPIO34_FFUART_RXD,
	GPIO39_FFUART_TXD,

	/* NAND */
	GPIO15_nCS_1,
	GPIO18_RDY,

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

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

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

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

static struct platform_device palmtx_flash = {
	.name		= "physmap-flash",
	.id		= 0,
	.resource	= &palmtx_flash_resource,
	.num_resources	= 1,
	.dev 		= {
		.platform_data = palmtx_flash_data,
	},
};

static void __init palmtx_nor_init(void)
{
	platform_device_register(&palmtx_flash);
}
#else
static inline void palmtx_nor_init(void) {}
#endif

/******************************************************************************
 * GPIO keyboard
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static const unsigned int palmtx_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 palmtx_matrix_keymap_data = {
	.keymap			= palmtx_matrix_keys,
	.keymap_size		= ARRAY_SIZE(palmtx_matrix_keys),
};

static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
	.matrix_key_rows	= 4,
	.matrix_key_cols	= 3,
	.matrix_keymap_data	= &palmtx_matrix_keymap_data,

	.debounce_interval	= 30,
};

static void __init palmtx_kpc_init(void)
{
	pxa_set_keypad_info(&palmtx_keypad_platform_data);
}
#else
static inline void palmtx_kpc_init(void) {}
#endif

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

static struct gpio_keys_platform_data palmtx_pxa_keys_data = {
	.buttons	= palmtx_pxa_buttons,
	.nbuttons	= ARRAY_SIZE(palmtx_pxa_buttons),
};

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

static void __init palmtx_keys_init(void)
{
	platform_device_register(&palmtx_pxa_keys);
}
#else
static inline void palmtx_keys_init(void) {}
#endif

/******************************************************************************
 * NAND Flash
 ******************************************************************************/
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
	defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
static void palmtx_nand_cmd_ctl(struct nand_chip *this, int cmd,
				unsigned int ctrl)
{
	char __iomem *nandaddr = this->legacy.IO_ADDR_W;

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_CLE)
		writeb(cmd, PALMTX_NAND_CLE_VIRT);
	else if (ctrl & NAND_ALE)
		writeb(cmd, PALMTX_NAND_ALE_VIRT);
	else
		writeb(cmd, nandaddr);
}

static struct mtd_partition palmtx_partition_info[] = {
	[0] = {
		.name	= "palmtx-0",
		.offset	= 0,
		.size	= MTDPART_SIZ_FULL
	},
};

struct platform_nand_data palmtx_nand_platdata = {
	.chip	= {
		.nr_chips		= 1,
		.chip_offset		= 0,
		.nr_partitions		= ARRAY_SIZE(palmtx_partition_info),
		.partitions		= palmtx_partition_info,
		.chip_delay		= 20,
	},
	.ctrl	= {
		.cmd_ctrl	= palmtx_nand_cmd_ctl,
	},
};

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

static struct platform_device palmtx_nand = {
	.name		= "gen_nand",
	.num_resources	= ARRAY_SIZE(palmtx_nand_resource),
	.resource	= palmtx_nand_resource,
	.id		= -1,
	.dev		= {
		.platform_data	= &palmtx_nand_platdata,
	}
};

static void __init palmtx_nand_init(void)
{
	platform_device_register(&palmtx_nand);
}
#else
static inline void palmtx_nand_init(void) {}
#endif

/******************************************************************************
 * Machine init
 ******************************************************************************/
static struct map_desc palmtx_io_desc[] __initdata = {
{
	.virtual	= (unsigned long)PALMTX_PCMCIA_VIRT,
	.pfn		= __phys_to_pfn(PALMTX_PCMCIA_PHYS),
	.length		= PALMTX_PCMCIA_SIZE,
	.type		= MT_DEVICE,
}, {
	.virtual	= (unsigned long)PALMTX_NAND_ALE_VIRT,
	.pfn		= __phys_to_pfn(PALMTX_NAND_ALE_PHYS),
	.length		= SZ_1M,
	.type		= MT_DEVICE,
}, {
	.virtual	= (unsigned long)PALMTX_NAND_CLE_VIRT,
	.pfn		= __phys_to_pfn(PALMTX_NAND_CLE_PHYS),
	.length		= SZ_1M,
	.type		= MT_DEVICE,
}
};

static void __init palmtx_map_io(void)
{
	pxa27x_map_io();
	iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
}

static struct gpiod_lookup_table palmtx_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTX_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTX_SD_READONLY,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTX_SD_POWER,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

static void __init palmtx_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	palm27x_mmc_init(&palmtx_mci_gpio_table);
	gpiod_add_lookup_table(&palmtx_wm97xx_touch_gpio_table);
	palm27x_pm_init(PALMTX_STR_BASE);
	palm27x_lcd_init(-1, &palm_320x480_lcd_mode);
	palm27x_udc_init(GPIO_NR_PALMTX_USB_DETECT_N,
			GPIO_NR_PALMTX_USB_PULLUP, 1);
	palm27x_irda_init(GPIO_NR_PALMTX_IR_DISABLE);
	palm27x_ac97_init(PALMTX_BAT_MIN_VOLTAGE, PALMTX_BAT_MAX_VOLTAGE,
			GPIO_NR_PALMTX_EARPHONE_DETECT, 95);
	palm27x_pwm_init(GPIO_NR_PALMTX_BL_POWER, GPIO_NR_PALMTX_LCD_POWER);
	palm27x_power_init(GPIO_NR_PALMTX_POWER_DETECT, -1);
	palm27x_pmic_init();
	palmtx_kpc_init();
	palmtx_keys_init();
	palmtx_nor_init();
	palmtx_nand_init();
}

MACHINE_START(PALMTX, "Palm T|X")
	.atag_offset	= 0x100,
	.map_io		= palmtx_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= palmtx_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIOs and interrupts for Palm T|X Handheld Computer
 *
 * Based on palmld-gpio.h by Alex Osborne
 *
 * Authors:	Marek Vasut <marek.vasut@gmail.com>
 *		Cristiano P. <cristianop@users.sourceforge.net>
 *		Jan Herman <2hp@seznam.cz>
 */

#ifndef _INCLUDE_PALMTX_H_
#define _INCLUDE_PALMTX_H_

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

/** HERE ARE GPIOs **/

/* GPIOs */
#define GPIO_NR_PALMTX_GPIO_RESET		1

#define GPIO_NR_PALMTX_POWER_DETECT		12 /* 90 */
#define GPIO_NR_PALMTX_HOTSYNC_BUTTON_N		10
#define GPIO_NR_PALMTX_EARPHONE_DETECT		107

/* SD/MMC */
#define GPIO_NR_PALMTX_SD_DETECT_N		14
#define GPIO_NR_PALMTX_SD_POWER			114 /* probably */
#define GPIO_NR_PALMTX_SD_READONLY		115 /* probably */

/* TOUCHSCREEN */
#define GPIO_NR_PALMTX_WM9712_IRQ		27

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

/* USB */
#define GPIO_NR_PALMTX_USB_DETECT_N		13
#define GPIO_NR_PALMTX_USB_PULLUP		93

/* LCD/BACKLIGHT */
#define GPIO_NR_PALMTX_BL_POWER			84
#define GPIO_NR_PALMTX_LCD_POWER		96

/* LCD BORDER */
#define GPIO_NR_PALMTX_BORDER_SWITCH		98
#define GPIO_NR_PALMTX_BORDER_SELECT		22

/* BLUETOOTH */
#define GPIO_NR_PALMTX_BT_POWER			17
#define GPIO_NR_PALMTX_BT_RESET			83

/* PCMCIA (WiFi) */
#define GPIO_NR_PALMTX_PCMCIA_POWER1		94
#define GPIO_NR_PALMTX_PCMCIA_POWER2		108
#define GPIO_NR_PALMTX_PCMCIA_RESET		79
#define GPIO_NR_PALMTX_PCMCIA_READY		116

/* NAND Flash ... this GPIO may be incorrect! */
#define GPIO_NR_PALMTX_NAND_BUFFER_DIR		79

/* INTERRUPTS */
#define IRQ_GPIO_PALMTX_SD_DETECT_N	PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_SD_DETECT_N)
#define IRQ_GPIO_PALMTX_WM9712_IRQ	PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_WM9712_IRQ)
#define IRQ_GPIO_PALMTX_USB_DETECT	PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_USB_DETECT)
#define IRQ_GPIO_PALMTX_GPIO_RESET	PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_GPIO_RESET)

/** HERE ARE INIT VALUES **/

/* Various addresses  */
#define PALMTX_PCMCIA_PHYS	0x28000000
#define PALMTX_PCMCIA_VIRT	IOMEM(0xf0000000)
#define PALMTX_PCMCIA_SIZE	0x100000

#define PALMTX_PHYS_RAM_START	0xa0000000
#define PALMTX_PHYS_IO_START	0x40000000

#define PALMTX_STR_BASE		0xa0200000

#define PALMTX_PHYS_FLASH_START	PXA_CS0_PHYS	/* ChipSelect 0 */
#define PALMTX_PHYS_NAND_START	PXA_CS1_PHYS	/* ChipSelect 1 */

#define PALMTX_NAND_ALE_PHYS	(PALMTX_PHYS_NAND_START | (1 << 24))
#define PALMTX_NAND_CLE_PHYS	(PALMTX_PHYS_NAND_START | (1 << 25))
#define PALMTX_NAND_ALE_VIRT	IOMEM(0xff100000)
#define PALMTX_NAND_CLE_VIRT	IOMEM(0xff200000)

/* TOUCHSCREEN */
#define AC97_LINK_FRAME			21

/* BATTERY */
#define PALMTX_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
#define PALMTX_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
#define PALMTX_BAT_MAX_CURRENT		0	/* unknown */
#define PALMTX_BAT_MIN_CURRENT		0	/* unknown */
#define PALMTX_BAT_MAX_CHARGE		1	/* unknown */
#define PALMTX_BAT_MIN_CHARGE		1	/* unknown */
#define PALMTX_MAX_LIFE_MINS		360	/* on-life in minutes */

#define PALMTX_BAT_MEASURE_DELAY	(HZ * 1)

/* BACKLIGHT */
#define PALMTX_MAX_INTENSITY		0xFE
#define PALMTX_DEFAULT_INTENSITY	0x7E
#define PALMTX_LIMIT_MASK		0x7F
#define PALMTX_PRESCALER		0x3F
#define PALMTX_PERIOD_NS		3500

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Hardware definitions for Palm Zire72
 *
 * Authors:
 *	Vladimir "Farcaller" Pouzanov <farcaller@gmail.com>
 *	Sergey Lapin <slapin@ossfans.org>
 *	Alex Osborne <bobofdoom@gmail.com>
 *	Jan Herman <2hp@seznam.cz>
 *
 * Rewrite for mainline:
 *	Marek Vasut <marek.vasut@gmail.com>
 *
 * (find more info at www.hackndev.com)
 */

#include <linux/platform_device.h>
#include <linux/syscore_ops.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/platform_data/i2c-gpio.h>
#include <linux/gpio/machine.h>

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

#include "pxa27x.h"
#include <linux/platform_data/asoc-pxa.h>
#include "palmz72.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 "pm.h"
#include <linux/platform_data/media/camera-pxa.h>

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

/******************************************************************************
 * Pin configuration
 ******************************************************************************/
static unsigned long palmz72_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 */
	GPIO115_GPIO,	/* SD RO */
	GPIO98_GPIO,	/* SD power */

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

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

	/* PWM */
	GPIO16_PWM0_OUT,

	/* USB */
	GPIO15_GPIO,	/* usb detect */
	GPIO95_GPIO,	/* usb pullup */

	/* 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,

	GPIO20_GPIO,	/* bl power */
	GPIO21_GPIO,	/* LCD border switch */
	GPIO22_GPIO,	/* LCD border color */
	GPIO96_GPIO,	/* lcd power */

	/* PXA Camera */
	GPIO81_CIF_DD_0,
	GPIO48_CIF_DD_5,
	GPIO50_CIF_DD_3,
	GPIO51_CIF_DD_2,
	GPIO52_CIF_DD_4,
	GPIO53_CIF_MCLK,
	GPIO54_CIF_PCLK,
	GPIO55_CIF_DD_1,
	GPIO84_CIF_FV,
	GPIO85_CIF_LV,
	GPIO93_CIF_DD_6,
	GPIO108_CIF_DD_7,

	GPIO56_GPIO,	/* OV9640 Powerdown */
	GPIO57_GPIO,	/* OV9640 Reset */
	GPIO91_GPIO,	/* OV9640 Power */

	/* I2C */
	GPIO117_GPIO,	/* I2C_SCL */
	GPIO118_GPIO,	/* I2C_SDA */

	/* Misc. */
	GPIO0_GPIO	| WAKEUP_ON_LEVEL_HIGH,	/* power detect */
	GPIO88_GPIO,				/* green led */
	GPIO27_GPIO,				/* WM9712 IRQ */
};

/******************************************************************************
 * GPIO keyboard
 ******************************************************************************/
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static const unsigned int palmz72_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 almz72_matrix_keymap_data = {
	.keymap			= palmz72_matrix_keys,
	.keymap_size		= ARRAY_SIZE(palmz72_matrix_keys),
};

static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
	.matrix_key_rows	= 4,
	.matrix_key_cols	= 3,
	.matrix_keymap_data	= &almz72_matrix_keymap_data,

	.debounce_interval	= 30,
};

static void __init palmz72_kpc_init(void)
{
	pxa_set_keypad_info(&palmz72_keypad_platform_data);
}
#else
static inline void palmz72_kpc_init(void) {}
#endif

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

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

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

static void __init palmz72_leds_init(void)
{
	platform_device_register(&palmz72_leds);
}
#else
static inline void palmz72_leds_init(void) {}
#endif

#ifdef CONFIG_PM

/* We have some black magic here
 * PalmOS ROM on recover expects special struct physical address
 * to be transferred via PSPR. Using this struct PalmOS restores
 * its state after sleep. As for Linux, we need to setup it the
 * same way. More than that, PalmOS ROM changes some values in memory.
 * For now only one location is found, which needs special treatment.
 * Thanks to Alex Osborne, Andrzej Zaborowski, and lots of other people
 * for reading backtraces for me :)
 */

#define PALMZ72_SAVE_DWORD ((unsigned long *)0xc0000050)

static struct palmz72_resume_info palmz72_resume_info = {
	.magic0 = 0xb4e6,
	.magic1 = 1,

	/* reset state, MMU off etc */
	.arm_control = 0,
	.aux_control = 0,
	.ttb = 0,
	.domain_access = 0,
	.process_id = 0,
};

static unsigned long store_ptr;

/* syscore_ops for Palm Zire 72 PM */

static int palmz72_pm_suspend(void)
{
	/* setup the resume_info struct for the original bootloader */
	palmz72_resume_info.resume_addr = (u32) cpu_resume;

	/* Storing memory touched by ROM */
	store_ptr = *PALMZ72_SAVE_DWORD;

	/* Setting PSPR to a proper value */
	PSPR = __pa_symbol(&palmz72_resume_info);

	return 0;
}

static void palmz72_pm_resume(void)
{
	*PALMZ72_SAVE_DWORD = store_ptr;
}

static struct syscore_ops palmz72_pm_syscore_ops = {
	.suspend = palmz72_pm_suspend,
	.resume = palmz72_pm_resume,
};

static int __init palmz72_pm_init(void)
{
	if (machine_is_palmz72()) {
		register_syscore_ops(&palmz72_pm_syscore_ops);
		return 0;
	}
	return -ENODEV;
}

device_initcall(palmz72_pm_init);
#endif

static struct gpiod_lookup_table palmz72_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMZ72_SD_DETECT_N,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMZ72_SD_RO,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMZ72_SD_POWER_N,
			    "power", GPIO_ACTIVE_LOW),
		{ },
	},
};

/******************************************************************************
 * Machine init
 ******************************************************************************/
static void __init palmz72_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	palm27x_mmc_init(&palmz72_mci_gpio_table);
	palm27x_lcd_init(-1, &palm_320x320_lcd_mode);
	palm27x_udc_init(GPIO_NR_PALMZ72_USB_DETECT_N,
			GPIO_NR_PALMZ72_USB_PULLUP, 0);
	palm27x_irda_init(GPIO_NR_PALMZ72_IR_DISABLE);
	palm27x_ac97_init(PALMZ72_BAT_MIN_VOLTAGE, PALMZ72_BAT_MAX_VOLTAGE,
			-1, 113);
	palm27x_pwm_init(-1, -1);
	palm27x_power_init(-1, -1);
	palm27x_pmic_init();
	palmz72_kpc_init();
	palmz72_leds_init();
}

MACHINE_START(PALMZ72, "Palm Zire72")
	.atag_offset	= 0x100,
	.map_io		= pxa27x_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= palmz72_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GPIOs and interrupts for Palm Zire72 Handheld Computer
 *
 * Authors:	Alex Osborne <bobofdoom@gmail.com>
 *		Jan Herman <2hp@seznam.cz>
 *		Sergey Lapin <slapin@ossfans.org>
 */

#ifndef _INCLUDE_PALMZ72_H_
#define _INCLUDE_PALMZ72_H_

/* Power and control */
#define GPIO_NR_PALMZ72_GPIO_RESET		1
#define GPIO_NR_PALMZ72_POWER_DETECT		0

/* SD/MMC */
#define GPIO_NR_PALMZ72_SD_DETECT_N		14
#define GPIO_NR_PALMZ72_SD_POWER_N		98
#define GPIO_NR_PALMZ72_SD_RO			115

/* Touchscreen */
#define GPIO_NR_PALMZ72_WM9712_IRQ		27

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

/* USB */
#define GPIO_NR_PALMZ72_USB_DETECT_N		15
#define GPIO_NR_PALMZ72_USB_PULLUP		95

/* LCD/Backlight */
#define GPIO_NR_PALMZ72_BL_POWER		20
#define GPIO_NR_PALMZ72_LCD_POWER		96

/* LED */
#define GPIO_NR_PALMZ72_LED_GREEN		88

/* Bluetooth */
#define GPIO_NR_PALMZ72_BT_POWER		17
#define GPIO_NR_PALMZ72_BT_RESET		83

/* Camera */
#define GPIO_NR_PALMZ72_CAM_PWDN		56
#define GPIO_NR_PALMZ72_CAM_RESET		57
#define GPIO_NR_PALMZ72_CAM_POWER		91

/** Initial values **/

/* Battery */
#define PALMZ72_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
#define PALMZ72_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
#define PALMZ72_BAT_MAX_CURRENT		0	/* unknown */
#define PALMZ72_BAT_MIN_CURRENT		0	/* unknown */
#define PALMZ72_BAT_MAX_CHARGE		1	/* unknown */
#define PALMZ72_BAT_MIN_CHARGE		1	/* unknown */
#define PALMZ72_MAX_LIFE_MINS		360	/* on-life in minutes */

/* Backlight */
#define PALMZ72_MAX_INTENSITY		0xFE
#define PALMZ72_DEFAULT_INTENSITY	0x7E
#define PALMZ72_LIMIT_MASK		0x7F
#define PALMZ72_PRESCALER		0x3F
#define PALMZ72_PERIOD_NS		3500

#ifdef CONFIG_PM
struct palmz72_resume_info {
	u32 magic0;		/* 0x0 */
	u32 magic1;		/* 0x4 */
	u32 resume_addr;	/* 0x8 */
	u32 pad[11];		/* 0xc..0x37 */
	u32 arm_control;	/* 0x38 */
	u32 aux_control;	/* 0x3c */
	u32 ttb;		/* 0x40 */
	u32 domain_access;	/* 0x44 */
	u32 process_id;		/* 0x48 */
};
#endif
#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/pcm027.c
 *  Support for the Phytec phyCORE-PXA270 CPU card (aka PCM-027).
 *
 *  Refer
 *   http://www.phytec.com/products/sbc/ARM-XScale/phyCORE-XScale-PXA270.html
 *  for additional hardware info
 *
 *  Author:	Juergen Kilb
 *  Created:	April 05, 2005
 *  Copyright:	Phytec Messtechnik GmbH
 *  e-Mail:	armlinux@phytec.de
 *
 *  based on Intel Mainstone Board
 *
 *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
 */

#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/spi/spi.h>
#include <linux/spi/max7301.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/leds.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "pxa27x.h"
#include "pcm027.h"
#include "generic.h"

/*
 * ABSTRACT:
 *
 * The PXA270 processor comes with a bunch of hardware on its silicon.
 * Not all of this hardware can be used at the same time and not all
 * is routed to module's connectors. Also it depends on the baseboard, what
 * kind of hardware can be used in which way.
 * -> So this file supports the main devices on the CPU card only!
 * Refer pcm990-baseboard.c how to extend this features to get a full
 * blown system with many common interfaces.
 *
 * The PCM-027 supports the following interfaces through its connectors and
 * will be used in pcm990-baseboard.c:
 *
 * - LCD support
 * - MMC support
 * - IDE/CF card
 * - FFUART
 * - BTUART
 * - IRUART
 * - AC97
 * - SSP
 * - SSP3
 *
 * Claimed GPIOs:
 * GPIO0 -> IRQ input from RTC
 * GPIO2 -> SYS_ENA*)
 * GPIO3 -> PWR_SCL
 * GPIO4 -> PWR_SDA
 * GPIO5 -> PowerCap0*)
 * GPIO6 -> PowerCap1*)
 * GPIO7 -> PowerCap2*)
 * GPIO8 -> PowerCap3*)
 * GPIO15 -> /CS1
 * GPIO20 -> /CS2
 * GPIO21 -> /CS3
 * GPIO33 -> /CS5 network controller select
 * GPIO52 -> IRQ from network controller
 * GPIO78 -> /CS2
 * GPIO80 -> /CS4
 * GPIO90 -> LED0
 * GPIO91 -> LED1
 * GPIO114 -> IRQ from CAN controller
 * GPIO117 -> SCL
 * GPIO118 -> SDA
 *
 * *) CPU internal use only
 */

static unsigned long pcm027_pin_config[] __initdata = {
	/* Chip Selects */
	GPIO20_nSDCS_2,
	GPIO21_nSDCS_3,
	GPIO15_nCS_1,
	GPIO78_nCS_2,
	GPIO80_nCS_4,
	GPIO33_nCS_5,	/* Ethernet */

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

	/* GPIO */
	GPIO52_GPIO,	/* IRQ from network controller */
#ifdef CONFIG_LEDS_GPIO
	GPIO90_GPIO,	/* PCM027_LED_CPU */
	GPIO91_GPIO,	/* PCM027_LED_HEART_BEAT */
#endif
	GPIO114_GPIO,	/* IRQ from CAN controller */
};

/*
 * SMC91x network controller specific stuff
 */
static struct resource smc91x_resources[] = {
	[0] = {
		.start	= PCM027_ETH_PHYS + 0x300,
		.end	= PCM027_ETH_PHYS + PCM027_ETH_SIZE,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= PCM027_ETH_IRQ,
		.end	= PCM027_ETH_IRQ,
		/* note: smc91x's driver doesn't use the trigger bits yet */
		.flags	= IORESOURCE_IRQ | PCM027_ETH_IRQ_EDGE,
	}
};

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

/*
 * SPI host and devices
 */
static struct pxa2xx_spi_controller pxa_ssp_master_info = {
	.num_chipselect	= 1,
};

static struct max7301_platform_data max7301_info = {
	.base = -1,
};

/* bus_num must match id in pxa2xx_set_spi_info() call */
static struct spi_board_info spi_board_info[] __initdata = {
	{
		.modalias	= "max7301",
		.platform_data	= &max7301_info,
		.max_speed_hz	= 13000000,
		.bus_num	= 1,
		.chip_select	= 0,
		.mode		= SPI_MODE_0,
	},
};

/*
 * NOR flash
 */
static struct physmap_flash_data pcm027_flash_data = {
	.width  = 4,
};

static struct resource pcm027_flash_resource = {
	.start          = PCM027_FLASH_PHYS,
	.end            = PCM027_FLASH_PHYS + PCM027_FLASH_SIZE - 1 ,
	.flags          = IORESOURCE_MEM,
};

static struct platform_device pcm027_flash = {
	.name           = "physmap-flash",
	.id             = 0,
	.dev            = {
		.platform_data  = &pcm027_flash_data,
	},
	.resource       = &pcm027_flash_resource,
	.num_resources  = 1,
};

#ifdef CONFIG_LEDS_GPIO

static struct gpio_led pcm027_led[] = {
	{
		.name = "led0:red",	/* FIXME */
		.gpio = PCM027_LED_CPU
	},
	{
		.name = "led1:green",	/* FIXME */
		.gpio = PCM027_LED_HEARD_BEAT
	},
};

static struct gpio_led_platform_data pcm027_led_data = {
	.num_leds	= ARRAY_SIZE(pcm027_led),
	.leds		= pcm027_led
};

static struct platform_device pcm027_led_dev = {
	.name		= "leds-gpio",
	.id		= 0,
	.dev		= {
		.platform_data	= &pcm027_led_data,
	},
};

#endif /* CONFIG_LEDS_GPIO */

/*
 * declare the available device resources on this board
 */
static struct platform_device *devices[] __initdata = {
	&smc91x_device,
	&pcm027_flash,
#ifdef CONFIG_LEDS_GPIO
	&pcm027_led_dev
#endif
};

/*
 * pcm027_init - breath some life into the board
 */
static void __init pcm027_init(void)
{
	/* system bus arbiter setting
	 * - Core_Park
	 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
	 */
	ARB_CNTRL = ARB_CORE_PARK | 0x234;

	pxa2xx_mfp_config(pcm027_pin_config, ARRAY_SIZE(pcm027_pin_config));

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

	platform_add_devices(devices, ARRAY_SIZE(devices));

	/* at last call the baseboard to initialize itself */
#ifdef CONFIG_MACH_PCM990_BASEBOARD
	pcm990_baseboard_init();
#endif

	pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
}

static void __init pcm027_map_io(void)
{
	pxa27x_map_io();

	/* initialize sleep mode regs (wake-up sources, etc) */
	PGSR0 = 0x01308000;
	PGSR1 = 0x00CF0002;
	PGSR2 = 0x0E294000;
	PGSR3 = 0x0000C000;
	PWER  = 0x40000000 | PWER_GPIO0 | PWER_GPIO1;
	PRER  = 0x00000000;
	PFER  = 0x00000003;
}

MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
	/* Maintainer: Pengutronix */
	.atag_offset	= 0x100,
	.map_io		= pcm027_map_io,
	.nr_irqs	= PCM027_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= pcm027_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * arch/arm/mach-pxa/include/mach/pcm027.h
 *
 * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
 * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
 */

/*
 * Definitions of CPU card resources only
 */

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

/* phyCORE-PXA270 (PCM027) Interrupts */
#define PCM027_IRQ(x)          (IRQ_BOARD_START + (x))
#define PCM027_BTDET_IRQ       PCM027_IRQ(0)
#define PCM027_FF_RI_IRQ       PCM027_IRQ(1)
#define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
#define PCM027_PM_5V_IRQ       PCM027_IRQ(3)

#define PCM027_NR_IRQS		(IRQ_BOARD_START + 32)

/* I2C RTC */
#define PCM027_RTC_IRQ_GPIO	0
#define PCM027_RTC_IRQ		PXA_GPIO_TO_IRQ(PCM027_RTC_IRQ_GPIO)
#define PCM027_RTC_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING
#define ADR_PCM027_RTC		0x51	/* I2C address */

/* I2C EEPROM */
#define ADR_PCM027_EEPROM	0x54	/* I2C address */

/* Ethernet chip (SMSC91C111) */
#define PCM027_ETH_IRQ_GPIO	52
#define PCM027_ETH_IRQ		PXA_GPIO_TO_IRQ(PCM027_ETH_IRQ_GPIO)
#define PCM027_ETH_IRQ_EDGE	IRQ_TYPE_EDGE_RISING
#define PCM027_ETH_PHYS		PXA_CS5_PHYS
#define PCM027_ETH_SIZE		(1*1024*1024)

/* CAN controller SJA1000 (unsupported yet) */
#define PCM027_CAN_IRQ_GPIO	114
#define PCM027_CAN_IRQ		PXA_GPIO_TO_IRQ(PCM027_CAN_IRQ_GPIO)
#define PCM027_CAN_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING
#define PCM027_CAN_PHYS		0x22000000
#define PCM027_CAN_SIZE		0x100

/* SPI GPIO expander (unsupported yet) */
#define PCM027_EGPIO_IRQ_GPIO	27
#define PCM027_EGPIO_IRQ	PXA_GPIO_TO_IRQ(PCM027_EGPIO_IRQ_GPIO)
#define PCM027_EGPIO_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING
#define PCM027_EGPIO_CS		24
/*
 * TODO: Switch this pin from dedicated usage to GPIO if
 * more than the MAX7301 device is connected to this SPI bus
 */
#define PCM027_EGPIO_CS_MODE	GPIO24_SFRM_MD

/* Flash memory */
#define PCM027_FLASH_PHYS	0x00000000
#define PCM027_FLASH_SIZE	0x02000000

/* onboard LEDs connected to GPIO */
#define PCM027_LED_CPU		90
#define PCM027_LED_HEARD_BEAT	91

/*
 * This CPU module needs a baseboard to work. After basic initializing
 * its own devices, it calls baseboard's init function.
 * TODO: Add your own basebaord init function and call it from
 * inside pcm027_init(). This example here is for the developmen board.
 * Refer pcm990-baseboard.c
 */
extern void pcm990_baseboard_init(void);


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  arch/arm/mach-pxa/pcm990-baseboard.c
 *  Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
 *
 *  Refer
 *   http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
 *  for additional hardware info
 *
 *  Author:	Juergen Kilb
 *  Created:	April 05, 2005
 *  Copyright:	Phytec Messtechnik GmbH
 *  e-Mail:	armlinux@phytec.de
 *
 *  based on Intel Mainstone Board
 *
 *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
 */
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.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/usb-ohci-pxa27x.h>
#include "pcm990_baseboard.h"
#include <linux/platform_data/video-pxafb.h>

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

static unsigned long pcm990_pin_config[] __initdata = {
	/* MMC */
	GPIO32_MMC_CLK,
	GPIO112_MMC_CMD,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	/* USB */
	GPIO88_USBH1_PWR,
	GPIO89_USBH1_PEN,
	/* PWM0 */
	GPIO16_PWM0_OUT,

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,

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

static void __iomem *pcm990_cpld_base;

static u8 pcm990_cpld_readb(unsigned int reg)
{
	return readb(pcm990_cpld_base + reg);
}

static void pcm990_cpld_writeb(u8 value, unsigned int reg)
{
	writeb(value, pcm990_cpld_base + reg);
}

/*
 * pcm990_lcd_power - control power supply to the LCD
 * @on: 0 = switch off, 1 = switch on
 *
 * Called by the pxafb driver
 */
#ifndef CONFIG_PCM990_DISPLAY_NONE
static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
{
	if (on) {
		/* enable LCD-Latches
		 * power on LCD
		 */
		pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
				PCM990_CTRL_REG3);
	} else {
		/* disable LCD-Latches
		 * power off LCD
		 */
		pcm990_cpld_writeb(0, PCM990_CTRL_REG3);
	}
}
#endif

#if defined(CONFIG_PCM990_DISPLAY_SHARP)
static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = {
	.pixclock		= 28000,
	.xres			= 640,
	.yres			= 480,
	.bpp			= 16,
	.hsync_len		= 20,
	.left_margin		= 103,
	.right_margin		= 47,
	.vsync_len		= 6,
	.upper_margin		= 28,
	.lower_margin		= 5,
	.sync			= 0,
	.cmap_greyscale		= 0,
};

static struct pxafb_mach_info pcm990_fbinfo __initdata = {
	.modes			= &fb_info_sharp_lq084v1dg21,
	.num_modes		= 1,
	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
	.pxafb_lcd_power	= pcm990_lcd_power,
};
#elif defined(CONFIG_PCM990_DISPLAY_NEC)
struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = {
	.pixclock		= 39720,
	.xres			= 640,
	.yres			= 480,
	.bpp			= 16,
	.hsync_len		= 32,
	.left_margin		= 16,
	.right_margin		= 48,
	.vsync_len		= 2,
	.upper_margin		= 12,
	.lower_margin		= 17,
	.sync			= 0,
	.cmap_greyscale		= 0,
};

static struct pxafb_mach_info pcm990_fbinfo __initdata = {
	.modes			= &fb_info_nec_nl6448bc20_18d,
	.num_modes		= 1,
	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
	.pxafb_lcd_power	= pcm990_lcd_power,
};
#endif

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

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

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

/*
 * The PCM-990 development baseboard uses PCM-027's hardware in the
 * following way:
 *
 * - LCD support is in use
 *  - GPIO16 is output for back light on/off with PWM
 *  - GPIO58 ... GPIO73 are outputs for display data
 *  - GPIO74 is output output for LCDFCLK
 *  - GPIO75 is output for LCDLCLK
 *  - GPIO76 is output for LCDPCLK
 *  - GPIO77 is output for LCDBIAS
 * - MMC support is in use
 *  - GPIO32 is output for MMCCLK
 *  - GPIO92 is MMDAT0
 *  - GPIO109 is MMDAT1
 *  - GPIO110 is MMCS0
 *  - GPIO111 is MMCS1
 *  - GPIO112 is MMCMD
 * - IDE/CF card is in use
 *  - GPIO48 is output /POE
 *  - GPIO49 is output /PWE
 *  - GPIO50 is output /PIOR
 *  - GPIO51 is output /PIOW
 *  - GPIO54 is output /PCE2
 *  - GPIO55 is output /PREG
 *  - GPIO56 is input /PWAIT
 *  - GPIO57 is output /PIOS16
 *  - GPIO79 is output PSKTSEL
 *  - GPIO85 is output /PCE1
 * - FFUART is in use
 *  - GPIO34 is input FFRXD
 *  - GPIO35 is input FFCTS
 *  - GPIO36 is input FFDCD
 *  - GPIO37 is input FFDSR
 *  - GPIO38 is input FFRI
 *  - GPIO39 is output FFTXD
 *  - GPIO40 is output FFDTR
 *  - GPIO41 is output FFRTS
 * - BTUART is in use
 *  - GPIO42 is input BTRXD
 *  - GPIO43 is output BTTXD
 *  - GPIO44 is input BTCTS
 *  - GPIO45 is output BTRTS
 * - IRUART is in use
 *  - GPIO46 is input STDRXD
 *  - GPIO47 is output STDTXD
 * - AC97 is in use*)
 *  - GPIO28 is input AC97CLK
 *  - GPIO29 is input AC97DatIn
 *  - GPIO30 is output AC97DatO
 *  - GPIO31 is output AC97SYNC
 *  - GPIO113 is output AC97_RESET
 * - SSP is in use
 *  - GPIO23 is output SSPSCLK
 *  - GPIO24 is output chip select to Max7301
 *  - GPIO25 is output SSPTXD
 *  - GPIO26 is input SSPRXD
 *  - GPIO27 is input for Max7301 IRQ
 *  - GPIO53 is input SSPSYSCLK
 * - SSP3 is in use
 *  - GPIO81 is output SSPTXD3
 *  - GPIO82 is input SSPRXD3
 *  - GPIO83 is output SSPSFRM
 *  - GPIO84 is output SSPCLK3
 *
 * Otherwise claimed GPIOs:
 * GPIO1 -> IRQ from user switch
 * GPIO9 -> IRQ from power management
 * GPIO10 -> IRQ from WML9712 AC97 controller
 * GPIO11 -> IRQ from IDE controller
 * GPIO12 -> IRQ from CF controller
 * GPIO13 -> IRQ from CF controller
 * GPIO14 -> GPIO free
 * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
 * GPIO19 -> GPIO free
 * GPIO20 -> /SDCS2
 * GPIO21 -> /CS3 PC card socket select
 * GPIO33 -> /CS5  network controller select
 * GPIO78 -> /CS2  (16 bit wide data path)
 * GPIO80 -> /CS4  (16 bit wide data path)
 * GPIO86 -> GPIO free
 * GPIO87 -> GPIO free
 * GPIO90 -> LED0 on CPU module
 * GPIO91 -> LED1 on CPI module
 * GPIO117 -> SCL
 * GPIO118 -> SDA
 */

static unsigned long pcm990_irq_enabled;

static void pcm990_mask_ack_irq(struct irq_data *d)
{
	int pcm990_irq = (d->irq - PCM027_IRQ(0));

	pcm990_irq_enabled &= ~(1 << pcm990_irq);

	pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
}

static void pcm990_unmask_irq(struct irq_data *d)
{
	int pcm990_irq = (d->irq - PCM027_IRQ(0));
	u8 val;

	/* the irq can be acknowledged only if deasserted, so it's done here */

	pcm990_irq_enabled |= (1 << pcm990_irq);

	val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
	val |= 1 << pcm990_irq;
	pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR);

	pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
}

static struct irq_chip pcm990_irq_chip = {
	.irq_mask_ack	= pcm990_mask_ack_irq,
	.irq_unmask	= pcm990_unmask_irq,
};

static void pcm990_irq_handler(struct irq_desc *desc)
{
	unsigned int irq;
	unsigned long pending;

	pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
	pending &= pcm990_irq_enabled;

	do {
		/* clear our parent IRQ */
		desc->irq_data.chip->irq_ack(&desc->irq_data);
		if (likely(pending)) {
			irq = PCM027_IRQ(0) + __ffs(pending);
			generic_handle_irq(irq);
		}
		pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
		pending &= pcm990_irq_enabled;
	} while (pending);
}

static void __init pcm990_init_irq(void)
{
	int irq;

	/* setup extra PCM990 irqs */
	for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
		irq_set_chip_and_handler(irq, &pcm990_irq_chip,
					 handle_level_irq);
		irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
	}

	/* disable all Interrupts */
	pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA);
	pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR);

	irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
	irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
}

static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
			void *data)
{
	int err;

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

	return err;
}

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

	val = pcm990_cpld_readb(PCM990_CTRL_REG5);

	if ((1 << vdd) & p_d->ocr_mask)
		val |= PCM990_CTRL_MMC2PWR;
	else
		val &= ~PCM990_CTRL_MMC2PWR;

	pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
	return 0;
}

static void pcm990_mci_exit(struct device *dev, void *data)
{
	free_irq(PCM027_MMCDET_IRQ, data);
}

#define MSECS_PER_JIFFY (1000/HZ)

static struct pxamci_platform_data pcm990_mci_platform_data = {
	.detect_delay_ms	= 250,
	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
	.init 			= pcm990_mci_init,
	.setpower 		= pcm990_mci_setpower,
	.exit			= pcm990_mci_exit,
};

static struct pxaohci_platform_data pcm990_ohci_platform_data = {
	.port_mode	= PMM_PERPORT_MODE,
	.flags		= ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
	.power_on_delay	= 10,
};

/*
 * system init for baseboard usage. Will be called by pcm027 init.
 *
 * Add platform devices present on this baseboard and init
 * them from CPU side as far as required to use them later on
 */
void __init pcm990_baseboard_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));

	pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE);
	if (!pcm990_cpld_base) {
		pr_err("pcm990: failed to ioremap cpld\n");
		return;
	}

	/* register CPLD's IRQ controller */
	pcm990_init_irq();

#ifndef CONFIG_PCM990_DISPLAY_NONE
	pxa_set_fb_info(NULL, &pcm990_fbinfo);
#endif
	pwm_add_table(pcm990_pwm_lookup, ARRAY_SIZE(pcm990_pwm_lookup));
	platform_device_register(&pcm990_backlight_device);

	/* MMC */
	pxa_set_mci_info(&pcm990_mci_platform_data);

	/* USB host */
	pxa_set_ohci_info(&pcm990_ohci_platform_data);

	pxa_set_i2c_info(NULL);
	pxa_set_ac97_info(NULL);

	printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
}


code:
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
 *
 * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
 * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
 */

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

/*
 * definitions relevant only when the PCM-990
 * development base board is in use
 */

/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
#define PCM990_CTRL_INT_IRQ_GPIO	9
#define PCM990_CTRL_INT_IRQ		PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO)
#define PCM990_CTRL_INT_IRQ_EDGE	IRQ_TYPE_EDGE_RISING
#define PCM990_CTRL_PHYS		PXA_CS1_PHYS	/* 16-Bit */
#define PCM990_CTRL_SIZE		(1*1024*1024)

#define PCM990_CTRL_PWR_IRQ_GPIO	14
#define PCM990_CTRL_PWR_IRQ		PXA_GPIO_TO_IRQ(PCM990_CTRL_PWR_IRQ_GPIO)
#define PCM990_CTRL_PWR_IRQ_EDGE	IRQ_TYPE_EDGE_RISING

/* visible CPLD (U7) registers */
#define PCM990_CTRL_REG0	0x0000	/* RESET REGISTER */
#define PCM990_CTRL_SYSRES	0x0001	/* System RESET REGISTER */
#define PCM990_CTRL_RESOUT	0x0002	/* RESETOUT Enable REGISTER */
#define PCM990_CTRL_RESGPIO	0x0004	/* RESETGPIO Enable REGISTER */

#define PCM990_CTRL_REG1	0x0002	/* Power REGISTER */
#define PCM990_CTRL_5VOFF	0x0001	/* Disable  5V Regulators */
#define PCM990_CTRL_CANPWR	0x0004	/* Enable CANPWR ADUM */
#define PCM990_CTRL_PM_5V	0x0008	/* Read 5V OK */

#define PCM990_CTRL_REG2	0x0004	/* LED REGISTER */
#define PCM990_CTRL_LEDPWR	0x0001	/* POWER LED enable */
#define PCM990_CTRL_LEDBAS	0x0002	/* BASIS LED enable */
#define PCM990_CTRL_LEDUSR	0x0004	/* USER LED enable */

#define PCM990_CTRL_REG3	0x0006	/* LCD CTRL REGISTER 3 */
#define PCM990_CTRL_LCDPWR	0x0001	/* RW LCD Power on */
#define PCM990_CTRL_LCDON	0x0002	/* RW LCD Latch on */
#define PCM990_CTRL_LCDPOS1	0x0004	/* RW POS 1 */
#define PCM990_CTRL_LCDPOS2	0x0008	/* RW POS 2 */

#define PCM990_CTRL_REG4	0x0008	/* MMC1 CTRL REGISTER 4 */
#define PCM990_CTRL_MMC1PWR	0x0001 /* RW MMC1 Power on */

#define PCM990_CTRL_REG5	0x000A	/* MMC2 CTRL REGISTER 5 */
#define PCM990_CTRL_MMC2PWR	0x0001	/* RW MMC2 Power on */
#define PCM990_CTRL_MMC2LED	0x0002	/* RW MMC2 LED */
#define PCM990_CTRL_MMC2DE	0x0004	/* R MMC2 Card detect */
#define PCM990_CTRL_MMC2WP	0x0008	/* R MMC2 Card write protect */

#define PCM990_CTRL_INTSETCLR	0x000C	/* Interrupt Clear REGISTER */
#define PCM990_CTRL_INTC0	0x0001	/* Clear Reg BT Detect */
#define PCM990_CTRL_INTC1	0x0002	/* Clear Reg FR RI */
#define PCM990_CTRL_INTC2	0x0004	/* Clear Reg MMC1 Detect */
#define PCM990_CTRL_INTC3	0x0008	/* Clear Reg PM_5V off */

#define PCM990_CTRL_INTMSKENA	0x000E	/* Interrupt Enable REGISTER */
#define PCM990_CTRL_ENAINT0	0x0001	/* Enable Int BT Detect */
#define PCM990_CTRL_ENAINT1	0x0002	/* Enable Int FR RI */
#define PCM990_CTRL_ENAINT2	0x0004	/* Enable Int MMC1 Detect */
#define PCM990_CTRL_ENAINT3	0x0008	/* Enable Int PM_5V off */

#define PCM990_CTRL_REG8	0x0014	/* Uart REGISTER */
#define PCM990_CTRL_FFSD	0x0001	/* BT Uart Enable */
#define PCM990_CTRL_BTSD	0x0002	/* FF Uart Enable */
#define PCM990_CTRL_FFRI	0x0004	/* FF Uart RI detect */
#define PCM990_CTRL_BTRX	0x0008	/* BT Uart Rx detect */

#define PCM990_CTRL_REG9	0x0010	/* AC97 Flash REGISTER */
#define PCM990_CTRL_FLWP	0x0001	/* pC Flash Write Protect */
#define PCM990_CTRL_FLDIS	0x0002	/* pC Flash Disable */
#define PCM990_CTRL_AC97ENA	0x0004	/* Enable AC97 Expansion */

#define PCM990_CTRL_REG10	0x0012	/* GPS-REGISTER */
#define PCM990_CTRL_GPSPWR	0x0004	/* GPS-Modul Power on */
#define PCM990_CTRL_GPSENA	0x0008	/* GPS-Modul Enable */

#define PCM990_CTRL_REG11	0x0014	/* Accu REGISTER */
#define PCM990_CTRL_ACENA	0x0001	/* Charge Enable */
#define PCM990_CTRL_ACSEL	0x0002	/* Charge Akku -> DC Enable */
#define PCM990_CTRL_ACPRES	0x0004	/* DC Present */
#define PCM990_CTRL_ACALARM	0x0008	/* Error Akku */

/*
 * IDE
 */
#define PCM990_IDE_IRQ_GPIO	13
#define PCM990_IDE_IRQ		PXA_GPIO_TO_IRQ(PCM990_IDE_IRQ_GPIO)
#define PCM990_IDE_IRQ_EDGE	IRQ_TYPE_EDGE_RISING
#define PCM990_IDE_PLD_PHYS	0x20000000	/* 16 bit wide */
#define PCM990_IDE_PLD_BASE	0xee000000
#define PCM990_IDE_PLD_SIZE	(1*1024*1024)

/* visible CPLD (U6) registers */
#define PCM990_IDE_PLD_REG0	0x1000	/* OFFSET IDE REGISTER 0 */
#define PCM990_IDE_PM5V		0x0004	/* R System VCC_5V */
#define PCM990_IDE_STBY		0x0008	/* R System StandBy */

#define PCM990_IDE_PLD_REG1	0x1002	/* OFFSET IDE REGISTER 1 */
#define PCM990_IDE_IDEMODE	0x0001	/* R TrueIDE Mode */
#define PCM990_IDE_DMAENA	0x0004	/* RW DMA Enable */
#define PCM990_IDE_DMA1_0	0x0008	/* RW 1=DREQ1 0=DREQ0 */

#define PCM990_IDE_PLD_REG2	0x1004	/* OFFSET IDE REGISTER 2 */
#define PCM990_IDE_RESENA	0x0001	/* RW IDE Reset Bit enable */
#define PCM990_IDE_RES		0x0002	/* RW IDE Reset Bit */
#define PCM990_IDE_RDY		0x0008	/* RDY */

#define PCM990_IDE_PLD_REG3	0x1006	/* OFFSET IDE REGISTER 3 */
#define PCM990_IDE_IDEOE	0x0001	/* RW Latch on Databus */
#define PCM990_IDE_IDEON	0x0002	/* RW Latch on Control Address */
#define PCM990_IDE_IDEIN	0x0004	/* RW Latch on Interrupt usw. */

#define PCM990_IDE_PLD_REG4	0x1008	/* OFFSET IDE REGISTER 4 */
#define PCM990_IDE_PWRENA	0x0001	/* RW IDE Power enable */
#define PCM990_IDE_5V		0x0002	/* R IDE Power 5V */
#define PCM990_IDE_PWG		0x0008	/* R IDE Power is on */

#define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
#define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)

/*
 * Compact Flash
 */
#define PCM990_CF_IRQ_GPIO	11
#define PCM990_CF_IRQ		PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO)
#define PCM990_CF_IRQ_EDGE	IRQ_TYPE_EDGE_RISING

#define PCM990_CF_CD_GPIO	12
#define PCM990_CF_CD		PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO)
#define PCM990_CF_CD_EDGE	IRQ_TYPE_EDGE_RISING

#define PCM990_CF_PLD_PHYS	0x30000000	/* 16 bit wide */

/* visible CPLD (U6) registers */
#define PCM990_CF_PLD_REG0	0x1000	/* OFFSET CF REGISTER 0 */
#define PCM990_CF_REG0_LED	0x0001	/* RW LED on */
#define PCM990_CF_REG0_BLK	0x0002	/* RW LED flash when access */
#define PCM990_CF_REG0_PM5V	0x0004	/* R System VCC_5V enable */
#define PCM990_CF_REG0_STBY	0x0008	/* R System StandBy */

#define PCM990_CF_PLD_REG1	0x1002	/* OFFSET CF REGISTER 1 */
#define PCM990_CF_REG1_IDEMODE	0x0001	/* RW CF card run as TrueIDE */
#define PCM990_CF_REG1_CF0	0x0002	/* RW CF card at ADDR 0x28000000 */

#define PCM990_CF_PLD_REG2	0x1004	/* OFFSET CF REGISTER 2 */
#define PCM990_CF_REG2_RES	0x0002	/* RW CF RESET BIT */
#define PCM990_CF_REG2_RDYENA	0x0004	/* RW Enable CF_RDY */
#define PCM990_CF_REG2_RDY	0x0008	/* R CF_RDY auf PWAIT */

#define PCM990_CF_PLD_REG3	0x1006	/* OFFSET CF REGISTER 3 */
#define PCM990_CF_REG3_CFOE	0x0001	/* RW Latch on Databus */
#define PCM990_CF_REG3_CFON	0x0002	/* RW Latch on Control Address */
#define PCM990_CF_REG3_CFIN	0x0004	/* RW Latch on Interrupt usw. */
#define PCM990_CF_REG3_CFCD	0x0008	/* RW Latch on CD1/2 VS1/2 usw */

#define PCM990_CF_PLD_REG4	0x1008	/* OFFSET CF REGISTER 4 */
#define PCM990_CF_REG4_PWRENA	0x0001	/* RW CF Power on (CD1/2 = "00") */
#define PCM990_CF_REG4_5_3V	0x0002	/* RW 1 = 5V CF_VCC 0 = 3 V CF_VCC */
#define PCM990_CF_REG4_3B	0x0004	/* RW 3.0V Backup from VCC (5_3V=0) */
#define PCM990_CF_REG4_PWG	0x0008	/* R CF-Power is on */

#define PCM990_CF_PLD_REG5	0x100A	/* OFFSET CF REGISTER 5 */
#define PCM990_CF_REG5_BVD1	0x0001	/* R CF /BVD1 */
#define PCM990_CF_REG5_BVD2	0x0002	/* R CF /BVD2 */
#define PCM990_CF_REG5_VS1	0x0004	/* R CF /VS1 */
#define PCM990_CF_REG5_VS2	0x0008	/* R CF /VS2 */

#define PCM990_CF_PLD_REG6	0x100C	/* OFFSET CF REGISTER 6 */
#define PCM990_CF_REG6_CD1	0x0001	/* R CF Card_Detect1 */
#define PCM990_CF_REG6_CD2	0x0002	/* R CF Card_Detect2 */

/*
 * Wolfson AC97 Touch
 */
#define PCM990_AC97_IRQ_GPIO	10
#define PCM990_AC97_IRQ		PXA_GPIO_TO_IRQ(PCM990_AC97_IRQ_GPIO)
#define PCM990_AC97_IRQ_EDGE	IRQ_TYPE_EDGE_RISING

/*
 * MMC phyCORE
 */
#define PCM990_MMC0_IRQ_GPIO	9
#define PCM990_MMC0_IRQ		PXA_GPIO_TO_IRQ(PCM990_MMC0_IRQ_GPIO)
#define PCM990_MMC0_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING

/*
 * USB phyCore
 */
#define PCM990_USB_OVERCURRENT (88 | GPIO_ALT_FN_1_IN)
#define PCM990_USB_PWR_EN (89 | GPIO_ALT_FN_2_OUT)


code:
/*
 * PXA250/210 Power Management Routines
 *
 * Original code for the SA11x0:
 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
 *
 * Modified for the PXA250 by Nicolas Pitre:
 * Copyright (c) 2002 Monta Vista Software, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License.
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/slab.h>

#include "pm.h"

struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
static unsigned long *sleep_save;

int pxa_pm_enter(suspend_state_t state)
{
	unsigned long sleep_save_checksum = 0, checksum = 0;
	int i;

#ifdef CONFIG_IWMMXT
	/* force any iWMMXt context to ram **/
	if (elf_hwcap & HWCAP_IWMMXT)
		iwmmxt_task_disable(NULL);
#endif

	/* skip registers saving for standby */
	if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) {
		pxa_cpu_pm_fns->save(sleep_save);
		/* before sleeping, calculate and save a checksum */
		for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
			sleep_save_checksum += sleep_save[i];
	}

	/* *** go zzz *** */
	pxa_cpu_pm_fns->enter(state);

	if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) {
		/* after sleeping, validate the checksum */
		for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
			checksum += sleep_save[i];

		/* if invalid, display message and wait for a hardware reset */
		if (checksum != sleep_save_checksum) {

			lubbock_set_hexled(0xbadbadc5);

			while (1)
				pxa_cpu_pm_fns->enter(state);
		}
		pxa_cpu_pm_fns->restore(sleep_save);
	}

	pr_debug("*** made it back from resume\n");

	return 0;
}

EXPORT_SYMBOL_GPL(pxa_pm_enter);

static int pxa_pm_valid(suspend_state_t state)
{
	if (pxa_cpu_pm_fns)
		return pxa_cpu_pm_fns->valid(state);

	return -EINVAL;
}

int pxa_pm_prepare(void)
{
	int ret = 0;

	if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->prepare)
		ret = pxa_cpu_pm_fns->prepare();

	return ret;
}

void pxa_pm_finish(void)
{
	if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish)
		pxa_cpu_pm_fns->finish();
}

static const struct platform_suspend_ops pxa_pm_ops = {
	.valid		= pxa_pm_valid,
	.enter		= pxa_pm_enter,
	.prepare	= pxa_pm_prepare,
	.finish		= pxa_pm_finish,
};

static int __init pxa_pm_init(void)
{
	if (!pxa_cpu_pm_fns) {
		printk(KERN_ERR "no valid pxa_cpu_pm_fns defined\n");
		return -EINVAL;
	}

	sleep_save = kmalloc_array(pxa_cpu_pm_fns->save_count,
				   sizeof(*sleep_save),
				   GFP_KERNEL);
	if (!sleep_save)
		return -ENOMEM;

	suspend_set_ops(&pxa_pm_ops);
	return 0;
}

device_initcall(pxa_pm_init);


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2005 Richard Purdie
 */

#include <linux/suspend.h>

struct pxa_cpu_pm_fns {
	int	save_count;
	void	(*save)(unsigned long *);
	void	(*restore)(unsigned long *);
	int	(*valid)(suspend_state_t state);
	void	(*enter)(suspend_state_t state);
	int	(*prepare)(void);
	void	(*finish)(void);
};

extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;

/* sleep.S */
extern int pxa25x_finish_suspend(unsigned long);
extern int pxa27x_finish_suspend(unsigned long);

extern int pxa_pm_enter(suspend_state_t state);
extern int pxa_pm_prepare(void);
extern void pxa_pm_finish(void);

extern const char pm_enter_standby_start[], pm_enter_standby_end[];
extern int pxa3xx_finish_suspend(unsigned long);

/* NOTE: this is for PM debugging on Lubbock,  it's really a big
 * ugly, but let's keep the crap minimum here, instead of direct
 * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c
 */
#ifdef CONFIG_ARCH_LUBBOCK
extern void lubbock_set_hexled(uint32_t value);
#else
#define lubbock_set_hexled(x)
#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-pxa/poodle.c
 *
 *  Support for the SHARP Poodle Board.
 *
 * Based on:
 *  linux/arch/arm/mach-pxa/lubbock.c Author:	Nicolas Pitre
 *
 * Change Log
 *  12-Dec-2002 Sharp Corporation for Poodle
 *  John Lenz <lenz@cs.wisc.edu> updates to 2.6
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/i2c.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/mtd/sharpsl.h>
#include <linux/memblock.h>

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

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

#include "pxa25x.h"
#include "udc.h"
#include "poodle.h"

#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/asoc-poodle.h>

#include <asm/hardware/scoop.h>
#include <asm/hardware/locomo.h>
#include <asm/mach/sharpsl_param.h>

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

static unsigned long poodle_pin_config[] __initdata = {
	/* I/O */
	GPIO79_nCS_3,
	GPIO80_nCS_4,
	GPIO18_RDY,

	/* Clock */
	GPIO12_32KHz,

	/* SSP1 */
	GPIO23_SSP1_SCLK,
	GPIO25_SSP1_TXD,
	GPIO26_SSP1_RXD,
	GPIO24_GPIO,	/* POODLE_GPIO_TP_CS - SFRM as chip select */

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

	/* Infra-Red */
	GPIO47_FICP_TXD,
	GPIO46_FICP_RXD,

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

	/* LCD */
	GPIOxx_LCD_TFT_16BPP,

	/* PC Card */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO52_nPCE_1,
	GPIO53_nPCE_2,
	GPIO54_nPSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,

	/* MMC */
	GPIO6_MMC_CLK,
	GPIO8_MMC_CS0,

	/* GPIO */
	GPIO9_GPIO,	/* POODLE_GPIO_nSD_DETECT */
	GPIO7_GPIO,	/* POODLE_GPIO_nSD_WP */
	GPIO3_GPIO,	/* POODLE_GPIO_SD_PWR */
	GPIO33_GPIO,	/* POODLE_GPIO_SD_PWR1 */

	GPIO20_GPIO,	/* POODLE_GPIO_USB_PULLUP */
	GPIO22_GPIO,	/* POODLE_GPIO_IR_ON */
};

static struct resource poodle_scoop_resources[] = {
	[0] = {
		.start		= 0x10800000,
		.end		= 0x10800fff,
		.flags		= IORESOURCE_MEM,
	},
};

static struct scoop_config poodle_scoop_setup = {
	.io_dir		= POODLE_SCOOP_IO_DIR,
	.io_out		= POODLE_SCOOP_IO_OUT,
	.gpio_base	= POODLE_SCOOP_GPIO_BASE,
};

struct platform_device poodle_scoop_device = {
	.name		= "sharp-scoop",
	.id		= -1,
	.dev		= {
		.platform_data	= &poodle_scoop_setup,
	},
	.num_resources	= ARRAY_SIZE(poodle_scoop_resources),
	.resource	= poodle_scoop_resources,
};

static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
{
	.dev        = &poodle_scoop_device.dev,
	.irq        = POODLE_IRQ_GPIO_CF_IRQ,
	.cd_irq     = POODLE_IRQ_GPIO_CF_CD,
	.cd_irq_str = "PCMCIA0 CD",
},
};

static struct scoop_pcmcia_config poodle_pcmcia_config = {
	.devs         = &poodle_pcmcia_scoop[0],
	.num_devs     = 1,
};

EXPORT_SYMBOL(poodle_scoop_device);

/* LoCoMo device */
static struct resource locomo_resources[] = {
	[0] = {
		.start		= 0x10000000,
		.end		= 0x10001fff,
		.flags		= IORESOURCE_MEM,
	},
	[1] = {
		.start		= PXA_GPIO_TO_IRQ(10),
		.end		= PXA_GPIO_TO_IRQ(10),
		.flags		= IORESOURCE_IRQ,
	},
};

static struct locomo_platform_data locomo_info = {
	.irq_base	= IRQ_BOARD_START,
};

static struct platform_device poodle_locomo_device = {
	.name		= "locomo",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(locomo_resources),
	.resource	= locomo_resources,
	.dev		= {
		.platform_data	= &locomo_info,
	},
};

static struct poodle_audio_platform_data poodle_audio_pdata = {
	.locomo_dev	= &poodle_locomo_device.dev,

	.gpio_amp_on   	= POODLE_LOCOMO_GPIO_AMP_ON,
	.gpio_mute_l   	= POODLE_LOCOMO_GPIO_MUTE_L,
	.gpio_mute_r   	= POODLE_LOCOMO_GPIO_MUTE_R,
	.gpio_232vcc_on	= POODLE_LOCOMO_GPIO_232VCC_ON,
	.gpio_jk_b     	= POODLE_LOCOMO_GPIO_JK_B,
};

static struct platform_device poodle_audio_device = {
	.name	= "poodle-audio",
	.id	= -1,
	.dev.platform_data = &poodle_audio_pdata,
};

#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
static struct pxa2xx_spi_controller poodle_spi_info = {
	.num_chipselect	= 1,
};

static struct gpiod_lookup_table poodle_spi_gpio_table = {
	.dev_id = "pxa2xx-spi.1",
	.table = {
		GPIO_LOOKUP_IDX("gpio-pxa", POODLE_GPIO_TP_CS, "cs", 0, GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct ads7846_platform_data poodle_ads7846_info = {
	.model			= 7846,
	.vref_delay_usecs	= 100,
	.x_plate_ohms		= 419,
	.y_plate_ohms		= 486,
	.gpio_pendown		= POODLE_GPIO_TP_INT,
};

static struct spi_board_info poodle_spi_devices[] = {
	{
		.modalias	= "ads7846",
		.max_speed_hz	= 10000,
		.bus_num	= 1,
		.platform_data	= &poodle_ads7846_info,
		.irq		= PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
	},
};

static void __init poodle_init_spi(void)
{
	gpiod_add_lookup_table(&poodle_spi_gpio_table);
	pxa2xx_set_spi_info(1, &poodle_spi_info);
	spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
}
#else
static inline void poodle_init_spi(void) {}
#endif

/*
 * MMC/SD Device
 *
 * The card detect interrupt isn't debounced so we delay it by 250ms
 * to give the card a chance to fully insert/eject.
 */
static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data)
{
	int err;

	err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR");
	if (err)
		goto err_free_2;

	err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1");
	if (err)
		goto err_free_3;

	gpio_direction_output(POODLE_GPIO_SD_PWR, 0);
	gpio_direction_output(POODLE_GPIO_SD_PWR1, 0);

	return 0;

err_free_3:
	gpio_free(POODLE_GPIO_SD_PWR);
err_free_2:
	return err;
}

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

	if ((1 << vdd) & p_d->ocr_mask) {
		gpio_set_value(POODLE_GPIO_SD_PWR, 1);
		mdelay(2);
		gpio_set_value(POODLE_GPIO_SD_PWR1, 1);
	} else {
		gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
		gpio_set_value(POODLE_GPIO_SD_PWR, 0);
	}

	return 0;
}

static void poodle_mci_exit(struct device *dev, void *data)
{
	gpio_free(POODLE_GPIO_SD_PWR1);
	gpio_free(POODLE_GPIO_SD_PWR);
}

static struct pxamci_platform_data poodle_mci_platform_data = {
	.detect_delay_ms	= 250,
	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
	.init 			= poodle_mci_init,
	.setpower 		= poodle_mci_setpower,
	.exit			= poodle_mci_exit,
};

static struct gpiod_lookup_table poodle_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_DETECT,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_WP,
			    "wp", GPIO_ACTIVE_LOW),
		{ },
	},
};

/*
 * Irda
 */
static struct pxaficp_platform_data poodle_ficp_platform_data = {
	.gpio_pwdown		= POODLE_GPIO_IR_ON,
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
};

/*
 * USB Device Controller
 */
static struct pxa2xx_udc_mach_info udc_info __initdata = {
	/* no connect GPIO; poodle can't tell connection status */
	.gpio_pullup	= POODLE_GPIO_USB_PULLUP,
};

/* PXAFB device */
static struct pxafb_mode_info poodle_fb_mode = {
	.pixclock	= 144700,
	.xres		= 320,
	.yres		= 240,
	.bpp		= 16,
	.hsync_len	= 7,
	.left_margin	= 11,
	.right_margin	= 30,
	.vsync_len	= 2,
	.upper_margin	= 2,
	.lower_margin	= 0,
	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
};

static struct pxafb_mach_info poodle_fb_info = {
	.modes		= &poodle_fb_mode,
	.num_modes	= 1,
	.lcd_conn	= LCD_COLOR_TFT_16BPP,
};

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

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

static const char * const probes[] = {
	"cmdlinepart",
	"ofpart",
	"sharpslpart",
	NULL,
};

static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
	.badblock_pattern	= &sharpsl_bbt,
	.part_parsers		= probes,
};

static struct resource sharpsl_nand_resources[] = {
	{
		.start	= 0x0C000000,
		.end	= 0x0C000FFF,
		.flags	= IORESOURCE_MEM,
	},
};

static struct platform_device sharpsl_nand_device = {
	.name		= "sharpsl-nand",
	.id		= -1,
	.resource	= sharpsl_nand_resources,
	.num_resources	= ARRAY_SIZE(sharpsl_nand_resources),
	.dev.platform_data	= &sharpsl_nand_platform_data,
};

static struct mtd_partition sharpsl_rom_parts[] = {
	{
		.name	="Boot PROM Filesystem",
		.offset	= 0x00120000,
		.size	= MTDPART_SIZ_FULL,
	},
};

static struct physmap_flash_data sharpsl_rom_data = {
	.width		= 2,
	.nr_parts	= ARRAY_SIZE(sharpsl_rom_parts),
	.parts		= sharpsl_rom_parts,
};

static struct resource sharpsl_rom_resources[] = {
	{
		.start	= 0x00000000,
		.end	= 0x007fffff,
		.flags	= IORESOURCE_MEM,
	},
};

static struct platform_device sharpsl_rom_device = {
	.name	= "physmap-flash",
	.id	= -1,
	.resource = sharpsl_rom_resources,
	.num_resources = ARRAY_SIZE(sharpsl_rom_resources),
	.dev.platform_data = &sharpsl_rom_data,
};

static struct platform_device *devices[] __initdata = {
	&poodle_locomo_device,
	&poodle_scoop_device,
	&poodle_audio_device,
	&sharpsl_nand_device,
	&sharpsl_rom_device,
};

static struct i2c_board_info __initdata poodle_i2c_devices[] = {
	{ I2C_BOARD_INFO("wm8731", 0x1b) },
};

static void poodle_poweroff(void)
{
	pxa_restart(REBOOT_HARD, NULL);
}

static void __init poodle_init(void)
{
	int ret = 0;

	pm_power_off = poodle_poweroff;

	PCFR |= PCFR_OPDE;

	pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config));

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

	platform_scoop_config = &poodle_pcmcia_config;

	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
	if (ret)
		pr_warn("poodle: Unable to register LoCoMo device\n");

	pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
	pxa_set_udc_info(&udc_info);
	gpiod_add_lookup_table(&poodle_mci_gpio_table);
	pxa_set_mci_info(&poodle_mci_platform_data);
	pxa_set_ficp_info(&poodle_ficp_platform_data);
	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
	poodle_init_spi();
	regulator_has_full_constraints();
}

static void __init fixup_poodle(struct tag *tags, char **cmdline)
{
	sharpsl_save_param();
	memblock_add(0xa0000000, SZ_32M);
}

MACHINE_START(POODLE, "SHARP Poodle")
	.fixup		= fixup_poodle,
	.map_io		= pxa25x_map_io,
	.nr_irqs	= POODLE_NR_IRQS,	/* 4 for LoCoMo */
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= poodle_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/*
 * arch/arm/mach-pxa/include/mach/poodle.h
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.
 *
 * Based on:
 *   arch/arm/mach-sa1100/include/mach/collie.h
 *
 * ChangeLog:
 *   04-06-2001 Lineo Japan, Inc.
 *   04-16-2001 SHARP Corporation
 *   Update to 2.6 John Lenz
 */
#ifndef __ASM_ARCH_POODLE_H
#define __ASM_ARCH_POODLE_H  1

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

/*
 * GPIOs
 */
/* PXA GPIOs */
#define POODLE_GPIO_ON_KEY		(0)
#define POODLE_GPIO_AC_IN		(1)
#define POODLE_GPIO_CO			16
#define POODLE_GPIO_TP_INT		(5)
#define POODLE_GPIO_TP_CS		(24)
#define POODLE_GPIO_WAKEUP		(11)	/* change battery */
#define POODLE_GPIO_GA_INT		(10)
#define POODLE_GPIO_IR_ON		(22)
#define POODLE_GPIO_HP_IN		(4)
#define POODLE_GPIO_CF_IRQ		(17)
#define POODLE_GPIO_CF_CD		(14)
#define POODLE_GPIO_CF_STSCHG		(14)
#define POODLE_GPIO_SD_PWR		(33)
#define POODLE_GPIO_SD_PWR1		(3)
#define POODLE_GPIO_nSD_CLK		(6)
#define POODLE_GPIO_nSD_WP		(7)
#define POODLE_GPIO_nSD_INT		(8)
#define POODLE_GPIO_nSD_DETECT		(9)
#define POODLE_GPIO_MAIN_BAT_LOW	(13)
#define POODLE_GPIO_BAT_COVER		(13)
#define POODLE_GPIO_USB_PULLUP		(20)
#define POODLE_GPIO_ADC_TEMP_ON		(21)
#define POODLE_GPIO_BYPASS_ON		(36)
#define POODLE_GPIO_CHRG_ON		(38)
#define POODLE_GPIO_CHRG_FULL		(16)
#define POODLE_GPIO_DISCHARGE_ON        (42) /* Enable battery discharge */

/* PXA GPIOs */
#define POODLE_IRQ_GPIO_ON_KEY		PXA_GPIO_TO_IRQ(0)
#define POODLE_IRQ_GPIO_AC_IN		PXA_GPIO_TO_IRQ(1)
#define POODLE_IRQ_GPIO_HP_IN		PXA_GPIO_TO_IRQ(4)
#define POODLE_IRQ_GPIO_CO		PXA_GPIO_TO_IRQ(16)
#define POODLE_IRQ_GPIO_TP_INT		PXA_GPIO_TO_IRQ(5)
#define POODLE_IRQ_GPIO_WAKEUP		PXA_GPIO_TO_IRQ(11)
#define POODLE_IRQ_GPIO_GA_INT		PXA_GPIO_TO_IRQ(10)
#define POODLE_IRQ_GPIO_CF_IRQ		PXA_GPIO_TO_IRQ(17)
#define POODLE_IRQ_GPIO_CF_CD		PXA_GPIO_TO_IRQ(14)
#define POODLE_IRQ_GPIO_nSD_INT		PXA_GPIO_TO_IRQ(8)
#define POODLE_IRQ_GPIO_nSD_DETECT	PXA_GPIO_TO_IRQ(9)
#define POODLE_IRQ_GPIO_MAIN_BAT_LOW	PXA_GPIO_TO_IRQ(13)

/* SCOOP GPIOs */
#define POODLE_SCOOP_CHARGE_ON	SCOOP_GPCR_PA11
#define POODLE_SCOOP_CP401	SCOOP_GPCR_PA13
#define POODLE_SCOOP_VPEN	SCOOP_GPCR_PA18
#define POODLE_SCOOP_L_PCLK	SCOOP_GPCR_PA20
#define POODLE_SCOOP_L_LCLK	SCOOP_GPCR_PA21
#define POODLE_SCOOP_HS_OUT	SCOOP_GPCR_PA22

#define POODLE_SCOOP_IO_DIR	( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT )
#define POODLE_SCOOP_IO_OUT	( 0 )

#define POODLE_SCOOP_GPIO_BASE	(PXA_NR_BUILTIN_GPIO)
#define POODLE_GPIO_CHARGE_ON	(POODLE_SCOOP_GPIO_BASE + 0)
#define POODLE_GPIO_CP401	(POODLE_SCOOP_GPIO_BASE + 2)
#define POODLE_GPIO_VPEN	(POODLE_SCOOP_GPIO_BASE + 7)
#define POODLE_GPIO_L_PCLK	(POODLE_SCOOP_GPIO_BASE + 9)
#define POODLE_GPIO_L_LCLK	(POODLE_SCOOP_GPIO_BASE + 10)
#define POODLE_GPIO_HS_OUT	(POODLE_SCOOP_GPIO_BASE + 11)

#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)

#define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */

#endif /* __ASM_ARCH_POODLE_H  */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/pxa-dt.c
 *
 *  Copyright (C) 2012 Daniel Mack
 */

#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include "irqs.h"

#include "generic.h"

#ifdef CONFIG_PXA25x
static const char * const pxa25x_dt_board_compat[] __initconst = {
	"marvell,pxa250",
	NULL,
};

DT_MACHINE_START(PXA25X_DT, "Marvell PXA25x (Device Tree Support)")
	.map_io		= pxa25x_map_io,
	.restart	= pxa_restart,
	.dt_compat	= pxa25x_dt_board_compat,
MACHINE_END
#endif

#ifdef CONFIG_PXA27x
static const char * const pxa27x_dt_board_compat[] __initconst = {
	"marvell,pxa270",
	NULL,
};

DT_MACHINE_START(PXA27X_DT, "Marvell PXA27x (Device Tree Support)")
	.map_io		= pxa27x_map_io,
	.restart	= pxa_restart,
	.dt_compat	= pxa27x_dt_board_compat,
MACHINE_END
#endif

#ifdef CONFIG_PXA3xx
static const char *const pxa3xx_dt_board_compat[] __initconst = {
	"marvell,pxa300",
	"marvell,pxa310",
	"marvell,pxa320",
	NULL,
};

DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)")
	.map_io		= pxa3xx_map_io,
	.restart	= pxa_restart,
	.dt_compat	= pxa3xx_dt_board_compat,
MACHINE_END
#endif