diff options
-rw-r--r-- | linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch | 8760 |
1 files changed, 8760 insertions, 0 deletions
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch index e69de29bb2..7ae04c21a6 100644 --- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch +++ b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch @@ -0,0 +1,8760 @@ + +# +# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher +# + +--- linux-2.4.25/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/Makefile 2004-05-02 22:47:57.000000000 +0200 +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 4 + SUBLEVEL = 25 +-EXTRAVERSION =-vrs2-pxa1 ++EXTRAVERSION =-vrs2-pxa1-jpm1 + + KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) + +--- linux-2.4.25/arch/arm/mach-sa1100/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:39.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/Makefile 2004-05-02 22:45:42.000000000 +0200 +@@ -18,7 +18,8 @@ + export-objs := assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \ + flexanet.o freebird.o frodo.o generic.o h3600.o \ + huw_webpanel.o irq.o sa1111.o sa1111-pcibuf.o \ +- system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o ++ system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o \ ++ simpad.o + + # These aren't present yet, and prevents a plain -ac kernel building. + # hwtimer.o +@@ -30,7 +31,6 @@ + ifeq ($(CONFIG_CPU_FREQ),y) + obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o + obj-$(CONFIG_SA1100_CEP) += cpu-sa1110.o +-obj-$(CONFIG_SA1100_CONSUS) += cpu-sa1110.o + obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o + obj-$(CONFIG_SA1100_HACKKIT) += cpu-sa1110.o + obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o +@@ -52,7 +52,6 @@ + obj-$(CONFIG_SA1100_BRUTUS) += brutus.o + obj-$(CONFIG_SA1100_CEP) += cep.o + obj-$(CONFIG_SA1100_CERF) += cerf.o +-obj-$(CONFIG_SA1100_CONSUS) += consus.o + obj-$(CONFIG_SA1100_EMPEG) += empeg.o + obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o + obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o +@@ -87,7 +86,6 @@ + leds-$(CONFIG_SA1100_ASSABET) += leds-assabet.o + leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o + leds-$(CONFIG_SA1100_CERF) += leds-cerf.o +-leds-$(CONFIG_SA1100_CONSUS) += leds-consus.o + leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o + leds-$(CONFIG_SA1100_FRODO) += leds-frodo.o + leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o +@@ -108,7 +106,12 @@ + + # Miscelaneous functions + obj-$(CONFIG_PM) += pm.o sleep.o ++obj-$(CONFIG_APM) += apm.o + ++# SIMpad specific ++export-objs += simpad_pm.o ++obj-$(CONFIG_SIMPAD_PM) += simpad_pm.o ++ + obj-$(CONFIG_SA1100_SSP) += ssp.o + + include $(TOPDIR)/Rules.make +--- linux-2.4.25/drivers/video/fbmem.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/video/fbmem.c 2004-05-02 22:45:42.000000000 +0200 +@@ -109,6 +109,7 @@ + extern int chips_init(void); + extern int g364fb_init(void); + extern int sa1100fb_init(void); ++extern int mq200fb_init(void); + extern int pxafb_init(void); + extern int fm2fb_init(void); + extern int fm2fb_setup(char*); +@@ -306,6 +307,9 @@ + #ifdef CONFIG_FB_SA1100 + { "sa1100", sa1100fb_init, NULL }, + #endif ++#ifdef CONFIG_FB_MQ200 ++ { "mq200fb", mq200fb_init, NULL }, ++#endif + #ifdef CONFIG_FB_PXA + { "pxa", pxafb_init, NULL }, + #endif +--- linux-2.4.25/arch/arm/config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/arch/arm/config.in 2004-05-02 22:45:42.000000000 +0200 +@@ -128,6 +128,9 @@ + dep_bool ' Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100 + dep_bool ' Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100 + dep_bool ' Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100 ++if [ "$CONFIG_SA1100_SIMPAD" = "y" ]; then ++ bool ' T-Sinus PAD' CONFIG_SA1100_SIMPAD_SINUSPAD ++fi + dep_bool ' Simputer' CONFIG_SA1100_SIMPUTER $CONFIG_ARCH_SA1100 + dep_bool ' Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100 + dep_bool ' Victor' CONFIG_SA1100_VICTOR $CONFIG_ARCH_SA1100 +@@ -587,6 +590,10 @@ + tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF + tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC + dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL ++dep_tristate 'Advanced power management emulation support' CONFIG_APM $CONFIG_PM ++if [ "$CONFIG_APM" != "n" ]; then ++ bool ' SIMpad power management' CONFIG_SIMPAD_PM ++fi + dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32 + string 'Default kernel command string' CONFIG_CMDLINE "" + +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/arch/arm/def-configs/simpad 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,967 @@ ++# ++# Automatically generated by make menuconfig: don't edit ++# ++CONFIG_ARM=y ++# CONFIG_EISA is not set ++# CONFIG_SBUS is not set ++# CONFIG_MCA is not set ++CONFIG_UID16=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set ++# CONFIG_GENERIC_BUST_SPINLOCK is not set ++# CONFIG_GENERIC_ISA_DMA is not set ++ ++# ++# Code maturity level options ++# ++CONFIG_EXPERIMENTAL=y ++# CONFIG_OBSOLETE is not set ++ ++# ++# Loadable module support ++# ++CONFIG_MODULES=y ++# CONFIG_MODVERSIONS is not set ++CONFIG_KMOD=y ++ ++# ++# System Type ++# ++# CONFIG_ARCH_ANAKIN is not set ++# CONFIG_ARCH_ARCA5K is not set ++# CONFIG_ARCH_CLPS7500 is not set ++# CONFIG_ARCH_CLPS711X is not set ++# CONFIG_ARCH_CO285 is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_CAMELOT is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_INTEGRATOR is not set ++# CONFIG_ARCH_OMAHA is not set ++# CONFIG_ARCH_L7200 is not set ++# CONFIG_ARCH_MX1ADS is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_RISCSTATION is not set ++CONFIG_ARCH_SA1100=y ++# CONFIG_ARCH_SHARK is not set ++# CONFIG_ARCH_AT91RM9200DK is not set ++ ++# ++# Archimedes/A5000 Implementations ++# ++# CONFIG_ARCH_ARC is not set ++# CONFIG_ARCH_A5K is not set ++ ++# ++# Footbridge Implementations ++# ++# CONFIG_ARCH_CATS is not set ++# CONFIG_ARCH_PERSONAL_SERVER is not set ++# CONFIG_ARCH_EBSA285_ADDIN is not set ++# CONFIG_ARCH_EBSA285_HOST is not set ++# CONFIG_ARCH_NETWINDER is not set ++ ++# ++# SA11x0 Implementations ++# ++# CONFIG_SA1100_ACCELENT is not set ++# CONFIG_SA1100_ASSABET is not set ++# CONFIG_ASSABET_NEPONSET is not set ++# CONFIG_SA1100_ADSAGC is not set ++# CONFIG_SA1100_ADSBITSY is not set ++# CONFIG_SA1100_ADSBITSYPLUS is not set ++# CONFIG_SA1100_BRUTUS is not set ++# CONFIG_SA1100_CEP is not set ++# CONFIG_SA1100_CERF is not set ++# CONFIG_SA1100_H3100 is not set ++# CONFIG_SA1100_H3600 is not set ++# CONFIG_SA1100_H3800 is not set ++# CONFIG_SA1100_H3XXX is not set ++# CONFIG_H3600_SLEEVE is not set ++# CONFIG_SA1100_EXTENEX1 is not set ++# CONFIG_SA1100_FLEXANET is not set ++# CONFIG_SA1100_FREEBIRD is not set ++# CONFIG_SA1100_FRODO is not set ++# CONFIG_SA1100_GRAPHICSCLIENT is not set ++# CONFIG_SA1100_GRAPHICSMASTER is not set ++# CONFIG_SA1100_HACKKIT is not set ++# CONFIG_SA1100_BADGE4 is not set ++# CONFIG_SA1100_JORNADA720 is not set ++# CONFIG_SA1100_HUW_WEBPANEL is not set ++# CONFIG_SA1100_ITSY is not set ++# CONFIG_SA1100_LART is not set ++# CONFIG_SA1100_NANOENGINE is not set ++# CONFIG_SA1100_OMNIMETER is not set ++# CONFIG_SA1100_PANGOLIN is not set ++# CONFIG_SA1100_PLEB is not set ++# CONFIG_SA1100_PT_SYSTEM3 is not set ++# CONFIG_SA1100_SHANNON is not set ++# CONFIG_SA1100_SHERMAN is not set ++CONFIG_SA1100_SIMPAD=y ++# CONFIG_SA1100_SIMPAD_SINUSPAD is not set ++# CONFIG_SA1100_SIMPUTER is not set ++# CONFIG_SA1100_PFS168 is not set ++# CONFIG_SA1100_VICTOR is not set ++# CONFIG_SA1100_XP860 is not set ++# CONFIG_SA1100_YOPY is not set ++CONFIG_SA1100_USB=m ++CONFIG_SA1100_USB_NETLINK=m ++CONFIG_SA1100_USB_CHAR=m ++# CONFIG_SA1100_SSP is not set ++ ++# ++# CLPS711X/EP721X Implementations ++# ++# CONFIG_ARCH_AUTCPU12 is not set ++# CONFIG_ARCH_CDB89712 is not set ++# CONFIG_ARCH_CLEP7312 is not set ++# CONFIG_ARCH_EDB7211 is not set ++# CONFIG_ARCH_FORTUNET is not set ++# CONFIG_ARCH_GUIDEA07 is not set ++# CONFIG_ARCH_P720T is not set ++# CONFIG_ARCH_EP7211 is not set ++# CONFIG_ARCH_EP7212 is not set ++# CONFIG_ARCH_ACORN is not set ++# CONFIG_FOOTBRIDGE is not set ++# CONFIG_FOOTBRIDGE_HOST is not set ++# CONFIG_FOOTBRIDGE_ADDIN is not set ++CONFIG_CPU_32=y ++# CONFIG_CPU_26 is not set ++# CONFIG_CPU_ARM610 is not set ++# CONFIG_CPU_ARM710 is not set ++# CONFIG_CPU_ARM720T is not set ++# CONFIG_CPU_ARM920T is not set ++# CONFIG_CPU_ARM922T is not set ++# CONFIG_PLD is not set ++# CONFIG_CPU_ARM926T is not set ++# CONFIG_CPU_ARM1020 is not set ++# CONFIG_CPU_ARM1026 is not set ++# CONFIG_CPU_SA110 is not set ++CONFIG_CPU_SA1100=y ++# CONFIG_CPU_32v3 is not set ++CONFIG_CPU_32v4=y ++CONFIG_DISCONTIGMEM=y ++ ++# ++# General setup ++# ++# CONFIG_PCI is not set ++CONFIG_ISA=y ++# CONFIG_ISA_DMA is not set ++# CONFIG_ZBOOT_ROM is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_CPU_FREQ=y ++CONFIG_HOTPLUG=y ++ ++# ++# PCMCIA/CardBus support ++# ++CONFIG_PCMCIA=y ++CONFIG_PCMCIA_PROBE=y ++# CONFIG_I82092 is not set ++# CONFIG_I82365 is not set ++# CONFIG_TCIC is not set ++# CONFIG_PCMCIA_CLPS6700 is not set ++CONFIG_PCMCIA_SA1100=y ++CONFIG_NET=y ++CONFIG_SYSVIPC=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++CONFIG_SYSCTL=y ++CONFIG_FPE_NWFPE=y ++# CONFIG_FPE_FASTFPE is not set ++CONFIG_KCORE_ELF=y ++# CONFIG_KCORE_AOUT is not set ++# CONFIG_BINFMT_AOUT is not set ++CONFIG_BINFMT_ELF=y ++CONFIG_BINFMT_MISC=m ++CONFIG_PM=y ++CONFIG_APM=y ++CONFIG_SIMPAD_PM=y ++# CONFIG_ARTHUR is not set ++CONFIG_CMDLINE="mtdparts=sa1100:512k(boot),1m(kernel),-(root) console=ttySA root=1f02 noinitrd mem=64M" ++CONFIG_LEDS=y ++CONFIG_LEDS_TIMER=y ++CONFIG_LEDS_CPU=y ++CONFIG_ALIGNMENT_TRAP=y ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT is not set ++ ++# ++# Memory Technology Devices (MTD) ++# ++CONFIG_MTD=y ++# CONFIG_MTD_DEBUG is not set ++CONFIG_MTD_PARTITIONS=y ++# CONFIG_MTD_CONCAT is not set ++CONFIG_MTD_REDBOOT_PARTS=y ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_GEN_PROBE=y ++CONFIG_MTD_CFI_ADV_OPTIONS=y ++CONFIG_MTD_CFI_NOSWAP=y ++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set ++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set ++CONFIG_MTD_CFI_GEOMETRY=y ++# CONFIG_MTD_CFI_B1 is not set ++CONFIG_MTD_CFI_B2=y ++# CONFIG_MTD_CFI_B4 is not set ++# CONFIG_MTD_CFI_B8 is not set ++CONFIG_MTD_CFI_I1=y ++# CONFIG_MTD_CFI_I2 is not set ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++CONFIG_MTD_CFI_INTELEXT=y ++# CONFIG_MTD_CFI_AMDSTD is not set ++# CONFIG_MTD_RAM is not set ++CONFIG_MTD_ROM=y ++# CONFIG_MTD_ABSENT is not set ++# CONFIG_MTD_OBSOLETE_CHIPS is not set ++# CONFIG_MTD_AMDSTD is not set ++# CONFIG_MTD_SHARP is not set ++# CONFIG_MTD_JEDEC is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_PHYSMAP is not set ++# CONFIG_MTD_NORA is not set ++# CONFIG_MTD_ARM_INTEGRATOR is not set ++# CONFIG_MTD_CDB89712 is not set ++CONFIG_MTD_SA1100=y ++# CONFIG_MTD_DC21285 is not set ++# CONFIG_MTD_IQ80310 is not set ++# CONFIG_MTD_FORTUNET is not set ++# CONFIG_MTD_EPXA is not set ++# CONFIG_MTD_AUTCPU12 is not set ++# CONFIG_MTD_EDB7312 is not set ++# CONFIG_MTD_IMPA7 is not set ++# CONFIG_MTD_PCI is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_PMC551 is not set ++# CONFIG_MTD_SLRAM is not set ++CONFIG_MTD_MTDRAM=y ++CONFIG_MTDRAM_TOTAL_SIZE=32768 ++CONFIG_MTDRAM_ERASE_SIZE=1 ++CONFIG_MTDRAM_ABS_POS=C2000000 ++# CONFIG_MTD_BLKMTD is not set ++# CONFIG_MTD_DOC1000 is not set ++# CONFIG_MTD_DOC2000 is not set ++# CONFIG_MTD_DOC2001 is not set ++# CONFIG_MTD_DOCPROBE is not set ++ ++# ++# NAND Flash Device Drivers ++# ++# CONFIG_MTD_NAND is not set ++ ++# ++# Plug and Play configuration ++# ++# CONFIG_PNP is not set ++# CONFIG_ISAPNP is not set ++ ++# ++# Block devices ++# ++# CONFIG_BLK_DEV_FD is not set ++# CONFIG_BLK_DEV_XD is not set ++# CONFIG_PARIDE is not set ++# CONFIG_BLK_CPQ_DA is not set ++# CONFIG_BLK_CPQ_CISS_DA is not set ++# CONFIG_CISS_SCSI_TAPE is not set ++# CONFIG_BLK_DEV_DAC960 is not set ++# CONFIG_BLK_DEV_UMEM is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++# CONFIG_BLK_DEV_INITRD is not set ++ ++# ++# Multi-device support (RAID and LVM) ++# ++# CONFIG_MD is not set ++# CONFIG_BLK_DEV_MD is not set ++# CONFIG_MD_LINEAR is not set ++# CONFIG_MD_RAID0 is not set ++# CONFIG_MD_RAID1 is not set ++# CONFIG_MD_RAID5 is not set ++# CONFIG_MD_MULTIPATH is not set ++# CONFIG_BLK_DEV_LVM is not set ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++CONFIG_PACKET_MMAP=y ++# CONFIG_NETLINK_DEV is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_FILTER is not set ++CONFIG_UNIX=y ++CONFIG_INET=y ++# CONFIG_IP_MULTICAST is not set ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_ARPD is not set ++# CONFIG_INET_ECN is not set ++# CONFIG_SYN_COOKIES is not set ++# CONFIG_IPV6 is not set ++# CONFIG_KHTTPD is not set ++# CONFIG_ATM is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++ ++# ++# Appletalk devices ++# ++# CONFIG_DEV_APPLETALK is not set ++# CONFIG_DECNET is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_LLC is not set ++# CONFIG_NET_DIVERT is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_NET_FASTROUTE is not set ++# CONFIG_NET_HW_FLOWCONTROL is not set ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++ ++# ++# Network device support ++# ++CONFIG_NETDEVICES=y ++ ++# ++# ARCnet devices ++# ++# CONFIG_ARCNET is not set ++CONFIG_DUMMY=y ++# CONFIG_BONDING is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++# CONFIG_ETHERTAP is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=y ++# CONFIG_ARM_AM79C961A is not set ++# CONFIG_ARM_CIRRUS is not set ++# CONFIG_SUNLANCE is not set ++# CONFIG_SUNBMAC is not set ++# CONFIG_SUNQE is not set ++# CONFIG_SUNGEM is not set ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_LANCE is not set ++# CONFIG_NET_VENDOR_SMC is not set ++# CONFIG_NET_VENDOR_RACAL is not set ++# CONFIG_AT1700 is not set ++# CONFIG_DEPCA is not set ++# CONFIG_HP100 is not set ++# CONFIG_NET_ISA is not set ++CONFIG_NET_PCI=y ++# CONFIG_PCNET32 is not set ++# CONFIG_ADAPTEC_STARFIRE is not set ++# CONFIG_AC3200 is not set ++# CONFIG_APRICOT is not set ++# CONFIG_CS89x0 is not set ++# CONFIG_TULIP is not set ++# CONFIG_TC35815 is not set ++# CONFIG_DM9102 is not set ++# CONFIG_EEPRO100 is not set ++# CONFIG_LNE390 is not set ++# CONFIG_FEALNX is not set ++# CONFIG_NATSEMI is not set ++# CONFIG_NE2K_PCI is not set ++# CONFIG_NE3210 is not set ++# CONFIG_ES3210 is not set ++# CONFIG_8139CP is not set ++# CONFIG_8139TOO is not set ++# CONFIG_8139TOO_PIO is not set ++# CONFIG_8139TOO_TUNE_TWISTER is not set ++# CONFIG_8139TOO_8129 is not set ++# CONFIG_8139_NEW_RX_RESET is not set ++# CONFIG_SIS900 is not set ++# CONFIG_EPIC100 is not set ++# CONFIG_SUNDANCE is not set ++# CONFIG_VIA_RHINE is not set ++# CONFIG_VIA_RHINE_MMIO is not set ++# CONFIG_WINBOND_840 is not set ++# CONFIG_NET_POCKET is not set ++ ++# ++# Ethernet (1000 Mbit) ++# ++# CONFIG_ACENIC is not set ++# CONFIG_DL2K is not set ++# CONFIG_MYRI_SBUS is not set ++# CONFIG_NS83820 is not set ++# CONFIG_HAMACHI is not set ++# CONFIG_YELLOWFIN is not set ++# CONFIG_SK98LIN is not set ++# CONFIG_TIGON3 is not set ++# CONFIG_FDDI is not set ++# CONFIG_HIPPI is not set ++# CONFIG_PLIP is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++CONFIG_NET_RADIO=y ++# CONFIG_STRIP is not set ++# CONFIG_WAVELAN is not set ++# CONFIG_ARLAN is not set ++# CONFIG_AIRONET4500 is not set ++# CONFIG_AIRONET4500_NONCS is not set ++# CONFIG_AIRONET4500_PROC is not set ++CONFIG_AIRO=m ++# CONFIG_HERMES is not set ++# CONFIG_PCMCIA_HERMES is not set ++CONFIG_AIRO_CS=m ++CONFIG_NET_WIRELESS=y ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++# CONFIG_NET_FC is not set ++# CONFIG_RCPCI is not set ++# CONFIG_SHAPER is not set ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++ ++# ++# PCMCIA network device support ++# ++CONFIG_NET_PCMCIA=y ++CONFIG_PCMCIA_3C589=m ++CONFIG_PCMCIA_3C574=m ++# CONFIG_PCMCIA_FMVJ18X is not set ++CONFIG_PCMCIA_PCNET=m ++# CONFIG_PCMCIA_AXNET is not set ++# CONFIG_PCMCIA_NMCLAN is not set ++CONFIG_PCMCIA_SMC91C92=m ++CONFIG_PCMCIA_XIRC2PS=m ++# CONFIG_ARCNET_COM20020_CS is not set ++# CONFIG_PCMCIA_IBMTR is not set ++CONFIG_NET_PCMCIA_RADIO=y ++# CONFIG_PCMCIA_RAYCS is not set ++# CONFIG_PCMCIA_NETWAVE is not set ++CONFIG_PCMCIA_WAVELAN=m ++# CONFIG_AIRONET4500_CS is not set ++ ++# ++# Amateur Radio support ++# ++# CONFIG_HAMRADIO is not set ++ ++# ++# IrDA (infrared) support ++# ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++# CONFIG_IRNET is not set ++CONFIG_IRCOMM=m ++# CONFIG_IRDA_ULTRA is not set ++# CONFIG_IRDA_CACHE_LAST_LSAP is not set ++# CONFIG_IRDA_FAST_RR is not set ++# CONFIG_IRDA_DEBUG is not set ++ ++# ++# Infrared-port device drivers ++# ++CONFIG_IRTTY_SIR=m ++CONFIG_IRPORT_SIR=m ++# CONFIG_DONGLE is not set ++# CONFIG_USB_IRDA is not set ++# CONFIG_NSC_FIR is not set ++# CONFIG_WINBOND_FIR is not set ++# CONFIG_TOSHIBA_FIR is not set ++# CONFIG_SMC_IRCC_FIR is not set ++# CONFIG_ALI_FIR is not set ++# CONFIG_VLSI_FIR is not set ++CONFIG_SA1100_FIR=m ++ ++# ++# ATA/ATAPI/MFM/RLL support ++# ++CONFIG_IDE=m ++ ++# ++# IDE, ATA and ATAPI Block devices ++# ++CONFIG_BLK_DEV_IDE=m ++# CONFIG_BLK_DEV_HD_IDE is not set ++# CONFIG_BLK_DEV_HD is not set ++CONFIG_BLK_DEV_IDEDISK=m ++# CONFIG_IDEDISK_MULTI_MODE is not set ++# CONFIG_IDEDISK_STROKE is not set ++# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set ++# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set ++# CONFIG_BLK_DEV_IDEDISK_IBM is not set ++# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set ++# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set ++# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set ++# CONFIG_BLK_DEV_IDEDISK_WD is not set ++# CONFIG_BLK_DEV_COMMERIAL is not set ++# CONFIG_BLK_DEV_TIVO is not set ++CONFIG_BLK_DEV_IDECS=m ++# CONFIG_BLK_DEV_IDECD is not set ++# CONFIG_BLK_DEV_IDETAPE is not set ++# CONFIG_BLK_DEV_IDEFLOPPY is not set ++# CONFIG_BLK_DEV_IDESCSI is not set ++# CONFIG_IDE_TASK_IOCTL is not set ++# CONFIG_BLK_DEV_CMD640 is not set ++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set ++# CONFIG_BLK_DEV_ISAPNP is not set ++# CONFIG_IDE_CHIPSETS is not set ++# CONFIG_IDEDMA_AUTO is not set ++# CONFIG_DMA_NONPCI is not set ++# CONFIG_BLK_DEV_IDE_MODES is not set ++# CONFIG_BLK_DEV_ATARAID is not set ++# CONFIG_BLK_DEV_ATARAID_PDC is not set ++# CONFIG_BLK_DEV_ATARAID_HPT is not set ++ ++# ++# SCSI support ++# ++# CONFIG_SCSI is not set ++ ++# ++# I2O device support ++# ++# CONFIG_I2O is not set ++# CONFIG_I2O_BLOCK is not set ++# CONFIG_I2O_LAN is not set ++# CONFIG_I2O_SCSI is not set ++# CONFIG_I2O_PROC is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Input core support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_KEYBDEV is not set ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_VT_CONSOLE=y ++CONFIG_SERIAL=m ++# CONFIG_SERIAL_EXTENDED is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++# CONFIG_SERIAL_ANAKIN is not set ++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set ++# CONFIG_SERIAL_AMBA is not set ++# CONFIG_SERIAL_AMBA_CONSOLE is not set ++# CONFIG_SERIAL_CLPS711X is not set ++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set ++# CONFIG_SERIAL_21285 is not set ++# CONFIG_SERIAL_21285_OLD is not set ++# CONFIG_SERIAL_21285_CONSOLE is not set ++# CONFIG_SERIAL_UART00 is not set ++# CONFIG_SERIAL_UART00_CONSOLE is not set ++CONFIG_SERIAL_SA1100=y ++CONFIG_SERIAL_SA1100_CONSOLE=y ++CONFIG_SA1100_DEFAULT_BAUDRATE=115200 ++# CONFIG_SERIAL_OMAHA is not set ++# CONFIG_SERIAL_OMAHA_CONSOLE is not set ++# CONFIG_SERIAL_AT91US3 is not set ++# CONFIG_SERIAL_AT91US3_CONSOLE is not set ++# CONFIG_SERIAL_8250 is not set ++# CONFIG_SERIAL_8250_CONSOLE is not set ++# CONFIG_SERIAL_8250_EXTENDED is not set ++# CONFIG_SERIAL_8250_MANY_PORTS is not set ++# CONFIG_SERIAL_8250_SHARE_IRQ is not set ++# CONFIG_SERIAL_8250_DETECT_IRQ is not set ++# CONFIG_SERIAL_8250_MULTIPORT is not set ++# CONFIG_SERIAL_8250_HUB6 is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX98_PTY_COUNT=32 ++ ++# ++# I2C support ++# ++# CONFIG_I2C is not set ++ ++# ++# L3 serial bus support ++# ++# CONFIG_L3 is not set ++# CONFIG_L3_ALGOBIT is not set ++# CONFIG_L3_BIT_SA1100_GPIO is not set ++# CONFIG_L3_SA1111 is not set ++# CONFIG_BIT_SA1100_GPIO is not set ++ ++# ++# Mice ++# ++# CONFIG_BUSMOUSE is not set ++# CONFIG_MOUSE is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_GAMEPORT is not set ++# CONFIG_INPUT_NS558 is not set ++# CONFIG_INPUT_LIGHTNING is not set ++# CONFIG_INPUT_PCIGAME is not set ++# CONFIG_INPUT_CS461X is not set ++# CONFIG_INPUT_EMU10K1 is not set ++# CONFIG_INPUT_SERIO is not set ++# CONFIG_INPUT_SERPORT is not set ++# CONFIG_INPUT_ANALOG is not set ++# CONFIG_INPUT_A3D is not set ++# CONFIG_INPUT_ADI is not set ++# CONFIG_INPUT_COBRA is not set ++# CONFIG_INPUT_GF2K is not set ++# CONFIG_INPUT_GRIP is not set ++# CONFIG_INPUT_INTERACT is not set ++# CONFIG_INPUT_TMDC is not set ++# CONFIG_INPUT_SIDEWINDER is not set ++# CONFIG_INPUT_IFORCE_USB is not set ++# CONFIG_INPUT_IFORCE_232 is not set ++# CONFIG_INPUT_WARRIOR is not set ++# CONFIG_INPUT_MAGELLAN is not set ++# CONFIG_INPUT_SPACEORB is not set ++# CONFIG_INPUT_SPACEBALL is not set ++# CONFIG_INPUT_STINGER is not set ++# CONFIG_INPUT_DB9 is not set ++# CONFIG_INPUT_GAMECON is not set ++# CONFIG_INPUT_TURBOGRAFX is not set ++# CONFIG_QIC02_TAPE is not set ++ ++# ++# Watchdog Cards ++# ++# CONFIG_WATCHDOG is not set ++# CONFIG_NVRAM is not set ++# CONFIG_RTC is not set ++CONFIG_SA1100_RTC=y ++# CONFIG_DTLK is not set ++# CONFIG_R3964 is not set ++# CONFIG_APPLICOM is not set ++ ++# ++# Ftape, the floppy tape device driver ++# ++# CONFIG_FTAPE is not set ++# CONFIG_AGP is not set ++# CONFIG_DRM is not set ++ ++# ++# PCMCIA character devices ++# ++CONFIG_PCMCIA_SERIAL_CS=m ++CONFIG_TDA8007=m ++ ++# ++# Multimedia devices ++# ++# CONFIG_VIDEO_DEV is not set ++ ++# ++# File systems ++# ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++CONFIG_REISERFS_FS=m ++# CONFIG_REISERFS_CHECK is not set ++CONFIG_REISERFS_PROC_INFO=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_ADFS_FS_RW is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_BFS_FS is not set ++CONFIG_EXT3_FS=m ++CONFIG_JBD=m ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FAT_FS=m ++CONFIG_MSDOS_FS=m ++CONFIG_UMSDOS_FS=m ++CONFIG_VFAT_FS=m ++# CONFIG_EFS_FS is not set ++CONFIG_JFFS_FS=m ++CONFIG_JFFS_FS_VERBOSE=0 ++CONFIG_JFFS_PROC_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_CRAMFS=m ++# CONFIG_TMPFS is not set ++CONFIG_RAMFS=y ++# CONFIG_ISO9660_FS is not set ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_NTFS_FS is not set ++# CONFIG_NTFS_RW is not set ++# CONFIG_HPFS_FS is not set ++CONFIG_PROC_FS=y ++CONFIG_DEVFS_FS=y ++CONFIG_DEVFS_MOUNT=y ++CONFIG_DEVFS_DEBUG=y ++# CONFIG_DEVPTS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX4FS_RW is not set ++# CONFIG_ROMFS_FS is not set ++CONFIG_EXT2_FS=m ++# CONFIG_SYSV_FS is not set ++# CONFIG_UDF_FS is not set ++# CONFIG_UDF_RW is not set ++# CONFIG_UFS_FS is not set ++# CONFIG_UFS_FS_WRITE is not set ++ ++# ++# Network File Systems ++# ++# CONFIG_CODA_FS is not set ++# CONFIG_INTERMEZZO_FS is not set ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_ROOT_NFS is not set ++# CONFIG_NFSD is not set ++# CONFIG_NFSD_V3 is not set ++CONFIG_SUNRPC=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_SMB_FS=m ++# CONFIG_SMB_NLS_DEFAULT is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_NCPFS_PACKET_SIGNING is not set ++# CONFIG_NCPFS_IOCTL_LOCKING is not set ++# CONFIG_NCPFS_STRONG is not set ++# CONFIG_NCPFS_NFS_NS is not set ++# CONFIG_NCPFS_OS2_NS is not set ++# CONFIG_NCPFS_SMALLDOS is not set ++# CONFIG_NCPFS_NLS is not set ++# CONFIG_NCPFS_EXTRAS is not set ++# CONFIG_ZISOFS_FS is not set ++CONFIG_ZLIB_FS_INFLATE=m ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++CONFIG_SMB_NLS=y ++CONFIG_NLS=y ++ ++# ++# Native Language Support ++# ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++CONFIG_NLS_CODEPAGE_850=y ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++CONFIG_NLS_ISO8859_1=y ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++CONFIG_NLS_ISO8859_15=y ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++ ++# ++# Console drivers ++# ++CONFIG_PC_KEYMAP=y ++# CONFIG_VGA_CONSOLE is not set ++ ++# ++# Frame-buffer support ++# ++CONFIG_FB=y ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FB_ACORN is not set ++# CONFIG_FB_ANAKIN is not set ++# CONFIG_FB_CLPS711X is not set ++# CONFIG_FB_SA1100 is not set ++# CONFIG_FB_CYBER2000 is not set ++CONFIG_FB_MQ200=y ++# CONFIG_FB_VIRTUAL is not set ++CONFIG_FBCON_ADVANCED=y ++# CONFIG_FBCON_MFB is not set ++# CONFIG_FBCON_CFB2 is not set ++CONFIG_FBCON_CFB4=y ++CONFIG_FBCON_CFB8=y ++CONFIG_FBCON_CFB16=y ++# CONFIG_FBCON_CFB24 is not set ++# CONFIG_FBCON_CFB32 is not set ++# CONFIG_FBCON_AFB is not set ++# CONFIG_FBCON_ILBM is not set ++# CONFIG_FBCON_IPLAN2P2 is not set ++# CONFIG_FBCON_IPLAN2P4 is not set ++# CONFIG_FBCON_IPLAN2P8 is not set ++# CONFIG_FBCON_MAC is not set ++# CONFIG_FBCON_VGA_PLANES is not set ++# CONFIG_FBCON_VGA is not set ++# CONFIG_FBCON_HGA is not set ++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set ++CONFIG_FBCON_FONTS=y ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++# CONFIG_FONT_SUN8x16 is not set ++# CONFIG_FONT_SUN12x22 is not set ++# CONFIG_FONT_6x11 is not set ++# CONFIG_FONT_PEARL_8x8 is not set ++# CONFIG_FONT_ACORN_8x8 is not set ++ ++# ++# Sound ++# ++CONFIG_SOUND=y ++# CONFIG_SOUND_BT878 is not set ++# CONFIG_SOUND_CMPCI is not set ++# CONFIG_SOUND_EMU10K1 is not set ++# CONFIG_MIDI_EMU10K1 is not set ++# CONFIG_SOUND_FUSION is not set ++# CONFIG_SOUND_CS4281 is not set ++# CONFIG_SOUND_ES1370 is not set ++# CONFIG_SOUND_ES1371 is not set ++# CONFIG_SOUND_ESSSOLO1 is not set ++# CONFIG_SOUND_MAESTRO is not set ++# CONFIG_SOUND_MAESTRO3 is not set ++# CONFIG_SOUND_ICH is not set ++# CONFIG_SOUND_RME96XX is not set ++# CONFIG_SOUND_SONICVIBES is not set ++# CONFIG_SOUND_TRIDENT is not set ++# CONFIG_SOUND_MSNDCLAS is not set ++# CONFIG_SOUND_MSNDPIN is not set ++# CONFIG_SOUND_VIA82CXXX is not set ++# CONFIG_MIDI_VIA82CXXX is not set ++CONFIG_SOUND_SA1100=y ++# CONFIG_SOUND_UDA1341 is not set ++# CONFIG_SOUND_ASSABET_UDA1341 is not set ++# CONFIG_SOUND_H3600_UDA1341 is not set ++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set ++# CONFIG_SOUND_SA1111_UDA1341 is not set ++# CONFIG_SOUND_SA1111_AC97 is not set ++# CONFIG_SOUND_SA1100SSP is not set ++# CONFIG_SOUND_OSS is not set ++# CONFIG_SOUND_VIDC is not set ++# CONFIG_SOUND_WAVEARTIST is not set ++# CONFIG_SOUND_TVMIXER is not set ++ ++# ++# Multimedia Capabilities Port drivers ++# ++CONFIG_MCP=y ++CONFIG_MCP_SA1100=y ++CONFIG_MCP_UCB1200=y ++CONFIG_MCP_UCB1200_AUDIO=y ++CONFIG_MCP_UCB1200_TS=y ++ ++# ++# Console Switches ++# ++CONFIG_SWITCHES=y ++CONFIG_SWITCHES_SA1100=y ++CONFIG_SWITCHES_UCB1X00=y ++ ++# ++# USB support ++# ++# CONFIG_USB is not set ++ ++# ++# Bluetooth support ++# ++# CONFIG_BLUEZ is not set ++ ++# ++# Kernel hacking ++# ++CONFIG_FRAME_POINTER=y ++CONFIG_DEBUG_USER=y ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_NO_PGT_CACHE is not set ++# CONFIG_DEBUG_KERNEL is not set ++# CONFIG_DEBUG_SLAB is not set ++# CONFIG_MAGIC_SYSRQ is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++# CONFIG_DEBUG_WAITQ is not set ++# CONFIG_DEBUG_BUGVERBOSE is not set ++# CONFIG_DEBUG_ERRORS is not set ++# CONFIG_DEBUG_LL is not set ++# CONFIG_DEBUG_DC21285_PORT is not set ++# CONFIG_DEBUG_CLPS711X_UART2 is not set +--- linux-2.4.25/arch/arm/kernel/head-armv.S~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/arch/arm/kernel/head-armv.S 2004-05-02 22:45:42.000000000 +0200 +@@ -93,6 +93,8 @@ + .section ".text.init",#alloc,#execinstr + .type stext, #function + ENTRY(stext) ++ mov r1, #87 ++ mov r0, #0 + mov r12, r0 + /* + * NOTE! Any code which is placed here should be done for one of +--- linux-2.4.25/arch/arm/kernel/irq.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200 ++++ linux-2.4.25/arch/arm/kernel/irq.c 2004-05-02 22:45:42.000000000 +0200 +@@ -82,9 +82,9 @@ + + spin_lock_irqsave(&irq_controller_lock, flags); + if (!desc->disable_depth++) { +-#ifndef CONFIG_CPU_SA1100 ++// #ifndef CONFIG_CPU_SA1100 + desc->mask(irq); +-#endif ++// #endif + } + spin_unlock_irqrestore(&irq_controller_lock, flags); + } +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/apm.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,520 @@ ++/* ++ * bios-less APM driver for ARM Linux ++ * Jamey Hicks <jamey@crl.dec.com> ++ * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com) ++ * ++ * APM 1.2 Reference: ++ * Intel Corporation, Microsoft Corporation. Advanced Power Management ++ * (APM) BIOS Interface Specification, Revision 1.2, February 1996. ++ * ++ * [This document is available from Microsoft at: ++ * http://www.microsoft.com/hwdev/busbios/amp_12.htm] ++ */ ++ ++#include <linux/config.h> ++#include <linux/module.h> ++ ++#include <linux/poll.h> ++#include <linux/types.h> ++#include <linux/stddef.h> ++#include <linux/timer.h> ++#include <linux/fcntl.h> ++#include <linux/slab.h> ++#include <linux/stat.h> ++#include <linux/proc_fs.h> ++#include <linux/miscdevice.h> ++#include <linux/apm_bios.h> ++#include <linux/init.h> ++#include <linux/sched.h> ++#include <linux/pm.h> ++#include <linux/kernel.h> ++#include <linux/smp_lock.h> ++ ++#include <asm/system.h> ++#include <asm/hardware.h> ++#if FIXME ++#include <asm/arch-sa1100/pm.h> ++#endif ++ ++#ifdef CONFIG_IPAQ_HANDHELD ++#include <asm/arch-sa1100/h3600_hal.h> ++#endif ++ ++#ifdef CONFIG_SA1100_SIMPAD ++#include <asm/arch-sa1100/simpad_pm.h> ++#endif ++ ++#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) ++extern int (*console_blank_hook)(int); ++#endif ++ ++struct apm_bios_info apm_bios_info = { ++ /* this driver simulates APM version 1.2 */ ++ version: 0x102, ++ flags: APM_32_BIT_SUPPORT ++}; ++ ++/* ++ * The apm_bios device is one of the misc char devices. ++ * This is its minor number. ++ */ ++#define APM_MINOR_DEV 134 ++ ++/* ++ * See Documentation/Config.help for the configuration options. ++ * ++ * Various options can be changed at boot time as follows: ++ * (We allow underscores for compatibility with the modules code) ++ * apm=on/off enable/disable APM ++ * [no-]debug log some debugging messages ++ * [no-]power[-_]off power off on shutdown ++ */ ++ ++/* ++ * Need to poll the APM BIOS every second ++ */ ++#define APM_CHECK_TIMEOUT (HZ) ++ ++/* ++ * Ignore suspend events for this amount of time after a resume ++ */ ++#define DEFAULT_BOUNCE_INTERVAL (3 * HZ) ++ ++/* ++ * Maximum number of events stored ++ */ ++#define APM_MAX_EVENTS 20 ++ ++/* ++ * The per-file APM data ++ */ ++struct apm_user { ++ int magic; ++ struct apm_user * next; ++ int suser: 1; ++ int suspend_wait: 1; ++ int suspend_result; ++ int suspends_pending; ++ int standbys_pending; ++ int suspends_read; ++ int standbys_read; ++ int event_head; ++ int event_tail; ++ apm_event_t events[APM_MAX_EVENTS]; ++}; ++ ++/* ++ * The magic number in apm_user ++ */ ++#define APM_BIOS_MAGIC 0x4101 ++ ++/* ++ * Local variables ++ */ ++//static int suspends_pending; ++//static int standbys_pending; ++//static int ignore_normal_resume; ++ ++#ifdef CONFIG_APM_RTC_IS_GMT ++# define clock_cmos_diff 0 ++# define got_clock_diff 1 ++#else ++//static long clock_cmos_diff; ++//static int got_clock_diff; ++#endif ++static int debug; ++static int apm_disabled; ++#ifdef CONFIG_SMP ++static int power_off; ++#else ++static int power_off = 1; ++#endif ++static int exit_kapmd; ++static int kapmd_running; ++ ++static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); ++static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); ++static struct apm_user * user_list = NULL; ++ ++static char driver_version[] = "1.13"; /* no spaces */ ++ ++typedef struct lookup_t { ++ int key; ++ char * msg; ++} lookup_t; ++ ++static const lookup_t error_table[] = { ++/* N/A { APM_SUCCESS, "Operation succeeded" }, */ ++ { APM_DISABLED, "Power management disabled" }, ++ { APM_CONNECTED, "Real mode interface already connected" }, ++ { APM_NOT_CONNECTED, "Interface not connected" }, ++ { APM_16_CONNECTED, "16 bit interface already connected" }, ++/* N/A { APM_16_UNSUPPORTED, "16 bit interface not supported" }, */ ++ { APM_32_CONNECTED, "32 bit interface already connected" }, ++ { APM_32_UNSUPPORTED, "32 bit interface not supported" }, ++ { APM_BAD_DEVICE, "Unrecognized device ID" }, ++ { APM_BAD_PARAM, "Parameter out of range" }, ++ { APM_NOT_ENGAGED, "Interface not engaged" }, ++ { APM_BAD_FUNCTION, "Function not supported" }, ++ { APM_RESUME_DISABLED, "Resume timer disabled" }, ++ { APM_BAD_STATE, "Unable to enter requested state" }, ++/* N/A { APM_NO_EVENTS, "No events pending" }, */ ++ { APM_NO_ERROR, "BIOS did not set a return code" }, ++ { APM_NOT_PRESENT, "No APM present" } ++}; ++#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t)) ++ ++static int apm_get_power_status(u_char *ac_line_status, ++ u_char *battery_status, ++ u_char *battery_flag, ++ u_char *battery_percentage, ++ u_short *battery_life) ++{ ++#ifdef CONFIG_IPAQ_HANDHELD ++ h3600_apm_get_power_status(ac_line_status, battery_status, battery_flag, battery_percentage, battery_life); ++#endif ++#ifdef CONFIG_SA1100_SIMPAD ++ simpad_apm_get_power_status(ac_line_status, battery_status, battery_flag, battery_percentage, battery_life); ++#endif ++ return APM_SUCCESS; ++} ++ ++static int queue_empty(struct apm_user *as) ++{ ++ return as->event_head == as->event_tail; ++} ++ ++static apm_event_t get_queued_event(struct apm_user *as) ++{ ++ as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; ++ return as->events[as->event_tail]; ++} ++ ++static int check_apm_user(struct apm_user *as, const char *func) ++{ ++ if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) { ++ printk(KERN_ERR "apm: %s passed bad filp\n", func); ++ return 1; ++ } ++ return 0; ++} ++ ++static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos) ++{ ++ struct apm_user * as; ++ int i; ++ apm_event_t event; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ as = fp->private_data; ++ if (check_apm_user(as, "read")) ++ return -EIO; ++ if (count < sizeof(apm_event_t)) ++ return -EINVAL; ++ if (queue_empty(as)) { ++ if (fp->f_flags & O_NONBLOCK) ++ return -EAGAIN; ++ add_wait_queue(&apm_waitqueue, &wait); ++ printk("do_read: waiting\n"); ++repeat: ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (queue_empty(as) && !signal_pending(current)) { ++ schedule(); ++ goto repeat; ++ } ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&apm_waitqueue, &wait); ++ } ++ i = count; ++ while ((i >= sizeof(event)) && !queue_empty(as)) { ++ event = get_queued_event(as); ++ printk(" do_read: event=%d\n", event); ++ if (copy_to_user(buf, &event, sizeof(event))) { ++ if (i < count) ++ break; ++ return -EFAULT; ++ } ++ switch (event) { ++ case APM_SYS_SUSPEND: ++ case APM_USER_SUSPEND: ++ as->suspends_read++; ++ break; ++ ++ case APM_SYS_STANDBY: ++ case APM_USER_STANDBY: ++ as->standbys_read++; ++ break; ++ } ++ buf += sizeof(event); ++ i -= sizeof(event); ++ } ++ if (i < count) ++ return count - i; ++ if (signal_pending(current)) ++ return -ERESTARTSYS; ++ return 0; ++} ++ ++static unsigned int do_poll(struct file *fp, poll_table * wait) ++{ ++ struct apm_user * as; ++ ++ as = fp->private_data; ++ if (check_apm_user(as, "poll")) ++ return 0; ++ poll_wait(fp, &apm_waitqueue, wait); ++ if (!queue_empty(as)) ++ return POLLIN | POLLRDNORM; ++ return 0; ++} ++ ++static int do_ioctl(struct inode * inode, struct file *filp, ++ u_int cmd, u_long arg) ++{ ++ struct apm_user * as; ++ ++ as = filp->private_data; ++ if (check_apm_user(as, "ioctl")) ++ return -EIO; ++ if (!as->suser) ++ return -EPERM; ++ switch (cmd) { ++ case APM_IOC_SUSPEND: ++#if FIXME ++ pm_suggest_suspend(); ++#endif ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int do_release(struct inode * inode, struct file * filp) ++{ ++ struct apm_user * as; ++ ++ as = filp->private_data; ++ if (check_apm_user(as, "release")) ++ return 0; ++ filp->private_data = NULL; ++ lock_kernel(); ++ unlock_kernel(); ++ kfree(as); ++ return 0; ++} ++ ++static int do_open(struct inode * inode, struct file * filp) ++{ ++ struct apm_user * as; ++ ++ as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL); ++ if (as == NULL) { ++ printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", ++ sizeof(*as)); ++ return -ENOMEM; ++ } ++ as->magic = APM_BIOS_MAGIC; ++ as->event_tail = as->event_head = 0; ++ as->suspends_pending = as->standbys_pending = 0; ++ as->suspends_read = as->standbys_read = 0; ++ /* ++ * XXX - this is a tiny bit broken, when we consider BSD ++ * process accounting. If the device is opened by root, we ++ * instantly flag that we used superuser privs. Who knows, ++ * we might close the device immediately without doing a ++ * privileged operation -- cevans ++ */ ++ as->suser = capable(CAP_SYS_ADMIN); ++ as->next = user_list; ++ user_list = as; ++ filp->private_data = as; ++ return 0; ++} ++ ++static int apm_get_info(char *buf, char **start, off_t fpos, int length) ++{ ++ char * p; ++ unsigned short dx; ++ unsigned short error; ++ unsigned char ac_line_status = 0xff; ++ unsigned char battery_status = 0xff; ++ unsigned char battery_flag = 0xff; ++ unsigned char percentage = 0xff; ++ int time_units = -1; ++ char *units = "?"; ++ ++ p = buf; ++ ++ if ((smp_num_cpus == 1) && ++ !(error = apm_get_power_status(&ac_line_status, ++ &battery_status, &battery_flag, &percentage, &dx))) { ++ if (apm_bios_info.version > 0x100) { ++ if (dx != 0xffff) { ++ units = (dx & 0x8000) ? "min" : "sec"; ++ time_units = dx & 0x7fff; ++ } ++ } ++ } ++ /* Arguments, with symbols from linux/apm_bios.h. Information is ++ from the Get Power Status (0x0a) call unless otherwise noted. ++ ++ 0) Linux driver version (this will change if format changes) ++ 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2. ++ 2) APM flags from APM Installation Check (0x00): ++ bit 0: APM_16_BIT_SUPPORT ++ bit 1: APM_32_BIT_SUPPORT ++ bit 2: APM_IDLE_SLOWS_CLOCK ++ bit 3: APM_BIOS_DISABLED ++ bit 4: APM_BIOS_DISENGAGED ++ 3) AC line status ++ 0x00: Off-line ++ 0x01: On-line ++ 0x02: On backup power (BIOS >= 1.1 only) ++ 0xff: Unknown ++ 4) Battery status ++ 0x00: High ++ 0x01: Low ++ 0x02: Critical ++ 0x03: Charging ++ 0x04: Selected battery not present (BIOS >= 1.2 only) ++ 0xff: Unknown ++ 5) Battery flag ++ bit 0: High ++ bit 1: Low ++ bit 2: Critical ++ bit 3: Charging ++ bit 7: No system battery ++ 0xff: Unknown ++ 6) Remaining battery life (percentage of charge): ++ 0-100: valid ++ -1: Unknown ++ 7) Remaining battery life (time units): ++ Number of remaining minutes or seconds ++ -1: Unknown ++ 8) min = minutes; sec = seconds */ ++ ++ p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", ++ driver_version, ++ (apm_bios_info.version >> 8) & 0xff, ++ apm_bios_info.version & 0xff, ++ apm_bios_info.flags, ++ ac_line_status, ++ battery_status, ++ battery_flag, ++ percentage, ++ time_units, ++ units); ++ ++ return p - buf; ++} ++ ++#ifndef MODULE ++static int __init apm_setup(char *str) ++{ ++ int invert; ++ ++ while ((str != NULL) && (*str != '\0')) { ++ if (strncmp(str, "off", 3) == 0) ++ apm_disabled = 1; ++ if (strncmp(str, "on", 2) == 0) ++ apm_disabled = 0; ++ invert = (strncmp(str, "no-", 3) == 0); ++ if (invert) ++ str += 3; ++ if (strncmp(str, "debug", 5) == 0) ++ debug = !invert; ++ if ((strncmp(str, "power-off", 9) == 0) || ++ (strncmp(str, "power_off", 9) == 0)) ++ power_off = !invert; ++ str = strchr(str, ','); ++ if (str != NULL) ++ str += strspn(str, ", \t"); ++ } ++ return 1; ++} ++ ++__setup("apm=", apm_setup); ++#endif ++ ++static struct file_operations apm_bios_fops = { ++ owner: THIS_MODULE, ++ read: do_read, ++ poll: do_poll, ++ ioctl: do_ioctl, ++ open: do_open, ++ release: do_release, ++}; ++ ++static struct miscdevice apm_device = { ++ APM_MINOR_DEV, ++ "apm_bios", ++ &apm_bios_fops ++}; ++ ++#define APM_INIT_ERROR_RETURN return -1 ++ ++/* ++ * Just start the APM thread. We do NOT want to do APM BIOS ++ * calls from anything but the APM thread, if for no other reason ++ * than the fact that we don't trust the APM BIOS. This way, ++ * most common APM BIOS problems that lead to protection errors ++ * etc will have at least some level of being contained... ++ * ++ * In short, if something bad happens, at least we have a choice ++ * of just killing the apm thread.. ++ */ ++static int __init apm_init(void) ++{ ++ if (apm_bios_info.version == 0) { ++ printk(KERN_INFO "apm: BIOS not found.\n"); ++ APM_INIT_ERROR_RETURN; ++ } ++ printk(KERN_INFO ++ "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n", ++ ((apm_bios_info.version >> 8) & 0xff), ++ (apm_bios_info.version & 0xff), ++ apm_bios_info.flags, ++ driver_version); ++ ++ if (apm_disabled) { ++ printk(KERN_NOTICE "apm: disabled on user request.\n"); ++ APM_INIT_ERROR_RETURN; ++ } ++ ++ if (PM_IS_ACTIVE()) { ++ printk(KERN_NOTICE "apm: overridden by ACPI.\n"); ++ APM_INIT_ERROR_RETURN; ++ } ++ pm_active = 1; ++ ++ create_proc_info_entry("apm", 0, NULL, apm_get_info); ++ ++ misc_register(&apm_device); ++ ++ return 0; ++} ++ ++static void __exit apm_exit(void) ++{ ++ misc_deregister(&apm_device); ++ remove_proc_entry("apm", NULL); ++ if (power_off) ++ pm_power_off = NULL; ++ exit_kapmd = 1; ++ while (kapmd_running) ++ schedule(); ++ pm_active = 0; ++} ++ ++module_init(apm_init); ++module_exit(apm_exit); ++ ++MODULE_AUTHOR("Jamey Hicks, pulling bits from original by Stephen Rothwell"); ++MODULE_DESCRIPTION("A minimal emulation of APM"); ++MODULE_PARM(debug, "i"); ++MODULE_PARM_DESC(debug, "Enable debug mode"); ++MODULE_PARM(power_off, "i"); ++MODULE_PARM_DESC(power_off, "Enable power off"); ++ ++EXPORT_NO_SYMBOLS; +--- linux-2.4.25/arch/arm/mach-sa1100/leds.c~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:39.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/leds.c 2004-05-02 22:45:42.000000000 +0200 +@@ -45,6 +45,8 @@ + leds_event = pfs168_leds_event; + if (machine_is_pt_system3()) + leds_event = system3_leds_event; ++ if (machine_is_simpad()) ++ leds_event = simpad_leds_event; + + leds_event(led_start); + return 0; +--- linux-2.4.25/arch/arm/mach-sa1100/leds.h~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:39.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/leds.h 2004-05-02 22:45:42.000000000 +0200 +@@ -12,4 +12,6 @@ + extern void hackkit_leds_event(led_event_t evt); + extern void lart_leds_event(led_event_t evt); + extern void pfs168_leds_event(led_event_t evt); ++extern void simpad_leds_event(led_event_t evt); + extern void system3_leds_event(led_event_t evt); ++ +--- linux-2.4.25/arch/arm/mach-sa1100/pm.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/pm.c 2004-05-02 22:45:42.000000000 +0200 +@@ -63,6 +63,7 @@ + SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, + + SLEEP_SAVE_ICMR, ++ SLEEP_SAVE_MECR, + SLEEP_SAVE_Ser1SDCR0, + + SLEEP_SAVE_SIZE +@@ -109,6 +110,8 @@ + + SAVE(ICMR); + ++ SAVE(MECR); ++ + /* ... maybe a global variable initialized by arch code to set this? */ + GRER = PWER; + GFER = 0; +@@ -163,6 +166,8 @@ + ICCR = 1; + RESTORE(ICMR); + ++ RESTORE(MECR); ++ + /* restore current time */ + xtime.tv_sec = RCNR + delta; + +--- linux-2.4.25/arch/arm/mach-sa1100/simpad.c~2.4.25-vrs2-pxa1-jpm1.patch 2003-06-13 16:51:29.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/simpad.c 2004-05-02 22:48:26.000000000 +0200 +@@ -10,6 +10,7 @@ + #include <linux/tty.h> + #include <linux/proc_fs.h> + #include <linux/string.h> ++#include <linux/pm.h> + + #include <asm/hardware.h> + #include <asm/setup.h> +@@ -28,6 +29,11 @@ + return cs3_shadow; + } + ++void set_cs3(long value) ++{ ++ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value; ++} ++ + void set_cs3_bit(int value) + { + cs3_shadow |= value; +@@ -40,31 +46,62 @@ + *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; + } + ++EXPORT_SYMBOL(set_cs3_bit); ++EXPORT_SYMBOL(clear_cs3_bit); ++ ++static void simpad_power_off(void) ++{ ++ cli(); ++ set_cs3(0x800); /* only SD_MEDIAQ */ ++ ++ /* disable internal oscillator, float CS lines */ ++ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); ++ /* enable wake-up on GPIO0 (Assabet...) */ ++ PWER = GFER = GRER = 1; ++ /* ++ * 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); ++} ++ ++static int __init simpad_init(void) ++{ ++ pm_power_off = simpad_power_off; ++ return 0; ++} ++ ++__initcall(simpad_init); ++ + static void __init + fixup_simpad(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) + { +-#ifdef CONFIG_SA1100_SIMPAD_DRAM_64MB /* DRAM */ +- SET_BANK( 0, 0xc0000000, 64*1024*1024 ); +-#else ++#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); ++#else ++ SET_BANK( 0, 0xc0000000, 64*1024*1024 ); + #endif + mi->nr_banks = 1; +- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); ++ + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); + } + +- + static struct map_desc simpad_io_desc[] __initdata = { +- /* virtual physical length domain r w c b */ +- { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, +- { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */ +- { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Paules CS3, write only */ ++ /* virtual physical length domain r w c b */ ++ { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, ++ { 0xe9000000, 0x08000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, ++ { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CS3, write only */ ++ { 0xf2000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CS4, tda8007 */ ++ { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */ + LAST_DESC + }; + +- + static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate) + { + if (port->mapbase == (u_int)&Ser1UTCR0) { +@@ -81,20 +118,32 @@ + + static void __init simpad_map_io(void) + { +- sa1100_map_io(); +- iotable_init(simpad_io_desc); ++ sa1100_map_io(); ++ iotable_init(simpad_io_desc); + +- PSPR = 0xc0008000; +- GPDR &= ~GPIO_GPIO0; +- cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | +- ENABLE_5V | RESET_SIMCARD); +- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; ++ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | ++ ENABLE_5V | nRESET_SIMCARD); + +- //It is only possible to register 3 UART in serial_sa1100.c +- sa1100_register_uart(0, 3); +- sa1100_register_uart(1, 1); ++ //It is only possible to register 3 UART in serial_sa1100.c ++ sa1100_register_uart(0, 3); ++ sa1100_register_uart(1, 1); + +- set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE); ++ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); ++ GPDR |= GPIO_UART_TXD; ++ GPDR &= ~GPIO_UART_RXD; ++ PPAR |= PPAR_UPR; ++ ++ set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE); ++ set_GPIO_IRQ_edge(GPIO_POWER_BUTTON, GPIO_FALLING_EDGE); ++ ++ /* ++ * Set up registers for sleep mode. ++ */ ++ ++ PWER = PWER_GPIO0; ++ PGSR = 0x818; ++ PCFR = 0; ++ PSDR = 0; + } + + #ifdef CONFIG_PROC_FS +@@ -140,7 +189,17 @@ + + return len; + } +- ++ ++static int proc_cs3_write(struct file * file, const char * buffer, ++ size_t count, loff_t *ppos) ++{ ++ unsigned long newRegValue; ++ char *endp; ++ ++ newRegValue = simple_strtoul(buffer,&endp,0); ++ set_cs3( newRegValue ); ++ return (count+endp-buffer); ++} + + static struct proc_dir_entry *proc_cs3; + +@@ -148,7 +207,10 @@ + { + proc_cs3 = create_proc_entry("cs3", 0, 0); + if (proc_cs3) ++ { + proc_cs3->read_proc = proc_cs3_read; ++ proc_cs3->write_proc = (void*)proc_cs3_write; ++ } + return 0; + } + +@@ -165,6 +227,7 @@ + MACHINE_START(SIMPAD, "Simpad") + MAINTAINER("Juergen Messerer") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) ++ BOOT_PARAMS(0xc0000100) + FIXUP(fixup_simpad) + MAPIO(simpad_map_io) + INITIRQ(sa1100_init_irq) +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/arch/arm/mach-sa1100/simpad_pm.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,147 @@ ++/* ++* Powermanagement layer for SIMPad. ++* ++* Copyright 2003 Peter Pregler ++* Copyright 2000,2001 Compaq Computer Corporation. ++* ++* Use consistent with the GNU GPL is permitted, ++* provided that this copyright notice is ++* preserved in its entirety in all copies and derived works. ++* ++* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, ++* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS ++* FITNESS FOR ANY PARTICULAR PURPOSE. ++* ++* Author: Peter Pregler (based on work for ipaq by Andrew Christian) ++* May, 2003 ++*/ ++ ++#include <linux/module.h> ++#include <linux/version.h> ++ ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/delay.h> ++#include <linux/poll.h> ++#include <asm/uaccess.h> /* get_user,copy_to_user */ ++#include <linux/string.h> ++#include <linux/interrupt.h> ++#include <linux/sysctl.h> ++#include <linux/console.h> ++#include <linux/devfs_fs_kernel.h> ++ ++#include <linux/tqueue.h> ++#include <linux/sched.h> ++#include <linux/pm.h> ++#include <linux/proc_fs.h> ++#include <linux/apm_bios.h> ++#include <linux/kmod.h> ++ ++#include <asm/hardware.h> ++#include <asm/arch-sa1100/simpad_pm.h> ++ ++MODULE_AUTHOR("Peter Pregler"); ++MODULE_DESCRIPTION("Power manamgement abstraction layer for the SIMpad"); ++ ++/****************************************************************************/ ++/* Functions exported for use by the kernel and kernel modules */ ++/****************************************************************************/ ++ ++int simpad_apm_get_power_status(u_char *ac_line_status, ++ u_char *battery_status, ++ u_char *battery_flag, ++ u_char *battery_percentage, ++ u_short *battery_life) ++{ ++ struct simpad_battery bstat; ++ unsigned char ac = APM_AC_UNKNOWN; ++ unsigned char level = APM_BATTERY_STATUS_UNKNOWN; ++ int status, result; ++ ++ result = simpad_get_battery(&bstat); ++ if (result) { ++ printk("%s: unable to access battery information: result=%d\n", __FUNCTION__, result); ++ return 0; ++ } ++ ++ switch (bstat.ac_status) { ++ case SIMPAD_AC_STATUS_AC_OFFLINE: ++ ac = APM_AC_OFFLINE; ++ break; ++ case SIMPAD_AC_STATUS_AC_ONLINE: ++ ac = APM_AC_ONLINE; ++ break; ++ case SIMPAD_AC_STATUS_AC_BACKUP: ++ ac = APM_AC_BACKUP; ++ break; ++ } ++ ++ if (ac_line_status != NULL) ++ *ac_line_status = ac; ++ ++ status = bstat.status; ++ if (status & (SIMPAD_BATT_STATUS_CHARGING | SIMPAD_BATT_STATUS_CHARGE_MAIN)) ++ level = APM_BATTERY_STATUS_CHARGING; ++ else if (status & (SIMPAD_BATT_STATUS_HIGH | SIMPAD_BATT_STATUS_FULL)) ++ level = APM_BATTERY_STATUS_HIGH; ++ else if (status & SIMPAD_BATT_STATUS_LOW) ++ level = APM_BATTERY_STATUS_LOW; ++ else if (status & SIMPAD_BATT_STATUS_CRITICAL) ++ level = APM_BATTERY_STATUS_CRITICAL; ++ ++ if (battery_status != NULL) ++ *battery_status = level; ++ ++ if (battery_percentage != NULL) ++ *battery_percentage = bstat.percentage; ++ ++ /* we have a dumb battery - so we know nothing */ ++ if (battery_life != NULL) { ++ *battery_life = APM_BATTERY_LIFE_UNKNOWN; ++ } ++ ++#if 0 ++ printk("apm_get_power: ac: %02x / bs: %02x / bf: %02x / perc: %02x / life: %d\n", ++ *ac_line_status, *battery_status, *battery_flag, ++ *battery_percentage, *battery_life ); ++#endif ++ return 1; ++} ++ ++EXPORT_SYMBOL(simpad_apm_get_power_status); ++ ++ ++/***********************************************************************************/ ++/* Initialization */ ++/***********************************************************************************/ ++ ++#ifdef CONFIG_FB_MQ200 ++extern void (*mq200_blank_helper)(int blank); ++#endif ++ ++int __init simpad_hal_init_module(void) ++{ ++ int i; ++ printk(KERN_INFO "SIMpad Registering HAL abstraction layer\n"); ++ ++ /* Request the appropriate underlying module to provide services */ ++ ++#ifdef CONFIG_FB_SA1100 ++ sa1100fb_blank_helper = simpad_hal_backlight_helper; ++#endif ++ ++ return 0; ++} ++ ++void simpad_hal_cleanup_module(void) ++{ ++ int i; ++ printk(KERN_INFO "SIMpad shutting down HAL abstraction layer\n"); ++ ++#ifdef CONFIG_FB_SA1100 ++ sa1100fb_blank_helper = NULL; ++#endif ++} ++ ++module_init(simpad_hal_init_module); ++module_exit(simpad_hal_cleanup_module); +--- linux-2.4.25/drivers/char/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/char/Config.in 2004-05-02 22:45:42.000000000 +0200 +@@ -425,4 +425,7 @@ + tristate ' MT6N TTL I/O suport' CONFIG_TRIZEPS2_TTLIO + fi + ++if [ "$CONFIG_SA1100_SIMPAD" = "y" ]; then ++ tristate 'Smartcardreader(TDA8007) support' CONFIG_TDA8007 ++fi + endmenu +--- linux-2.4.25/drivers/char/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/char/Makefile 2004-05-02 22:45:42.000000000 +0200 +@@ -376,6 +376,8 @@ + obj-y += ipmi/ipmi.o + endif + ++obj-$(CONFIG_TDA8007) += tda8007.o ++ + include $(TOPDIR)/Rules.make + + fastdep: +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/char/tda8007.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,514 @@ ++/* ++ * linux/drivers/char/tda8007.c ++ * ++ * Copyright (C) 2001 juergen.messerer@freesurf.ch, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License. ++ * ++ * The TDA8007B driver provides basic services for handling IO, ++ * interrupts, and accessing registers. ++ */ ++ ++#include <linux/delay.h> ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/errno.h> ++#include <linux/interrupt.h> ++#include <linux/proc_fs.h> ++ ++#include <asm/dma.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/arch/simpad.h> ++#include <asm/uaccess.h> ++ ++#include "tda8007b.h" ++ ++#define TDA8007_DIRNAME "driver/tda8007" ++#define REG_DIRNAME "registers" ++ ++extern void clear_cs3_bit(int value); ++ ++static struct proc_dir_entry *regdir; ++static struct proc_dir_entry *tda8007dir; ++ ++static ssize_t proc_tda8007_read(struct file * file, char * buf, ++ size_t nbytes, loff_t *ppos); ++static ssize_t proc_tda8007_write(struct file * file, const char * buffer, ++ size_t count, loff_t *ppos); ++ ++static struct file_operations proc_reg_operations = { ++ read: proc_tda8007_read, ++ write: proc_tda8007_write ++}; ++ ++static int __init tda8007_init(); ++ ++/* ------------------------------------------------------------------------- */ ++void tda8007_reg_write(int reg, int val) ++{ ++ printk("Address:%x \n", CS4_BASE+reg); ++ printk("Value:%x \n", val); ++ TDA_REG_WRITE(reg,val); ++} ++/* ------------------------------------------------------------------------- */ ++int tda8007_reg_read(int reg) ++{ ++ printk("Address:%x \n", CS4_BASE+reg); ++ return(TDA_REG_READ(reg)&0xff); ++} ++/* ------------------------------------------------------------------------- */ ++int tdaregs[16]; ++/* ------------------------------------------------------------------------- */ ++static void tda8007_irq(int irqnr, void *devid, struct pt_regs *regs) ++{ ++ printk("\n****tda8007_irq****\n"); ++} ++/* ------------------------------------------------------------------------- */ ++static int tda_card_present( uint cardport ) ++{ ++ int val=0; ++ ++ switch( cardport ) ++ { ++ case CARD_PORT1: ++ if( tda8007_reg_read(TDA_MSR) & TDA_MSR_PR1 ) ++ val = 1; ++ break; ++ case CARD_PORT2: ++ if( tda8007_reg_read(TDA_MSR) & TDA_MSR_PR2 ) ++ val = 1; ++ break; ++ default: ++ val =0; ++ break; ++ } ++ ++ return val; ++} ++/* ------------------------------------------------------------------------- */ ++void tda_inituart(void) ++{ ++ int hsr_reg, fcr_reg; ++ ++ printk("Init TDA8007 Uart\n"); ++ hsr_reg = tda8007_reg_read(TDA_HSR); ++ tda8007_reg_write(TDA_PCR, 0x00); ++ ++ tda8007_reg_write(TDA_CSR, 0x00); ++ tda8007_reg_write(TDA_CSR, TDA_CSR_SC1); /* select Card 1 */ ++ ++ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU|TDA_CSR_SC1); ++ tda8007_reg_write(TDA_PCR, 0x00); ++ ++ tda8007_reg_write(TDA_PDR, TDA_PDR_VAL); /* Rat v. jandu 8.9.2000 */ ++ tda8007_reg_write(TDA_UCR2, TDA_UCR2_DIV); ++ ++ tda8007_reg_write(TDA_CCR, 0x40|TDA_CCR_AC1); /*1=XTAL/2 2=XTAL/4 3=XTAL/8 */ ++ tda8007_reg_write(TDA_GTR, TDA_GTR_GT1); ++ ++ fcr_reg = tda8007_reg_read(TDA_FCR); ++ tda8007_reg_write(TDA_FCR, (fcr_reg & 0xf0) | TDA_FCR_FL1); ++ ++ tda8007_reg_write(TDA_FCR, TDA_FCR_FL2|TDA_FCR_FL1|TDA_FCR_FL0); ++ tda8007_reg_write(TDA_UCR1, TDA_UCR_SS|TDA_UCR_CONV); ++ tda8007_reg_write(TDA_PCR, 0x00); ++ ++ while( tda8007_reg_read(TDA_USR) & TDA_USR_TBE_RBF ) ++ { ++ hsr_reg = tda8007_reg_read(TDA_URR); ++ udelay(5); ++ } ++} ++/* ------------------------------------------------------------------------- */ ++void start_tda8007_sync(int volt) ++{ ++ int i=0,j=0; ++ if( tda_card_present( CARD_PORT1 ) ) ++ { ++ printk("Card Present "); ++ tda8007_reg_write(TDA_TOR1, TDA_TOR1_TOL2|TDA_TOR1_TOL3); ++ tda8007_reg_write(TDA_TOR2, TDA_TOR2_TOL16|TDA_TOR2_TOL15| ++ TDA_TOR2_TOL13|TDA_TOR2_TOL12| ++ TDA_TOR2_TOL11); ++ tda8007_reg_write(TDA_TOR3, 0x00); ++ tda8007_reg_write(TDA_TOC, TDA_TOC_MODE2); ++ tda_inituart(); ++ tda8007_reg_write(TDA_UCR2, TDA_UCR_DISAUX|TDA_UCR2_DIV); // DIS_AUX ASYNC MODE ++ ++ if( volt == 3 ) ++ volt = TDA_PCR_3V_5V; ++ else ++ volt = 0x00; ++ ++ tda8007_reg_write(TDA_PCR, 0x00|volt); // Set /Reset,3V ++ udelay(1000); ++ tda8007_reg_write(TDA_PCR, TDA_PCR_START|volt); // /Reset,3V,Start ++ udelay(2000); ++ tda8007_reg_write(TDA_PCR, TDA_PCR_RSTIN|TDA_PCR_START|volt); // Set Reset High ++ i=0; ++ while( 1 )// !serstat() ++ { ++ if( ((msr[i]=tda8007_reg_read(TDA_MSR)) & TDA_MSR_FE) == 0 ) ++ { ++ hsr[i]=tda8007_reg_read(TDA_HSR); ++ usr[i]=tda8007_reg_read(TDA_USR); ++ csr[i]=tda8007_reg_read(TDA_CSR); ++ urr[i]=tda8007_reg_read(TDA_URR); ++ i++; ++ } ++ if( i == 1 ) ++ { ++ /* Reset SS */ ++ tda8007_reg_write(TDA_UCR1, ++ tda8007_reg_read(TDA_UCR1) & ~TDA_UCR_SS); ++ /* Set Autoconv high */ ++ tda8007_reg_write(TDA_UCR2, ++ tda8007_reg_read(TDA_UCR2) | TDA_UCR_nAUTOCONV); ++ } ++ ++ if( i >= BUFFSIZE ) ++ { ++ printk("Buffer Overflow"); ++ break; ++ } ++ // tda8007_reg_write(TDA_FCR, TDA_FCR_PEC0|TDA_FCR_FL0); ++ } ++ hsr[i]=tda8007_reg_read(TDA_HSR); ++ msr[i]=tda8007_reg_read(TDA_MSR); ++ csr[i]=tda8007_reg_read(TDA_CSR); ++ urr[i]=tda8007_reg_read(TDA_URR); ++ i++; ++ //serin(); ++ if( i==1 ) ++ printk("No Characters received\n"); ++ else ++ for(j=0;j<i-1; j++) ++ printk("Buffer[%3d]=USR(0x%02x) HSR(0x%02x) MSR(0x%02x) CSR(0x%02x) URR(0x%02x=%c)\n", ++ j,usr[j],hsr[j],msr[j],csr[j],urr[j],pascii(urr[j])); ++ ++ printk("Now USR(0x%02x) HSR(0x%02x) MSR(0x%02x) CSR(0x%02x) URR(0x%02x=%c)\n", ++ usr[j],hsr[j],msr[j],csr[j],urr[j],pascii(urr[j])); ++ ++ tda8007_reg_write(TDA_PCR, TDA_PCR_RSTIN|volt); // remove start ++ udelay(2000); ++ tda8007_reg_write(TDA_PCR, 0x00|volt); // remove Reset ++ ++ } ++ else ++ { ++ tda8007_reg_write(TDA_PCR, TDA_PCR_3V_5V); ++ } ++ ++} ++/* -------------------------------------------------------------------------*/ ++int test_tda8007(void) ++{ ++ int c, i,j, reg,end=0; ++ ++ printk("\nTDA8007 TEST:"); ++ ++ for( i=0; i < 0x10; i++ ) ++ printk("\nTDA8007 Reg %2d = 0x%02x ", i, tda8007_reg_read(i)&0xff); ++ ++ for( i=0 ;i < 0x10; i++ ) ++ { ++ tdaregs[i]=tda8007_reg_read(i) & 0xff; ++ } ++ do ++ { ++ printk("\nTDA8007 IRQ=%s Command:", ++ (GPLR&(1<<10) ? "HIGH":"LOW")); ++ ++ //c=serin(); ++ //serout(c); ++ printk("\n"); ++ ++ switch (c ) ++ { ++ ++ case 'c': ++ printk("\nReg?:"); ++ //reg=gethex(serin,serout); ++ printk("\nVal?:"); ++ //i=gethex(serin,serout); ++ tda8007_reg_write(reg,i); ++ j=tda8007_reg_read(reg); ++ printk("Reg 0x%02x (0x%02x) now 0x%02x\n", reg, i, j); ++ break; ++ ++ case 'i': ++ printk("\nInit\n"); ++ tda8007_init(); ++ ++ case 'p': ++ for( i=0; i < 0x10; i++ ) ++ printk("\nTDA8007 Reg %2d = 0x%02x ", i, ++ tda8007_reg_read(i)&0xff); ++ break; ++ case 'e': ++ end=1; ++ break; ++ ++ case 'r': ++ while( 1 ) // serstat() == 0 ++ { ++ for( i=0 ;i < 0x10; i++ ) ++ { ++ tdaregs[i]=tda8007_reg_read(i) & 0xff; ++ } ++ } ++ //serin(); ++ break; ++ ++ case 'S': ++ start_tda8007_sync(5); ++ break; ++ case 's': ++ start_tda8007_sync(3); ++ break; ++ case 'w': ++ while( 1 )//serstat() == 0 ++ { ++ for( i=0 ;i < 0x10; i++ ) ++ { ++ tda8007_reg_write(i,0x10-i); ++ } ++ } ++ //serin(); ++ break; ++ ++ default : ++ //serout(0x07); ++ break; ++ } ++ ++ }while( end == 0 ); ++ return(0); ++} ++/*-------------------------------------------------------------------------*/ ++static int tda8007_ioctl(struct inode *ino, struct file *filp, ++ uint cmd, ulong arg) ++{ ++ unsigned int val, gain; ++ int ret = 0; ++ ++ if (_IOC_TYPE(cmd) != 'M') ++ return -EINVAL; ++ ++ switch (_IOC_NR(cmd)) ++ { ++ case TDA_INFO: ++ break; ++ ++ case TDA_INIT: ++ break; ++ ++ case TDA_SET: ++ break; ++ ++ case TDA_CARD_PRESENT: ++ break; ++ ++ case TDA_CARD_VOLT: ++ break; ++ ++ default: ++ val = 0; ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++/* ------------------------------------------------------------------------- */ ++static ssize_t proc_tda8007_read( struct file *file, char *buf, size_t nbytes, ++ loff_t *ppos) ++{ ++ char outputbuf[80]; ++ int count = 0; ++ int i = 0; ++ int i_ino = (file->f_dentry->d_inode)->i_ino; ++ tda8007_reg_entry_t* current_reg = NULL; ++ ++ if ((*ppos) > 0) /* Assume reading completed in previous read*/ ++ return 0; ++ ++ for (i=0; i<NUM_OF_TDA8007_REG_ENTRY; i++) ++ { ++ if (tda8007_regs[i].low_ino==i_ino) ++ { ++ if( tda8007_regs[i].mode == 2 ) /* write only */ ++ { ++ printk("%s\n", tda8007_regs[i].description); ++ printk("Read operation is on this register not possible!\n"); ++ return -EINVAL; ++ } ++ current_reg = &tda8007_regs[i]; ++ ++ break; ++ } ++ } ++ ++ if (current_reg==NULL) ++ return -EINVAL; ++ ++ printk("%s\n", current_reg->description); ++ count += sprintf(outputbuf, "%s: 0x%x\n", current_reg->name, ++ tda8007_reg_read( current_reg->addr )); ++ /* count = sprintf(outputbuf, "value: 0x%x\n", ++ tda8007_reg_read( current_reg->addr ));*/ ++ ++ *ppos+=count; ++ ++ if (count>nbytes) /* Assume output can be read at one time */ ++ return -EINVAL; ++ ++ if (copy_to_user(buf, outputbuf, count)) ++ return -EFAULT; ++ ++ return count; ++} ++/* ------------------------------------------------------------------------- */ ++static ssize_t proc_tda8007_write(struct file * file, const char * buffer, ++ size_t count, loff_t *ppos) ++{ ++ int i; ++ unsigned long newRegValue; ++ char *endp; ++ int i_ino = (file->f_dentry->d_inode)->i_ino; ++ tda8007_reg_entry_t* current_reg=NULL; ++ ++ for (i=0; i<NUM_OF_TDA8007_REG_ENTRY; i++) ++ { ++ if (tda8007_regs[i].low_ino==i_ino) ++ { ++ if( tda8007_regs[i].mode == 1 ) /* read only */ ++ { ++ printk("%s\n", tda8007_regs[i].description); ++ printk("Write operation is on this register not possible!\n"); ++ return -EINVAL; ++ } ++ current_reg = &tda8007_regs[i]; ++ break; ++ } ++ } ++ if (current_reg==NULL) ++ return -EINVAL; ++ ++ newRegValue = simple_strtoul(buffer,&endp,0); ++ tda8007_reg_write( current_reg->addr, newRegValue); ++ return (count+endp-buffer); ++} ++/* ------------------------------------------------------------------------- */ ++static int __init tda8007_init() ++{ ++ int i, hsr_reg, res; ++ int ret = -ENODEV; ++ struct proc_dir_entry *entry; ++ int tda8007_major = 60; ++ ++ res = register_chrdev( tda8007_major, "tda8007", NULL ); ++ ++ if(res < 0){ ++ printk(KERN_WARNING "tda8007: can't get major%d\n", tda8007_major); ++ return res; ++ } ++ ++ if( tda8007_major == 0 ) ++ tda8007_major = res; ++ ++ set_GPIO_IRQ_edge(GPIO_SMART_CARD, GPIO_RISING_EDGE); ++ ++ ret = request_irq( IRQ_GPIO_SMART_CARD, tda8007_irq, ++ SA_INTERRUPT, "SMARTCARD_CD", NULL ); ++ if (ret) { ++ printk(KERN_ERR "tda8007: unable to grab irq%d: %d\n", ++ IRQ_GPIO_SMART_CARD, ret); ++ return ret; ++ } ++ ++ printk("\nInit TDA8007 IRQ=%s\n", ++ (GPLR&(1<<10) ? "HIGH":"LOW")); ++ ++// clear_cs3_bit(RESET_SIMCARD); ++ ++ ++#ifdef CONFIG_PROC_FS ++ /* Create two dir entries for the TDA8007 */ ++ tda8007dir = proc_mkdir("tda8007"/*TDA8007_DIRNAME*/, NULL); ++ if (tda8007dir == NULL) { ++ printk(KERN_ERR "tda80007: can't create /proc/" TDA8007_DIRNAME "\n"); ++ return(-ENOMEM); ++ } ++ ++ regdir = proc_mkdir(REG_DIRNAME, tda8007dir); ++ if (regdir == NULL) { ++ printk(KERN_ERR "tda8007: can't create /proc/" TDA8007_DIRNAME "/" REG_DIRNAME "\n"); ++ return(-ENOMEM); ++ } ++ ++ for(i=0;i<NUM_OF_TDA8007_REG_ENTRY;i++) { ++ entry = create_proc_entry(tda8007_regs[i].name, ++ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, ++ regdir); ++ if(entry) { ++ tda8007_regs[i].low_ino = entry->low_ino; ++ entry->proc_fops = &proc_reg_operations; ++ } ++ else { ++ printk( KERN_ERR ++ "tda8007: can't create /proc/" REG_DIRNAME ++ "/%s\n", tda8007_regs[i].name); ++ return(-ENOMEM); ++ } ++ } ++ ++#endif // CONFIG_PROC_FS ++ ++ ++ tda8007_reg_write(TDA_CSR, 0); ++ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU); ++ for( i=0; i < 16; i++ ) ++ tda8007_reg_write(i,0); ++ ++ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU|TDA_CSR_SC2); ++ tda8007_reg_write(TDA_PCR, 0); /* START=0 */ ++ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU|TDA_CSR_SC1); ++ tda8007_reg_write(TDA_PCR, 0); /* START=0 */ ++ tda8007_reg_write(TDA_TOC, 0); ++ tda8007_reg_write(TDA_FCR, TDA_FCR_FL2|TDA_FCR_FL1|TDA_FCR_FL0); ++ ++ tda8007_reg_write(TDA_UCR2, TDA_UCR_DISAUX|TDA_UCR2_DIV); // DIS_AUX DIS_CLK ++ tda8007_reg_write(TDA_UCR2, TDA_UCR_DISAUX|TDA_UCR2_DIV); // DIS_AUX CLK SYNC-MODE ++ hsr_reg = tda8007_reg_read(TDA_HSR); ++ ++ tda8007_reg_write(TDA_CCR, TDA_CCR_AC1|TDA_CCR_AC0); /* XTAL/8 */ ++ ++ return 0; ++} ++/* ------------------------------------------------------------------------- */ ++static void __exit tda8007_exit(void) ++{ ++ int i; ++ ++ free_irq(IRQ_GPIO_SMART_CARD, NULL); ++ /* kfree(my_ucb);*/ ++ ++ if (regdir) ++ { ++ for(i=0;i<NUM_OF_TDA8007_REG_ENTRY;i++) { ++ remove_proc_entry( tda8007_regs[i].name, regdir); ++ } ++ } ++} ++/* ------------------------------------------------------------------------- */ ++module_init(tda8007_init); ++module_exit(tda8007_exit); ++ ++MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>"); ++MODULE_DESCRIPTION("TDA8007 driver"); ++MODULE_LICENSE("GPL"); +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/char/tda8007b.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,312 @@ ++/* ++ * Double multiprotocol IC car interface (Philips SmartCard reader) ++ * ++ * linux/drivers/char/tda8007b.h ++ * ++ * Copyright (C) 2002 juergen.messerer@freesurf.ch, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License. ++ */ ++#ifndef TDA8007B_H ++#define TDA8007B_H ++ ++#define CS4BUSTYPE unsigned volatile long ++#define CS4_BASE 0xf2000000 ++ ++#define CARD_PORT1 1 ++#define CARD_PORT2 2 ++#define CARD_PORT3 3 ++ ++#define TDA_REG_READ(reg) *(CS4BUSTYPE *)(CS4_BASE+reg) ++#define TDA_REG_WRITE(reg,val) *(CS4BUSTYPE *)(CS4_BASE+reg)=val ++ ++#define TDA_MULTIPLEXED_MODE 0 ++ ++#define TDA_UCR2_DIV 0 ++#define TDA_PDR_VAL 12 ++ ++#define pascii(i) ((i>=' ' && i < 0x7f) ? (i):'.') ++ ++#define BUFFSIZE 128 ++ ++#define TDA_READ 1 ++#define TDA_WRITE 2 ++ ++#define TDA_INFO 1 ++#define TDA_INIT 2 ++#define TDA_SET 3 ++#define TDA_CARD_PRESENT 4 ++#define TDA_CARD_VOLT 5 ++ ++int hsr[BUFFSIZE]; ++int msr[BUFFSIZE]; ++int csr[BUFFSIZE]; ++int urr[BUFFSIZE]; ++int usr[BUFFSIZE]; ++ ++/*************************** Control Register ********************************/ ++ ++/* ++ * Card select register (read/write) ++ * all significant bits are cleared execept SC1 which is set (xxxx'0001) ++ */ ++#define TDA_CSR 0x00 ++#define TDA_CSR_SC1 (1 << 0) ++#define TDA_CSR_SC2 (1 << 1) ++#define TDA_CSR_SC3 (1 << 2) ++#define TDA_CSR_nRIU (1 << 3) ++ ++/* ++ * Clock configuration register (read/write) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_CCR 0x01 ++#define TDA_CCR_AC0 (1 << 0) ++#define TDA_CCR_AC1 (1 << 1) ++#define TDA_CCR_AC2 (1 << 2) ++#define TDA_CCR_SC (1 << 3) ++#define TDA_CCR_CST (1 << 4) ++#define TDA_CCR_SHL (1 << 5) ++ ++/* ++ * Programmable divider register (read/write) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_PDR 0x02 ++#define TDA_PDR_PD0 (1 << 0) ++#define TDA_PDR_PD1 (1 << 1) ++#define TDA_PDR_PD2 (1 << 2) ++#define TDA_PDR_PD3 (1 << 3) ++#define TDA_PDR_PD4 (1 << 4) ++#define TDA_PDR_PD5 (1 << 5) ++#define TDA_PDR_PD6 (1 << 6) ++#define TDA_PDR_PD7 (1 << 7) ++ ++/* ++ * UART configuration register 2(read/write) ++ * all relevant bits are cleared after reset (x000'0000) ++ */ ++#define TDA_UCR2 0x03 ++#define TDA_UCR_PSC (1 << 0) ++#define TDA_UCR_CKU (1 << 1) ++#define TDA_UCR_nAUTOCONV (1 << 2) ++#define TDA_UCR_SAN (1 << 3) ++#define TDA_UCR_PDWN (1 << 4) ++#define TDA_UCR_DISAUX (1 << 5) ++#define TDA_UCR_DISTBE_RBF (1 << 6) ++ ++/* ++ * Guard time register (read/write) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_GTR 0x05 ++#define TDA_GTR_GT0 (1 << 0) ++#define TDA_GTR_GT1 (1 << 1) ++#define TDA_GTR_GT2 (1 << 2) ++#define TDA_GTR_GT3 (1 << 3) ++#define TDA_GTR_GT4 (1 << 4) ++#define TDA_GTR_GT5 (1 << 5) ++#define TDA_GTR_GT6 (1 << 6) ++#define TDA_GTR_GT7 (1 << 7) ++ ++/* ++ * UART configuration register 1(read/write) ++ * all relevant bits are cleared after reset (x000'0000) ++ */ ++#define TDA_UCR1 0x06 ++#define TDA_UCR_CONV (1 << 0) ++#define TDA_UCR_SS (1 << 1) ++#define TDA_UCR_LCT (1 << 2) ++#define TDA_UCR_T_R (1 << 3) ++#define TDA_UCR_PROT (1 << 4) ++#define TDA_UCR_FC (1 << 5) ++#define TDA_UCR_FIP (1 << 6) ++ ++/* ++ * Power control register (read/write) ++ * all relevant bits are cleared after reset (xx11'0000) ++ */ ++#define TDA_PCR 0x07 ++#define TDA_PCR_START (1 << 0) ++#define TDA_PCR_3V_5V (1 << 1) ++#define TDA_PCR_RSTIN (1 << 2) ++#define TDA_PCR_1V8 (1 << 3) ++#define TDA_PCR_C4 (1 << 4) ++#define TDA_PCR_C8 (1 << 5) ++ ++/* ++ * Time-out configuration register (read/write) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_TOC 0x08 ++#define TDA_TOC_STOP_ALL 0x00 ++#define TDA_TOC_MODE1 0x61 ++#define TDA_TOC_MODE2 0x65 ++#define TDA_TOC_MODE3 0x68 ++#define TDA_TOC_MODE4 0x7c ++#define TDA_TOC_MODE5 0xe5 ++ ++/* ++ * Time-out register 1(write only) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_TOR1 0x09 ++#define TDA_TOR1_TOL0 (1 << 0) ++#define TDA_TOR1_TOL1 (1 << 1) ++#define TDA_TOR1_TOL2 (1 << 2) ++#define TDA_TOR1_TOL3 (1 << 3) ++#define TDA_TOR1_TOL4 (1 << 4) ++#define TDA_TOR1_TOL5 (1 << 5) ++#define TDA_TOR1_TOL6 (1 << 6) ++#define TDA_TOR1_TOL7 (1 << 7) ++ ++/* ++ * Time-out register 2(write only) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_TOR2 0x0a ++#define TDA_TOR2_TOL10 (1 << 0) ++#define TDA_TOR2_TOL11 (1 << 1) ++#define TDA_TOR2_TOL12 (1 << 2) ++#define TDA_TOR2_TOL13 (1 << 3) ++#define TDA_TOR2_TOL14 (1 << 4) ++#define TDA_TOR2_TOL15 (1 << 5) ++#define TDA_TOR2_TOL16 (1 << 6) ++#define TDA_TOR2_TOL17 (1 << 7) ++ ++/* ++ * Time-out register 3(write only) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_TOR3 0x0b ++#define TDA_TOR3_TOL16 (1 << 0) ++#define TDA_TOR3_TOL17 (1 << 1) ++#define TDA_TOR3_TOL18 (1 << 2) ++#define TDA_TOR3_TOL19 (1 << 3) ++#define TDA_TOR3_TOL20 (1 << 4) ++#define TDA_TOR3_TOL21 (1 << 5) ++#define TDA_TOR3_TOL22 (1 << 6) ++#define TDA_TOR3_TOL23 (1 << 7) ++ ++/* ++ * Mixed status register (read only) ++ * bits TBE, RBF and BGT are cleared, bit FE is set after reset (x10x'xxx0) ++ */ ++#define TDA_MSR 0x0c ++#define TDA_MSR_TBE_RBF (1 << 0) ++#define TDA_MSR_INTAUX (1 << 1) ++#define TDA_MSR_PR1 (1 << 2) ++#define TDA_MSR_PR2 (1 << 3) ++#define TDA_MSR_BGT (1 << 5) ++#define TDA_MSR_FE (1 << 6) ++ ++/* ++ * FIFO control register (write only) ++ * all relevant bits are cleared after reset (x000'x000) ++ */ ++#define TDA_FCR 0x0c ++#define TDA_FCR_FL0 (1 << 0) ++#define TDA_FCR_FL1 (1 << 1) ++#define TDA_FCR_FL2 (1 << 2) ++#define TDA_FCR_PEC0 (1 << 4) ++#define TDA_FCR_PEC1 (1 << 5) ++#define TDA_FCR_PEC2 (1 << 6) ++ ++/* ++ * UART transmit register (write only) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_UTR 0x0d ++#define TDA_UTR_UT0 (1 << 0) ++#define TDA_UTR_UT1 (1 << 1) ++#define TDA_UTR_UT2 (1 << 2) ++#define TDA_UTR_UT3 (1 << 3) ++#define TDA_UTR_UT4 (1 << 4) ++#define TDA_UTR_UT5 (1 << 5) ++#define TDA_UTR_UT6 (1 << 6) ++#define TDA_UTR_UT7 (1 << 7) ++ ++/* ++ * UART receive register (read only) ++ * all bits are cleared (0000'0000) ++ */ ++#define TDA_URR 0x0d ++#define TDA_URR_UR0 (1 << 0) ++#define TDA_URR_UR1 (1 << 1) ++#define TDA_URR_UR2 (1 << 2) ++#define TDA_URR_UR3 (1 << 3) ++#define TDA_URR_UR4 (1 << 4) ++#define TDA_URR_UR5 (1 << 5) ++#define TDA_URR_UR6 (1 << 6) ++#define TDA_URR_UR7 (1 << 7) ++ ++/* ++ * UART status register (read only) ++ * all bits are cleared (0x00'0000) ++ */ ++#define TDA_USR 0x0e ++#define TDA_USR_TBE_RBF (1 << 0) ++#define TDA_USR_FER (1 << 1) ++#define TDA_USR_OVR (1 << 2) ++#define TDA_USR_PE (1 << 3) ++#define TDA_USR_EA (1 << 4) ++#define TDA_USR_TO1 (1 << 5) ++#define TDA_USR_TO3 (1 << 7) ++ ++/* ++ * Hardware status register (read only) ++ * all significant bits are cleared, except SUPL (x001'0000) ++ */ ++#define TDA_HSR 0x0f ++#define TDA_HSR_PTL (1 << 0) ++#define TDA_HSR_INTAUXL (1 << 1) ++#define TDA_HSR_PRL1 (1 << 2) ++#define TDA_HSR_PRL2 (1 << 3) ++#define TDA_HSR_SUPL (1 << 4) ++#define TDA_HSR_PRTL1 (1 << 5) ++#define TDA_HSR_PRTL2 (1 << 6) ++ ++typedef struct tda8007_reg_entry { ++ u32 addr; ++ char* name; ++ char* description; ++ u8 mode; ++ unsigned short low_ino; ++} tda8007_reg_entry_t; ++ ++ ++/* ++ * Read : 1 ++ * Write : 2 ++ * Read/Write : 3 ++ */ ++ ++static tda8007_reg_entry_t tda8007_regs[] = ++{ ++ {TDA_CSR, "TDA_CSR", "Card select register (read/write)", 3}, ++ {TDA_CCR, "TDA_CCR", "Clock configuration register (read/write)", 3}, ++ {TDA_PDR, "TDA_PDR", "Programmable divider register (read/write)", 3}, ++ {TDA_UCR2, "TDA_UCR2", "UART configuration register 2(read/write)", 3}, ++ {TDA_GTR, "TDA_GTR", "Guard time register (read/write)", 3}, ++ {TDA_UCR1, "TDA_UCR1", "UART configuration register 1(read/write)", 3}, ++ {TDA_PCR, "TDA_PCR", "Power control register (read/write)", 3}, ++ {TDA_TOC, "TDA_TOC", "Time-out configuration register (read/write)", 3}, ++ {TDA_MSR, "TDA_MSR", "Mixed status register (read only)", 1}, ++ {TDA_URR, "TDA_URR", "UART receive register (read only)", 1}, ++ {TDA_USR, "TDA_USR", "UART status register (read only)", 1}, ++ {TDA_HSR, "TDA_HSR", "Hardware status register (read only)", 1}, ++ {TDA_TOR1, "TDA_TOR1", "Time-out register 1(write only)", 2}, ++ {TDA_TOR2, "TDA_TOR2", "Time-out register 2(write only)", 2}, ++ {TDA_TOR3, "TDA_TOR3", "Time-out register 3(write only)", 2}, ++ {TDA_FCR, "TDA_FCR", "FIFO control register (write only)", 2}, ++ {TDA_UTR, "TDA_UTR", "UART transmit register (write only)", 2} ++}; ++#define NUM_OF_TDA8007_REG_ENTRY (sizeof(tda8007_regs)/sizeof(tda8007_reg_entry_t)) ++/* ++struct tda8007 { ++ ++}; ++*/ ++#endif /* TDA8007B_H */ +--- linux-2.4.25/drivers/misc/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/misc/Config.in 2004-05-02 22:45:42.000000000 +0200 +@@ -16,3 +16,15 @@ + dep_tristate ' UCB1400 Touchscreen support' CONFIG_MCP_UCB1400_TS $CONFIG_ARCH_PXA $CONFIG_SOUND + + endmenu ++mainmenu_option next_comment ++comment 'Console Switches' ++ ++tristate 'Console Switch Support' CONFIG_SWITCHES ++if [ "$CONFIG_SWITCHES" != "n" ]; then ++ dep_bool ' SA-1100 switches' CONFIG_SWITCHES_SA1100 $CONFIG_ARCH_SA1100 ++ if [ "$CONFIG_MCP_UCB1200" != "n" ]; then ++ bool ' UCB1x00 switches' CONFIG_SWITCHES_UCB1X00 ++ fi ++fi ++ ++endmenu +--- linux-2.4.25/drivers/misc/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/misc/Makefile 2004-05-02 22:45:42.000000000 +0200 +@@ -21,6 +21,24 @@ + obj-$(CONFIG_MCP_UCB1400_TS) += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o + obj-$(CONFIG_PXA_CERF_PDA) += cerf_ucb1400gpio.o + ++ifeq ($(CONFIG_SA1100_ASSABET),y) ++obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o ++endif ++ ++ifeq ($(CONFIG_SA1100_SIMPAD),y) ++export-objs += ucb1x00-simpad.o ++obj-$(CONFIG_MCP_UCB1200) += ucb1x00-simpad.o ++endif ++ ++obj-$(CONFIG_SWITCHES) += switches.o ++ ++switches-objs-y += switches-core.o ++switches-objs-$(CONFIG_SWITCHES_SA1100) += switches-sa1100.o ++switches-objs-$(CONFIG_SWITCHES_UCB1X00) += switches-ucb1x00.o ++ + include $(TOPDIR)/Rules.make + ++switches.o: $(switches-objs-y) ++ $(LD) $(LD_RFLAG) -r -o $@ $(switches-objs-y) ++ + fastdep: +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/misc/switches-core.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,226 @@ ++/* ++ * linux/drivers/misc/switches-core.c ++ * ++ * Copyright (C) 2000-2001 John Dorsey ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 5 October 2000 - created. ++ * ++ * 25 October 2000 - userland file interface added. ++ * ++ * 13 January 2001 - added support for Spot. ++ * ++ * 11 September 2001 - UCB1200 driver framework support added. ++ * ++ * 19 December 2001 - separated out SA-1100 and UCB1x00 code. ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/kernel.h> ++#include <linux/miscdevice.h> ++#include <linux/module.h> ++#include <linux/mm.h> ++#include <linux/poll.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/wait.h> ++ ++#include <asm/uaccess.h> ++ ++#include "switches.h" ++ ++ ++MODULE_AUTHOR("John Dorsey"); ++MODULE_DESCRIPTION("Console switch support"); ++MODULE_LICENSE("GPL"); ++ ++ ++struct switches_action { ++ struct list_head list; ++ switches_mask_t mask; ++}; ++ ++ ++static int switches_users = 0; ++ ++static spinlock_t switches_lock = SPIN_LOCK_UNLOCKED; ++ ++DECLARE_WAIT_QUEUE_HEAD(switches_wait); ++LIST_HEAD(switches_event_queue); ++ ++ ++static ssize_t switches_read(struct file *file, char *buffer, ++ size_t count, loff_t *pos) ++{ ++ unsigned long flags; ++ struct list_head *event; ++ struct switches_action *action; ++ ++ if (count < sizeof(struct switches_mask_t)) ++ return -EINVAL; ++ ++ while (list_empty(&switches_event_queue)) { ++ ++ if (file->f_flags & O_NDELAY) ++ return -EAGAIN; ++ ++ interruptible_sleep_on(&switches_wait); ++ ++ if (signal_pending(current)) ++ return -ERESTARTSYS; ++ ++ } ++ ++ if (verify_area(VERIFY_WRITE, buffer, sizeof(struct switches_mask_t))) ++ return -EFAULT; ++ ++ spin_lock_irqsave(&switches_lock, flags); ++ ++ event = switches_event_queue.next; ++ action = list_entry(event, struct switches_action, list); ++ copy_to_user(buffer, &(action->mask), sizeof(struct switches_mask_t)); ++ list_del(event); ++ kfree(action); ++ ++ spin_unlock_irqrestore(&switches_lock, flags); ++ ++ return sizeof(struct switches_mask_t); ++ ++} ++ ++static ssize_t switches_write(struct file *file, const char *buffer, ++ size_t count, loff_t *ppos) ++{ ++ return -EINVAL; ++} ++ ++static unsigned int switches_poll(struct file *file, poll_table *wait) ++{ ++ ++ poll_wait(file, &switches_wait, wait); ++ ++ if (!list_empty(&switches_event_queue)) ++ return POLLIN | POLLRDNORM; ++ ++ return 0; ++ ++} ++ ++static int switches_open(struct inode *inode, struct file *file) ++{ ++ ++ if (switches_users > 0) ++ return -EBUSY; ++ ++ MOD_INC_USE_COUNT; ++ ++switches_users; ++ return 0; ++ ++} ++ ++static int switches_release(struct inode *inode, struct file *file) ++{ ++ ++ --switches_users; ++ MOD_DEC_USE_COUNT; ++ return 0; ++ ++} ++ ++static struct file_operations switches_ops = { ++ read: switches_read, ++ write: switches_write, ++ poll: switches_poll, ++ open: switches_open, ++ release: switches_release ++}; ++ ++static struct miscdevice switches_misc = { ++ MISC_DYNAMIC_MINOR, SWITCHES_NAME, &switches_ops ++}; ++ ++int switches_event(switches_mask_t *mask) ++{ ++ struct switches_action *action; ++ ++ if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) { ++ ++ if ((action = (struct switches_action *) ++ kmalloc(sizeof(struct switches_action), ++ GFP_ATOMIC)) == NULL) { ++ printk(KERN_ERR "%s: unable to allocate action " ++ "descriptor\n", SWITCHES_NAME); ++ return -1; ++ } ++ ++ action->mask = *mask; ++ ++ spin_lock(&switches_lock); ++ list_add_tail(&action->list, &switches_event_queue); ++ spin_unlock(&switches_lock); ++ ++ wake_up_interruptible(&switches_wait); ++ ++ } ++ ++ return 0; ++ ++} ++ ++static int __init switches_init(void) ++{ ++ ++#ifdef CONFIG_SWITCHES_SA1100 ++ if (switches_sa1100_init() < 0) { ++ printk(KERN_ERR "%s: unable to initialize SA-1100 switches\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++#endif ++ ++#ifdef CONFIG_SWITCHES_UCB1X00 ++ if (switches_ucb1x00_init() < 0) { ++ printk(KERN_ERR "%s: unable to initialize UCB1x00 switches\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++#endif ++ ++ if (misc_register(&switches_misc) < 0) { ++ printk(KERN_ERR "%s: unable to register misc device\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++ ++ printk("Console switches initialized\n"); ++ ++ return 0; ++ ++} ++ ++static void __exit switches_exit(void) ++{ ++ ++#ifdef CONFIG_SWITCHES_SA1100 ++ switches_sa1100_exit(); ++#endif ++ ++#ifdef CONFIG_SWITCHES_UCB1X00 ++ switches_ucb1x00_exit(); ++#endif ++ ++ if (misc_deregister(&switches_misc) < 0) ++ printk(KERN_ERR "%s: unable to deregister misc device\n", ++ SWITCHES_NAME); ++ ++} ++ ++module_init(switches_init); ++module_exit(switches_exit); ++ ++EXPORT_NO_SYMBOLS; +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/misc/switches-sa1100.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,311 @@ ++/* ++ * linux/drivers/misc/switches-sa1100.c ++ * ++ * Copyright (C) 2001 John Dorsey ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 19 December 2001 - created from sa1100_switches.c. ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/sched.h> ++ ++#include <asm/hardware.h> ++#include <asm/irq.h> ++ ++#ifdef CONFIG_SA1100_ASSABET ++#include <asm/arch/assabet.h> ++#endif ++ ++#ifdef CONFIG_SA1100_SIMPAD ++#include <asm/arch/simpad.h> ++#endif ++ ++#include "switches.h" ++ ++ ++static void switches_sa1100_handler(int irq, void *dev_id, ++ struct pt_regs *regs); ++ ++ ++#ifdef CONFIG_SA1100_ASSABET ++ ++/* Assabet ++ * ^^^^^^^ ++ * We have two general-purpose switches, S1 and S2, available via GPIO ++ * on Assabet. This code sets bits in the range [1, 2] in the mask that ++ * we return to userland. ++ */ ++ ++static int assabet_switches_sa1100_init(void) ++{ ++ ++ if (machine_has_neponset()) ++ NCR_0 |= NCR_GP01_OFF; ++ ++ set_irq_type(IRQ_GPIO0, IRQT_BOTHEDGE); ++ set_irq_type(IRQ_GPIO1, IRQT_BOTHEDGE); ++ ++ if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT, ++ SWITCHES_NAME, NULL) < 0) { ++ printk(KERN_ERR "%s: unable to register IRQ for GPIO 0\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++ ++ if (request_irq(IRQ_GPIO1, switches_sa1100_handler, SA_INTERRUPT, ++ SWITCHES_NAME, NULL) < 0) { ++ printk(KERN_ERR "%s: unable to register IRQ for GPIO 1\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++ ++ return 0; ++ ++} ++ ++static void assabet_switches_sa1100_shutdown(void) ++{ ++ ++ free_irq(IRQ_GPIO1, NULL); ++ free_irq(IRQ_GPIO0, NULL); ++ ++} ++ ++static void assabet_switches_sa1100_handler(int irq, switches_mask_t *mask) ++{ ++ unsigned int s, last, this; ++ static unsigned int states = 0; ++ ++ switch (irq) { ++ ++ case IRQ_GPIO0: s = 0; break; ++ ++ case IRQ_GPIO1: s = 1; break; ++ ++ default: return; ++ ++ } ++ ++ last = ((states & (1 << s)) != 0); ++ this = ((GPLR & GPIO_GPIO(s)) != 0); ++ ++ if (last == this) /* debounce */ ++ return; ++ ++ SWITCHES_SET(mask, s + 1, this); ++ ++ states = this ? (states | (1 << s)) : (states & ~(1 << s)); ++ ++} ++#endif /* CONFIG_SA1100_ASSABET */ ++ ++ ++#ifdef CONFIG_SA1100_SPOT ++ ++/* Spot ++ * ^^^^ ++ * Spot (R2, R3) has a single general-purpose switch (S1), which is ++ * also the power-on switch. We set bit [1] in the mask we return to ++ * userland. ++ */ ++ ++static int spot_switches_sa1100_init(void) ++{ ++ ++ set_GPIO_IRQ_edge(GPIO_SW1, GPIO_BOTH_EDGES); ++ ++ if (request_irq(IRQ_GPIO_SW1, switches_sa1100_handler, SA_INTERRUPT, ++ SWITCHES_NAME, NULL) < 0) { ++ printk(KERN_ERR "%s: unable to register IRQ for SW1\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++ ++ return 0; ++ ++} ++ ++static void spot_switches_sa1100_shutdown(void) ++{ ++ ++ free_irq(IRQ_GPIO_SW1, NULL); ++ ++} ++ ++static void spot_switches_sa1100_handler(int irq, switches_mask_t *mask) ++{ ++ unsigned int s, last, this; ++ static unsigned int states = 0; ++ ++ switch (irq) { ++ ++ case IRQ_GPIO_SW1: s = 0; break; ++ ++ default: return; ++ ++ } ++ ++ last = ((states & (1 << s)) != 0); ++ this = ((GPLR & GPIO_GPIO(s)) != 0); ++ ++ if (last == this) /* debounce */ ++ return; ++ ++ SWITCHES_SET(mask, s + 1, this); ++ ++ states = this ? (states | (1 << s)) : (states & ~(1 << s)); ++ ++} ++#endif /* CONFIG_SA1100_SPOT */ ++ ++#ifdef CONFIG_SA1100_SIMPAD ++ ++/* SIMpad ++ * ^^^^ ++ * SIMpad has a single general-purpose switch (S0), which is ++ * also the power-on switch. We set bit [1] in the mask we return to ++ * userland. ++ */ ++ ++static int simpad_switches_sa1100_init(void) ++{ ++ ++ set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_BOTH_EDGES); ++ ++ if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT, ++ SWITCHES_NAME, NULL) < 0) { ++ printk(KERN_ERR "%s: unable to register IRQ for SW0\n", ++ SWITCHES_NAME); ++ return -EIO; ++ } ++ ++ return 0; ++ ++} ++ ++static void simpad_switches_sa1100_shutdown(void) ++{ ++ ++ free_irq(IRQ_GPIO0, NULL); ++ ++} ++ ++static void simpad_switches_sa1100_handler(int irq, switches_mask_t *mask) ++{ ++ unsigned int s, last, this; ++ static unsigned int states = 0; ++ ++ switch (irq) { ++ ++ case IRQ_GPIO0: s = 0; break; ++ ++ default: return; ++ ++ } ++ ++ last = ((states & (1 << s)) != 0); ++ this = ((GPLR & GPIO_GPIO(s)) != 0); ++ ++ if (last == this) /* debounce */ ++ return; ++ ++ SWITCHES_SET(mask, s + 1, this); ++ ++ states = this ? (states | (1 << s)) : (states & ~(1 << s)); ++ ++} ++#endif /* CONFIG_SA1100_SIMPAD */ ++ ++ ++ ++/* switches_sa1100_handler() ++ * ^^^^^^^^^^^^^^^^^^^^^^^^^ ++ * This routine is a generalized handler for SA-1100 switches ++ * which manages action descriptors and calls a board-specific ++ * service routine. This routine is appropriate for GPIO switches ++ * or other primary interrupt sources, and can be registered as a ++ * first-class IRQ handler using request_irq(). ++ */ ++static void switches_sa1100_handler(int irq, void *dev_id, ++ struct pt_regs *regs) ++{ ++ switches_mask_t mask; ++ ++ SWITCHES_ZERO(&mask); ++ ++ /* Porting note: call a board-specific switch interrupt handler ++ * here. The handler can assume that sufficient storage for ++ * `mask' has been allocated, and that the corresponding ++ * switches_mask_t structure has been zeroed. ++ */ ++ ++ if (machine_is_assabet()) { ++#ifdef CONFIG_SA1100_ASSABET ++ assabet_switches_sa1100_handler(irq, &mask); ++#endif ++ } else if (machine_is_spot()) { ++#ifdef CONFIG_SA1100_SPOT ++ spot_switches_sa1100_handler(irq, &mask); ++#endif ++ } else if (machine_is_simpad()) { ++#ifdef CONFIG_SA1100_SIMPAD ++ simpad_switches_sa1100_handler(irq, &mask); ++#endif ++ } ++ ++ switches_event(&mask); ++ ++} ++ ++int __init switches_sa1100_init(void) ++{ ++ ++ /* Porting note: call a board-specific init routine here. */ ++ ++ if (machine_is_assabet()) { ++#ifdef CONFIG_SA1100_ASSABET ++ if (assabet_switches_sa1100_init() < 0) ++ return -EIO; ++#endif ++ } else if (machine_is_spot()) { ++#ifdef CONFIG_SA1100_SPOT ++ if (spot_switches_sa1100_init() < 0) ++ return -EIO; ++#endif ++ } else if (machine_is_simpad()) { ++#ifdef CONFIG_SA1100_SIMPAD ++ if (simpad_switches_sa1100_init() < 0) ++ return -EIO; ++#endif ++ } ++ ++ return 0; ++ ++} ++ ++void __exit switches_sa1100_exit(void) ++{ ++ ++ /* Porting note: call a board-specific shutdown routine here. */ ++ ++ if (machine_is_assabet()) { ++#ifdef CONFIG_SA1100_ASSABET ++ assabet_switches_sa1100_shutdown(); ++#endif ++ } else if (machine_is_spot()) { ++#ifdef CONFIG_SA1100_SPOT ++ spot_switches_sa1100_shutdown(); ++#endif ++ } else if (machine_is_simpad()) { ++#ifdef CONFIG_SA1100_SIMPAD ++ simpad_switches_sa1100_shutdown(); ++#endif ++ } ++ ++} +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/misc/switches-ucb1x00.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,331 @@ ++/* ++ * linux/drivers/misc/switches-ucb1x00.c ++ * ++ * Copyright (C) 2001 John Dorsey ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 19 December 2001 - created from sa1100_switches.c. ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/sched.h> ++ ++#include <asm/dma.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++ ++#ifdef CONFIG_SA1100_ASSABET ++#include <asm/arch/assabet.h> ++#endif ++ ++#ifdef CONFIG_SA1100_SIMPAD ++#include <asm/arch/simpad.h> ++#endif ++ ++#include "switches.h" ++#include "ucb1x00.h" ++ ++ ++static struct ucb1x00 *ucb1x00; ++ ++static void switches_ucb1x00_handler(int irq, void *devid); ++ ++ ++#ifdef CONFIG_SA1100_ASSABET ++ ++/* Assabet ++ * ^^^^^^^ ++ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8. ++ * This code sets bits in the range [3, 8] in the mask that we ++ * return to userland. Note that we transpose signals SW7 and SW8; ++ * see assabet_switches_ucb1x00_handler(). ++ */ ++ ++static int assabet_switches_ucb1x00_init(void) ++{ ++ int i; ++ ++ /* Note that ucb1x00_init() must complete before this point: */ ++ ++ if ((ucb1x00 = ucb1x00_get()) == NULL) { ++ printk(KERN_ERR "%s: UCB1300 driver not ready; switches " ++ "3 -- 8 will not be available\n", ++ SWITCHES_NAME); ++ return 0; ++ } ++ ++ ucb1x00_enable(ucb1x00); ++ ++ ucb1x00_io_set_dir(ucb1x00, ++ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 | ++ UCB_IO_3 | UCB_IO_4 | UCB_IO_5, 0); ++ ++ for (i = 0; i < 6; ++i) { ++ ++ ucb1x00_enable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING); ++ ++ if (ucb1x00_hook_irq(ucb1x00, i, ++ switches_ucb1x00_handler, NULL) < 0) { ++ printk(KERN_ERR "%s: unable to hook IRQ for " ++ "UCB1300 IO_%d\n", SWITCHES_NAME, i); ++ return -EBUSY; ++ } ++ ++ } ++ ++ return 0; ++ ++} ++ ++static void assabet_switches_ucb1x00_shutdown(void) ++{ ++ int i; ++ ++ for (i = 5; i >= 0; --i) { ++ ++ ucb1x00_disable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING); ++ ++ /* Only error conditions are ENOENT and EINVAL; silently ++ * ignore: ++ */ ++ ucb1x00_free_irq(ucb1x00, i, NULL); ++ ++ } ++ ++} ++ ++static void assabet_switches_ucb1x00_handler(int irq, switches_mask_t *mask) ++{ ++ unsigned int last, this; ++ static unsigned int states = 0; ++ ++ last = ((states & (1 << irq)) != 0); ++ this = ((ucb1x00_io_read(ucb1x00) & (1 << irq)) != 0); ++ ++ if (last == this) /* debounce */ ++ return; ++ ++ /* Intel StrongARM SA-1110 Development Board ++ * Schematics Figure 5, Sheet 5 of 12 ++ * ++ * See switches S8 and S7. Notice their ++ * relationship to signals SW7 and SW8. Hmmm. ++ */ ++ ++ switch (irq) { ++ ++ case 4: ++ ++ SWITCHES_SET(mask, 8, this); ++ break; ++ ++ case 5: ++ ++ SWITCHES_SET(mask, 7, this); ++ break; ++ ++ default: ++ ++ SWITCHES_SET(mask, irq + 3, this); ++ ++ } ++ ++ states = this ? (states | (1 << irq)) : (states & ~(1 << irq)); ++ ++} ++#endif /* CONFIG_SA1100_ASSABET */ ++ ++#ifdef CONFIG_SA1100_SIMPAD ++ ++/* SIMpad ++ * ^^^^^^ ++ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8. ++ * This code sets bits in the range [3, 8] in the mask that we ++ * return to userland. ++ */ ++ ++static int simpad_switches_ucb1x00_init(void) ++{ ++ int i; ++ ++ /* Note that ucb1x00_init() must complete before this point: */ ++ ++ if ((ucb1x00 = ucb1x00_get()) == NULL) { ++ printk(KERN_ERR "%s: UCB1300 driver not ready; switches " ++ "3 -- 8 will not be available\n", ++ SWITCHES_NAME); ++ return 0; ++ } ++ ++ ucb1x00_enable(ucb1x00); ++ ++ ucb1x00_io_set_dir(ucb1x00, ++ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 | ++ UCB_IO_3 | UCB_IO_4 | UCB_IO_5, ++ UCB_IO_8 | UCB_IO_9); ++ ++ ucb1x00_disable(ucb1x00); ++ ++ for (i = 0; i < 6; ++i) { ++ ++ if (ucb1x00_hook_irq(ucb1x00, i, ++ switches_ucb1x00_handler, NULL) < 0) { ++ printk(KERN_ERR "%s: unable to hook IRQ for " ++ "UCB1300 IO_%d\n", SWITCHES_NAME, i); ++ return -EBUSY; ++ } ++ ++ ucb1x00_enable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING); ++ } ++ ++ return 0; ++ ++} ++ ++int simpad_switches_ucb1x00_reinit(void) ++{ ++ int i; ++ ucb1x00_enable(ucb1x00); ++ ++ ucb1x00_io_set_dir(ucb1x00, ++ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 | ++ UCB_IO_3 | UCB_IO_4 | UCB_IO_5, ++ UCB_IO_8 | UCB_IO_9); ++ ++ ucb1x00_disable(ucb1x00); ++ ++ for (i = 0; i < 6; ++i) ++ ucb1x00_enable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING); ++ ++ return 0; ++} ++ ++static void simpad_switches_ucb1x00_shutdown(void) ++{ ++ int i; ++ ++ for (i = 5; i >= 0; --i) { ++ ++ ucb1x00_disable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING); ++ ++ /* Only error conditions are ENOENT and EINVAL; silently ++ * ignore: ++ */ ++ ucb1x00_free_irq(ucb1x00, i, NULL); ++ ++ } ++ ++} ++ ++static void simpad_switches_ucb1x00_handler(int irq, switches_mask_t *mask) ++{ ++ unsigned int last, this; ++ static unsigned int states = 0; ++ ++ last = ((states & (1 << irq)) != 0); ++ this = ((~ucb1x00_io_read(ucb1x00) & (1 << irq)) != 0); ++ ++ if (last == this) /* debounce */ ++ return; ++ ++ switch (irq) { ++ ++ case 4: ++ ++ ++ ++ case 5: ++ ++ ++ ++ default: ++ ++ SWITCHES_SET(mask, irq + 3, this); ++ ++ } ++ ++ states = this ? (states | (1 << irq)) : (states & ~(1 << irq)); ++ ++} ++#endif /* CONFIG_SA1100_SIMPAD */ ++ ++ ++/* switches_ucb1x00_handler() ++ * ^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ * This routine is a generalized handler for UCB1x00 GPIO switches ++ * which calls a board-specific service routine and passes an event ++ * mask to the core event handler. This routine is appropriate for ++ * systems which use the ucb1x00 framework, and can be registered ++ * using ucb1x00_hook_irq(). ++ */ ++static void switches_ucb1x00_handler(int irq, void *devid) ++{ ++ switches_mask_t mask; ++ ++ SWITCHES_ZERO(&mask); ++ ++ /* Porting note: call a board-specific UCB1x00 switch handler here. ++ * The handler can assume that sufficient storage for `mask' has ++ * been allocated, and that the corresponding switches_mask_t ++ * structure has been zeroed. ++ */ ++ ++ if (machine_is_assabet()) { ++#ifdef CONFIG_SA1100_ASSABET ++ assabet_switches_ucb1x00_handler(irq, &mask); ++#endif ++ } ++ if (machine_is_simpad()) { ++#ifdef CONFIG_SA1100_SIMPAD ++ simpad_switches_ucb1x00_handler(irq, &mask); ++#endif ++ } ++ ++ switches_event(&mask); ++ ++} ++ ++int __init switches_ucb1x00_init(void) ++{ ++ ++ /* Porting note: call a board-specific init routine here. */ ++ ++ if (machine_is_assabet()) { ++#ifdef CONFIG_SA1100_ASSABET ++ if (assabet_switches_ucb1x00_init() < 0) ++ return -EIO; ++#endif ++ } ++ if (machine_is_simpad()) { ++#ifdef CONFIG_SA1100_SIMPAD ++ if (simpad_switches_ucb1x00_init() < 0) ++ return -EIO; ++#endif ++ } ++ ++ return 0; ++ ++} ++ ++void __exit switches_ucb1x00_exit(void) ++{ ++ ++ /* Porting note: call a board-specific shutdown routine here. */ ++ ++ if (machine_is_assabet()) { ++#ifdef CONFIG_SA1100_ASSABET ++ assabet_switches_ucb1x00_shutdown(); ++#endif ++ } ++ if (machine_is_simpad()) { ++#ifdef CONFIG_SA1100_SIMPAD ++ simpad_switches_ucb1x00_shutdown(); ++#endif ++ } ++ ++} +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/misc/switches.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,28 @@ ++/* ++ * linux/drivers/misc/switches.h ++ * ++ * Copyright (C) 2001 John Dorsey ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 19 December 2001 - created. ++ */ ++ ++#if !defined(_SWITCHES_H) ++# define _SWITCHES_H ++ ++#include <linux/switches.h> ++ ++#define SWITCHES_NAME "switches" ++ ++extern int switches_event(switches_mask_t *mask); ++ ++extern int switches_sa1100_init(void); ++extern void switches_sa1100_exit(void); ++ ++extern int switches_ucb1x00_init(void); ++extern void switches_ucb1x00_exit(void); ++ ++#endif /* !defined(_SWITCHES_H) */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/misc/ucb1x00-assabet.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,114 @@ ++/* ++ * linux/drivers/misc/ucb1x00-assabet.c ++ * ++ * Copyright (C) 2001 Russell King, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License. ++ * ++ * We handle the machine-specific bits of the UCB1x00 driver here. ++ */ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/proc_fs.h> ++ ++#include <asm/dma.h> ++ ++#include "ucb1x00.h" ++ ++static struct proc_dir_entry *dir; ++static struct ucb1x00 *ucb; ++ ++static int ucb1x00_assabet_read_vbatt(struct ucb1x00 *ucb) ++{ ++ int val; ++ ucb1x00_adc_enable(ucb); ++ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_NOSYNC); ++ ucb1x00_adc_disable(ucb); ++ ++ return val; ++} ++ ++static int ucb1x00_assabet_read_vcharger(struct ucb1x00 *ucb) ++{ ++ int val; ++ ucb1x00_adc_enable(ucb); ++ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD0, UCB_NOSYNC); ++ ucb1x00_adc_disable(ucb); ++ ++ return val; ++} ++ ++static int ucb1x00_assabet_read_batt_temp(struct ucb1x00 *ucb) ++{ ++ int val; ++ ucb1x00_adc_enable(ucb); ++ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD2, UCB_NOSYNC); ++ ucb1x00_adc_disable(ucb); ++ ++ return val; ++} ++ ++static int ucb_read(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ char *p = page; ++ int (*fn)(struct ucb1x00 *) = data; ++ int v, len; ++ ++ v = fn(ucb); ++ ++ p += sprintf(p, "%d\n", v); ++ ++ len = (p - page) - off; ++ if (len < 0) ++ len = 0; ++ ++ *eof = (len <= count) ? 1 : 0; ++ *start = page + off; ++ ++ return len; ++} ++ ++static int __init ucb1x00_assabet_init(void) ++{ ++ struct proc_dir_entry *res; ++ ++ ucb = ucb1x00_get(); ++ ++ if (!ucb) ++ return -ENODEV; ++ ++ dir = proc_mkdir("ucb1x00", NULL); ++ if (!dir) ++ return -ENOMEM; ++ ++ res = create_proc_read_entry("vbatt", S_IRUGO, dir, ucb_read, ucb1x00_assabet_read_vbatt); ++ if (!res) ++ return -ENOMEM; ++ ++ res = create_proc_read_entry("vcharger", S_IRUGO, dir, ucb_read, ucb1x00_assabet_read_vcharger); ++ if (!res) ++ return -ENOMEM; ++ ++ res = create_proc_read_entry("batt_temp", S_IRUGO, dir, ucb_read, ucb1x00_assabet_read_batt_temp); ++ if (!res) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static void __exit ucb1x00_assabet_exit(void) ++{ ++ remove_proc_entry("vbatt", dir); ++ remove_proc_entry("vcharger", dir); ++ remove_proc_entry("batt_temp", dir); ++} ++ ++module_init(ucb1x00_assabet_init); ++module_exit(ucb1x00_assabet_exit); ++ ++MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); ++MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver"); ++MODULE_LICENSE("GPL"); +--- linux-2.4.25/drivers/misc/ucb1x00-audio.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200 ++++ linux-2.4.25/drivers/misc/ucb1x00-audio.c 2004-05-02 22:48:00.000000000 +0200 +@@ -283,7 +283,7 @@ + { + struct ucb1x00_audio *ucba; + +- ucba = kmalloc(sizeof(*ucba), GFP_KERNEL); ++ ucba = kmalloc(sizeof(*ucba), GFP_ATOMIC); + if (ucba) { + memset(ucba, 0, sizeof(*ucba)); + +--- linux-2.4.25/drivers/misc/ucb1x00-core.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/misc/ucb1x00-core.c 2004-05-02 22:45:42.000000000 +0200 +@@ -215,6 +215,9 @@ + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr); + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); + ucb1x00_disable(ucb); ++#ifdef CONFIG_SA1100_SIMPAD ++ simpad_switches_ucb1x00_reinit(); ++#endif + } + + return 0; +@@ -561,8 +564,10 @@ + default_irq = IRQ_GPIO_UCB1300_IRQ; + #endif + #ifdef CONFIG_SA1100_SIMPAD +- if (machine_is_simpad()) ++ if (machine_is_simpad()) { + default_irq = IRQ_GPIO_UCB1300_IRQ; ++ irq_gpio_pin = GPIO_UCB1300_IRQ; ++ } + #endif + #ifdef CONFIG_SA1100_SIMPUTER + if (machine_is_simputer()) { +@@ -660,7 +665,7 @@ + if (id == UCB_ID_1400 && mcp_reg_read(mcp, 0x00) == 0x002a) + id = UCB_ID_1400_BUGGY; + +- my_ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL); ++ my_ucb = kmalloc(sizeof(struct ucb1x00), GFP_ATOMIC); + ret = -ENOMEM; + if (!my_ucb) + goto out; +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/misc/ucb1x00-simpad.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,241 @@ ++/* ++ * linux/drivers/misc/ucb1x00-simpad.c ++ * ++ * Modified by Juergen Messerer for SIMpad ++ * Copyright (C) 2001 Russell King, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License. ++ * ++ * We handle the machine-specific bits of the UCB1x00 driver here. ++ */ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/proc_fs.h> ++ ++#include <asm/dma.h> ++ ++#include <asm/arch-sa1100/simpad_pm.h> ++ ++#include "ucb1x00.h" ++ ++/* ++ * Conversion from AD -> mV ++ * 7.5V = 1023 7.3313mV/Digit ++ * ++ * 400 Units == 9.7V ++ * a = ADC value ++ * 21 = ADC error ++ * 12600 = Divident to get 2*7.3242 ++ * 860 = Divider to get 2*7.3242 ++ * 170 = Voltagedrop over ++ */ ++#define CALIBRATE_BATTERY(a) ((((a + 21)*12600)/860) + 170) ++ ++/* ++ * We have two types of batteries a small and a large one ++ * To get the right value we to distinguish between those two ++ * 450 Units == 15 V ++ */ ++#ifdef SMALL_BATTERY ++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 51) ++#define MIN_SUPPLY 8500 /* Less then 8.5V means no powersupply */ ++#else ++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 45) ++//#define MIN_SUPPLY 14000 /* Less then 14V means no powersupply */ ++#define MIN_SUPPLY 12000 /* Less then 12V means no powersupply */ ++#endif ++ ++/* ++ * Charging Current ++ * if value is >= 50 then charging is on ++ */ ++#define CALIBRATE_CHARGING(a) (((a)* 1000)/(152/4))) ++//#define CHARGING_LED_LEVEL 50 ++ ++#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD ++ ++#define CHARGING_LED_LEVEL 12 ++#define CHARGING_MAX_LEVEL 120 ++#define BATT_FULL 8100 ++#define BATT_LOW 7300 ++#define BATT_CRITICAL 6700 ++#define BATT_EMPTY 6400 ++ ++ ++#else // CONFIG_SA1100_SIMPAD_SINUSPAD ++ ++#define CHARGING_LED_LEVEL 28 ++#define CHARGING_MAX_LEVEL 265 ++#define BATT_FULL 8300 ++#define BATT_LOW 7400 ++#define BATT_CRITICAL 6800 ++#define BATT_EMPTY 6500 ++ ++#endif // CONFIG_SA1100_SIMPAD_SINUSPAD ++ ++ ++static struct proc_dir_entry *dir; ++static struct ucb1x00 *ucb; ++ ++static int ucb1x00_simpad_read_vbatt(struct ucb1x00 *ucb) ++{ ++ int val; ++ ucb1x00_adc_enable(ucb); ++ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_NOSYNC); ++ ucb1x00_adc_disable(ucb); ++ ++ return CALIBRATE_BATTERY(val); ++} ++ ++static int ucb1x00_simpad_read_vcharger(struct ucb1x00 *ucb) ++{ ++ int val; ++ ucb1x00_adc_enable(ucb); ++ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD2, UCB_NOSYNC); ++ ucb1x00_adc_disable(ucb); ++ ++ return CALIBRATE_SUPPLY(val); ++} ++ ++static int ucb1x00_simpad_read_icharger(struct ucb1x00 *ucb) ++{ ++ int val; ++ ucb1x00_adc_enable(ucb); ++ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD3, UCB_NOSYNC); ++ ucb1x00_adc_disable(ucb); ++ ++ return val; ++} ++ ++static int ucb_read(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ char *p = page; ++ int (*fn)(struct ucb1x00 *) = data; ++ int v, len; ++ ++ v = fn(ucb); ++ ++ p += sprintf(p, "%d\n", v); ++ ++ len = (p - page) - off; ++ if (len < 0) ++ len = 0; ++ ++ *eof = (len <= count) ? 1 : 0; ++ *start = page + off; ++ ++ return len; ++} ++ ++/****************************************************************************/ ++/* Functions exported for use by the kernel and kernel modules */ ++/****************************************************************************/ ++ ++int simpad_get_battery(struct simpad_battery *bstat) ++{ ++ int icharger, vcharger, vbatt; ++ ++ if ( ucb ) { ++ icharger = ucb1x00_simpad_read_icharger( ucb ); ++ vcharger = ucb1x00_simpad_read_vcharger( ucb ); ++ vbatt = ucb1x00_simpad_read_vbatt( ucb ); ++ } else { ++ bstat->ac_status = SIMPAD_AC_STATUS_AC_UNKNOWN; ++ bstat->status = SIMPAD_BATT_STATUS_UNKNOWN; ++ bstat->percentage = 0x64; /* lets say 100% */ ++ bstat->life = 360; /* lets say a long time */ ++ return 0; ++ } ++ ++ /* AC status */ ++ bstat->ac_status = SIMPAD_AC_STATUS_AC_OFFLINE; ++ if ( vcharger>MIN_SUPPLY ) { ++ bstat->ac_status = SIMPAD_AC_STATUS_AC_ONLINE; ++ } ++ ++ /* charging */ ++ bstat->status = 0x0; ++ if ( icharger > CHARGING_LED_LEVEL ) { ++ bstat->status = SIMPAD_BATT_STATUS_CHARGING; ++ } ++ ++ if ( vbatt > BATT_LOW ) ++ bstat->status |= SIMPAD_BATT_STATUS_HIGH; ++ else if ( vbatt < BATT_CRITICAL ) ++ bstat->status |= SIMPAD_BATT_STATUS_CRITICAL; ++ else ++ bstat->status |= SIMPAD_BATT_STATUS_LOW; ++ ++ if (bstat->status & SIMPAD_BATT_STATUS_CHARGING) { ++ if (icharger > CHARGING_MAX_LEVEL) icharger = CHARGING_MAX_LEVEL; ++ if (icharger < CHARGING_LED_LEVEL) icharger = CHARGING_LED_LEVEL; ++ bstat->percentage = 100 - 100 * (icharger - CHARGING_LED_LEVEL) / ++ (CHARGING_MAX_LEVEL - CHARGING_LED_LEVEL); ++ } else { ++ if (vbatt > BATT_FULL) vbatt = BATT_FULL; ++ if (vbatt < BATT_EMPTY) vbatt = BATT_EMPTY; ++ bstat->percentage = 100 * (vbatt - BATT_EMPTY) / (BATT_FULL - BATT_EMPTY); ++ } ++ ++ /* let's assume: full load is 7h */ ++ /* bstat->life = 420*bstat->percentage/100; */ ++ bstat->life = 0; ++ ++#if 0 ++ printk("get_battery: ac: %02x / ch: %02x / perc: %02x / life: %d\n", ++ bstat->ac_status, bstat->status, ++ bstat->percentage, bstat->life ); ++#endif ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL(simpad_get_battery); ++ ++/****************************************************************************/ ++/* sample proc interface */ ++/****************************************************************************/ ++static int __init ucb1x00_simpad_init(void) ++{ ++ struct proc_dir_entry *res; ++ ++ ucb = ucb1x00_get(); ++ ++ if (!ucb) ++ return -ENODEV; ++ ++ dir = proc_mkdir("ucb1x00", NULL); ++ if (!dir) ++ return -ENOMEM; ++ ++ res = create_proc_read_entry("vbatt", S_IRUGO, dir, ucb_read, ucb1x00_simpad_read_vbatt); ++ if (!res) ++ return -ENOMEM; ++ ++ res = create_proc_read_entry("vcharger", S_IRUGO, dir, ucb_read, ucb1x00_simpad_read_vcharger); ++ if (!res) ++ return -ENOMEM; ++ ++ res = create_proc_read_entry("icharger", S_IRUGO, dir, ucb_read, ucb1x00_simpad_read_icharger); ++ if (!res) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static void __exit ucb1x00_simpad_exit(void) ++{ ++ remove_proc_entry("vbatt", dir); ++ remove_proc_entry("vcharger", dir); ++ remove_proc_entry("icharger", dir); ++} ++ ++module_init(ucb1x00_simpad_init); ++module_exit(ucb1x00_simpad_exit); ++ ++MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>"); ++MODULE_DESCRIPTION("SIMpad noddy testing only example ADC driver"); ++MODULE_LICENSE("GPL"); +--- linux-2.4.25/drivers/misc/ucb1x00-ts.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/misc/ucb1x00-ts.c 2004-05-02 22:45:42.000000000 +0200 +@@ -356,7 +356,7 @@ + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); + +- udelay(55); ++ udelay(250); /*former 55*/ + + return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); + } +@@ -379,7 +379,7 @@ + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); + +- udelay(55); ++ udelay(250); /*former 55*/ + + return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync); + } +--- linux-2.4.25/drivers/mtd/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.25/drivers/mtd/Config.in 2004-05-02 22:45:42.000000000 +0200 +@@ -11,6 +11,9 @@ + if [ "$CONFIG_MTD_DEBUG" = "y" ]; then + int ' Debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_MTD_DEBUG_VERBOSE 0 + fi ++ if [ "$CONFIG_CRAMFS" = "y" ]; then ++ bool ' Cramfs root partition' CONFIG_ROOT_CRAMFS ++ fi + dep_tristate ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD + dep_tristate ' MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD + dep_tristate ' RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS +--- linux-2.4.25/drivers/mtd/maps/sa1100-flash.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200 ++++ linux-2.4.25/drivers/mtd/maps/sa1100-flash.c 2004-05-02 22:45:42.000000000 +0200 +@@ -767,40 +767,38 @@ + #endif + + #ifdef CONFIG_SA1100_SIMPAD +-#define SIMPAD_FLASH_SIZE 0x02000000 +-static struct mtd_partition simpad_partitions[] = { +- { +- name: "SIMpad boot firmware", +- size: 0x00080000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "SIMpad kernel", +- size: 0x00100000, +- offset: 0x00080000, +- }, { +-#ifdef CONFIG_JFFS2_FS +- name: "SIMpad root jffs2", +- size: MTDPART_SIZ_FULL, +- offset: 0x00180000, ++ ++#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD ++#define SIMPAD_FLASH_SIZE 0x01000000 + #else +- name: "SIMpad initrd", +- size: 0x00300000, +- offset: 0x00180000, +- }, { +- name: "SIMpad root cramfs", +- size: 0x00300000, +- offset: 0x00480000, +- }, { +- name: "SIMpad usr cramfs", +- size: 0x005c0000, +- offset: 0x00780000, +- }, { +- name: "SIMpad usr local", +- size: MTDPART_SIZ_FULL, +- offset: 0x00d40000, ++#define SIMPAD_FLASH_SIZE 0x02000000 + #endif +- } ++ ++static struct mtd_partition simpad_partitions[] = { ++ { ++ name: "SIMpad boot firmware", ++ offset: 0, ++ size: 0x00080000, ++ mask_flags: MTD_WRITEABLE /* force read-only */ ++ },{ ++ name: "SIMpad kernel", ++ offset: MTDPART_OFS_APPEND, ++ size: 0x00100000 ++ },{ ++#ifdef CONFIG_ROOT_CRAMFS ++ name: "SIMpad root cramfs", ++ offset: MTDPART_OFS_APPEND, ++ size: 0x00D80000 ++ },{ ++ name: "SIMpad local jffs", ++ offset: MTDPART_OFS_APPEND, ++ size: MTDPART_SIZ_FULL ++#else ++ name: "SIMpad root jffs2", ++ offset: MTDPART_OFS_APPEND, ++ size: MTDPART_SIZ_FULL ++#endif /* CONFIG_CRAM_FS */ ++ } + }; + #endif /* CONFIG_SA1100_SIMPAD */ + +--- linux-2.4.25/drivers/pcmcia/sa1100_simpad.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200 ++++ linux-2.4.25/drivers/pcmcia/sa1100_simpad.c 2004-05-02 22:45:42.000000000 +0200 +@@ -9,20 +9,18 @@ + + #include <asm/hardware.h> + #include <asm/irq.h> ++#include <asm/arch/simpad.h> ++ + #include "sa1100_generic.h" +- ++ + extern long get_cs3_shadow(void); +-extern void set_cs3_bit(int value); ++extern void set_cs3_bit(int value); + extern void clear_cs3_bit(int value); + + + static int simpad_pcmcia_init(struct pcmcia_init *init){ + int irq, res; + +- set_cs3_bit(PCMCIA_RESET); +- clear_cs3_bit(PCMCIA_BUFF_DIS); +- clear_cs3_bit(PCMCIA_RESET); +- + clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); + + /* Set transition detect */ +@@ -63,6 +61,9 @@ + + if(state_array->size<2) return -1; + ++ memset(state_array->state, 0, ++ (state_array->size)*sizeof(struct pcmcia_state)); ++ + levels=GPLR; + + state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0; +@@ -100,13 +101,15 @@ + static int simpad_pcmcia_configure_socket(const struct pcmcia_configure + *configure) + { +- unsigned long value, flags; ++ static int irq_disabled = 0; + +- if(configure->sock>1) return -1; ++ if(configure->sock>1) ++ return -1; + +- if(configure->sock==0) return 0; ++ if(configure->sock==0) ++ return 0; + +- save_flags_cli(flags); ++ //local_irq_save(flags); + + /* Murphy: see table of MIC2562a-1 */ + +@@ -116,8 +119,8 @@ + break; + + case 33: +- clear_cs3_bit(VCC_3V_EN|EN0); +- set_cs3_bit(VCC_5V_EN|EN1); ++ clear_cs3_bit(VCC_3V_EN|EN1); ++ set_cs3_bit(VCC_5V_EN|EN0); + break; + + case 50: +@@ -129,26 +132,50 @@ + printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, + configure->vcc); + clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); +- restore_flags(flags); ++ //restore_flags(flags); + return -1; + } + +- /* Silently ignore Vpp, output enable, speaker enable. */ ++ if(configure->reset) ++ set_cs3_bit(PCMCIA_RESET); ++ else ++ clear_cs3_bit(PCMCIA_RESET); ++ ++ if(configure->output) ++ clear_cs3_bit(PCMCIA_BUFF_DIS); ++ else ++ set_cs3_bit(PCMCIA_BUFF_DIS); + +- restore_flags(flags); ++ if(configure->irq) { ++ enable_irq(IRQ_GPIO_CF_IRQ); ++ irq_disabled = 0; ++ } ++ else { ++ if (!irq_disabled) { ++ disable_irq(IRQ_GPIO_CF_IRQ); ++ irq_disabled = 1; ++ } ++ } ++ ++ //local_irq_restore(flags); + + return 0; + } + + static int simpad_pcmcia_socket_init(int sock) + { +- set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_BOTH_EDGES); ++ if(sock == 1) ++ set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_BOTH_EDGES); + return 0; + } + + static int simpad_pcmcia_socket_suspend(int sock) + { +- set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_NO_EDGES); ++ if(sock == 1) ++ { ++ set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_NO_EDGES); ++ set_cs3_bit(PCMCIA_RESET); ++ } + return 0; + } + +--- linux-2.4.25/drivers/video/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/video/Config.in 2004-05-02 22:45:42.000000000 +0200 +@@ -61,6 +61,10 @@ + fi + fi + dep_tristate ' CyberPro 2000/2010/5000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI ++ if [ "$CONFIG_SA1100_SIMPAD" = "y" -o \ ++ "$CONFIGG_SA1100_GDS2200" = "y" ]; then ++ bool ' MQ200 VGA support' CONFIG_FB_MQ200 ++ fi + if [ "$CONFIG_APOLLO" = "y" ]; then + define_bool CONFIG_FB_APOLLO y + fi +--- linux-2.4.25/drivers/video/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/drivers/video/Makefile 2004-05-02 22:45:42.000000000 +0200 +@@ -141,6 +141,7 @@ + obj-$(CONFIG_FB_PVR2) += pvr2fb.o + obj-$(CONFIG_FB_VOODOO1) += sstfb.o + obj-$(CONFIG_FB_ANAKIN) += anakinfb.o ++obj-$(CONFIG_FB_MQ200) += mq200fb.o + + # Generic Low Level Drivers + +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/drivers/video/mq200fb.c 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,1963 @@ ++/* MQ200 console frame buffer driver---mq200fb.c ++ * ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive for ++ * more details. ++ */ ++ ++#include <linux/config.h> ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/string.h> ++#include <linux/mm.h> ++#include <linux/tty.h> ++#include <linux/slab.h> ++#include <linux/vmalloc.h> ++#include <linux/delay.h> ++#include <linux/pm.h> ++#include <linux/interrupt.h> ++#include <linux/proc_fs.h> /* all the /proc functions */ ++#include <linux/ioport.h> ++#include <asm/uaccess.h> ++#include <linux/fb.h> ++#include <linux/init.h> ++#include <linux/pci.h> ++#include <asm/io.h> ++ ++#include <linux/console.h> ++ ++#include <video/fbcon.h> ++#ifdef CONFIG_FBCON_MFB ++#include <video/fbcon-mfb.h> ++#endif ++#ifdef CONFIG_FBCON_CFB2 ++#include <video/fbcon-cfb2.h> ++#endif ++#ifdef CONFIG_FBCON_CFB4 ++#include <video/fbcon-cfb4.h> ++#endif ++#ifdef CONFIG_FBCON_CFB8 ++#include <video/fbcon-cfb8.h> ++#endif ++#ifdef CONFIG_FBCON_CFB16 ++#include <video/fbcon-cfb16.h> ++#endif ++#ifdef CONFIG_FBCON_CFB24 ++#include <video/fbcon-cfb24.h> ++#endif ++#ifdef CONFIG_FBCON_CFB32 ++#include <video/fbcon-cfb32.h> ++#endif ++ ++#include <video/MQ200/mq2hw.h> ++#include <video/MQ200/mqdata.h> ++#include <video/MQ200/mqplat.h> ++ ++/* GPIO handling */ ++#include <asm/irq.h> ++#include <asm/hardware.h> ++ ++#ifdef TEST ++#undef PDEBUG /* Safety */ ++ ++#define PDEBUG(fmt, args...) printk(KERN_EMERG fmt, ##args) ++#else ++#define PDEBUG(fmt, args...) ++#endif ++ ++#define MQ200_DIRNAME "driver/mq200" ++#define REG_DIRNAME "registers" ++ ++void enable_cursor(void *pMQMMIO); ++ ++static ssize_t proc_read_reg(struct file * file, char * buf, ++ size_t nbytes, loff_t *ppos); ++static ssize_t proc_write_reg(struct file * file, const char * buffer, ++ size_t count, loff_t *ppos); ++ ++static struct file_operations proc_reg_operations = { ++ read: proc_read_reg, ++ write: proc_write_reg ++}; ++ ++typedef struct sa1110_reg_entry { ++ u32 phyaddr; ++ char* name; ++ char* description; ++ unsigned short low_ino; ++} sa1110_reg_entry_t; ++ ++#define CMAPSIZE 32 ++#define arraysize(x) (sizeof(x)/sizeof(*(x))) ++ ++#define mq200_p2v( x ) \ ++ (((x) - 0x4b800000) + 0xf2800000) ++ ++/* The following is copied from mq2hw.c for initialization of MQ200 */ ++/* PLL1 data */ ++#define PLL1_83MHZ 0x0EF2082A ++#define DEF_MIU2_83MHZ 0x4143E086 ++#define PLL1_50MHZ 0x0B200A2A ++#define DEF_MIU2_50MHZ 0x40C30086 ++ ++/* Miscellaneous default data */ ++#define DEF_D1 0x05000271 ++#define DEF_D2 0x00000271 ++#define DEF_MIU3 0x6D6AABFF ++#define DEF_MIU4 0x00000001 ++#define DEF_MIU5 0x0000010D ++ ++#ifdef CONFIG_SA1100_GDS2200 ++#define DEF_GPO_CONTROL 0x00020054 ++#else ++#define DEF_GPO_CONTROL 0x00000000 ++#endif ++ ++#define DEF_GPIO_CONTROL 0x00000000 ++#define DEF_PWM_CONTROL 0x00A16c44 ++#define PWMOFFMASK 0xFF0FFF0F ++ ++struct fb_info_mq200 { ++ struct fb_info fb_info; ++ struct fb_fix_screeninfo fix; ++ struct fb_var_screeninfo var; ++ struct display disp; ++ struct { ++ __u8 red, green, blue; ++ } palette[256]; ++ struct fb_info_mq200 *next; ++ unsigned int mqMmioAddrVirt; ++ unsigned int mqFbAddrVirt; ++ unsigned int mqMmioAddrPhys; ++ unsigned int mqFbAddrPhys; ++#ifdef CONFIG_PM ++ struct pm_dev *pm; ++#endif ++}; ++ ++u32 mqflag; ++u32 mqMmioAddr, mqFbAddr; ++ ++/* Interface need to console.c. The following variable are defined in ++ drivers/char/console.c */ ++ ++extern unsigned char color_table[]; ++extern int default_red[]; ++extern int default_grn[]; ++extern int default_blu[]; ++ ++#ifdef CONFIG_SA1100_SIMPAD ++ extern void set_cs3_bit(int value); ++ extern void clear_cs3_bit(int value); ++ DISPLAY_CONFIG dc = {800, 600, 16, 60, 1600, 0x00130004}; ++#else ++ DISPLAY_CONFIG dc = {800, 600, 32, 60, 3200, 0x0023000f}; ++#endif ++ ++static int currcon = 0; ++static char mq200fb_name[16] = "MQ200FB"; ++ ++static struct fb_var_screeninfo mq200fb_default = { ++ /* 800x600, 32 bpp */ ++ 800, 600, 800, 600, 0, 0, 32, 0, ++ {0, 8, 0}, {8, 8, 0}, {16, 8, 0}, {24, 8, 0}, ++ 0, 0, -1, -1, 0, MQ200_FB_SIZE, 64, 64, 32, 32, 64, 2, ++ 0, FB_VMODE_NONINTERLACED ++}; ++static union { ++ u16 cfb16[CMAPSIZE]; ++ u32 cfb24[CMAPSIZE]; ++ u32 cfb32[CMAPSIZE]; ++} fbcon_cmap; ++ ++static struct proc_dir_entry *regdir; ++static struct proc_dir_entry *mq200dir; ++static struct proc_dir_entry *driverdir; ++ ++/* Functions used to initialize MQ200 chip */ ++void setmqmode(PDISPLAY_CONFIG, void *); ++void setup_cursor(void *); ++void onoffdisplay(int, void *); ++unsigned long getbppbits(int); ++PDISPLAY_TIMING getgcparam(int, int, int); ++void setpal(int, unsigned long, void *); ++void setupfp(int, void *); ++void setuphfbuffer(int, unsigned long, void *); ++void setupgc(int, int, int, int, int, void *); ++void setupgcmem(PDISPLAY_CONFIG, unsigned long, void *); ++long idmqchip(void *pMQMMIO); ++void turnoffMQ200(void * pMQMMIO); ++ ++/* Interface used by the world */ ++int mq200fb_setup(char*); ++static int mq200fb_open(struct fb_info *info, int user); ++static int mq200fb_release (struct fb_info *info, int user); ++static int mq200fb_get_fix(struct fb_fix_screeninfo *fix, int con, \ ++ struct fb_info *info); ++static int mq200fb_get_var(struct fb_var_screeninfo *var, int con, \ ++ struct fb_info *info); ++static int mq200fb_set_var(struct fb_var_screeninfo *var, int con, \ ++ struct fb_info *info); ++static int mq200fb_pan_display(struct fb_var_screeninfo *var, int con, \ ++ struct fb_info *info); ++static int mq200fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, \ ++ struct fb_info *info); ++static int mq200fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, \ ++ struct fb_info *info); ++static int mq200fb_ioctl(struct inode *inode, struct file *file, u_int cmd, ++ u_long arg, int con, struct fb_info *info); ++ ++/* Interface to the low level console driver */ ++int mq200fb_init(void); ++static int mq200fbcon_switch(int con, struct fb_info *info); ++static int mq200fbcon_updatevar(int con, struct fb_info *info); ++static void mq200fbcon_blank(int blank, struct fb_info *info); ++ ++/* int sa1100fb_map_video_memory(void * pmem int memsize); */ ++ ++/* ++ *Internal routines ++ */ ++ ++static u_long get_line_length(int xres_virtual, int bpp); ++static void mq200fb_encode_fix(struct fb_fix_screeninfo *fix, ++ struct fb_var_screeninfo *var); ++static void set_color_bitfields(struct fb_var_screeninfo *var); ++static int mq200fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, ++ u_int *transp, struct fb_info *info); ++static int mq200fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ++ u_int transp, struct fb_info *info); ++static void do_install_cmap(int con, struct fb_info *info); ++ ++#ifdef CONFIG_PM ++static int mq200fb_pm_callback(struct pm_dev *, pm_request_t, void *); ++#endif ++ ++#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD) ++static void mq200_backlight(void *, int); ++#endif ++ ++#ifdef CONFIG_SA1100_SIMPAD ++static void writeBrightness(void *, int); ++#endif ++ ++static struct fb_ops mq200fb_ops = { ++ owner: THIS_MODULE, ++ fb_get_fix: mq200fb_get_fix, ++ fb_get_var: mq200fb_get_var, ++ fb_set_var: mq200fb_set_var, ++ fb_get_cmap: mq200fb_get_cmap, ++ fb_set_cmap: mq200fb_set_cmap, ++ fb_pan_display: mq200fb_pan_display, ++ fb_ioctl: mq200fb_ioctl, ++}; ++ ++typedef struct mq200_reg_entry { ++ u32 phyaddr; ++ char* name; ++ char* description; ++ unsigned short low_ino; ++} mq200_reg_entry_t; ++ ++static mq200_reg_entry_t mq200_regs[] = ++{ ++ { 0x4be00000, "PM_MISC", "MQ200 PM_MISC" }, ++ { 0x4be00004, "D1_STATE", "MQ200 D1_STATE" }, ++ { 0x4be00008, "D2_STATE", "MQ200 D2_STATE" }, ++ { 0x4be00018, "PLL2_CONTROL", "MQ200 PLL2_CONTROL" }, ++ { 0x4be0001c, "PLL3_CONTROL", "MQ200 PLL3_CONTROL" }, ++ { 0x4be02000, "CPU_CONTROL", "MQ200 CPU_CONTROL" }, ++ { 0x4be02004, "DRAW_STATUS", "MQ200 DRAW_STATUS" }, ++ { 0x4be04000, "MIU_CONTROL1", "MQ200 MIU_CONTROL1" }, ++ { 0x4be04004, "MIU_CONTROL2", "MQ200 MIU_CONTROL2" }, ++ { 0x4be04008, "MIU_CONTROL3", "MQ200 MIU_CONTROL3" }, ++ { 0x4be0400c, "MIU_CONTROL4", "MQ200 MIU_CONTROL4" }, ++ { 0x4be04010, "MIU_CONTROL5", "MQ200 MIU_CONTROL5" }, ++ { 0x4be0a000, "GC1_CONTROL", "MQ200 GC1_CONTROL" }, ++ { 0x4be0a004, "GC1_CRT_CONTROL", "MQ200 GC1_CRT_CONTROL" }, ++ { 0x4be0a008, "HD1_CONTROL", "MQ200 HD1_CONTROL" }, ++ { 0x4be0a00c, "VD1_CONTROL", "MQ200 VD1_CONTROL" }, ++ { 0x4be0a010, "HS1_CONTROL", "MQ200 HS1_CONTROL" }, ++ { 0x4be0a014, "VS1_CONTROL", "MQ200 VS1_CONTROL" }, ++ { 0x4be0a020, "HW1_CONTROL", "MQ200 HW1_CONTROL" }, ++ { 0x4be0a024, "VW1_CONTROL", "MQ200 VW1_CONTROL" }, ++ { 0x4be0a040, "HW_CURSOR1_POS", "MQ200 HW_CURSOR1_POS" }, ++ { 0x4be0a044, "HW_CURSOR1_ADDR", "MQ200 HW_CURSOR1_ADDR" }, ++ { 0x4be0e000, "FP_CONTROL", "MQ200 FP_CONTROL" }, ++ { 0x4be0e004, "FP_PIN_CONTROL", "MQ200 FP_PIN_CONTROL" }, ++ { 0x4be0e008, "FP_GPO_CONTROL", "MQ200 FP_GPO_CONTROL" }, ++ { 0x4be0e00c, "FP_GPIO_CONTROL", "MQ200 FP_GPIO_CONTROL" }, ++ { 0x4be0e010, "STN_CONTROL", "MQ200 STN_CONTROL" }, ++ { 0x4be0e014, "DSTN_FB_CONTROL", "MQ200 DSTN_FB_CONTROL" }, ++ { 0x4be0e03c, "PWM_CONTROL", "MQ200 PWM_CONTROL" }, ++ { 0x4be14000, "DC_0", "MQ200 DC_1" }, ++ { 0x4be14004, "DC_1", "MQ200 DC_2" }, ++ { 0x4be14008, "DC_SW_0", "MQ200 DC_SW_0" }, ++ { 0x4be1400c, "DC_SW_1", "MQ200 DC_SW_1" }, ++ { 0x4be16040, "PMR", "MQ200 PMR" }, ++ { 0x4be16044, "PMCSR", "MQ200 PMCSR" } ++}; ++ ++#define NUM_OF_MQ200_REG_ENTRY (sizeof(mq200_regs)/sizeof(mq200_reg_entry_t)) ++ ++static int mq200fb_open(struct fb_info *info, int user) ++{ ++ /* ++ * Nothing, only a usage count for the moment ++ */ ++ MOD_INC_USE_COUNT; ++ return(0); ++ ++} ++ ++/* Release console */ ++static int mq200fb_release (struct fb_info *info, int user) ++{ ++ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info; ++ turnoffMQ200((void *) p->mqMmioAddrVirt); ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++/* Get the Fixed Part of the Display */ ++static int mq200fb_get_fix(struct fb_fix_screeninfo *fix, int con, ++ struct fb_info *info) ++{ ++ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info; ++ ++ PDEBUG("mq200fb: %i---in mq200fb_get_fix.\n", __LINE__); ++ ++ *fix = p->fix; ++ return 0; ++ ++} ++ ++ ++ /* ++ * Get the User Defined Part of the Display ++ */ ++ ++static int mq200fb_get_var(struct fb_var_screeninfo *var, int con, ++ struct fb_info *info) ++{ ++ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info; ++ ++ PDEBUG("mq200fb: %i---in mq200fb_get_var.\n", __LINE__); ++ ++ *var = p->var; ++ return 0; ++} ++ ++ ++ /* ++ * Set the User Defined Part of the Display ++ */ ++ ++static int mq200fb_set_var(struct fb_var_screeninfo *var, int con, ++ struct fb_info *info) ++{ ++ struct fb_info_mq200 * p = (struct fb_info_mq200 *) info; ++ int err, activate = var->activate; ++ int oldxres, oldyres, oldvxres, oldvyres, oldbpp; ++ u_long line_length; ++ ++ struct display *display; ++ ++ PDEBUG("mq200fb: %i---in mq200fb_set_var.\n", __LINE__); ++ ++ if (con >= 0) ++ display = &fb_display[con]; ++ else ++ display = &(p->disp); /* used during initialization */ ++ ++ /* ++ * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! ++ * as FB_VMODE_SMOOTH_XPAN is only used internally ++ */ ++ ++ if (var->vmode & FB_VMODE_CONUPDATE) { ++ var->vmode |= FB_VMODE_YWRAP; ++ var->xoffset = display->var.xoffset; ++ var->yoffset = display->var.yoffset; ++ } ++ ++ /* ++ * Memory limit ++ */ ++ line_length = get_line_length(var->xres_virtual, var->bits_per_pixel); ++ if (line_length*var->yres_virtual > MQ200_FB_SIZE) ++ return -ENOMEM; ++ ++ set_color_bitfields(var); ++ ++ if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { ++ oldxres = display->var.xres; ++ oldyres = display->var.yres; ++ oldvxres = display->var.xres_virtual; ++ oldvyres = display->var.yres_virtual; ++ oldbpp = display->var.bits_per_pixel; ++ display->var = *var; ++ if (oldxres != var->xres || oldyres != var->yres || ++ oldvxres != var->xres_virtual || oldvyres != var->yres_virtual || ++ oldbpp != var->bits_per_pixel) { ++ ++ display->screen_base = (char *) p->mqFbAddrVirt; ++ display->visual = p->fix.visual; ++ display->type = p->fix.type; ++ display->type_aux = p->fix.type_aux; ++ display->ypanstep = p->fix.ypanstep; ++ display->ywrapstep = p->fix.ywrapstep; ++ display->line_length = p->fix.line_length; ++ display->can_soft_blank = 1; ++ display->inverse = 0; ++ ++ switch (var->bits_per_pixel) { ++#ifdef CONFIG_FBCON_MFB ++ case 1: ++ display->dispsw = &fbcon_mfb; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB2 ++ case 2: ++ display->dispsw = &fbcon_cfb2; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB4 ++ case 4: ++ display->dispsw = &fbcon_cfb4; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB8 ++ case 8: ++ display->dispsw = &fbcon_cfb8; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB16 ++ case 16: ++ display->dispsw = &fbcon_cfb16; ++ display->dispsw_data = fbcon_cmap.cfb16; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB24 ++ case 24: ++ display->dispsw = &fbcon_cfb24; ++ display->dispsw_data = fbcon_cmap.cfb24; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB32 ++ case 32: ++ display->dispsw = &fbcon_cfb32; ++ display->dispsw_data = fbcon_cmap.cfb32; ++ break; ++#endif ++ default: ++ display->dispsw = &fbcon_dummy; ++ break; ++ } ++ ++ ++ if (p->fb_info.changevar) ++ (*p->fb_info.changevar)(con); ++ } ++ ++ if (oldbpp != var->bits_per_pixel) { ++ if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) ++ return err; ++ do_install_cmap(con, info); ++ } ++ ++ } ++ ++ return 0; ++} ++ ++ ++ /* ++ * Pan or Wrap the Display ++ * ++ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag ++ */ ++ ++static int mq200fb_pan_display(struct fb_var_screeninfo *var, int con, ++ struct fb_info *info) ++{ ++ PDEBUG("mq200fb: %i---mq200fb_pan_display.\n", __LINE__); ++ ++ if (var->vmode & FB_VMODE_YWRAP) { ++ if (var->yoffset < 0 || ++ var->yoffset >= fb_display[con].var.yres_virtual || ++ var->xoffset) ++ return -EINVAL; ++ } else { ++ if (var->xoffset+fb_display[con].var.xres > ++ fb_display[con].var.xres_virtual || ++ var->yoffset+fb_display[con].var.yres > ++ fb_display[con].var.yres_virtual) ++ return -EINVAL; ++ } ++ fb_display[con].var.xoffset = var->xoffset; ++ fb_display[con].var.yoffset = var->yoffset; ++ if (var->vmode & FB_VMODE_YWRAP) ++ fb_display[con].var.vmode |= FB_VMODE_YWRAP; ++ else ++ fb_display[con].var.vmode &= ~FB_VMODE_YWRAP; ++ return 0; ++} ++ ++ /* ++ * Get the Colormap ++ */ ++ ++static int mq200fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, ++ struct fb_info *info) ++{ ++ PDEBUG("mq200fb: %i---mq200fb_get_cmap.\n", __LINE__); ++ ++ if (con == currcon) /* current console? */ ++ return fb_get_cmap(cmap, kspc, mq200fb_getcolreg, info); ++ else if (fb_display[con].cmap.len) /* non default colormap? */ ++ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); ++ else ++ { ++ int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16; ++ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2); ++ } ++ return 0; ++} ++ ++ /* ++ * Set the Colormap ++ */ ++ ++static int mq200fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, ++ struct fb_info *info) ++{ ++ int err; ++ ++ PDEBUG("mq200fb: %i---mq200fb_set_cmap.\n", __LINE__); ++ ++ if (!fb_display[con].cmap.len) { /* no colormap allocated? */ ++ int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16; ++ if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0))) ++ return err; ++ } ++ if (con == currcon) /* current console? */ ++ return fb_set_cmap(cmap, kspc, mq200fb_setcolreg, info); ++ else ++ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); ++ return 0; ++} ++ ++ ++static int mq200fb_ioctl(struct inode *inode, struct file *file, u_int cmd, ++ u_long arg, int con, struct fb_info *info) ++{ ++ return -EINVAL; ++} ++ ++ ++int __init mq200fb_setup(char *options) ++{ ++ PDEBUG("mq200fb.c: %i---mq200fb_setup\n", __LINE__); ++ ++/* ++ char *this_opt; ++ ++ fb_info.fontname[0] = '\0'; ++ ++ if (!options || !*options) ++ return 0; ++ ++ for (this_opt = strtok(options, ","); this_opt; ++ this_opt = strtok(NULL, ",")) { ++ if (!strncmp(this_opt, "font:", 5)) ++ strcpy(fb_info.fontname, this_opt+5); ++ } ++*/ ++ return 0; ++} ++ ++ ++ /* ++ * Initialisation ++ */ ++ ++int __init mq200fb_init(void) ++{ ++ struct fb_info_mq200 *p = NULL; ++ int i; /* used as loop counter */ ++ struct proc_dir_entry *entry; ++ ++ p = (struct fb_info_mq200 *) kmalloc(sizeof(*p), GFP_ATOMIC); ++ if(p==NULL) ++ return 0; ++ memset(p, 0, sizeof(*p)); ++ ++ mq200dir = proc_mkdir(MQ200_DIRNAME, NULL); ++ if (mq200dir == NULL) { ++ printk(KERN_ERR "mq200fb: can't create /proc/" MQ200_DIRNAME "\n"); ++ return(-ENOMEM); ++ } ++ ++ regdir = proc_mkdir(REG_DIRNAME, mq200dir); ++ if (regdir == NULL) { ++ printk(KERN_ERR "mq200fb: can't create /proc/" MQ200_DIRNAME "/" REG_DIRNAME "\n"); ++ return(-ENOMEM); ++ } ++ ++ for(i=0;i<NUM_OF_MQ200_REG_ENTRY;i++) { ++ entry = create_proc_entry(mq200_regs[i].name, ++ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, ++ regdir); ++ if(entry) { ++ mq200_regs[i].low_ino = entry->low_ino; ++ entry->proc_fops = &proc_reg_operations; ++ } ++ else { ++ printk( KERN_ERR ++ "mq200fb: can't create /proc/" REG_DIRNAME ++ "/%s\n", mq200_regs[i].name); ++ return(-ENOMEM); ++ } ++ } ++ ++ ++#ifdef MQ_SA1110 ++ ++#ifdef CONFIG_SA1100_ASSABET ++ pCPUReg=(u32 *)ioremap( MSC2, 4); ++ *pCPUReg = 0x42194449; ++ iounmap((void *) pCPUReg); ++ ++ GPDR |= 0x08000000; ++ GAFR |= 0x08000000; ++ TUCR |= 0x20000000; ++ ++ ASSABET_BCR_set(ASSABET_BCR_GFX_RST); /* ASSABET_BCR */ ++ ++ MQ_DELAY(8); ++ ASSABET_BCR_clear(ASSABET_BCR_GFX_RST); ++ MQ_DELAY(30); ++ ASSABET_BCR_set(ASSABET_BCR_GFX_RST); /* ASSABET_BCR */ ++#endif ++ ++#ifdef CONFIG_SA1100_SIMPAD ++ GPDR |= (1<<3); ++ GAFR |= ~(1<<3); ++ GPSR |= (1<<3); ++#endif ++ ++ p->mqMmioAddrPhys=REGISTER_BASE; ++ p->mqFbAddrPhys=FB_BASE; ++ ++ p->mqMmioAddrVirt = mqMmioAddr = 0xf2e00000; ++ p->mqFbAddrVirt = mqFbAddr = 0xf2800000; ++ ++#endif /* MQ_SA1110 */ ++ ++ mqflag = dc.flag; ++ ++ PDEBUG("mq200fb.c: line %i, mqMmioAddr = 0X%08X, mqFbAddr = 0X%08X\n",\ ++ __LINE__, mqMmioAddr, mqFbAddr); ++ ++ /* Setmode for MQ200 chip */ ++ setmqmode(&dc, (void *) mqMmioAddr); ++ ++ /* Set fb_info_mq200.fix info */ ++ strcpy(p->fix.id, mq200fb_name); ++ p->fix.smem_start = p->mqFbAddrPhys; ++ p->fix.smem_len = MQ200_FB_SIZE; ++ p->fix.mmio_start = p->mqMmioAddrPhys; ++ p->fix.mmio_len = MQ200_MMIO_SIZE; ++ p->fix.type = FB_TYPE_PACKED_PIXELS; ++ ++ if(dc.bpp <= 8) ++ p->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else if (dc.bpp >= 16) ++ p->fix.visual = FB_VISUAL_DIRECTCOLOR; ++ ++ p->fix.line_length = dc.stride; ++ ++ /* Set fb_info_mq200.var info */ ++ p->var.xres = dc.x; ++ p->var.yres = dc.y; ++ p->var.xres_virtual = dc.x; ++ p->var.yres_virtual = dc.y; ++ p->var.bits_per_pixel = dc.bpp; ++ ++ if(dc.bpp == 8) { ++ p->var.red.offset = 0; ++ p->var.green.offset = 0; ++ p->var.blue.offset = 0; ++ p->var.red.length = p->var.green.length = \ ++ p->var.blue.length = dc.bpp; ++ p->var.transp.length = 0; ++ p->var.transp.offset = 0; ++ } ++ else if(dc.bpp == 16) { ++#ifdef CONF ++ IG_PREP ++ p->var.red.offset = 2; ++ p->var.green.offset = -3; ++ p->var.blue.offset = 8; ++#else ++ p->var.red.offset = 11; ++ p->var.green.offset = 5; ++ p->var.blue.offset = 0; ++#endif ++ ++ p->var.red.length = 5; ++ p->var.green.length = 6; ++ p->var.blue.length = 5; ++ } ++ else if (dc.bpp == 24) { ++#ifdef CONFIG_PREP ++ p->var.red.offset = 8; ++ p->var.green.offset = 16; ++ p->var.blue.offset = 24; ++#else ++ p->var.red.offset = 16; ++ p->var.green.offset = 8; ++ p->var.blue.offset = 0; ++#endif ++ p->var.red.length = 8; ++ p->var.green.length = 8; ++ p->var.blue.length = 8; ++ } ++ else if(dc.bpp == 32) { ++#ifdef CONFIG_PREP ++ p->var.red.offset = 8; ++ p->var.green.offset = 16; ++ p->var.blue.offset = 24; ++#else ++ p->var.red.offset = 0; ++ p->var.green.offset = 8; ++ p->var.blue.offset = 16; ++#endif /* CONFIG_PREP */ ++ p->var.red.length = 8; ++ p->var.green.length = 8; ++ p->var.blue.length = 8; ++ } ++ ++ p->var.transp.length = 0; ++ p->var.transp.offset = 0; ++ p->var.height = p->var.width = -1; ++ p->var.vmode = FB_VMODE_NONINTERLACED; ++ p->var.pixclock = 10000; ++ p->var.left_margin = p->var.right_margin = 16; ++ p->var.upper_margin = p->var.lower_margin = 16; ++ p->var.hsync_len = p->var.vsync_len = 8; ++ ++ /* Set fb_info_mq200.disp info */ ++ p->disp.var = p->var; ++ p->disp.cmap.red = NULL; ++ p->disp.cmap.green = NULL; ++ p->disp.cmap.blue = NULL; ++ p->disp.cmap.transp = NULL; ++ p->disp.screen_base = (char *) p->mqFbAddrVirt; ++ p->disp.visual = p->fix.visual; ++ p->disp.type = p->fix.type; ++ p->disp.type_aux = p->fix.type_aux; ++ p->disp.line_length = p->fix.line_length; ++ p->disp.can_soft_blank = 1; ++ ++ switch(dc.bpp) { ++#ifdef CONFIG_FBCON_CFB8 ++ case 8: ++ p->disp.dispsw = &fbcon_cfb8; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB16 ++ case 16: ++ p->disp.dispsw = &fbcon_cfb16; ++ p->disp.dispsw_data = fbcon_cmap.cfb16; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB24 ++ case 24: ++ p->disp.dispsw = &fbcon_cfb24; ++ p->disp.dispsw_data = fbcon_cmap.cfb24; ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB32 ++ case 32: ++ p->disp.dispsw = &fbcon_cfb32; ++ p->disp.dispsw_data = fbcon_cmap.cfb32; ++ break; ++#endif ++ default: ++ PDEBUG("mq200fb.c: %i---Wrong configuration options", __LINE__); ++ } ++ ++ p->disp.scrollmode = SCROLL_YREDRAW; ++ ++ strcpy(p->fb_info.modename, p->fix.id); ++ p->fb_info.changevar = NULL; ++ p->fb_info.node = NODEV; ++ ++ p->fb_info.fbops = &mq200fb_ops; ++ p->fb_info.disp = &(p->disp); ++ p->fb_info.switch_con = &mq200fbcon_switch; ++ p->fb_info.updatevar = &mq200fbcon_updatevar; ++ p->fb_info.blank = &mq200fbcon_blank; ++ p->fb_info.flags = FBINFO_FLAG_DEFAULT; ++ ++ for (i = 0; i < 16; i++) { ++ int j = color_table[i]; ++ p->palette[i].red = default_red[j]; ++ p->palette[i].green = default_grn[j]; ++ p->palette[i].blue = default_blu[j]; ++ } ++ ++ if (register_framebuffer(&p->fb_info) < 0) { ++ PDEBUG("Oops...register_framebuffer failed!\n"); ++ iounmap(p); ++ iounmap((void *)mqMmioAddr); ++ iounmap((void *)mqFbAddr); ++ return -EINVAL; ++ } ++ ++#ifdef CONFIG_PM ++ /* ++ * Note that the console registers this as well, but we want to ++ * power down the display prior to sleeping. ++ */ ++ p->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, mq200fb_pm_callback); ++ if (p->pm) ++ p->pm->data = p; ++#endif ++ PDEBUG("fb%d: Virtual frame buffer device, using %ldK of video memory\n", \ ++ GET_FB_IDX(p->fb_info.node), MQ200_FB_SIZE >> 10); ++ return 0; ++} ++ ++static int mq200fbcon_switch(int con, struct fb_info *info) ++{ ++ /* Do we have to save the colormap? */ ++ ++ PDEBUG("mq200fb: mq200fbcon_switch.\n"); ++ ++ if (fb_display[currcon].cmap.len) ++ fb_get_cmap(&fb_display[currcon].cmap, 1, mq200fb_getcolreg, info); ++ ++ currcon = con; ++ /* Install new colormap */ ++ do_install_cmap(con, info); ++ return 0; ++} ++ ++/* ++ * Update the `var' structure (called by fbcon.c) ++ */ ++ ++static int mq200fbcon_updatevar(int con, struct fb_info *info) ++{ ++ /* Nothing */ ++ ++ PDEBUG("mq200fb: mq200fbcon_updatevar.\n"); ++ ++ return 0; ++} ++ ++/* ++ * Blank the display. ++ */ ++ ++static void mq200fbcon_blank(int blank, struct fb_info *info) ++{ ++ /*struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;*/ ++ ++ /* Nothing */ ++ /* ++ if(blank) ++ onoffdisplay(DISABLE_LCD_GC1, (void *) p->mqMmioAddrVirt); ++ else ++ onoffdisplay(ENABLE_LCD_GC1, (void *) p->mqMmioAddrVirt);*/ ++} ++ ++static u_long get_line_length(int xres_virtual, int bpp) ++{ ++ u_long length; ++ ++ PDEBUG("mq200fb: get_line_length.\n"); ++ ++ length = (xres_virtual+bpp-1)/bpp; ++ length = (length+31)&-32; ++ length >>= 3; ++ return(length); ++} ++ ++static void mq200fb_encode_fix(struct fb_fix_screeninfo *fix, ++ struct fb_var_screeninfo *var) ++{ ++ ++ PDEBUG("mq200fb: mq200fb_encode_fix.\n"); ++ ++ memset(fix, 0, sizeof(struct fb_fix_screeninfo)); ++ strcpy(fix->id, mq200fb_name); ++ fix->smem_start = mqFbAddr; ++ fix->smem_len = MQ200_FB_SIZE; ++ fix->type = FB_TYPE_PACKED_PIXELS; ++ fix->type_aux = 0; ++ switch (var->bits_per_pixel) { ++ case 1: ++ fix->visual = FB_VISUAL_MONO01; ++ break; ++ case 2: ++ case 4: ++ case 8: ++ fix->visual = FB_VISUAL_PSEUDOCOLOR; ++ break; ++ case 16: ++ case 24: ++ case 32: ++ fix->visual = FB_VISUAL_DIRECTCOLOR; ++ break; ++ } ++ fix->ywrapstep = 1; ++ fix->xpanstep = 1; ++ fix->ypanstep = 1; ++ fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel); ++} ++ ++static void set_color_bitfields(struct fb_var_screeninfo *var) ++{ ++ ++ PDEBUG("mq200fb: set_color_bitfields.\n"); ++ ++ switch (var->bits_per_pixel) { ++ case 1: ++ case 8: ++ var->red.offset = 0; ++ var->red.length = 8; ++ var->green.offset = 0; ++ var->green.length = 8; ++ var->blue.offset = 0; ++ var->blue.length = 8; ++ var->transp.offset = 0; ++ var->transp.length = 0; ++ break; ++ case 16: /* RGB 565 */ ++#ifdef CONFIG_PREP ++ var->red.offset = 2; ++ var->green.offset = -3; ++ var->blue.offset = 8; ++#else ++ var->red.offset = 11; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++#endif ++ var->red.length = 5; ++ var->green.length = 6; ++ var->blue.length = 5; ++ var->transp.length = 0; ++ var->transp.offset = 0; ++ break; ++ case 24: /* RGB 888 */ ++#ifdef CONFIG_PREP ++ var->red.offset = 8; ++ var->green.offset = 16; ++ var->blue.offset = 24; ++#else ++ var->red.offset = 16; ++ var->green.offset = 8; ++ var->blue.offset = 0; ++#endif ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ break; ++ case 32: /* RGBA 8888 */ ++ var->red.offset = 0; ++ var->red.length = 8; ++ var->green.offset = 8; ++ var->green.length = 8; ++ var->blue.offset = 16; ++ var->blue.length = 8; ++ var->transp.offset = 24; ++ var->transp.length = 8; ++ break; ++ } ++ var->red.msb_right = 0; ++ var->green.msb_right = 0; ++ var->blue.msb_right = 0; ++ var->transp.msb_right = 0; ++} ++ ++ ++ /* ++ * Read a single color register and split it into ++ * colors/transparent. Return != 0 for invalid regno. ++ */ ++ ++static int mq200fb_getcolreg(u_int regno, u_int *red, u_int *green, ++ u_int *blue, u_int *transp, struct fb_info *info) ++{ ++ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info; ++ ++ /*PDEBUG("mq200fb: mq200fb_getcolreg.\n");*/ ++ ++ if (regno > 255) ++ return 1; ++ *red = (p->palette[regno].red<<8) | p->palette[regno].red; ++ *green = (p->palette[regno].green<<8) | p->palette[regno].green; ++ *blue = (p->palette[regno].blue<<8) | p->palette[regno].blue; ++ *transp = 0; ++ return 0; ++} ++ ++ ++ /* ++ * Set a single color register. The values supplied are already ++ * rounded down to the hardware's capabilities (according to the ++ * entries in the var structure). Return != 0 for invalid regno. ++ */ ++ ++static int mq200fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ++ u_int transp, struct fb_info *info) ++{ ++ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info; ++ unsigned long color; ++ ++ if (regno > 255) ++ return 1; ++ ++ /*PDEBUG("In mq200fb_setcolreg, regno = %d, 0x%0x\n", regno, red);*/ ++ ++ /*PDEBUG("mq200fb: mq200fb_setcolreg.\n");*/ ++ ++ switch (p->var.bits_per_pixel) { ++#ifdef CONFIG_FBCON_CFB16 ++ case 16: ++ if(regno < CMAPSIZE) ++#ifdef CONFIG_PREP ++ fbcon_cmap.cfb16[regno] = ++ ((red & 0xf800) >> 9) | ++ ((green & 0xf800) >> 14) | ++ ((green & 0xf800) << 2) | ((blue & 0xf800) >> 3); ++#else ++ fbcon_cmap.cfb16[regno] = ++ ((red & 0xf800) >> 0) | ++ ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11); ++ ++#endif /* CONFIG_PREP */ ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB24 ++ case 24: ++ if (regno < CMAPSIZE) ++#ifdef CONFIG_PREP ++ fbcon_cmap.cfb24[regno] = ++ ((red & 0xff00)) | ++ ((green & 0xff00) << 8) | ((blue & 0xff00) << 16); ++#else ++ fbcon_cmap.cfb24[regno] = ++ ((red & 0xff00) << 8) | ++ ((green & 0xff00)) | ((blue & 0xff00) >> 8); ++#endif ++ break; ++#endif ++#ifdef CONFIG_FBCON_CFB32 ++ case 32: ++ if(regno < CMAPSIZE) ++#ifdef CONFIG_PREP ++ fbcon_cmap.cfb32[regno] = ++ ((red & 0xff00)) | ++ ((green & 0xff00) << 8) | ((blue & 0xff00) << 16); ++#else ++ fbcon_cmap.cfb32[regno] = ++ ((red & 0xff00) >> 8) | ++ ((green & 0xff00)) | ((blue & 0xff00) << 8); ++#endif ++ ++ break; ++#endif ++ default: ++ break; ++ } ++ ++ red &= 0xFF; ++ green &= 0xFF; ++ blue &= 0xFF; ++ ++ p->palette[regno].red = red; ++ p->palette[regno].green = green; ++ p->palette[regno].blue = blue; ++ ++ color = red | (green << 8) | (blue << 16); ++ setpal(regno, color, (void *)p->mqMmioAddrVirt); ++ ++ return 0; ++} ++ ++ ++static void do_install_cmap(int con, struct fb_info *info) ++{ ++ if (con != currcon) ++ return; ++ ++ PDEBUG("mq200fb: do_install_cmap.\n"); ++ ++ if (fb_display[con].cmap.len) ++ fb_set_cmap(&fb_display[con].cmap, 1, mq200fb_setcolreg, info); ++ else { ++ int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16; ++ fb_set_cmap(fb_default_cmap(size), 1, mq200fb_setcolreg, info); ++ } ++} ++ ++ ++#ifdef MODULE ++int init_module(void) ++{ ++ return mq200fb_init(); ++} ++ ++void cleanup_module(void) ++{ ++ unregister_framebuffer(&(fb_info_mq200.fb_info)); ++ iounmap((void *)(fb_info_mq200.mqMmioAddrVirt)); ++ iounmap((void *)(fb_info_mq200.mqFbAddrVirt)); ++} ++ ++#endif /* MODULE */ ++ ++/* The following is copied from mq2hw.c for initialization of MQ200 */ ++ ++long idmqchip(void *pMQMMIO) ++{ ++ unsigned long id; ++ ++ id = READ32(PCI_VENDOR_DEVICE); ++ return (id); ++} ++ ++/* Setmode for MediaQ chip ++ * ++ */ ++void setmqmode(PDISPLAY_CONFIG pDC, void *pMQMMIO) ++{ ++ volatile unsigned long regdata, pmmisc; ++ int x=0, y=0, freq=0, paneltype; /* i is used as loop counter */ ++ unsigned long screensize, gc_startaddr; ++ ++ printk("mq200fb: setmqmode - before reset\n"); ++ regdata = SW_CHIP_RESET; ++ REG32(DC_0, regdata); ++ MQ_DELAY(10); ++ /* use 50MHz for LCD only and 83MHz if CRT is on */ ++ if (pDC->flag & CRT_ON) ++ regdata = PLL1_83MHZ; ++ else ++ regdata = PLL1_50MHZ; ++ REG32(DC_0, regdata); ++ MQ_DELAY(30); ++ ++ /* Enter D0 state from reset D3 state */ ++ ++ REG32(PCI_PM_CNTL_STATUS, ENTER_D0); ++ MQ_DELAY(30); ++ ++ while(1) ++ { ++ if((READ32(PCI_PM_CNTL_STATUS) & POWER_STATE_MASK) == 0x0) ++ break; ++ } ++ ++ /* In stable D3 state here ... */ ++ /* ++ * Set up PMU misc registers ++ * - also PMCLK_2048CYCLE and FP_PMCLK_128K if SA1110 ++ */ ++ if ((READ32(DC_1) & BUS_MODE_MASK) == BUS_MODE_SA1110) ++ regdata = GE_ENABLE|GE_BY_PLL1|PMCLK_2048CYCLE|FP_PMCLK_512; ++ else ++ /* the rest of CPUs */ ++ regdata = GE_ENABLE|GE_BY_PLL1; ++ REG32(PM_MISC, regdata); ++ ++ REG32(D1_STATE, DEF_D1); ++ REG32(D2_STATE, DEF_D2); ++ ++ /* To initialize MIU block ... */ ++ REG32(MIU_CONTROL1, DRAM_RESET_DISABLE); ++ MQ_DELAY(5); ++ ++ REG32(MIU_CONTROL1, 0x00); ++ MQ_DELAY(5); ++ ++ if (pDC->flag & CRT_ON) ++ regdata = DEF_MIU2_83MHZ; ++ else ++ regdata = DEF_MIU2_50MHZ; ++ REG32(MIU_CONTROL2, regdata); ++ REG32(MIU_CONTROL3, DEF_MIU3); ++ /* MIU REG 5 MUST BE PROGRAMMED BEFORE MIU REG 4 */ ++ REG32(MIU_CONTROL5, DEF_MIU5); ++ REG32(MIU_CONTROL4, DEF_MIU4); ++ MQ_DELAY(5); ++ ++ REG32(MIU_CONTROL1, MIU_ENABLE | MIU_RESET_DISABLE); ++ MQ_DELAY(5); ++ ++ /* Here, MIU is supposed to ready to serve ... */ ++ ++ gc_startaddr = 0; ++ /* Last 1KB is reserved for hardware cursor */ ++ if (mqflag & ENA_HW_CURSOR) ++ { ++ printk("mq200fb: enabling hardware cursor\n"); ++ setup_cursor(pMQMMIO); ++ enable_cursor(pMQMMIO); ++ ++ } ++ /* Set up GE Base Address */ ++ REG32(BASE_ADDRESS, gc_startaddr); ++ /* Set up flat panel parameters ++ * ++ */ ++ paneltype = pDC->flag & PANEL_TYPE_MASK; ++ if (paneltype) ++ { ++ /* Panel is used as a display in the system */ ++ setupfp(paneltype, pMQMMIO); ++ ++ /* Set up DSTN half frame buffer */ ++ screensize = pDC->x * pDC->y * pDC->bpp / 8 + gc_startaddr; ++ setuphfbuffer(paneltype, screensize, pMQMMIO); ++ ++ /* Get flat panel frequency */ ++ freq = fpControlData[paneltype].freq; ++ } ++ ++ /* Based on display configuration, proper GC is set up .. */ ++ if (pDC->flag & LARGE_DESKTOP) ++ { ++ switch (pDC->flag & LCDCRT_POS_MASK) ++ { ++ case HORI_CRT_LCD: ++ case HORI_LCD_CRT: ++ x = pDC->x / 2; ++ y = pDC->y; ++ break; ++ ++ case VERT_CRT_LCD: ++ case VERT_LCD_CRT: ++ x = pDC->x; ++ y = pDC->y / 2; ++ break; ++ } ++ } ++ else ++ { ++ /* SAME_IMAGE and simultaneous LCD and/or CRT */ ++ x = pDC->x; ++ y = pDC->y; ++ } ++ ++ /* Set up GC memory configuration */ ++ setupgcmem(pDC, gc_startaddr, pMQMMIO); ++ ++ pmmisc = READ32(PM_MISC); ++ ++ /* Set up 2 GCs */ ++ if (pDC->flag & USE_2GCs) ++ { ++ /* Set up GC1 for CRT */ ++ setupgc(IS_GC1, x, y, pDC->bpp, pDC->refresh, pMQMMIO); ++ ++ /* Set up GC2 for flat panel */ ++ setupgc(IS_GC2, x, y, pDC->bpp, freq, pMQMMIO); ++ ++ /* PLL2 and PLL3 are both used ... */ ++ /* to save a little bit power, can shut down PLL3 if both LCD ++ and CRT are the same frequency... ++ */ ++ pmmisc |= (PLL2_ENABLE | PLL3_ENABLE); ++ REG32(PM_MISC, pmmisc); ++ ++ /* Enable panel and CRT accordingly */ ++ if (pDC->flag & LCD_ON) ++ onoffdisplay(ENABLE_LCD_GC2, pMQMMIO); ++ ++ if (pDC->flag & CRT_ON) ++ onoffdisplay(ENABLE_CRT_GC1, pMQMMIO); ++ } ++ else ++ { ++ /* Simultaneous mode - set up GC1 only */ ++ if (paneltype) ++ setupgc(IS_GC1, x, y, pDC->bpp, freq, pMQMMIO); ++ else ++ setupgc(IS_GC1, x, y, pDC->bpp, pDC->refresh, pMQMMIO); ++ ++ /* Use PLL2 */ ++ pmmisc |= PLL2_ENABLE; ++ REG32(PM_MISC, pmmisc); ++ ++ /* Enable panel and CRT accordingly */ ++ if (pDC->flag & LCD_ON) ++ onoffdisplay(ENABLE_LCD_GC1, pMQMMIO); ++ ++ if (pDC->flag & CRT_ON) ++ onoffdisplay(ENABLE_CRT_GC1, pMQMMIO); ++ } ++} ++ ++/* Set up flat panel register depending on panel type ++ * ++ */ ++void setupfp(int panel, void *pMQMMIO) ++{ ++ PFPDATA_CONTROL pFP; ++ int frcaddr, frcidx, i; ++ ++ /* Locate panel data pointer */ ++ pFP = &fpControlData[panel]; ++ printk("FP_PIN_CONTROL set to %x\n", (u_int)pFP->fpPinControl); ++ REG32(FP_CONTROL, pFP->fpControl); ++ REG32(FP_PIN_CONTROL, pFP->fpPinControl); ++ REG32(STN_CONTROL, pFP->stnControl); ++ REG32(FP_GPO_CONTROL, DEF_GPO_CONTROL); ++ REG32(FP_GPIO_CONTROL, DEF_GPIO_CONTROL); ++ REG32(PWM_CONTROL, DEF_PWM_CONTROL); ++ ++ /* Program FRC registers for STN panel (DSTN and SSTN) */ ++ frcidx = 0; /* DSTN */ ++ if ( (pFP->fpControl & FP_TYPE_MASK) != FP_TYPE_TFT ) ++ { ++ if ((pFP->fpControl & FP_TYPE_MASK) == FP_TYPE_SSTN) ++ frcidx++; /* SSTN index */ ++ ++ for ( i = frcaddr = 0; i < FRC_PATTERN_CNT; i++,frcaddr+=4 ) ++ REG32((FRC_PATTERN + frcaddr), ++ FRCControlData[frcidx].frcPattern[i]); ++ ++ for ( i = frcaddr = 0; i < FRC_WEIGHT_CNT; i++,frcaddr+=4 ) ++ REG32((FRC_WEIGHT + frcaddr), FRCControlData[frcidx].frcWeight[i]); ++ } ++ ++ /* Set up flat panel GPO and GPIO register from default */ ++ REG32(FP_GPO_CONTROL, DEF_GPO_CONTROL); ++ REG32(FP_GPIO_CONTROL, DEF_GPIO_CONTROL); ++ ++ return; ++} ++ ++/* Set up DSTN half frame buffer register depending on panel type ++ * ++ * panel : panel type ++ * sizeused : used (occupied) area of frame buffer ++ * ++ */ ++void setuphfbuffer(int panel, unsigned long sizeused, void *pMQMMIO) ++{ ++ PFPDATA_CONTROL pFP; ++ unsigned long dstnfbsize, dstnstart, dstnend; ++ ++ /* Locate panel data pointer */ ++ pFP = &fpControlData[panel]; ++ ++ /* Figure out half frame buffer for DSTN panel */ ++ if ( (pFP->fpControl & FP_TYPE_MASK) == FP_TYPE_DSTN ) ++ { ++ /* Color D-STN memory requirement - no need to *3 for mono dstn panel */ ++ if (pFP->fpControl & FP_MONO) ++ dstnfbsize = pFP->x; ++ else ++ dstnfbsize = pFP->x * 3; ++ dstnfbsize = (((dstnfbsize + 127) >> 7) * pFP->y) << 3; ++ ++ /* make it suitable for register bits definition */ ++ dstnstart = (sizeused + 127) >> 7; ++ dstnend = (sizeused + dstnfbsize + 15) >> 4; ++ REG32(DSTN_FB_CONTROL, (dstnstart | ((dstnend - 1) << 16))); ++ } ++ return; ++} ++ ++/* Set up graphics controller (GC1 or GC2) timing registers and PLLx ++ * ++ * gc: GC1 or GC2 ++ * x : horizontal viewport size ++ * y : vertical viewport size ++ * refresh : refresh rate (mainly VESA-supported mode) ++ * ++ */ ++void setupgc(int gc, int x, int y, int bpp, int refresh, void *pMQMMIO) ++{ ++ PDISPLAY_TIMING pDT; ++ unsigned long gccontrol; ++ ++ /* Locate GC timing parameters first */ ++ pDT = getgcparam(x, y, refresh); ++ ++ /* error checking for pDT here */ ++ ++ gccontrol = getbppbits(bpp) | ++ FDx_1 | (1L << 24) | ++ IM_ENABLE; ++ ++ if (gc == IS_GC1) ++ { ++ /* Set up GC window as display */ ++ REG32(HW1_CONTROL, ((x - 1) << 16) | (1 << 28)); ++ REG32(VW1_CONTROL, ((y - 1) << 16)); ++ ++ REG32(HD1_CONTROL, pDT->hd); ++ REG32(VD1_CONTROL, pDT->vd); ++ REG32(HS1_CONTROL, pDT->hs); ++ REG32(VS1_CONTROL, pDT->vs); ++ REG32(VS1_CONTROL, pDT->vs); ++ REG32(GC1_CRT_CONTROL, pDT->crtc); ++ ++ /* Program PLL2 for GC1 */ ++ REG32(PLL2_CONTROL, pDT->pll); ++ ++ /* GC1 control register */ ++ gccontrol |= GxRCLK_PLL2; ++ REG32(GC1_CONTROL, gccontrol); ++ } ++ else ++ if (gc == IS_GC2) ++ { ++ /* Set up GC window as display */ ++ REG32(HW2_CONTROL, ((x - 1) << 16)); ++ REG32(VW2_CONTROL, ((y - 1) << 16)); ++ ++ REG32(HD2_CONTROL, pDT->hd); ++ REG32(VD2_CONTROL, pDT->vd); ++ REG32(HS2_CONTROL, pDT->hs); ++ REG32(VS2_CONTROL, pDT->vs); ++ REG32(VS2_CONTROL, pDT->vs); ++ REG32(GC1_CRT_CONTROL, pDT->crtc); ++ ++ /* Program PLL3 for GC2 */ ++ REG32(PLL3_CONTROL, pDT->pll); ++ ++ /* GC2 control register */ ++ gccontrol |= GxRCLK_PLL3; ++ REG32(GC2_CONTROL, gccontrol); ++ } ++ return; ++} ++ ++/* Set up graphics controller (GC1 or GC2) memory configuration (stride and ++ * starting address etc.) ++ * ++ * pDC : pointer to active DIPSLAY_CONFIG structure ++ * startaddr : starting address - 0 if starting from very beginning ++ * ++ * - use GC1 for Simultaneous mode (1 GC) ++ * - use GC1 for CRT and GC2 for LCD at QView mode ++ * ++ */ ++void setupgcmem(PDISPLAY_CONFIG pDC, unsigned long startaddr, void *pMQMMIO) ++{ ++ unsigned long stride=0, start1=0, start2=0; ++ ++ if (pDC->flag & LARGE_DESKTOP) ++ { ++ /* 4 possible layouts */ ++ switch (pDC->flag & LCDCRT_POS_MASK) ++ { ++ case HORI_CRT_LCD: ++ stride = (pDC->x / 2) * pDC->bpp / 8; ++ start1 = startaddr; ++ start2 = startaddr + stride; ++ break; ++ ++ case HORI_LCD_CRT: ++ stride = (pDC->x / 2) * pDC->bpp / 8; ++ start1 = startaddr + stride; ++ start2 = startaddr; ++ break; ++ ++ case VERT_CRT_LCD: ++ stride = pDC->x * pDC->bpp / 8; ++ start1 = startaddr; ++ start2 = startaddr + stride * pDC->y / 2; ++ break; ++ ++ case VERT_LCD_CRT: ++ stride = pDC->x * pDC->bpp / 8; ++ start1 = startaddr + stride * pDC->y / 2; ++ start2 = startaddr; ++ break; ++ } ++ ++ /* Program to the chip */ ++ REG32(IW1_STRIDE, stride); ++ REG32(IW2_STRIDE, stride); ++ ++ REG32(IW1_START_ADDR, start1); ++ REG32(IW2_START_ADDR, start2); ++ } ++ else ++ { ++ /* QView Same Image and Simultaneous LCD and/or CRT ++ * ++ * - set up 2 GCs in any cases ... ++ * - 2 addidtional registers write vs. code size ++ * ++ */ ++ ++ /* Calculate stride */ ++ stride = pDC->x * pDC->bpp / 8; ++ ++ REG32(IW1_STRIDE, stride); ++ REG32(IW2_STRIDE, stride); ++ ++ REG32(IW1_START_ADDR, startaddr); ++ REG32(IW2_START_ADDR, startaddr); ++ } ++ return; ++} ++ ++/* Program palette entry ++ * ++ */ ++void setpal(int index, unsigned long color, void *pMQMMIO) ++{ ++ /*PDEBUG("mq200fb: setpal. %d %d\n", index, color);*/ ++ ++ REG32_PAL(index, color); ++} ++ ++/* Vertical blank time is in progress .. ++ * ++ */ ++void invblank(void *pMQMMIO) ++{ ++ unsigned long *intstat = (unsigned long *)(pMQMMIO+INT_STATUS_REG); ++ ++ /* Make sure int occurs first */ ++ while ( !(*intstat & ST_GC1_VDE_F) ); ++ ++ /* Reset GC1 VDE F status bit - write 1 to clear the status */ ++ REG32(INT_STATUS_REG,ST_GC1_VDE_F); ++ ++ /* Wait for next VDE falling edge for DAC access */ ++ while ( !(*intstat & ST_GC1_VDE_F) ); ++ ++ /* Here MQ200 should be in V blank period ... */ ++ return; ++} ++ ++/* Retrive graphics controller parameters from supported table ++ * ++ */ ++PDISPLAY_TIMING getgcparam(int x, int y, int refresh) ++{ ++ int i; ++ ++ for (i=0; i < MAX_MQMODE; i++) ++ { ++ if ( TimingParam[i].x == x ++ && TimingParam[i].y == y ++ && TimingParam[i].refresh == refresh ) ++ return ( (PDISPLAY_TIMING)&TimingParam[i] ); ++ } ++ return (NULL); /* not existed */ ++} ++ ++/* Return color depth setting for GC ++ * ++ */ ++unsigned long getbppbits(int bpp) ++{ ++ unsigned long bppbits = 0; ++ ++ switch(bpp) ++ { ++ case 8UL: bppbits = GC_8BPP; break; ++ case 16UL: bppbits = GC_16BPP_BP; break; ++ case 24UL: bppbits = GC_24BPP_BP; break; ++ case 32UL: bppbits = GC_32BPP_ARGB_BP; break; ++ case 4UL: bppbits = GC_4BPP; break; ++ case 2UL: bppbits = GC_2BPP; break; ++ case 1UL: bppbits = GC_1BPP; break; ++ } ++ return (bppbits); ++} ++ ++/* Turn on/off LCD or CRT driven by either GC1 or GC2 ++ * ++ */ ++void onoffdisplay(int display_flag, void *pMQMMIO) ++{ ++ unsigned long fpcontrol, gccontrol, crtcontrol; ++ ++ switch (display_flag) ++ { ++ case ENABLE_LCD_GC1: ++ /* Obtain current setting */ ++ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK; ++ gccontrol = READ32(GC1_CONTROL); ++ ++ /* Turn on GC1 first if remain disabled */ ++ if (!(gccontrol & GC_ENABLE)) ++ REG32(GC1_CONTROL, gccontrol | GC_ENABLE); ++ ++ /* Flat panel controlled by GC1 */ ++ REG32(FP_CONTROL, fpcontrol | FPI_BY_GC1); ++ ++#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD) ++ mq200_backlight(pMQMMIO, 1); ++#endif ++ ++ break; ++ ++ case ENABLE_LCD_GC2: ++ /* Obtain current setting */ ++ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK; ++ gccontrol = READ32(GC2_CONTROL); ++ ++ /* Turn on GC1 first if remain disabled */ ++ if (!(gccontrol & GC_ENABLE)) ++ REG32(GC2_CONTROL, gccontrol | GC_ENABLE); ++ ++ /* Flat panel controlled by GC1 */ ++ REG32(FP_CONTROL, fpcontrol | FPI_BY_GC2); ++ break; ++ ++ case DISABLE_LCD_GC1: ++ /* Disable flat panel first */ ++ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK; ++ REG32(FP_CONTROL, fpcontrol); ++ ++ crtcontrol = READ32(GC1_CRT_CONTROL) & (~CRT_BY_GCxMASK); ++#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD) ++ mq200_backlight(pMQMMIO, 0); ++#endif ++ ++ /* Disable GC1 if not used for CRT */ ++ if (!(crtcontrol == CRT_BY_GC1)) ++ { ++ gccontrol = READ32(GC1_CONTROL); ++ REG32(GC1_CONTROL, gccontrol & GC_DISABLE); ++ } ++ break; ++ ++ case DISABLE_LCD_GC2: ++ /* Disable flat panel first */ ++ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK; ++ REG32(FP_CONTROL, fpcontrol); ++ ++ crtcontrol = READ32(GC1_CRT_CONTROL) & (~CRT_BY_GCxMASK); ++ ++ /* Disable GC2 if not used for CRT */ ++ if (!(crtcontrol == CRT_BY_GC2)) ++ { ++ gccontrol = READ32(GC2_CONTROL); ++ REG32(GC2_CONTROL, gccontrol & GC_DISABLE); ++ } ++ break; ++ ++ case ENABLE_CRT_GC1: ++ /* Enable GC1 if not yet enabled */ ++ gccontrol = READ32(GC1_CONTROL); ++ if (!(gccontrol & GC_ENABLE)) ++ REG32(GC1_CONTROL, gccontrol | GC_ENABLE); ++ ++ /* Enable CRT by GC1 */ ++ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK; ++ REG32(GC1_CRT_CONTROL, crtcontrol | CRT_BY_GC1); ++ break; ++ ++ case ENABLE_CRT_GC2: ++ /* Enable GC2 if not yet enabled */ ++ gccontrol = READ32(GC2_CONTROL); ++ if (!(gccontrol & GC_ENABLE)) ++ REG32(GC2_CONTROL, gccontrol | GC_ENABLE); ++ ++ /* Enable CRT by GC2 */ ++ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK; ++ REG32(GC1_CRT_CONTROL, crtcontrol | CRT_BY_GC2); ++ break; ++ ++ case DISABLE_CRT_GC1: ++ /* Disable CRT first */ ++ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK; ++ REG32(GC1_CRT_CONTROL, crtcontrol); ++ ++ fpcontrol = READ32(FP_CONTROL) & (~FPI_BY_GCxMASK); ++ ++ /* Disable GC1 if not used for CRT */ ++ if (!(crtcontrol == CRT_BY_GC1)) ++ { ++ gccontrol = READ32(GC1_CONTROL); ++ REG32(GC1_CONTROL, gccontrol & GC_DISABLE); ++ } ++ break; ++ ++ case DISABLE_CRT_GC2: ++ /* Disable CRT first */ ++ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK; ++ REG32(GC1_CRT_CONTROL, crtcontrol); ++ ++ fpcontrol = READ32(FP_CONTROL) & (~FPI_BY_GCxMASK); ++ ++ /* Disable GC2 if not used for CRT */ ++ if (!(crtcontrol == CRT_BY_GC2)) ++ { ++ gccontrol = READ32(GC2_CONTROL); ++ REG32(GC2_CONTROL, gccontrol & GC_DISABLE); ++ } ++ break; ++ } ++ return; ++} ++ ++/* Setup hardware cursor data area start address in the frame buffer ++ * ++ */ ++void setup_cursor(void *pMQMMIO) ++{ ++ REG32(HW_CURSOR1_FGCLR, CURSOR_FGCLR); ++ REG32(HW_CURSOR2_FGCLR, CURSOR_FGCLR); ++ REG32(HW_CURSOR1_BGCLR, CURSOR_BGCLR); ++ REG32(HW_CURSOR2_BGCLR, CURSOR_BGCLR); ++ REG32(HW_CURSOR1_ADDR, 0x000007ff); ++ REG32(HW_CURSOR2_ADDR, 0x000007ff); ++} ++ ++/* Move cursor position and adjust hot spot offset ++ * ++ */ ++void move_cursor(unsigned long pos, unsigned long addr, void *pMQMMIO) ++{ ++ REG32(HW_CURSOR1_POS, pos); ++ REG32(HW_CURSOR2_POS, pos); ++} ++ ++/* Enable hardware cursor ++ * ++ */ ++void enable_cursor(void *pMQMMIO) ++{ ++ u32 temp; ++ ++ temp = READ32(GC1_CONTROL) | HC_ENABLE; ++ REG32(GC1_CONTROL, temp); ++ if (mqflag & USE_2GCs) ++ { ++ temp = READ32(GC2_CONTROL) | HC_ENABLE; ++ REG32(GC2_CONTROL, temp); ++ } ++} ++ ++/* Disable hardware cursor ++ * ++ */ ++void disable_cursor(void *pMQMMIO) ++{ ++ u32 temp; ++ ++ temp = READ32(GC1_CONTROL) & HC_DISABLE; ++ REG32(GC1_CONTROL, temp); ++ if (mqflag & USE_2GCs) ++ { ++ temp = READ32(GC2_CONTROL) & HC_DISABLE; ++ REG32(GC2_CONTROL, temp); ++ } ++} ++/* The above is copied from mq2hw.c for initialization of MQ200 */ ++ ++void turnoffMQ200(void * pMQMMIO) ++{ ++ volatile u32 temp; ++ ++ temp = READ32(FP_CONTROL); ++ temp &=0xfffffffc; ++ REG32(FP_CONTROL, temp); ++ udelay(5000); ++ temp =READ32(FP_CONTROL) & 0x3; ++ if(temp != 0) ++ PDEBUG("FP_CONTROL is not cleared properly"); ++ else ++ PDEBUG("FP_CONTROL is cleared properly"); ++ ++ temp = READ32(FP_PIN_CONTROL); ++ temp |= 0x1; ++ REG32(FP_PIN_CONTROL, temp); ++ udelay(5000); ++ ++ temp = READ32(GC1_CONTROL); ++ temp &=0xfffffffe; ++ REG32(GC1_CONTROL, temp); ++ udelay(5000); ++ temp = READ32(GC1_CONTROL) & 0x1; ++ if(temp != 0) ++ PDEBUG("GC1_CONTROL is not cleared properly"); ++ else ++ PDEBUG("GC1_CONTROL is cleared properly"); ++ ++ temp = READ32(GC1_CRT_CONTROL); ++ temp &=0xfffffffe; ++ REG32(GC1_CRT_CONTROL, temp); ++ udelay(5000); ++ ++ temp = READ32(GC2_CONTROL); ++ temp &=0xfffffffe; ++ REG32(GC2_CONTROL, temp); ++ udelay(5000); ++ temp = READ32(GC2_CONTROL) & 0x1; ++ if(temp != 0) ++ PDEBUG("GC2_CONTROL is not cleared properly"); ++ else ++ PDEBUG("GC2_CONTROL is cleared properly"); ++ ++ return; ++} ++ ++#ifdef CONFIG_PM ++/* ++ * Power management hook. Note that we won't be called from IRQ context, ++ * unlike the blank functions above, so we may sleep. ++ */ ++static int ++mq200fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) ++{ ++ struct fb_info_mq200 *p = (struct fb_info_mq200 *) pm_dev->data; ++ void * pMQMMIO = (void *) p->mqMmioAddrVirt; ++ ++ if (req == PM_SUSPEND){ ++ ++ onoffdisplay(DISABLE_LCD_GC1, pMQMMIO); ++ REG32(PCI_PM_CNTL_STATUS, ENTER_D3); ++ MQ_DELAY(30); ++ } ++ if( req == PM_RESUME){ ++ setmqmode(&dc, pMQMMIO); ++ onoffdisplay(ENABLE_LCD_GC1, pMQMMIO); ++ REG32(PCI_PM_CNTL_STATUS, ENTER_D0); ++ MQ_DELAY(30); ++ } ++ ++ return 0; ++} ++#endif ++ ++#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD) ++ ++static void mq200_backlight(void *pMQMMIO, int flag) ++{ ++ ++#ifdef CONFIG_SA1100_GDS2200 ++ unsigned long gpiocontrol, data; ++ int i; ++ ++ gpiocontrol = READ32(FP_GPIO_CONTROL) & 0x3f; ++ data = (flag ? GPIO2_OUT_HIGH : 0); ++ for(i = 0 ; i < 128 ; i++) { ++ REG32(FP_GPIO_CONTROL, gpiocontrol | data); ++ MQ_DELAY(1); ++ REG32(FP_GPIO_CONTROL, gpiocontrol | GPIO1_OUT_HIGH | data); ++ MQ_DELAY(1); ++ REG32(FP_GPIO_CONTROL, gpiocontrol); ++ MQ_DELAY(1); ++ } ++ ++#endif /* CONFIG_SA1100_GDS2200 */ ++ ++#ifdef CONFIG_SA1100_SIMPAD ++ ++ if(flag) ++ set_cs3_bit(DISPLAY_ON); ++ else ++ clear_cs3_bit(DISPLAY_ON); ++ ++#endif /* CONFIG_SA1100_SIMPAD */ ++ ++} ++#endif /* CONFIG_SA1100_GDS2200 || CONFIG_SA1100_SIMPAD */ ++ ++#ifdef CONFIG_SA1100_SIMPAD ++ ++static void writeBrightness(void *pMQMMIO, int brightness) ++{ ++ unsigned long dutyCycle, pwmcontrol; ++ int MAX_BRIGHT_REG = 0x000000fc; /* int 254 */ ++ ++ if(brightness > MAX_BRIGHT_REG) ++ return; ++ else ++ { ++ /* ++ *Determine dutyCycle. ++ *Note: the lower the value, the brighter the display! ++ */ ++ ++ dutyCycle = MAX_BRIGHT_REG - brightness; ++ ++ /* ++ *Configure PWM0 (source clock = oscillator clock, pwm always enabled, ++ *zero, clock pre-divider = 4) pwm frequency = 12.0kHz ++ */ ++ pwmcontrol = READ32(PWM_CONTROL); ++ REG32(PWM_CONTROL, 0x00000044 | (pwmcontrol & 0xffffff00)); ++ ++ ++ /* Write to pwm duty cycle register. */ ++ ++ REG32(PWM_CONTROL, ((dutyCycle << 8) & 0x0000ff00) | ++ (pwmcontrol & 0xffff00ff)); ++ } ++} ++ ++#endif /* CONFIG_SA1100_SIMPAD */ ++ ++static int proc_read_reg(struct file * file, char * buf, ++ size_t nbytes, loff_t *ppos) ++{ ++ int i_ino = (file->f_dentry->d_inode)->i_ino; ++ char outputbuf[15]; ++ int count; ++ int i; ++ mq200_reg_entry_t* current_reg=NULL; ++ if (*ppos>0) /* Assume reading completed in previous read*/ ++ return 0; ++ for (i=0;i<NUM_OF_MQ200_REG_ENTRY;i++) { ++ if (mq200_regs[i].low_ino==i_ino) { ++ current_reg = &mq200_regs[i]; ++ break; ++ } ++ } ++ if (current_reg==NULL) ++ return -EINVAL; ++ ++ count = sprintf(outputbuf, "0x%08X\n", ++ *((volatile *) mq200_p2v(current_reg->phyaddr))); ++ *ppos+=count; ++ if (count>nbytes) /* Assume output can be read at one time */ ++ return -EINVAL; ++ if (copy_to_user(buf, outputbuf, count)) ++ return -EFAULT; ++ return count; ++} ++ ++static ssize_t proc_write_reg(struct file * file, const char * buffer, ++ size_t count, loff_t *ppos) ++{ ++ int i_ino = (file->f_dentry->d_inode)->i_ino; ++ mq200_reg_entry_t* current_reg=NULL; ++ int i; ++ unsigned long newRegValue; ++ char *endp; ++ ++ for (i=0;i<NUM_OF_MQ200_REG_ENTRY;i++) { ++ if (mq200_regs[i].low_ino==i_ino) { ++ current_reg = &mq200_regs[i]; ++ break; ++ } ++ } ++ if (current_reg==NULL) ++ return -EINVAL; ++ ++ newRegValue = simple_strtoul(buffer,&endp,0); ++ *((volatile *) mq200_p2v(current_reg->phyaddr))=newRegValue; ++ return (count+endp-buffer); ++} ++ +--- linux-2.4.25/include/asm-arm/arch-sa1100/simpad.h~2.4.25-vrs2-pxa1-jpm1.patch 2002-08-03 02:39:45.000000000 +0200 ++++ linux-2.4.25/include/asm-arm/arch-sa1100/simpad.h 2004-05-02 22:45:42.000000000 +0200 +@@ -28,6 +28,7 @@ + #define GPIO_UART3_DCD GPIO_GPIO18 + #define GPIO_UART3_DSR GPIO_GPIO17 + ++#define GPIO_POWER_BUTTON GPIO_GPIO0 + #define GPIO_UCB1300_IRQ GPIO_GPIO (22) /* UCB GPIO and touchscreen */ + + #define IRQ_UART1_CTS IRQ_GPIO15 +@@ -37,7 +38,12 @@ + #define IRQ_UART3_DCD GPIO_GPIO18 + #define IRQ_UART3_DSR GPIO_GPIO17 + +-#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22 ++#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22 ++#define IRQ_GPIO_POWER_BUTTON IRQ_GPIO0 ++ ++/*--- SmartCard ---*/ ++#define GPIO_SMART_CARD GPIO_GPIO10 ++#define IRQ_GPIO_SMART_CARD IRQ_GPIO10 + + /*--- PCMCIA ---*/ + #define GPIO_CF_CD GPIO_GPIO24 +@@ -65,7 +71,7 @@ + #define LED2_ON 0x1000 + #define IRDA_MODE 0x2000 // Fast/Slow IrDA mode + #define ENABLE_5V 0x4000 // Enable 5V circuit +-#define RESET_SIMCARD 0x8000 ++#define nRESET_SIMCARD 0x8000 + + #define RS232_ENABLE 0x0440 + #define PCMCIAMASK 0x402f +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/asm-arm/arch-sa1100/simpad_pm.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,236 @@ ++/* ++* Abstraction interface for microcontroller connection to rest of system ++* ++* Copyright 2003 Peter Pregler ++* Copyright 2000,1 Compaq Computer Corporation. ++* ++* Use consistent with the GNU GPL is permitted, ++* provided that this copyright notice is ++* preserved in its entirety in all copies and derived works. ++* ++* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, ++* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS ++* FITNESS FOR ANY PARTICULAR PURPOSE. ++* ++* Author: Peter Pregler (based on work for ipaq by Andrew Christian) ++* ++*/ ++ ++#ifndef __SIMPAD_HAL_H ++#define __SIMPAD_HAL_H ++ ++extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status, ++ unsigned char *battery_flag, unsigned char *battery_percentage, ++ unsigned short *battery_life); ++ ++ ++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 */ ++}; ++ ++extern int simpad_get_battery(struct simpad_battery *bstat); ++ ++/* 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 ++ ++#if FIXME ++#include <linux/simpad_ts.h> ++ ++enum simpad_asset_type { ++ ASSET_TCHAR = 0, ++ ASSET_SHORT, ++ ASSET_LONG ++}; ++ ++#define TTYPE(_type) (((unsigned int)_type) << 8) ++#define TCHAR(_len) (TTYPE(ASSET_TCHAR) | (_len)) ++#define TSHORT TTYPE(ASSET_SHORT) ++#define TLONG TTYPE(ASSET_LONG) ++#define ASSET(_type,_num) ((((unsigned int)_type)<<16) | (_num)) ++ ++#define ASSET_HM_VERSION ASSET( TCHAR(10), 0 ) /* 1.1, 1.2 */ ++#define ASSET_SERIAL_NUMBER ASSET( TCHAR(40), 1 ) /* Unique iPAQ serial number */ ++#define ASSET_MODULE_ID ASSET( TCHAR(20), 2 ) /* E.g., "iPAQ 3700" */ ++#define ASSET_PRODUCT_REVISION ASSET( TCHAR(10), 3 ) /* 1.0, 2.0 */ ++#define ASSET_PRODUCT_ID ASSET( TSHORT, 4 ) /* 2 = Palm-sized computer */ ++#define ASSET_FRAME_RATE ASSET( TSHORT, 5 ) ++#define ASSET_PAGE_MODE ASSET( TSHORT, 6 ) /* 0 = Flash memory */ ++#define ASSET_COUNTRY_ID ASSET( TSHORT, 7 ) /* 0 = USA */ ++#define ASSET_IS_COLOR_DISPLAY ASSET( TSHORT, 8 ) /* Boolean, 1 = yes */ ++#define ASSET_ROM_SIZE ASSET( TSHORT, 9 ) /* 16, 32 */ ++#define ASSET_RAM_SIZE ASSET( TSHORT, 10 ) /* 32768 */ ++#define ASSET_HORIZONTAL_PIXELS ASSET( TSHORT, 11 ) /* 240 */ ++#define ASSET_VERTICAL_PIXELS ASSET( TSHORT, 12 ) /* 320 */ ++ ++#define ASSET_TYPE(_asset) (((_asset)&0xff000000)>>24) ++#define ASSET_TCHAR_LEN(_asset) (((_asset)&0x00ff0000)>>16) ++#define ASSET_NUMBER(_asset) ((_asset)&0x0000ffff) ++ ++#define MAX_TCHAR_LEN 40 ++ ++struct simpad_asset { ++ unsigned int type; ++ union { ++ unsigned char tchar[ MAX_TCHAR_LEN ]; ++ unsigned short vshort; ++ unsigned long vlong; ++ } a; ++}; ++ ++/******************************************************************** ++ * Interface to the hardware-type specific functions ++ * ++ * get_version Read the version number of the microcontroller on the option pack SPI bus ++ * spi_read Reads from the serial EEPROM memory on the option pack SPI bus ++ * spi_write Write to the serial EEPROM memory on the option pack SPI bus ++ * get_option_detect Returns whether or not an option pack is present ++ * ++ * get_thermal_sensor Return measured temperature of the unit, in units of 0.125 deg C ++ * set_notify_led Turns on, off, or blinks the Green LED ++ * read_light_sensor Returns the value of the front light sensor ++ * get_battery Returns the current voltage and charging state of all batteries ++ * audio_clock Sets the audio CODEC to run at a particular rate ++ * audio_power Turns on/off audio CODEC (internally calls audio_clock) ++ * audio_mute Mutes the audio CODEC ++ * asset_read Extracts PocketPC-style asset information from persistent memory ++ * backlight_control Adjusts the backlight level (only on/off for 3100) ++ * ++ * ++ * iPAQ 3100 only ++ * ============== ++ * codec_control Reset/mute/control level of 3100 audio codec ++ * contrast_control Adjusts the contrast level (only for 3100) ++ * ++ * iPAQ 3600, 3700 only ++ * ==================== ++ * eeprom_read Reads from the asset information on the eeprom of a 3600 (deprecated) ++ * eeprom_write Writes to the asset information on the eeprom (deprecated) ++ * ++ * The interfaces to the EEPROM functions are maintained only because the simpad_ts driver has ++ * a deprecated ioctl call for them. They are used internally by the "asset_read" function. ++ * ++ * iPAQ 3800, 3900 only ++ * ==================== ++ * set_ebat Tells enhanced PCMCIA sleeves that this iPAQ can handle ++ * a wider voltage range (applies to 3800, 3900) ++ * ++ *********************************************************************/ ++ ++struct simpad_hal_ops { ++ /* Functions provided by the underlying hardware */ ++ int (*get_version)( struct simpad_ts_version * ); ++ int (*eeprom_read)( unsigned short address, unsigned char *data, unsigned short len ); ++ int (*eeprom_write)( unsigned short address, unsigned char *data, unsigned short len ); ++ int (*get_thermal_sensor)( unsigned short * ); ++ int (*set_notify_led)( unsigned char mode, unsigned char duration, ++ unsigned char ontime, unsigned char offtime ); ++ int (*read_light_sensor)( unsigned char *result ); ++ int (*get_battery)( struct simpad_battery * ); ++ int (*spi_read)( unsigned short address, unsigned char *data, unsigned short len ); ++ int (*spi_write)( unsigned short address, unsigned char *data, unsigned short len ); ++ int (*codec_control)( unsigned char, unsigned char ); ++ int (*get_option_detect)( int *result ); ++ int (*audio_clock)( long samplerate ); ++ int (*audio_power)( long samplerate ); ++ int (*audio_mute)( int mute ); ++ int (*asset_read)( struct simpad_asset *asset ); ++ int (*set_ebat)( void ); ++ ++ /* Functions indirectly provided by the underlying hardware */ ++ int (*backlight_control)( enum flite_pwr power, unsigned char level ); ++ int (*contrast_control)( unsigned char level ); ++ ++ /* for module use counting */ ++ struct module *owner; ++}; ++ ++/* Used by the device-specific hardware module to register itself */ ++extern int simpad_hal_register_interface( struct simpad_hal_ops *ops ); ++extern void simpad_hal_unregister_interface( struct simpad_hal_ops *ops ); ++ ++/* ++ * Calls into HAL from the device-specific hardware module ++ * These run at interrupt time ++ */ ++extern void simpad_hal_keypress( unsigned char key ); ++extern void simpad_hal_touchpanel( unsigned short x, unsigned short y, int down ); ++extern void simpad_hal_option_detect( int present ); ++ ++/* Callbacks registered by device drivers */ ++struct simpad_driver_ops { ++ void (*keypress)( unsigned char key ); ++ void (*touchpanel)( unsigned short x, unsigned short y, int down ); ++ void (*option_detect)( int present ); ++}; ++ ++extern int simpad_hal_register_driver( struct simpad_driver_ops * ); ++extern void simpad_hal_unregister_driver( struct simpad_driver_ops * ); ++ ++ ++/* Calls into HAL from device drivers and other kernel modules */ ++extern void simpad_get_flite( struct simpad_ts_backlight *bl ); ++extern void simpad_get_contrast( unsigned char *contrast ); ++extern int simpad_set_flite( enum flite_pwr pwr, unsigned char brightness ); ++extern int simpad_set_contrast( unsigned char contrast ); ++extern int simpad_toggle_frontlight( void ); ++ ++extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status, ++ unsigned char *battery_flag, unsigned char *battery_percentage, ++ unsigned short *battery_life); ++ ++extern struct simpad_hal_ops *simpad_hal_ops; ++ ++/* Do not use this macro in driver files - instead, use the inline functions defined below */ ++#define CALL_HAL( f, args... ) \ ++ { int __result = -EIO; \ ++ if ( simpad_hal_ops && simpad_hal_ops->f ) { \ ++ __MOD_INC_USE_COUNT(simpad_hal_ops->owner); \ ++ __result = simpad_hal_ops->f(args); \ ++ __MOD_DEC_USE_COUNT(simpad_hal_ops->owner); \ ++ } \ ++ return __result; } ++ ++#define HFUNC static __inline__ int ++ ++/* The eeprom_read/write address + len has a maximum value of 512. Both must be even numbers */ ++HFUNC simpad_eeprom_read( u16 addr, u8 *data, u16 len ) CALL_HAL(eeprom_read,addr,data,len) ++HFUNC simpad_eeprom_write( u16 addr, u8 *data, u16 len) CALL_HAL(eeprom_write,addr,data,len) ++HFUNC simpad_spi_read( u8 addr, u8 *data, u16 len) CALL_HAL(spi_read,addr,data,len) ++HFUNC simpad_spi_write( u8 addr, u8 *data, u16 len) CALL_HAL(spi_write,addr,data,len) ++HFUNC simpad_get_version( struct simpad_ts_version *v ) CALL_HAL(get_version,v) ++HFUNC simpad_get_thermal_sensor( u16 *thermal ) CALL_HAL(get_thermal_sensor,thermal) ++HFUNC simpad_set_led( u8 mode, u8 dur, u8 ont, u8 offt ) CALL_HAL(set_notify_led, mode, dur, ont, offt) ++HFUNC simpad_get_light_sensor( u8 *result ) CALL_HAL(read_light_sensor,result) ++HFUNC simpad_get_battery( struct simpad_battery *bat ) CALL_HAL(get_battery,bat) ++HFUNC simpad_get_option_detect( int *result) CALL_HAL(get_option_detect,result) ++HFUNC simpad_audio_clock( long samplerate ) CALL_HAL(audio_clock,samplerate) ++HFUNC simpad_audio_power( long samplerate ) CALL_HAL(audio_power,samplerate) ++HFUNC simpad_audio_mute( int mute ) CALL_HAL(audio_mute,mute) ++HFUNC simpad_asset_read( struct simpad_asset *asset ) CALL_HAL(asset_read,asset) ++HFUNC simpad_set_ebat( void ) CALL_HAL(set_ebat) ++ ++/* Don't use these functions directly - rather, call {get,set}_{flite,contrast} */ ++ /* Functions indirectly provided by the underlying hardware */ ++HFUNC simpad_backlight_control( enum flite_pwr p, u8 v ) CALL_HAL(backlight_control,p,v) ++HFUNC simpad_contrast_control( u8 level ) CALL_HAL(contrast_control,level) ++ ++#endif ++#endif +--- linux-2.4.25/include/linux/apm_bios.h~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:44.000000000 +0200 ++++ linux-2.4.25/include/linux/apm_bios.h 2004-05-02 22:45:42.000000000 +0200 +@@ -216,4 +216,19 @@ + #define APM_IOC_STANDBY _IO('A', 1) + #define APM_IOC_SUSPEND _IO('A', 2) + ++#define APM_AC_OFFLINE 0 ++#define APM_AC_ONLINE 1 ++#define APM_AC_BACKUP 2 ++#define APM_AC_UNKNOWN 0xFF ++ ++#define APM_BATTERY_STATUS_HIGH 0 ++#define APM_BATTERY_STATUS_LOW 1 ++#define APM_BATTERY_STATUS_CRITICAL 2 ++#define APM_BATTERY_STATUS_CHARGING 3 ++#define APM_BATTERY_STATUS_UNKNOWN 0xFF ++ ++#define APM_BATTERY_LIFE_UNKNOWN 0xFFFF ++#define APM_BATTERY_LIFE_MINUTES 0x8000 ++#define APM_BATTERY_LIFE_VALUE_MASK 0x7FFF ++ + #endif /* LINUX_APM_H */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/linux/switches.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,74 @@ ++/* ++ * linux/include/linux/switches.h ++ * ++ * Copyright (C) 2000 John Dorsey ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 23 October 2000 - created. ++ */ ++ ++#if !defined(_LINUX_SWITCHES_H) ++#define _LINUX_SWITCHES_H ++ ++#define SWITCHES_MASK_SIZE (128) ++ ++typedef unsigned long switches_bitfield; ++ ++#define SWITCHES_BITS (sizeof(switches_bitfield) * 8) ++#define SWITCHES_NUM_FIELDS (SWITCHES_MASK_SIZE / SWITCHES_BITS) ++#define SWITCHES_FIELD_SELECT(i) ((i) / SWITCHES_BITS) ++#define SWITCHES_FIELD_MASK(i) ((switches_bitfield)(1 << (i) % \ ++ SWITCHES_BITS)) ++ ++typedef struct switches_mask_t { ++ unsigned int count; ++ switches_bitfield events[SWITCHES_NUM_FIELDS]; ++ switches_bitfield states[SWITCHES_NUM_FIELDS]; ++} switches_mask_t; ++ ++#define SWITCHES_ZERO(m) \ ++do { \ ++ unsigned int sz_i; \ ++ (m)->count = 0; \ ++ for(sz_i = 0; sz_i < SWITCHES_NUM_FIELDS; ++sz_i) \ ++ (m)->events[sz_i] = (m)->states[sz_i] = 0; \ ++} while (0) ++ ++/* `s' is the state of the switch, either 0 or non-zero: */ ++#define SWITCHES_SET(m, i, s) \ ++do { \ ++ ((m)->events[SWITCHES_FIELD_SELECT((i))] |= \ ++ SWITCHES_FIELD_MASK((i))); \ ++ if(s) \ ++ ((m)->states[SWITCHES_FIELD_SELECT((i))] |= \ ++ SWITCHES_FIELD_MASK((i))); \ ++ else \ ++ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \ ++ ~SWITCHES_FIELD_MASK((i))); \ ++ ++((m)->count); \ ++} while (0) ++ ++/* Should only use to clear an event set by SWITCHES_SET(): */ ++#define SWITCHES_CLEAR(m, i) \ ++do { \ ++ ((m)->events[SWITCHES_FIELD_SELECT((i))] &= \ ++ ~SWITCHES_FIELD_MASK((i))); \ ++ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \ ++ ~SWITCHES_FIELD_MASK((i))); \ ++ --((m)->count); \ ++} ++ ++#define SWITCHES_COUNT(m) ((m)->count) ++ ++/* Returns 0 or non-zero: */ ++#define SWITCHES_EVENT(m, i) \ ++((m)->events[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i))) ++ ++/* Returns 0 or non-zero: */ ++#define SWITCHES_STATE(m, i) \ ++((m)->states[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i))) ++ ++#endif /* !defined(_LINUX_SWITCHES_H) */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/video/MQ200/mq2ge.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,81 @@ ++#ifndef _VIDEO_MQ200_MQ2GE_H ++#define _VIDEO_MQ200_MQ2GE_H ++ ++ ++/* Misc. GE Function Macro */ ++#undef CHECK_SRCFIFO ++#define RGB_RASTER_CHECK ++#define INCLUDE_GENERIC_CODE ++ ++#ifdef CHECK_SRCFIFO ++#define geWAITSRCFIFO(cnt) geWaitSrcFIFO(cnt) ++#define geWAITCMDFIFO(cnt) geWaitCmdFIFO(cnt) ++#define geWAITNOTBUSY() geWaitNotBusy() ++#else ++#define geWAITSRCFIFO(cnt) ++#define geWAITCMDFIFO(cnt) ++#define geWAITNOTBUSY() ++#endif ++ ++/* Additional UGL Raster Ops */ ++#define UGL_RASTER_OP_NOP 0x00000000L ++ ++#define UGL_RASTER_OP_BLACKNESS 0x00000001L ++#define UGL_RASTER_OP_BSRC_BLACK 0x00000002L ++#define UGL_RASTER_OP_BSRC_OCOPY 0x00000003L ++#define UGL_RASTER_OP_BSRC_XCOPY 0x00000004L ++ ++#define UGL_RASTER_OP_WHITENESS 0x00010001L ++#define UGL_RASTER_OP_WSRC_COPY 0x00010002L ++#define UGL_RASTER_OP_WSRC_WHITE 0x00010003L ++#define UGL_RASTER_OP_WSRC_INVERT 0x00010004L ++ ++#define UGL_RASTER_OP_SRC_COPY 0x00020001L ++#define UGL_RASTER_OP_SRCDEST_AND 0x00020002L ++#define UGL_RASTER_OP_SRCDEST_OR 0x00020003L ++#define UGL_RASTER_OP_SRCDEST_XOR 0x00020004L ++ ++#define UGL_RASTER_OP_DEST_COPY 0x00030001L ++#define UGL_RASTER_OP_DESTSRC_AND 0x00030002L ++#define UGL_RASTER_OP_DESTSRC_OR 0x00030003L ++#define UGL_RASTER_OP_DESTSRC_XOR 0x00030004L ++ ++/* MediaQ Raster Ops */ ++#define MQ200_SOURCE_ROP 0x01 ++#define MQ200_PATTERN_ROP 0x02 ++#define MQ200_GE_NOP 0x000000AAL ++#define MQ200_GE_BLACKNESS 0x00000000L ++#define MQ200_GE_WHITENESS 0x000000FFL ++#define MQ200_GE_SRC_INVERT 0x00000033L ++#define MQ200_GE_SRC_COPY 0x000000CCL ++#define MQ200_GE_SRCDEST_XOR 0x00000066L ++#define MQ200_GE_SRCDEST_AND 0x00000088L ++#define MQ200_GE_SRCDEST_OR 0x000000EEL ++#define MQ200_GE_PATTERN_INVERT 0x0000000FL ++#define MQ200_GE_PATTERN_COPY 0x000000F0L ++#define MQ200_GE_PATDEST_XOR 0x0000005AL ++#define MQ200_GE_PATDEST_AND 0x000000A0L ++#define MQ200_GE_PATDEST_OR 0x000000FAL ++/* MediaQ Raster Ops mapping table */ ++#define UGL_NR_OPERAND 4 ++#define UGL_NR_OPERATION 5 ++ ++#define geREG_2( idx1, val1, idx2, val2 ) \ ++ geREG( idx2, val2 ); \ ++ geREG( idx1, val1 ) ++#define geREG_3( idx1, val1, idx2, val2, idx3, val3 ) \ ++ geREG_2( idx2, val2, idx3, val3 ); \ ++ geREG( idx1, val1 ) ++#define geREG_4( idx1, val1, idx2, val2, idx3, val3, idx4, val4 ) \ ++ geREG_3( idx2, val2, idx3, val3, idx4, val4 ); \ ++ geREG( idx1, val1 ) ++#define geREG_5( idx1, val1, idx2, val2, idx3, val3, idx4, val4, idx5, val5 ) \ ++ geREG_4( idx2, val2, idx3, val3, idx4, val4, idx5, val5 ); \ ++ geREG( idx1, val1 ) ++ ++/* Declare MQ200 GE Utility Functions */ ++void geWaitNotBusy(void); ++void geWaitCmdFIFO(u32 cnt); ++void geWaitSrcFIFO(u32 cnt); ++ ++#endif /* _VIDEO_MQ200_MQ2GE_H */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/video/MQ200/mq2hw.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,879 @@ ++/*************************************************************************** ++ MQ200HW.H ++ ++ MQ200 chip definition file ++ ++ Copyright (c) 2000 by MediaQ, Incorporated. ++ All Rights Reserved. ++ ++***************************************************************************/ ++#ifndef _VIDEO_MQ200_MQ2HW_H ++#define _VIDEO_MQ200_MQ2HW_H ++ ++#define MQ200_VENDOR_ID 0x4D51 ++#define MQ200_DEVICE_ID 0x0200 ++#define MQ200_ID 0x02004D51 ++#define PM_ID_CAP 0x06210001 /* Power management ID/capability */ ++ ++/* Revision ID */ ++#define MQ200_REV_0X 0x00 ++#define MQ200_REV_1A 0x01 ++#define MQ200_REV_1B1C 0x11 ++#define MQ200_REV_1D 0x10 ++ ++/* Some useful defines */ ++#ifndef ULONG ++#define ULONG unsigned long ++#endif ++#ifndef USHORT ++#define USHORT unsigned short ++#endif ++#ifndef BYTE ++#define BYTE unsigned char ++#endif ++ ++/* To access MediaQ memory-mapped IO register (32bit in size) */ ++#define REG32(addr,val) (*(volatile ULONG *)((ULONG)pMQMMIO+addr)=(val)) ++#define READ32(addr) (*((volatile ULONG *)((ULONG)pMQMMIO+addr))) ++#define geREG(addr,val) (*(volatile ULONG *)(mqMmioAddr+addr)=(val)) ++#define geREAD(addr) (*((volatile ULONG *)(mqMmioAddr+addr))) ++#define gcREG(addr,val) geREG(addr,val) ++#define gcREAD(addr) geREAD(addr) ++#define cpuREG(addr,val) geREG(addr,val) ++#define cpuREAD(addr) geREAD(addr) ++#define pmuREG(addr,val) geREG(addr,val) ++#define pmuREAD(addr) geREAD(addr) ++#define pciREG(addr,val) geREG(addr,val) ++#define pciREAD(addr) geREAD(addr) ++ ++/* To access MediaQ DAC - index-based */ ++#define REG32_PAL(idx,val) (*(ULONG *)((ULONG)pMQMMIO+C1_BASE+idx*4)=(val)) ++#define READ32_PAL(idx) (*(ULONG *)((ULONG)pMQMMIO+C1_BASE+idx*4)) ++ ++/* MQ200 module offset */ ++#define PM_BASE (0) /* Power Management + Clk Gen */ ++#define CC_BASE (0x2000) /* CPU interface */ ++#define MM_BASE (0x4000) /* Memory Controller (m1/m2) */ ++#define VI_BASE (0x6000) /* Video-in controller */ ++#define IN_BASE (0x8000) /* Interrupt controller */ ++#define GC_BASE (0xA000) /* Graphics Controller 1/2 */ ++#define GE_BASE (0xC000) /* Graphics engine */ ++#define GE2_BASE (0xC200) /* Graphics engine (GE2) */ ++#define FP_BASE (0xE000) /* Flat panel interface */ ++#define C1_BASE (0x10000) /* Color palette 1 */ ++#define C2_BASE (0x12000) /* Color palette 2 */ ++#define DC_BASE (0x14000) /* Device Configuration Space */ ++#define PC_BASE (0x16000) /* PCI Configuration Header */ ++#define PSF_BASE (0x18000) /* Primary Source FIFO Space */ ++#define SSF_BASE (0x1A000) /* Secondary Source FIFO Space */ ++ ++#define MQ200_MMIO_SIZE (0x1C0000L) ++#define MQ200_FB_SIZE (0x200000L) /* 2MB memory */ ++#define GC_OFFSET (0x80) ++ ++/* Interrupt Controller */ ++#define INT_CONTROL_REG (IN_BASE + 0x00) /* Global interrupt ctrl reg */ ++#define INT_MASK_REG (IN_BASE + 0x04) /* Interrupt mask reg */ ++#define INT_STATUS_REG (IN_BASE + 0x08) /* Interrupt status reg */ ++#define INT_RAW_STATUS_REG (IN_BASE + 0x0C) /* Interrupt pin raw */ ++ /* status reg*/ ++ ++/* INT_CONTROL_REG - Global Interrupt Control Register */ ++#define INT_ENABLE 0x00000001 /* Interrupt to CPU enabled */ ++#define INT_PORLARITY_HIGH 0x00000002 /* Interrupt is active high */ ++#define INT_GPIO1_0To1 0x00000004 /* Interrupt as xition 0 to 1 */ ++#define INT_GPIO2_0To1 0x00000008 /* Interrupt as xition 0 to 1 */ ++#define INT_GPIO3_0To1 0x00000010 /* Interrupt as xtion 0 to 1 */ ++ ++/* INT_MASK_REG -- Interrupt Mask Register */ ++#define UM_GC1_VSE_R 0x00000001 /* GC1 VSE - Rising edge */ ++#define UM_GC1_VSE_F 0x00000002 /* GC1 VSE - Falling edge */ ++#define UM_GC1_VDE_R 0x00000004 /* GC1 VDE - Rising edge */ ++#define UM_GC1_VDE_F 0x00000008 /* GC1 VDE - Falling edge */ ++#define UM_GC2_VSE_R 0x00000010 /* GC2 VSE - Rising edge */ ++#define UM_GC2_VSE_F 0x00000020 /* GC2 VSE - Falling edge */ ++#define UM_GC2_VDE_R 0x00000040 /* GC2 VDE - Rising edge */ ++#define UM_GC2_VDE_F 0x00000080 /* GC2 VDE - Falling edge */ ++#define UM_CFIFO_HALF_EMPTY 0x00000100 /* Command fifo half empty */ ++#define UM_CFIFO_EMPTY 0x00000200 /* Command fifo empty */ ++#define UM_SFIFO_HALF_EMPTY 0x00000400 /* Source fifo half empty */ ++#define UM_SFIFO_EMPTY 0x00000800 /* Source fifo empty */ ++#define UM_GE_IDLE 0x00001000 /* GE is idle */ ++#define UM_GPIO_1 0x00002000 /* GPIO pin 1 */ ++#define UM_GPIO_2 0x00004000 /* GPIO pin 2 */ ++#define UM_GPIO_3 0x00008000 /* GPIO pin 3 */ ++ ++/* INT_STATUS_REG -- Interrupt Status Register */ ++#define ST_GC1_VSE_R 0x00000001 /* GC1 VSE - Rising edge */ ++#define ST_GC1_VSE_F 0x00000002 /* GC1 VSE - Falling edge */ ++#define ST_GC1_VDE_R 0x00000004 /* GC1 VDE - Rising edge */ ++#define ST_GC1_VDE_F 0x00000008 /* GC1 VDE - Falling edge */ ++#define ST_GC2_VSE_R 0x00000010 /* GC2 VSE - Rising edge */ ++#define ST_GC2_VSE_F 0x00000020 /* GC2 VSE - Falling edge */ ++#define ST_GC2_VDE_R 0x00000040 /* GC2 VDE - Rising edge */ ++#define ST_GC2_VDE_F 0x00000080 /* GC2 VDE - Falling edge */ ++#define ST_CFIFO_HALF_EMPTY 0x00000100 /* Command fifo half empty */ ++#define ST_CFIFO_EMPTY 0x00000200 /* Command fifo empty */ ++#define ST_SFIFO_HALF_EMPTY 0x00000400 /* Source fifo half empty */ ++#define ST_SFIFO_EMPTY 0x00000800 /* Source fifo empty */ ++#define ST_GE_IDLE 0x00001000 /* GE is idle */ ++#define ST_GPIO_1 0x00002000 /* GPIO pin 1 */ ++#define ST_GPIO_2 0x00004000 /* GPIO pin 2 */ ++#define ST_GPIO_3 0x00008000 /* GPIO pin 3 */ ++ ++/* INT_RAW_STATUA_REG -- Interrupt Pin Raw Status Register */ ++#define GC1_VSE 0x00000001 /* GC1 - VSE */ ++#define GC1_VDE 0x00000004 /* GC1 - VDE */ ++#define GC2_VSE 0x00000010 /* GC2 - VSE */ ++#define GC2_VDE 0x00000040 /* GC2 - VDE */ ++#define INT_GE_BUSY 0x00000100 /* GE busy */ ++#define SFIFO_EMPTY 0x00000200 /* Source fifo empty */ ++#define SFIFO_HEMPTY 0x00000400 /* Source fifo half empty */ ++#define CFIFO_EMPTY 0x00000800 /* Command fifo empty */ ++#define CFIFO_HEMPTY 0x00001000 /* Command fifo half empty */ ++#define GPIO_PIN_1 0x00002000 /* GPIO pin 1 */ ++#define GPIO_PIN_2 0x00004000 /* GPIO pin 2 */ ++#define GPIO_PIN_3 0x00008000 /* GPIO pin 3 */ ++ ++/* 2D Engine registers - GE1 (0x00 - 0x7F) */ ++#define DRAW_CMD (GE_BASE + 0x00) /* Drawing command register */ ++#define WIDTH_HEIGHT (GE_BASE + 0x04) /* Width/height register */ ++#define LINE_DRAW WIDTH_HEIGHT /* Bresenham Line Draw reg */ ++#define DEST_XY (GE_BASE + 0x08) /* Destination X/Y register */ ++#define LINE_MAJOR_X DEST_XY /* Bresenham Line Start X/Y reg */ ++#define PAT_OFFSET DEST_XY /* Pattern Offset register */ ++#define SRC_XY (GE_BASE + 0x0C) /* Source X/Y register */ ++#define LINE_MINOR_Y SRC_XY /* Bresenham Line Delta register */ ++#define COLOR_COMPARE (GE_BASE + 0x10) /* Color compare register */ ++#define CLIP_LeftT (GE_BASE + 0x14) /* Clip Left/Top register */ ++#define CLIP_RightB (GE_BASE + 0x18) /* Clip Right/Bottom register */ ++#define FG_COLOR (GE_BASE + 0x1C) /* Fg color for Mono src reg */ ++#define BG_COLOR (GE_BASE + 0x20) /* Bg color for Mono src reg */ ++#define SRC_STRIDE_OFFSET (GE_BASE + 0x24) /* Source Stride & Offset Reg */ ++#define DEST_STRIDE (GE_BASE + 0x28) /* Base address register */ ++#define BASE_ADDRESS (GE_BASE + 0x2C) /* Base address register */ ++#define TEST_RESULT_REG (GE_BASE + 0x7C) /* Test result register */ ++#define COLOR_PATTERN (GE_BASE + 0x100) /* Color pattern registers */ ++#define MONO_PATTERN0 COLOR_PATTERN /* Mono Pattern register 0 */ ++#define MONO_PATTERN1 (GE_BASE + 0x104) /* Mono Pattern register 1 */ ++#define PAT_FG_COLOR (GE_BASE + 0x108) /* Mono Pattern Fg color reg */ ++#define PAT_BG_COLOR (GE_BASE + 0x10C) /* Mono Pattern Bg color reg */ ++#define _FIRST_GE DRAW_CMD ++#define _LAST_GE (COLOR_PATTERN + 0x80) ++#define SRC_IMAGE_DATA (GE_BASE + 0xC000) /* Source Data register */ ++ ++/* 2D Engine registers - GE2 (0x80 to 0xFF) */ ++#define DRAW_CMD2 (GE2_BASE + 0x00) /* Drawing command register */ ++#define WIDTH_HEIGHT2 (GE2_BASE + 0x04) /* Width/height register */ ++#define LINE_DRAW2 WIDTH_HEIGHT2 /* Bresenham Line Draw register */ ++#define DEST_XY2 (GE2_BASE + 0x08) /* Destination X/Y register */ ++#define LINE_MAJOR_X2 DEST_XY2 /* Bresenham Line Start X/Y reg */ ++#define PAT_OFFSET2 DEST_XY2 /* Pattern Offset register */ ++#define SRC_XY2 (GE2_BASE + 0x0C) /* Source X/Y register */ ++#define LINE_MINOR_Y2 SRC_XY2 /* Bresenham Line Delta register */ ++#define COLOR_COMPARE2 (GE2_BASE + 0x10) /* Color compare register */ ++#define CLIP_LeftT2 (GE2_BASE + 0x14) /* Clip Left/Top register */ ++#define CLIP_RightB2 (GE2_BASE + 0x18) /* Clip Right/Bottom register */ ++#define FG_COLOR2 (GE2_BASE + 0x1C) /* Fg color for Mono src reg */ ++#define BG_COLOR2 (GE2_BASE + 0x20) /* Bg color for Mono src reg */ ++#define SRC_STRIDE_OFFSET2 (GE2_BASE + 0x24) /* Source Stride & Offset Reg */ ++#define DEST_STRIDE2 (GE2_BASE + 0x28) /* Base address register */ ++#define BASE_ADDRESS2 (GE2_BASE + 0x2C) /* Base address register */ ++#define TEST_RESULT_REG2 (GE2_BASE + 0x7C) /* Test result register */ ++#define COLOR_PATTERN2 (GE2_BASE + 0x100) /* Color pattern registers */ ++#define MONO_PATTERN02 COLOR_PATTERN2 /* Mono Pattern register 0 */ ++#define MONO_PATTERN12 (GE2_BASE + 0x104) /* Mono Pattern register 1 */ ++#define PAT_FG_COLOR2 (GE2_BASE + 0x108) /* Mono Pattern Fg color reg */ ++#define PAT_BG_COLOR2 (GE2_BASE + 0x10C) /* Mono Pattern Bg color reg */ ++#define _FIRST_GE2 DRAW_CMD2 ++#define _LAST_GE2 (COLOR_PATTERN2 + 0x80) ++#define SRC_IMAGE_DATA2 (GE2_BASE + 0xC000) /* Source Data register */ ++ ++ ++/* DEST_STRIDE color depth */ ++#define GE_8BPP 0x00000000 /* 8BPP mode */ ++#define GE_16BPP 0x40000000 /* 16BPP mode */ ++#define GE_24BPP 0x80000000 /* 24BPP mode */ ++#define GE_32BPP 0xC0000000 /* 24BPP mode */ ++ ++/* BASE_ADDRESS */ ++#define GE_TEST_MODE_ENABLE 0x20000000 /* Test mode enabled */ ++#define GE_TEST_MASK 0xc0000000 /* Test mode read path select */ ++#define SEL_CLIP_LR 0x40000000 /* Select clipping left/right */ ++#define SEL_CLIP_TB 0x80000000 /* Select clipping top/bottom */ ++ ++/* Draw command register bits */ ++#define DO_BITBLT 0x00000200 ++#define DO_AAFONT 0x00000300 ++#define DO_LINEDRAW 0x00000400 ++#define X_DIR 0x00000800 /* Negative X direction */ ++#define Y_DIR 0x00001000 /* Negative Y direction */ ++#define SRC_IS_MEMORY 0x00002000 /* Source is in system memory */ ++#define MONO_SRC 0x00004000 /* Source is mono bitmap */ ++#define MONO_PATTERN 0x00008000 /* Pattern is monochrome */ ++#define TRANS_COLOR 0x00010000 /* Transparency is enabled */ ++#define TRANS_NOT_EQUAL 0x00020000 /* Polarity for color */ ++#define TRANS_MONO 0x00040000 /* Mono xparency is enabled */ ++#define TRANS_MONO_FG 0x00080000 /* Polarity for mono */ ++#define PACKED_MODE 0x00100000 /* Memory xfer mode select */ ++#define ALPHA_BYTE_MASK 0x00600000 /* Alpha Byte mask for 32bpp */ ++#define MONO_SOLID 0x00800000 /* Solid Mono Pattern */ ++#define SRC_NE_DEST_STRIDE 0x01000000 /* Src Not Equal Dest Stride */ ++#define ROP2_ENABLE 0x02000000 /* Use Rop2 code */ ++#define CLIP_ENABLE 0x04000000 /* Clipping is enabled */ ++#define AUTO_EXEC 0x08000000 /* Auto execute at dest X/Y */ ++#define VDE_GC2_ENABLE 0x10000000 /* Enable falling edge check */ ++#define VDE_GC1_ENABLE 0x20000000 /* Enable falling edge check */ ++#define COLOR_DEPTH_MASK 0xC0000000 /* Color Depth mask */ ++#define GE_8BPP 0x00000000 /* 8BPP mode */ ++#define GE_16BPP 0x40000000 /* 16BPP mode */ ++#define GE_24BPP 0x80000000 /* 24BPP mode */ ++ ++/* Graphics Controller 1 Registers */ ++#define GC1_CONTROL (GC_BASE + 0x00) /* Graphics Controll 1 Control Reg */ ++#define GC1_CRT_CONTROL (GC_BASE + 0x04) /* CRT controll register */ ++#define HD1_CONTROL (GC_BASE + 0x08) /* Horizontal Display 1 Control */ ++#define VD1_CONTROL (GC_BASE + 0x0C) /* Vertical Display 1 Control */ ++#define HS1_CONTROL (GC_BASE + 0x10) /* Horizontal Sync 1 Control */ ++#define VS1_CONTROL (GC_BASE + 0x14) /* Vertical Sync 1 Control */ ++#define HW1_CONTROL (GC_BASE + 0x20) /* Horizontal Window 1 Control */ ++#define VW1_CONTROL (GC_BASE + 0x24) /* Vertical Window 1 Control */ ++#define AHW1_CONTROL (GC_BASE + 0x28) /* Alt Horizontal Window 1 Control */ ++#define AVW1_CONTROL (GC_BASE + 0x2C) /* Alt Vertical Window 1 Control */ ++#define IW1_START_ADDR (GC_BASE + 0x30) /* Image Window 1 Start Address */ ++#define AIW1_START_ADDR (GC_BASE + 0x34) /* Alt Image Window 1 Start Address */ ++#define IW1_STRIDE (GC_BASE + 0x38) /* (Alt) Image Window 1 Stride */ ++#define IW1_LINE_SIZE (GC_BASE + 0x3C) /* (Alt) Image Window 1 Line Size */ ++#define HW_CURSOR1_POS (GC_BASE + 0x40) /* Hardware cursor 1 position */ ++#define HW_CURSOR1_ADDR (GC_BASE + 0x44) /* Start address and offset */ ++#define HW_CURSOR1_FGCLR (GC_BASE + 0x48) /* Foreground color */ ++#define HW_CURSOR1_BGCLR (GC_BASE + 0x4C) /* Background color */ ++ ++/* Graphics Controller 2 Registers */ ++#define GC2_CONTROL (GC_BASE + 0x80) /* Graphics Controll 2 Control Reg */ ++#define GC2_CRC_CONTROL (GC_BASE + 0x84) /* CRC Control */ ++#define HD2_CONTROL (GC_BASE + 0x88) /* Horizontal Display 2 Control */ ++#define VD2_CONTROL (GC_BASE + 0x8C) /* Vertical Display 2 Control */ ++#define HS2_CONTROL (GC_BASE + 0x90) /* Horizontal Sync 2 Control */ ++#define VS2_CONTROL (GC_BASE + 0x94) /* Vertical Sync 2 Control */ ++#define HW2_CONTROL (GC_BASE + 0xA0) /* Horizontal Window 2 Control */ ++#define VW2_CONTROL (GC_BASE + 0xA4) /* Vertical Window 2 Control */ ++#define AHW2_CONTROL (GC_BASE + 0xA8) /* Alt Horizontal Window 2 Control */ ++#define AVW2_CONTROL (GC_BASE + 0xAC) /* Alt Vertical Window 2 Control */ ++#define IW2_START_ADDR (GC_BASE + 0xB0) /* Image Window 2 Start Address */ ++#define AIW2_START_ADDR (GC_BASE + 0xB4) /* Alt Image Window 2 Start Address */ ++#define IW2_STRIDE (GC_BASE + 0xB8) /* (Alt) Image Window 2 Stride */ ++#define IW2_LINE_SIZE (GC_BASE + 0xBC) /* (Alt) Image Window 2 Line Size */ ++#define HW_CURSOR2_POS (GC_BASE + 0xC0) /* Hardware cursor 2 position */ ++#define HW_CURSOR2_ADDR (GC_BASE + 0xC4) /* Start address and offset */ ++#define HW_CURSOR2_FGCLR (GC_BASE + 0xC8) /* Foreground color */ ++#define HW_CURSOR2_BGCLR (GC_BASE + 0xCC) /* Background color */ ++ ++/* GC1_CONTROL/GC2_CONTROL register */ ++#define GC_ENABLE 0x00000001UL /* Controll 1/2 enabled */ ++#define GC_DISABLE 0xfffffffeUL /* Controll 1/2 disabled */ ++#define HORZ_COUNT_RESET 0x00000002UL /* Horiz counter 1/2 reset */ ++#define VERT_COUNT_RESET 0x00000004UL /* Vertical counter 1/2 reset */ ++#define IM_ENABLE 0x00000008UL /* Image Window 1/2 Enable */ ++#define IM_DISABLE 0xfffffff7UL /* Image Window 1/2 Disable */ ++ ++#define GC_1BPP 0x00000000UL /* GC1/2 color depth */ ++#define GC_2BPP 0x00000010UL ++#define GC_4BPP 0x00000020UL ++#define GC_8BPP 0x00000030UL ++#define GC_16BPP 0x00000040UL /* with color palette enabled */ ++#define GC_24BPP_NBP 0x00000050UL /* with color palette enabled */ ++#define GC_32BPP_ABGR 0x00000060UL /* with color palette enabled */ ++#define GC_32BPP_ARGB 0x00000070UL /* with color palette enabled */ ++#define GC_16BPP_BP 0x000000C0UL /* with color pal bypassed */ ++#define GC_24BPP_BP 0x000000D0UL /* with color pal bypassed */ ++#define GC_32BPP_ABGR_BP 0x000000E0UL /* with color pal bypassed */ ++#define GC_32BPP_ARGB_BP 0x000000F0UL /* with color pal bypassed */ ++#define GC_32BPP GC_32BPP_ARGB /* Default 32bpp with ARGB */ ++#define GC_24BPP GC_24BPP_NBP ++ ++#define HC_ENABLE 0x00000100UL /* Hardware cursor enable */ ++#define HC_DISABLE 0xfffffeffUL /* And mask to disable HC */ ++#define AIM_ENABLE 0x00000800UL /* Alt Image Win 1/2 Enable */ ++ ++#define AGC_1BPP 0x00000000UL /* Alt GC1/2 color depth */ ++#define AGC_2BPP 0x00001000UL ++#define AGC_4BPP 0x00002000UL ++#define AGC_8BPP 0x00003000UL ++#define AGC_16BPP 0x00004000UL ++#define AGC_24BPP 0x00005000UL ++#define AGC_32BPP_ABGR 0x00006000UL ++#define AGC_32BPP_ARGB 0x00007000UL ++#define AGC_16BPP_BP 0x0000C000UL ++#define AGC_24BPP_BP 0x0000D000UL ++#define AGC_32BPP_ABGR_BP 0x0000E000UL ++#define AGC_32BPP_ARGB_BP 0x0000F000UL ++#define AGC_32BPP AGC_32BPP_ARGB_BP /* Default 32bpp w/ ARGB_BP */ ++ ++#define GxRCLK_BUSCLK 0x00000000UL /* G1RCLK source is bus clock */ ++#define GxRCLK_PLL1 0x00010000UL /* G1RCLK source is PLL1 */ ++#define GxRCLK_PLL2 0x00020000UL /* G1RCLK source is PLL2 */ ++#define GxRCLK_PLL3 0x00030000UL /* G1RCLK source is PLL3 */ ++#define GxRCLK_PLL_MASK 0x00030000UL /* G1RCLK source mask */ ++#define GC_TEST_MODE0 0x00040000UL /* Test mode 0 enabled */ ++#define GC_TEST_MODE1 0x00080000UL /* Test mode 1 enabled */ ++ ++#define FDx_1 0x00000000UL /* FD1 = 1 */ ++#define FDx_15 0x00100000UL /* FD1 = 1.5 */ ++#define FDx_25 0x00200000UL /* FD1 = 2.5 */ ++#define FDx_35 0x00300000UL /* FD1 = 3.5 */ ++#define FDx_45 0x00400000UL /* FD1 = 4.5 */ ++#define FDx_55 0x00500000UL /* FD1 = 5.5 */ ++#define FDx_65 0x00600000UL /* FD1 = 6.5 */ ++ ++/* GC1_CRT_CONTROL register */ ++#define CRT_ENABLE 0x00000001UL /* CRT DAC enabled */ ++#define CRT_DISABLE 0xfffffffeUL /* CRT DAC disabled -and mask */ ++#define CRT_BY_GC1 0x00000001UL /* CRT DAC driven by GC1 */ ++#define CRT_BY_GC2 0x00000003UL /* CRT DAC driven by GC2 */ ++#define CRT_BY_GCxMASK 0xfffffffcUL /* Mask for CRT DAC */ ++#define VSYNC_OUT_PMCLK 0x00000004UL /* CRT VSYNC output PMCLK ++ at PwrDn */ ++#define HSYNC_OUT_PMCLK 0x00000008UL /* CRT HSYNC output PMCLK ++ at PwrDn */ ++#define HSYNC_OUT_LOW 0x00000010UL /* CRT HSYNC output pin low */ ++#define HSYNC_OUT_HIGH 0x00000020UL /* CRT HSYNC output pin high */ ++#define VSYNC_OUT_LOW 0x00000040UL /* CRT VSYNC output pin low */ ++#define VSYNC_OUT_HIGH 0x00000080UL /* CRT VSYNC output pin high */ ++#define HSYNC_POLARITY_LOW 0x00000100UL /* active low */ ++#define VSYNC_POLARITY_LOW 0x00000200UL /* active low */ ++#define SYNC_PED_ENABLE 0x00000400UL /* Sync pedestal enable */ ++#define BLANK_PED_ENABLE 0x00000800UL /* Blank pedestal enable */ ++#define CSYNC_ENABLE 0x00001000UL /* Composite Sync Enable */ ++#define VREF_EXTERNAL 0x00002000UL /* Select external VREF */ ++#define MON_SENSE_ENABLE 0x00004000UL /* CRT DAC monitor sense ++ enable */ ++#define CONST_OUT_ENABLE 0x00008000UL /* Constant output enable */ ++#define BLUE_NOT_LOADED 0x01000000UL /* Blue DAC is not loaded */ ++#define GREEN_NOT_LOADED 0x02000000UL /* Green DAC is not loaded */ ++#define RED_NOT_LOADED 0x04000000UL /* Red DAC is not loaded */ ++ ++/* GC2_CRC_CONTROL */ ++#define CRC_ENABLE 0x00000001UL /* Enable CRC logic */ ++#define CRC_2_VSYNC 0x00000002UL /* Wait for 2 vsync */ ++#define CRC_READ_BLUE 0x00000000UL /* Read CRC result for blue */ ++#define CRC_READ_GREEN 0x00000004UL /* Read CRC result for green */ ++#define CRC_READ_RED 0x00000008UL /* Read CRC result for red */ ++#define CRC_RESULT_MASK 0x3fffff00UL /* CRC result mask */ ++ ++/* Flat Panel Interface Registers */ ++#define FP_CONTROL (FP_BASE + 0x00) /* Flat panel control */ ++#define FP_PIN_CONTROL (FP_BASE + 0x04) /* Flat panel pin control */ ++#define FP_GPO_CONTROL (FP_BASE + 0x08) /* FP Gen. purpose output ctrl */ ++#define FP_GPIO_CONTROL (FP_BASE + 0x0C) /* FP Gen. purpose I/O control */ ++#define STN_CONTROL (FP_BASE + 0x10) /* STN panel control */ ++#define DSTN_FB_CONTROL (FP_BASE + 0x14) /* D-STN frame buffer control */ ++#define PWM_CONTROL (FP_BASE + 0x3C) /* PWM control */ ++#define FRC_PATTERN (FP_BASE + 0x40) /* FRC pattern starting index */ ++#define FRC_WEIGHT (FP_BASE + 0xC0) /* FRC weight starting index */ ++ ++/* FP_CONTROL */ ++#define FPI_ENABLE 0x00000001UL /* Trigger fp power up sequence */ ++#define FPI_DISABLE 0xfffffffeUL /* Trigger fp power down sequence */ ++#define FPI_BY_GC1 0x00000001UL /* FPI enabled & driven by GC1 */ ++#define FPI_BY_GC2 0x00000003UL /* FPI enabled & driven by GC2 */ ++#define FPI_BY_GCxMASK 0xfffffffcUL /* mask */ ++#define FP_TYPE_TFT 0x00000000UL /* Flat panel type TFT */ ++#define FP_TYPE_SSTN 0x00000004UL /* Flat panel type S-STN */ ++#define FP_TYPE_DSTN 0x00000008UL /* Flat panel type D-STN */ ++#define FP_TYPE_MASK 0x0000000cUL /* Flat panel type mask */ ++#define FP_COLOR 0x00000000UL /* Color flat panel */ ++#define FP_MONO 0x00000010UL /* Mono flat panel */ ++#define TFT_4BITS_MONO 0x00000000UL /* Specify num of bits/pixel */ ++#define TFT_12BITS_COLOR 0x00000000UL /* Specify num of bits/pixel */ ++#define SSTN_4BITS_MONOCLR 0x00000000UL /* Specify num of bits/pixel */ ++#define DSTN_8BITS_MONOCLR 0x00000000UL /* Specify num of bits/pixel */ ++#define TFT_6BITS_MONO 0x00000020UL /* Specify num of bits/pixel */ ++#define TFT_18BITS_COLOR 0x00000020UL /* Specify num of bits/pixel */ ++#define SSTN_8BITS_MONOCLR 0x00000020UL /* Specify num of bits/pixel */ ++#define DSTN_16BITS_MONOCLR 0x00000020UL /* Specify num of bits/pixel */ ++#define TFT_8BITS_MONO 0x00000040UL /* Specify num of bits/pixel */ ++#define TFT_24BITS_COLOR 0x00000040UL /* Specify num of bits/pixel */ ++#define SSTN_12BITS_COLOR 0x00000040UL /* Specify num of bits/pixel */ ++#define DSTN_24BITS_COLOR 0x00000040UL /* Specify num of bits/pixel */ ++#define SSTN_16BITS_MONOCLR 0x00000060UL /* Specify num of bits/pixel */ ++#define SSTN_24BITS_COLOR 0x00000080UL /* Specify num of bits/pixel */ ++#define DITHER_PATTERN_0 0x00000000UL /* Dither pattern */ ++#define DITHER_PATTERN_1 0x00000100UL /* Dither pattern */ ++#define DITHER_PATTERN_2 0x00000200UL /* Dither pattern */ ++#define DITHER_PATTERN_3 0x00000300UL /* Dither pattern */ ++#define DITHER_BASE_8BITS 0x00000000UL /* No dithering */ ++#define DITHER_BASE_2BITS 0x00002000UL /* Num of bits to be dithered */ ++#define DITHER_BASE_3BITS 0x00003000UL /* Num of bits to be dithered */ ++#define DITHER_BASE_4BITS 0x00004000UL /* Num of bits to be dithered */ ++#define DITHER_BASE_6BITS 0x00006000UL /* Num of bits to be dithered */ ++#define FRC_ALTWIN_DISABLE 0x00008000UL /* Disable Dither/FRC if Alt enabled */ ++#define FRC_2LEVEL 0x00000000UL /* Disable FRC */ ++#define FRC_4LEVEL 0x00010000UL /* 4-level FRC */ ++#define FRC_8LEVEL 0x00020000UL /* 8-level FRC */ ++#define FRC_16LEVEL 0x00030000UL /* 16-level FRC */ ++#define DITHER_PATTERN_ADJ1 0x00fc0000UL /* Dither pattern adjust 1 */ ++#define DITHER_PATTERN_ADJ2 0x07000000UL /* Dither pattern adjust 2 */ ++#define DITHER_PATTERN_ADJ3 0x08000000UL /* Dither pattern adjust 3 */ ++#define TEST_MODE0_ENABLE 0x10000000UL /* Enable test mode 0 */ ++#define TEST_MODE1_ENABLE 0x20000000UL /* Enable test mode 1 */ ++#define TEST_MODE2_ENABLE 0x40000000UL /* Enable test mode 2 */ ++#define TEST_MODE3_ENABLE 0x80000000UL /* Enable test mode 3 */ ++ ++/* FP_PIN_CONTROL */ ++#define FP_PIN_DISABLE 0x00000001UL /* Disable flat panel pins */ ++#define DATA_INV_ENABLE 0x00000002UL /* TFT fp data inversion enabled */ ++#define FP_DISP_ENABLE 0x00000004UL /* FP Display enable control */ ++#define FMOD_ENABLE 0x00000008UL /* Flat panel AC mod enable */ ++#define FD2_SCLK 0x00000010UL /* STN output shift clk on FD2 pin*/ ++#define FSCLK_OUTPUT_ENABLE 0x00000020UL /* FSCLK output enable */ ++#define TFT_SCLK_SELECT 0x00000040UL /* TFT shift clock select */ ++#define SCLK_MASK 0x00000080UL /* Shift clock mask */ ++#define STN_LP_DISABLE 0x00000100UL /* STN LP control */ ++#define SCLK_DISABLE 0x00000200UL /* STN shift clock control */ ++#define STN_ExtraLP_ENABLE 0x00000400UL /* STN extra LP control */ ++#define FP_FD2_MAX 0x00000000UL /* FD2 drive strength - max (16mA)*/ ++#define FP_FD2_MEDIUM 0x00001000UL /* FD2 drive strength - medium */ ++#define FP_FD2_MEDIUM2 0x00002000UL /* FD2 drive strength - medium 2 */ ++#define FP_FD2_MIN 0x00003000UL /* FD2 drive strength - min */ ++#define FP_DATA_MAX 0x00000000UL /* Data drv strength - max (16mA) */ ++#define FP_DATA_MEDIUM 0x00004000UL /* Data drive strength - medium */ ++#define FP_DATA_MEDIUM2 0x00008000UL /* Data drive strength - medium 2 */ ++#define FP_DATA_MIN 0x0000c000UL /* Data drive strength - min */ ++#define FD2_ACTIVE_L 0x00010000UL /* Flat panel data bit 2 polarity */ ++#define FD_ACTIVE_L 0x00020000UL /* Flat panel data polarity */ ++#define FDE_ACTIVE_L 0x00040000UL /* Data enable polarity */ ++#define FHSYNC_ACTIVE_L 0x00080000UL /* Horz sync polarity */ ++#define FVSYNC_ACTIVE_L 0x00100000UL /* Vert sync polarity */ ++#define FSCLK_ACTIVE_L 0x00200000UL /* Shift clock polarity */ ++#define FP_FSCLK_MAX 0x00000000UL /* Sh clk drv strength -max (16mA)*/ ++#define FP_FSCLK_MEDIUM 0x00400000UL /* Sh clk drv strength -medium */ ++#define FP_FSCLK_MEDIUM2 0x00800000UL /* Sh clk drv strength -medium 2 */ ++#define FP_FSCLK_MIN 0x00c00000UL /* Sh clk drv strength -min */ ++#define FSCLK_DELAY 0x07000000UL /* Shift clock delay */ ++ ++/* FP_GPO_CONTROL */ ++#define ENCTL_AS_GPO0 0x00000001UL /* ENCTL used as GPO 0 */ ++#define ENCTL_AS_OSC 0x00000002UL /* ENCTL used as Oscillator clock */ ++#define ENCTL_AS_PLL3 0x00000003UL /* ENCTL used as PLL3 clock */ ++#define ENVEE_AS_GPO1 0x00000004UL /* ENVEE used as GPO 1 */ ++#define PWM0_AS_GPO2 0x00000010UL /* PWM0 pin used as GPO 2 */ ++#define PWM1_AS_GPO3 0x00000040UL /* PWM1 pin used as GPO 3 */ ++#define ENVDD_AS_GPO4 0x00000100UL /* ENVDD pin used as GPO 4 */ ++#define FP_PWM_MAX 0x00000000UL /* PWM0/1 drv strength -max (16mA)*/ ++#define FP_PWM_MEDIUM 0x00000400UL /* PWM0/1 drv strength -medium */ ++#define FP_PWM_MEDIUM2 0x00000800UL /* PWM0/1 drv strength -medium 2 */ ++#define FP_PWM_MIN 0x00000c00UL /* PWM0/1 drv strength -min */ ++#define FP_GPIO_MAX 0x00000000UL /* GPIO0/1/2 drv strgth. -max 16mA*/ ++#define FP_GPIO_MEDIUM 0x00001000UL /* GPIO0/1/2 drv strgth. -medium */ ++#define FP_GPIO_MEDIUM2 0x00002000UL /* GPIO0/1/2 drv strgth. -medium 2*/ ++#define FP_GPIO_MIN 0x00003000UL /* GPIO0/1/2 drv strgth. -min */ ++#define FP_EN_MAX 0x00000000UL /* ENVDD/ENCTL/ENVEE -max (16mA) */ ++#define FP_EN_MEDIUM 0x00004000UL /* ENVDD/ENCTL/ENVEE -medium */ ++#define FP_EN_MEDIUM2 0x00008000UL /* ENVDD/ENCTL/ENVEE -medium 2 */ ++#define FP_EN_MIN 0x0000c000UL /* ENVDD/ENCTL/ENVEE -min */ ++#define GPO0_DATA_HIGH 0x00010000UL /* ENCTL is driven high */ ++#define GPO1_DATA_HIGH 0x00020000UL /* ENVEE is driven high */ ++#define GPO2_DATA_HIGH 0x00040000UL /* PWM0 is driven high */ ++#define GPO3_DATA_HIGH 0x00080000UL /* PWM1 is driven high */ ++#define GPO4_DATA_HIGH 0x00100000UL /* ENVDD is driven high */ ++ ++/* FP_GPIO_CONTROL */ ++#define GPIO0_IN 0x00000000UL /* General-purpose input */ ++#define GPIO0_OUT 0x00000001UL /* General-purpose output */ ++#define GPIO0_PLL1 0x00000002UL /* GPIO0 used to output PLL 1 clk */ ++#define GPIO0_CRC_B 0x00000003UL /* GPIO0 used to output CRC Blue */ ++#define GPIO1_IN 0x00000000UL /* General-purpose input */ ++#define GPIO1_OUT 0x00000004UL /* General-purpose output */ ++#define GPIO1_PLL2 0x00000008UL /* GPIO1 used to output PLL 2 clk */ ++#define GPIO1_CRC_G 0x0000000cUL /* GPIO1 used to output CRC Green */ ++#define GPIO2_IN 0x00000000UL /* General-purpose input */ ++#define GPIO2_OUT 0x00000010UL /* General-purpose output */ ++#define GPIO2_PLL3 0x00000020UL /* GPIO2 used to output PLL 3 clk */ ++#define GPIO2_CRC_R 0x00000030UL /* GPIO2 used to output CRC Red */ ++#define GPIO0_OUT_HIGH 0x00010000UL /* GOIO0 output data */ ++#define GPIO1_OUT_HIGH 0x00020000UL /* GOIO1 output data */ ++#define GPIO2_OUT_HIGH 0x00040000UL /* GOIO2 output data */ ++#define GPIO0_IN_HIGH 0x01000000UL /* GOIO0 input data */ ++#define GPIO1_IN_HIGH 0x02000000UL /* GOIO1 input data */ ++#define GPIO2_IN_HIGH 0x04000000UL /* GOIO2 input data */ ++ ++/* STN_CONTROL */ ++#define FMOD_FRAMECLK 0x00000000UL /* FMOD generated using frame clock */ ++#define FMOD_LINECLK 0x80000000UL /* FMOD generated using line clock */ ++ ++/* PWM_CONTROL */ ++#define PWM0_BY_PLL 0x00000000UL /* PWM 0 signal by PLL */ ++#define PWM0_BY_BUS 0x00000001UL /* PWM 0 signal using bus clk */ ++#define PWM0_BY_PMC 0x00000002UL /* PWM 0 signal by power mgt clock */ ++#define PWM0_ALWAYS_ON 0x00000004UL /* PWM 0 signal always generated */ ++#define PWM0_DC_MASK 0xffff00ffUL /* PWM 0 duty cycle mask */ ++#define PWM0_MASK 0xffff0000UL /* PWM 0 mask */ ++#define PWM1_BY_PLL 0x00000000UL /* PWM 1 signal by PLL */ ++#define PWM1_BY_BUS 0x00010000UL /* PWM 1 signal using bus clk */ ++#define PWM1_BY_PMC 0x00020000UL /* PWM 1 signal by power mgt clock */ ++#define PWM1_ALWAYS_ON 0x00040000UL /* PWM 1 signal always generated */ ++#define PWM1_DC_MASK 0x00ffffffUL /* PWM 0 duty cycle mask */ ++#define PWM1_MASK 0x0000ffffUL /* PWM 1 mask */ ++ ++/* PCI Power Management Interface Registers */ ++#ifndef PCI_VENDOR_DEVICE ++#define PCI_VENDOR_DEVICE (PC_BASE + 0x00) ++#endif ++ ++#ifndef PCI_CMD_STATUS ++#define PCI_CMD_STATUS (PC_BASE + 0x04) ++#endif ++ ++#ifndef PCI_REV_CLASS ++#define PCI_REV_CLASS (PC_BASE + 0x08) ++#endif ++ ++#ifndef PCI_HEADER_TYPE ++#define PCI_HEADER_TYPE (PC_BASE + 0x0c) ++#endif ++ ++#ifndef PCI_SUB_ID ++#define PCI_SUB_ID (PC_BASE + 0x2c) ++#endif ++ ++#ifndef PCI_ROM_BASE ++#define PCI_ROM_BASE (PC_BASE + 0x30) ++#endif ++ ++#ifndef PCI_CAP_PTR ++#define PCI_CAP_PTR (PC_BASE + 0x34) ++#endif ++ ++#ifndef PCI_INTERRUPT ++#define PCI_INTERRUPT (PC_BASE + 0x3c) ++#endif ++ ++#ifndef PCI_PM_REGISTER ++#define PCI_PM_REGISTER (PC_BASE + 0x40) ++#endif ++ ++#ifndef PCI_PM_CNTL_STATUS ++#define PCI_PM_CNTL_STATUS (PC_BASE + 0x44) ++#endif ++ ++/* POWER_STATE */ ++#define POWER_STATE_MASK 0x00000003UL /* Device power state mask */ ++#define ENTER_D0 0x00000000UL /* Enter D0 state */ ++#define ENTER_D1 0x00000001UL /* Enter D1 state */ ++#define ENTER_D2 0x00000002UL /* Enter D2 state */ ++#define ENTER_D3 0x00000003UL /* Enter D3 state */ ++ ++/* DC (Device Configuration Unit) Registers */ ++#define DC_0 (DC_BASE + 0x00) /* Device Configruation Register 0 */ ++#define DC_1 (DC_BASE + 0x04) /* Device Configruation Register 1 */ ++#define DC_SW_0 (DC_BASE + 0x08) /* Software Register 0 */ ++#define DC_SW_1 (DC_BASE + 0x0C) /* Software Register 1 */ ++ ++/* DC_0 */ ++#define OSC_BYPASSED 0x00000001UL /* Oscillator bypassed, powered down */ ++#define OSC_ENABLE 0x00000002UL /* Oscillator control can be enabled */ ++#define PLL1_BYPASSED 0x00000004UL /* PLL1 bypassed */ ++#define PLL1_ENABLE 0x00000008UL /* PLL1 can be enabled */ ++#define PLL1_DIVBY1 0x00000000UL /* PLL1 P output divisor by 1 */ ++#define PLL1_DIVBY2 0x00000010UL /* PLL1 P output divisor by 2 */ ++#define PLL1_DIVBY4 0x00000020UL /* PLL1 P output divisor by 4 */ ++#define PLL1_DIVBY8 0x00000030UL /* PLL1 P output divisor by 8 */ ++#define PLL1_DIVBY16 0x00000040UL /* PLL1 P output divisor by 16 */ ++#define PLL1_DIV_MASK 0x00000070UL /* PLL1 P output divisor mask */ ++#define CIF_DIVBY1 0x00000000UL /* CPU Interface clk divisor by 1 */ ++#define CIF_DIVBY2 0x00000080UL /* CPU Interface clk divisor by 2 */ ++#define STRONGARM_SYNC_F 0x00002000UL /* StrongARM bus intrf at fall edge */ ++#define SW_CHIP_RESET 0x00004000UL /* Software chip reset */ ++#define MEM_STANDBY_DISABLE 0x00008000UL /* Memory Power unit Standby disab. */ ++#define OSC_SHAPER_DISABLE 0x01000000UL /* Oscillator waveform shaper disab. */ ++#define FAST_POWER_DISABLE 0x02000000UL /* Fast Power Sequencing disable */ ++#define OSC_FREQ_SEL_0 0x00000000UL /* Osc frequency select range 0 */ ++#define OSC_FREQ_SEL_1 0x04000000UL /* Osc frequency select range 1 */ ++#define OSC_FREQ_SEL_2 0x08000000UL /* Osc frequency select range 2 */ ++#define OSC_FREQ_SEL_3 0x0c000000UL /* Osc frequency select range 3 */ ++ ++/* DC_1 */ ++#define BUS_MODE_MASK 0x0000003FUL /* Bus interface mode mask */ ++#define BUS_MODE_SH7709 0x00000001UL /* Bus interface mode - SH7709 */ ++#define BUS_MODE_SH7750 0x00000002UL /* Bus interface mode - SH7750 */ ++#define BUS_MODE_VR41xx 0x00000004UL /* Bus interface mode - VR4111/21 */ ++#define BUS_MODE_SA1110 0x00000008UL /* Bus interface mode - SA1110 */ ++#define BUS_MODE_TX3922 0x00000010UL /* Bus interface mode - TX3922 */ ++#define BUS_MODE_PCI 0x00000020UL /* Bus interface mode - PCI */ ++ ++/* PMU (Power Management Unit) Registers */ ++#define PM_MISC (PM_BASE + 0x00) /* Power management misc ctrl */ ++#define D1_STATE (PM_BASE + 0x04) /* D1 state control */ ++#define D2_STATE (PM_BASE + 0x08) /* D2 state control */ ++#define PLL2_CONTROL (PM_BASE + 0x18) /* PLL2 programming */ ++#define PLL3_CONTROL (PM_BASE + 0x1C) /* PLL3 programming */ ++ ++/* PM_MISC */ ++#define PLL1_N_BIT5 0x00000001UL /* Bit 5 of PLL1 N parameter */ ++#define PLL2_ENABLE 0x00000004UL /* PLL2 can be enabled */ ++#define PLL3_ENABLE 0x00000008UL /* PLL3 can be enabled */ ++#define FORCE_POWER_STATE 0x00000020UL /* For testing */ ++#define GE_ENABLE 0x00000100UL /* GE can be enabled */ ++#define GE_CLOCK_ON 0x00000200UL /* GE clock is always running */ ++#define GE_PIPELINE_ON 0x00000400UL /* GE pipeline always running */ ++#define GE_BY_BUS 0x00000000UL /* GE driven by bus intf clk */ ++#define GE_BY_PLL1 0x00000800UL /* GE driven by PLL1 */ ++#define GE_BY_PLL2 0x00001000UL /* GE driven by PLL2 */ ++#define GE_BY_PLL3 0x00001800UL /* GE driven by PLL3 */ ++#define GE_BY_MASK 0x00001800UL /* GE clock select mask */ ++#define GE_CMDFIFO_RESET 0x00002000UL /* GE command FIFO is reset */ ++#define GE_SRCFIFO_RESET 0x00004000UL /* GE CPU src FIFO is reset */ ++#define POWER_ON_IF_MIU_ON 0x00008000UL /* Pwr seq on when MIU enab.*/ ++#define D3_MEM_REFRESF 0x00010000UL /* FrameBuf refreshed in D3 */ ++#define D4_MEM_REFRESF 0x00020000UL /* FrameBuf refreshed in D4 */ ++#define PMCLK_4CYCLE 0x00000000UL /* Power sequencing interval */ ++#define PMCLK_8CYCLE 0x00040000UL /* Power sequencing interval */ ++#define PMCLK_16CYCLE 0x00080000UL /* Power sequencing interval */ ++#define PMCLK_2048CYCLE 0x000c0000UL /* Power sequencing interval */ ++#define FP_PMCLK_512 0x00000000UL /* FP power seq interval */ ++#define FP_PMCLK_1024 0x00100000UL /* FP power seq interval */ ++#define FP_PMCLK_2048 0x00200000UL /* FP power seq interval */ ++#define FP_PMCLK_128K 0x00300000UL /* FP power seq interval */ ++#define POWER_SEQ_ALL 0x00400000UL /* General power seq interval */ ++#define PMU_TEST_MODE 0x008000UL /* PMU test mode */ ++#define PM_POWER_MASK 0x03000000UL /* Power state mask */ ++#define PM_D0_STATE 0x00000000UL /* Power state D0 */ ++#define PM_D1_STATE 0x01000000UL /* Power state D1 */ ++#define PM_D2_STATE 0x02000000UL /* Power state D2 */ ++#define PM_D3_STATE 0x03000000UL /* Power state D3 */ ++#define POWER_IN_PROGRESS 0x04000000UL /* Power seq. active status */ ++ ++/* D1_STATE and D2_STATE */ ++#define DxOSC_ENABLE 0x00000001UL /* Oscillator can be enabled in D1/2 */ ++#define DxPLL1_ENABLE 0x00000002UL /* PLL1 can be enabled in D1/2 */ ++#define DxPLL2_ENABLE 0x00000004UL /* PLL2 can be enabled in D1/2 */ ++#define DxPLL3_ENABLE 0x00000008UL /* PLL3 can be enabled in D1/2 */ ++#define DxMIU_ENABLE 0x00000010UL /* MIU can be enabled in D1/2 */ ++#define DxMEM_REFRESH 0x00000020UL /* Memory is refreshed in D1/2 */ ++#define DxGE_ENABLE 0x00000040UL /* GE can be enabled in D1/2 */ ++#define DxCRT_ENABLE 0x00000100UL /* CRT can be enabled in D1/2 */ ++#define DxFP_ENABLE 0x00000200UL /* Flat panel can be enabled in D1/2 */ ++#define DxGC1_ENABLE 0x00010000UL /* GC1 can be enabled in D1/2 */ ++#define DxW1_ENABLE 0x00020000UL /* Window 1 can be enabled in D1/2 */ ++#define DxAW1_ENABLE 0x00040000UL /* Alt window 1 enabled in D1/2 */ ++#define DxHC1_ENABLE 0x00080000UL /* Cursor 1 enabled in D1/2 */ ++#define DxGC2_ENABLE 0x01000000UL /* GC2 can be enabled in D1/2 */ ++#define DxW2_ENABLE 0x02000000UL /* Window 2 can be enabled in D1/2 */ ++#define DxAW2_ENABLE 0x04000000UL /* Alt window 2 enabled in D1/2 */ ++#define DxHC2_ENABLE 0x08000000UL /* Cursor 2 enabled in D1/2 */ ++ ++/* PLL2_CONTROL/PLL3_CONTROL */ ++#define PLL_FROM_OSC 0x00000000UL /* PLL2/3 ref clock from OSCCLK */ ++#define PLL_FROM_PxCLK 0x00000001UL /* PLL2/3 ref clock from P2CLK */ ++#define PLL_BYPASSED 0x00000002UL /* PLL2/3 is bypassed */ ++#define PLL_DIVBY1 0x00000000UL /* PLL2/3 P output divisor by 1 */ ++#define PLL_DIVBY2 0x00000010UL /* PLL2/3 P output divisor by 2 */ ++#define PLL_DIVBY4 0x00000020UL /* PLL2/3 P output divisor by 4 */ ++#define PLL_DIVBY8 0x00000030UL /* PLL2/3 P output divisor by 8 */ ++#define PLL_DIVBY16 0x00000040UL /* PLL2/3 P output divisor by 16 */ ++#define PLL_DIV_MASK 0x00000070UL /* PLL2/3 P output divisor mask */ ++ ++/* CPU Interface Registers */ ++#define CPU_CONTROL (CC_BASE + 0x00) /* CPU control register */ ++#define DRAW_STATUS (CC_BASE + 0x04) /* Drawing status register */ ++ ++/* CPU_CONTROL */ ++#define SW_RESET 0x00000002UL /* Reset all modules except CIF */ ++#define MIU_READ_REQ 0x00000004UL /* MIU read request */ ++#define CLKRUN_ENABLE 0x00000008UL /* CLKRUN enabled. On Pwr-on, disab. */ ++ ++/* DRAW_STATUS */ ++#define CMD_FIFO_MASK 0x0000001fUL /* Command FIFO entries mask */ ++#define SRC_FIFO_MASK 0x00000f00UL /* Source FIFO entry mask */ ++#define GE_BUSY 0x00010000UL /* Any command in Comm FIFO */ ++#define CMD_FIFO_FULL 0x00000000UL /* Cmd fifo full bit */ ++#define CMD_FIFO_EMPTY 0x00000010UL /* Cmd fifo empty, 16x32 bits free */ ++#define SRC_FIFO_FULL 0x00000000UL /* Src fifo full bit */ ++#define SRC_FIFO_EMPTY 0x00000800UL /* Src fifo empty, 8x128 bits free */ ++ ++#define CMD_FIFO_CNT 16 /* Command FIFO full entry */ ++#define CMD_FIFO_MAX_INDEX 64 ++#define SRC_FIFO_MAX_BYTES 128 /* max pixels in src fifo - 8bits */ ++#define SRC_FIFO_MAX_WORDS 64 /* max pixels in src fifo - 16bits */ ++#define SRC_FIFO_MAX_DWORDS 32 /* max dwords in src fifo - 32bits */ ++ ++/* MIU (Memory Interface Unit) Registers */ ++#define MIU_CONTROL1 (MM_BASE + 0x00) /* Memory interface control 1 */ ++#define MIU_CONTROL2 (MM_BASE + 0x04) /* Memory interface control 2 */ ++#define MIU_CONTROL3 (MM_BASE + 0x08) /* Memory interface control 3 */ ++#define MIU_CONTROL4 (MM_BASE + 0x0C) /* Memory interface control 4 */ ++#define MIU_CONTROL5 (MM_BASE + 0x10) /* Memory interface control 5 */ ++ ++/* MIU_CONTROL1 */ ++#define MIU_ENABLE 0x00000001UL /* Enable MIU */ ++#define MIU_RESET_DISABLE 0x00000002UL /* MIU reset is disabled */ ++#define DRAM_RESET_DISABLE 0x00000004UL /* DRAM reset is disabled */ ++ ++/* MIU_CONTROL2 */ ++#define CLK_FROM_BUS 0x00000001UL /* Bus clk for mem clk src */ ++#define CLK_FROM_PLL2 0x00000001UL /* PLL2 for mem clock source */ ++#define MEM_REFRESH_ENABLE 0x00000002UL /* Mem ref disab at pwr dw mod*/ ++#define CPU_PB_ENABLE 0x00000004UL /* Page Break enab after CPU mem cyc */ ++#define GC1_PB_ENABLE 0x00000008UL /* Page Break after GC1 mem cycles */ ++#define GC2_PB_ENABLE 0x00000010UL /* Page Break after GC2 mem cycles */ ++#define STN_R_PB_ENABLE 0x00000020UL /* Page Break after STN read mem cyc */ ++#define STN_W_PB_ENABLE 0x00000040UL /* Page Break after STN wr. mem cyc */ ++#define GE_PB_ENABLE 0x00000080UL /* Page Break after GE memory cycles */ ++#define AUTO_REF_ENABLE 0x40000000UL /* Standby sig enab. when MIU active */ ++#define STANDBY_ENABLE 0x80000000UL /* Standby sig enab. when MIU active */ ++ ++/* MIU_CONTROL3 */ ++#define DISPLAY_BURST2 0x00000000UL /* Burst size for disp mem refresh */ ++#define DISPLAY_BURST4 0x00000001UL ++#define DISPLAY_BURST6 0x00000002UL ++#define DISPLAY_BURST8 0x00000003UL ++#define STN_R_BURST2 0x00000000UL /* Burst size for STN read mem cycle */ ++#define STN_R_BURST4 0x00000004UL ++#define STN_R_BURST6 0x00000008UL ++#define STN_R_BURST8 0x0000000cUL ++#define STN_W_BURST2 0x00000000UL /* Burst size for STN write mem cyc */ ++#define STN_W_BURST4 0x00000010UL ++#define STN_W_BURST6 0x00000020UL ++#define STN_W_BURST8 0x00000030UL ++#define GE_RW_BURST2 0x00000000UL /* Burst size for GE r/w mem cycle */ ++#define GE_RW_BURST4 0x00000040UL ++#define GE_RW_BURST6 0x00000080UL ++#define GE_RW_BURST8 0x000000c0UL ++#define CPU_RW_BURST2 0x00000000UL /* Burst size for CPU r/w mem cycle */ ++#define CPU_RW_BURST4 0x00000100UL ++#define CPU_RW_BURST6 0x00000200UL ++#define CPU_RW_BURST8 0x00000300UL ++ ++/* MIU_CONTROL4 */ ++#define R_LATENCY_REQUEST 0x00000001UL /* Read Latency Request */ ++ ++/* MIU_CONTROL5 */ ++#define LATENCY_1 0x00000001UL /* EDRAM Latency 1 */ ++#define LATENCY_2 0x00000005UL /* EDRAM Latency 2 */ ++#define LATENCY_3 0x00000007UL /* EDRAM Latency 3 */ ++#define DUMMY_IN_COMMANDS 0x00000008UL /* Dummy cycle insertion betw cmds */ ++#define DUMMY_IN_PRECHARGE 0x00000010UL /* Dummy cyc between precharge cyc */ ++#define DELAY_1ns 0x00000000UL /* Internal memory clock delay */ ++#define ACT_TO_CLOSE_3 0x00000100UL /* Bank activate to close - 3 mclk */ ++#define ACT_TO_CLOSE_4 0x00000200UL /* Bank activate to close - 4 mclk */ ++#define ACT_TO_CLOSE_5 0x00000300UL /* Bank activate to close - 5 mclk */ ++#define ACT_TO_COMMAND_2 0x00000000UL /* Bank activate to cmd r/w - 2 mclk */ ++#define ACT_TO_COMMAND_3 0x00000400UL /* Bank activate to cmd r/w - 3 mclk */ ++#define CLOSE_TO_ACT_2 0x00000000UL /* Bank close to activate - 2 mclk */ ++#define CLOSE_TO_ACT_3 0x00000800UL /* Bank close to activate - 3 mclk */ ++#define ROW_CYCLE_6 0x00000000UL /* Row Cycle time - 6 memory clock */ ++#define ROW_CYCLE_8 0x00001000UL /* Row Cycle time - 8 memory clock */ ++#define DELAY_R_CLOCK_0_0 0x00000000UL /* Delay for read clock - no delay */ ++#define DELAY_R_CLOCK_0_5 0x00010000UL /* Delay for read clock - 0.5ns */ ++#define DELAY_R_CLOCK_1_0 0x00020000UL /* Delay for read clock - 1.0ns */ ++#define DELAY_R_CLOCK_1_5 0x00030000UL /* Delay for read clock - 1.5ns */ ++#define DELAY_M_CLOCK_0_0 0x00000000UL /* Delay for memory clock - no delay */ ++#define DELAY_M_CLOCK_0_5 0x00020000UL /* Delay for memory clock - 0.5ns */ ++#define DELAY_M_CLOCK_1_0 0x00080000UL /* Delay for memory clock - 1.0ns */ ++#define DELAY_M_CLOCK_1_5 0x000c0000UL /* Delay for memory clock - 1.5ns */ ++ ++ ++/* ++ * Data structure and defines for MQ chip and driver interface ++ */ ++ ++/* Display configuration structure - for interface */ ++typedef struct DisplayConfig ++{ ++ int x; /* x resolution */ ++ int y; /* y resolution */ ++ int bpp; /* color depth */ ++ int refresh; /* CRT refresh rate */ ++ int stride; /* memory stride */ ++ unsigned long flag; /* display flag */ ++} DISPLAY_CONFIG, *PDISPLAY_CONFIG; ++ ++/* Flag definition */ ++#define PANEL_TYPE_MASK 0x000000ff /* Panel type mask */ ++#define PROCESSOR_MASK 0x00003f00 /* Mask of processor type */ ++#define IS_SH3 0x00000000 ++#define IS_SH4 0x00000100 ++#define IS_NEC 0x00000200 ++#define IS_SARM 0x00000300 ++#define IS_TOSHIBA 0x00000400 ++#define IS_PCI 0x00000500 ++#define LCD_ON 0x00010000 /* LCD mode */ ++#define CRT_ON 0x00020000 /* CRT mode */ ++#define LARGE_DESKTOP 0x00040000 /* Large desktop mode is on */ ++#define INDEP_DISPLAY 0x00080000 /* Independent display */ ++#define SAME_IMAGE 0x00100000 /* Use 2 GC but same image */ ++#define USE_2GCs 0x001C0000 /* 2 GCs are used */ ++#define USE_2GCs_MASK 0x001C0000 /* mask for 2 GCs */ ++#define ENA_HW_CURSOR 0x00200000 /* Enable hw cursor */ ++#define HORI_LCD_CRT 0x00000000 /* QView hori arrangement */ ++#define HORI_CRT_LCD 0x10000000 /* QView hori arrangement */ ++#define VERT_CRT_LCD 0x20000000 /* QView vert arrangement */ ++#define VERT_LCD_CRT 0x30000000 /* QView vert arrangement */ ++#define LCDCRT_POS_MASK 0x30000000 /* mask for QV orientation */ ++ ++/* Display timing structure */ ++typedef struct DisplayTiming ++{ ++ int x; /* x resolution */ ++ int y; /* y resolution */ ++ int refresh; /* refresh rate */ ++ unsigned long hd; /* hori display control */ ++ unsigned long vd; /* vert display control */ ++ unsigned long hs; /* hori sync control */ ++ unsigned long vs; /* vert sync control */ ++ unsigned long crtc; /* crt control */ ++ unsigned long pll; /* PLL2 or PLL3 setting */ ++} DISPLAY_TIMING, *PDISPLAY_TIMING; ++ ++/* Flat panel register */ ++typedef struct FPControl ++{ ++ int x; /* panel size x */ ++ int y; /* panel size y */ ++ int freq; /* panel freq */ ++ unsigned long fpControl; /* flat panel control */ ++ unsigned long fpPinControl; /* flat panel pin control */ ++ unsigned long stnControl; /* stn panel control */ ++} FPDATA_CONTROL, *PFPDATA_CONTROL; ++ ++/* Frame rate control */ ++#define FRC_PATTERN_CNT 32 ++#define FRC_WEIGHT_CNT 8 ++typedef struct FRCControl ++{ ++ ULONG frcPattern[FRC_PATTERN_CNT]; /* FRC pattern control */ ++ ULONG frcWeight[FRC_WEIGHT_CNT]; /* FRC weight control */ ++} FRC_CONTROL, *PFRC_CONTROL; ++ ++/* Miscellaneous defines */ ++#define IS_GC1 1 ++#define IS_GC2 2 ++ ++/* Turn on/off display */ ++#define ENABLE_LCD_GC1 0 ++#define ENABLE_LCD_GC2 1 ++#define DISABLE_LCD_GC1 2 ++#define DISABLE_LCD_GC2 3 ++#define ENABLE_CRT_GC1 4 ++#define ENABLE_CRT_GC2 5 ++#define DISABLE_CRT_GC1 6 ++#define DISABLE_CRT_GC2 7 ++ ++/* ++ * Handy macro ++ * ++ */ ++/* ++#define CHECK_IF_STATE_D(s) {\ ++ unsigned long ulState = (s);\ ++ unsigned long ulPMReg;\ ++ while(1)\ ++ {\ ++ ulPMReg = READ32(PCI_PM_CNTL_STATUS);\ ++ if((ulPMReg &0x03) == ulState)\ ++ break;\ ++ } } ++*/ ++#endif /* _VIDEO_MQ200_MQ2HW_H */ ++ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/video/MQ200/mqdata.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,754 @@ ++/*************************************************************************** ++ MQDATA.C ++ ++ This file contains timing and flat panel parameters for MediaQ graphics ++ chip. ++ ++ Copyright (c) 2000 by MediaQ, Incorporated. ++ All Rights Reserved. ++ ++***************************************************************************/ ++#ifndef _VIDEO_MQ200_MQDATA_H ++#define _VIDEO_MQ200_MQDATA_H ++/* LCD/CRT timing parameters for each resolution - VESA modes ++ * ++ * . the first entry is reserved to provide customized panel timing support ++ * . OEM can fill in proper timing for non-VESA LCD (or CRT) ++ * ++ */ ++DISPLAY_TIMING TimingParam[] = ++{ ++ { /* customized refresh rate - reserved for non-VESA panel timing */ ++ 0,0,0, /* X/Y/Freq */ ++ 0, /* HD Total + HD End */ ++ 0, /* VD Total + VD End */ ++ 0, /* HS Start + HS End */ ++ 0, /* VS Start + VS End */ ++ 0x00000000, /* CRT control */ ++ 0x00000000, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 640 x 240 90Hz (25.175 MHz) */ ++ 640,240,90, /* X/Y/Freq */ ++ (793-2) | (640L << 16), /* HD Total + HD End */ ++ (262-1) | ((240L-1) << 16), /* VD Total + VD End */ ++ 647 | (704L << 16), /* HS Start + HS End */ ++ 245 | (246L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00a30930, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 640 x 480 60Hz (25.175 MHz) */ ++ 640,480,60, /* X/Y/Freq */ ++ (800-2) | (640L << 16), /* HD Total + HD End */ ++ (525-1) | ((480L-1) << 16), /* VD Total + VD End */ ++ 656 | (752L << 16), /* HS Start + HS End */ ++ 490 | (492L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00a30930, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 640 x 480 72Hz (31.5 MHz) */ ++ 640,480,72, /* X/Y/Freq */ ++ (832-2) | (640L << 16), /* HD Total + HD End */ ++ (520-1) | ((480L-1) << 16), /* VD Total + VD End */ ++ 688 | (728L << 16), /* HS Start + HS End */ ++ 489 | (492L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00f50b30, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 640 x 480 75Hz (31.5 MHz) */ ++ 640,480,75, /* X/Y/Freq */ ++ (840-2) | (640L << 16), /* HD Total + HD End */ ++ (500-1) | ((480L-1) << 16), /* VD Total + VD End */ ++ 680 | (744L << 16), /* HS Start + HS End */ ++ 481 | (484L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00f50b30, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 640 x 480 85Hz (36 MHz) */ ++ 640,480,85, /* X/Y/Freq */ ++ (832-2) | (640L << 16), /* HD Total + HD End */ ++ (509-1) | ((480L-1) << 16), /* VD Total + VD End */ ++ 696 | (752L << 16), /* HS Start + HS End */ ++ 481 | (484L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00d20830, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 800 x 600 60Hz (40 MHz) */ ++ 800,600,60, /* X/Y/Freq */ ++ (1056-2) | (800L << 16), /* HD Total + HD End */ ++ (628-1) | ((600L-1) << 16), /* VD Total + VD End */ ++ 839 | (967L << 16), /* HS Start + HS End */ ++ 601 | (605L << 16), /* VS Start + VS End */ ++ BLANK_PED_ENABLE, /* CRT control */ ++ 0x00e90830, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 800 x 600 72Hz 50 MHz) */ ++ 800,600,72, /* X/Y/Freq */ ++ (1040-2) | (800L << 16), /* HD Total + HD End */ ++ (666-1) | ((600L-1) << 16), /* VD Total + VD End */ ++ 856 | (976L << 16), /* HS Start + HS End */ ++ 637 | (643L << 16), /* VS Start + VS End */ ++ BLANK_PED_ENABLE, /* CRT control */ ++ 0x00b20a20, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 800 x 600 75Hz (49.5 MHz) */ ++ 800,600,75, /* X/Y/Freq */ ++ (1056-2) | (800L << 16), /* HD Total + HD End */ ++ (625-1) | ((600L-1) << 16), /* VD Total + VD End */ ++ 816 | (896L << 16), /* HS Start + HS End */ ++ 601 | (604L << 16), /* VS Start + VS End */ ++ BLANK_PED_ENABLE, /* CRT control */ ++ 0x00900820, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 800 x 600 85Hz (56.25 MHz) */ ++ 800,600,85, /* X/Y/Freq */ ++ (1047-2) | (800L << 16), /* HD Total + HD End */ ++ (631-1) | ((600L-1) << 16), /* VD Total + VD End */ ++ 832 | (896L << 16), /* HS Start + HS End */ ++ 601 | (604L << 16), /* VS Start + VS End */ ++ BLANK_PED_ENABLE, /* CRT control */ ++ 0x00b60920, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 1024 x 768 60Hz (65 MHz) */ ++ 1024,768,60, /* X/Y/Freq */ ++ (1344-2) | (1024L << 16), /* HD Total + HD End */ ++ (806-1) | ((768L-1) << 16), /* VD Total + VD End */ ++ 1048 | (1184L << 16), /* HS Start + HS End */ ++ 771 | (777L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00fd0b20, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 1024 x 768 70Hz (75 MHz) */ ++ 1024,768,70, /* X/Y/Freq */ ++ (1327-2) | (1024L << 16), /* HD Total + HD End */ ++ (806-1) | ((768L-1) << 16), /* VD Total + VD End */ ++ 1047 | (1183L << 16), /* HS Start + HS End */ ++ 771 | (777L << 16), /* VS Start + VS End */ ++ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE, ++ /* CRT control */ ++ 0x00f30920, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 1024 x 768 75Hz (78.750 MHz) */ ++ 1024,768,75, /* X/Y/Freq */ ++ (1312-2) | (1024L << 16), /* HD Total + HD End */ ++ (806-1) | ((768L-1) << 16), /* VD Total + VD End */ ++ 1040 | (1136L << 16), /* HS Start + HS End */ ++ 769 | (772L << 16), /* VS Start + VS End */ ++ BLANK_PED_ENABLE, /* CRT control */ ++ 0x00cc0720, /* PLLx multiplier and control */ ++ }, ++ ++ { /* 1024 x 768 85Hz (94.5 MHz) */ ++ 1024,768,85, /* X/Y/Freq */ ++ (1375-2) | (1024L << 16), /* HD Total + HD End */ ++ (808-1) | ((768L-1) << 16), /* VD Total + VD End */ ++ 1072 | (1168L << 16), /* HS Start + HS End */ ++ 769 | (772L << 16), /* VS Start + VS End */ ++ BLANK_PED_ENABLE, /* CRT control */ ++ 0x007a0710, /* PLLx multiplier and control */ ++ } ++}; ++#define MAX_MQMODE (sizeof(TimingParam) / sizeof(TimingParam[0])) ++ ++/* Flat panel control registers ++ */ ++FPDATA_CONTROL fpControlData[] = ++{ ++ /* Type 0 : OEM Specific panel ++ */ ++ { /* Flat panel info */ ++ 0, 0, 0, ++ ++ /* Flat panel Control */ ++ 0 ++ , ++ ++ /* Flat panel pin control */ ++ 0 ++ , ++ ++ /* STN panel control */ ++ 0x0 ++ }, ++ /* Type 1 : SSTN VGA 8Bit Color - 72Hz ++ * - Sanyo SSTN 640x480 8-bit color interface ++ */ ++ { /* Flat panel info */ ++ 640, 480, 72, ++ ++ /* Flat panel Control */ ++ FP_TYPE_SSTN ++ | FP_COLOR ++ | SSTN_8BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x00400000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0000 ++ }, ++ ++ /* Type 2 : DSTN 16 Bit VGA Color - 72Hz ++ * - Hitachi 8.2" SX21V001 ++ * - Sanyo 10.4" LM-CJ53-22NTK ++ * - Sharp 10.4" LM64C35P ++ */ ++ { /* Flat panel info */ ++ 640, 480, 72, ++ ++ /* Flat panel Control */ ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_16BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0c840000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 3 : TFT 18 Bit VGA - 60Hz ++ * - NEC 10.4" NL6448AC33-24 ++ */ ++ { /* Flat panel info */ ++ 640, 480, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_TFT ++ | FP_COLOR ++ | TFT_18BITS_COLOR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_6BITS ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 4 : TFT 18 Bit SVGA - 60Hz ++ * - Hitachi 12.1" 800x600 TX31D24VC1CAA ++ */ ++ { /* Flat panel info */ ++ 800, 600, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_TFT ++ | FP_COLOR ++ | TFT_18BITS_COLOR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_6BITS ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 5 : DSTN 16Bit SVGA Color Panel - 72Hz ++ * - Hitachi 10.0" SX25S001 ++ * - Hitachi 12.1" SX25S003 ++ */ ++ { /* Flat panel info */ ++ 800, 600, 72, ++ ++ /* Flat panel Control */ ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_16BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0c840000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 6 : DSTN 8 Bit VGA Color - 72Hz ++ */ ++ { /* Flat panel info */ ++ 640, 480, 72, ++ ++ /* Flat panel Control */ ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_8BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0c840000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 7 : SSTN VGA 16Bit Color - 72Hz ++ */ ++ { /* Flat panel info */ ++ 640, 480, 72, ++ ++ /* Flat panel Control */ ++ FP_TYPE_SSTN ++ | FP_COLOR ++ | SSTN_16BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x00400000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0000 ++ }, ++ ++ /* Type 8 : SSTN VGA 8Bit Color - 60Hz ++ * - Sanyo SSTN 640x480 8-bit color interface ++ */ ++ { /* Flat panel info */ ++ 640, 480, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_SSTN ++ | FP_COLOR ++ | SSTN_8BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x00400000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0000 ++ }, ++ ++ /* Type 9 : DSTN 16 Bit VGA Color - 60Hz ++ * - Hitachi 8.2" SX21V001 ++ * - Sanyo 10.4" LM-CJ53-22NTK ++ * - Sharp 10.4" LM64C35P ++ */ ++ { /* Flat panel info */ ++ 640, 480, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_16BITS_MONOCLR ++ | DITHER_PATTERN_1 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0c840000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 10 : DSTN 16Bit SVGA Color Panel - 60Hz ++ * - Hitachi 10.0" SX25S001 ++ * - Hitachi 12.1" SX25S003 ++ * - Sanyo LM-FC53-22NTK ++ */ ++ { /* Flat panel info */ ++ 800, 600, 60, ++ ++ /* Flat panel Control */ ++#if 1 ++ 0x0C1B4128 ++#else ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_16BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0C840000 ++#endif ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 11 : DSTN 24Bit XGA Color Panel - 60Hz ++ * - Hitachi 12.1" SX25S003 ++ */ ++ { /* Flat panel info */ ++ 1024, 768, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_24BITS_COLOR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0c840000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 12 : DSTN 16Bit XGA Color Panel - 60Hz ++ * - Hitachi 12.1" SX25S003 ++ */ ++ { /* Flat panel info */ ++ 1024, 768, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_DSTN ++ | FP_COLOR ++ | DSTN_16BITS_MONOCLR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x0c840000 ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 13 : TFT 18Bit XGA - 60Hz ++ * - Hitachi 12.1" 800x600 TX31D24VC1CAA ++ */ ++ { /* Flat panel info */ ++ 1024, 768, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_TFT ++ | FP_COLOR ++ | TFT_18BITS_COLOR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_6BITS ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | FHSYNC_ACTIVE_L ++ | FVSYNC_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 14 : TFT 24Bit XGA - 60Hz ++ * - Hitachi 12.1" 800x600 TX31D24VC1CAA ++ */ ++ { /* Flat panel info */ ++ 1024, 768, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_TFT ++ | FP_COLOR ++ | TFT_24BITS_COLOR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_6BITS ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | FHSYNC_ACTIVE_L ++ | FVSYNC_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 15 : TFT 18 Bit SVGA - 60Hz (Similar to type 4) ++ * - NEC 12.1" 800x600 TX31D24VC1CAA ++ */ ++ { /* Flat panel control */ ++ 800, 600, 60, ++ ++ /* Flat panel Control */ ++ FP_TYPE_TFT ++ | FP_COLOR ++ | TFT_18BITS_COLOR ++ | DITHER_PATTERN_3 ++ | DITHER_BASE_6BITS ++ , ++ ++ /* Flat panel pin control */ ++ FSCLK_OUTPUT_ENABLE ++ | FHSYNC_ACTIVE_L ++ | FVSYNC_ACTIVE_L ++ | FSCLK_ACTIVE_L ++ | FSCLK_DELAY ++ , ++ /* STN panel control */ ++ 0x00bd0001 ++ }, ++ ++ /* Type 16 : SSTN VGA 8Bit Color - 90Hz ++ * - Sharp LM8M64 SSTN 640x240 8-bit color interface ++ */ ++ { /* Flat panel control */ ++ 640, 240, 90, ++ ++ FP_TYPE_SSTN ++ | FP_COLOR ++ | SSTN_8BITS_MONOCLR ++ | DITHER_PATTERN_1 ++ | DITHER_BASE_4BITS ++ | FRC_16LEVEL ++ | 0x00400000 ++ , ++ ++ FSCLK_OUTPUT_ENABLE ++ | SCLK_MASK ++ | FDE_ACTIVE_L ++ , ++ ++ /* STN panel control */ ++ 0x00bd0000 ++ } ++}; ++ ++/* Flat panel FRC weight/pattern registers - for SSTN and DSTN panel only ++ * ++ */ ++FRC_CONTROL FRCControlData[] = ++{ ++ { ++ { ++ 0x97A4C5F8, ++ 0x61E3DB02, ++ 0xD3E081BC, ++ 0x25A79F46, ++ 0x5B680934, ++ 0xAD2F17CE, ++ 0x1F2C4D70, ++ 0xE96B538A, ++ 0x0E3D5C61, ++ 0xF87A429B, ++ 0x4A791825, ++ 0xBC3E06DF, ++ 0xC2F190AD, ++ 0x34B68E57, ++ 0x86B5D4E9, ++ 0x70F2CA13, ++ 0xF1C2A39E, ++ 0x0785BD64, ++ 0xB586E7DA, ++ 0x43C1F920, ++ 0x3D0E6F52, ++ 0xCB4971A8, ++ 0x794A2B16, ++ 0x8F0D35EC, ++ 0x685B3A07, ++ 0x9E1C24FD, ++ 0x2C1F7E43, ++ 0xDA5860B9, ++ 0xA497F6CB, ++ 0x52D0E831, ++ 0xE0D3B28F, ++ 0x1694AC75, ++ }, ++ ++ { ++ /* FRC weight data */ ++ 0x80800000, ++ 0x88888420, ++ 0x94a49248, ++ 0xaaaaaa54, ++ 0x6b5b55ab, ++ 0x77776db7, ++ 0x7f7f7bdf, ++ 0xffff7fff ++ } ++ }, ++ ++ /* FRC Pattern Data - 2FCA (for SSTN) */ ++ { ++ { ++ 0x97A4C5F8, ++ 0x61E3DB02, ++ 0xD3E081BC, ++ 0x25A79F46, ++ 0x4A791825, ++ 0xBC3E06DF, ++ 0x0E3D5C61, ++ 0xF87A429B, ++ 0xF1C2A39E, ++ 0x0785BD64, ++ 0xB586E7DA, ++ 0x43C1F920, ++ 0x2C1F7E43, ++ 0xDA5860B9, ++ 0x685B3A07, ++ 0x9E1C24FD, ++ 0xE0D3B28F, ++ 0x1694AC75, ++ 0xA497F6CB, ++ 0x52D0E831, ++ 0x3D0E6F52, ++ 0xCB4971A8, ++ 0x794A2B16, ++ 0x8F0D35EC, ++ 0x86B5D4E9, ++ 0x70F2CA13, ++ 0xC2F190AD, ++ 0x34B68E57, ++ 0x5B680934, ++ 0xAD2F17CE, ++ 0x1F2C4D70, ++ 0xE96B538A, ++ }, ++ ++ { ++ /* FRC weight data */ ++ 0x80800000, ++ 0x88888420, ++ 0x94a49248, ++ 0xaaaaaa54, ++ 0x6b5b55ab, ++ 0x77776db7, ++ 0x7f7f7bdf, ++ 0xffff7fff ++ } ++ }, ++ ++ /* FRC Pattern Data - (for Panletype 4-> Simpad) */ ++ { ++ { ++ 0x97A4C5F8, ++ 0x61E3DB02, ++ 0x3D0E6F52, ++ 0xCB4971A8, ++ 0x794A2B16, ++ 0x8F0D35EC, ++ 0xD3E081BC, ++ 0x25A79F46, ++ 0x1F2C4D70, ++ 0xE96B538A, ++ 0xB586E7DA, ++ 0x43C1F920, ++ 0xF1C2A39E, ++ 0x0785BD64, ++ 0x5B680934, ++ 0xAD2F17CE, ++ 0x794A2B16, ++ 0x8F0D35EC, ++ 0xD3E081BC, ++ 0x25A79F46, ++ 0x97A4C5F8, ++ 0x61E3DB02, ++ 0x3D0E6F52, ++ 0xCB4971A8, ++ 0xF1C2A39E, ++ 0x0785BD64, ++ 0x5B680934, ++ 0xAD2F17CE, ++ 0x1F2C4D70, ++ 0xE96B538A, ++ 0xB586E7DA, ++ 0x43C1F920, ++ }, ++ { ++ /* FRC weight data */ ++ 0x80800000, ++ 0x88888420, ++ 0x94a49248, ++ 0xaaaaaa54, ++ 0x6b5b55ab, ++ 0x77776db7, ++ 0x7f7f7bdf, ++ 0xffff7fff ++ } ++ } ++}; ++#endif /* _VIDEO_MQ200_MQDATA_H */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/video/MQ200/mqmacros.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,86 @@ ++#ifndef _VIDEO_MQ200_MQMACROS_H ++#define _VIDEO_MQ200_MQMACROS_H ++ ++#ifdef CHECK_SRCFIFO ++ ++#define PUMP_PACKED_SRCFIFO(pSrcData,srcStride,nDwords,height,extras) \ ++ { \ ++ u32 *pData; \ ++ u32 i,j; \ ++ while( height-- ) \ ++ { \ ++ pData = (u32 *)((u32)(pSrcData + 3UL) & ~0x03UL); \ ++ j = nDwords; \ ++ while ( j >= SRC_FIFO_MAX_DWORDS ) \ ++ { \ ++ geWAITSRCFIFO( SRC_FIFO_MAX_DWORDS ); \ ++ for ( i = 0; i < SRC_FIFO_MAX_DWORDS; i++ ) \ ++ geREG(SRC_IMAGE_DATA, *pData++); \ ++ j -= SRC_FIFO_MAX_DWORDS; \ ++ } \ ++ geWAITSRCFIFO( j ); \ ++ while( j-- ) \ ++ geREG(SRC_IMAGE_DATA, *pData++); \ ++ pSrcData += srcStride; \ ++ } \ ++ geWAITSRCFIFO( extras ); \ ++ while( extras-- ) \ ++ geREG(SRC_IMAGE_DATA, 0UL); \ ++ } ++ ++ ++#define PUMP_REAL_PACKED_SRCFIFO(pSrcData,nDwords,extras) \ ++ { \ ++ u32 *pData =(u32 *)pSrcData; \ ++ u32 i; \ ++ while(nDwords) \ ++ { \ ++ if (nDwords >= SRC_FIFO_MAX_DWORDS) \ ++ { \ ++ geWAITSRCFIFO( SRC_FIFO_MAX_DWORDS ); \ ++ for (i = SRC_FIFO_MAX_DWORDS; i > 0; i--) \ ++ geREG(SRC_IMAGE_DATA, *pData++); \ ++ nDwords -= SRC_FIFO_MAX_DWORDS; \ ++ } \ ++ else \ ++ { \ ++ geWAITSRCFIFO( nDwords ); \ ++ for (i = nDwords; i > 0; i--) \ ++ geREG(SRC_IMAGE_DATA, *pData++); \ ++ nDwords -= nDwords; \ ++ } \ ++ } \ ++ geWAITSRCFIFO(extras); \ ++ while( extras-- ) \ ++ geREG(SRC_IMAGE_DATA, 0UL); \ ++ } ++ ++#else /* CHECK_SRCFIFO */ ++ ++#define PUMP_PACKED_SRCFIFO(pSrcData,srcStride,nDwords,height,extras) \ ++ { \ ++ u32 *pData; \ ++ u32 i; \ ++ while( height-- ) \ ++ { \ ++ pData = (u32 *)((u32)(pSrcData + 3UL) & ~0x03UL); \ ++ for ( i = 0; i < nDwords; i++ ) \ ++ geREG(SRC_IMAGE_DATA, *pData++); \ ++ pSrcData += srcStride; \ ++ } \ ++ while( extras-- ) \ ++ geREG(SRC_IMAGE_DATA, 0UL); \ ++ } ++ ++#define PUMP_REAL_PACKED_SRCFIFO(pSrcData,nDwords,extras) \ ++ { \ ++ u32 *pData =(u32 *)pSrcData; \ ++ while(nDwords--) \ ++ geREG(SRC_IMAGE_DATA, *pData++); \ ++ while( extras-- ) \ ++ geREG(SRC_IMAGE_DATA, 0UL); \ ++ } ++ ++#endif ++ ++#endif /* _VIDEO_MQ200_MQMACROS_H */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/video/MQ200/mqplat.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,106 @@ ++/*************************************************************************** ++ MQPLAT.H ++ ++ MQ200 platform, system or OS specific header file ++ ++ Copyright (c) 2000 by MediaQ, Incorporated. ++ All Rights Reserved. ++ ++***************************************************************************/ ++#ifndef _VIDEO_MQ200_MQPLAT_H ++#define _VIDEO_MQ200_MQPLAT_H ++ ++/* OS variation - ONLY define one */ ++#undef MQ_VXWORKS ++#undef MQ_EPOC32 ++#undef MQ_WINCE ++#undef MQ_OS9 ++#define MQ_LINUX ++ ++/* CPU variation - ONLY define one */ ++#undef MQ_X86 ++#define MQ_SA1110 ++#undef MQ_MIPS_NEC ++#undef MQ_MIPS_TOSHIBA ++#undef MQ_SH4 ++ ++/* PCI support - undef accordingly */ ++#undef MQ_PCI ++#ifdef MQ_PCI ++ #warning "MQ200 driver compiled for PCI !" ++#endif ++ ++/* Derived equates from CPU type */ ++#ifdef MQ_SHx ++ #warning "MQ200 driver compiled for SHx !" ++ #define FB_BASE 0x93800000L /* MQ200 frame buffer adddr */ ++#endif ++ ++#ifdef MQ_MIPS_NEC ++ #warning "MQ200 driver compiled for NEC MIPS !" ++ #define CHECK_FIFO_REQUIRED /* GE fifo checking required */ ++ #define FB_BASE 0xAA000000L ++ ++ #ifdef MQ_PCI ++ #define IOREGS_BASE 0xAF000000L /* for VR4122 */ ++ #define IOREGS_SIZE 0x00002000L ++ #else ++ #define IOREGS_BASE 0xAB000000L /* for VR 4111/21 */ ++ #define IOREGS_SIZE 0x00001000L ++ #define CHECK_NOTBUSY /* Needed for NEC MIPS */ ++ #define CHECK_CMDFIFO /* Needed for NEC MIPS */ ++ #endif /* MQ_PCI */ ++#endif ++ ++#ifdef MQ_MIPS_TOSHIBA ++ #warning "MQ200 driver compiled for TOSHIBA MIPS !" ++ #define FB_BASE 0x6D800000L ++#endif ++ ++#ifdef MQ_SA1110 ++ #warning "MQ200 driver compiled for Intel SA1110 !" ++ #define FB_BASE_CS3 0x1b800000L /* configured as CS3 */ ++ #define FB_BASE_CS4 0x43800000L /* configured as CS4 */ ++#define FB_BASE_CS5 0x4b800000L /* configured as CS5 */ ++#define FB_BASE FB_BASE_CS5 /* change accordingly! */ ++#define REGISTER_BASE 0x4be00000L ++#endif ++ ++/* OS-derived misc defines */ ++#ifdef MQ_VXWORKS ++ #warning "MQ200 driver compiled for VxWorks !" ++ #define MQ_DELAY(cnt) taskDelay(cnt*30); ++ #define MQ_COLOR_RGB /* Color (32bit):ARGB */ ++#endif ++ ++#ifdef MQ_WINCE ++ #warning "MQ200 driver compiled for Window CE !" ++ #define MQ_DELAY(cnt) Sleep(cnt) ++#endif ++ ++#ifdef MQ_LINUX ++ #warning "MQ200 driver compiled for Linux !" ++/* #define MQ_DELAY(cnt) {volatile int delay; for (delay=0; delay<10000*cnt; delay++); } */ ++ ++#define MQ_DELAY(cnt) mdelay(cnt * 10) ++#endif ++ ++/* Further derivation ++#ifdef MQ_COLOR_RGB ++ #define GETR(color) (unsigned char)(color >> 16) ++ #define GETG(color) (unsigned char)((unsigned short)(color) >> 8) ++ #define GETB(color) (unsigned char)(color) ++ #define MAKERGB(r,g,b) ((unsigned long)(((unsigned char)(r)|\ ++ ((unsigned short)((unsigned char)(g))<<8))|\ ++ (((unsigned long)(unsigned char)(b))<<16))) ++#endif ++*/ ++ ++/* Cursor color */ ++#ifndef CURSOR_FGCLR ++ #define CURSOR_FGCLR 0x0000FFFF /* Yellow */ ++#endif ++#ifndef CURSOR_BGCLR ++ #define CURSOR_BGCLR 0x00000000 /* Black */ ++#endif ++#endif /* _VIDEO_MQ200_MQPLAT_H */ +--- /dev/null 2003-09-23 19:59:22.000000000 +0200 ++++ linux-2.4.25/include/video/MQ200/mqproto.h 2004-05-02 22:45:42.000000000 +0200 +@@ -0,0 +1,19 @@ ++/*************************************************************************** ++ MQPROTO.H ++ ++ MQ200 common function prototypes ++ ++ Copyright (c) 2000 by MediaQ, Incorporated. ++ All Rights Reserved. ++ ++***************************************************************************/ ++#ifndef MQPROTO_H ++#define MQPROTO_H ++ ++/* ++ * mqdata.h ++ */ ++extern FPDATA_CONTROL fpControlData[]; ++extern DISPLAY_TIMING TimingParam[]; ++ ++#endif /* MQPROTO_H */ +--- linux-2.4.25/init/do_mounts.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200 ++++ linux-2.4.25/init/do_mounts.c 2004-05-02 22:45:42.000000000 +0200 +@@ -789,7 +789,13 @@ + return; + } + printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); ++#ifdef CONFIG_SA1100_SIMPAD ++ /* no floppy -> cramfs */ ++ printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying cramfs.\n"); ++ ROOT_DEV = MKDEV(31, 2); ++#else + ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0); ++#endif + } + #endif + devfs_make_root(root_device_name); |