code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/assabet.h
 *
 * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
 *
 * This file contains the hardware specific definitions for Assabet
 * Only include this file from SA1100-specific files.
 *
 * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
 *      Definitions for Neponset added.
 */
#ifndef __ASM_ARCH_ASSABET_H
#define __ASM_ARCH_ASSABET_H

/* System Configuration Register flags */

#define ASSABET_SCR_SDRAM_LOW	(1<<2)	/* SDRAM size (low bit) */
#define ASSABET_SCR_SDRAM_HIGH	(1<<3)	/* SDRAM size (high bit) */
#define ASSABET_SCR_FLASH_LOW	(1<<4)	/* Flash size (low bit) */
#define ASSABET_SCR_FLASH_HIGH	(1<<5)	/* Flash size (high bit) */
#define ASSABET_SCR_GFX		(1<<8)	/* Graphics Accelerator (0 = present) */
#define ASSABET_SCR_SA1111	(1<<9)	/* Neponset (0 = present) */

#define ASSABET_SCR_INIT	-1

extern unsigned long SCR_value;

#ifdef CONFIG_ASSABET_NEPONSET
#define machine_has_neponset()  ((SCR_value & ASSABET_SCR_SA1111) == 0)
#else
#define machine_has_neponset()	(0)
#endif

/* Board Control Register */

#define ASSABET_BCR_BASE  0xf1000000
#define ASSABET_BCR (*(volatile unsigned int *)(ASSABET_BCR_BASE))

#define ASSABET_BCR_CF_PWR	(1<<0)	/* Compact Flash Power (1 = 3.3v, 0 = off) */
#define ASSABET_BCR_CF_RST	(1<<1)	/* Compact Flash Reset (1 = power up reset) */
#define ASSABET_BCR_NGFX_RST	(1<<1)	/* Graphics Accelerator Reset (0 = hold reset) */
#define ASSABET_BCR_NCODEC_RST	(1<<2)	/* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */
#define ASSABET_BCR_IRDA_FSEL	(1<<3)	/* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */
#define ASSABET_BCR_IRDA_MD0	(1<<4)	/* Range/Power select */
#define ASSABET_BCR_IRDA_MD1	(1<<5)	/* Range/Power select */
#define ASSABET_BCR_STEREO_LB	(1<<6)	/* Stereo Loopback */
#define ASSABET_BCR_CF_BUS_OFF	(1<<7)	/* Compact Flash bus (0 = on, 1 = off (float)) */
#define ASSABET_BCR_AUDIO_ON	(1<<8)	/* Audio power on */
#define ASSABET_BCR_LIGHT_ON	(1<<9)	/* Backlight */
#define ASSABET_BCR_LCD_12RGB	(1<<10)	/* 0 = 16RGB, 1 = 12RGB */
#define ASSABET_BCR_LCD_ON	(1<<11)	/* LCD power on */
#define ASSABET_BCR_RS232EN	(1<<12)	/* RS232 transceiver enable */
#define ASSABET_BCR_LED_RED	(1<<13)	/* D9 (0 = on, 1 = off) */
#define ASSABET_BCR_LED_GREEN	(1<<14)	/* D8 (0 = on, 1 = off) */
#define ASSABET_BCR_VIB_ON	(1<<15)	/* Vibration motor (quiet alert) */
#define ASSABET_BCR_COM_DTR	(1<<16)	/* COMport Data Terminal Ready */
#define ASSABET_BCR_COM_RTS	(1<<17)	/* COMport Request To Send */
#define ASSABET_BCR_RAD_WU	(1<<18)	/* Radio wake up interrupt */
#define ASSABET_BCR_SMB_EN	(1<<19)	/* System management bus enable */
#define ASSABET_BCR_TV_IR_DEC	(1<<20)	/* TV IR Decode Enable (not implemented) */
#define ASSABET_BCR_QMUTE	(1<<21)	/* Quick Mute */
#define ASSABET_BCR_RAD_ON	(1<<22)	/* Radio Power On */
#define ASSABET_BCR_SPK_OFF	(1<<23)	/* 1 = Speaker amplifier power off */

#ifdef CONFIG_SA1100_ASSABET
extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
#else
#define ASSABET_BCR_frob(x,y)	do { } while (0)
#endif

extern void assabet_uda1341_reset(int set);

#define ASSABET_BCR_set(x)	ASSABET_BCR_frob((x), (x))
#define ASSABET_BCR_clear(x)	ASSABET_BCR_frob((x), 0)

#define ASSABET_BSR_BASE	0xf1000000
#define ASSABET_BSR (*(volatile unsigned int*)(ASSABET_BSR_BASE))

#define ASSABET_BSR_RS232_VALID	(1 << 24)
#define ASSABET_BSR_COM_DCD	(1 << 25)
#define ASSABET_BSR_COM_CTS	(1 << 26)
#define ASSABET_BSR_COM_DSR	(1 << 27)
#define ASSABET_BSR_RAD_CTS	(1 << 28)
#define ASSABET_BSR_RAD_DSR	(1 << 29)
#define ASSABET_BSR_RAD_DCD	(1 << 30)
#define ASSABET_BSR_RAD_RI	(1 << 31)

/* GPIOs (bitmasks) for which the generic definition doesn't say much */
#define ASSABET_GPIO_RADIO_IRQ		GPIO_GPIO (14)	/* Radio interrupt request  */
#define ASSABET_GPIO_PS_MODE_SYNC	GPIO_GPIO (16)	/* Power supply mode/sync   */
#define ASSABET_GPIO_STEREO_64FS_CLK	GPIO_GPIO (19)	/* SSP UDA1341 clock input  */
#define ASSABET_GPIO_GFX_IRQ		GPIO_GPIO (24)	/* Graphics IRQ */
#define ASSABET_GPIO_BATT_LOW		GPIO_GPIO (26)	/* Low battery */
#define ASSABET_GPIO_RCLK		GPIO_GPIO (26)	/* CCLK/2  */

#endif

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/mach-sa1100/include/mach/badge4.h
 *
 *   Tim Connors <connors@hpl.hp.com>
 *   Christopher Hoover <ch@hpl.hp.com>
 *
 * Copyright (C) 2002 Hewlett-Packard Company
 */

#ifndef __ASM_ARCH_HARDWARE_H
#error "include <mach/hardware.h> instead"
#endif

#define BADGE4_SA1111_BASE		(0x48000000)

/* GPIOs on the BadgePAD 4 */
#define BADGE4_GPIO_INT_1111		GPIO_GPIO0   /* SA-1111 IRQ */

#define BADGE4_GPIO_INT_VID		GPIO_GPIO1   /* Video expansion */
#define BADGE4_GPIO_LGP2		GPIO_GPIO2   /* GPIO_LDD8 */
#define BADGE4_GPIO_LGP3		GPIO_GPIO3   /* GPIO_LDD9 */
#define BADGE4_GPIO_LGP4		GPIO_GPIO4   /* GPIO_LDD10 */
#define BADGE4_GPIO_LGP5		GPIO_GPIO5   /* GPIO_LDD11 */
#define BADGE4_GPIO_LGP6		GPIO_GPIO6   /* GPIO_LDD12 */
#define BADGE4_GPIO_LGP7		GPIO_GPIO7   /* GPIO_LDD13 */
#define BADGE4_GPIO_LGP8		GPIO_GPIO8   /* GPIO_LDD14 */
#define BADGE4_GPIO_LGP9		GPIO_GPIO9   /* GPIO_LDD15 */
#define BADGE4_GPIO_GPA_VID		GPIO_GPIO10  /* Video expansion */
#define BADGE4_GPIO_GPB_VID		GPIO_GPIO11  /* Video expansion */
#define BADGE4_GPIO_GPC_VID		GPIO_GPIO12  /* Video expansion */

#define BADGE4_GPIO_UART_HS1		GPIO_GPIO13
#define BADGE4_GPIO_UART_HS2		GPIO_GPIO14

#define BADGE4_GPIO_MUXSEL0		GPIO_GPIO15
#define BADGE4_GPIO_TESTPT_J7		GPIO_GPIO16

#define BADGE4_GPIO_SDSDA		GPIO_GPIO17  /* SDRAM SPD Data */
#define BADGE4_GPIO_SDSCL		GPIO_GPIO18  /* SDRAM SPD Clock */
#define BADGE4_GPIO_SDTYP0		GPIO_GPIO19  /* SDRAM Type Control */
#define BADGE4_GPIO_SDTYP1		GPIO_GPIO20  /* SDRAM Type Control */

#define BADGE4_GPIO_BGNT_1111		GPIO_GPIO21  /* GPIO_MBGNT */
#define BADGE4_GPIO_BREQ_1111		GPIO_GPIO22  /* GPIO_TREQA */

#define BADGE4_GPIO_TESTPT_J6		GPIO_GPIO23

#define BADGE4_GPIO_PCMEN5V		GPIO_GPIO24  /* 5V power */

#define BADGE4_GPIO_SA1111_NRST		GPIO_GPIO25  /* SA-1111 nRESET */

#define BADGE4_GPIO_TESTPT_J5		GPIO_GPIO26

#define BADGE4_GPIO_CLK_1111		GPIO_GPIO27  /* GPIO_32_768kHz */

/* Interrupts on the BadgePAD 4 */
#define BADGE4_IRQ_GPIO_SA1111		IRQ_GPIO0    /* SA-1111 interrupt */

/* PCM5ENV Usage tracking */

#define BADGE4_5V_PCMCIA_SOCK0		(1<<0)
#define BADGE4_5V_PCMCIA_SOCK1		(1<<1)
#define BADGE4_5V_PCMCIA_SOCK(n)	(1<<(n))
#define BADGE4_5V_USB			(1<<2)
#define BADGE4_5V_INITIALLY		(1<<3)

#ifndef __ASSEMBLY__
extern void badge4_set_5V(unsigned subsystem, int on);
#endif


code:
/*
 *	FILE    	bitfield.h
 *
 *	Version 	1.1
 *	Author  	Copyright (c) Marc A. Viredaz, 1998
 *	        	DEC Western Research Laboratory, Palo Alto, CA
 *	Date    	April 1998 (April 1997)
 *	System  	Advanced RISC Machine (ARM)
 *	Language	C or ARM Assembly
 *	Purpose 	Definition of macros to operate on bit fields.
 */

#ifndef __BITFIELD_H
#define __BITFIELD_H

#ifndef __ASSEMBLY__
#define UData(Data)	((unsigned long) (Data))
#else
#define UData(Data)	(Data)
#endif

/*
 * MACRO: Fld
 *
 * Purpose
 *    The macro "Fld" encodes a bit field, given its size and its shift value
 *    with respect to bit 0.
 *
 * Note
 *    A more intuitive way to encode bit fields would have been to use their
 *    mask. However, extracting size and shift value information from a bit
 *    field's mask is cumbersome and might break the assembler (255-character
 *    line-size limit).
 *
 * Input
 *    Size      	Size of the bit field, in number of bits.
 *    Shft      	Shift value of the bit field with respect to bit 0.
 *
 * Output
 *    Fld       	Encoded bit field.
 */

#define Fld(Size, Shft)	(((Size) << 16) + (Shft))

/*
 * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
 *
 * Purpose
 *    The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
 *    the size, shift value, mask, aligned mask, and first bit of a
 *    bit field.
 *
 * Input
 *    Field     	Encoded bit field (using the macro "Fld").
 *
 * Output
 *    FSize     	Size of the bit field, in number of bits.
 *    FShft     	Shift value of the bit field with respect to bit 0.
 *    FMsk      	Mask for the bit field.
 *    FAlnMsk   	Mask for the bit field, aligned on bit 0.
 *    F1stBit   	First bit of the bit field.
 */

#define FSize(Field)	((Field) >> 16)
#define FShft(Field)	((Field) & 0x0000FFFF)
#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
#define F1stBit(Field)	(UData (1) << FShft (Field))

/*
 * MACRO: FInsrt
 *
 * Purpose
 *    The macro "FInsrt" inserts a value into a bit field by shifting the
 *    former appropriately.
 *
 * Input
 *    Value     	Bit-field value.
 *    Field     	Encoded bit field (using the macro "Fld").
 *
 * Output
 *    FInsrt    	Bit-field value positioned appropriately.
 */

#define FInsrt(Value, Field) \
                	(UData (Value) << FShft (Field))

/*
 * MACRO: FExtr
 *
 * Purpose
 *    The macro "FExtr" extracts the value of a bit field by masking and
 *    shifting it appropriately.
 *
 * Input
 *    Data      	Data containing the bit-field to be extracted.
 *    Field     	Encoded bit field (using the macro "Fld").
 *
 * Output
 *    FExtr     	Bit-field value.
 */

#define FExtr(Data, Field) \
                	((UData (Data) >> FShft (Field)) & FAlnMsk (Field))

#endif /* __BITFIELD_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/mach-sa1100/include/mach/cerf.h
 *
 * Apr-2003 : Removed some old PDA crud [FB]
 */
#ifndef _INCLUDE_CERF_H_
#define _INCLUDE_CERF_H_

#define CERF_ETH_IO			0xf0000000
#define CERF_ETH_IRQ IRQ_GPIO26

#define CERF_GPIO_CF_BVD2		19
#define CERF_GPIO_CF_BVD1		20
#define CERF_GPIO_CF_RESET		21
#define CERF_GPIO_CF_IRQ		22
#define CERF_GPIO_CF_CD			23

#endif // _INCLUDE_CERF_H_


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/collie.h
 *
 * This file contains the hardware specific definitions for Collie
 * Only include this file from SA1100-specific files.
 *
 * ChangeLog:
 *   04-06-2001 Lineo Japan, Inc.
 *   04-16-2001 SHARP Corporation
 *   07-07-2002 Chris Larson <clarson@digi.com>
 *
 */
#ifndef __ASM_ARCH_COLLIE_H
#define __ASM_ARCH_COLLIE_H

#include "hardware.h" /* Gives GPIO_MAX */

extern void locomolcd_power(int on);

#define COLLIE_SCOOP_GPIO_BASE	(GPIO_MAX + 1)
#define COLLIE_GPIO_CHARGE_ON	(COLLIE_SCOOP_GPIO_BASE + 0)
#define COLLIE_SCP_DIAG_BOOT1	SCOOP_GPCR_PA12
#define COLLIE_SCP_DIAG_BOOT2	SCOOP_GPCR_PA13
#define COLLIE_SCP_MUTE_L	SCOOP_GPCR_PA14
#define COLLIE_SCP_MUTE_R	SCOOP_GPCR_PA15
#define COLLIE_SCP_5VON		SCOOP_GPCR_PA16
#define COLLIE_SCP_AMP_ON	SCOOP_GPCR_PA17
#define COLLIE_GPIO_VPEN	(COLLIE_SCOOP_GPIO_BASE + 7)
#define COLLIE_SCP_LB_VOL_CHG	SCOOP_GPCR_PA19

#define COLLIE_SCOOP_IO_DIR	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
				COLLIE_SCP_LB_VOL_CHG)
#define COLLIE_SCOOP_IO_OUT	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)

/* GPIOs for gpiolib  */

#define COLLIE_GPIO_ON_KEY		(0)
#define COLLIE_GPIO_AC_IN		(1)
#define COLLIE_GPIO_SDIO_INT		(11)
#define COLLIE_GPIO_CF_IRQ		(14)
#define COLLIE_GPIO_nREMOCON_INT	(15)
#define COLLIE_GPIO_UCB1x00_RESET	(16)
#define COLLIE_GPIO_nMIC_ON		(17)
#define COLLIE_GPIO_nREMOCON_ON		(18)
#define COLLIE_GPIO_CO			(20)
#define COLLIE_GPIO_MCP_CLK		(21)
#define COLLIE_GPIO_CF_CD		(22)
#define COLLIE_GPIO_UCB1x00_IRQ		(23)
#define COLLIE_GPIO_WAKEUP		(24)
#define COLLIE_GPIO_GA_INT		(25)
#define COLLIE_GPIO_MAIN_BAT_LOW	(26)

/* GPIO definitions for direct register access */

#define _COLLIE_GPIO_ON_KEY		GPIO_GPIO(0)
#define _COLLIE_GPIO_AC_IN		GPIO_GPIO(1)
#define _COLLIE_GPIO_nREMOCON_INT	GPIO_GPIO(15)
#define _COLLIE_GPIO_UCB1x00_RESET	GPIO_GPIO(16)
#define _COLLIE_GPIO_nMIC_ON		GPIO_GPIO(17)
#define _COLLIE_GPIO_nREMOCON_ON	GPIO_GPIO(18)
#define _COLLIE_GPIO_CO			GPIO_GPIO(20)
#define _COLLIE_GPIO_WAKEUP		GPIO_GPIO(24)
/* Interrupts */

#define COLLIE_IRQ_GPIO_ON_KEY		IRQ_GPIO0
#define COLLIE_IRQ_GPIO_AC_IN		IRQ_GPIO1
#define COLLIE_IRQ_GPIO_SDIO_IRQ	IRQ_GPIO11
#define COLLIE_IRQ_GPIO_CF_IRQ		IRQ_GPIO14
#define COLLIE_IRQ_GPIO_nREMOCON_INT	IRQ_GPIO15
#define COLLIE_IRQ_GPIO_CO		IRQ_GPIO20
#define COLLIE_IRQ_GPIO_CF_CD		IRQ_GPIO22
#define COLLIE_IRQ_GPIO_UCB1x00_IRQ	IRQ_GPIO23
#define COLLIE_IRQ_GPIO_WAKEUP		IRQ_GPIO24
#define COLLIE_IRQ_GPIO_GA_INT		IRQ_GPIO25
#define COLLIE_IRQ_GPIO_MAIN_BAT_LOW	IRQ_GPIO26

/* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
#define COLLIE_TC35143_GPIO_BASE	(GPIO_MAX + 13)
#define COLLIE_TC35143_GPIO_VERSION0    UCB_IO_0
#define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1
#define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2
#define COLLIE_GPIO_IR_ON		(COLLIE_TC35143_GPIO_BASE + 3)
#define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4
#define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5
#define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5
#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
#define COLLIE_GPIO_MBAT_ON     	(COLLIE_TC35143_GPIO_BASE + 7)
#define COLLIE_GPIO_BBAT_ON     	(COLLIE_TC35143_GPIO_BASE + 8)
#define COLLIE_GPIO_TMP_ON      	(COLLIE_TC35143_GPIO_BASE + 9)
#define COLLIE_TC35143_GPIO_IN		(UCB_IO_0 | UCB_IO_2 | UCB_IO_5)
#define COLLIE_TC35143_GPIO_OUT		(UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
						| UCB_IO_6)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Definitions for Compaq iPAQ H3100 and H3600 handheld computers
 *
 * (c) 2000 Compaq Computer Corporation. (Author: Jamey Hicks)
 * (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
 */

#ifndef _INCLUDE_H3XXX_H_
#define _INCLUDE_H3XXX_H_

#include "hardware.h" /* Gives GPIO_MAX */

/* Physical memory regions corresponding to chip selects */
#define H3600_EGPIO_PHYS	(SA1100_CS5_PHYS + 0x01000000)
#define H3600_BANK_2_PHYS	SA1100_CS2_PHYS
#define H3600_BANK_4_PHYS	SA1100_CS4_PHYS

/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
#define H3600_EGPIO_VIRT	0xf0000000
#define H3600_BANK_2_VIRT	0xf1000000
#define H3600_BANK_4_VIRT	0xf3800000

/*
 * gpiolib numbers for all iPAQs
 */
#define H3XXX_GPIO_PWR_BUTTON		0
#define H3XXX_GPIO_PCMCIA_CD1		10
#define H3XXX_GPIO_PCMCIA_IRQ1		11
#define H3XXX_GPIO_PCMCIA_CD0		17
#define H3XXX_GPIO_ACTION_BUTTON	18
#define H3XXX_GPIO_SYS_CLK		19
#define H3XXX_GPIO_PCMCIA_IRQ0		21
#define H3XXX_GPIO_COM_DCD		23
#define H3XXX_GPIO_OPTION		24
#define H3XXX_GPIO_COM_CTS		25
#define H3XXX_GPIO_COM_RTS		26

/* machine-specific gpios */

#define H3100_GPIO_BT_ON		2
#define H3100_GPIO_QMUTE		4
#define H3100_GPIO_LCD_3V_ON		5
#define H3100_GPIO_AUD_ON		6
#define H3100_GPIO_AUD_PWR_ON		7
#define H3100_GPIO_IR_ON		8
#define H3100_GPIO_IR_FSEL		9

#define H3600_GPIO_CLK_SET0		12	/* audio sample rate clock generator */
#define H3600_GPIO_CLK_SET1		13
#define H3600_GPIO_SOFT_RESET		20	/* also known as BATT_FAULT */
#define H3600_GPIO_OPT_LOCK		22
#define H3600_GPIO_OPT_DET		27

/* H3100 / 3600 EGPIO pins */
#define H3XXX_EGPIO_BASE		(GPIO_MAX + 1)

#define H3XXX_EGPIO_VPP_ON		(H3XXX_EGPIO_BASE + 0)
#define H3XXX_EGPIO_CARD_RESET		(H3XXX_EGPIO_BASE + 1) /* reset the attached pcmcia/compactflash card.  active high. */
#define H3XXX_EGPIO_OPT_RESET		(H3XXX_EGPIO_BASE + 2) /* reset the attached option pack.  active high. */
#define H3XXX_EGPIO_CODEC_NRESET	(H3XXX_EGPIO_BASE + 3) /* reset the onboard UDA1341.  active low. */
#define H3XXX_EGPIO_OPT_NVRAM_ON	(H3XXX_EGPIO_BASE + 4) /* apply power to optionpack nvram, active high. */
#define H3XXX_EGPIO_OPT_ON		(H3XXX_EGPIO_BASE + 5) /* full power to option pack.  active high. */
#define H3XXX_EGPIO_LCD_ON		(H3XXX_EGPIO_BASE + 6) /* enable 3.3V to LCD.  active high. */
#define H3XXX_EGPIO_RS232_ON		(H3XXX_EGPIO_BASE + 7) /* UART3 transceiver force on.  Active high. */

/* H3600 only EGPIO pins */
#define H3600_EGPIO_LCD_PCI		(H3XXX_EGPIO_BASE + 8) /* LCD control IC enable.  active high. */
#define H3600_EGPIO_IR_ON		(H3XXX_EGPIO_BASE + 9) /* apply power to IR module.  active high. */
#define H3600_EGPIO_AUD_AMP_ON		(H3XXX_EGPIO_BASE + 10) /* apply power to audio power amp.  active high. */
#define H3600_EGPIO_AUD_PWR_ON		(H3XXX_EGPIO_BASE + 11) /* apply power to reset of audio circuit.  active high. */
#define H3600_EGPIO_QMUTE		(H3XXX_EGPIO_BASE + 12) /* mute control for onboard UDA1341.  active high. */
#define H3600_EGPIO_IR_FSEL		(H3XXX_EGPIO_BASE + 13) /* IR speed select: 1->fast, 0->slow */
#define H3600_EGPIO_LCD_5V_ON		(H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
#define H3600_EGPIO_LVDD_ON		(H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */

void __init h3xxx_map_io(void);
void __init h3xxx_mach_init(void);

#endif /* _INCLUDE_H3XXX_H_ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/hardware.h
 *
 * Copyright (C) 1998 Nicolas Pitre <nico@fluxnic.net>
 *
 * This file contains the hardware definitions for SA1100 architecture
 *
 * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
 *      Definitions for SA1111 added.
 */

#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H

#define UNCACHEABLE_ADDR	0xfa050000	/* ICIP */

/*
 * SA1100 internal I/O mappings
 *
 * We have the following mapping:
 *      phys            virt
 *      80000000        f8000000
 *      90000000        fa000000
 *      a0000000        fc000000
 *      b0000000        fe000000
 */

#define VIO_BASE        0xf8000000	/* virtual start of IO space */
#define VIO_SHIFT       3		/* x = IO space shrink power */
#define PIO_START       0x80000000	/* physical start of IO space */

#define io_p2v( x )             \
   IOMEM( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE )
#define io_v2p( x )             \
   ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )

#define __MREG(x)	IOMEM(io_p2v(x))

#ifndef __ASSEMBLY__

# define __REG(x)	(*((volatile unsigned long __iomem *)io_p2v(x)))
# define __PREG(x)	(io_v2p((unsigned long)&(x)))

#else

# define __REG(x)	io_p2v(x)
# define __PREG(x)	io_v2p(x)

#endif

#include "SA-1100.h"

#endif  /* _ASM_ARCH_HARDWARE_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/irqs.h
 *
 * Copyright (C) 1996 Russell King
 * Copyright (C) 1998 Deborah Wallach (updates for SA1100/Brutus).
 * Copyright (C) 1999 Nicolas Pitre (full GPIO irq isolation)
 *
 * 2001/11/14	RMK	Cleaned up and standardised a lot of the IRQs.
 */

#define	IRQ_GPIO0_SC		1
#define	IRQ_GPIO1_SC		2
#define	IRQ_GPIO2_SC		3
#define	IRQ_GPIO3_SC		4
#define	IRQ_GPIO4_SC		5
#define	IRQ_GPIO5_SC		6
#define	IRQ_GPIO6_SC		7
#define	IRQ_GPIO7_SC		8
#define	IRQ_GPIO8_SC		9
#define	IRQ_GPIO9_SC		10
#define	IRQ_GPIO10_SC		11
#define	IRQ_GPIO11_27		12
#define	IRQ_LCD			13	/* LCD controller           */
#define	IRQ_Ser0UDC		14	/* Ser. port 0 UDC          */
#define	IRQ_Ser1SDLC		15	/* Ser. port 1 SDLC         */
#define	IRQ_Ser1UART		16	/* Ser. port 1 UART         */
#define	IRQ_Ser2ICP		17	/* Ser. port 2 ICP          */
#define	IRQ_Ser3UART		18	/* Ser. port 3 UART         */
#define	IRQ_Ser4MCP		19	/* Ser. port 4 MCP          */
#define	IRQ_Ser4SSP		20	/* Ser. port 4 SSP          */
#define	IRQ_DMA0		21	/* DMA controller channel 0 */
#define	IRQ_DMA1		22	/* DMA controller channel 1 */
#define	IRQ_DMA2		23	/* DMA controller channel 2 */
#define	IRQ_DMA3		24	/* DMA controller channel 3 */
#define	IRQ_DMA4		25	/* DMA controller channel 4 */
#define	IRQ_DMA5		26	/* DMA controller channel 5 */
#define	IRQ_OST0		27	/* OS Timer match 0         */
#define	IRQ_OST1		28	/* OS Timer match 1         */
#define	IRQ_OST2		29	/* OS Timer match 2         */
#define	IRQ_OST3		30	/* OS Timer match 3         */
#define	IRQ_RTC1Hz		31	/* RTC 1 Hz clock           */
#define	IRQ_RTCAlrm		32	/* RTC Alarm                */

#define	IRQ_GPIO0		33
#define	IRQ_GPIO1		34
#define	IRQ_GPIO2		35
#define	IRQ_GPIO3		36
#define	IRQ_GPIO4		37
#define	IRQ_GPIO5		38
#define	IRQ_GPIO6		39
#define	IRQ_GPIO7		40
#define	IRQ_GPIO8		41
#define	IRQ_GPIO9		42
#define	IRQ_GPIO10		43
#define	IRQ_GPIO11		44
#define	IRQ_GPIO12		45
#define	IRQ_GPIO13		46
#define	IRQ_GPIO14		47
#define	IRQ_GPIO15		48
#define	IRQ_GPIO16		49
#define	IRQ_GPIO17		50
#define	IRQ_GPIO18		51
#define	IRQ_GPIO19		52
#define	IRQ_GPIO20		53
#define	IRQ_GPIO21		54
#define	IRQ_GPIO22		55
#define	IRQ_GPIO23		56
#define	IRQ_GPIO24		57
#define	IRQ_GPIO25		58
#define	IRQ_GPIO26		59
#define	IRQ_GPIO27		60

/*
 * The next 16 interrupts are for board specific purposes.  Since
 * the kernel can only run on one machine at a time, we can re-use
 * these.  If you need more, increase IRQ_BOARD_END, but keep it
 * within sensible limits.  IRQs 61 to 76 are available.
 */
#define IRQ_BOARD_START		61
#define IRQ_BOARD_END		77

/*
 * Figure out the MAX IRQ number.
 *
 * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
 * allocate their IRQs above NR_IRQS.
 *
 * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
 * to be included in the NR_IRQS calculation.
 */
#ifdef CONFIG_SHARP_LOCOMO
#define NR_IRQS_LOCOMO		4
#else
#define NR_IRQS_LOCOMO		0
#endif

#ifndef NR_IRQS
#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
#endif
#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/mach-sa1100/include/mach/jornada720.h
 *
 * SSP/MCU communication definitions for HP Jornada 710/720/728
 *
 * Copyright 2007,2008 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
 *  Copyright 2000 John Ankcorn <jca@lcs.mit.edu>
 */

 /* HP Jornada 7xx microprocessor commands */
#define GETBATTERYDATA		0xc0
#define GETSCANKEYCODE		0x90
#define GETTOUCHSAMPLES		0xa0
#define GETCONTRAST		0xD0
#define SETCONTRAST		0xD1
#define GETBRIGHTNESS		0xD2
#define SETBRIGHTNESS		0xD3
#define CONTRASTOFF		0xD8
#define BRIGHTNESSOFF		0xD9
#define PWMOFF			0xDF
#define TXDUMMY			0x11
#define ERRORCODE		0x00

extern void jornada_ssp_start(void);
extern void jornada_ssp_end(void);
extern int jornada_ssp_inout(u8 byte);
extern int jornada_ssp_byte(u8 byte);


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/memory.h
 *
 * Copyright (C) 1999-2000 Nicolas Pitre <nico@fluxnic.net>
 */

#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H

#include <linux/sizes.h>

/*
 * Because of the wide memory address space between physical RAM banks on the
 * SA1100, it's much convenient to use Linux's SparseMEM support to implement
 * our memory map representation.  Assuming all memory nodes have equal access
 * characteristics, we then have generic discontiguous memory support.
 *
 * The sparsemem banks are matched with the physical memory bank addresses
 * which are incidentally the same as virtual addresses.
 *
 * 	node 0:  0xc0000000 - 0xc7ffffff
 * 	node 1:  0xc8000000 - 0xcfffffff
 * 	node 2:  0xd0000000 - 0xd7ffffff
 * 	node 3:  0xd8000000 - 0xdfffffff
 */
#define MAX_PHYSMEM_BITS	32
#define SECTION_SIZE_BITS	27

/*
 * Cache flushing area - SA1100 zero bank
 */
#define FLUSH_BASE_PHYS		0xe0000000
#define FLUSH_BASE		0xf5000000
#define FLUSH_BASE_MINICACHE	0xf5100000

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * MTD primitives for XIP support. Architecture specific functions
 *
 * Do not include this file directly. It's included from linux/mtd/xip.h
 *
 * Author:	Nicolas Pitre
 * Created:	Nov 2, 2004
 * Copyright:	(C) 2004 MontaVista Software, Inc.
 */

#ifndef __ARCH_SA1100_MTD_XIP_H__
#define __ARCH_SA1100_MTD_XIP_H__

#include <mach/hardware.h>

#define xip_irqpending()	(ICIP & ICMR)

/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
#define xip_currtime()		readl_relaxed(OSCR)
#define xip_elapsed_since(x)	(signed)((readl_relaxed(OSCR) - (x)) / 4)

#endif /* __ARCH_SA1100_MTD_XIP_H__ */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/mach-sa1100/include/mach/nanoengine.h
 *
 * This file contains the hardware specific definitions for nanoEngine.
 * Only include this file from SA1100-specific files.
 *
 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
 */
#ifndef __ASM_ARCH_NANOENGINE_H
#define __ASM_ARCH_NANOENGINE_H

#include <mach/irqs.h>

#define GPIO_PC_READY0	11 /* ready for socket 0 (active high)*/
#define GPIO_PC_READY1	12 /* ready for socket 1 (active high) */
#define GPIO_PC_CD0	13 /* detect for socket 0 (active low) */
#define GPIO_PC_CD1	14 /* detect for socket 1 (active low) */
#define GPIO_PC_RESET0	15 /* reset socket 0 */
#define GPIO_PC_RESET1	16 /* reset socket 1 */

#define NANOENGINE_IRQ_GPIO_PCI		IRQ_GPIO0
#define NANOENGINE_IRQ_GPIO_PC_READY0	IRQ_GPIO11
#define NANOENGINE_IRQ_GPIO_PC_READY1	IRQ_GPIO12
#define NANOENGINE_IRQ_GPIO_PC_CD0	IRQ_GPIO13
#define NANOENGINE_IRQ_GPIO_PC_CD1	IRQ_GPIO14

/*
 * nanoEngine Memory Map:
 *
 * 0000.0000 - 003F.0000 -   4 MB Flash
 * C000.0000 - C1FF.FFFF -  32 MB SDRAM
 * 1860.0000 - 186F.FFFF -   1 MB Internal PCI Memory Read/Write
 * 18A1.0000 - 18A1.FFFF -  64 KB Internal PCI Config Space
 * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode
 * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode
 *
 */

#define NANO_PCI_MEM_RW_PHYS		0x18600000
#define NANO_PCI_MEM_RW_VIRT		0xf1000000
#define NANO_PCI_MEM_RW_SIZE		SZ_1M
#define NANO_PCI_CONFIG_SPACE_PHYS	0x18A10000
#define NANO_PCI_CONFIG_SPACE_VIRT	0xf2000000
#define NANO_PCI_CONFIG_SPACE_SIZE	SZ_64K

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/neponset.h
 *
 * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
 *
 * This file contains the hardware specific definitions for Assabet
 * Only include this file from SA1100-specific files.
 *
 * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
 *      Definitions for Neponset added.
 */
#ifndef __ASM_ARCH_NEPONSET_H
#define __ASM_ARCH_NEPONSET_H

/*
 * Neponset definitions:
 */
#define NCR_GP01_OFF		(1<<0)
#define NCR_TP_PWR_EN		(1<<1)
#define NCR_MS_PWR_EN		(1<<2)
#define NCR_ENET_OSC_EN		(1<<3)
#define NCR_SPI_KB_WK_UP	(1<<4)
#define NCR_A0VPP		(1<<5)
#define NCR_A1VPP		(1<<6)

void neponset_ncr_frob(unsigned int, unsigned int);
#define neponset_ncr_set(v)	neponset_ncr_frob(0, v)
#define neponset_ncr_clear(v)	neponset_ncr_frob(v, 0)

#endif


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

#include "hardware.h"

#define RESET_STATUS_HARDWARE	(1 << 0)	/* Hardware Reset */
#define RESET_STATUS_WATCHDOG	(1 << 1)	/* Watchdog Reset */
#define RESET_STATUS_LOWPOWER	(1 << 2)	/* Exit from Low Power/Sleep */
#define RESET_STATUS_GPIO	(1 << 3)	/* GPIO Reset */
#define RESET_STATUS_ALL	(0xf)

static inline void clear_reset_status(unsigned int mask)
{
	RCSR = mask;
}

#endif /* __ASM_ARCH_RESET_H */


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

/* taken from comp.os.inferno Tue, 12 Sep 2000 09:21:50 GMT,
 * written by <forsyth@vitanuova.com> */

#define SHANNON_GPIO_SPI_FLASH		GPIO_GPIO (0)	/* Output - Driven low, enables SPI to flash */
#define SHANNON_GPIO_SPI_DSP		GPIO_GPIO (1)	/* Output - Driven low, enables SPI to DSP */
/* lcd lower = GPIO 2-9 */
#define SHANNON_GPIO_SPI_OUTPUT		GPIO_GPIO (10)	/* Output - SPI output to DSP */
#define SHANNON_GPIO_SPI_INPUT		GPIO_GPIO (11)	/* Input  - SPI input from DSP */
#define SHANNON_GPIO_SPI_CLOCK		GPIO_GPIO (12)	/* Output - Clock for SPI */
#define SHANNON_GPIO_SPI_FRAME		GPIO_GPIO (13)	/* Output - Frame marker - not used */
#define SHANNON_GPIO_SPI_RTS		GPIO_GPIO (14)	/* Input  - SPI Ready to Send */
#define SHANNON_IRQ_GPIO_SPI_RTS	IRQ_GPIO14
#define SHANNON_GPIO_SPI_CTS		GPIO_GPIO (15)	/* Output - SPI Clear to Send */
#define SHANNON_GPIO_IRQ_CODEC		GPIO_GPIO (16)	/* in, irq from ucb1200 */
#define SHANNON_IRQ_GPIO_IRQ_CODEC	IRQ_GPIO16
#define SHANNON_GPIO_DSP_RESET		GPIO_GPIO (17)	/* Output - Drive low to reset the DSP */
#define SHANNON_GPIO_CODEC_RESET	GPIO_GPIO (18)	/* Output - Drive low to reset the UCB1x00 */
#define SHANNON_GPIO_U3_RTS		GPIO_GPIO (19)	/* ?? */
#define SHANNON_GPIO_U3_CTS		GPIO_GPIO (20)	/* ?? */
#define SHANNON_GPIO_SENSE_12V		GPIO_GPIO (21)	/* Input, 12v flash unprotect detected */
#define SHANNON_GPIO_DISP_EN		22		/* out */
/* XXX GPIO 23 unaccounted for */
#define SHANNON_GPIO_EJECT_0		24		/* in */
#define SHANNON_GPIO_EJECT_1		25		/* in */
#define SHANNON_GPIO_RDY_0		26		/* in */
#define SHANNON_GPIO_RDY_1		27		/* in */

/* MCP UCB codec GPIO pins... */

#define SHANNON_UCB_GPIO_BACKLIGHT	9
#define SHANNON_UCB_GPIO_BRIGHT_MASK  	7
#define SHANNON_UCB_GPIO_BRIGHT		6
#define SHANNON_UCB_GPIO_CONTRAST_MASK	0x3f
#define SHANNON_UCB_GPIO_CONTRAST	0

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/simpad.h
 *
 * based of assabet.h same as HUW_Webpanel
 *
 * This file contains the hardware specific definitions for SIMpad
 *
 * 2001/05/14 Juergen Messerer <juergen.messerer@freesurf.ch>
 */

#ifndef __ASM_ARCH_SIMPAD_H
#define __ASM_ARCH_SIMPAD_H

#define GPIO_UART1_RTS	GPIO_GPIO14
#define GPIO_UART1_DTR	GPIO_GPIO7
#define GPIO_UART1_CTS	GPIO_GPIO8
#define GPIO_UART1_DCD	GPIO_GPIO23
#define GPIO_UART1_DSR	GPIO_GPIO6

#define GPIO_UART3_RTS	GPIO_GPIO12
#define GPIO_UART3_DTR	GPIO_GPIO16
#define GPIO_UART3_CTS	GPIO_GPIO13
#define GPIO_UART3_DCD	GPIO_GPIO18
#define GPIO_UART3_DSR	GPIO_GPIO17

#define GPIO_POWER_BUTTON	GPIO_GPIO0
#define GPIO_UCB1300_IRQ	GPIO_GPIO22	/* UCB GPIO and touchscreen */

#define IRQ_UART1_CTS	IRQ_GPIO15
#define IRQ_UART1_DCD	GPIO_GPIO23
#define IRQ_UART1_DSR	GPIO_GPIO6
#define IRQ_UART3_CTS	GPIO_GPIO13
#define IRQ_UART3_DCD	GPIO_GPIO18
#define IRQ_UART3_DSR	GPIO_GPIO17

#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22
#define IRQ_GPIO_POWER_BUTTON IRQ_GPIO0

/*---  PCMCIA  ---*/
#define GPIO_CF_CD              24
#define GPIO_CF_IRQ             1

/*--- SmartCard ---*/
#define GPIO_SMART_CARD		GPIO_GPIO10
#define IRQ_GPIO_SMARD_CARD	IRQ_GPIO10

/*--- ucb1x00 GPIO ---*/
#define SIMPAD_UCB1X00_GPIO_BASE	(GPIO_MAX + 1)
#define SIMPAD_UCB1X00_GPIO_PROG1	(SIMPAD_UCB1X00_GPIO_BASE)
#define SIMPAD_UCB1X00_GPIO_PROG2	(SIMPAD_UCB1X00_GPIO_BASE + 1)
#define SIMPAD_UCB1X00_GPIO_UP		(SIMPAD_UCB1X00_GPIO_BASE + 2)
#define SIMPAD_UCB1X00_GPIO_DOWN	(SIMPAD_UCB1X00_GPIO_BASE + 3)
#define SIMPAD_UCB1X00_GPIO_LEFT	(SIMPAD_UCB1X00_GPIO_BASE + 4)
#define SIMPAD_UCB1X00_GPIO_RIGHT	(SIMPAD_UCB1X00_GPIO_BASE + 5)
#define SIMPAD_UCB1X00_GPIO_6		(SIMPAD_UCB1X00_GPIO_BASE + 6)
#define SIMPAD_UCB1X00_GPIO_7		(SIMPAD_UCB1X00_GPIO_BASE + 7)
#define SIMPAD_UCB1X00_GPIO_HEADSET	(SIMPAD_UCB1X00_GPIO_BASE + 8)
#define SIMPAD_UCB1X00_GPIO_SPEAKER	(SIMPAD_UCB1X00_GPIO_BASE + 9)

/*--- CS3 Latch ---*/
#define SIMPAD_CS3_GPIO_BASE		(GPIO_MAX + 11)
#define SIMPAD_CS3_VCC_5V_EN		(SIMPAD_CS3_GPIO_BASE)
#define SIMPAD_CS3_VCC_3V_EN		(SIMPAD_CS3_GPIO_BASE + 1)
#define SIMPAD_CS3_EN1			(SIMPAD_CS3_GPIO_BASE + 2)
#define SIMPAD_CS3_EN0			(SIMPAD_CS3_GPIO_BASE + 3)
#define SIMPAD_CS3_DISPLAY_ON		(SIMPAD_CS3_GPIO_BASE + 4)
#define SIMPAD_CS3_PCMCIA_BUFF_DIS	(SIMPAD_CS3_GPIO_BASE + 5)
#define SIMPAD_CS3_MQ_RESET		(SIMPAD_CS3_GPIO_BASE + 6)
#define SIMPAD_CS3_PCMCIA_RESET		(SIMPAD_CS3_GPIO_BASE + 7)
#define SIMPAD_CS3_DECT_POWER_ON	(SIMPAD_CS3_GPIO_BASE + 8)
#define SIMPAD_CS3_IRDA_SD		(SIMPAD_CS3_GPIO_BASE + 9)
#define SIMPAD_CS3_RS232_ON		(SIMPAD_CS3_GPIO_BASE + 10)
#define SIMPAD_CS3_SD_MEDIAQ		(SIMPAD_CS3_GPIO_BASE + 11)
#define SIMPAD_CS3_LED2_ON		(SIMPAD_CS3_GPIO_BASE + 12)
#define SIMPAD_CS3_IRDA_MODE		(SIMPAD_CS3_GPIO_BASE + 13)
#define SIMPAD_CS3_ENABLE_5V		(SIMPAD_CS3_GPIO_BASE + 14)
#define SIMPAD_CS3_RESET_SIMCARD	(SIMPAD_CS3_GPIO_BASE + 15)

#define SIMPAD_CS3_PCMCIA_BVD1		(SIMPAD_CS3_GPIO_BASE + 16)
#define SIMPAD_CS3_PCMCIA_BVD2		(SIMPAD_CS3_GPIO_BASE + 17)
#define SIMPAD_CS3_PCMCIA_VS1		(SIMPAD_CS3_GPIO_BASE + 18)
#define SIMPAD_CS3_PCMCIA_VS2		(SIMPAD_CS3_GPIO_BASE + 19)
#define SIMPAD_CS3_LOCK_IND		(SIMPAD_CS3_GPIO_BASE + 20)
#define SIMPAD_CS3_CHARGING_STATE	(SIMPAD_CS3_GPIO_BASE + 21)
#define SIMPAD_CS3_PCMCIA_SHORT		(SIMPAD_CS3_GPIO_BASE + 22)
#define SIMPAD_CS3_GPIO_23		(SIMPAD_CS3_GPIO_BASE + 23)

#define CS3_BASE        IOMEM(0xf1000000)

long simpad_get_cs3_ro(void);
long simpad_get_cs3_shadow(void);
void simpad_set_cs3_bit(int value);
void simpad_clear_cs3_bit(int value);

#define VCC_5V_EN	0x0001 /* For 5V PCMCIA */
#define VCC_3V_EN	0x0002 /* FOR 3.3V PCMCIA */
#define EN1		0x0004 /* This is only for EPROM's */
#define EN0		0x0008 /* Both should be enable for 3.3V or 5V */
#define DISPLAY_ON	0x0010
#define PCMCIA_BUFF_DIS	0x0020
#define MQ_RESET	0x0040
#define PCMCIA_RESET	0x0080
#define DECT_POWER_ON	0x0100
#define IRDA_SD		0x0200 /* Shutdown for powersave */
#define RS232_ON	0x0400
#define SD_MEDIAQ	0x0800 /* Shutdown for powersave */
#define LED2_ON		0x1000
#define IRDA_MODE	0x2000 /* Fast/Slow IrDA mode */
#define ENABLE_5V	0x4000 /* Enable 5V circuit */
#define RESET_SIMCARD	0x8000

#define PCMCIA_BVD1	0x01
#define PCMCIA_BVD2	0x02
#define PCMCIA_VS1	0x04
#define PCMCIA_VS2	0x08
#define LOCK_IND	0x10
#define CHARGING_STATE	0x20
#define PCMCIA_SHORT	0x40

/*--- Battery ---*/
struct simpad_battery {
	unsigned char ac_status;	/* line connected yes/no */
	unsigned char status;		/* battery loading yes/no */
	unsigned char percentage;	/* percentage loaded */
	unsigned short life;		/* life till empty */
};

/* These should match the apm_bios.h definitions */
#define SIMPAD_AC_STATUS_AC_OFFLINE      0x00
#define SIMPAD_AC_STATUS_AC_ONLINE       0x01
#define SIMPAD_AC_STATUS_AC_BACKUP       0x02   /* What does this mean? */
#define SIMPAD_AC_STATUS_AC_UNKNOWN      0xff

/* These bitfields are rarely "or'd" together */
#define SIMPAD_BATT_STATUS_HIGH          0x01
#define SIMPAD_BATT_STATUS_LOW           0x02
#define SIMPAD_BATT_STATUS_CRITICAL      0x04
#define SIMPAD_BATT_STATUS_CHARGING      0x08
#define SIMPAD_BATT_STATUS_CHARGE_MAIN   0x10
#define SIMPAD_BATT_STATUS_DEAD          0x20   /* Battery will not charge */
#define SIMPAD_BATT_NOT_INSTALLED        0x20   /* For expansion pack batteries */
#define SIMPAD_BATT_STATUS_FULL          0x40   /* Battery fully charged (and connected to AC) */
#define SIMPAD_BATT_STATUS_NOBATT        0x80
#define SIMPAD_BATT_STATUS_UNKNOWN       0xff

extern int simpad_get_battery(struct simpad_battery* );

#endif // __ASM_ARCH_SIMPAD_H


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/mach-sa1100/include/mach/uncompress.h
 *
 * (C) 1999 Nicolas Pitre <nico@fluxnic.net>
 *
 * Reorganised to be machine independent.
 */

#include "hardware.h"

#define IOMEM(x)	(x)

/*
 * The following code assumes the serial port has already been
 * initialized by the bootloader.  We search for the first enabled
 * port in the most probable order.  If you didn't setup a port in
 * your bootloader then nothing will appear (which might be desired).
 */

#define UART(x)		(*(volatile unsigned long *)(serial_port + (x)))

static inline void putc(int c)
{
	unsigned long serial_port;

	do {
		serial_port = _Ser3UTCR0;
		if (UART(UTCR3) & UTCR3_TXE) break;
		serial_port = _Ser1UTCR0;
		if (UART(UTCR3) & UTCR3_TXE) break;
		serial_port = _Ser2UTCR0;
		if (UART(UTCR3) & UTCR3_TXE) break;
		return;
	} while (0);

	/* wait for space in the UART's transmitter */
	while (!(UART(UTSR1) & UTSR1_TNF))
		barrier();

	/* send the character out. */
	UART(UTDR) = c;
}

static inline void flush(void)
{
}

/*
 * Nothing to do for these
 */
#define arch_decomp_setup()


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-sa1100/jornada720.c
 *
 * HP Jornada720 init code
 *
 * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
 * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
 *  Copyright (C) 2005 Michael Gernoth <michael@gernoth.net>
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/gpio/machine.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <video/s1d13xxxfb.h>

#include <asm/hardware/sa1111.h>
#include <asm/page.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>

#include <mach/hardware.h>
#include <mach/irqs.h>

#include "generic.h"

/*
 * HP Documentation referred in this file:
 * http://www.jlime.com/downloads/development/docs/jornada7xx/jornada720.txt
 */

/* line 110 of HP's doc */
#define TUCR_VAL	0x20000400

/* memory space (line 52 of HP's doc) */
#define SA1111REGSTART	0x40000000
#define SA1111REGLEN	0x00002000
#define EPSONREGSTART	0x48000000
#define EPSONREGLEN	0x00100000
#define EPSONFBSTART	0x48200000
/* 512kB framebuffer */
#define EPSONFBLEN	512*1024

static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
	/* line 344 of HP's doc */
	{0x0001,0x00},	// Miscellaneous Register
	{0x01FC,0x00},	// Display Mode Register
	{0x0004,0x00},	// General IO Pins Configuration Register 0
	{0x0005,0x00},	// General IO Pins Configuration Register 1
	{0x0008,0x00},	// General IO Pins Control Register 0
	{0x0009,0x00},	// General IO Pins Control Register 1
	{0x0010,0x01},	// Memory Clock Configuration Register
	{0x0014,0x11},	// LCD Pixel Clock Configuration Register
	{0x0018,0x01},	// CRT/TV Pixel Clock Configuration Register
	{0x001C,0x01},	// MediaPlug Clock Configuration Register
	{0x001E,0x01},	// CPU To Memory Wait State Select Register
	{0x0020,0x00},	// Memory Configuration Register
	{0x0021,0x45},	// DRAM Refresh Rate Register
	{0x002A,0x01},	// DRAM Timings Control Register 0
	{0x002B,0x03},	// DRAM Timings Control Register 1
	{0x0030,0x1c},	// Panel Type Register
	{0x0031,0x00},	// MOD Rate Register
	{0x0032,0x4F},	// LCD Horizontal Display Width Register
	{0x0034,0x07},	// LCD Horizontal Non-Display Period Register
	{0x0035,0x01},	// TFT FPLINE Start Position Register
	{0x0036,0x0B},	// TFT FPLINE Pulse Width Register
	{0x0038,0xEF},	// LCD Vertical Display Height Register 0
	{0x0039,0x00},	// LCD Vertical Display Height Register 1
	{0x003A,0x13},	// LCD Vertical Non-Display Period Register
	{0x003B,0x0B},	// TFT FPFRAME Start Position Register
	{0x003C,0x01},	// TFT FPFRAME Pulse Width Register
	{0x0040,0x05},	// LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
	{0x0041,0x00},	// LCD Miscellaneous Register
	{0x0042,0x00},	// LCD Display Start Address Register 0
	{0x0043,0x00},	// LCD Display Start Address Register 1
	{0x0044,0x00},	// LCD Display Start Address Register 2
	{0x0046,0x80},	// LCD Memory Address Offset Register 0
	{0x0047,0x02},	// LCD Memory Address Offset Register 1
	{0x0048,0x00},	// LCD Pixel Panning Register
	{0x004A,0x00},	// LCD Display FIFO High Threshold Control Register
	{0x004B,0x00},	// LCD Display FIFO Low Threshold Control Register
	{0x0050,0x4F},	// CRT/TV Horizontal Display Width Register
	{0x0052,0x13},	// CRT/TV Horizontal Non-Display Period Register
	{0x0053,0x01},	// CRT/TV HRTC Start Position Register
	{0x0054,0x0B},	// CRT/TV HRTC Pulse Width Register
	{0x0056,0xDF},	// CRT/TV Vertical Display Height Register 0
	{0x0057,0x01},	// CRT/TV Vertical Display Height Register 1
	{0x0058,0x2B},	// CRT/TV Vertical Non-Display Period Register
	{0x0059,0x09},	// CRT/TV VRTC Start Position Register
	{0x005A,0x01},	// CRT/TV VRTC Pulse Width Register
	{0x005B,0x10},	// TV Output Control Register
	{0x0060,0x03},	// CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
	{0x0062,0x00},	// CRT/TV Display Start Address Register 0
	{0x0063,0x00},	// CRT/TV Display Start Address Register 1
	{0x0064,0x00},	// CRT/TV Display Start Address Register 2
	{0x0066,0x40},	// CRT/TV Memory Address Offset Register 0
	{0x0067,0x01},	// CRT/TV Memory Address Offset Register 1
	{0x0068,0x00},	// CRT/TV Pixel Panning Register
	{0x006A,0x00},	// CRT/TV Display FIFO High Threshold Control Register
	{0x006B,0x00},	// CRT/TV Display FIFO Low Threshold Control Register
	{0x0070,0x00},	// LCD Ink/Cursor Control Register
	{0x0071,0x01},	// LCD Ink/Cursor Start Address Register
	{0x0072,0x00},	// LCD Cursor X Position Register 0
	{0x0073,0x00},	// LCD Cursor X Position Register 1
	{0x0074,0x00},	// LCD Cursor Y Position Register 0
	{0x0075,0x00},	// LCD Cursor Y Position Register 1
	{0x0076,0x00},	// LCD Ink/Cursor Blue Color 0 Register
	{0x0077,0x00},	// LCD Ink/Cursor Green Color 0 Register
	{0x0078,0x00},	// LCD Ink/Cursor Red Color 0 Register
	{0x007A,0x1F},	// LCD Ink/Cursor Blue Color 1 Register
	{0x007B,0x3F},	// LCD Ink/Cursor Green Color 1 Register
	{0x007C,0x1F},	// LCD Ink/Cursor Red Color 1 Register
	{0x007E,0x00},	// LCD Ink/Cursor FIFO Threshold Register
	{0x0080,0x00},	// CRT/TV Ink/Cursor Control Register
	{0x0081,0x01},	// CRT/TV Ink/Cursor Start Address Register
	{0x0082,0x00},	// CRT/TV Cursor X Position Register 0
	{0x0083,0x00},	// CRT/TV Cursor X Position Register 1
	{0x0084,0x00},	// CRT/TV Cursor Y Position Register 0
	{0x0085,0x00},	// CRT/TV Cursor Y Position Register 1
	{0x0086,0x00},	// CRT/TV Ink/Cursor Blue Color 0 Register
	{0x0087,0x00},	// CRT/TV Ink/Cursor Green Color 0 Register
	{0x0088,0x00},	// CRT/TV Ink/Cursor Red Color 0 Register
	{0x008A,0x1F},	// CRT/TV Ink/Cursor Blue Color 1 Register
	{0x008B,0x3F},	// CRT/TV Ink/Cursor Green Color 1 Register
	{0x008C,0x1F},	// CRT/TV Ink/Cursor Red Color 1 Register
	{0x008E,0x00},	// CRT/TV Ink/Cursor FIFO Threshold Register
	{0x0100,0x00},	// BitBlt Control Register 0
	{0x0101,0x00},	// BitBlt Control Register 1
	{0x0102,0x00},	// BitBlt ROP Code/Color Expansion Register
	{0x0103,0x00},	// BitBlt Operation Register
	{0x0104,0x00},	// BitBlt Source Start Address Register 0
	{0x0105,0x00},	// BitBlt Source Start Address Register 1
	{0x0106,0x00},	// BitBlt Source Start Address Register 2
	{0x0108,0x00},	// BitBlt Destination Start Address Register 0
	{0x0109,0x00},	// BitBlt Destination Start Address Register 1
	{0x010A,0x00},	// BitBlt Destination Start Address Register 2
	{0x010C,0x00},	// BitBlt Memory Address Offset Register 0
	{0x010D,0x00},	// BitBlt Memory Address Offset Register 1
	{0x0110,0x00},	// BitBlt Width Register 0
	{0x0111,0x00},	// BitBlt Width Register 1
	{0x0112,0x00},	// BitBlt Height Register 0
	{0x0113,0x00},	// BitBlt Height Register 1
	{0x0114,0x00},	// BitBlt Background Color Register 0
	{0x0115,0x00},	// BitBlt Background Color Register 1
	{0x0118,0x00},	// BitBlt Foreground Color Register 0
	{0x0119,0x00},	// BitBlt Foreground Color Register 1
	{0x01E0,0x00},	// Look-Up Table Mode Register
	{0x01E2,0x00},	// Look-Up Table Address Register
	/* not sure, wouldn't like to mess with the driver */
	{0x01E4,0x00},	// Look-Up Table Data Register
	/* jornada doc says 0x00, but I trust the driver */
	{0x01F0,0x10},	// Power Save Configuration Register
	{0x01F1,0x00},	// Power Save Status Register
	{0x01F4,0x00},	// CPU-to-Memory Access Watchdog Timer Register
	{0x01FC,0x01},	// Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
};

static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
	.initregs		= s1d13xxxfb_initregs,
	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
	.platform_init_video	= NULL
};

static struct resource s1d13xxxfb_resources[] = {
	[0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN),
	[1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN),
};

static struct platform_device s1d13xxxfb_device = {
	.name		= S1D_DEVICENAME,
	.id		= 0,
	.dev		= {
		.platform_data	= &s1d13xxxfb_data,
	},
	.num_resources	= ARRAY_SIZE(s1d13xxxfb_resources),
	.resource	= s1d13xxxfb_resources,
};

static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
	.dev_id = "1800",
	.table = {
		GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct resource sa1111_resources[] = {
	[0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
	[1] = DEFINE_RES_IRQ(IRQ_GPIO1),
};

static struct sa1111_platform_data sa1111_info = {
	.disable_devs	= SA1111_DEVID_PS2_MSE,
};

static u64 sa1111_dmamask = 0xffffffffUL;

static struct platform_device sa1111_device = {
	.name		= "sa1111",
	.id		= 0,
	.dev		= {
		.dma_mask = &sa1111_dmamask,
		.coherent_dma_mask = 0xffffffff,
		.platform_data = &sa1111_info,
	},
	.num_resources	= ARRAY_SIZE(sa1111_resources),
	.resource	= sa1111_resources,
};

static struct platform_device jornada_ssp_device = {
	.name           = "jornada_ssp",
	.id             = -1,
};

static struct resource jornada_kbd_resources[] = {
	DEFINE_RES_IRQ(IRQ_GPIO0),
};

static struct platform_device jornada_kbd_device = {
	.name		= "jornada720_kbd",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(jornada_kbd_resources),
	.resource	= jornada_kbd_resources,
};

static struct gpiod_lookup_table jornada_ts_gpiod_table = {
	.dev_id		= "jornada_ts",
	.table		= {
		GPIO_LOOKUP("gpio", 9, "penup", GPIO_ACTIVE_HIGH),
	},
};

static struct platform_device jornada_ts_device = {
	.name		= "jornada_ts",
	.id		= -1,
};

static struct platform_device *devices[] __initdata = {
	&sa1111_device,
	&jornada_ssp_device,
	&s1d13xxxfb_device,
	&jornada_kbd_device,
	&jornada_ts_device,
};

static int __init jornada720_init(void)
{
	int ret = -ENODEV;

	if (machine_is_jornada720()) {
		/* we want to use gpio20 as input to drive the clock of our uart 3 */
		GPDR |= GPIO_GPIO20;	/* Clear gpio20 pin as input */
		TUCR = TUCR_VAL;
		GPSR = GPIO_GPIO20;	/* start gpio20 pin */
		udelay(1);
		GPCR = GPIO_GPIO20;	/* stop gpio20 */
		udelay(1);
		GPSR = GPIO_GPIO20;	/* restart gpio20 */
		udelay(20);		/* give it some time to restart */

		gpiod_add_lookup_table(&jornada_ts_gpiod_table);
		gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);

		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
	}

	return ret;
}

arch_initcall(jornada720_init);

static struct map_desc jornada720_io_desc[] __initdata = {
	{	/* Epson registers */
		.virtual	= 0xf0000000,
		.pfn		= __phys_to_pfn(EPSONREGSTART),
		.length		= EPSONREGLEN,
		.type		= MT_DEVICE
	}, {	/* Epson frame buffer */
		.virtual	= 0xf1000000,
		.pfn		= __phys_to_pfn(EPSONFBSTART),
		.length		= EPSONFBLEN,
		.type		= MT_DEVICE
	}
};

static void __init jornada720_map_io(void)
{
	sa1100_map_io();
	iotable_init(jornada720_io_desc, ARRAY_SIZE(jornada720_io_desc));

	sa1100_register_uart(0, 3);
	sa1100_register_uart(1, 1);
}

static struct mtd_partition jornada720_partitions[] = {
	{
		.name		= "JORNADA720 boot firmware",
		.size		= 0x00040000,
		.offset		= 0,
		.mask_flags	= MTD_WRITEABLE, /* force read-only */
	}, {
		.name		= "JORNADA720 kernel",
		.size		= 0x000c0000,
		.offset		= 0x00040000,
	}, {
		.name		= "JORNADA720 params",
		.size		= 0x00040000,
		.offset		= 0x00100000,
	}, {
		.name		= "JORNADA720 initrd",
		.size		= 0x00100000,
		.offset		= 0x00140000,
	}, {
		.name		= "JORNADA720 root cramfs",
		.size		= 0x00300000,
		.offset		= 0x00240000,
	}, {
		.name		= "JORNADA720 usr cramfs",
		.size		= 0x00800000,
		.offset		= 0x00540000,
	}, {
		.name		= "JORNADA720 usr local",
		.size		= 0, /* will expand to the end of the flash */
		.offset		= 0x00d00000,
	}
};

static void jornada720_set_vpp(int vpp)
{
	if (vpp)
		/* enabling flash write (line 470 of HP's doc) */
		PPSR |= PPC_LDD7;
	else
		/* disabling flash write (line 470 of HP's doc) */
		PPSR &= ~PPC_LDD7;
	PPDR |= PPC_LDD7;
}

static struct flash_platform_data jornada720_flash_data = {
	.map_name	= "cfi_probe",
	.set_vpp	= jornada720_set_vpp,
	.parts		= jornada720_partitions,
	.nr_parts	= ARRAY_SIZE(jornada720_partitions),
};

static struct resource jornada720_flash_resource =
	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);

static void __init jornada720_mach_init(void)
{
	sa11x0_register_mtd(&jornada720_flash_data, &jornada720_flash_resource, 1);
}

MACHINE_START(JORNADA720, "HP Jornada 720")
	/* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */
	.atag_offset	= 0x100,
	.map_io		= jornada720_map_io,
	.nr_irqs	= SA1100_NR_IRQS,
	.init_irq	= sa1100_init_irq,
	.init_time	= sa1100_timer_init,
	.init_machine	= jornada720_mach_init,
	.init_late	= sa11x0_init_late,
#ifdef CONFIG_SA1111
	.dma_zone_size	= SZ_1M,
#endif
	.restart	= sa11x0_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/**
 *  arch/arm/mac-sa1100/jornada720_ssp.c
 *
 *  Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
 *   Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
 *
 *  SSP driver for the HP Jornada 710/720/728
 */

#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/io.h>

#include <mach/hardware.h>
#include <mach/jornada720.h>
#include <asm/hardware/ssp.h>

static DEFINE_SPINLOCK(jornada_ssp_lock);
static unsigned long jornada_ssp_flags;

/**
 * jornada_ssp_reverse - reverses input byte
 *
 * we need to reverse all data we receive from the mcu due to its physical location
 * returns : 01110111 -> 11101110
 */
inline u8 jornada_ssp_reverse(u8 byte)
{
	return
		((0x80 & byte) >> 7) |
		((0x40 & byte) >> 5) |
		((0x20 & byte) >> 3) |
		((0x10 & byte) >> 1) |
		((0x08 & byte) << 1) |
		((0x04 & byte) << 3) |
		((0x02 & byte) << 5) |
		((0x01 & byte) << 7);
};
EXPORT_SYMBOL(jornada_ssp_reverse);

/**
 * jornada_ssp_byte - waits for ready ssp bus and sends byte
 *
 * waits for fifo buffer to clear and then transmits, if it doesn't then we will
 * timeout after <timeout> rounds. Needs mcu running before its called.
 *
 * returns : %mcu output on success
 *	   : %-ETIMEDOUT on timeout
 */
int jornada_ssp_byte(u8 byte)
{
	int timeout = 400000;
	u16 ret;

	while ((GPLR & GPIO_GPIO10)) {
		if (!--timeout) {
			printk(KERN_WARNING "SSP: timeout while waiting for transmit\n");
			return -ETIMEDOUT;
		}
		cpu_relax();
	}

	ret = jornada_ssp_reverse(byte) << 8;

	ssp_write_word(ret);
	ssp_read_word(&ret);

	return jornada_ssp_reverse(ret);
};
EXPORT_SYMBOL(jornada_ssp_byte);

/**
 * jornada_ssp_inout - decide if input is command or trading byte
 *
 * returns : (jornada_ssp_byte(byte)) on success
 *         : %-ETIMEDOUT on timeout failure
 */
int jornada_ssp_inout(u8 byte)
{
	int ret, i;

	/* true means command byte */
	if (byte != TXDUMMY) {
		ret = jornada_ssp_byte(byte);
		/* Proper return to commands is TxDummy */
		if (ret != TXDUMMY) {
			for (i = 0; i < 256; i++)/* flushing bus */
				if (jornada_ssp_byte(TXDUMMY) == -1)
					break;
			return -ETIMEDOUT;
		}
	} else /* Exchange TxDummy for data */
		ret = jornada_ssp_byte(TXDUMMY);

	return ret;
};
EXPORT_SYMBOL(jornada_ssp_inout);

/**
 * jornada_ssp_start - enable mcu
 *
 */
void jornada_ssp_start(void)
{
	spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
	GPCR = GPIO_GPIO25;
	udelay(50);
	return;
};
EXPORT_SYMBOL(jornada_ssp_start);

/**
 * jornada_ssp_end - disable mcu and turn off lock
 *
 */
void jornada_ssp_end(void)
{
	GPSR = GPIO_GPIO25;
	spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
	return;
};
EXPORT_SYMBOL(jornada_ssp_end);

static int jornada_ssp_probe(struct platform_device *dev)
{
	int ret;

	GPSR = GPIO_GPIO25;

	ret = ssp_init();

	/* worked fine, lets not bother with anything else */
	if (!ret) {
		printk(KERN_INFO "SSP: device initialized with irq\n");
		return ret;
	}

	printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n");

	/* init of Serial 4 port */
	Ser4MCCR0 = 0;
	Ser4SSCR0 = 0x0387;
	Ser4SSCR1 = 0x18;

	/* clear out any left over data */
	ssp_flush();

	/* enable MCU */
	jornada_ssp_start();

	/* see if return value makes sense */
	ret = jornada_ssp_inout(GETBRIGHTNESS);

	/* seems like it worked, just feed it with TxDummy to get rid of data */
	if (ret == TXDUMMY)
		jornada_ssp_inout(TXDUMMY);

	jornada_ssp_end();

	/* failed, lets just kill everything */
	if (ret == -ETIMEDOUT) {
		printk(KERN_WARNING "SSP: attempts failed, bailing\n");
		ssp_exit();
		return -ENODEV;
	}

	/* all fine */
	printk(KERN_INFO "SSP: device initialized\n");
	return 0;
};

static int jornada_ssp_remove(struct platform_device *dev)
{
	/* Note that this doesn't actually remove the driver, since theres nothing to remove
	 * It just makes sure everything is turned off */
	GPSR = GPIO_GPIO25;
	ssp_exit();
	return 0;
};

struct platform_driver jornadassp_driver = {
	.probe	= jornada_ssp_probe,
	.remove	= jornada_ssp_remove,
	.driver	= {
		.name	= "jornada_ssp",
	},
};

static int __init jornada_ssp_init(void)
{
	return platform_driver_register(&jornadassp_driver);
}

module_init(jornada_ssp_init);


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * linux/arch/arm/mach-sa1100/lart.c
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/tty.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/platform_device.h>

#include <video/sa1100fb.h>

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

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/irqs.h>

#include "generic.h"

static struct mcp_plat_data lart_mcp_data = {
	.mccr0		= MCCR0_ADM,
	.sclk_rate	= 11981000,
};

#ifdef LART_GREY_LCD
static struct sa1100fb_mach_info lart_grey_info = {
	.pixclock	= 150000,	.bpp		= 4,
	.xres		= 320,		.yres		= 240,

	.hsync_len	= 1,		.vsync_len	= 1,
	.left_margin	= 4,		.upper_margin	= 0,
	.right_margin	= 2,		.lower_margin	= 0,

	.cmap_greyscale	= 1,
	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,

	.lccr0		= LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_COLOR_LCD
static struct sa1100fb_mach_info lart_color_info = {
	.pixclock	= 150000,	.bpp		= 16,
	.xres		= 320,		.yres		= 240,

	.hsync_len	= 2,		.vsync_len	= 3,
	.left_margin	= 69,		.upper_margin	= 14,
	.right_margin	= 8,		.lower_margin	= 4,

	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
	.lccr3		= LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_VIDEO_OUT
static struct sa1100fb_mach_info lart_video_info = {
	.pixclock	= 39721,	.bpp		= 16,
	.xres		= 640,		.yres		= 480,

	.hsync_len	= 95,		.vsync_len	= 2,
	.left_margin	= 40,		.upper_margin	= 32,
	.right_margin	= 24,		.lower_margin	= 11,

	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,

	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
	.lccr3		= LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif

#ifdef LART_KIT01_LCD
static struct sa1100fb_mach_info lart_kit01_info = {
	.pixclock	= 63291,	.bpp		= 16,
	.xres		= 640,		.yres		= 480,

	.hsync_len	= 64,		.vsync_len	= 3,
	.left_margin	= 122,		.upper_margin	= 45,
	.right_margin	= 10,		.lower_margin	= 10,

	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
	.lccr3		= LCCR3_OutEnH | LCCR3_PixFlEdg
};
#endif

static void __init lart_init(void)
{
	struct sa1100fb_mach_info *inf = NULL;

#ifdef LART_GREY_LCD
	inf = &lart_grey_info;
#endif
#ifdef LART_COLOR_LCD
	inf = &lart_color_info;
#endif
#ifdef LART_VIDEO_OUT
	inf = &lart_video_info;
#endif
#ifdef LART_KIT01_LCD
	inf = &lart_kit01_info;
#endif

	if (inf)
		sa11x0_register_lcd(inf);

	sa11x0_ppc_configure_mcp();
	sa11x0_register_mcp(&lart_mcp_data);
}

static struct map_desc lart_io_desc[] __initdata = {
	{	/* main flash memory */
		.virtual	=  0xe8000000,
		.pfn		= __phys_to_pfn(0x00000000),
		.length		= 0x00400000,
		.type		= MT_DEVICE
	}, {	/* main flash, alternative location */
		.virtual	=  0xec000000,
		.pfn		= __phys_to_pfn(0x08000000),
		.length		= 0x00400000,
		.type		= MT_DEVICE
	}
};

/* LEDs */
struct gpio_led lart_gpio_leds[] = {
	{
		.name			= "lart:red",
		.default_trigger	= "cpu0",
		.gpio			= 23,
	},
};

static struct gpio_led_platform_data lart_gpio_led_info = {
	.leds		= lart_gpio_leds,
	.num_leds	= ARRAY_SIZE(lart_gpio_leds),
};

static struct platform_device lart_leds = {
	.name	= "leds-gpio",
	.id	= -1,
	.dev	= {
		.platform_data	= &lart_gpio_led_info,
	}
};
static void __init lart_map_io(void)
{
	sa1100_map_io();
	iotable_init(lart_io_desc, ARRAY_SIZE(lart_io_desc));

	sa1100_register_uart(0, 3);
	sa1100_register_uart(1, 1);
	sa1100_register_uart(2, 2);

	GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
	GPDR |= GPIO_UART_TXD;
	GPDR &= ~GPIO_UART_RXD;
	PPAR |= PPAR_UPR;

	platform_device_register(&lart_leds);
}

MACHINE_START(LART, "LART")
	.atag_offset	= 0x100,
	.map_io		= lart_map_io,
	.nr_irqs	= SA1100_NR_IRQS,
	.init_irq	= sa1100_init_irq,
	.init_machine	= lart_init,
	.init_late	= sa11x0_init_late,
	.init_time	= sa1100_timer_init,
	.restart	= sa11x0_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-sa1100/nanoengine.c
 *
 * Bright Star Engineering's nanoEngine board init code.
 *
 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
 */

#include <linux/init.h>
#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/root_dev.h>

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

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

#include <mach/hardware.h>
#include <mach/nanoengine.h>
#include <mach/irqs.h>

#include "generic.h"

/* Flash bank 0 */
static struct mtd_partition nanoengine_partitions[] = {
	{
		.name	= "nanoEngine boot firmware and parameter table",
		.size		= 0x00010000,  /* 32K */
		.offset		= 0,
		.mask_flags	= MTD_WRITEABLE,
	}, {
		.name		= "kernel/initrd reserved",
		.size		= 0x002f0000,
		.offset		= 0x00010000,
		.mask_flags	= MTD_WRITEABLE,
	}, {
		.name		= "experimental filesystem allocation",
		.size		= 0x00100000,
		.offset		= 0x00300000,
		.mask_flags	= MTD_WRITEABLE,
	}
};

static struct flash_platform_data nanoengine_flash_data = {
	.map_name	= "jedec_probe",
	.parts		= nanoengine_partitions,
	.nr_parts	= ARRAY_SIZE(nanoengine_partitions),
};

static struct resource nanoengine_flash_resources[] = {
	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
	DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
};

static struct map_desc nanoengine_io_desc[] __initdata = {
	{
		/* System Registers */
		.virtual	= 0xf0000000,
		.pfn		= __phys_to_pfn(0x10000000),
		.length		= 0x00100000,
		.type		= MT_DEVICE
	}, {
		/* Internal PCI Memory Read/Write */
		.virtual	= NANO_PCI_MEM_RW_VIRT,
		.pfn		= __phys_to_pfn(NANO_PCI_MEM_RW_PHYS),
		.length		= NANO_PCI_MEM_RW_SIZE,
		.type		= MT_DEVICE
	}, {
		/* Internal PCI Config Space */
		.virtual	= NANO_PCI_CONFIG_SPACE_VIRT,
		.pfn		= __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS),
		.length		= NANO_PCI_CONFIG_SPACE_SIZE,
		.type		= MT_DEVICE
	}
};

static void __init nanoengine_map_io(void)
{
	sa1100_map_io();
	iotable_init(nanoengine_io_desc, ARRAY_SIZE(nanoengine_io_desc));

	sa1100_register_uart(0, 1);
	sa1100_register_uart(1, 2);
	sa1100_register_uart(2, 3);
	Ser1SDCR0 |= SDCR0_UART;
	/* disable IRDA -- UART2 is used as a normal serial port */
	Ser2UTCR4 = 0;
	Ser2HSCR0 = 0;
}

static struct gpiod_lookup_table nanoengine_pcmcia0_gpio_table = {
	.dev_id = "sa11x0-pcmcia.0",
	.table = {
		GPIO_LOOKUP("gpio", 11, "ready", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio", 13, "detect", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio", 15, "reset", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct gpiod_lookup_table nanoengine_pcmcia1_gpio_table = {
	.dev_id = "sa11x0-pcmcia.1",
	.table = {
		GPIO_LOOKUP("gpio", 12, "ready", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio", 14, "detect", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio", 16, "reset", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static void __init nanoengine_init(void)
{
	sa11x0_register_pcmcia(0, &nanoengine_pcmcia0_gpio_table);
	sa11x0_register_pcmcia(1, &nanoengine_pcmcia1_gpio_table);
	sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
		ARRAY_SIZE(nanoengine_flash_resources));
}

MACHINE_START(NANOENGINE, "BSE nanoEngine")
	.atag_offset	= 0x100,
	.map_io		= nanoengine_map_io,
	.nr_irqs	= SA1100_NR_IRQS,
	.init_irq	= sa1100_init_irq,
	.init_time	= sa1100_timer_init,
	.init_machine	= nanoengine_init,
	.init_late	= sa11x0_init_late,
	.restart	= sa11x0_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * linux/arch/arm/mach-sa1100/neponset.c
 */
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/gpio-reg.h>
#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <linux/smc91x.h>

#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/hardware/sa1111.h>
#include <linux/sizes.h>

#include <mach/hardware.h>
#include <mach/assabet.h>
#include <mach/neponset.h>
#include <mach/irqs.h>

#define NEP_IRQ_SMC91X	0
#define NEP_IRQ_USAR	1
#define NEP_IRQ_SA1111	2
#define NEP_IRQ_NR	3

#define WHOAMI		0x00
#define LEDS		0x10
#define SWPK		0x20
#define IRR		0x24
#define KP_Y_IN		0x80
#define KP_X_OUT	0x90
#define NCR_0		0xa0
#define MDM_CTL_0	0xb0
#define MDM_CTL_1	0xb4
#define AUD_CTL		0xc0

#define IRR_ETHERNET	(1 << 0)
#define IRR_USAR	(1 << 1)
#define IRR_SA1111	(1 << 2)

#define NCR_NGPIO	7
#define MDM_CTL0_NGPIO	4
#define MDM_CTL1_NGPIO	6
#define AUD_NGPIO	2

extern void sa1110_mb_disable(void);

#define to_neponset_gpio_chip(x) container_of(x, struct neponset_gpio_chip, gc)

static const char *neponset_ncr_names[] = {
	"gp01_off", "tp_power", "ms_power", "enet_osc",
	"spi_kb_wk_up", "a0vpp", "a1vpp"
};

static const char *neponset_mdmctl0_names[] = {
	"rts3", "dtr3", "rts1", "dtr1",
};

static const char *neponset_mdmctl1_names[] = {
	"cts3", "dsr3", "dcd3", "cts1", "dsr1", "dcd1"
};

static const char *neponset_aud_names[] = {
	"sel_1341", "mute_1341",
};

struct neponset_drvdata {
	void __iomem *base;
	struct platform_device *sa1111;
	struct platform_device *smc91x;
	unsigned irq_base;
	struct gpio_chip *gpio[4];
};

static struct gpiod_lookup_table neponset_uart1_gpio_table = {
	.dev_id = "sa11x0-uart.1",
	.table = {
		GPIO_LOOKUP("neponset-mdm-ctl0", 2, "rts", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl0", 3, "dtr", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl1", 3, "cts", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl1", 4, "dsr", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl1", 5, "dcd", GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct gpiod_lookup_table neponset_uart3_gpio_table = {
	.dev_id = "sa11x0-uart.3",
	.table = {
		GPIO_LOOKUP("neponset-mdm-ctl0", 0, "rts", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl0", 1, "dtr", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl1", 0, "cts", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl1", 1, "dsr", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("neponset-mdm-ctl1", 2, "dcd", GPIO_ACTIVE_LOW),
		{ },
	},
};

static struct gpiod_lookup_table neponset_pcmcia_table = {
	.dev_id = "1800",
	.table = {
		GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct neponset_drvdata *nep;

void neponset_ncr_frob(unsigned int mask, unsigned int val)
{
	struct neponset_drvdata *n = nep;
	unsigned long m = mask, v = val;

	if (nep)
		n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
	else
		WARN(1, "nep unset\n");
}
EXPORT_SYMBOL(neponset_ncr_frob);

/*
 * Install handler for Neponset IRQ.  Note that we have to loop here
 * since the ETHERNET and USAR IRQs are level based, and we need to
 * ensure that the IRQ signal is deasserted before returning.  This
 * is rather unfortunate.
 */
static void neponset_irq_handler(struct irq_desc *desc)
{
	struct neponset_drvdata *d = irq_desc_get_handler_data(desc);
	unsigned int irr;

	while (1) {
		/*
		 * Acknowledge the parent IRQ.
		 */
		desc->irq_data.chip->irq_ack(&desc->irq_data);

		/*
		 * Read the interrupt reason register.  Let's have all
		 * active IRQ bits high.  Note: there is a typo in the
		 * Neponset user's guide for the SA1111 IRR level.
		 */
		irr = readb_relaxed(d->base + IRR);
		irr ^= IRR_ETHERNET | IRR_USAR;

		if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
			break;

		/*
		 * Since there is no individual mask, we have to
		 * mask the parent IRQ.  This is safe, since we'll
		 * recheck the register for any pending IRQs.
		 */
		if (irr & (IRR_ETHERNET | IRR_USAR)) {
			desc->irq_data.chip->irq_mask(&desc->irq_data);

			/*
			 * Ack the interrupt now to prevent re-entering
			 * this neponset handler.  Again, this is safe
			 * since we'll check the IRR register prior to
			 * leaving.
			 */
			desc->irq_data.chip->irq_ack(&desc->irq_data);

			if (irr & IRR_ETHERNET)
				generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X);

			if (irr & IRR_USAR)
				generic_handle_irq(d->irq_base + NEP_IRQ_USAR);

			desc->irq_data.chip->irq_unmask(&desc->irq_data);
		}

		if (irr & IRR_SA1111)
			generic_handle_irq(d->irq_base + NEP_IRQ_SA1111);
	}
}

/* Yes, we really do not have any kind of masking or unmasking */
static void nochip_noop(struct irq_data *irq)
{
}

static struct irq_chip nochip = {
	.name = "neponset",
	.irq_ack = nochip_noop,
	.irq_mask = nochip_noop,
	.irq_unmask = nochip_noop,
};

static int neponset_init_gpio(struct gpio_chip **gcp,
	struct device *dev, const char *label, void __iomem *reg,
	unsigned num, bool in, const char *const * names)
{
	struct gpio_chip *gc;

	gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
			   readl_relaxed(reg), names, NULL, NULL);
	if (IS_ERR(gc))
		return PTR_ERR(gc);

	*gcp = gc;

	return 0;
}

static struct sa1111_platform_data sa1111_info = {
	.disable_devs	= SA1111_DEVID_PS2_MSE,
};

static int neponset_probe(struct platform_device *dev)
{
	struct neponset_drvdata *d;
	struct resource *nep_res, *sa1111_res, *smc91x_res;
	struct resource sa1111_resources[] = {
		DEFINE_RES_MEM(0x40000000, SZ_8K),
		{ .flags = IORESOURCE_IRQ },
	};
	struct platform_device_info sa1111_devinfo = {
		.parent = &dev->dev,
		.name = "sa1111",
		.id = 0,
		.res = sa1111_resources,
		.num_res = ARRAY_SIZE(sa1111_resources),
		.data = &sa1111_info,
		.size_data = sizeof(sa1111_info),
		.dma_mask = 0xffffffffUL,
	};
	struct resource smc91x_resources[] = {
		DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
			0x02000000, "smc91x-regs"),
		DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
			0x02000000, "smc91x-attrib"),
		{ .flags = IORESOURCE_IRQ },
	};
	struct smc91x_platdata smc91x_platdata = {
		.flags = SMC91X_USE_8BIT | SMC91X_IO_SHIFT_2 | SMC91X_NOWAIT,
	};
	struct platform_device_info smc91x_devinfo = {
		.parent = &dev->dev,
		.name = "smc91x",
		.id = 0,
		.res = smc91x_resources,
		.num_res = ARRAY_SIZE(smc91x_resources),
		.data = &smc91x_platdata,
		.size_data = sizeof(smc91x_platdata),
	};
	int ret, irq;

	if (nep)
		return -EBUSY;

	irq = ret = platform_get_irq(dev, 0);
	if (ret < 0)
		goto err_alloc;

	nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
	sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
	if (!nep_res || !smc91x_res || !sa1111_res) {
		ret = -ENXIO;
		goto err_alloc;
	}

	d = kzalloc(sizeof(*d), GFP_KERNEL);
	if (!d) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	d->base = ioremap(nep_res->start, SZ_4K);
	if (!d->base) {
		ret = -ENOMEM;
		goto err_ioremap;
	}

	if (readb_relaxed(d->base + WHOAMI) != 0x11) {
		dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
			 readb_relaxed(d->base + WHOAMI));
		ret = -ENODEV;
		goto err_id;
	}

	ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
	if (ret <= 0) {
		dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
			NEP_IRQ_NR, ret);
		if (ret == 0)
			ret = -ENOMEM;
		goto err_irq_alloc;
	}

	d->irq_base = ret;

	irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
		handle_simple_irq);
	irq_clear_status_flags(d->irq_base + NEP_IRQ_SMC91X, IRQ_NOREQUEST | IRQ_NOPROBE);
	irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
		handle_simple_irq);
	irq_clear_status_flags(d->irq_base + NEP_IRQ_USAR, IRQ_NOREQUEST | IRQ_NOPROBE);
	irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);

	irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
	irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);

	/* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
	writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);

	neponset_init_gpio(&d->gpio[0], &dev->dev, "neponset-ncr",
			   d->base + NCR_0, NCR_NGPIO, false,
			   neponset_ncr_names);
	neponset_init_gpio(&d->gpio[1], &dev->dev, "neponset-mdm-ctl0",
			   d->base + MDM_CTL_0, MDM_CTL0_NGPIO, false,
			   neponset_mdmctl0_names);
	neponset_init_gpio(&d->gpio[2], &dev->dev, "neponset-mdm-ctl1",
			   d->base + MDM_CTL_1, MDM_CTL1_NGPIO, true,
			   neponset_mdmctl1_names);
	neponset_init_gpio(&d->gpio[3], &dev->dev, "neponset-aud-ctl",
			   d->base + AUD_CTL, AUD_NGPIO, false,
			   neponset_aud_names);

	gpiod_add_lookup_table(&neponset_uart1_gpio_table);
	gpiod_add_lookup_table(&neponset_uart3_gpio_table);
	gpiod_add_lookup_table(&neponset_pcmcia_table);

	/*
	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
	 * something on the Neponset activates this IRQ on sleep (eth?)
	 */
#if 0
	enable_irq_wake(irq);
#endif

	dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
		 d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
	nep = d;

	/* Ensure that the memory bus request/grant signals are setup */
	sa1110_mb_disable();

	sa1111_resources[0].parent = sa1111_res;
	sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
	sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
	d->sa1111 = platform_device_register_full(&sa1111_devinfo);

	smc91x_resources[0].parent = smc91x_res;
	smc91x_resources[1].parent = smc91x_res;
	smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
	smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
	d->smc91x = platform_device_register_full(&smc91x_devinfo);

	platform_set_drvdata(dev, d);

	return 0;

 err_irq_alloc:
 err_id:
	iounmap(d->base);
 err_ioremap:
	kfree(d);
 err_alloc:
	return ret;
}

static int neponset_remove(struct platform_device *dev)
{
	struct neponset_drvdata *d = platform_get_drvdata(dev);
	int irq = platform_get_irq(dev, 0);

	if (!IS_ERR(d->sa1111))
		platform_device_unregister(d->sa1111);
	if (!IS_ERR(d->smc91x))
		platform_device_unregister(d->smc91x);

	gpiod_remove_lookup_table(&neponset_pcmcia_table);
	gpiod_remove_lookup_table(&neponset_uart3_gpio_table);
	gpiod_remove_lookup_table(&neponset_uart1_gpio_table);

	irq_set_chained_handler(irq, NULL);
	irq_free_descs(d->irq_base, NEP_IRQ_NR);
	nep = NULL;
	iounmap(d->base);
	kfree(d);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int neponset_resume(struct device *dev)
{
	struct neponset_drvdata *d = dev_get_drvdata(dev);
	int i, ret = 0;

	for (i = 0; i < ARRAY_SIZE(d->gpio); i++) {
		ret = gpio_reg_resume(d->gpio[i]);
		if (ret)
			break;
	}

	return ret;
}

static const struct dev_pm_ops neponset_pm_ops = {
	.resume_noirq = neponset_resume,
	.restore_noirq = neponset_resume,
};
#define PM_OPS &neponset_pm_ops
#else
#define PM_OPS NULL
#endif

static struct platform_driver neponset_device_driver = {
	.probe		= neponset_probe,
	.remove		= neponset_remove,
	.driver		= {
		.name	= "neponset",
		.pm	= PM_OPS,
	},
};

static int __init neponset_init(void)
{
	return platform_driver_register(&neponset_device_driver);
}

subsys_initcall(neponset_init);


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * linux/arch/arm/mach-sa1100/pci-nanoengine.c
 *
 * PCI functions for BSE nanoEngine PCI
 *
 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
 */
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/pci.h>

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

#include <mach/nanoengine.h>
#include <mach/hardware.h>

static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus,
					    unsigned int devfn, int where)
{
	if (bus->number != 0 || (devfn >> 3) != 0)
		return NULL;

	return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
		((bus->number << 16) | (devfn << 8) | (where & ~3));
}

static struct pci_ops pci_nano_ops = {
	.map_bus = nanoengine_pci_map_bus,
	.read	= pci_generic_config_read32,
	.write	= pci_generic_config_write32,
};

static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot,
	u8 pin)
{
	return NANOENGINE_IRQ_GPIO_PCI;
}

static struct resource pci_io_ports =
	DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO");

static struct resource pci_non_prefetchable_memory = {
	.name	= "PCI non-prefetchable",
	.start	= NANO_PCI_MEM_RW_PHYS,
	/* nanoEngine documentation says there is a 1 Megabyte window here,
	 * but PCI reports just 128 + 8 kbytes. */
	.end	= NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1,
/*	.end	= NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/
	.flags	= IORESOURCE_MEM,
};

/*
 * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it
 * overlaps with previously defined memory.
 *
 * Here is what happens:
 *
# dmesg
...
pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
pci 0000:00:00.0: reg 14: [io  0x0000-0x003f]
pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
pci 0000:00:00.0: supports D1 D2
pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
pci 0000:00:00.0: PME# disabled
PCI: bus0: Fast back to back transfers enabled
pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000)
pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
pci 0000:00:00.0: BAR 1: assigned [io  0x0400-0x043f]
pci 0000:00:00.0: BAR 1: set to [io  0x0400-0x043f] (PCI address [0x0-0x3f])
 *
 * On the other hand, if we do not request the prefetchable memory resource,
 * linux will alloc it first and the two non-prefetchable memory areas that
 * are our real interest will not be mapped. So we choose to map it to an
 * unused area. It gets recognized as expansion ROM, but becomes disabled.
 *
 * Here is what happens then:
 *
# dmesg
...
pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
pci 0000:00:00.0: reg 14: [io  0x0000-0x003f]
pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
pci 0000:00:00.0: supports D1 D2
pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
pci 0000:00:00.0: PME# disabled
PCI: bus0: Fast back to back transfers enabled
pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref]
pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
pci 0000:00:00.0: BAR 1: assigned [io  0x0400-0x043f]
pci 0000:00:00.0: BAR 1: set to [io  0x0400-0x043f] (PCI address [0x0-0x3f])

# lspci -vv -s 0000:00:00.0
00:00.0 Class 0200: Device 8086:1209 (rev 09)
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx-
        Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes
        Interrupt: pin A routed to IRQ 0
        Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K]
        Region 1: I/O ports at 0400 [size=64]
        Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K]
        [virtual] Expansion ROM at 78000000 [disabled] [size=1M]
        Capabilities: [dc] Power Management version 2
                Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
                Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME-
        Kernel driver in use: e100
        Kernel modules: e100
 *
 */
static struct resource pci_prefetchable_memory = {
	.name	= "PCI prefetchable",
	.start	= 0x78000000,
	.end	= 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1,
	.flags	= IORESOURCE_MEM  | IORESOURCE_PREFETCH,
};

static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys)
{
	if (request_resource(&ioport_resource, &pci_io_ports)) {
		printk(KERN_ERR "PCI: unable to allocate io port region\n");
		return -EBUSY;
	}
	if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) {
		release_resource(&pci_io_ports);
		printk(KERN_ERR "PCI: unable to allocate non prefetchable\n");
		return -EBUSY;
	}
	if (request_resource(&iomem_resource, &pci_prefetchable_memory)) {
		release_resource(&pci_io_ports);
		release_resource(&pci_non_prefetchable_memory);
		printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
		return -EBUSY;
	}
	pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset);
	pci_add_resource_offset(&sys->resources,
				&pci_non_prefetchable_memory, sys->mem_offset);
	pci_add_resource_offset(&sys->resources,
				&pci_prefetchable_memory, sys->mem_offset);

	return 1;
}

int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
{
	int ret = 0;

	pcibios_min_io = 0;
	pcibios_min_mem = 0;

	if (nr == 0) {
		sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
		sys->io_offset = 0x400;
		ret = pci_nanoengine_setup_resources(sys);
		/* Enable alternate memory bus master mode, see
		 * "Intel StrongARM SA1110 Developer's Manual",
		 * section 10.8, "Alternate Memory Bus Master Mode". */
		GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
		GAFR |= GPIO_MBGNT | GPIO_MBREQ;
		TUCR |= TUCR_MBGPIO;
	}

	return ret;
}

static struct hw_pci nanoengine_pci __initdata = {
	.map_irq		= pci_nanoengine_map_irq,
	.nr_controllers		= 1,
	.ops			= &pci_nano_ops,
	.setup			= pci_nanoengine_setup,
};

static int __init nanoengine_pci_init(void)
{
	if (machine_is_nanoengine())
		pci_common_init(&nanoengine_pci);
	return 0;
}

subsys_initcall(nanoengine_pci_init);


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * linux/arch/arm/mach-sa1100/pleb.c
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/mtd/partitions.h>
#include <linux/smc91x.h>

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

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

#include "generic.h"

/*
 * Ethernet IRQ mappings
 */

#define PLEB_ETH0_P		(0x20000300)	/* Ethernet 0 in PCMCIA0 IO */
#define PLEB_ETH0_V		(0xf6000300)

#define GPIO_ETH0_IRQ		GPIO_GPIO(21)
#define GPIO_ETH0_EN		GPIO_GPIO(26)

#define IRQ_GPIO_ETH0_IRQ	IRQ_GPIO21

static struct resource smc91x_resources[] = {
	[0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000),
#if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
	[1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ),
#endif
};

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

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

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

/*
 * Pleb's memory map
 * has flash memory (typically 4 or 8 meg) selected by
 * the two SA1100 lowest chip select outputs.
 */
static struct resource pleb_flash_resources[] = {
	[0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M),
	[1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M),
};

static struct mtd_partition pleb_partitions[] = {
	{
		.name		= "blob",
		.offset		= 0,
		.size		= 0x00020000,
	}, {
		.name		= "kernel",
		.offset		= MTDPART_OFS_APPEND,
		.size		= 0x000e0000,
	}, {
		.name		= "rootfs",
		.offset		= MTDPART_OFS_APPEND,
		.size		= 0x00300000,
	}
};

static struct flash_platform_data pleb_flash_data = {
	.map_name = "cfi_probe",
	.parts = pleb_partitions,
	.nr_parts = ARRAY_SIZE(pleb_partitions),
};

static void __init pleb_init(void)
{
	sa11x0_register_mtd(&pleb_flash_data, pleb_flash_resources,
			      ARRAY_SIZE(pleb_flash_resources));

	platform_add_devices(devices, ARRAY_SIZE(devices));
}

static void __init pleb_map_io(void)
{
	sa1100_map_io();

	sa1100_register_uart(0, 3);
	sa1100_register_uart(1, 1);

	GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
	GPDR |= GPIO_UART_TXD;
	GPDR &= ~GPIO_UART_RXD;
	PPAR |= PPAR_UPR;

	/*
	 * Fix expansion memory timing for network card
	 */
	MECR = ((2<<10) | (2<<5) | (2<<0));

	/*
	 * Enable the SMC ethernet controller
	 */
	GPDR |= GPIO_ETH0_EN;	/* set to output */
	GPCR  = GPIO_ETH0_EN;	/* clear MCLK (enable smc) */

	GPDR &= ~GPIO_ETH0_IRQ;

	irq_set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING);
}

MACHINE_START(PLEB, "PLEB")
	.map_io		= pleb_map_io,
	.nr_irqs	= SA1100_NR_IRQS,
	.init_irq	= sa1100_init_irq,
	.init_time	= sa1100_timer_init,
	.init_machine   = pleb_init,
	.init_late	= sa11x0_init_late,
	.restart	= sa11x0_restart,
MACHINE_END


code:
/*
 * SA1100 Power Management Routines
 *
 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License.
 *
 * History:
 *
 * 2001-02-06:	Cliff Brake         Initial code
 *
 * 2001-02-25:	Sukjae Cho <sjcho@east.isi.edu> &
 * 		Chester Kuo <chester@linux.org.tw>
 * 			Save more value for the resume function! Support
 * 			Bitsy/Assabet/Freebird board
 *
 * 2001-08-29:	Nicolas Pitre <nico@fluxnic.net>
 * 			Cleaned up, pushed platform dependent stuff
 * 			in the platform specific files.
 *
 * 2002-05-27:	Nicolas Pitre	Killed sleep.h and the kmalloced save array.
 * 				Storage is local on the stack now.
 */
#include <linux/init.h>
#include <linux/io.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>

#include <mach/hardware.h>
#include <asm/memory.h>
#include <asm/suspend.h>
#include <asm/mach/time.h>

extern int sa1100_finish_suspend(unsigned long);

#define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
#define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]

/*
 * List of global SA11x0 peripheral registers to preserve.
 * More ones like CP and general purpose register values are preserved
 * on the stack and then the stack pointer is stored last in sleep.S.
 */
enum {	SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
	SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,

	SLEEP_SAVE_Ser1SDCR0,

	SLEEP_SAVE_COUNT
};

static int sa11x0_pm_enter(suspend_state_t state)
{
	unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];

	gpio = GPLR;

	/* save vital registers */
	SAVE(GPDR);
	SAVE(GAFR);

	SAVE(PPDR);
	SAVE(PPSR);
	SAVE(PPAR);
	SAVE(PSDR);

	SAVE(Ser1SDCR0);

	/* Clear previous reset status */
	RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;

	/* set resume return address */
	PSPR = __pa_symbol(cpu_resume);

	/* go zzz */
	cpu_suspend(0, sa1100_finish_suspend);

	/*
	 * Ensure not to come back here if it wasn't intended
	 */
	RCSR = RCSR_SMR;
	PSPR = 0;

	/*
	 * Ensure interrupt sources are disabled; we will re-init
	 * the interrupt subsystem via the device manager.
	 */
	ICLR = 0;
	ICCR = 1;
	ICMR = 0;

	/* restore registers */
	RESTORE(GPDR);
	RESTORE(GAFR);

	RESTORE(PPDR);
	RESTORE(PPSR);
	RESTORE(PPAR);
	RESTORE(PSDR);

	RESTORE(Ser1SDCR0);

	GPSR = gpio;
	GPCR = ~gpio;

	/*
	 * Clear the peripheral sleep-hold bit.
	 */
	PSSR = PSSR_PH;

	return 0;
}

static const struct platform_suspend_ops sa11x0_pm_ops = {
	.enter		= sa11x0_pm_enter,
	.valid		= suspend_valid_only_mem,
};

int __init sa11x0_pm_init(void)
{
	suspend_set_ops(&sa11x0_pm_ops);
	return 0;
}


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * linux/arch/arm/mach-sa1100/shannon.c
 */

#include <linux/init.h>
#include <linux/device.h>
#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/tty.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>

#include <video/sa1100fb.h>

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

#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/shannon.h>
#include <mach/irqs.h>

#include "generic.h"

static struct mtd_partition shannon_partitions[] = {
	{
		.name		= "BLOB boot loader",
		.offset		= 0,
		.size		= 0x20000
	},
	{
		.name		= "kernel",
		.offset		= MTDPART_OFS_APPEND,
		.size		= 0xe0000
	},
	{
		.name		= "initrd",
		.offset		= MTDPART_OFS_APPEND,
		.size		= MTDPART_SIZ_FULL
	}
};

static struct flash_platform_data shannon_flash_data = {
	.map_name	= "cfi_probe",
	.parts		= shannon_partitions,
	.nr_parts	= ARRAY_SIZE(shannon_partitions),
};

static struct resource shannon_flash_resource =
	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M);

static struct mcp_plat_data shannon_mcp_data = {
	.mccr0		= MCCR0_ADM,
	.sclk_rate	= 11981000,
};

static struct sa1100fb_mach_info shannon_lcd_info = {
	.pixclock	= 152500,	.bpp		= 8,
	.xres		= 640,		.yres		= 480,

	.hsync_len	= 4,		.vsync_len	= 3,
	.left_margin	= 2,		.upper_margin	= 0,
	.right_margin	= 1,		.lower_margin	= 0,

	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,

	.lccr0		= LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
	.lccr3		= LCCR3_ACBsDiv(512),
};

static struct gpiod_lookup_table shannon_pcmcia0_gpio_table = {
	.dev_id = "sa11x0-pcmcia.0",
	.table = {
		GPIO_LOOKUP("gpio", 24, "detect", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio", 26, "ready", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct gpiod_lookup_table shannon_pcmcia1_gpio_table = {
	.dev_id = "sa11x0-pcmcia.1",
	.table = {
		GPIO_LOOKUP("gpio", 25, "detect", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("gpio", 27, "ready", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct regulator_consumer_supply shannon_cf_vcc_consumers[] = {
	REGULATOR_SUPPLY("vcc", "sa11x0-pcmcia.0"),
	REGULATOR_SUPPLY("vcc", "sa11x0-pcmcia.1"),
};

static struct fixed_voltage_config shannon_cf_vcc_pdata __initdata = {
	.supply_name = "cf-power",
	.microvolts = 3300000,
	.enabled_at_boot = 1,
};

static struct gpiod_lookup_table shannon_display_gpio_table = {
	.dev_id = "sa11x0-fb",
	.table = {
		GPIO_LOOKUP("gpio", 22, "shannon-lcden", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static void __init shannon_init(void)
{
	sa11x0_register_fixed_regulator(0, &shannon_cf_vcc_pdata,
					shannon_cf_vcc_consumers,
					ARRAY_SIZE(shannon_cf_vcc_consumers),
					false);
	sa11x0_register_pcmcia(0, &shannon_pcmcia0_gpio_table);
	sa11x0_register_pcmcia(1, &shannon_pcmcia1_gpio_table);
	sa11x0_ppc_configure_mcp();
	gpiod_add_lookup_table(&shannon_display_gpio_table);
	sa11x0_register_lcd(&shannon_lcd_info);
	sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
	sa11x0_register_mcp(&shannon_mcp_data);
}

static void __init shannon_map_io(void)
{
	sa1100_map_io();

	sa1100_register_uart(0, 3);
	sa1100_register_uart(1, 1);

	Ser1SDCR0 |= SDCR0_SUS;
	GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
	GPDR |= GPIO_UART_TXD | SHANNON_GPIO_CODEC_RESET;
	GPDR &= ~GPIO_UART_RXD;
	PPAR |= PPAR_UPR;

	/* reset the codec */
	GPCR = SHANNON_GPIO_CODEC_RESET;
	GPSR = SHANNON_GPIO_CODEC_RESET;
}

MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
	.atag_offset	= 0x100,
	.map_io		= shannon_map_io,
	.nr_irqs	= SA1100_NR_IRQS,
	.init_irq	= sa1100_init_irq,
	.init_time	= sa1100_timer_init,
	.init_machine	= shannon_init,
	.init_late	= sa11x0_init_late,
	.restart	= sa11x0_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * linux/arch/arm/mach-sa1100/simpad.c
 */

#include <linux/module.h>
#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/pm.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
#include <linux/gpio/driver.h>

#include <mach/hardware.h>
#include <asm/setup.h>
#include <asm/irq.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/simpad.h>
#include <mach/irqs.h>

#include <linux/serial_core.h>
#include <linux/ioport.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/leds.h>
#include <linux/platform_data/i2c-gpio.h>

#include "generic.h"

/*
 * CS3 support
 */

static long cs3_shadow;
static spinlock_t cs3_lock;
static struct gpio_chip cs3_gpio;

long simpad_get_cs3_ro(void)
{
	return readl(CS3_BASE);
}
EXPORT_SYMBOL(simpad_get_cs3_ro);

long simpad_get_cs3_shadow(void)
{
	return cs3_shadow;
}
EXPORT_SYMBOL(simpad_get_cs3_shadow);

static void __simpad_write_cs3(void)
{
	writel(cs3_shadow, CS3_BASE);
}

void simpad_set_cs3_bit(int value)
{
	unsigned long flags;

	spin_lock_irqsave(&cs3_lock, flags);
	cs3_shadow |= value;
	__simpad_write_cs3();
	spin_unlock_irqrestore(&cs3_lock, flags);
}
EXPORT_SYMBOL(simpad_set_cs3_bit);

void simpad_clear_cs3_bit(int value)
{
	unsigned long flags;

	spin_lock_irqsave(&cs3_lock, flags);
	cs3_shadow &= ~value;
	__simpad_write_cs3();
	spin_unlock_irqrestore(&cs3_lock, flags);
}
EXPORT_SYMBOL(simpad_clear_cs3_bit);

static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	if (offset > 15)
		return;
	if (value)
		simpad_set_cs3_bit(1 << offset);
	else
		simpad_clear_cs3_bit(1 << offset);
};

static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	if (offset > 15)
		return !!(simpad_get_cs3_ro() & (1 << (offset - 16)));
	return !!(simpad_get_cs3_shadow() & (1 << offset));
};

static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	if (offset > 15)
		return 0;
	return -EINVAL;
};

static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
	int value)
{
	if (offset > 15)
		return -EINVAL;
	cs3_gpio_set(chip, offset, value);
	return 0;
};

static struct map_desc simpad_io_desc[] __initdata = {
	{	/* MQ200 */
		.virtual	=  0xf2800000,
		.pfn		= __phys_to_pfn(0x4b800000),
		.length		= 0x00800000,
		.type		= MT_DEVICE
	}, {	/* Simpad CS3 */
		.virtual	= (unsigned long)CS3_BASE,
		.pfn		= __phys_to_pfn(SA1100_CS3_PHYS),
		.length		= 0x00100000,
		.type		= MT_DEVICE
	},
};

static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
{
	if (port->mapbase == (u_int)&Ser1UTCR0) {
		if (state)
		{
			simpad_clear_cs3_bit(RS232_ON);
			simpad_clear_cs3_bit(DECT_POWER_ON);
		}else
		{
			simpad_set_cs3_bit(RS232_ON);
			simpad_set_cs3_bit(DECT_POWER_ON);
		}
	}
}

static struct sa1100_port_fns simpad_port_fns __initdata = {
	.pm	   = simpad_uart_pm,
};

static struct mtd_partition simpad_partitions[] = {
	{
		.name       = "SIMpad boot firmware",
		.size       = 0x00080000,
		.offset     = 0,
		.mask_flags = MTD_WRITEABLE,
	}, {
		.name       = "SIMpad kernel",
		.size       = 0x0010000,
		.offset     = MTDPART_OFS_APPEND,
	}, {
		.name       = "SIMpad root jffs2",
		.size       = MTDPART_SIZ_FULL,
		.offset     = MTDPART_OFS_APPEND,
	}
};

static struct flash_platform_data simpad_flash_data = {
	.map_name    = "cfi_probe",
	.parts       = simpad_partitions,
	.nr_parts    = ARRAY_SIZE(simpad_partitions),
};

static struct resource simpad_flash_resources [] = {
	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
	DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
};

static struct ucb1x00_plat_data simpad_ucb1x00_data = {
	.gpio_base	= SIMPAD_UCB1X00_GPIO_BASE,
};

static struct mcp_plat_data simpad_mcp_data = {
	.mccr0		= MCCR0_ADM,
	.sclk_rate	= 11981000,
	.codec_pdata	= &simpad_ucb1x00_data,
};

static void __init simpad_map_io(void)
{
	sa1100_map_io();

	iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));

	/* Initialize CS3 */
	cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON |
		RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
	__simpad_write_cs3(); /* Spinlocks not yet initialized */

        sa1100_register_uart_fns(&simpad_port_fns);
	sa1100_register_uart(0, 3);  /* serial interface */
	sa1100_register_uart(1, 1);  /* DECT             */

	// Reassign UART 1 pins
	GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
	GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
	GPDR &= ~GPIO_UART_RXD;
	PPAR |= PPAR_UPR;

	/*
	 * Set up registers for sleep mode.
	 */

	PWER = PWER_GPIO0| PWER_RTC;
	PGSR = 0x818;
	PCFR = 0;
	PSDR = 0;

}

static void simpad_power_off(void)
{
	local_irq_disable();
	cs3_shadow = SD_MEDIAQ;
	__simpad_write_cs3(); /* Bypass spinlock here */

	/* disable internal oscillator, float CS lines */
	PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
	/* enable wake-up on GPIO0 */
	PWER = GFER = GRER = PWER_GPIO0;
	/*
	 * set scratchpad to zero, just in case it is used as a
	 * restart address by the bootloader.
	 */
	PSPR = 0;
	PGSR = 0;
	/* enter sleep mode */
	PMCR = PMCR_SF;
	while(1);

	local_irq_enable(); /* we won't ever call it */

}

/*
 * gpio_keys
*/

static struct gpio_keys_button simpad_button_table[] = {
	{ KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
};

static struct gpio_keys_platform_data simpad_keys_data = {
	.buttons = simpad_button_table,
	.nbuttons = ARRAY_SIZE(simpad_button_table),
};

static struct platform_device simpad_keys = {
	.name = "gpio-keys",
	.dev = {
		.platform_data = &simpad_keys_data,
	},
};

static struct gpio_keys_button simpad_polled_button_table[] = {
	{ KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" },
	{ KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" },
	{ KEY_UP,    SIMPAD_UCB1X00_GPIO_UP,    1, "up button" },
	{ KEY_DOWN,  SIMPAD_UCB1X00_GPIO_DOWN,  1, "down button" },
	{ KEY_LEFT,  SIMPAD_UCB1X00_GPIO_LEFT,  1, "left button" },
	{ KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" },
};

static struct gpio_keys_platform_data simpad_polled_keys_data = {
	.buttons = simpad_polled_button_table,
	.nbuttons = ARRAY_SIZE(simpad_polled_button_table),
	.poll_interval = 50,
};

static struct platform_device simpad_polled_keys = {
	.name = "gpio-keys-polled",
	.dev = {
		.platform_data = &simpad_polled_keys_data,
	},
};

/*
 * GPIO LEDs
 */

static struct gpio_led simpad_leds[] = {
	{
		.name = "simpad:power",
		.gpio = SIMPAD_CS3_LED2_ON,
		.active_low = 0,
		.default_trigger = "default-on",
	},
};

static struct gpio_led_platform_data simpad_led_data = {
	.num_leds = ARRAY_SIZE(simpad_leds),
	.leds = simpad_leds,
};

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

/*
 * i2c
 */
static struct gpiod_lookup_table simpad_i2c_gpiod_table = {
	.dev_id = "i2c-gpio.0",
	.table = {
		GPIO_LOOKUP_IDX("gpio", 21, NULL, 0,
				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
		GPIO_LOOKUP_IDX("gpio", 25, NULL, 1,
				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
	},
};

static struct i2c_gpio_platform_data simpad_i2c_data = {
	.udelay = 10,
	.timeout = HZ,
};

static struct platform_device simpad_i2c = {
	.name = "i2c-gpio",
	.id = 0,
	.dev = {
		.platform_data = &simpad_i2c_data,
	},
};

/*
 * MediaQ Video Device
 */
static struct platform_device simpad_mq200fb = {
	.name = "simpad-mq200",
	.id   = 0,
};

static struct platform_device *devices[] __initdata = {
	&simpad_keys,
	&simpad_polled_keys,
	&simpad_mq200fb,
	&simpad_gpio_leds,
	&simpad_i2c,
};

/* Compact Flash */
static struct gpiod_lookup_table simpad_cf_gpio_table = {
	.dev_id = "sa11x0-pcmcia",
	.table = {
		GPIO_LOOKUP("gpio", GPIO_CF_IRQ, "cf-ready", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("gpio", GPIO_CF_CD, "cf-detect", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static int __init simpad_init(void)
{
	int ret;

	spin_lock_init(&cs3_lock);

	cs3_gpio.label = "simpad_cs3";
	cs3_gpio.base = SIMPAD_CS3_GPIO_BASE;
	cs3_gpio.ngpio = 24;
	cs3_gpio.set = cs3_gpio_set;
	cs3_gpio.get = cs3_gpio_get;
	cs3_gpio.direction_input = cs3_gpio_direction_input;
	cs3_gpio.direction_output = cs3_gpio_direction_output;
	ret = gpiochip_add_data(&cs3_gpio, NULL);
	if (ret)
		printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");

	pm_power_off = simpad_power_off;

	sa11x0_register_pcmcia(-1, &simpad_cf_gpio_table);
	sa11x0_ppc_configure_mcp();
	sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
			      ARRAY_SIZE(simpad_flash_resources));
	sa11x0_register_mcp(&simpad_mcp_data);

	gpiod_add_lookup_table(&simpad_i2c_gpiod_table);
	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
	if(ret)
		printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");

	return 0;
}

arch_initcall(simpad_init);

MACHINE_START(SIMPAD, "Simpad")
	/* Maintainer: Holger Freyther */
	.atag_offset	= 0x100,
	.map_io		= simpad_map_io,
	.nr_irqs	= SA1100_NR_IRQS,
	.init_irq	= sa1100_init_irq,
	.init_late	= sa11x0_init_late,
	.init_time	= sa1100_timer_init,
	.restart	= sa11x0_restart,
MACHINE_END