code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Battery and Power Management code for the Sharp SL-Cxx00
 *
 * Copyright (c) 2005 Richard Purdie
 */

#include <linux/module.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/apm-emulation.h>

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

#include "spitz.h"
#include "pxa27x.h"
#include "sharpsl_pm.h"

#include "generic.h"

#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */

static int spitz_last_ac_status;

static struct gpio spitz_charger_gpios[] = {
	{ SPITZ_GPIO_KEY_INT,	GPIOF_IN, "Keyboard Interrupt" },
	{ SPITZ_GPIO_SYNC,	GPIOF_IN, "Sync" },
	{ SPITZ_GPIO_AC_IN,     GPIOF_IN, "Charger Detection" },
	{ SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
	{ SPITZ_GPIO_JK_B,	  GPIOF_OUT_INIT_LOW, "JK B" },
	{ SPITZ_GPIO_CHRG_ON,	  GPIOF_OUT_INIT_LOW, "Charger On" },
};

static void spitz_charger_init(void)
{
	gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
}

static void spitz_measure_temp(int on)
{
	gpio_set_value(SPITZ_GPIO_ADC_TEMP_ON, on);
}

static void spitz_charge(int on)
{
	if (on) {
		if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
			gpio_set_value(SPITZ_GPIO_JK_B, 1);
			gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
		} else {
			gpio_set_value(SPITZ_GPIO_JK_B, 0);
			gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
		}
	} else {
		gpio_set_value(SPITZ_GPIO_JK_B, 0);
		gpio_set_value(SPITZ_GPIO_CHRG_ON, 1);
	}
}

static void spitz_discharge(int on)
{
	gpio_set_value(SPITZ_GPIO_JK_A, on);
}

/* HACK - For unknown reasons, accurate voltage readings are only made with a load
   on the power bus which the green led on spitz provides */
static void spitz_discharge1(int on)
{
	gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
}

static unsigned long gpio18_config = GPIO18_GPIO;

static void spitz_presuspend(void)
{
	spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);

	/* GPIO Sleep Register */
	PGSR0 = 0x00144018;
	PGSR1 = 0x00EF0000;
	if (machine_is_akita()) {
		PGSR2 = 0x2121C000;
		PGSR3 = 0x00600400;
	} else {
		PGSR2 = 0x0121C000;
		PGSR3 = 0x00600000;
	}

	PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
	PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
	PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
	PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
	PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);

	pxa2xx_mfp_config(&gpio18_config, 1);
	gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
	gpio_free(18);

	PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
	PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
	PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
	PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
	PKSR = 0xffffffff; /* clear */

	/* nRESET_OUT Disable */
	PSLR |= PSLR_SL_ROD;

	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
	PCFR = PCFR_GPR_EN | PCFR_OPDE;
}

static void spitz_postsuspend(void)
{
}

static int spitz_should_wakeup(unsigned int resume_on_alarm)
{
	int is_resume = 0;
	int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);

	if (spitz_last_ac_status != acin) {
		if (acin) {
			/* charge on */
			sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
			dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
		} else {
			/* charge off */
			dev_dbg(sharpsl_pm.dev, "AC Removed\n");
			sharpsl_pm_led(SHARPSL_LED_OFF);
			sharpsl_pm.machinfo->charge(0);
			sharpsl_pm.charge_mode = CHRG_OFF;
		}
		spitz_last_ac_status = acin;
		/* Return to suspend as this must be what we were woken for */
		return 0;
	}

	if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
		is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);

	if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
		is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);

	if (resume_on_alarm && (PEDR & PWER_RTC))
		is_resume |= PWER_RTC;

	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n", is_resume);
	return is_resume;
}

static bool spitz_charger_wakeup(void)
{
	return !gpio_get_value(SPITZ_GPIO_KEY_INT) ||
		gpio_get_value(SPITZ_GPIO_SYNC);
}

unsigned long spitzpm_read_devdata(int type)
{
	switch (type) {
	case SHARPSL_STATUS_ACIN:
		return !gpio_get_value(SPITZ_GPIO_AC_IN);
	case SHARPSL_STATUS_LOCK:
		return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock);
	case SHARPSL_STATUS_CHRGFULL:
		return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull);
	case SHARPSL_STATUS_FATAL:
		return gpio_get_value(sharpsl_pm.machinfo->gpio_fatal);
	case SHARPSL_ACIN_VOLT:
		return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT);
	case SHARPSL_BATT_TEMP:
		return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP);
	case SHARPSL_BATT_VOLT:
	default:
		return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT);
	}
}

struct sharpsl_charger_machinfo spitz_pm_machinfo = {
	.init             = spitz_charger_init,
	.exit             = NULL,
	.gpio_batlock     = SPITZ_GPIO_BAT_COVER,
	.gpio_acin        = SPITZ_GPIO_AC_IN,
	.gpio_batfull     = SPITZ_GPIO_CHRG_FULL,
	.batfull_irq	  = 1,
	.gpio_fatal       = SPITZ_GPIO_FATAL_BAT,
	.discharge        = spitz_discharge,
	.discharge1       = spitz_discharge1,
	.charge           = spitz_charge,
	.measure_temp     = spitz_measure_temp,
	.presuspend       = spitz_presuspend,
	.postsuspend      = spitz_postsuspend,
	.read_devdata     = spitzpm_read_devdata,
	.charger_wakeup   = spitz_charger_wakeup,
	.should_wakeup    = spitz_should_wakeup,
#if defined(CONFIG_LCD_CORGI)
	.backlight_limit = corgi_lcd_limit_intensity,
#endif
	.charge_on_volt	  = SHARPSL_CHARGE_ON_VOLT,
	.charge_on_temp	  = SHARPSL_CHARGE_ON_TEMP,
	.charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH,
	.charge_acin_low  = SHARPSL_CHARGE_ON_ACIN_LOW,
	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
	.bat_levels       = 40,
	.bat_levels_noac  = sharpsl_battery_levels_noac,
	.bat_levels_acin  = sharpsl_battery_levels_acin,
	.status_high_acin = 188,
	.status_low_acin  = 178,
	.status_high_noac = 185,
	.status_low_noac  = 175,
};

static struct platform_device *spitzpm_device;

static int spitzpm_init(void)
{
	int ret;

	if (!machine_is_spitz() && !machine_is_akita()
			&& !machine_is_borzoi())
		return -ENODEV;

	spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
	if (!spitzpm_device)
		return -ENOMEM;

	spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
	ret = platform_device_add(spitzpm_device);

	if (ret)
		platform_device_put(spitzpm_device);

	return ret;
}

static void spitzpm_exit(void)
{
	platform_device_unregister(spitzpm_device);
}

module_init(spitzpm_init);
module_exit(spitzpm_exit);


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * PXA27x standby mode
 *
 * Author: David Burrage
 *
 * 2005 (c) MontaVista Software, Inc.
 */

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

#include "pxa2xx-regs.h"

		.text

#ifdef CONFIG_PXA27x
ENTRY(pxa_cpu_standby)
	ldr	r0, =PSSR
	mov	r1, #(PSSR_PH | PSSR_STS)
	mov	r2, #PWRMODE_STANDBY
	mov	r3, #UNCACHED_PHYS_0	@ Read mem context in.
	ldr	ip, [r3]
	b	1f

	.align	5
1:	mcr	p14, 0, r2, c7, c0, 0	@ put the system into Standby
	str	r1, [r0]		@ make sure PSSR_PH/STS are clear
	ret	lr

#endif

#ifdef CONFIG_PXA3xx

#define PXA3_MDCNFG		0x0000
#define PXA3_MDCNFG_DMCEN	(1 << 30)
#define PXA3_DDR_HCAL		0x0060
#define PXA3_DDR_HCAL_HCRNG	0x1f
#define PXA3_DDR_HCAL_HCPROG	(1 << 28)
#define PXA3_DDR_HCAL_HCEN	(1 << 31)
#define PXA3_DMCIER		0x0070
#define PXA3_DMCIER_EDLP	(1 << 29)
#define PXA3_DMCISR		0x0078
#define PXA3_RCOMP		0x0100
#define PXA3_RCOMP_SWEVAL	(1 << 31)

ENTRY(pm_enter_standby_start)
	mov	r1, #0xf6000000			@ DMEMC_REG_BASE (PXA3_MDCNFG)
	add	r1, r1, #0x00100000

	/*
	 * Preload the TLB entry for accessing the dynamic memory
	 * controller registers.  Note that page table lookups will
	 * fail until the dynamic memory controller has been
	 * reinitialised - and that includes MMU page table walks.
	 * This also means that only the dynamic memory controller
	 * can be reliably accessed in the code following standby.
	 */
	ldr	r2, [r1]			@ Dummy read PXA3_MDCNFG

	mcr	p14, 0, r0, c7, c0, 0
	.rept	8
	nop
	.endr

	ldr	r0, [r1, #PXA3_DDR_HCAL]	@ Clear (and wait for) HCEN
	bic	r0, r0, #PXA3_DDR_HCAL_HCEN
	str	r0, [r1, #PXA3_DDR_HCAL]
1:	ldr	r0, [r1, #PXA3_DDR_HCAL]
	tst	r0, #PXA3_DDR_HCAL_HCEN
	bne	1b

	ldr	r0, [r1, #PXA3_RCOMP]		@ Initiate RCOMP
	orr	r0, r0, #PXA3_RCOMP_SWEVAL
	str	r0, [r1, #PXA3_RCOMP]

	mov	r0, #~0				@ Clear interrupts
	str	r0, [r1, #PXA3_DMCISR]

	ldr	r0, [r1, #PXA3_DMCIER]		@ set DMIER[EDLP]
	orr	r0, r0, #PXA3_DMCIER_EDLP
	str	r0, [r1, #PXA3_DMCIER]

	ldr	r0, [r1, #PXA3_DDR_HCAL]	@ clear HCRNG, set HCPROG, HCEN
	bic	r0, r0, #PXA3_DDR_HCAL_HCRNG
	orr	r0, r0, #PXA3_DDR_HCAL_HCEN | PXA3_DDR_HCAL_HCPROG
	str	r0, [r1, #PXA3_DDR_HCAL]

1:	ldr	r0, [r1, #PXA3_DMCISR]
	tst	r0, #PXA3_DMCIER_EDLP
	beq	1b

	ldr	r0, [r1, #PXA3_MDCNFG]		@ set PXA3_MDCNFG[DMCEN]
	orr	r0, r0, #PXA3_MDCNFG_DMCEN
	str	r0, [r1, #PXA3_MDCNFG]
1:	ldr	r0, [r1, #PXA3_MDCNFG]
	tst	r0, #PXA3_MDCNFG_DMCEN
	beq	1b

	ldr	r0, [r1, #PXA3_DDR_HCAL]	@ set PXA3_DDR_HCAL[HCRNG]
	orr	r0, r0, #2 @ HCRNG
	str	r0, [r1, #PXA3_DDR_HCAL]

	ldr	r0, [r1, #PXA3_DMCIER]		@ Clear the interrupt
	bic	r0, r0, #0x20000000
	str	r0, [r1, #PXA3_DMCIER]

	ret	lr
ENTRY(pm_enter_standby_end)

#endif

repo_name: angery/linux


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/tavorevb.c
 *
 *  Support for the Marvell PXA930 Evaluation Board
 *
 *  Copyright (C) 2007-2008 Marvell International Ltd.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/smc91x.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>

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

#include "pxa930.h"
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/keypad-pxa27x.h>

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

/* Tavor EVB MFP configurations */
static mfp_cfg_t tavorevb_mfp_cfg[] __initdata = {
	/* Ethernet */
	DF_nCS1_nCS3,
	GPIO47_GPIO,

	/* LCD */
	GPIO23_LCD_DD0,
	GPIO24_LCD_DD1,
	GPIO25_LCD_DD2,
	GPIO26_LCD_DD3,
	GPIO27_LCD_DD4,
	GPIO28_LCD_DD5,
	GPIO29_LCD_DD6,
	GPIO44_LCD_DD7,
	GPIO21_LCD_CS,
	GPIO22_LCD_CS2,

	GPIO17_LCD_FCLK_RD,
	GPIO18_LCD_LCLK_A0,
	GPIO19_LCD_PCLK_WR,

	/* LCD Backlight */
	GPIO43_PWM3,	/* primary backlight */
	GPIO32_PWM0,	/* secondary backlight */

	/* Keypad */
	GPIO0_KP_MKIN_0,
	GPIO2_KP_MKIN_1,
	GPIO4_KP_MKIN_2,
	GPIO6_KP_MKIN_3,
	GPIO8_KP_MKIN_4,
	GPIO10_KP_MKIN_5,
	GPIO12_KP_MKIN_6,
	GPIO1_KP_MKOUT_0,
	GPIO3_KP_MKOUT_1,
	GPIO5_KP_MKOUT_2,
	GPIO7_KP_MKOUT_3,
	GPIO9_KP_MKOUT_4,
	GPIO11_KP_MKOUT_5,
	GPIO13_KP_MKOUT_6,

	GPIO14_KP_DKIN_2,
	GPIO15_KP_DKIN_3,
};

#define TAVOREVB_ETH_PHYS	(0x14000000)

static struct resource smc91x_resources[] = {
	[0] = {
		.start	= (TAVOREVB_ETH_PHYS + 0x300),
		.end	= (TAVOREVB_ETH_PHYS + 0xfffff),
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)),
		.end	= PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
	}
};

static struct smc91x_platdata tavorevb_smc91x_info = {
	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
};

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

#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static const unsigned int tavorevb_matrix_key_map[] = {
	/* KEY(row, col, key_code) */
	KEY(0, 4, KEY_A), KEY(0, 5, KEY_B), KEY(0, 6, KEY_C),
	KEY(1, 4, KEY_E), KEY(1, 5, KEY_F), KEY(1, 6, KEY_G),
	KEY(2, 4, KEY_I), KEY(2, 5, KEY_J), KEY(2, 6, KEY_K),
	KEY(3, 4, KEY_M), KEY(3, 5, KEY_N), KEY(3, 6, KEY_O),
	KEY(4, 5, KEY_R), KEY(4, 6, KEY_S),
	KEY(5, 4, KEY_U), KEY(5, 4, KEY_V), KEY(5, 6, KEY_W),

	KEY(6, 4, KEY_Y), KEY(6, 5, KEY_Z),

	KEY(0, 3, KEY_0), KEY(2, 0, KEY_1), KEY(2, 1, KEY_2), KEY(2, 2, KEY_3),
	KEY(2, 3, KEY_4), KEY(1, 0, KEY_5), KEY(1, 1, KEY_6), KEY(1, 2, KEY_7),
	KEY(1, 3, KEY_8), KEY(0, 2, KEY_9),

	KEY(6, 6, KEY_SPACE),
	KEY(0, 0, KEY_KPASTERISK), 	/* * */
	KEY(0, 1, KEY_KPDOT), 		/* # */

	KEY(4, 1, KEY_UP),
	KEY(4, 3, KEY_DOWN),
	KEY(4, 0, KEY_LEFT),
	KEY(4, 2, KEY_RIGHT),
	KEY(6, 0, KEY_HOME),
	KEY(3, 2, KEY_END),
	KEY(6, 1, KEY_DELETE),
	KEY(5, 2, KEY_BACK),
	KEY(6, 3, KEY_CAPSLOCK),	/* KEY_LEFTSHIFT), */

	KEY(4, 4, KEY_ENTER),		/* scroll push */
	KEY(6, 2, KEY_ENTER),		/* keypad action */

	KEY(3, 1, KEY_SEND),
	KEY(5, 3, KEY_RECORD),
	KEY(5, 0, KEY_VOLUMEUP),
	KEY(5, 1, KEY_VOLUMEDOWN),

	KEY(3, 0, KEY_F22),	/* soft1 */
	KEY(3, 3, KEY_F23),	/* soft2 */
};

static struct matrix_keymap_data tavorevb_matrix_keymap_data = {
	.keymap		= tavorevb_matrix_key_map,
	.keymap_size	= ARRAY_SIZE(tavorevb_matrix_key_map),
};

static struct pxa27x_keypad_platform_data tavorevb_keypad_info = {
	.matrix_key_rows	= 7,
	.matrix_key_cols	= 7,
	.matrix_keymap_data	= &tavorevb_matrix_keymap_data,
	.debounce_interval	= 30,
};

static void __init tavorevb_init_keypad(void)
{
	pxa_set_keypad_info(&tavorevb_keypad_info);
}
#else
static inline void tavorevb_init_keypad(void) {}
#endif /* CONFIG_KEYBOARD_PXA27x || CONFIG_KEYBOARD_PXA27x_MODULE */

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

static struct platform_pwm_backlight_data tavorevb_backlight_data[] = {
	[0] = {
		/* primary backlight */
		.max_brightness	= 100,
		.dft_brightness	= 100,
	},
	[1] = {
		/* secondary backlight */
		.max_brightness	= 100,
		.dft_brightness	= 100,
	},
};

static struct platform_device tavorevb_backlight_devices[] = {
	[0] = {
		.name		= "pwm-backlight",
		.id		= 0,
		.dev		= {
			.platform_data = &tavorevb_backlight_data[0],
		},
	},
	[1] = {
		.name		= "pwm-backlight",
		.id		= 1,
		.dev		= {
			.platform_data = &tavorevb_backlight_data[1],
		},
	},
};

static uint16_t panel_init[] = {
	/* DSTB OUT */
	SMART_CMD(0x00),
	SMART_CMD_NOOP,
	SMART_DELAY(1),

	SMART_CMD(0x00),
	SMART_CMD_NOOP,
	SMART_DELAY(1),

	SMART_CMD(0x00),
	SMART_CMD_NOOP,
	SMART_DELAY(1),

	/* STB OUT */
	SMART_CMD(0x00),
	SMART_CMD(0x1D),
	SMART_DAT(0x00),
	SMART_DAT(0x05),
	SMART_DELAY(1),

	/* P-ON Init sequence */
	SMART_CMD(0x00), /* OSC ON */
	SMART_CMD(0x00),
	SMART_DAT(0x00),
	SMART_DAT(0x01),
	SMART_CMD(0x00),
	SMART_CMD(0x01), /* SOURCE DRIVER SHIFT DIRECTION and display RAM setting */
	SMART_DAT(0x01),
	SMART_DAT(0x27),
	SMART_CMD(0x00),
	SMART_CMD(0x02), /* LINE INV */
	SMART_DAT(0x02),
	SMART_DAT(0x00),
	SMART_CMD(0x00),
	SMART_CMD(0x03), /* IF mode(1) */
	SMART_DAT(0x01), /* 8bit smart mode(8-8),high speed write mode */
	SMART_DAT(0x30),
	SMART_CMD(0x07),
	SMART_CMD(0x00), /* RAM Write Mode */
	SMART_DAT(0x00),
	SMART_DAT(0x03),
	SMART_CMD(0x00),

	/* DISPLAY Setting,  262K, fixed(NO scroll), no split screen */
	SMART_CMD(0x07),
	SMART_DAT(0x40), /* 16/18/19 BPP */
	SMART_DAT(0x00),
	SMART_CMD(0x00),
	SMART_CMD(0x08), /* BP, FP Seting, BP=2H, FP=3H */
	SMART_DAT(0x03),
	SMART_DAT(0x02),
	SMART_CMD(0x00),
	SMART_CMD(0x0C), /* IF mode(2), using internal clock & MPU */
	SMART_DAT(0x00),
	SMART_DAT(0x00),
	SMART_CMD(0x00),
	SMART_CMD(0x0D), /* Frame setting, 1Min. Frequence, 16CLK */
	SMART_DAT(0x00),
	SMART_DAT(0x10),
	SMART_CMD(0x00),
	SMART_CMD(0x12), /* Timing(1),ASW W=4CLK, ASW ST=1CLK */
	SMART_DAT(0x03),
	SMART_DAT(0x02),
	SMART_CMD(0x00),
	SMART_CMD(0x13), /* Timing(2),OEV ST=0.5CLK, OEV ED=1CLK */
	SMART_DAT(0x01),
	SMART_DAT(0x02),
	SMART_CMD(0x00),
	SMART_CMD(0x14), /* Timing(3), ASW HOLD=0.5CLK */
	SMART_DAT(0x00),
	SMART_DAT(0x00),
	SMART_CMD(0x00),
	SMART_CMD(0x15), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */
	SMART_DAT(0x20),
	SMART_DAT(0x00),
	SMART_CMD(0x00),
	SMART_CMD(0x1C),
	SMART_DAT(0x00),
	SMART_DAT(0x00),
	SMART_CMD(0x03),
	SMART_CMD(0x00),
	SMART_DAT(0x04),
	SMART_DAT(0x03),
	SMART_CMD(0x03),
	SMART_CMD(0x01),
	SMART_DAT(0x03),
	SMART_DAT(0x04),
	SMART_CMD(0x03),
	SMART_CMD(0x02),
	SMART_DAT(0x04),
	SMART_DAT(0x03),
	SMART_CMD(0x03),
	SMART_CMD(0x03),
	SMART_DAT(0x03),
	SMART_DAT(0x03),
	SMART_CMD(0x03),
	SMART_CMD(0x04),
	SMART_DAT(0x01),
	SMART_DAT(0x01),
	SMART_CMD(0x03),
	SMART_CMD(0x05),
	SMART_DAT(0x00),
	SMART_DAT(0x00),
	SMART_CMD(0x04),
	SMART_CMD(0x02),
	SMART_DAT(0x00),
	SMART_DAT(0x00),
	SMART_CMD(0x04),
	SMART_CMD(0x03),
	SMART_DAT(0x01),
	SMART_DAT(0x3F),
	SMART_DELAY(0),

	/* DISP RAM setting: 240*320 */
	SMART_CMD(0x04), /* HADDR, START 0 */
	SMART_CMD(0x06),
	SMART_DAT(0x00),
	SMART_DAT(0x00), /* x1,3 */
	SMART_CMD(0x04), /* HADDR,  END   4 */
	SMART_CMD(0x07),
	SMART_DAT(0x00),
	SMART_DAT(0xEF), /* x2, 7 */
	SMART_CMD(0x04), /* VADDR, START 8 */
	SMART_CMD(0x08),
	SMART_DAT(0x00), /* y1, 10 */
	SMART_DAT(0x00), /* y1, 11 */
	SMART_CMD(0x04), /* VADDR, END 12 */
	SMART_CMD(0x09),
	SMART_DAT(0x01), /* y2, 14 */
	SMART_DAT(0x3F), /* y2, 15 */
	SMART_CMD(0x02), /* RAM ADDR SETTING 16 */
	SMART_CMD(0x00),
	SMART_DAT(0x00),
	SMART_DAT(0x00), /* x1, 19 */
	SMART_CMD(0x02), /* RAM ADDR SETTING 20 */
	SMART_CMD(0x01),
	SMART_DAT(0x00), /* y1, 22 */
	SMART_DAT(0x00), /* y1, 23 */
};

static uint16_t panel_on[] = {
	/* Power-IC ON */
	SMART_CMD(0x01),
	SMART_CMD(0x02),
	SMART_DAT(0x07),
	SMART_DAT(0x7D),
	SMART_CMD(0x01),
	SMART_CMD(0x03),
	SMART_DAT(0x00),
	SMART_DAT(0x05),
	SMART_CMD(0x01),
	SMART_CMD(0x04),
	SMART_DAT(0x00),
	SMART_DAT(0x00),
	SMART_CMD(0x01),
	SMART_CMD(0x05),
	SMART_DAT(0x00),
	SMART_DAT(0x15),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0xC0),
	SMART_DAT(0x10),
	SMART_DELAY(30),

	/* DISP ON */
	SMART_CMD(0x01),
	SMART_CMD(0x01),
	SMART_DAT(0x00),
	SMART_DAT(0x01),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0xFF),
	SMART_DAT(0xFE),
	SMART_DELAY(150),
};

static uint16_t panel_off[] = {
	SMART_CMD(0x00),
	SMART_CMD(0x1E),
	SMART_DAT(0x00),
	SMART_DAT(0x0A),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0xFF),
	SMART_DAT(0xEE),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0xF8),
	SMART_DAT(0x12),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0xE8),
	SMART_DAT(0x11),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0xC0),
	SMART_DAT(0x11),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0x40),
	SMART_DAT(0x11),
	SMART_CMD(0x01),
	SMART_CMD(0x00),
	SMART_DAT(0x00),
	SMART_DAT(0x10),
};

static uint16_t update_framedata[] = {
	/* write ram */
	SMART_CMD(0x02),
	SMART_CMD(0x02),

	/* write frame data */
	SMART_CMD_WRITE_FRAME,
};

static void ltm020d550_lcd_power(int on, struct fb_var_screeninfo *var)
{
	struct fb_info *info = container_of(var, struct fb_info, var);

	if (on) {
		pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_init));
		pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_on));
	} else {
		pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_off));
	}

	if (pxafb_smart_flush(info))
		pr_err("%s: timed out\n", __func__);
}

static void ltm020d550_update(struct fb_info *info)
{
	pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata));
	pxafb_smart_flush(info);
}

static struct pxafb_mode_info toshiba_ltm020d550_modes[] = {
	[0] = {
		.xres			= 240,
		.yres			= 320,
		.bpp			= 16,
		.a0csrd_set_hld		= 30,
		.a0cswr_set_hld		= 30,
		.wr_pulse_width		= 30,
		.rd_pulse_width 	= 170,
		.op_hold_time 		= 30,
		.cmd_inh_time		= 60,

		/* L_LCLK_A0 and L_LCLK_RD active low */
		.sync			= FB_SYNC_HOR_HIGH_ACT |
					  FB_SYNC_VERT_HIGH_ACT,
	},
};

static struct pxafb_mach_info tavorevb_lcd_info = {
	.modes			= toshiba_ltm020d550_modes,
	.num_modes		= 1,
	.lcd_conn		= LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL,
	.pxafb_lcd_power	= ltm020d550_lcd_power,
	.smart_update		= ltm020d550_update,
};

static void __init tavorevb_init_lcd(void)
{
	pwm_add_table(tavorevb_pwm_lookup, ARRAY_SIZE(tavorevb_pwm_lookup));
	platform_device_register(&tavorevb_backlight_devices[0]);
	platform_device_register(&tavorevb_backlight_devices[1]);
	pxa_set_fb_info(NULL, &tavorevb_lcd_info);
}
#else
static inline void tavorevb_init_lcd(void) {}
#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */

static void __init tavorevb_init(void)
{
	/* initialize MFP configurations */
	pxa3xx_mfp_config(ARRAY_AND_SIZE(tavorevb_mfp_cfg));

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

	platform_device_register(&smc91x_device);

	tavorevb_init_lcd();
	tavorevb_init_keypad();
}

MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
	/* Maintainer: Eric Miao <eric.miao@marvell.com> */
	.atag_offset    = 0x100,
	.map_io         = pxa3xx_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq       = pxa3xx_init_irq,
	.handle_irq       = pxa3xx_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine   = tavorevb_init,
	.restart	= pxa_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Bluetooth built-in chip control
 *
 * Copyright (c) 2008 Dmitry Baryshkov
 */

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

#include "tosa_bt.h"

static void tosa_bt_on(struct tosa_bt_data *data)
{
	gpio_set_value(data->gpio_reset, 0);
	gpio_set_value(data->gpio_pwr, 1);
	gpio_set_value(data->gpio_reset, 1);
	mdelay(20);
	gpio_set_value(data->gpio_reset, 0);
}

static void tosa_bt_off(struct tosa_bt_data *data)
{
	gpio_set_value(data->gpio_reset, 1);
	mdelay(10);
	gpio_set_value(data->gpio_pwr, 0);
	gpio_set_value(data->gpio_reset, 0);
}

static int tosa_bt_set_block(void *data, bool blocked)
{
	pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on");

	if (!blocked) {
		pr_info("TOSA_BT: going ON\n");
		tosa_bt_on(data);
	} else {
		pr_info("TOSA_BT: going OFF\n");
		tosa_bt_off(data);
	}

	return 0;
}

static const struct rfkill_ops tosa_bt_rfkill_ops = {
	.set_block = tosa_bt_set_block,
};

static int tosa_bt_probe(struct platform_device *dev)
{
	int rc;
	struct rfkill *rfk;

	struct tosa_bt_data *data = dev->dev.platform_data;

	rc = gpio_request(data->gpio_reset, "Bluetooth reset");
	if (rc)
		goto err_reset;
	rc = gpio_direction_output(data->gpio_reset, 0);
	if (rc)
		goto err_reset_dir;
	rc = gpio_request(data->gpio_pwr, "Bluetooth power");
	if (rc)
		goto err_pwr;
	rc = gpio_direction_output(data->gpio_pwr, 0);
	if (rc)
		goto err_pwr_dir;

	rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
			   &tosa_bt_rfkill_ops, data);
	if (!rfk) {
		rc = -ENOMEM;
		goto err_rfk_alloc;
	}

	rc = rfkill_register(rfk);
	if (rc)
		goto err_rfkill;

	platform_set_drvdata(dev, rfk);

	return 0;

err_rfkill:
	rfkill_destroy(rfk);
err_rfk_alloc:
	tosa_bt_off(data);
err_pwr_dir:
	gpio_free(data->gpio_pwr);
err_pwr:
err_reset_dir:
	gpio_free(data->gpio_reset);
err_reset:
	return rc;
}

static int tosa_bt_remove(struct platform_device *dev)
{
	struct tosa_bt_data *data = dev->dev.platform_data;
	struct rfkill *rfk = platform_get_drvdata(dev);

	platform_set_drvdata(dev, NULL);

	if (rfk) {
		rfkill_unregister(rfk);
		rfkill_destroy(rfk);
	}
	rfk = NULL;

	tosa_bt_off(data);

	gpio_free(data->gpio_pwr);
	gpio_free(data->gpio_reset);

	return 0;
}

static struct platform_driver tosa_bt_driver = {
	.probe = tosa_bt_probe,
	.remove = tosa_bt_remove,

	.driver = {
		.name = "tosa-bt",
	},
};
module_platform_driver(tosa_bt_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dmitry Baryshkov");
MODULE_DESCRIPTION("Bluetooth built-in chip control");


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Support for Sharp SL-C6000x PDAs
 *  Model: (Tosa)
 *
 *  Copyright (c) 2005 Dirk Opfer
 *
 *	Based on code written by Sharp/Lineo for 2.4 kernels
 */

#include <linux/clkdev.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/mmc/host.h>
#include <linux/mfd/tc6393xb.h>
#include <linux/mfd/tmio.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/pm.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/power/gpio-charger.h>
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/input/matrix_keypad.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/reboot.h>
#include <linux/memblock.h>

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

#include "pxa25x.h"
#include "reset.h"
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/mmc-pxamci.h>
#include "udc.h"
#include "tosa_bt.h"
#include <linux/platform_data/asoc-pxa.h>
#include "smemc.h"

#include <asm/mach/arch.h>
#include "tosa.h"

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

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

static unsigned long tosa_pin_config[] = {
	GPIO78_nCS_2, /* Scoop */
	GPIO80_nCS_4, /* tg6393xb */
	GPIO33_nCS_5, /* Scoop */

	// GPIO76 CARD_VCC_ON1

	GPIO19_GPIO, /* Reset out */
	GPIO1_RST | WAKEUP_ON_EDGE_FALL,

	GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* WAKE_UP */
	GPIO2_GPIO | WAKEUP_ON_EDGE_BOTH, /* AC_IN */
	GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* RECORD */
	GPIO4_GPIO | WAKEUP_ON_EDGE_FALL, /* SYNC */
	GPIO20_GPIO, /* EAR_IN */
	GPIO22_GPIO, /* On */

	GPIO5_GPIO, /* USB_IN */
	GPIO32_GPIO, /* Pen IRQ */

	GPIO7_GPIO, /* Jacket Detect */
	GPIO14_GPIO, /* BAT0_CRG */
	GPIO12_GPIO, /* BAT1_CRG */
	GPIO17_GPIO, /* BAT0_LOW */
	GPIO84_GPIO, /* BAT1_LOW */
	GPIO38_GPIO, /* BAT_LOCK */

	GPIO11_3_6MHz,
	GPIO15_GPIO, /* TC6393XB IRQ */
	GPIO18_RDY,
	GPIO27_GPIO, /* LCD Sync */

	/* MMC */
	GPIO6_MMC_CLK,
	GPIO8_MMC_CS0,
	GPIO9_GPIO, /* Detect */
	GPIO10_GPIO, /* nSD_INT */

	/* CF */
	GPIO13_GPIO, /* CD_IRQ */
	GPIO21_GPIO, /* Main Slot IRQ */
	GPIO36_GPIO, /* Jacket Slot IRQ */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO52_nPCE_1,
	GPIO53_nPCE_2,
	GPIO54_nPSKTSEL,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,

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

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

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

	/* Keybd */
	GPIO58_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 0 */
	GPIO59_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 1 */
	GPIO60_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 2 */
	GPIO61_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 3 */
	GPIO62_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 4 */
	GPIO63_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 5 */
	GPIO64_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 6 */
	GPIO65_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 7 */
	GPIO66_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 8 */
	GPIO67_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 9 */
	GPIO68_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 10 */
	GPIO69_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 0 */
	GPIO70_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 1 */
	GPIO71_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 2 */
	GPIO72_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 3 */
	GPIO73_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 4 */
	GPIO74_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 5 */
	GPIO75_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 6 */

	/* SPI */
	GPIO81_SSP2_CLK_OUT,
	GPIO82_SSP2_FRM_OUT,
	GPIO83_SSP2_TXD,

	/* IrDA is managed in other way */
	GPIO46_GPIO,
	GPIO47_GPIO,
};

/*
 * SCOOP Device
 */
static struct resource tosa_scoop_resources[] = {
	[0] = {
		.start	= TOSA_CF_PHYS,
		.end	= TOSA_CF_PHYS + 0xfff,
		.flags	= IORESOURCE_MEM,
	},
};

static struct scoop_config tosa_scoop_setup = {
	.io_dir 	= TOSA_SCOOP_IO_DIR,
	.gpio_base	= TOSA_SCOOP_GPIO_BASE,
};

static struct platform_device tosascoop_device = {
	.name		= "sharp-scoop",
	.id		= 0,
	.dev		= {
 		.platform_data	= &tosa_scoop_setup,
	},
	.num_resources	= ARRAY_SIZE(tosa_scoop_resources),
	.resource	= tosa_scoop_resources,
};

/*
 * SCOOP Device Jacket
 */
static struct resource tosa_scoop_jc_resources[] = {
	[0] = {
		.start		= TOSA_SCOOP_PHYS + 0x40,
		.end		= TOSA_SCOOP_PHYS + 0xfff,
		.flags		= IORESOURCE_MEM,
	},
};

static struct scoop_config tosa_scoop_jc_setup = {
	.io_dir 	= TOSA_SCOOP_JC_IO_DIR,
	.gpio_base	= TOSA_SCOOP_JC_GPIO_BASE,
};

static struct platform_device tosascoop_jc_device = {
	.name		= "sharp-scoop",
	.id		= 1,
	.dev		= {
 		.platform_data	= &tosa_scoop_jc_setup,
		.parent 	= &tosascoop_device.dev,
	},
	.num_resources	= ARRAY_SIZE(tosa_scoop_jc_resources),
	.resource	= tosa_scoop_jc_resources,
};

/*
 * PCMCIA
 */
static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
{
	.dev        = &tosascoop_device.dev,
	.irq        = TOSA_IRQ_GPIO_CF_IRQ,
	.cd_irq     = TOSA_IRQ_GPIO_CF_CD,
	.cd_irq_str = "PCMCIA0 CD",
},{
	.dev        = &tosascoop_jc_device.dev,
	.irq        = TOSA_IRQ_GPIO_JC_CF_IRQ,
	.cd_irq     = -1,
},
};

static struct scoop_pcmcia_config tosa_pcmcia_config = {
	.devs         = &tosa_pcmcia_scoop[0],
	.num_devs     = 2,
};

/*
 * USB Device Controller
 */
static struct gpiod_lookup_table tosa_udc_gpiod_table = {
	.dev_id = "gpio-vbus",
	.table = {
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_USB_IN,
			    "vbus", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_USB_PULLUP,
			    "pullup", GPIO_ACTIVE_HIGH),
		{ },
	},
};

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

/*
 * MMC/SD Device
 */
static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data)
{
	int err;

	err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int");
	if (err) {
		printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
		goto err_gpio_int;
	}
	err = gpio_direction_input(TOSA_GPIO_nSD_INT);
	if (err)
		goto err_gpio_int_dir;

	return 0;

err_gpio_int_dir:
	gpio_free(TOSA_GPIO_nSD_INT);
err_gpio_int:
	return err;
}

static void tosa_mci_exit(struct device *dev, void *data)
{
	gpio_free(TOSA_GPIO_nSD_INT);
}

static struct pxamci_platform_data tosa_mci_platform_data = {
	.detect_delay_ms	= 250,
	.ocr_mask       	= MMC_VDD_32_33|MMC_VDD_33_34,
	.init           	= tosa_mci_init,
	.exit           	= tosa_mci_exit,
};

static struct gpiod_lookup_table tosa_mci_gpio_table = {
	.dev_id = "pxa2xx-mci.0",
	.table = {
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_nSD_DETECT,
			    "cd", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("sharp-scoop.0", TOSA_GPIO_SD_WP - TOSA_SCOOP_GPIO_BASE,
			    "wp", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("sharp-scoop.0", TOSA_GPIO_PWR_ON - TOSA_SCOOP_GPIO_BASE,
			    "power", GPIO_ACTIVE_HIGH),
		{ },
	},
};

/*
 * Irda
 */
static void tosa_irda_transceiver_mode(struct device *dev, int mode)
{
	if (mode & IR_OFF) {
		gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0);
		pxa2xx_transceiver_mode(dev, mode);
		gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
	} else {
		pxa2xx_transceiver_mode(dev, mode);
		gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1);
	}
}

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

	ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX");
	if (ret)
		goto err_tx;
	ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
	if (ret)
		goto err_tx_dir;

	ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown");
	if (ret)
		goto err_pwr;

	ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
	if (ret)
		goto err_pwr_dir;

	tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);

	return 0;

err_pwr_dir:
	gpio_free(TOSA_GPIO_IR_POWERDWN);
err_pwr:
err_tx_dir:
	gpio_free(TOSA_GPIO_IRDA_TX);
err_tx:
	return ret;
}

static void tosa_irda_shutdown(struct device *dev)
{
	tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
	gpio_free(TOSA_GPIO_IR_POWERDWN);
	gpio_free(TOSA_GPIO_IRDA_TX);
}

static struct pxaficp_platform_data tosa_ficp_platform_data = {
	.gpio_pwdown		= -1,
	.transceiver_cap	= IR_SIRMODE | IR_OFF,
	.transceiver_mode	= tosa_irda_transceiver_mode,
	.startup		= tosa_irda_startup,
	.shutdown		= tosa_irda_shutdown,
};

/*
 * Tosa AC IN
 */
static struct gpiod_lookup_table tosa_power_gpiod_table = {
	.dev_id = "gpio-charger",
	.table = {
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_AC_IN,
			    NULL, GPIO_ACTIVE_LOW),
		{ },
	},
};

static char *tosa_ac_supplied_to[] = {
	"main-battery",
	"backup-battery",
	"jacket-battery",
};

static struct gpio_charger_platform_data tosa_power_data = {
	.name			= "charger",
	.type			= POWER_SUPPLY_TYPE_MAINS,
	.supplied_to		= tosa_ac_supplied_to,
	.num_supplicants	= ARRAY_SIZE(tosa_ac_supplied_to),
};

static struct resource tosa_power_resource[] = {
	{
		.name		= "ac",
		.start		= PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN),
		.end		= PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN),
		.flags		= IORESOURCE_IRQ |
				  IORESOURCE_IRQ_HIGHEDGE |
				  IORESOURCE_IRQ_LOWEDGE,
	},
};

static struct platform_device tosa_power_device = {
	.name			= "gpio-charger",
	.id			= -1,
	.dev.platform_data	= &tosa_power_data,
	.resource		= tosa_power_resource,
	.num_resources		= ARRAY_SIZE(tosa_power_resource),
};

/*
 * Tosa Keyboard
 */
static const uint32_t tosakbd_keymap[] = {
	KEY(0, 1, KEY_W),
	KEY(0, 5, KEY_K),
	KEY(0, 6, KEY_BACKSPACE),
	KEY(0, 7, KEY_P),
	KEY(1, 0, KEY_Q),
	KEY(1, 1, KEY_E),
	KEY(1, 2, KEY_T),
	KEY(1, 3, KEY_Y),
	KEY(1, 5, KEY_O),
	KEY(1, 6, KEY_I),
	KEY(1, 7, KEY_COMMA),
	KEY(2, 0, KEY_A),
	KEY(2, 1, KEY_D),
	KEY(2, 2, KEY_G),
	KEY(2, 3, KEY_U),
	KEY(2, 5, KEY_L),
	KEY(2, 6, KEY_ENTER),
	KEY(2, 7, KEY_DOT),
	KEY(3, 0, KEY_Z),
	KEY(3, 1, KEY_C),
	KEY(3, 2, KEY_V),
	KEY(3, 3, KEY_J),
	KEY(3, 4, TOSA_KEY_ADDRESSBOOK),
	KEY(3, 5, TOSA_KEY_CANCEL),
	KEY(3, 6, TOSA_KEY_CENTER),
	KEY(3, 7, TOSA_KEY_OK),
	KEY(3, 8, KEY_LEFTSHIFT),
	KEY(4, 0, KEY_S),
	KEY(4, 1, KEY_R),
	KEY(4, 2, KEY_B),
	KEY(4, 3, KEY_N),
	KEY(4, 4, TOSA_KEY_CALENDAR),
	KEY(4, 5, TOSA_KEY_HOMEPAGE),
	KEY(4, 6, KEY_LEFTCTRL),
	KEY(4, 7, TOSA_KEY_LIGHT),
	KEY(4, 9, KEY_RIGHTSHIFT),
	KEY(5, 0, KEY_TAB),
	KEY(5, 1, KEY_SLASH),
	KEY(5, 2, KEY_H),
	KEY(5, 3, KEY_M),
	KEY(5, 4, TOSA_KEY_MENU),
	KEY(5, 6, KEY_UP),
	KEY(5, 10, TOSA_KEY_FN),
	KEY(6, 0, KEY_X),
	KEY(6, 1, KEY_F),
	KEY(6, 2, KEY_SPACE),
	KEY(6, 3, KEY_APOSTROPHE),
	KEY(6, 4, TOSA_KEY_MAIL),
	KEY(6, 5, KEY_LEFT),
	KEY(6, 6, KEY_DOWN),
	KEY(6, 7, KEY_RIGHT),
};

static struct matrix_keymap_data tosakbd_keymap_data = {
	.keymap		= tosakbd_keymap,
	.keymap_size	= ARRAY_SIZE(tosakbd_keymap),
};

static const int tosakbd_col_gpios[] =
			{ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68 };
static const int tosakbd_row_gpios[] =
			{ 69, 70, 71, 72, 73, 74, 75 };

static struct matrix_keypad_platform_data tosakbd_pdata = {
	.keymap_data		= &tosakbd_keymap_data,
	.row_gpios		= tosakbd_row_gpios,
	.col_gpios		= tosakbd_col_gpios,
	.num_row_gpios		= ARRAY_SIZE(tosakbd_row_gpios),
	.num_col_gpios		= ARRAY_SIZE(tosakbd_col_gpios),
	.col_scan_delay_us	= 10,
	.debounce_ms		= 10,
	.wakeup			= 1,
};

static struct platform_device tosakbd_device = {
	.name		= "matrix-keypad",
	.id		= -1,
	.dev		= {
		.platform_data = &tosakbd_pdata,
	},
};

static struct gpio_keys_button tosa_gpio_keys[] = {
	/*
	 * Two following keys are directly tied to "ON" button of tosa. Why?
	 * The first one can be used as a wakeup source, the second can't;
	 * also the first one is OR of ac_powered and on_button.
	 */
	{
		.type	= EV_PWR,
		.code	= KEY_RESERVED,
		.gpio	= TOSA_GPIO_POWERON,
		.desc	= "Poweron",
		.wakeup	= 1,
		.active_low = 1,
	},
	{
		.type	= EV_PWR,
		.code	= KEY_SUSPEND,
		.gpio	= TOSA_GPIO_ON_KEY,
		.desc	= "On key",
		/*
		 * can't be used as wakeup
		 * .wakeup	= 1,
		 */
		.active_low = 1,
	},
	{
		.type	= EV_KEY,
		.code	= TOSA_KEY_RECORD,
		.gpio	= TOSA_GPIO_RECORD_BTN,
		.desc	= "Record Button",
		.wakeup	= 1,
		.active_low = 1,
	},
	{
		.type	= EV_KEY,
		.code	= TOSA_KEY_SYNC,
		.gpio	= TOSA_GPIO_SYNC,
		.desc	= "Sync Button",
		.wakeup	= 1,
		.active_low = 1,
	},
	{
		.type	= EV_SW,
		.code	= SW_HEADPHONE_INSERT,
		.gpio	= TOSA_GPIO_EAR_IN,
		.desc	= "HeadPhone insert",
		.active_low = 1,
		.debounce_interval = 300,
	},
};

static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
	.buttons	= tosa_gpio_keys,
	.nbuttons	= ARRAY_SIZE(tosa_gpio_keys),
};

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

/*
 * Tosa LEDs
 */
static struct gpio_led tosa_gpio_leds[] = {
	{
		.name			= "tosa:amber:charge",
		.default_trigger	= "main-battery-charging",
		.gpio			= TOSA_GPIO_CHRG_ERR_LED,
	},
	{
		.name			= "tosa:green:mail",
		.default_trigger	= "nand-disk",
		.gpio			= TOSA_GPIO_NOTE_LED,
	},
	{
		.name			= "tosa:dual:wlan",
		.default_trigger	= "none",
		.gpio			= TOSA_GPIO_WLAN_LED,
	},
	{
		.name			= "tosa:blue:bluetooth",
		.default_trigger	= "tosa-bt",
		.gpio			= TOSA_GPIO_BT_LED,
	},
};

static struct gpio_led_platform_data tosa_gpio_leds_platform_data = {
	.leds		= tosa_gpio_leds,
	.num_leds	= ARRAY_SIZE(tosa_gpio_leds),
};

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

/*
 * Toshiba Mobile IO Controller
 */
static struct resource tc6393xb_resources[] = {
	[0] = {
		.start	= TOSA_LCDC_PHYS,
		.end	= TOSA_LCDC_PHYS + 0x3ffffff,
		.flags	= IORESOURCE_MEM,
	},

	[1] = {
		.start	= TOSA_IRQ_GPIO_TC6393XB_INT,
		.end	= TOSA_IRQ_GPIO_TC6393XB_INT,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct gpiod_lookup_table tosa_battery_gpio_table = {
	.dev_id = "wm97xx-battery",
	.table = {
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_CRG,
			    "main battery full", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_CRG,
			    "jacket battery full", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_LOW,
			    "main battery low", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_LOW,
			    "jacket battery low", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_JACKET_DETECT,
			    "jacket detect", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static int tosa_tc6393xb_enable(struct platform_device *dev)
{
	int rc;

	rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr");
	if (rc)
		goto err_req_pclr;
	rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend");
	if (rc)
		goto err_req_suspend;
	rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v");
	if (rc)
		goto err_req_l3v;
	rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0);
	if (rc)
		goto err_dir_l3v;
	rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0);
	if (rc)
		goto err_dir_suspend;
	rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0);
	if (rc)
		goto err_dir_pclr;

	mdelay(1);

	gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);

	mdelay(10);

	gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1);
	gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);

	return 0;
err_dir_pclr:
err_dir_suspend:
err_dir_l3v:
	gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
err_req_l3v:
	gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
err_req_suspend:
	gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
err_req_pclr:
	return rc;
}

static void tosa_tc6393xb_disable(struct platform_device *dev)
{
	gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
	gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
	gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
}

static int tosa_tc6393xb_resume(struct platform_device *dev)
{
	gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
	mdelay(10);
	gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
	mdelay(10);

	return 0;
}

static int tosa_tc6393xb_suspend(struct platform_device *dev)
{
	gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0);
	gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0);
	return 0;
}

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

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

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

static struct tmio_nand_data tosa_tc6393xb_nand_config = {
	.badblock_pattern = &tosa_tc6393xb_nand_bbt,
	.part_parsers = probes,
};

#ifdef CONFIG_MFD_TC6393XB
static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
	{
		.xres = 480,
		.yres = 640,
		.pixclock = 0x002cdf00,/* PLL divisor */
		.left_margin = 0x004c,
		.right_margin = 0x005b,
		.upper_margin = 0x0001,
		.lower_margin = 0x000d,
		.hsync_len = 0x0002,
		.vsync_len = 0x0001,
		.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode = FB_VMODE_NONINTERLACED,
	},{
		.xres = 240,
		.yres = 320,
		.pixclock = 0x00e7f203,/* PLL divisor */
		.left_margin = 0x0024,
		.right_margin = 0x002f,
		.upper_margin = 0x0001,
		.lower_margin = 0x000d,
		.hsync_len = 0x0002,
		.vsync_len = 0x0001,
		.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode = FB_VMODE_NONINTERLACED,
	}
};

static struct tmio_fb_data tosa_tc6393xb_fb_config = {
	.lcd_set_power	= tc6393xb_lcd_set_power,
	.lcd_mode	= tc6393xb_lcd_mode,
	.num_modes	= ARRAY_SIZE(tosa_tc6393xb_lcd_mode),
	.modes		= &tosa_tc6393xb_lcd_mode[0],
	.height		= 82,
	.width		= 60,
};
#endif

static struct tc6393xb_platform_data tosa_tc6393xb_data = {
	.scr_pll2cr	= 0x0cc1,
	.scr_gper	= 0x3300,

	.irq_base	= IRQ_BOARD_START,

	.enable		= tosa_tc6393xb_enable,
	.disable	= tosa_tc6393xb_disable,
	.suspend	= tosa_tc6393xb_suspend,
	.resume		= tosa_tc6393xb_resume,

	.nand_data	= &tosa_tc6393xb_nand_config,
#ifdef CONFIG_MFD_TC6393XB
	.fb_data	= &tosa_tc6393xb_fb_config,
#endif

	.resume_restore = 1,
};

static struct platform_device tc6393xb_device = {
	.name	= "tc6393xb",
	.id	= -1,
	.dev	= {
		.platform_data	= &tosa_tc6393xb_data,
	},
	.num_resources	= ARRAY_SIZE(tc6393xb_resources),
	.resource	= tc6393xb_resources,
};

static struct tosa_bt_data tosa_bt_data = {
	.gpio_pwr	= TOSA_GPIO_BT_PWR_EN,
	.gpio_reset	= TOSA_GPIO_BT_RESET,
};

static struct platform_device tosa_bt_device = {
	.name	= "tosa-bt",
	.id	= -1,
	.dev.platform_data = &tosa_bt_data,
};

static struct pxa2xx_spi_controller pxa_ssp_master_info = {
	.num_chipselect	= 1,
};

static struct spi_board_info spi_board_info[] __initdata = {
	{
		.modalias	= "tosa-lcd",
		// .platform_data
		.max_speed_hz	= 28750,
		.bus_num	= 2,
		.chip_select	= 0,
		.mode		= SPI_MODE_0,
	},
};

static struct mtd_partition sharpsl_rom_parts[] = {
	{
		.name	="Boot PROM Filesystem",
		.offset	= 0x00160000,
		.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 wm9712_device = {
	.name	= "wm9712-codec",
	.id	= -1,
};

static struct platform_device tosa_audio_device = {
	.name	= "tosa-audio",
	.id	= -1,
};

static struct platform_device *devices[] __initdata = {
	&tosascoop_device,
	&tosascoop_jc_device,
	&tc6393xb_device,
	&tosa_power_device,
	&tosakbd_device,
	&tosa_gpio_keys_device,
	&tosaled_device,
	&tosa_bt_device,
	&sharpsl_rom_device,
	&wm9712_device,
	&tosa_gpio_vbus,
	&tosa_audio_device,
};

static void tosa_poweroff(void)
{
	pxa_restart(REBOOT_GPIO, NULL);
}

static void tosa_restart(enum reboot_mode mode, const char *cmd)
{
	uint32_t msc0 = __raw_readl(MSC0);

	/* Bootloader magic for a reboot */
	if((msc0 & 0xffff0000) == 0x7ff00000)
		__raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0);

	tosa_poweroff();
}

static void __init tosa_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));

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

	gpio_set_wake(MFP_PIN_GPIO1, 1);
	/* We can't pass to gpio-keys since it will drop the Reset altfunc */

	init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0);

	pm_power_off = tosa_poweroff;

	PCFR |= PCFR_OPDE;

	/* enable batt_fault */
	PMCR = 0x01;

	gpiod_add_lookup_table(&tosa_battery_gpio_table);

	gpiod_add_lookup_table(&tosa_mci_gpio_table);
	pxa_set_mci_info(&tosa_mci_platform_data);
	pxa_set_ficp_info(&tosa_ficp_platform_data);
	pxa_set_i2c_info(NULL);
	pxa_set_ac97_info(NULL);
	platform_scoop_config = &tosa_pcmcia_config;

	pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));

	clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);

	gpiod_add_lookup_table(&tosa_udc_gpiod_table);
	gpiod_add_lookup_table(&tosa_power_gpiod_table);
	platform_add_devices(devices, ARRAY_SIZE(devices));
}

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

MACHINE_START(TOSA, "SHARP Tosa")
	.fixup          = fixup_tosa,
	.map_io         = pxa25x_map_io,
	.nr_irqs	= TOSA_NR_IRQS,
	.init_irq       = pxa25x_init_irq,
	.handle_irq       = pxa25x_handle_irq,
	.init_machine   = tosa_init,
	.init_time	= pxa_timer_init,
	.restart	= tosa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Hardware specific definitions for Sharp SL-C6000x series of PDAs
 *
 * Copyright (c) 2005 Dirk Opfer
 *
 * Based on Sharp's 2.4 kernel patches
 */
#ifndef _ASM_ARCH_TOSA_H_
#define _ASM_ARCH_TOSA_H_ 1

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

/*  TOSA Chip selects  */
#define TOSA_LCDC_PHYS		PXA_CS4_PHYS
/* Internel Scoop */
#define TOSA_CF_PHYS		(PXA_CS2_PHYS + 0x00800000)
/* Jacket Scoop */
#define TOSA_SCOOP_PHYS  	(PXA_CS5_PHYS + 0x00800000)

#define TOSA_NR_IRQS		(IRQ_BOARD_START + TC6393XB_NR_IRQS)
/*
 * SCOOP2 internal GPIOs
 */
#define TOSA_SCOOP_GPIO_BASE		PXA_NR_BUILTIN_GPIO
#define TOSA_SCOOP_PXA_VCORE1		SCOOP_GPCR_PA11
#define TOSA_GPIO_TC6393XB_REST_IN	(TOSA_SCOOP_GPIO_BASE + 1)
#define TOSA_GPIO_IR_POWERDWN		(TOSA_SCOOP_GPIO_BASE + 2)
#define TOSA_GPIO_SD_WP			(TOSA_SCOOP_GPIO_BASE + 3)
#define TOSA_GPIO_PWR_ON		(TOSA_SCOOP_GPIO_BASE + 4)
#define TOSA_SCOOP_AUD_PWR_ON		SCOOP_GPCR_PA16
#define TOSA_GPIO_BT_RESET		(TOSA_SCOOP_GPIO_BASE + 6)
#define TOSA_GPIO_BT_PWR_EN		(TOSA_SCOOP_GPIO_BASE + 7)
#define TOSA_SCOOP_AC_IN_OL		SCOOP_GPCR_PA19

/* GPIO Direction   1 : output mode / 0:input mode */
#define TOSA_SCOOP_IO_DIR     (TOSA_SCOOP_PXA_VCORE1 | \
		TOSA_SCOOP_AUD_PWR_ON)

/*
 * SCOOP2 jacket GPIOs
 */
#define TOSA_SCOOP_JC_GPIO_BASE		(PXA_NR_BUILTIN_GPIO + 12)
#define TOSA_GPIO_BT_LED		(TOSA_SCOOP_JC_GPIO_BASE + 0)
#define TOSA_GPIO_NOTE_LED		(TOSA_SCOOP_JC_GPIO_BASE + 1)
#define TOSA_GPIO_CHRG_ERR_LED		(TOSA_SCOOP_JC_GPIO_BASE + 2)
#define TOSA_GPIO_USB_PULLUP		(TOSA_SCOOP_JC_GPIO_BASE + 3)
#define TOSA_GPIO_TC6393XB_SUSPEND	(TOSA_SCOOP_JC_GPIO_BASE + 4)
#define TOSA_GPIO_TC6393XB_L3V_ON	(TOSA_SCOOP_JC_GPIO_BASE + 5)
#define TOSA_SCOOP_JC_WLAN_DETECT	SCOOP_GPCR_PA17
#define TOSA_GPIO_WLAN_LED		(TOSA_SCOOP_JC_GPIO_BASE + 7)
#define TOSA_SCOOP_JC_CARD_LIMIT_SEL	SCOOP_GPCR_PA19

/* GPIO Direction   1 : output mode / 0:input mode */
#define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL)

/*
 * PXA GPIOs
 */
#define TOSA_GPIO_POWERON		(0)
#define TOSA_GPIO_RESET			(1)
#define TOSA_GPIO_AC_IN			(2)
#define TOSA_GPIO_RECORD_BTN		(3)
#define TOSA_GPIO_SYNC			(4)	/* Cradle SYNC Button */
#define TOSA_GPIO_USB_IN		(5)
#define TOSA_GPIO_JACKET_DETECT		(7)
#define TOSA_GPIO_nSD_DETECT		(9)
#define TOSA_GPIO_nSD_INT		(10)
#define TOSA_GPIO_TC6393XB_CLK		(11)
#define TOSA_GPIO_BAT1_CRG		(12)
#define TOSA_GPIO_CF_CD			(13)
#define TOSA_GPIO_BAT0_CRG		(14)
#define TOSA_GPIO_TC6393XB_INT		(15)
#define TOSA_GPIO_BAT0_LOW		(17)
#define TOSA_GPIO_TC6393XB_RDY		(18)
#define TOSA_GPIO_ON_RESET		(19)
#define TOSA_GPIO_EAR_IN		(20)
#define TOSA_GPIO_CF_IRQ		(21)	/* CF slot0 Ready */
#define TOSA_GPIO_ON_KEY		(22)
#define TOSA_GPIO_VGA_LINE		(27)
#define TOSA_GPIO_TP_INT		(32)	/* Touch Panel pen down interrupt */
#define TOSA_GPIO_JC_CF_IRQ		(36)	/* CF slot1 Ready */
#define TOSA_GPIO_BAT_LOCKED		(38)	/* Battery locked */
#define TOSA_GPIO_IRDA_TX		(47)
#define TOSA_GPIO_TG_SPI_SCLK		(81)
#define TOSA_GPIO_TG_SPI_CS		(82)
#define TOSA_GPIO_TG_SPI_MOSI		(83)
#define TOSA_GPIO_BAT1_LOW		(84)

#define TOSA_GPIO_HP_IN			GPIO_EAR_IN

#define TOSA_GPIO_MAIN_BAT_LOW		GPIO_BAT0_LOW

#define TOSA_KEY_STROBE_NUM		(11)
#define TOSA_KEY_SENSE_NUM		(7)

#define TOSA_GPIO_HIGH_STROBE_BIT	(0xfc000000)
#define TOSA_GPIO_LOW_STROBE_BIT	(0x0000001f)
#define TOSA_GPIO_ALL_SENSE_BIT		(0x00000fe0)
#define TOSA_GPIO_ALL_SENSE_RSHIFT	(5)
#define TOSA_GPIO_STROBE_BIT(a)		GPIO_bit(58+(a))
#define TOSA_GPIO_SENSE_BIT(a)		GPIO_bit(69+(a))
#define TOSA_GAFR_HIGH_STROBE_BIT	(0xfff00000)
#define TOSA_GAFR_LOW_STROBE_BIT	(0x000003ff)
#define TOSA_GAFR_ALL_SENSE_BIT		(0x00fffc00)
#define TOSA_GPIO_KEY_SENSE(a) 		(69+(a))
#define TOSA_GPIO_KEY_STROBE(a)		(58+(a))

/*
 * Interrupts
 */
#define TOSA_IRQ_GPIO_WAKEUP        	PXA_GPIO_TO_IRQ(TOSA_GPIO_WAKEUP)
#define TOSA_IRQ_GPIO_AC_IN         	PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN)
#define TOSA_IRQ_GPIO_RECORD_BTN    	PXA_GPIO_TO_IRQ(TOSA_GPIO_RECORD_BTN)
#define TOSA_IRQ_GPIO_SYNC          	PXA_GPIO_TO_IRQ(TOSA_GPIO_SYNC)
#define TOSA_IRQ_GPIO_USB_IN        	PXA_GPIO_TO_IRQ(TOSA_GPIO_USB_IN)
#define TOSA_IRQ_GPIO_JACKET_DETECT 	PXA_GPIO_TO_IRQ(TOSA_GPIO_JACKET_DETECT)
#define TOSA_IRQ_GPIO_nSD_INT       	PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_INT)
#define TOSA_IRQ_GPIO_nSD_DETECT    	PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_DETECT)
#define TOSA_IRQ_GPIO_BAT1_CRG      	PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_CRG)
#define TOSA_IRQ_GPIO_CF_CD         	PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_CD)
#define TOSA_IRQ_GPIO_BAT0_CRG      	PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_CRG)
#define TOSA_IRQ_GPIO_TC6393XB_INT    	PXA_GPIO_TO_IRQ(TOSA_GPIO_TC6393XB_INT)
#define TOSA_IRQ_GPIO_BAT0_LOW      	PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_LOW)
#define TOSA_IRQ_GPIO_EAR_IN        	PXA_GPIO_TO_IRQ(TOSA_GPIO_EAR_IN)
#define TOSA_IRQ_GPIO_CF_IRQ        	PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_IRQ)
#define TOSA_IRQ_GPIO_ON_KEY        	PXA_GPIO_TO_IRQ(TOSA_GPIO_ON_KEY)
#define TOSA_IRQ_GPIO_VGA_LINE      	PXA_GPIO_TO_IRQ(TOSA_GPIO_VGA_LINE)
#define TOSA_IRQ_GPIO_TP_INT        	PXA_GPIO_TO_IRQ(TOSA_GPIO_TP_INT)
#define TOSA_IRQ_GPIO_JC_CF_IRQ     	PXA_GPIO_TO_IRQ(TOSA_GPIO_JC_CF_IRQ)
#define TOSA_IRQ_GPIO_BAT_LOCKED    	PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT_LOCKED)
#define TOSA_IRQ_GPIO_BAT1_LOW      	PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_LOW)
#define TOSA_IRQ_GPIO_KEY_SENSE(a)  	PXA_GPIO_TO_IRQ(69+(a))

#define TOSA_IRQ_GPIO_MAIN_BAT_LOW 	PXA_GPIO_TO_IRQ(TOSA_GPIO_MAIN_BAT_LOW)

#define TOSA_KEY_SYNC		KEY_102ND /* ??? */

#ifndef CONFIG_TOSA_USE_EXT_KEYCODES
#define TOSA_KEY_RECORD		KEY_YEN
#define TOSA_KEY_ADDRESSBOOK	KEY_KATAKANA
#define TOSA_KEY_CANCEL		KEY_ESC
#define TOSA_KEY_CENTER		KEY_HIRAGANA
#define TOSA_KEY_OK		KEY_HENKAN
#define TOSA_KEY_CALENDAR	KEY_KATAKANAHIRAGANA
#define TOSA_KEY_HOMEPAGE	KEY_HANGEUL
#define TOSA_KEY_LIGHT		KEY_MUHENKAN
#define TOSA_KEY_MENU		KEY_HANJA
#define TOSA_KEY_FN		KEY_RIGHTALT
#define TOSA_KEY_MAIL		KEY_ZENKAKUHANKAKU
#else
#define TOSA_KEY_RECORD		KEY_RECORD
#define TOSA_KEY_ADDRESSBOOK	KEY_ADDRESSBOOK
#define TOSA_KEY_CANCEL		KEY_CANCEL
#define TOSA_KEY_CENTER		KEY_SELECT /* ??? */
#define TOSA_KEY_OK		KEY_OK
#define TOSA_KEY_CALENDAR	KEY_CALENDAR
#define TOSA_KEY_HOMEPAGE	KEY_HOMEPAGE
#define TOSA_KEY_LIGHT		KEY_KBDILLUMTOGGLE
#define TOSA_KEY_MENU		KEY_MENU
#define TOSA_KEY_FN		KEY_FN
#define TOSA_KEY_MAIL		KEY_MAIL
#endif

#endif /* _ASM_ARCH_TOSA_H_ */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Tosa bluetooth built-in chip control.
 *
 * Later it may be shared with some other platforms.
 *
 * Copyright (c) 2008 Dmitry Baryshkov
 */
#ifndef TOSA_BT_H
#define TOSA_BT_H

struct tosa_bt_data {
	int gpio_pwr;
	int gpio_reset;
};

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/drivers/pcmcia/pxa2xx_trizeps4.c
 *
 * TRIZEPS PCMCIA specific routines.
 *
 * Author:	Jürgen Schindele
 * Created:	20 02, 2006
 * Copyright:	Jürgen Schindele
 */

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

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

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

#include <pcmcia/soc_common.h>

extern void board_pcmcia_power(int power);

static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
	/* we dont have voltage/card/ready detection
	 * so we dont need interrupts for it
	 */
	switch (skt->nr) {
	case 0:
		skt->stat[SOC_STAT_CD].gpio = GPIO_PCD;
		skt->stat[SOC_STAT_CD].name = "cs0_cd";
		skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY;
		skt->stat[SOC_STAT_RDY].name = "cs0_rdy";
		break;
	default:
		break;
	}
	/* release the reset of this card */
	pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);

	return 0;
}

static unsigned long trizeps_pcmcia_status[2];

static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
				struct pcmcia_state *state)
{
	unsigned short status = 0, change;
	status = CFSR_readw();
	change = (status ^ trizeps_pcmcia_status[skt->nr]) &
				ConXS_CFSR_BVD_MASK;
	if (change) {
		trizeps_pcmcia_status[skt->nr] = status;
		if (status & ConXS_CFSR_BVD1) {
			/* enable_irq empty */
		} else {
			/* disable_irq empty */
		}
	}

	switch (skt->nr) {
	case 0:
		/* just fill in fix states */
		state->bvd1   = (status & ConXS_CFSR_BVD1) ? 1 : 0;
		state->bvd2   = (status & ConXS_CFSR_BVD2) ? 1 : 0;
		state->vs_3v  = (status & ConXS_CFSR_VS1) ? 0 : 1;
		state->vs_Xv  = (status & ConXS_CFSR_VS2) ? 0 : 1;
		break;

#ifndef CONFIG_MACH_TRIZEPS_CONXS
	/* on ConXS we only have one slot. Second is inactive */
	case 1:
		state->detect = 0;
		state->ready  = 0;
		state->bvd1   = 0;
		state->bvd2   = 0;
		state->vs_3v  = 0;
		state->vs_Xv  = 0;
		break;

#endif
	}
}

static int trizeps_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
				const socket_state_t *state)
{
	int ret = 0;
	unsigned short power = 0;

	/* we do nothing here just check a bit */
	switch (state->Vcc) {
	case 0:  power &= 0xfc; break;
	case 33: power |= ConXS_BCR_S0_VCC_3V3; break;
	case 50:
		pr_err("%s(): Vcc 5V not supported in socket\n", __func__);
		break;
	default:
		pr_err("%s(): bad Vcc %u\n", __func__, state->Vcc);
		ret = -1;
	}

	switch (state->Vpp) {
	case 0:  power &= 0xf3; break;
	case 33: power |= ConXS_BCR_S0_VPP_3V3; break;
	case 120:
		pr_err("%s(): Vpp 12V not supported in socket\n", __func__);
		break;
	default:
		if (state->Vpp != state->Vcc) {
			pr_err("%s(): bad Vpp %u\n", __func__, state->Vpp);
			ret = -1;
		}
	}

	switch (skt->nr) {
	case 0:			 /* we only have 3.3V */
		board_pcmcia_power(power);
		break;

#ifndef CONFIG_MACH_TRIZEPS_CONXS
	/* on ConXS we only have one slot. Second is inactive */
	case 1:
#endif
	default:
		break;
	}

	return ret;
}

static void trizeps_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
	/* default is on */
	board_pcmcia_power(0x9);
}

static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
	board_pcmcia_power(0x0);
}

static struct pcmcia_low_level trizeps_pcmcia_ops = {
	.owner			= THIS_MODULE,
	.hw_init		= trizeps_pcmcia_hw_init,
	.socket_state		= trizeps_pcmcia_socket_state,
	.configure_socket	= trizeps_pcmcia_configure_socket,
	.socket_init		= trizeps_pcmcia_socket_init,
	.socket_suspend		= trizeps_pcmcia_socket_suspend,
#ifdef CONFIG_MACH_TRIZEPS_CONXS
	.nr			= 1,
#else
	.nr			= 2,
#endif
	.first			= 0,
};

static struct platform_device *trizeps_pcmcia_device;

static int __init trizeps_pcmcia_init(void)
{
	int ret;

	if (!machine_is_trizeps4() && !machine_is_trizeps4wl())
		return -ENODEV;

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

	ret = platform_device_add_data(trizeps_pcmcia_device,
			&trizeps_pcmcia_ops, sizeof(trizeps_pcmcia_ops));

	if (ret == 0)
		ret = platform_device_add(trizeps_pcmcia_device);

	if (ret)
		platform_device_put(trizeps_pcmcia_device);

	return ret;
}

static void __exit trizeps_pcmcia_exit(void)
{
	platform_device_unregister(trizeps_pcmcia_device);
}

fs_initcall(trizeps_pcmcia_init);
module_exit(trizeps_pcmcia_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Juergen Schindele");
MODULE_ALIAS("platform:pxa2xx-pcmcia");


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-pxa/trizeps4.c
 *
 *  Support for the Keith und Koep Trizeps4 Module Platform.
 *
 *  Author:	Jürgen Schindele
 *  Created:	20 02, 2006
 *  Copyright:	Jürgen Schindele
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/leds.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/dm9000.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>
#include <linux/regulator/machine.h>
#include <linux/platform_data/i2c-pxa.h>

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

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

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

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

/*	comment out the following line if you want to use the
 *	Standard UART from PXA for serial / irda transmission
 *	and acivate it if you have status leds connected */
#define STATUS_LEDS_ON_STUART_PINS 1

/*****************************************************************************
 * MultiFunctionPins of CPU
 *****************************************************************************/
static unsigned long trizeps4_pin_config[] __initdata = {
	/* Chip Selects */
	GPIO15_nCS_1,		/* DiskOnChip CS */
	GPIO93_GPIO,		/* TRIZEPS4_DOC_IRQ */
	GPIO94_GPIO,		/* DOC lock */

	GPIO78_nCS_2,		/* DM9000 CS */
	GPIO101_GPIO,		/* TRIZEPS4_ETH_IRQ */

	GPIO79_nCS_3,		/* Logic CS */
	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,	/* Logic irq */

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

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

	/* UART */
	GPIO9_FFUART_CTS,
	GPIO10_FFUART_DCD,
	GPIO16_FFUART_TXD,
	GPIO33_FFUART_DSR,
	GPIO38_FFUART_RI,
	GPIO82_FFUART_DTR,
	GPIO83_FFUART_RTS,
	GPIO96_FFUART_RXD,

	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,
	GPIO45_BTUART_RTS,
#ifdef STATUS_LEDS_ON_STUART_PINS
	GPIO46_GPIO,
	GPIO47_GPIO,
#else
	GPIO46_STUART_RXD,
	GPIO47_STUART_TXD,
#endif
	/* PCMCIA */
	GPIO11_GPIO,			/* TRIZEPS4_CD_IRQ */
	GPIO13_GPIO,			/* TRIZEPS4_READY_NINT */
	GPIO48_nPOE,
	GPIO49_nPWE,
	GPIO50_nPIOR,
	GPIO51_nPIOW,
	GPIO54_nPCE_2,
	GPIO55_nPREG,
	GPIO56_nPWAIT,
	GPIO57_nIOIS16,
	GPIO102_nPCE_1,
	GPIO104_PSKTSEL,

	/* MultiMediaCard */
	GPIO32_MMC_CLK,
	GPIO92_MMC_DAT_0,
	GPIO109_MMC_DAT_1,
	GPIO110_MMC_DAT_2,
	GPIO111_MMC_DAT_3,
	GPIO112_MMC_CMD,
	GPIO12_GPIO,			/* TRIZEPS4_MMC_IRQ */

	/* USB OHCI */
	GPIO88_USBH1_PWR,		/* USBHPWR1 */
	GPIO89_USBH1_PEN,		/* USBHPEN1 */

	/* I2C */
	GPIO117_I2C_SCL,
	GPIO118_I2C_SDA,
};

static unsigned long trizeps4wl_pin_config[] __initdata = {
	/* SSP 2 */
	GPIO14_SSP2_SFRM,
	GPIO19_SSP2_SCLK,
	GPIO53_GPIO,			/* TRIZEPS4_SPI_IRQ */
	GPIO86_SSP2_RXD,
	GPIO87_SSP2_TXD,
};

/****************************************************************************
 * ONBOARD FLASH
 ****************************************************************************/
static struct mtd_partition trizeps4_partitions[] = {
	{
		.name =		"Bootloader",
		.offset =	0x00000000,
		.size =		0x00040000,
		.mask_flags =	MTD_WRITEABLE  /* force read-only */
	}, {
		.name =		"Backup",
		.offset =	0x00040000,
		.size =		0x00040000,
	}, {
		.name =		"Image",
		.offset =	0x00080000,
		.size =		0x01080000,
	}, {
		.name =		"IPSM",
		.offset =	0x01100000,
		.size =		0x00e00000,
	}, {
		.name =		"Registry",
		.offset =	0x01f00000,
		.size =		MTDPART_SIZ_FULL,
	}
};

static struct physmap_flash_data trizeps4_flash_data[] = {
	{
		.width		= 4,			/* bankwidth in bytes */
		.parts		= trizeps4_partitions,
		.nr_parts	= ARRAY_SIZE(trizeps4_partitions)
	}
};

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

static struct platform_device flash_device = {
	.name		= "physmap-flash",
	.id		= 0,
	.dev = {
		.platform_data = trizeps4_flash_data,
	},
	.resource = &flash_resource,
	.num_resources = 1,
};

/****************************************************************************
 * DAVICOM DM9000 Ethernet
 ****************************************************************************/
static struct resource dm9000_resources[] = {
	[0] = {
		.start	= TRIZEPS4_ETH_PHYS+0x300,
		.end	= TRIZEPS4_ETH_PHYS+0x400-1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= TRIZEPS4_ETH_PHYS+0x8300,
		.end	= TRIZEPS4_ETH_PHYS+0x8400-1,
		.flags	= IORESOURCE_MEM,
	},
	[2] = {
		.start	= TRIZEPS4_ETH_IRQ,
		.end	= TRIZEPS4_ETH_IRQ,
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
	},
};

static struct dm9000_plat_data tri_dm9000_platdata = {
	.flags		= DM9000_PLATF_32BITONLY,
};

static struct platform_device dm9000_device = {
	.name		= "dm9000",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(dm9000_resources),
	.resource	= dm9000_resources,
	.dev		= {
		.platform_data = &tri_dm9000_platdata,
	}
};

/****************************************************************************
 * LED's on GPIO pins of PXA
 ****************************************************************************/
static struct gpio_led trizeps4_led[] = {
#ifdef STATUS_LEDS_ON_STUART_PINS
	{
		.name = "led0:orange:heartbeat",	/* */
		.default_trigger = "heartbeat",
		.gpio = GPIO_HEARTBEAT_LED,
		.active_low = 1,
	},
	{
		.name = "led1:yellow:cpubusy",		/* */
		.default_trigger = "cpu-busy",
		.gpio = GPIO_SYS_BUSY_LED,
		.active_low = 1,
	},
#endif
};

static struct gpio_led_platform_data trizeps4_led_data = {
	.leds		= trizeps4_led,
	.num_leds	= ARRAY_SIZE(trizeps4_led),
};

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

static struct platform_device *trizeps4_devices[] __initdata = {
	&flash_device,
	&dm9000_device,
	&leds_devices,
};

static struct platform_device *trizeps4wl_devices[] __initdata = {
	&flash_device,
	&leds_devices,
};

static short trizeps_conxs_bcr;

/* PCCARD power switching supports only 3,3V */
void board_pcmcia_power(int power)
{
	if (power) {
		/* switch power on, put in reset and enable buffers */
		trizeps_conxs_bcr |= power;
		trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
		trizeps_conxs_bcr &= ~ConXS_BCR_CF_BUF_EN;
		BCR_writew(trizeps_conxs_bcr);
		/* wait a little */
		udelay(2000);
		/* take reset away */
		trizeps_conxs_bcr &= ~ConXS_BCR_CF_RESET;
		BCR_writew(trizeps_conxs_bcr);
		udelay(2000);
	} else {
		/* put in reset */
		trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
		BCR_writew(trizeps_conxs_bcr);
		udelay(1000);
		/* switch power off */
		trizeps_conxs_bcr &= ~0xf;
		BCR_writew(trizeps_conxs_bcr);
	}
	pr_debug("%s: o%s 0x%x\n", __func__, power ? "n" : "ff",
			trizeps_conxs_bcr);
}
EXPORT_SYMBOL(board_pcmcia_power);

/* backlight power switching for LCD panel */
static void board_backlight_power(int on)
{
	if (on)
		trizeps_conxs_bcr |= ConXS_BCR_L_DISP;
	else
		trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP;

	pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff",
			trizeps_conxs_bcr);
	BCR_writew(trizeps_conxs_bcr);
}

/* a I2C based RTC is known on CONXS board */
static struct i2c_board_info trizeps4_i2c_devices[] __initdata = {
	{ I2C_BOARD_INFO("rtc-pcf8593", 0x51) }
};

/****************************************************************************
 * MMC card slot external to module
 ****************************************************************************/
static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int,
		void *data)
{
	int err;

	err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
			  IRQF_TRIGGER_RISING, "MMC card detect", data);
	if (err) {
		printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request"
						"MMC card detect IRQ\n");
		return -1;
	}
	return 0;
}

static void trizeps4_mci_exit(struct device *dev, void *data)
{
	free_irq(TRIZEPS4_MMC_IRQ, data);
}

static struct pxamci_platform_data trizeps4_mci_platform_data = {
	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
	.detect_delay_ms= 10,
	.init 		= trizeps4_mci_init,
	.exit		= trizeps4_mci_exit,
	.get_ro		= NULL,	/* write-protection not supported */
	.setpower 	= NULL,	/* power-switching not supported */
};

/****************************************************************************
 * IRDA mode switching on stuart
 ****************************************************************************/
#ifndef STATUS_LEDS_ON_STUART_PINS
static short trizeps_conxs_ircr;

static int trizeps4_irda_startup(struct device *dev)
{
	trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
	IRCR_writew(trizeps_conxs_ircr);
	return 0;
}

static void trizeps4_irda_shutdown(struct device *dev)
{
	trizeps_conxs_ircr |= ConXS_IRCR_SD;
	IRCR_writew(trizeps_conxs_ircr);
}

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

	local_irq_save(flags);
	/* Switch mode */
	if (mode & IR_SIRMODE)
		trizeps_conxs_ircr &= ~ConXS_IRCR_MODE;	/* Slow mode */
	else if (mode & IR_FIRMODE)
		trizeps_conxs_ircr |= ConXS_IRCR_MODE;	/* Fast mode */

	/* Switch power */
	if (mode & IR_OFF)
		trizeps_conxs_ircr |= ConXS_IRCR_SD;
	else
		trizeps_conxs_ircr &= ~ConXS_IRCR_SD;

	IRCR_writew(trizeps_conxs_ircr);
	local_irq_restore(flags);

	pxa2xx_transceiver_mode(dev, mode);
}

static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
	.gpio_pwdown		= -1,
	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
	.transceiver_mode	= trizeps4_irda_transceiver_mode,
	.startup		= trizeps4_irda_startup,
	.shutdown		= trizeps4_irda_shutdown,
};
#endif

/****************************************************************************
 * OHCI USB port
 ****************************************************************************/
static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
	.port_mode	= PMM_PERPORT_MODE,
	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
};

static struct map_desc trizeps4_io_desc[] __initdata = {
	{ 	/* ConXS CFSR */
		.virtual	= TRIZEPS4_CFSR_VIRT,
		.pfn		= __phys_to_pfn(TRIZEPS4_CFSR_PHYS),
		.length		= 0x00001000,
		.type		= MT_DEVICE
	},
	{	/* ConXS BCR */
		.virtual	= TRIZEPS4_BOCR_VIRT,
		.pfn		= __phys_to_pfn(TRIZEPS4_BOCR_PHYS),
		.length		= 0x00001000,
		.type		= MT_DEVICE
	},
	{ 	/* ConXS IRCR */
		.virtual	= TRIZEPS4_IRCR_VIRT,
		.pfn		= __phys_to_pfn(TRIZEPS4_IRCR_PHYS),
		.length		= 0x00001000,
		.type		= MT_DEVICE
	},
	{	/* ConXS DCR */
		.virtual	= TRIZEPS4_DICR_VIRT,
		.pfn		= __phys_to_pfn(TRIZEPS4_DICR_PHYS),
		.length		= 0x00001000,
		.type		= MT_DEVICE
	},
	{	/* ConXS UPSR */
		.virtual	= TRIZEPS4_UPSR_VIRT,
		.pfn		= __phys_to_pfn(TRIZEPS4_UPSR_PHYS),
		.length		= 0x00001000,
		.type		= MT_DEVICE
	}
};

static struct pxafb_mode_info sharp_lcd_mode = {
	.pixclock	= 78000,
	.xres		= 640,
	.yres		= 480,
	.bpp		= 8,
	.hsync_len	= 4,
	.left_margin	= 4,
	.right_margin	= 4,
	.vsync_len	= 2,
	.upper_margin	= 0,
	.lower_margin	= 0,
	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
	.cmap_greyscale	= 0,
};

static struct pxafb_mach_info sharp_lcd = {
	.modes		= &sharp_lcd_mode,
	.num_modes	= 1,
	.lcd_conn	= LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL,
	.cmap_inverse	= 0,
	.cmap_static	= 0,
	.pxafb_backlight_power = board_backlight_power,
};

static struct pxafb_mode_info toshiba_lcd_mode = {
	.pixclock	= 39720,
	.xres		= 640,
	.yres		= 480,
	.bpp		= 8,
	.hsync_len	= 63,
	.left_margin	= 12,
	.right_margin	= 12,
	.vsync_len	= 4,
	.upper_margin	= 32,
	.lower_margin	= 10,
	.sync		= 0,
	.cmap_greyscale	= 0,
};

static struct pxafb_mach_info toshiba_lcd = {
	.modes		= &toshiba_lcd_mode,
	.num_modes	= 1,
	.lcd_conn	= (LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL),
	.cmap_inverse	= 0,
	.cmap_static	= 0,
	.pxafb_backlight_power = board_backlight_power,
};

static void __init trizeps4_init(void)
{
	pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4_pin_config));
	if (machine_is_trizeps4wl()) {
		pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4wl_pin_config));
		platform_add_devices(trizeps4wl_devices,
					ARRAY_SIZE(trizeps4wl_devices));
	} else {
		platform_add_devices(trizeps4_devices,
					ARRAY_SIZE(trizeps4_devices));
	}

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

	if (0)	/* dont know how to determine LCD */
		pxa_set_fb_info(NULL, &sharp_lcd);
	else
		pxa_set_fb_info(NULL, &toshiba_lcd);

	pxa_set_mci_info(&trizeps4_mci_platform_data);
#ifndef STATUS_LEDS_ON_STUART_PINS
	pxa_set_ficp_info(&trizeps4_ficp_platform_data);
#endif
	pxa_set_ohci_info(&trizeps4_ohci_platform_data);
	pxa_set_ac97_info(NULL);
	pxa_set_i2c_info(NULL);
	i2c_register_board_info(0, trizeps4_i2c_devices,
					ARRAY_SIZE(trizeps4_i2c_devices));

	/* this is the reset value */
	trizeps_conxs_bcr = 0x00A0;

	BCR_writew(trizeps_conxs_bcr);
	board_backlight_power(1);

	regulator_has_full_constraints();
}

static void __init trizeps4_map_io(void)
{
	pxa27x_map_io();
	iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));

	if ((__raw_readl(MSC0) & 0x8) && (__raw_readl(BOOT_DEF) & 0x1)) {
		/* if flash is 16 bit wide its a Trizeps4 WL */
		__machine_arch_type = MACH_TYPE_TRIZEPS4WL;
		trizeps4_flash_data[0].width = 2;
	} else {
		/* if flash is 32 bit wide its a Trizeps4 */
		__machine_arch_type = MACH_TYPE_TRIZEPS4;
		trizeps4_flash_data[0].width = 4;
	}
}

MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
	/* MAINTAINER("Jürgen Schindele") */
	.atag_offset	= 0x100,
	.init_machine	= trizeps4_init,
	.map_io		= trizeps4_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END

MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
	/* MAINTAINER("Jürgen Schindele") */
	.atag_offset	= 0x100,
	.init_machine	= trizeps4_init,
	.map_io		= trizeps4_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa27x_init_irq,
	.handle_irq	= pxa27x_handle_irq,
	.init_time	= pxa_timer_init,
	.restart	= pxa_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0 */
/************************************************************************
 * Include file for TRIZEPS4 SoM and ConXS eval-board
 * Copyright (c) Jürgen Schindele
 * 2006
 ************************************************************************/

/*
 * Includes/Defines
 */
#ifndef _TRIPEPS4_H_
#define _TRIPEPS4_H_

#include "addr-map.h"
#include "irqs.h" /* PXA_GPIO_TO_IRQ */

/* physical memory regions */
#define TRIZEPS4_FLASH_PHYS	(PXA_CS0_PHYS)  /* Flash region */
#define TRIZEPS4_DISK_PHYS	(PXA_CS1_PHYS)  /* Disk On Chip region */
#define TRIZEPS4_ETH_PHYS	(PXA_CS2_PHYS)  /* Ethernet DM9000 region */
#define TRIZEPS4_PIC_PHYS	(PXA_CS3_PHYS)	/* Logic chip on ConXS-Board */
#define TRIZEPS4_SDRAM_BASE	0xa0000000      /* SDRAM region */

				/* Logic on ConXS-board CSFR register*/
#define TRIZEPS4_CFSR_PHYS	(PXA_CS3_PHYS)
				/* Logic on ConXS-board BOCR register*/
#define TRIZEPS4_BOCR_PHYS	(PXA_CS3_PHYS+0x02000000)
				/* Logic on ConXS-board IRCR register*/
#define TRIZEPS4_IRCR_PHYS	(PXA_CS3_PHYS+0x02400000)
				/* Logic on ConXS-board UPSR register*/
#define TRIZEPS4_UPSR_PHYS	(PXA_CS3_PHYS+0x02800000)
				/* Logic on ConXS-board DICR register*/
#define TRIZEPS4_DICR_PHYS	(PXA_CS3_PHYS+0x03800000)

/* virtual memory regions */
#define TRIZEPS4_DISK_VIRT	0xF0000000	/* Disk On Chip region */

#define TRIZEPS4_PIC_VIRT	0xF0100000	/* not used */
#define TRIZEPS4_CFSR_VIRT	0xF0100000
#define TRIZEPS4_BOCR_VIRT	0xF0200000
#define TRIZEPS4_DICR_VIRT	0xF0300000
#define TRIZEPS4_IRCR_VIRT	0xF0400000
#define TRIZEPS4_UPSR_VIRT	0xF0500000

/* size of flash */
#define TRIZEPS4_FLASH_SIZE	0x02000000	/* Flash size 32 MB */

/* Ethernet Controller Davicom DM9000 */
#define GPIO_DM9000		101
#define TRIZEPS4_ETH_IRQ	PXA_GPIO_TO_IRQ(GPIO_DM9000)

/* UCB1400 audio / TS-controller */
#define GPIO_UCB1400		1
#define TRIZEPS4_UCB1400_IRQ	PXA_GPIO_TO_IRQ(GPIO_UCB1400)

/* PCMCIA socket Compact Flash */
#define GPIO_PCD		11		/* PCMCIA Card Detect */
#define TRIZEPS4_CD_IRQ		PXA_GPIO_TO_IRQ(GPIO_PCD)
#define GPIO_PRDY		13		/* READY / nINT */
#define TRIZEPS4_READY_NINT	PXA_GPIO_TO_IRQ(GPIO_PRDY)

/* MMC socket */
#define GPIO_MMC_DET		12
#define TRIZEPS4_MMC_IRQ	PXA_GPIO_TO_IRQ(GPIO_MMC_DET)

/* DOC NAND chip */
#define GPIO_DOC_LOCK           94
#define GPIO_DOC_IRQ            93
#define TRIZEPS4_DOC_IRQ        PXA_GPIO_TO_IRQ(GPIO_DOC_IRQ)

/* SPI interface */
#define GPIO_SPI                53
#define TRIZEPS4_SPI_IRQ        PXA_GPIO_TO_IRQ(GPIO_SPI)

/* LEDS using tx2 / rx2 */
#define GPIO_SYS_BUSY_LED	46
#define GPIO_HEARTBEAT_LED	47

/* Off-module PIC on ConXS board */
#define GPIO_PIC		0
#define TRIZEPS4_PIC_IRQ	PXA_GPIO_TO_IRQ(GPIO_PIC)

#ifdef CONFIG_MACH_TRIZEPS_CONXS
/* for CONXS base board define these registers */
#define CFSR_P2V(x)	((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT)
#define CFSR_V2P(x)	((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS)

#define BCR_P2V(x)	((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT)
#define BCR_V2P(x)	((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS)

#define DCR_P2V(x)	((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT)
#define DCR_V2P(x)	((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS)

#define IRCR_P2V(x)	((x) - TRIZEPS4_IRCR_PHYS + TRIZEPS4_IRCR_VIRT)
#define IRCR_V2P(x)	((x) - TRIZEPS4_IRCR_VIRT + TRIZEPS4_IRCR_PHYS)

#ifndef __ASSEMBLY__
static inline unsigned short CFSR_readw(void)
{
	/* [Compact Flash Status Register] is read only */
	return *((unsigned short *)CFSR_P2V(0x0C000000));
}
static inline void BCR_writew(unsigned short value)
{
	/* [Board Control Regsiter] is write only */
	*((unsigned short *)BCR_P2V(0x0E000000)) = value;
}
static inline void DCR_writew(unsigned short value)
{
	/* [Display Control Register] is write only */
	*((unsigned short *)DCR_P2V(0x0E000000)) = value;
}
static inline void IRCR_writew(unsigned short value)
{
	/* [InfraRed data Control Register] is write only */
	*((unsigned short *)IRCR_P2V(0x0E000000)) = value;
}
#else
#define ConXS_CFSR		CFSR_P2V(0x0C000000)
#define ConXS_BCR		BCR_P2V(0x0E000000)
#define ConXS_DCR		DCR_P2V(0x0F800000)
#define ConXS_IRCR		IRCR_P2V(0x0F800000)
#endif
#else
/* for whatever baseboard define function registers */
static inline unsigned short CFSR_readw(void)
{
	return 0;
}
static inline void BCR_writew(unsigned short value)
{
	;
}
static inline void DCR_writew(unsigned short value)
{
	;
}
static inline void IRCR_writew(unsigned short value)
{
	;
}
#endif	/* CONFIG_MACH_TRIZEPS_CONXS */

#define ConXS_CFSR_BVD_MASK	0x0003
#define ConXS_CFSR_BVD1		(1 << 0)
#define ConXS_CFSR_BVD2		(1 << 1)
#define ConXS_CFSR_VS_MASK	0x000C
#define ConXS_CFSR_VS1		(1 << 2)
#define ConXS_CFSR_VS2		(1 << 3)
#define ConXS_CFSR_VS_5V	(0x3 << 2)
#define ConXS_CFSR_VS_3V3	0x0

#define ConXS_BCR_S0_POW_EN0	(1 << 0)
#define ConXS_BCR_S0_POW_EN1	(1 << 1)
#define ConXS_BCR_L_DISP	(1 << 4)
#define ConXS_BCR_CF_BUF_EN	(1 << 5)
#define ConXS_BCR_CF_RESET	(1 << 7)
#define ConXS_BCR_S0_VCC_3V3	0x1
#define ConXS_BCR_S0_VCC_5V0	0x2
#define ConXS_BCR_S0_VPP_12V	0x4
#define ConXS_BCR_S0_VPP_3V3	0x8

#define ConXS_IRCR_MODE		(1 << 0)
#define ConXS_IRCR_SD		(1 << 1)

#endif /* _TRIPEPS4_H_ */


code:
/*
 * arch/arm/mach-pxa/include/mach/udc.h
 *
 */
#include <linux/platform_data/pxa2xx_udc.h>

extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);


code:
/*
 * Viper/Zeus PCMCIA support
 *   Copyright 2004 Arcom Control Systems
 *
 * Maintained by Marc Zyngier <maz@misterjones.org>
 *
 * Based on:
 *   iPAQ h2200 PCMCIA support
 *   Copyright 2004 Koen Kooi <koen@vestingbar.nl>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 */

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

#include <pcmcia/ss.h>
#include <pcmcia/soc_common.h>

#include <asm/irq.h>

#include "viper-pcmcia.h"

static struct platform_device *arcom_pcmcia_dev;

static inline struct arcom_pcmcia_pdata *viper_get_pdata(void)
{
	return arcom_pcmcia_dev->dev.platform_data;
}

static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
	unsigned long flags;

	skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio;
	skt->stat[SOC_STAT_CD].name = "PCMCIA_CD";
	skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio;
	skt->stat[SOC_STAT_RDY].name = "CF ready";

	if (gpio_request(pdata->pwr_gpio, "CF power"))
		goto err_request_pwr;

	local_irq_save(flags);

	if (gpio_direction_output(pdata->pwr_gpio, 0)) {
		local_irq_restore(flags);
		goto err_dir;
	}

	local_irq_restore(flags);

	return 0;

err_dir:
	gpio_free(pdata->pwr_gpio);
err_request_pwr:
	dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n");
	return -1;
}

/*
 * Release all resources.
 */
static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();

	gpio_free(pdata->pwr_gpio);
}

static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
				      struct pcmcia_state *state)
{
	state->vs_3v  = 1; /* Can only apply 3.3V */
	state->vs_Xv  = 0;
}

static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
					 const socket_state_t *state)
{
	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();

	/* Silently ignore Vpp, output enable, speaker enable. */
	pdata->reset(state->flags & SS_RESET);

	/* Apply socket voltage */
	switch (state->Vcc) {
	case 0:
		gpio_set_value(pdata->pwr_gpio, 0);
		break;
	case 33:
		gpio_set_value(pdata->pwr_gpio, 1);
		break;
	default:
		dev_err(&arcom_pcmcia_dev->dev, "Unsupported Vcc:%d\n", state->Vcc);
		return -1;
	}

	return 0;
}

static struct pcmcia_low_level viper_pcmcia_ops = {
	.owner          	= THIS_MODULE,
	.hw_init        	= viper_pcmcia_hw_init,
	.hw_shutdown		= viper_pcmcia_hw_shutdown,
	.socket_state		= viper_pcmcia_socket_state,
	.configure_socket	= viper_pcmcia_configure_socket,
	.nr         		= 1,
};

static struct platform_device *viper_pcmcia_device;

static int viper_pcmcia_probe(struct platform_device *pdev)
{
	int ret;

	/* I can't imagine more than one device, but you never know... */
	if (arcom_pcmcia_dev)
		return -EEXIST;

	if (!pdev->dev.platform_data)
		return -EINVAL;

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

	arcom_pcmcia_dev = pdev;

	viper_pcmcia_device->dev.parent = &pdev->dev;

	ret = platform_device_add_data(viper_pcmcia_device,
				       &viper_pcmcia_ops,
				       sizeof(viper_pcmcia_ops));

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

	if (ret) {
		platform_device_put(viper_pcmcia_device);
		arcom_pcmcia_dev = NULL;
	}

	return ret;
}

static int viper_pcmcia_remove(struct platform_device *pdev)
{
	platform_device_unregister(viper_pcmcia_device);
	arcom_pcmcia_dev = NULL;
	return 0;
}

static struct platform_device_id viper_pcmcia_id_table[] = {
	{ .name = "viper-pcmcia", },
	{ .name = "zeus-pcmcia",  },
	{ },
};

static struct platform_driver viper_pcmcia_driver = {
	.probe		= viper_pcmcia_probe,
	.remove		= viper_pcmcia_remove,
	.driver		= {
		.name	= "arcom-pcmcia",
	},
	.id_table	= viper_pcmcia_id_table,
};

module_platform_driver(viper_pcmcia_driver);

MODULE_DEVICE_TABLE(platform, viper_pcmcia_id_table);
MODULE_LICENSE("GPL");


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

struct arcom_pcmcia_pdata {
	int	cd_gpio;
	int	rdy_gpio;
	int	pwr_gpio;
	void	(*reset)(int state);
};

#endif