diff -urN linux-2.6.7/.config.dimmPC linux-2.6.7-vpac1/.config.dimmPC --- linux-2.6.7/.config.dimmPC 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/.config.dimmPC 2004-06-28 08:32:51.000000000 +0200 @@ -0,0 +1,710 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_HOTPLUG=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_ADIFCC 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_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set + +# +# Intel PXA2xx Implementations +# +CONFIG_ARCH_LUBBOCK=y +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +CONFIG_PXA25x=y +# CONFIG_SA1111 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +CONFIG_XSCALE_PMU=y + +# +# General setup +# +CONFIG_ZBOOT_ROM=y +CONFIG_ZBOOT_ROM_TEXT=0x40000 +CONFIG_ZBOOT_ROM_BSS=0xa0400000 + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +# CONFIG_PCMCIA_DEBUG is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_PXA2XX=y + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="mem=32M root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS0,38400" +# CONFIG_LEDS is not set +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 is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_LUBBOCK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_NETFILTER is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_ARM_CS89x0 is not set +CONFIG_ARM_AX88796=y +CONFIG_NE2000=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# 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_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_PXA_ALGO=y + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_PXA_ADAP=y + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_LM90 is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_DS1339=y +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_HFSPLUS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_PXA=y +# CONFIG_LCD_SHARP_LQ64D343 is not set +CONFIG_LCD_HITACHI_SX14Q004ZZA=y +# CONFIG_FB_PXA_PARAMETERS is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +CONFIG_SOUND_PXA_AC97=y +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# Misc devices +# + +# +# USB support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.6.7/.config.uPC linux-2.6.7-vpac1/.config.uPC --- linux-2.6.7/.config.uPC 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/.config.uPC 2004-06-28 09:40:11.000000000 +0200 @@ -0,0 +1,571 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_ADIFCC 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_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set + +# +# Intel PXA2xx Implementations +# +CONFIG_ARCH_LUBBOCK=y +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +CONFIG_PXA25x=y +# CONFIG_SA1111 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +CONFIG_XSCALE_PMU=y + +# +# General setup +# +CONFIG_ZBOOT_ROM=y +CONFIG_ZBOOT_ROM_TEXT=0x40000 +CONFIG_ZBOOT_ROM_BSS=0xa0400000 + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="mem=32M root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS0,38400" +# CONFIG_LEDS is not set +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 is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_LUBBOCK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_NETFILTER is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_ARM_CS89x0=y +# CONFIG_ARM_AX88796 is not set +CONFIG_CS89x0=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set + +# +# Input Device Drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# 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 +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_HFSPLUS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +CONFIG_SOUND_PXA_AC97=y +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_AD1980 is not set + +# +# Misc devices +# + +# +# USB support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.6.7/Makefile linux-2.6.7-vpac1/Makefile --- linux-2.6.7/Makefile 2004-06-16 07:19:37.000000000 +0200 +++ linux-2.6.7-vpac1/Makefile 2004-06-21 05:14:01.000000000 +0200 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 7 -EXTRAVERSION = +EXTRAVERSION =-vpac1 NAME=Zonked Quokka # *DOCUMENTATION* @@ -182,8 +182,8 @@ # Default value for CROSS_COMPILE is not to prefix executables # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile -ARCH ?= $(SUBARCH) -CROSS_COMPILE ?= +ARCH ?= arm +CROSS_COMPILE ?= arm-linux- # Architecture as present in compile.h UTS_MACHINE := $(ARCH) diff -urN linux-2.6.7/arch/arm/Kconfig linux-2.6.7-vpac1/arch/arm/Kconfig --- linux-2.6.7/arch/arm/Kconfig 2004-06-16 07:19:29.000000000 +0200 +++ linux-2.6.7-vpac1/arch/arm/Kconfig 2004-06-21 05:17:40.000000000 +0200 @@ -216,7 +216,7 @@ ##################################################################### # SA1111 support config SA1111 - bool + bool "SA1111 support" depends on ASSABET_NEPONSET || SA1100_ADSBITSY || SA1100_BADGE4 || SA1100_CONSUS || SA1100_GRAPHICSMASTER || SA1100_JORNADA720 || ARCH_LUBBOCK || SA1100_PFS168 || SA1100_PT_SYSTEM3 || SA1100_XP860 default y @@ -336,7 +336,7 @@ config CPU_FREQ bool "Support CPU clock change (EXPERIMENTAL)" - depends on (ARCH_SA1100 || ARCH_INTEGRATOR) && EXPERIMENTAL + depends on (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_PXA) && EXPERIMENTAL help CPU clock scaling allows you to change the clock speed of the running CPU on the fly. This is a nice method to save battery power, diff -urN linux-2.6.7/arch/arm/boot/compressed/misc.c linux-2.6.7-vpac1/arch/arm/boot/compressed/misc.c --- linux-2.6.7/arch/arm/boot/compressed/misc.c 2004-06-16 07:19:42.000000000 +0200 +++ linux-2.6.7-vpac1/arch/arm/boot/compressed/misc.c 2004-06-21 04:23:50.000000000 +0200 @@ -128,7 +128,7 @@ * gzip delarations */ #define OF(args) args -#define STATIC static +#define STATIC typedef unsigned char uch; typedef unsigned short ush; @@ -137,12 +137,12 @@ #define WSIZE 0x8000 /* Window size must be at least 32k, */ /* and a power of two */ -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ +unsigned char *inbuf; /* input buffer */ +unsigned char window[WSIZE]; /* Sliding window buffer */ -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ +unsigned int insize; /* valid bytes in inbuf */ +unsigned int inptr; /* index of next byte to be processed in inbuf */ +unsigned int outcnt; /* bytes in output buffer */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ @@ -181,9 +181,9 @@ extern char input_data[]; extern char input_data_end[]; -static uch *output_data; -static ulg output_ptr; -static ulg bytes_out; +unsigned char *output_data; +unsigned long output_ptr; +unsigned long bytes_out; static void *malloc(int size); static void free(void *where); @@ -194,8 +194,8 @@ static void puts(const char *); extern int end; -static ulg free_mem_ptr; -static ulg free_mem_ptr_end; +unsigned long free_mem_ptr; +unsigned long free_mem_ptr_end; #define HEAP_SIZE 0x2000 diff -urN linux-2.6.7/arch/arm/mach-pxa/generic.c linux-2.6.7-vpac1/arch/arm/mach-pxa/generic.c --- linux-2.6.7/arch/arm/mach-pxa/generic.c 2004-06-16 07:19:02.000000000 +0200 +++ linux-2.6.7-vpac1/arch/arm/mach-pxa/generic.c 2004-06-23 04:46:54.000000000 +0200 @@ -180,10 +180,16 @@ .resource = pxafb_resources, }; +static struct platform_device pxa_ac97_device = { + .name = "pxa-audio", + .id = 0, +}; + static struct platform_device *devices[] __initdata = { &pxamci_device, &udc_device, &pxafb_device, + &pxa_ac97_device, }; static int __init pxa_init(void) diff -urN linux-2.6.7/arch/arm/mach-pxa/lubbock.c linux-2.6.7-vpac1/arch/arm/mach-pxa/lubbock.c --- linux-2.6.7/arch/arm/mach-pxa/lubbock.c 2004-06-16 07:19:13.000000000 +0200 +++ linux-2.6.7-vpac1/arch/arm/mach-pxa/lubbock.c 2004-06-23 07:20:25.000000000 +0200 @@ -32,7 +32,10 @@ #include #include #include + +#ifdef CONFIG_SA1111 #include +#endif #include "generic.h" @@ -69,6 +72,7 @@ .unmask = lubbock_unmask_irq, }; +#ifdef CONFIG_SA1111 static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { @@ -83,6 +87,12 @@ pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); } +#endif + +#define PCMCIA_SLOT0_IRQ_GPIO 10 +#define PCMCIA_SLOT1_IRQ_GPIO 11 + +#define IDE_IRQ_GPIO 15 static void __init lubbock_init_irq(void) { @@ -96,9 +106,41 @@ set_irq_handler(irq, do_level_IRQ); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - +#ifdef CONFIG_SA1111 set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); set_irq_type(IRQ_GPIO(0), IRQT_FALLING); +#endif + +#ifdef CONFIG_PCMCIA_PXA2XX + set_irq_type( PCMCIA_SLOT0_IRQ_GPIO, IRQT_BOTHEDGE); + set_irq_type( PCMCIA_SLOT1_IRQ_GPIO, IRQT_BOTHEDGE); +#endif + +#ifdef CONFIG_BLK_DEV_IDEDISK + /* setup PCMCIA socket, used by IDE ctrl */ + set_irq_type(IRQ_GPIO(IDE_IRQ_GPIO), IRQT_RISING); + + GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | + GPIO_bit(GPIO49_nPWE) | + GPIO_bit(GPIO50_nPIOR) | + GPIO_bit(GPIO51_nPIOW) | + GPIO_bit(GPIO52_nPCE_1) | + GPIO_bit(GPIO53_nPCE_2); + + pxa_gpio_mode(GPIO48_nPOE_MD); + pxa_gpio_mode(GPIO49_nPWE_MD); + pxa_gpio_mode(GPIO50_nPIOR_MD); + pxa_gpio_mode(GPIO51_nPIOW_MD); + pxa_gpio_mode(GPIO52_nPCE_1_MD); + pxa_gpio_mode(GPIO53_nPCE_2_MD); + pxa_gpio_mode(GPIO54_pSKTSEL_MD); /* REVISIT: s/b dependent on num sockets */ + pxa_gpio_mode(GPIO55_nPREG_MD); + pxa_gpio_mode(GPIO56_nPWAIT_MD); + pxa_gpio_mode(GPIO57_nIOIS16_MD); + + MECR |= GPIO_bit(0); // configure socket count = 2 + MECR |= GPIO_bit(1); // enable PCMCIA ctrl +#endif } static int lubbock_udc_is_connected(void) @@ -111,6 +153,7 @@ // no D+ pullup; lubbock can't connect/disconnect in software }; +#ifdef CONFIG_SA1111 static struct resource sa1111_resources[] = { [0] = { .start = 0x10000000, @@ -130,7 +173,9 @@ .num_resources = ARRAY_SIZE(sa1111_resources), .resource = sa1111_resources, }; +#endif +#ifdef CONFIG_ARM_SMC91X static struct resource smc91x_resources[] = { [0] = { .start = 0x0c000000, @@ -155,40 +200,171 @@ .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; +#endif + +#ifdef CONFIG_ARM_AX88796 + +#define AX88796_ETH0_IRQ_GPIO 20 +#define AX88796_ETH1_IRQ_GPIO 19 + +static struct resource ax88796_resources_0[] = { + [0] = { + .start = 0xf0000400, + .end = 0xf00fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO(AX88796_ETH0_IRQ_GPIO), + .end = IRQ_GPIO(AX88796_ETH0_IRQ_GPIO), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ax88796_device_0 = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(ax88796_resources_0), + .resource = ax88796_resources_0, +}; + +static struct resource ax88796_resources_1[] = { + [0] = { + .start = 0xf1000400, + .end = 0xf10fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO(AX88796_ETH1_IRQ_GPIO), + .end = IRQ_GPIO(AX88796_ETH1_IRQ_GPIO), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ax88796_device_1 = { + .name = "ax88796", + .id = 1, + .num_resources = ARRAY_SIZE(ax88796_resources_1), + .resource = ax88796_resources_1, +}; +#endif +#ifdef CONFIG_ARM_CS89x0 + +#define CS8900_ETH0_IRQ_GPIO 14 +#define CS8900_ETH1_IRQ_GPIO 19 + +static struct resource cs8900_resources_0[] = { + [0] = { + .start = 0xf0000303, + .end = 0xf00fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO(CS8900_ETH0_IRQ_GPIO), + .end = IRQ_GPIO(CS8900_ETH0_IRQ_GPIO), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cs8900_device_0 = { + .name = "cs8900", + .id = 0, + .num_resources = ARRAY_SIZE(cs8900_resources_0), + .resource = cs8900_resources_0, +}; + +static struct resource cs8900_resources_1[] = { + [0] = { + .start = 0xf1000303, + .end = 0xf10fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO(CS8900_ETH1_IRQ_GPIO), + .end = IRQ_GPIO(CS8900_ETH1_IRQ_GPIO), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cs8900_device_1 = { + .name = "cs8900", + .id = 1, + .num_resources = ARRAY_SIZE(cs8900_resources_1), + .resource = cs8900_resources_1, +}; +#endif static struct platform_device *devices[] __initdata = { +#ifdef CONFIG_SA1111 &sa1111_device, +#endif +#ifdef CONFIG_ARM_SMC91X &smc91x_device, +#endif +#ifdef CONFIG_ARM_AX88796 + &ax88796_device_0, + &ax88796_device_1, +#endif +#ifdef CONFIG_ARM_CS89x0 + &cs8900_device_0, + &cs8900_device_1, +#endif }; -static struct pxafb_mach_info sharp_lm8v31 __initdata = { - .pixclock = 270000, +#ifdef CONFIG_LCD_SHARP_LQ64D343 +static struct pxafb_mach_info sharp_lq640d343 __initdata = { + .pixclock = 0, .xres = 640, .yres = 480, .bpp = 16, .hsync_len = 1, - .left_margin = 3, + .left_margin = 1, + .right_margin = 161, + .vsync_len = 32, + .upper_margin = 1, + .lower_margin = 32, + .sync = 0, + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + .lccr0 = 0x003008f8, + .lccr3 = 0x04700001, +}; +#elif defined(CONFIG_LCD_HITACHI_SX14Q004ZZA) +static struct pxafb_mach_info hitachi_sx14q004zza __initdata = { + .pixclock = 0, + .xres = 320, + .yres = 240, + .bpp = 8, + .hsync_len = 1, + .left_margin = 1, .right_margin = 3, .vsync_len = 1, - .upper_margin = 0, - .lower_margin = 0, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .upper_margin = 3, + .lower_margin = 1, + .sync = (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT), .cmap_greyscale = 0, .cmap_inverse = 0, .cmap_static = 0, - .lccr0 = LCCR0_SDS, - .lccr3 = LCCR3_PCP | LCCR3_Acb(255), + .lccr0 = 0x00300a78, + .lccr3 = 0x03400015, }; +#endif static void __init lubbock_init(void) { pxa_set_udc_info(&udc_info); - set_pxa_fb_info(&sharp_lm8v31); +#if defined(CONFIG_LCD_SHARP_LQ64D343) + set_pxa_fb_info(&sharp_lq640d343); +#elif defined(CONFIG_LCD_HITACHI_SX14Q004ZZA) + set_pxa_fb_info(&hitachi_sx14q004zza); +#endif (void) platform_add_devices(devices, ARRAY_SIZE(devices)); } static struct map_desc lubbock_io_desc[] __initdata = { - { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */ + { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE }, /* eth0 ctrl */ + { 0xf1000000, 0x0c000000, 0x00100000, MT_DEVICE }, /* eth1 ctrl */ + { 0xf5000000, 0x20000000, 0x00100000, MT_DEVICE }, /* IDE */ }; static void __init lubbock_map_io(void) @@ -215,10 +391,12 @@ PCFR |= PCFR_OPDE; } -MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") - MAINTAINER("MontaVista Software Inc.") +MACHINE_START(LUBBOCK, "Voipac XScale development platform") + MAINTAINER("Voipac Technologies") BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + BOOT_PARAMS(0xa0000100) MAPIO(lubbock_map_io) INITIRQ(lubbock_init_irq) INIT_MACHINE(lubbock_init) MACHINE_END + diff -urN linux-2.6.7/drivers/i2c/algos/Kconfig linux-2.6.7-vpac1/drivers/i2c/algos/Kconfig --- linux-2.6.7/drivers/i2c/algos/Kconfig 2004-06-16 07:19:52.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/i2c/algos/Kconfig 2004-06-23 02:29:59.000000000 +0200 @@ -42,5 +42,17 @@ tristate "MPC8xx CPM I2C interface" depends on 8xx && I2C +config I2C_PXA_ALGO + tristate "PXA I2C Algorithm" + depends on ARCH_PXA && I2C + help + This supports the use of the PXA I2C interface found on the Intel + PXA 25x and PXA 26x systems. Say Y if you have one of these. + You should also say Y for the PXA I2C peripheral driver support below. + + This support is also available as a module. If you want to compile + it as a module, say M here and read Documentation/modules.txt. + The module will be called i2c-algo-pxa. + endmenu diff -urN linux-2.6.7/drivers/i2c/algos/Makefile linux-2.6.7-vpac1/drivers/i2c/algos/Makefile --- linux-2.6.7/drivers/i2c/algos/Makefile 2004-06-16 07:19:43.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/i2c/algos/Makefile 2004-06-23 02:30:30.000000000 +0200 @@ -5,6 +5,7 @@ obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o +obj-$(CONFIG_I2C_PXA_ALGO) += i2c-algo-pxa.o ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) EXTRA_CFLAGS += -DDEBUG diff -urN linux-2.6.7/drivers/i2c/algos/i2c-algo-pxa.c linux-2.6.7-vpac1/drivers/i2c/algos/i2c-algo-pxa.c --- linux-2.6.7/drivers/i2c/algos/i2c-algo-pxa.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/i2c/algos/i2c-algo-pxa.c 2004-06-23 02:27:33.000000000 +0200 @@ -0,0 +1,384 @@ +/* + * i2c-algo-pxa.c + * + * I2C algorithm for the PXA I2C bus access. + * Byte driven algorithm similar to pcf. + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * + * 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. + * + * History: + * Apr 2002: Initial version [CS] + * Jun 2002: Properly seperated algo/adap [FB] + * Jan 2003: added limited signal handling [Kai-Uwe Bloem] + * Jan 2003: allow SMBUS_QUICK as valid msg [FB] + * Jun 2003: updated for 2.5 [Dustin McIntire] + * + */ +#include +#include + +#include +#include +#include +#include /* struct i2c_msg and others */ +#include + +#include + +/* + * Set this to zero to remove all the debug statements via dead code elimination. + */ +//#define DEBUG 1 + +#if DEBUG +static unsigned int i2c_debug = DEBUG; +#else +#define i2c_debug 0 +#endif + +static int pxa_scan = 1; + +static int i2c_pxa_valid_messages( struct i2c_msg msgs[], int num) +{ + int i; + if (num < 1 || num > MAX_MESSAGES){ + if( i2c_debug) + printk(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n", + MAX_MESSAGES, num); + return -EINVAL; + } + + /* check consistency of our messages */ + for (i=0;ialgo_data; + + /* increment number of bytes to read by one -- read dummy byte */ + for (i = 0; i <= count; i++) { + if (i!=0){ + /* set ACK to NAK for last received byte ICR[ACKNAK] = 1 + only if not a repeated start */ + + if ((i == count) && last) { + adap->transfer( last, I2C_RECEIVE, 0); + }else{ + adap->transfer( 0, I2C_RECEIVE, 1); + } + + timeout = adap->wait_for_interrupt(I2C_RECEIVE); + +#ifdef DEBUG + if (timeout==BUS_ERROR){ + printk(KERN_INFO "i2c_pxa_readbytes: bus error -> forcing reset\n"); + adap->reset(); + return I2C_RETRY; + } else +#endif + if (timeout == -ERESTARTSYS) { + adap->abort(); + return timeout; + } else + if (timeout){ +#ifdef DEBUG + printk(KERN_INFO "i2c_pxa_readbytes: timeout -> forcing reset\n"); +#endif + adap->reset(); + return I2C_RETRY; + } + + } + + if (i) { + buf[i - 1] = adap->read_byte(); + } else { + adap->read_byte(); /* dummy read */ + } + } + return (i - 1); +} + +static int i2c_pxa_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, + int count, int last) +{ + + struct i2c_algo_pxa_data *adap = i2c_adap->algo_data; + int wrcount, timeout; + + for (wrcount=0; wrcountwrite_byte(buf[wrcount]); + if ((wrcount==(count-1)) && last) { + adap->transfer( last, I2C_TRANSMIT, 0); + }else{ + adap->transfer( 0, I2C_TRANSMIT, 1); + } + + timeout = adap->wait_for_interrupt(I2C_TRANSMIT); + +#ifdef DEBUG + if (timeout==BUS_ERROR) { + printk(KERN_INFO "i2c_pxa_sendbytes: bus error -> forcing reset.\n"); + adap->reset(); + return I2C_RETRY; + } else +#endif + if (timeout == -ERESTARTSYS) { + adap->abort(); + return timeout; + } else + if (timeout) { +#ifdef DEBUG + printk(KERN_INFO "i2c_pxa_sendbytes: timeout -> forcing reset\n"); +#endif + adap->reset(); + return I2C_RETRY; + } + } + return (wrcount); +} + + +static inline int i2c_pxa_set_ctrl_byte(struct i2c_algo_pxa_data * adap, struct i2c_msg *msg) +{ + u16 flags = msg->flags; + u8 addr; + addr = (u8) ( (0x7f & msg->addr) << 1 ); + if (flags & I2C_M_RD ) + addr |= 1; + if (flags & I2C_M_REV_DIR_ADDR ) + addr ^= 1; + adap->write_byte(addr); + return 0; +} + +static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +{ + struct i2c_algo_pxa_data * adap; + struct i2c_msg *pmsg=NULL; + int i; + int ret=0, timeout; + + adap = i2c_adap->algo_data; + + timeout = adap->wait_bus_not_busy(); + + if (timeout) { + return I2C_RETRY; + } + + for (i = 0;ret >= 0 && i < num; i++) { + int last = i + 1 == num; + pmsg = &msgs[i]; + + ret = i2c_pxa_set_ctrl_byte(adap,pmsg); + + /* Send START */ + if (i == 0) { + adap->start(); + }else{ + adap->repeat_start(); + } + + adap->transfer(0, I2C_TRANSMIT, 0); + + /* Wait for ITE (transmit empty) */ + timeout = adap->wait_for_interrupt(I2C_TRANSMIT); + +#ifdef DEBUG + /* Check for ACK (bus error) */ + if (timeout==BUS_ERROR){ + printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n"); + adap->reset(); + return I2C_RETRY; + } else +#endif + if (timeout == -ERESTARTSYS) { + adap->abort(); + return timeout; + } else + if (timeout) { +#ifdef DEBUG + printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n"); +#endif + adap->reset(); + return I2C_RETRY; + } +/* FIXME: handle arbitration... */ +#if 0 + /* Check for bus arbitration loss */ + if (adap->arbitration_loss()){ + printk("Arbitration loss detected \n"); + adap->reset(); + return I2C_RETRY; + } +#endif + + /* Read */ + if (pmsg->flags & I2C_M_RD) { + /* read bytes into buffer*/ + ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last); +#if DEBUG > 2 + if (ret != pmsg->len) { + printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n", + ret, pmsg->len); + } else { + printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret); + } +#endif + } else { /* Write */ + ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last); +#if DEBUG > 2 + if (ret != pmsg->len) { + printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n", + ret, pmsg->len); + } else { + printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret); + } +#endif + } + } + + if (ret<0){ + return ret; + }else{ + return i; + } +} + +static int i2c_pxa_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +{ + int retval = i2c_pxa_valid_messages( msgs, num); + if( retval > 0) + { + int i; + for (i=i2c_adap->retries; i>=0; i--){ + int retval = i2c_pxa_do_xfer(i2c_adap,msgs,num); + if (retval!=I2C_RETRY){ + return retval; + } + if( i2c_debug)printk(KERN_INFO"Retrying transmission \n"); + udelay(100); + } + if( i2c_debug)printk(KERN_INFO"Retried %i times\n",i2c_adap->retries); + return -EREMOTEIO; + + } + return retval; +} + +static u32 i2c_pxa_functionality(struct i2c_adapter * adapter) +{ + /* Emulate the SMBUS functions */ + return I2C_FUNC_SMBUS_EMUL; +} + +struct i2c_algorithm i2c_pxa_algorithm = { + name: "PXA I2C Algorithm", + id: I2C_ALGO_PXA, + master_xfer: i2c_pxa_xfer, + smbus_xfer: NULL, + slave_send: NULL, + slave_recv: NULL, + algo_control: NULL, + functionality: i2c_pxa_functionality, +}; + +/* + * registering functions to load algorithms at runtime + */ +int i2c_pxa_add_bus(struct i2c_adapter *i2c_adap) +{ + struct i2c_algo_pxa_data *adap = i2c_adap->algo_data; + + printk(KERN_INFO"I2C: Adding %s.\n", i2c_adap->name); + + i2c_adap->algo = &i2c_pxa_algorithm; + + MOD_INC_USE_COUNT; + + /* register new adapter to i2c module... */ + i2c_add_adapter(i2c_adap); + + adap->reset(); + + /* scan bus */ + if (pxa_scan) { + int i; + printk(KERN_INFO "I2C: Scanning bus "); + for (i = 0x02; i < 0xff; i+=2) { + if( i==(I2C_PXA_SLAVE_ADDR<<1)) continue; + + if (adap->wait_bus_not_busy()) { + printk(KERN_INFO "I2C: scanning bus %s - TIMEOUT.\n", + i2c_adap->name); + return -EIO; + } + adap->write_byte(i); + adap->start(); + adap->transfer(0, I2C_TRANSMIT, 0); + + if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) { + printk("(%02x)",i>>1); + adap->abort(); + } else { +// printk("."); + adap->stop(); + } + udelay(adap->udelay); + } + printk("\n"); + } + return 0; +} + +int i2c_pxa_del_bus(struct i2c_adapter *i2c_adap) +{ + int res; + if ((res = i2c_del_adapter(i2c_adap)) < 0) + return res; + + MOD_DEC_USE_COUNT; + + printk(KERN_INFO "I2C: Removing %s.\n", i2c_adap->name); + + return 0; +} + +static int __init i2c_algo_pxa_init (void) +{ + printk(KERN_INFO "I2C: PXA algorithm module loaded.\n"); + return 0; +} + +EXPORT_SYMBOL(i2c_pxa_add_bus); +EXPORT_SYMBOL(i2c_pxa_del_bus); + +MODULE_PARM(pxa_scan, "i"); +MODULE_PARM_DESC(pxa_scan, "Scan for active chips on the bus"); + +MODULE_AUTHOR("Intrinsyc Software Inc."); +MODULE_LICENSE("GPL"); + +module_init(i2c_algo_pxa_init); diff -urN linux-2.6.7/drivers/i2c/busses/Kconfig linux-2.6.7-vpac1/drivers/i2c/busses/Kconfig --- linux-2.6.7/drivers/i2c/busses/Kconfig 2004-06-16 07:19:52.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/i2c/busses/Kconfig 2004-06-23 02:32:15.000000000 +0200 @@ -396,4 +396,16 @@ This driver can also be built as a module. If so, the module will be called i2c-voodoo3. +config I2C_PXA_ADAP + tristate "PXA I2C Adapter" + depends on I2C_PXA_ALGO + help + This supports the use of the PXA I2C interface found on the Intel + PXA 25x and PXA 26x systems. Say Y if you have one of these. + You should also say Y for the PXA I2C driver algorithm support above. + + This support is also available as a module. If you want to compile + it as a module, say M here and read Documentation/modules.txt. + The module will be called i2c-adap-pxa. + endmenu diff -urN linux-2.6.7/drivers/i2c/busses/Makefile linux-2.6.7-vpac1/drivers/i2c/busses/Makefile --- linux-2.6.7/drivers/i2c/busses/Makefile 2004-06-16 07:18:57.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/i2c/busses/Makefile 2004-06-23 02:32:44.000000000 +0200 @@ -32,6 +32,7 @@ obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o +obj-$(CONFIG_I2C_PXA_ADAP) += i2c-adap-pxa.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG diff -urN linux-2.6.7/drivers/i2c/busses/i2c-adap-pxa.c linux-2.6.7-vpac1/drivers/i2c/busses/i2c-adap-pxa.c --- linux-2.6.7/drivers/i2c/busses/i2c-adap-pxa.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/i2c/busses/i2c-adap-pxa.c 2004-06-23 02:28:17.000000000 +0200 @@ -0,0 +1,388 @@ +/* + * i2c_adap_pxa.c + * + * I2C adapter for the PXA I2C bus access. + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * + * 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. + * + * History: + * Apr 2002: Initial version [CS] + * Jun 2002: Properly seperated algo/adap [FB] + * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem] + * Jan 2003: added limited signal handling [Kai-Uwe Bloem] + * Jun 2003: updated for 2.5 [Dustin McIntire] + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include /* for IRQ_I2C */ + +#include + +/* + * Set this to zero to remove all debug statements via dead code elimination. + */ +//#define DEBUG 1 + +#if DEBUG +static unsigned int i2c_debug = DEBUG; +#else +#define i2c_debug 0 +#endif + +static int irq = 0; +static volatile int i2c_pending = 0; /* interrupt pending when 1 */ +static volatile int bus_error = 0; +static volatile int tx_finished = 0; +static volatile int rx_finished = 0; + +static wait_queue_head_t i2c_wait; +static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte); + +/* place a byte in the transmit register */ +static void i2c_pxa_write_byte(u8 value) +{ + IDBR = value; +} + +/* read byte in the receive register */ +static u8 i2c_pxa_read_byte(void) +{ + return (u8) (0xff & IDBR); +} + +static void i2c_pxa_start(void) +{ + unsigned long icr = ICR; + icr |= ICR_START; + icr &= ~(ICR_STOP | ICR_ALDIE | ICR_ACKNAK); + ICR = icr; + + bus_error=0; /* clear any bus_error from previous txfers */ + tx_finished=0; /* clear rx and tx interrupts from previous txfers */ + rx_finished=0; + i2c_pending = 0; +} + +static void i2c_pxa_repeat_start(void) +{ + unsigned long icr = ICR; + icr |= ICR_START; + icr &= ~(ICR_STOP | ICR_ALDIE); + ICR = icr; + + bus_error=0; /* clear any bus_error from previous txfers */ + tx_finished=0; /* clear rx and tx interrupts from previous txfers */ + rx_finished=0; + i2c_pending = 0; +} + +static void i2c_pxa_stop(void) +{ + unsigned long icr = ICR; + icr |= ICR_STOP; + icr &= ~(ICR_START); + ICR = icr; +} + +static void i2c_pxa_midbyte(void) +{ + unsigned long icr = ICR; + icr &= ~(ICR_START | ICR_STOP); + ICR = icr; +} + +static void i2c_pxa_abort(void) +{ + unsigned long timeout = jiffies + HZ/4; + +#ifdef PXA_ABORT_MA + while ((long)(timeout - jiffies) > 0 && (ICR & ICR_TB)) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + + ICR |= ICR_MA; + udelay(100); +#else + while ((long)(timeout - jiffies) > 0 && (IBMR & 0x1) == 0) { + i2c_pxa_transfer( 1, I2C_RECEIVE, 1); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } +#endif + ICR &= ~(ICR_MA | ICR_START | ICR_STOP); +} + +static int i2c_pxa_wait_bus_not_busy( void) +{ + int timeout = DEF_TIMEOUT; + + while (timeout-- && (ISR & ISR_IBB)) { + udelay(100); /* wait for 100 us */ + } + + return (timeout<=0); +} + +spinlock_t i2c_pxa_irqlock = SPIN_LOCK_UNLOCKED; + +static void i2c_pxa_wait_for_ite(void){ + unsigned long flags; + if (irq > 0) { + spin_lock_irqsave(&i2c_pxa_irqlock, flags); + if (i2c_pending == 0) { + interruptible_sleep_on_timeout(&i2c_wait, I2C_SLEEP_TIMEOUT ); + } + i2c_pending = 0; + spin_unlock_irqrestore(&i2c_pxa_irqlock, flags); + } else { + udelay(100); + } +} + +static int i2c_pxa_wait_for_int( int wait_type) +{ + int timeout = DEF_TIMEOUT; +#ifdef DEBUG + if (bus_error) + printk(KERN_INFO"i2c_pxa_wait_for_int: Bus error on enter\n"); + if (rx_finished) + printk(KERN_INFO"i2c_pxa_wait_for_int: Receive interrupt on enter\n"); + if (tx_finished) + printk(KERN_INFO"i2c_pxa_wait_for_int: Transmit interrupt on enter\n"); +#endif + + if (wait_type == I2C_RECEIVE){ /* wait on receive */ + + do { + i2c_pxa_wait_for_ite(); + } while (!(rx_finished) && timeout-- && !signal_pending(current)); + +#ifdef DEBUG + if (timeout<0){ + if (tx_finished) + printk("Error: i2c-algo-pxa.o: received a tx" + " interrupt while waiting on a rx in wait_for_int"); + } +#endif + } else { /* wait on transmit */ + + do { + i2c_pxa_wait_for_ite(); + } while (!(tx_finished) && timeout-- && !signal_pending(current)); + +#ifdef DEBUG + if (timeout<0){ + if (rx_finished) + printk("Error: i2c-algo-pxa.o: received a rx" + " interrupt while waiting on a tx in wait_for_int"); + } +#endif + } + + udelay(ACK_DELAY); /* this is needed for the bus error */ + + tx_finished=0; + rx_finished=0; + + if (bus_error){ + bus_error=0; + if( i2c_debug > 2)printk("wait_for_int: error - no ack.\n"); + return BUS_ERROR; + } + + if (signal_pending(current)) { + return (-ERESTARTSYS); + } else if (timeout < 0) { + if( i2c_debug > 2)printk("wait_for_int: timeout.\n"); + return(-EIO); + } else + return(0); +} + +static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte) +{ + if( lastbyte) + { + if( receive==I2C_RECEIVE) ICR |= ICR_ACKNAK; + i2c_pxa_stop(); + } + else if( midbyte) + { + i2c_pxa_midbyte(); + } + ICR |= ICR_TB; +} + +static void i2c_pxa_reset( void) +{ +#ifdef DEBUG + printk("Resetting I2C Controller Unit\n"); +#endif + + /* abort any transfer currently under way */ + i2c_pxa_abort(); + + /* reset according to 9.8 */ + ICR = ICR_UR; + ISR = I2C_ISR_INIT; + ICR &= ~ICR_UR; + + /* set the global I2C clock on */ + CKEN |= CKEN14_I2C; + + /* set our slave address */ + ISAR = I2C_PXA_SLAVE_ADDR; + + /* set control register values */ + ICR = I2C_ICR_INIT; + + /* clear any leftover states from prior transmissions */ + i2c_pending = rx_finished = tx_finished = bus_error = 0; + + /* enable unit */ + ICR |= ICR_IUE; + udelay(100); +} + +static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long flags; + int status, wakeup = 0; + status = (ISR); + + if (status & ISR_BED){ + (ISR) |= ISR_BED; + bus_error=ISR_BED; + wakeup = 1; + } + if (status & ISR_ITE){ + (ISR) |= ISR_ITE; + tx_finished=ISR_ITE; + wakeup = 1; + } + if (status & ISR_IRF){ + (ISR) |= ISR_IRF; + rx_finished=ISR_IRF; + wakeup = 1; + } + if (wakeup) { + spin_lock_irqsave(&i2c_pxa_irqlock, flags); + i2c_pending = 1; + spin_unlock_irqrestore(&i2c_pxa_irqlock, flags); + wake_up_interruptible(&i2c_wait); + } + return IRQ_HANDLED; +} + +static int i2c_pxa_resource_init( void) +{ + init_waitqueue_head(&i2c_wait); + + irq = IRQ_I2C; + + if (request_irq( irq, &i2c_pxa_handler, SA_INTERRUPT, "I2C", 0) < 0) { + irq = 0; + if(i2c_debug) + printk(KERN_INFO "I2C: Failed to register I2C irq %i\n", IRQ_I2C); + return -ENODEV; + } + return 0; +} + +static void i2c_pxa_resource_release( void) +{ + if( irq > 0) + { + disable_irq(irq); + free_irq(irq,0); + irq=0; + } +} + +static int i2c_pxa_client_register(struct i2c_client *client) +{ + return 0; +} + +static int i2c_pxa_client_unregister(struct i2c_client *client) +{ + return 0; +} + +static struct i2c_algo_pxa_data i2c_pxa_data = { + write_byte: i2c_pxa_write_byte, + read_byte: i2c_pxa_read_byte, + + start: i2c_pxa_start, + repeat_start: i2c_pxa_repeat_start, + stop: i2c_pxa_stop, + abort: i2c_pxa_abort, + + wait_bus_not_busy: i2c_pxa_wait_bus_not_busy, + wait_for_interrupt: i2c_pxa_wait_for_int, + transfer: i2c_pxa_transfer, + reset: i2c_pxa_reset, + + udelay: 10, + timeout: DEF_TIMEOUT, +}; + +static struct i2c_adapter i2c_pxa_ops = { + .owner = THIS_MODULE, + .id = I2C_ALGO_PXA, + .algo_data = &i2c_pxa_data, + .name = "PXA I2C Adapter", + .client_register = i2c_pxa_client_register, + .client_unregister = i2c_pxa_client_unregister, + .retries = 2, +}; + +extern int i2c_pxa_add_bus(struct i2c_adapter *); +extern int i2c_pxa_del_bus(struct i2c_adapter *); + +static int __init i2c_adap_pxa_init(void) +{ + if( i2c_pxa_resource_init() == 0) { + + if (i2c_pxa_add_bus(&i2c_pxa_ops) < 0) { + i2c_pxa_resource_release(); + printk(KERN_INFO "I2C: Failed to add bus\n"); + return -ENODEV; + } + } else { + return -ENODEV; + } + + printk(KERN_INFO "I2C: Successfully added bus\n"); + + return 0; +} + +static void i2c_adap_pxa_exit(void) +{ + i2c_pxa_del_bus( &i2c_pxa_ops); + i2c_pxa_resource_release(); + + printk(KERN_INFO "I2C: Successfully removed bus\n"); +} + +module_init(i2c_adap_pxa_init); +module_exit(i2c_adap_pxa_exit); diff -urN linux-2.6.7/drivers/i2c/chips/Kconfig linux-2.6.7-vpac1/drivers/i2c/chips/Kconfig --- linux-2.6.7/drivers/i2c/chips/Kconfig 2004-06-16 07:19:35.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/i2c/chips/Kconfig 2004-06-23 02:38:25.000000000 +0200 @@ -250,4 +250,8 @@ This driver can also be built as a module. If so, the module will be called i2c-rtc8564. +config SENSORS_DS1339 + tristate "DS1339 Real time clock" + depends on I2C + endmenu diff -urN linux-2.6.7/drivers/i2c/chips/Makefile linux-2.6.7-vpac1/drivers/i2c/chips/Makefile --- linux-2.6.7/drivers/i2c/chips/Makefile 2004-06-16 07:20:26.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/i2c/chips/Makefile 2004-06-23 02:38:53.000000000 +0200 @@ -25,6 +25,7 @@ obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o +obj-$(CONFIG_SENSORS_DS1339) += ds1339.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff -urN linux-2.6.7/drivers/i2c/chips/ds1339.c linux-2.6.7-vpac1/drivers/i2c/chips/ds1339.c --- linux-2.6.7/drivers/i2c/chips/ds1339.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/i2c/chips/ds1339.c 2004-06-23 02:37:40.000000000 +0200 @@ -0,0 +1,355 @@ +/* + * ds1339.c + * + * Device driver for Dallas Semiconductor's Real Time Controller ds1339. + * + * Copyright (C) 2003 Voipac + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ds1339.h" + +//#define RTC_DEBUG + +static unsigned short slave_address = DS1339_I2C_SLAVE_ADDR; + +struct i2c_driver ds1339_driver; +struct i2c_client *ds1339_i2c_client = 0; + +static unsigned short ignore[] = { I2C_CLIENT_END }; +static unsigned short normal_addr[] = { DS1339_I2C_SLAVE_ADDR, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c: normal_addr, + normal_i2c_range: ignore, + probe: ignore, + probe_range: ignore, + ignore: ignore, + ignore_range: ignore, + force: ignore, +}; + +static int ds1339_rtc_ioctl( struct inode *, struct file *, unsigned int, unsigned long); +static int ds1339_rtc_open(struct inode *inode, struct file *file); +static int ds1339_rtc_release(struct inode *inode, struct file *file); + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + ioctl: ds1339_rtc_ioctl, + open: ds1339_rtc_open, + release: ds1339_rtc_release, +}; + +static struct miscdevice ds1339_rtc_miscdev = { + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int ds1339_attach_adapter(struct i2c_adapter *adap); +static int ds1339_detach_client(struct i2c_client *client); + +struct i2c_driver ds1339_driver = { + name: "ds1339", + owner: THIS_MODULE, + id: I2C_DRIVERID_DS1339, + flags: I2C_DF_NOTIFY, + attach_adapter: ds1339_attach_adapter, + detach_client: ds1339_detach_client +}; + +static spinlock_t ds1339_rtc_lock = SPIN_LOCK_UNLOCKED; + +static void ds1339_osc_enable(struct i2c_client *client) +{ +#ifdef RTC_DEBUG + printk ("ds1339_osc_enable\n"); +#endif + if( client) + { + unsigned long flags; + unsigned char buf[2], ad[1] = { DS1339_CONTROL_ADDR }; + struct i2c_msg msgs[2] = { + { client->addr, 0, 1, ad }, + { client->addr, I2C_M_RD, 1, buf } + }; + + // read ds1339 control register + spin_lock_irqsave(&ds1339_rtc_lock, flags); + i2c_transfer(client->adapter, msgs, 2); + spin_unlock_irqrestore(&ds1339_rtc_lock,flags); + + buf[1] = buf[0] & ~DS1339_OSC_ENABLE; // clear oscilator enable bit + buf[0] = DS1339_CONTROL_ADDR; // control register address on ds1339 + + if( i2c_master_send(client, (char *)buf, 2) != 2) + printk ("ds1339_osc_enable: i2c_master_send failed.\n"); + } +} + +static int ds1339_convert_to_time( struct rtc_time *dt, char* buf) +{ +#ifdef RTC_DEBUG + printk("ds1339_convert_to_time\n"); +#endif + + memset( dt, 0, sizeof(struct rtc_time)); + + dt->tm_sec = BCD_TO_BIN(buf[0]); + dt->tm_min = BCD_TO_BIN(buf[1]); + + if ( TWELVE_HOUR_MODE(buf[2]) ) + { + dt->tm_hour = HOURS_12(buf[2]); + if (HOURS_AP(buf[2])) // pm + dt->tm_hour += 12; + } + else // 24-hour-mode + dt->tm_hour = HOURS_24(buf[2]); + + dt->tm_mday = BCD_TO_BIN(buf[4]); + // dt->tm_mon is zero-based + dt->tm_mon = BCD_TO_BIN(buf[5]) - 1; + // year is 1900 + dt->tm_year + dt->tm_year = BCD_TO_BIN(buf[6]) + 100; + +#ifdef RTC_DEBUG + printk("ds1339_get_datetime: year = %d\n", dt->tm_year); + printk("ds1339_get_datetime: mon = %d\n", dt->tm_mon); + printk("ds1339_get_datetime: mday = %d\n", dt->tm_mday); + printk("ds1339_get_datetime: hour = %d\n", dt->tm_hour); + printk("ds1339_get_datetime: min = %d\n", dt->tm_min); + printk("ds1339_get_datetime: sec = %d\n", dt->tm_sec); +#endif + return 0; +} + +static int ds1339_get_datetime(struct i2c_client *client, struct rtc_time *dt) +{ + int ret = -EINVAL; + + if( client) + { + unsigned long flags; + unsigned char buf[DS1339_BCD_CNT_SIZE], addr[1] = { DS1339_BCD_CNT_ADDR }; + struct i2c_msg msgs[2] = { + { client->addr, 0, 1, addr }, + { client->addr, I2C_M_RD, DS1339_BCD_CNT_SIZE, buf } + }; + + memset(buf, 0, sizeof(buf)); + + spin_lock_irqsave(&ds1339_rtc_lock, flags); + ret = i2c_transfer(client->adapter, msgs, 2); + spin_unlock_irqrestore(&ds1339_rtc_lock,flags); + + if (ret == 2) + return ds1339_convert_to_time( dt, buf); + else + printk("ds1339_get_datetime: i2c_transfer returned %d\n",ret); + } + return ret; +} + +static int ds1339_detect(struct i2c_adapter *adap, int addr, int kind) +{ + struct i2c_client *client; + struct rtc_time dt; + +#ifdef RTC_DEBUG + printk ("ds1339_detect\n"); +#endif + if( (client = (struct i2c_client *) kmalloc( sizeof(struct i2c_client), GFP_KERNEL)) == NULL) + return -ENOMEM; + + memset( client, 0, sizeof(struct i2c_client)); + + strncpy( client->name, "ds1339", I2C_NAME_SIZE); + client->id = ds1339_driver.id; + client->flags = 0; + client->addr = addr; + client->adapter = adap; + client->driver = &ds1339_driver; + + if( ds1339_get_datetime( client, &dt) != 0) + printk ("ds1339_attach: i2c_transfer failed.\n"); + + ds1339_i2c_client = client; + ds1339_osc_enable(ds1339_i2c_client); + + return i2c_attach_client(client); +} + +static int ds1339_attach_adapter(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, ds1339_detect); +} + +static int ds1339_detach_client(struct i2c_client *client) +{ + i2c_detach_client(client); + + kfree(client); + ds1339_i2c_client = 0; + + return 0; +} + +static int ds1339_set_datetime(struct i2c_client *client, struct rtc_time *dt) +{ + int ret = -EIO; + unsigned long flags; + unsigned char buf[DS1339_BCD_CNT_SIZE+1]; + + if( client) + { +#ifdef RTC_DEBUG + printk("ds1339_set_datetime: year=%d,month=%d,mday=%d,hour=%d,min=%d,sec=%d\n", + dt->tm_year,dt->tm_mon,dt->tm_mday,dt->tm_hour,dt->tm_min,dt->tm_sec); +#endif + buf[0] = DS1339_BCD_CNT_ADDR; // register address on ds1339 + buf[1] = (BIN_TO_BCD(dt->tm_sec)); + buf[2] = (BIN_TO_BCD(dt->tm_min)); + buf[3] = (BIN_TO_BCD(dt->tm_hour)); + + buf[5] = (BIN_TO_BCD(dt->tm_mday)); + buf[6] = (BIN_TO_BCD(dt->tm_mon + 1)); + // The year only ranges from 0-99, we are being passed an offset from 1900 + // and the chip calulates leap years based on 2000, thus we adjust by 100. + buf[7] = (BIN_TO_BCD(dt->tm_year - 100)); + + spin_lock_irqsave(&ds1339_rtc_lock, flags); + ret = i2c_master_send(client, (char *)buf, DS1339_BCD_CNT_SIZE+1); + spin_unlock_irqrestore(&ds1339_rtc_lock,flags); + + if (ret != (DS1339_BCD_CNT_SIZE+1)) + printk("ds1339_set_datetime: i2c_master_send returned %d\n",ret); + } + return ret; +} + +static int ds1339_rtc_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int ds1339_rtc_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static int ds1339_rtc_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct rtc_time wtime; + + switch (cmd) + { + case RTC_RD_TIME: + ds1339_get_datetime(ds1339_i2c_client, &wtime); + + if( copy_to_user((void *)arg, &wtime, sizeof (struct rtc_time))) + return -EFAULT; + break; + + case RTC_SET_TIME: + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&wtime, (struct rtc_time *)arg, sizeof(struct rtc_time)) ) + return -EFAULT; + + if( wtime.tm_year < 100) // ds1339 base is year 2000 + return -EINVAL; + + ds1339_set_datetime(ds1339_i2c_client, &wtime); + + break; + + default: + return -EINVAL; + } + + return 0; +} + +static char* ds1339_mon2str( unsigned int mon) +{ + char *mon2str[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + return mon2str[mon%12]; +} + +static int ds1339_rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + struct rtc_time dt; + + len += sprintf(page + len, "Voipac ds1339 RTC driver (c) 2003\n\n"); + + if( ds1339_get_datetime(ds1339_i2c_client, &dt) == 0) + { + len += sprintf(page + len, "Date/Time : %02d-%s-%04d %02d:%02d:%02d\n", + dt.tm_mday, ds1339_mon2str(dt.tm_mon), dt.tm_year + 1900, dt.tm_hour, dt.tm_min, dt.tm_sec); + } + *eof = 1; + + return len; +} + +static __init int ds1339_init(void) +{ + if( slave_address != 0xffff) + normal_addr[0] = slave_address; + + if( normal_addr[0] > 127) + { + printk(KERN_ERR"I2C: Invalid slave address for ds1339 RTC (%#x)\n", normal_addr[0]); + return -EINVAL; + } + + if( i2c_add_driver(&ds1339_driver) == 0) + { + misc_register (&ds1339_rtc_miscdev); + create_proc_read_entry (PROC_DS1339_NAME, 0, 0, ds1339_rtc_read_proc, NULL); + printk("I2C: ds1339 RTC driver successfully loaded\n"); + } + return 0; +} + +static __exit void ds1339_exit(void) +{ + remove_proc_entry (PROC_DS1339_NAME, NULL); + misc_deregister(&ds1339_rtc_miscdev); + i2c_del_driver(&ds1339_driver); +} + +module_init(ds1339_init); +module_exit(ds1339_exit); + +MODULE_PARM (slave_address, "i"); +MODULE_PARM_DESC (slave_address, "I2C slave address for ds1339 RTC"); + +MODULE_AUTHOR ("Voipac"); +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.7/drivers/i2c/chips/ds1339.h linux-2.6.7-vpac1/drivers/i2c/chips/ds1339.h --- linux-2.6.7/drivers/i2c/chips/ds1339.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/i2c/chips/ds1339.h 2004-06-23 02:37:40.000000000 +0200 @@ -0,0 +1,43 @@ +/* + * ds1339.h + * + * Copyright (C) 2003 Voipac + * + * 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. + * + */ +#ifndef DS1339_H +#define DS1339_H + +#define DS1339_I2C_SLAVE_ADDR 0x68 + +#define I2C_DRIVERID_DS1339 61 + +#define DS1339_BCD_CNT_ADDR 0x00 // counter start address +#define DS1339_BCD_CNT_SIZE 0x07 // counter length (bytes) + +#define DS1339_ALARM1_ADDR 0x07 +#define DS1339_ALARM1_SIZE 0x04 + +#define DS1339_ALARM2_ADDR 0x0b +#define DS1339_ALARM2_SIZE 0x03 + +#define DS1339_CONTROL_ADDR 0x0e // enable/disable counter +#define DS1339_STATUS_ADDR 0x0f // osf + alarms status +#define DS1339_CHARGER_ADDR 0x10 // charger address + +#define PROC_DS1339_NAME "driver/ds1339" + +#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) +#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) + +#define TWELVE_HOUR_MODE(n) (((n)>>6)&1) +#define HOURS_AP(n) (((n)>>5)&1) +#define HOURS_12(n) BCD_TO_BIN((n)&0x1F) +#define HOURS_24(n) BCD_TO_BIN((n)&0x3F) + +#define DS1339_OSC_ENABLE 0x80 // osc enable mask + +#endif diff -urN linux-2.6.7/drivers/input/gameport/Kconfig linux-2.6.7-vpac1/drivers/input/gameport/Kconfig --- linux-2.6.7/drivers/input/gameport/Kconfig 2004-06-16 07:18:52.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/input/gameport/Kconfig 2004-06-21 05:52:44.000000000 +0200 @@ -37,6 +37,7 @@ # GAMEPORT is 'y' or 'n', it can be anything". config SOUND_GAMEPORT tristate + depends on GAMEPORT default y if GAMEPORT!=m default m if GAMEPORT=m diff -urN linux-2.6.7/drivers/mtd/maps/lubbock-flash.c linux-2.6.7-vpac1/drivers/mtd/maps/lubbock-flash.c --- linux-2.6.7/drivers/mtd/maps/lubbock-flash.c 2004-06-16 07:19:42.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/mtd/maps/lubbock-flash.c 2004-06-21 04:46:52.000000000 +0200 @@ -15,26 +15,31 @@ #include #include #include +#include #include #include #include -#include #include -#include #define ROM_ADDR 0x00000000 -#define FLASH_ADDR 0x04000000 +//#define FLASH_ADDR 0x04000000 #define WINDOW_SIZE 64*1024*1024 -static struct map_info lubbock_maps[2] = { { +static struct map_info lubbock_maps[] = { { .size = WINDOW_SIZE, .phys = 0x00000000, -}, { + .name = "Boot Flash", +}, +#ifdef FLASH_ADDR +{ .size = WINDOW_SIZE, .phys = 0x04000000, -} }; + .name = "Application Flash", +} +#endif +}; static struct mtd_partition lubbock_partitions[] = { { @@ -44,12 +49,12 @@ .mask_flags = MTD_WRITEABLE /* force read-only */ },{ .name = "Kernel", - .size = 0x00100000, + .size = 0x000c0000, .offset = 0x00040000, },{ .name = "Filesystem", .size = MTDPART_SIZ_FULL, - .offset = 0x00140000 + .offset = 0x00100000 } }; @@ -61,20 +66,20 @@ static int __init init_lubbock(void) { - int flashboot = (LUB_CONF_SWITCHES & 1); + int flashboot = 0; int ret = 0, i; - lubbock_maps[0].buswidth = lubbock_maps[1].buswidth = + lubbock_maps[0].buswidth = +#ifdef FLASH_ADDR + lubbock_maps[1].buswidth = +#endif (BOOT_DEF & 1) ? 2 : 4; /* Compensate for the nROMBT switch which swaps the flash banks */ - printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", - flashboot?"Flash":"ROM", flashboot); - - lubbock_maps[flashboot^1].name = "Lubbock Application Flash"; - lubbock_maps[flashboot].name = "Lubbock Boot ROM"; + printk(KERN_NOTICE "Device configured to boot from %s (bank %d)\n", + lubbock_maps[flashboot].name, flashboot); - for (i = 0; i < 2; i++) { + for (i = 0; i < ARRAY_SIZE(lubbock_maps); i++) { lubbock_maps[i].virt = (unsigned long)ioremap(lubbock_maps[i].phys, WINDOW_SIZE); if (!lubbock_maps[i].virt) { printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name); @@ -108,7 +113,7 @@ if (!mymtds[0] && !mymtds[1]) return ret; - for (i = 0; i < 2; i++) { + for (i = 0; i < ARRAY_SIZE(lubbock_maps); i++) { if (!mymtds[i]) { printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); } else if (nr_parsed_parts[i]) { @@ -127,7 +132,7 @@ static void __exit cleanup_lubbock(void) { int i; - for (i = 0; i < 2; i++) { + for (i = 0; i < ARRAY_SIZE(lubbock_maps); i++) { if (!mymtds[i]) continue; diff -urN linux-2.6.7/drivers/net/8390.h linux-2.6.7-vpac1/drivers/net/8390.h --- linux-2.6.7/drivers/net/8390.h 2004-06-16 07:19:42.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/net/8390.h 2004-06-21 06:02:55.000000000 +0200 @@ -96,8 +96,8 @@ /* Some generic ethernet register configurations. */ #define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ #define E8390_RX_IRQ_MASK 0x5 -#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ -#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ +#define E8390_RXCONFIG 0x44 /* EN0_RXCR: broadcasts, no multicast,errors */ +#define E8390_RXOFF 0x60 /* EN0_RXCR: Accept no packets */ #define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ #define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ @@ -117,37 +117,7 @@ * - removed AMIGA_PCMCIA from this list, handled as ISA io now */ -#if defined(CONFIG_MAC) || \ - defined(CONFIG_ZORRO8390) || defined(CONFIG_ZORRO8390_MODULE) || \ - defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE) -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#undef inb -#undef inb_p -#undef outb -#undef outb_p - -#define inb(port) in_8(port) -#define outb(val,port) out_8(port,val) -#define inb_p(port) in_8(port) -#define outb_p(val,port) out_8(port,val) - -#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE) -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#undef inb -#undef inb_p -#undef outb -#undef outb_p - -#define inb(_p) readb(_p) -#define outb(_v,_p) writeb(_v,_p) -#define inb_p(_p) inb(_p) -#define outb_p(_v,_p) outb(_v,_p) - -#elif defined(CONFIG_NET_CBUS) || defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE) -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#else -#define EI_SHIFT(x) (x) -#endif +#define EI_SHIFT(x) ((x)<<1) #define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */ /* Page 0 register offsets. */ diff -urN linux-2.6.7/drivers/net/arm/Kconfig linux-2.6.7-vpac1/drivers/net/arm/Kconfig --- linux-2.6.7/drivers/net/arm/Kconfig 2004-06-16 07:20:03.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/net/arm/Kconfig 2004-06-21 06:05:47.000000000 +0200 @@ -45,3 +45,13 @@ number (MTD support is required for this). Otherwise you will need to set a suitable hw address using ifconfig. +config ARM_CS89x0 + tristate "Cirrus Logic CS89x0 support" + depends on NET_ETHERNET && ARM + select CS89x0 + +config ARM_AX88796 + tristate "Asix AX88796 support" + depends on NET_ETHERNET && ARM + select NE2000 + diff -urN linux-2.6.7/drivers/net/arm/Makefile linux-2.6.7-vpac1/drivers/net/arm/Makefile --- linux-2.6.7/drivers/net/arm/Makefile 2004-06-16 07:19:37.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/net/arm/Makefile 2004-06-21 06:06:13.000000000 +0200 @@ -8,3 +8,5 @@ obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o +obj-$(CONFIG_ARM_CS89x0) += cs8900.o +obj-$(CONFIG_ARM_AX88796) += ax88796.o diff -urN linux-2.6.7/drivers/net/arm/ax88796.c linux-2.6.7-vpac1/drivers/net/arm/ax88796.c --- linux-2.6.7/drivers/net/arm/ax88796.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/net/arm/ax88796.c 2004-06-22 22:33:13.000000000 +0200 @@ -0,0 +1,128 @@ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PM +#include +#endif + +//#include +#include + +//#define DEBUG +#define CARDNAME "ax88796" + +int __init do_ne_probe(struct net_device *dev); +extern struct net_device *__alloc_ei_netdev(int size); + +#define NE_IO_EXTENT 0x40 + +static int ax88796_drv_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev; +#ifdef DEBUG + printk("ax88796_drv_probe: %s(%d)\n", pdev->name, pdev->id); +#endif + if (pdev->num_resources < 2) + return -ENODEV; + + if( (ndev = __alloc_ei_netdev(0)) == 0) + { + printk("%s: could not allocate device.\n", CARDNAME); + return -ENOMEM; + } + SET_MODULE_OWNER(ndev); + SET_NETDEV_DEV(ndev, dev); + + ndev->dma = (unsigned char)-1; + ndev->base_addr = pdev->resource[0].start; + ndev->irq = pdev->resource[1].start; + + sprintf(ndev->name, "eth%d", pdev->id); + + dev_set_drvdata(dev, ndev); + if( do_ne_probe(ndev) == 0) + { + set_irq_type( ndev->irq, IRQT_RISING); + return register_netdev(ndev); + } + return -ENODEV; +} + +static int ax88796_drv_remove(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); +#ifdef DEBUG + struct platform_device *pdev = to_platform_device(dev); + printk("ax88796_drv_remove: %s(%d)\n", pdev->name, pdev->id); +#endif + dev_set_drvdata(dev, NULL); + + unregister_netdev(ndev); + + free_irq(ndev->irq, ndev); + release_region(ndev->base_addr, NE_IO_EXTENT); + + kfree(ndev); + return 0; +} + +static int ax88796_drv_suspend(struct device *dev, u32 state, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); +#ifdef DEBUG + struct platform_device *pdev = to_platform_device(dev); + printk("ax88796_drv_suspend: %s(%d)\n", pdev->name, pdev->id); +#endif + if (ndev && level == SUSPEND_DISABLE) + if (netif_running(ndev)) { + netif_device_detach(ndev); +// ax88796_shutdown(ndev->base_addr); + } + + return 0; +} + +static int ax88796_drv_resume(struct device *dev, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); +#ifdef DEBUG + struct platform_device *pdev = to_platform_device(dev); + printk("ax88796_drv_resume: %s(%d)\n", pdev->name, pdev->id); +#endif + if (ndev && level == RESUME_ENABLE) + if (netif_running(ndev)) { +// ax88796_reset(ndev); + netif_device_attach(ndev); + } + + return 0; +} + +static struct device_driver ax88796_driver = { + .name = CARDNAME, + .bus = &platform_bus_type, + .probe = ax88796_drv_probe, + .remove = ax88796_drv_remove, + .suspend = ax88796_drv_suspend, + .resume = ax88796_drv_resume, +}; + +static int __init ax88796_init(void) +{ + return driver_register(&ax88796_driver); +} + +static void __exit ax88796_cleanup(void) +{ + driver_unregister(&ax88796_driver); +} + +module_init(ax88796_init); +module_exit(ax88796_cleanup); + diff -urN linux-2.6.7/drivers/net/arm/cs8900.c linux-2.6.7-vpac1/drivers/net/arm/cs8900.c --- linux-2.6.7/drivers/net/arm/cs8900.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/net/arm/cs8900.c 2004-06-21 06:06:57.000000000 +0200 @@ -0,0 +1,154 @@ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PM +#include +#endif + +#include +#include + +#define CARDNAME "cs8900" + +int __init cs89x0_probe(struct net_device *dev); + +#define NETCARD_IO_EXTENT 16 + +#define PP_ChipID 0x0000 // Chip Id +#define PP_IA 0x0158 // Physical Address Register + +#define ADD_PORT 0x0014 +#define DATA_PORT 0x0018 + +static int get_mac_address(struct net_device *dev) +{ + int i; + for (i=0; i < ETH_ALEN/2; i++) + { + unsigned int addr = dev->base_addr & ~3; + outw(PP_IA+i*2, addr + ADD_PORT); + addr = inw(addr + DATA_PORT); + dev->dev_addr[i*2] = addr & 0xFF; + dev->dev_addr[i*2+1] = addr >> 8; + } + return 0; +} + +static int cs8900_drv_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev; +#ifdef DEBUG + printk("cs8900_drv_probe: %s(%d)\n", pdev->name, pdev->id); +#endif + if (pdev->num_resources < 2) + return -ENODEV; + + if( (ndev = alloc_etherdev(0)) == 0) + { + printk("%s: could not allocate device.\n", CARDNAME); + return -ENOMEM; + } + SET_MODULE_OWNER(ndev); + SET_NETDEV_DEV(ndev, dev); + + ndev->dma = (unsigned char)-1; + ndev->base_addr = pdev->resource[0].start; + ndev->irq = pdev->resource[1].start; + + sprintf(ndev->name, "eth%d", pdev->id); + + get_mac_address(ndev); + + dev_set_drvdata(dev, ndev); + + if( cs89x0_probe(ndev) == 0) + { + set_irq_type( ndev->irq, IRQT_RISING); + return register_netdev(ndev); + } + return -ENODEV; +} + +static int cs8900_drv_remove(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); +#ifdef DEBUG + struct platform_device *pdev = to_platform_device(dev); + printk("cs8900_drv_remove: %s(%d)\n", pdev->name, pdev->id); +#endif + dev_set_drvdata(dev, NULL); + + unregister_netdev(ndev); + + // free allocated resources + outw(PP_ChipID, ndev->base_addr + ADD_PORT); + kfree(ndev->priv); + ndev->priv = NULL; // re-allocated by cs89x0_probe + + free_irq(ndev->irq, ndev); + release_region(ndev->base_addr, NETCARD_IO_EXTENT); + + kfree(ndev); + return 0; +} + +static int cs8900_drv_suspend(struct device *dev, u32 state, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); +#ifdef DEBUG + struct platform_device *pdev = to_platform_device(dev); + printk("cs8900_drv_suspend: %s(%d)\n", pdev->name, pdev->id); +#endif + if (ndev && level == SUSPEND_DISABLE) + if (netif_running(ndev)) { + netif_device_detach(ndev); +// cs89x0_shutdown(ndev->base_addr); + } + + return 0; +} + +static int cs8900_drv_resume(struct device *dev, u32 level) +{ + struct net_device *ndev = dev_get_drvdata(dev); +#ifdef DEBUG + struct platform_device *pdev = to_platform_device(dev); + printk("cs8900_drv_resume: %s(%d)\n", pdev->name, pdev->id); +#endif + if (ndev && level == RESUME_ENABLE) + if (netif_running(ndev)) { +// cs89x0_reset(ndev); + netif_device_attach(ndev); + } + + return 0; +} + +static struct device_driver cs8900_driver = { + .name = CARDNAME, + .bus = &platform_bus_type, + .probe = cs8900_drv_probe, + .remove = cs8900_drv_remove, + .suspend = cs8900_drv_suspend, + .resume = cs8900_drv_resume, +}; + +static int __init cs8900_init(void) +{ + return driver_register(&cs8900_driver); +} + +static void __exit cs8900_cleanup(void) +{ + driver_unregister(&cs8900_driver); +} + +module_init(cs8900_init); +module_exit(cs8900_cleanup); + diff -urN linux-2.6.7/drivers/net/cs89x0.c linux-2.6.7-vpac1/drivers/net/cs89x0.c --- linux-2.6.7/drivers/net/cs89x0.c 2004-06-16 07:19:52.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/net/cs89x0.c 2004-06-28 08:52:59.000000000 +0200 @@ -47,7 +47,7 @@ : ) : Don't call netif_wake_queue() in net_send_packet() : Fixed an out-of-mem bug in dma_rx() - : Updated Documentation/networking/cs89x0.txt + : Updated Documentation/cs89x0.txt Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1 : Use skb_reserve to longword align IP header (two places) @@ -97,13 +97,13 @@ * Note that even if DMA is turned off we still support the 'dma' and 'use_dma' * module options so we don't break any startup scripts. */ -#define ALLOW_DMA 1 +#define ALLOW_DMA 0 /* * Set this to zero to remove all the debug statements via * dead code elimination */ -#define DEBUGGING 1 +#define DEBUGGING 0 /* Sources: @@ -114,6 +114,7 @@ */ +#include #include #include #include @@ -156,14 +157,12 @@ static unsigned int netcard_portlist[] __initdata = { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int cs8900_irq_map[] = {12,0,0,0}; -#elif defined(CONFIG_SH_HICOSH4) -static unsigned int netcard_portlist[] __initdata = - { 0x0300, 0}; -static unsigned int cs8900_irq_map[] = {1,0,0,0}; #else +#ifdef CONFIG_ISA static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; -static unsigned int cs8900_irq_map[] = {10,11,12,5}; +#endif +static unsigned int cs8900_irq_map[] = {37,42,0,0}; #endif #if DEBUGGING @@ -212,7 +211,9 @@ /* Index to functions, as function prototypes. */ -static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular); +extern int cs89x0_probe(struct net_device *dev); + +static int cs89x0_probe1(struct net_device *dev, int ioaddr); static int net_open(struct net_device *dev); static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -250,7 +251,7 @@ #endif /* !defined(MODULE) && (ALLOW_DMA != 0) */ #ifndef MODULE -static int g_cs89x0_media__force; +static int g_cs89x0_media__force = FORCE_RJ45; static int __init media_fn(char *str) { @@ -272,51 +273,35 @@ Return 0 on success. */ -struct net_device * __init cs89x0_probe(int unit) +static int cs89x0_isa_probe(struct net_device *dev) +{ +#ifdef CONFIG_ISA + int i; + + for (i = 0; netcard_portlist[i]; i++) { + if (cs89x0_probe1(dev, netcard_portlist[i]) == 0) + return 0; + } + printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); +#endif + return -ENODEV; +} + +int __init cs89x0_probe(struct net_device *dev) { - struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); - unsigned *port; - int err = 0; - int irq; - int io; - - if (!dev) - return ERR_PTR(-ENODEV); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - io = dev->base_addr; - irq = dev->irq; + unsigned int base_addr = dev ? dev->base_addr : 0; + + SET_MODULE_OWNER(dev); if (net_debug) - printk("cs89x0:cs89x0_probe(0x%x)\n", io); + printk("cs89x0:cs89x0_probe(0x%x)\n", base_addr); - if (io > 0x1ff) { /* Check a single specified location. */ - err = cs89x0_probe1(dev, io, 0); - } else if (io != 0) { /* Don't probe at all. */ - err = -ENXIO; - } else { - for (port = netcard_portlist; *port; port++) { - if (cs89x0_probe1(dev, *port, 0) == 0) - break; - dev->irq = irq; - } - if (!*port) - err = -ENODEV; - } - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: - outw(PP_ChipID, dev->base_addr + ADD_PORT); - release_region(dev->base_addr, NETCARD_IO_EXTENT); -out: - free_netdev(dev); - printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); - return ERR_PTR(err); + if (base_addr > 0x1ff) /* Check a single specified location. */ + return cs89x0_probe1(dev, base_addr); + else if (base_addr != 0) /* Don't probe at all. */ + return -ENXIO; + + return cs89x0_isa_probe(dev); } static int @@ -396,35 +381,65 @@ Return 0 on success. */ +static int +cs89x0_request_irq(struct net_device *dev) +{ + struct net_local *lp = (struct net_local *)dev->priv; + + writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); + + if (lp->chip_type == CS8900) + { + int i; + /* Search the mapping table for the corresponding IRQ pin. */ + for (i = 0; i != sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]); i++) + if (cs8900_irq_map[i] == dev->irq) + { + if(net_debug) + printk(KERN_INFO "%s: cs89x0 assigned IRQ line %d\n", dev->name, i); + writereg(dev, PP_CS8900_ISAINT, i); + break; + } + } else + writereg(dev, PP_CS8920_ISAINT, dev->irq); + + return request_irq(dev->irq, &net_interrupt, 0, dev->name, dev); +} + static int __init -cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) +cs89x0_probe1(struct net_device *dev, int ioaddr) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp; static unsigned version_printed; int i; unsigned rev_type = 0; int eeprom_buff[CHKSUM_LEN]; int retval; - SET_MODULE_OWNER(dev); /* Initialize the device structure. */ - if (!modular) { + if (dev->priv == NULL) { + dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); + if (dev->priv == 0) { + retval = -ENOMEM; + goto out; + } + lp = (struct net_local *)dev->priv; memset(lp, 0, sizeof(*lp)); spin_lock_init(&lp->lock); -#ifndef MODULE -#if ALLOW_DMA +#if !defined(MODULE) && (ALLOW_DMA != 0) if (g_cs89x0_dma) { lp->use_dma = 1; lp->dma = g_cs89x0_dma; lp->dmasize = 16; /* Could make this an option... */ } #endif +#ifndef MODULE lp->force = g_cs89x0_media__force; #endif } + lp = (struct net_local *)dev->priv; /* Grab the region so we can find another board if autoIRQ fails. */ - /* WTF is going on here? */ if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) { printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n", dev->name, ioaddr, NETCARD_IO_EXTENT); @@ -432,35 +447,30 @@ goto out1; } -#ifdef CONFIG_SH_HICOSH4 - /* truely reset the chip */ - outw(0x0114, ioaddr + ADD_PORT); - outw(0x0040, ioaddr + DATA_PORT); -#endif - /* if they give us an odd I/O address, then do ONE write to the address port, to get it back to address zero, where we expect to find the EISA signature word. An IO with a base of 0x3 - will skip the test for the ADD_PORT. */ + will skip the test for the ADD_PORT. */ if (ioaddr & 1) { if (net_debug > 1) printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr); - if ((ioaddr & 2) != 2) + if ((ioaddr & 2) != 2) if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) { printk(KERN_ERR "%s: bad signature 0x%x\n", dev->name, inw((ioaddr & ~3)+ ADD_PORT)); retval = -ENODEV; goto out2; } - ioaddr &= ~3; + ioaddr &= ~3; outw(PP_ChipID, ioaddr + ADD_PORT); } -printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT)); + if(net_debug) + printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT)); if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) { printk(KERN_ERR "%s: incorrect signature 0x%x\n", dev->name, inw(ioaddr + DATA_PORT)); - retval = -ENODEV; + retval = -ENODEV; goto out2; } @@ -491,7 +501,7 @@ dev->base_addr); reset_chip(dev); - + /* Here we read the current configuration of the chip. If there is no Extended EEPROM then the idea is to not disturb the chip configuration, it should have been correctly setup by automatic @@ -499,38 +509,6 @@ the driver will always do *something* instead of complain that adapter_cnf is 0. */ -#ifdef CONFIG_SH_HICOSH4 - if (1) { - /* For the HiCO.SH4 board, things are different: we don't - have EEPROM, but there is some data in flash, so we go - get it there directly (MAC). */ - __u16 *confd; - short cnt; - if (((* (volatile __u32 *) 0xa0013ff0) & 0x00ffffff) - == 0x006c3000) { - confd = (__u16*) 0xa0013fc0; - } else { - confd = (__u16*) 0xa001ffc0; - } - cnt = (*confd++ & 0x00ff) >> 1; - while (--cnt > 0) { - __u16 j = *confd++; - - switch (j & 0x0fff) { - case PP_IA: - for (i = 0; i < ETH_ALEN/2; i++) { - dev->dev_addr[i*2] = confd[i] & 0xFF; - dev->dev_addr[i*2+1] = confd[i] >> 8; - } - break; - } - j = (j >> 12) + 1; - confd += j; - cnt -= j; - } - } else -#endif - if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == (EEPROM_OK|EEPROM_PRESENT)) { /* Load the MAC. */ @@ -584,13 +562,11 @@ printk("\n"); /* First check to see if an EEPROM is attached. */ -#ifdef CONFIG_SH_HICOSH4 /* no EEPROM on HiCO, don't hazzle with it here */ - if (1) { - printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n"); - } else -#endif if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0) - printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n"); + { + if(net_debug) + printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n"); + } else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n"); } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { @@ -713,13 +689,23 @@ dev->set_multicast_list = set_multicast_list; dev->set_mac_address = set_mac_address; + /* Fill in the fields of the device structure with ethernet values. */ + ether_setup(dev); + printk("\n"); + + if (cs89x0_request_irq(dev)) + printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq); + if (net_debug) printk("cs89x0_probe1() successful\n"); return 0; out2: release_region(ioaddr & ~3, NETCARD_IO_EXTENT); out1: + kfree(dev->priv); + dev->priv = 0; +out: return retval; } @@ -735,7 +721,7 @@ static void get_dma_channel(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (lp->dma) { dev->dma = lp->dma; @@ -757,7 +743,7 @@ static void write_dma(struct net_device *dev, int chip_type, int dma) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if ((lp->isa_config & ANY_ISA_DMA) == 0) return; if (chip_type == CS8900) { @@ -770,7 +756,7 @@ static void set_dma_cfg(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (lp->use_dma) { if ((lp->isa_config & ANY_ISA_DMA) == 0) { @@ -793,7 +779,7 @@ static int dma_bufcfg(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (lp->use_dma) return (lp->isa_config & ANY_ISA_DMA)? RX_DMA_ENBL : 0; else @@ -804,7 +790,7 @@ dma_busctl(struct net_device *dev) { int retval = 0; - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (lp->use_dma) { if (lp->isa_config & ANY_ISA_DMA) retval |= RESET_RX_DMA; /* Reset the DMA pointer */ @@ -820,7 +806,7 @@ static void dma_rx(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; struct sk_buff *skb; int status, length; unsigned char *bp = lp->rx_dma_ptr; @@ -882,7 +868,7 @@ void __init reset_chip(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; int reset_start_time; @@ -912,7 +898,7 @@ static void control_dc_dc(struct net_device *dev, int on_not_off) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; unsigned int selfcontrol; int timenow = jiffies; /* control the DC to DC convertor in the SelfControl register. @@ -940,7 +926,7 @@ static int detect_tp(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; int timenow = jiffies; int fdx; @@ -1055,7 +1041,7 @@ static int detect_aui(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (net_debug > 1) printk("%s: Attempting AUI\n", dev->name); control_dc_dc(dev, 0); @@ -1071,7 +1057,7 @@ static int detect_bnc(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (net_debug > 1) printk("%s: Attempting BNC\n", dev->name); control_dc_dc(dev, 1); @@ -1084,26 +1070,6 @@ return DETECTED_NONE; } - -static void -write_irq(struct net_device *dev, int chip_type, int irq) -{ - int i; - - if (chip_type == CS8900) { - /* Search the mapping table for the corresponding IRQ pin. */ - for (i = 0; i != sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]); i++) - if (cs8900_irq_map[i] == irq) - break; - /* Not found */ - if (i == sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0])) - i = 3; - writereg(dev, PP_CS8900_ISAINT, i); - } else { - writereg(dev, PP_CS8920_ISAINT, irq); - } -} - /* Open/initialize the board. This is called (in the current kernel) sometime after booting when the 'ifconfig' program is run. @@ -1117,63 +1083,11 @@ static int net_open(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; int result = 0; int i; int ret; -#ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this won't work */ - if (dev->irq < 2) { - /* Allow interrupts to be generated by the chip */ -/* Cirrus' release had this: */ -#if 0 - writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); -#endif -/* And 2.3.47 had this: */ - writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); - - for (i = 2; i < CS8920_NO_INTS; i++) { - if ((1 << i) & lp->irq_map) { - if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) { - dev->irq = i; - write_irq(dev, lp->chip_type, i); - /* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */ - break; - } - } - } - - if (i >= CS8920_NO_INTS) { - writereg(dev, PP_BusCTL, 0); /* disable interrupts. */ - printk(KERN_ERR "cs89x0: can't get an interrupt\n"); - ret = -EAGAIN; - goto bad_out; - } - } - else -#endif - { - if (((1 << dev->irq) & lp->irq_map) == 0) { - printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", - dev->name, dev->irq, lp->irq_map); - ret = -EAGAIN; - goto bad_out; - } -/* FIXME: Cirrus' release had this: */ - writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); -/* And 2.3.47 had this: */ -#if 0 - writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); -#endif - write_irq(dev, lp->chip_type, dev->irq); - ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev); - if (ret) { - if (net_debug) - printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq); - goto bad_out; - } - } - #if ALLOW_DMA if (lp->use_dma) { if (lp->isa_config & ANY_ISA_DMA) { @@ -1243,7 +1157,6 @@ release_dma_buff(lp); #endif writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); - free_irq(dev->irq, dev); ret = -EAGAIN; goto bad_out; } @@ -1358,7 +1271,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; if (net_debug > 3) { printk("%s: sent %d byte packet of type %x\n", @@ -1419,7 +1332,7 @@ int handled = 0; ioaddr = dev->base_addr; - lp = netdev_priv(dev); + lp = (struct net_local *)dev->priv; /* we MUST read all the events out of the ISQ, otherwise we'll never get interrupted again. As a consequence, we can't have any limit @@ -1517,7 +1430,7 @@ static void net_rx(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; struct sk_buff *skb; int status, length; @@ -1573,8 +1486,9 @@ static int net_close(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); - +#if ALLOW_DMA + struct net_local *lp = (struct net_local *)dev->priv; +#endif netif_stop_queue(dev); writereg(dev, PP_RxCFG, 0); @@ -1582,8 +1496,6 @@ writereg(dev, PP_BufCFG, 0); writereg(dev, PP_BusCTL, 0); - free_irq(dev->irq, dev); - #if ALLOW_DMA if (lp->use_dma && lp->dma) { free_dma(dev->dma); @@ -1600,7 +1512,7 @@ static struct net_device_stats * net_get_stats(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; spin_lock_irqsave(&lp->lock, flags); @@ -1614,7 +1526,7 @@ static void set_multicast_list(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; spin_lock_irqsave(&lp->lock, flags); @@ -1666,7 +1578,7 @@ #ifdef MODULE -static struct net_device *dev_cs89x0; +static struct net_device dev_cs89x0; /* * Support the 'debug' module parm even if we're compiled for non-debug to @@ -1744,7 +1656,6 @@ int init_module(void) { - struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); struct net_local *lp; int ret = 0; @@ -1753,12 +1664,18 @@ #else debug = 0; #endif - if (!dev) - return -ENOMEM; - dev->irq = irq; - dev->base_addr = io; - lp = netdev_priv(dev); + dev_cs89x0.irq = irq; + dev_cs89x0.base_addr = io; + + dev_cs89x0.init = cs89x0_probe; + dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); + if (dev_cs89x0.priv == 0) { + printk(KERN_ERR "cs89x0.c: Out of memory.\n"); + return -ENOMEM; + } + memset(dev_cs89x0.priv, 0, sizeof(struct net_local)); + lp = (struct net_local *)dev_cs89x0.priv; #if ALLOW_DMA if (use_dma) { @@ -1788,10 +1705,7 @@ printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n"); ret = -EPERM; goto out; - } else if (io <= 0x1ff) { - ret = -ENXIO; - goto out; - } + } #if ALLOW_DMA if (use_dma && dmasize != 16 && dmasize != 64) { @@ -1800,31 +1714,31 @@ goto out; } #endif - ret = cs89x0_probe1(dev, io, 1); - if (ret) - goto out; - if (register_netdev(dev) != 0) { + if (register_netdev(&dev_cs89x0) != 0) { printk(KERN_ERR "cs89x0.c: No card found at 0x%x\n", io); ret = -ENXIO; - outw(PP_ChipID, dev->base_addr + ADD_PORT); - release_region(dev->base_addr, NETCARD_IO_EXTENT); goto out; } - dev_cs89x0 = dev; - return 0; out: - free_netdev(dev); + if (ret) + kfree(dev_cs89x0.priv); return ret; } void cleanup_module(void) { - unregister_netdev(dev_cs89x0); - outw(PP_ChipID, dev_cs89x0->base_addr + ADD_PORT); - release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); - free_netdev(dev_cs89x0); + if (dev_cs89x0.priv != NULL) { + /* Free up the private structure, or leak memory :-) */ + unregister_netdev(&dev_cs89x0); + outw(PP_ChipID, dev_cs89x0.base_addr + ADD_PORT); + kfree(dev_cs89x0.priv); + dev_cs89x0.priv = NULL; /* gets re-allocated by cs89x0_probe1 */ + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_cs89x0->irq, dev_cs89x0); + release_region(dev_cs89x0.base_addr, NETCARD_IO_EXTENT); + } } #endif /* MODULE */ diff -urN linux-2.6.7/drivers/net/cs89x0.h linux-2.6.7-vpac1/drivers/net/cs89x0.h --- linux-2.6.7/drivers/net/cs89x0.h 2004-06-16 07:19:42.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/net/cs89x0.h 2004-06-28 08:49:44.000000000 +0200 @@ -326,14 +326,14 @@ #define RX_FRAME_PORT 0x0000 #define TX_FRAME_PORT RX_FRAME_PORT -#define TX_CMD_PORT 0x0004 +#define TX_CMD_PORT 0x0008 #define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */ #define TX_AFTER_381 0x0040 /* Tx packet after 381 bytes copied */ #define TX_AFTER_ALL 0x00c0 /* Tx packet after all bytes copied */ -#define TX_LEN_PORT 0x0006 -#define ISQ_PORT 0x0008 -#define ADD_PORT 0x000A -#define DATA_PORT 0x000C +#define TX_LEN_PORT 0x000c +#define ISQ_PORT 0x0010 +#define ADD_PORT 0x0014 +#define DATA_PORT 0x0018 #define EEPROM_WRITE_EN 0x00F0 #define EEPROM_WRITE_DIS 0x0000 diff -urN linux-2.6.7/drivers/net/ne.c linux-2.6.7-vpac1/drivers/net/ne.c --- linux-2.6.7/drivers/net/ne.c 2004-06-16 07:19:22.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/net/ne.c 2004-06-28 08:32:00.000000000 +0200 @@ -70,7 +70,7 @@ /* #define PACKETBUF_MEMSIZE 0x40 */ /* A zero-terminated list of I/O addresses to be probed at boot. */ -#ifndef MODULE +#ifdef CONFIG_ISA static unsigned int netcard_portlist[] __initdata = { 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 }; @@ -116,10 +116,10 @@ /* ---- No user-serviceable parts below ---- */ #define NE_BASE (dev->base_addr) -#define NE_CMD 0x00 -#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT 0x20 +#define NE_CMD EI_SHIFT(0x00) +#define NE_DATAPORT EI_SHIFT(0x10) /* NatSemi-defined port window offset. */ +#define NE_RESET EI_SHIFT(0x1f) /* Issue a read to reset, a write to clear. */ +#define NE_IO_EXTENT 0x40 #define NE1SM_START_PG 0x20 /* First page of TX buffer */ #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ @@ -140,6 +140,34 @@ static void ne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); + +static unsigned char configured_mac_address[2][ETH_ALEN] = { { 0x88, 0x79, 0x60, 0, 0, 0}, + { 0x88, 0x79, 0x60, 0, 0, 1}}; + +static int __init init_mac_addr(char *str) +{ + int i, c, dev; + + dev = *str++ - 0x30; + + if( dev >= 0 && dev < 2 && *str++ == '=') + { + for( i=0; i < ETH_ALEN; i++) + { + if( (c = *str++) == 0) break; + c = ((c&0x40)? (c-0x37):c)&0xf; + configured_mac_address[dev][i] = c<<4; + + if( (c = *str++) == 0) break; + c = ((c&0x40)? (c-0x37):c)&0xf; + configured_mac_address[dev][i] += c; + } + } + return 1; +} + +__setup("mac", init_mac_addr); + /* Probe for various non-shared-memory ethercards. @@ -162,12 +190,9 @@ E2010 starts at 0x100 and ends at 0x4000. E2010-x starts at 0x100 and ends at 0xffff. */ -static int __init do_ne_probe(struct net_device *dev) +int __init do_ne_probe(struct net_device *dev) { unsigned int base_addr = dev->base_addr; -#ifndef MODULE - int orig_irq = dev->irq; -#endif SET_MODULE_OWNER(dev); @@ -176,12 +201,11 @@ return ne_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - +#ifdef CONFIG_ISA /* Then look for any installed ISAPnP clones */ if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) return 0; -#ifndef MODULE /* Last resort. The semi-risky ISA auto-probe. */ for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { int ioaddr = netcard_portlist[base_addr]; @@ -190,7 +214,6 @@ return 0; } #endif - return -ENODEV; } @@ -297,13 +320,13 @@ { int regd; outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); - regd = inb_p(ioaddr + 0x0d); - outb_p(0xff, ioaddr + 0x0d); + regd = inb_p(ioaddr + EN0_COUNTER0); + outb_p(0xff, ioaddr + EN0_COUNTER0); outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ if (inb_p(ioaddr + EN0_COUNTER0) != 0) { outb_p(reg0, ioaddr); - outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ + outb_p(regd, ioaddr + EN0_COUNTER0); /* Restore the old values. */ ret = -ENODEV; goto err_out; } @@ -378,6 +401,8 @@ wordlength = 1; } + wordlength = 2; /* Added by Mark Lee */ + if (wordlength == 2) { for (i = 0; i < 16; i++) @@ -391,6 +416,10 @@ stop_page = NE1SM_STOP_PG; } + // ax88796 no prom, fake signature + SA_prom[14] = 0x57; + SA_prom[15] = 0x57; + neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00); @@ -472,10 +501,12 @@ dev->base_addr = ioaddr; - for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); - dev->dev_addr[i] = SA_prom[i]; - } + // set mac address to configured value + i = (dev->name[3] - 0x30) & 0x01; + memcpy( dev->dev_addr, configured_mac_address[i], ETH_ALEN); + + for(i = 0; i < ETHER_ADDR_LEN; i++) + printk(" %2.2x", dev->dev_addr[i]); printk("\n%s: %s found at %#x, using IRQ %d.\n", dev->name, name, ioaddr, dev->irq); diff -urN linux-2.6.7/drivers/pcmcia/Makefile linux-2.6.7-vpac1/drivers/pcmcia/Makefile --- linux-2.6.7/drivers/pcmcia/Makefile 2004-06-16 07:19:44.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/pcmcia/Makefile 2004-06-22 23:13:30.000000000 +0200 @@ -47,6 +47,7 @@ sa1100_cs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o sa1100_cs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o -pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o +#pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o +pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_dimmpc.o pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o diff -urN linux-2.6.7/drivers/pcmcia/pxa2xx_dimmpc.c linux-2.6.7-vpac1/drivers/pcmcia/pxa2xx_dimmpc.c --- linux-2.6.7/drivers/pcmcia/pxa2xx_dimmpc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/drivers/pcmcia/pxa2xx_dimmpc.c 2004-06-28 08:03:43.000000000 +0200 @@ -0,0 +1,126 @@ +/* + * linux/drivers/pcmcia/pxa2xx_dimmpc.c + */ +#include +#include +#include +#include +#include +#include + +#include + +#include "soc_common.h" + +#define PCMCIA_SLOT0_IRQ_GPIO IRQ_GPIO(10) +#define PCMCIA_SLOT1_IRQ_GPIO IRQ_GPIO(11) + +#define PCMCIA_STATUS_BASE 0xf1000000 +#define PCSR __REGP(PCMCIA_STATUS_BASE) + +#define PCSR_S1_CD 0x08 +#define PCSR_S0_CD 0x80 +#define PCSR_S1_BVD1 0x01 +#define PCSR_S1_BVD2 0x02 +#define PCSR_S0_BVD1 0x10 +#define PCSR_S0_BVD2 0x20 + +static int dimm_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ +// printk("dimm_pcmcia_hw_init: %d\n", skt->nr); + + skt->irq = skt->nr ? PCMCIA_SLOT1_IRQ_GPIO + : PCMCIA_SLOT0_IRQ_GPIO; + return 0; +} + +static void dimm_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ +// printk("dimm_pcmcia_hw_shutdown: %d\n", skt->nr); +} + +static void dimm_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) +{ + unsigned long status = PCSR; + +// printk("dimm_pcmcia_socket_state: %d = 0x%lx\n", skt->nr, status); + + switch (skt->nr) { + case 0: + state->detect = ((status & PCSR_S0_CD) == 0); +// state->bvd1 = ((status & PCSR_S0_BVD1) > 0); +// state->bvd2 = ((status & PCSR_S0_BVD2) > 0); + break; + case 1: + state->detect = ((status & PCSR_S1_CD) == 0); +// state->bvd1 = ((status & PCSR_S1_BVD1) > 0); +// state->bvd2 = ((status & PCSR_S1_BVD2) > 0); + break; + } + + state->ready = state->detect; + state->wrprot = 0; + state->bvd1 = 1; + state->bvd2 = 1; + state->vs_3v = 1; + state->vs_Xv = 0; +} + +static int dimm_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) +{ +// printk("dimm_pcmcia_configure_socket: %d\n", skt->nr); + return 0; +} + +static void dimm_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +// printk("dimm_pcmcia_socket_init: %d\n", skt->nr); +} + +static void dimm_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +// printk("dimm_pcmcia_socket_suspend: %d\n", skt->nr); +} + +static struct pcmcia_low_level dimm_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = dimm_pcmcia_hw_init, + .hw_shutdown = dimm_pcmcia_hw_shutdown, + .socket_state = dimm_pcmcia_socket_state, + .configure_socket = dimm_pcmcia_configure_socket, + .socket_init = dimm_pcmcia_socket_init, + .socket_suspend = dimm_pcmcia_socket_suspend, + .nr = 2, +}; + +static struct platform_device dimm_pcmcia_device; + +static int __init dimm_pcmcia_init(void) +{ + int ret; + +// dimm_pcmcia_device = kmalloc(sizeof(*dimm_pcmcia_device), GFP_KERNEL); +// if (!dimm_pcmcia_device) +// return -ENOMEM; + + memset( &dimm_pcmcia_device, 0, sizeof(dimm_pcmcia_device)); + dimm_pcmcia_device.name = "pxa2xx-pcmcia"; + dimm_pcmcia_device.dev.platform_data = &dimm_pcmcia_ops; + + ret = platform_device_register(&dimm_pcmcia_device); +// if (ret) +// kfree(dimm_pcmcia_device); + + return ret; +} + +static void __exit dimm_pcmcia_exit(void) +{ + platform_device_unregister(&dimm_pcmcia_device); +} + +module_init(dimm_pcmcia_init); +module_exit(dimm_pcmcia_exit); + +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.7/drivers/video/Kconfig linux-2.6.7-vpac1/drivers/video/Kconfig --- linux-2.6.7/drivers/video/Kconfig 2004-06-16 07:18:55.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/video/Kconfig 2004-06-23 06:33:22.000000000 +0200 @@ -937,6 +937,18 @@ If unsure, say N. +choice + prompt "LCD display type" + depends on FB_PXA + +config LCD_SHARP_LQ64D343 + bool "Sharp TFT display" + +config LCD_HITACHI_SX14Q004ZZA + bool "Hitachi STN display" + +endchoice + config FB_PXA_PARAMETERS bool "PXA LCD command line parameters" default n diff -urN linux-2.6.7/drivers/video/pxafb.c linux-2.6.7-vpac1/drivers/video/pxafb.c --- linux-2.6.7/drivers/video/pxafb.c 2004-06-16 07:19:13.000000000 +0200 +++ linux-2.6.7-vpac1/drivers/video/pxafb.c 2004-06-28 07:34:27.000000000 +0200 @@ -720,6 +720,19 @@ FDADR1 = fbi->fdadr1; LCCR0 |= LCCR0_ENB; +#ifdef CONFIG_LCD_HITACHI_SX14Q004ZZA + pxa_gpio_mode(GPIO33_nCS_5|GPIO_OUT); // backlight + pxa_gpio_mode(GPIO73_LDD_15|GPIO_OUT); // vcon + pxa_gpio_mode(GPIO77_LCD_ACBIAS|GPIO_OUT); // lcd on + + GPSR(GPIO73_LDD_15) |= GPIO_bit(GPIO73_LDD_15); //VCON + + udelay(30000); + + GPSR(GPIO77_LCD_ACBIAS) |= GPIO_bit(GPIO77_LCD_ACBIAS); //Display ON + GPCR(GPIO33_nCS_5) |= GPIO_bit(GPIO33_nCS_5); //Backlight ON +#endif + DPRINTK("FDADR0 0x%08x\n", (unsigned int) FDADR0); DPRINTK("FDADR1 0x%08x\n", (unsigned int) FDADR1); DPRINTK("LCCR0 0x%08x\n", (unsigned int) LCCR0); diff -urN linux-2.6.7/include/linux/i2c-id.h linux-2.6.7-vpac1/include/linux/i2c-id.h --- linux-2.6.7/include/linux/i2c-id.h 2004-06-16 07:18:57.000000000 +0200 +++ linux-2.6.7-vpac1/include/linux/i2c-id.h 2004-06-23 02:36:23.000000000 +0200 @@ -181,6 +181,7 @@ #define I2C_ALGO_IPMB 0x0c0000 /* IPMB adapter */ #define I2C_ALGO_MPC107 0x0d0000 #define I2C_ALGO_EC 0x100000 /* ACPI embedded controller */ +#define I2C_ALGO_PXA 0x200000 /* Intel PXA I2C algorithm */ #define I2C_ALGO_MPC8XX 0x110000 /* MPC8xx PowerPC I2C algorithm */ #define I2C_ALGO_OCP 0x120000 /* IBM or otherwise On-chip I2C algorithm */ diff -urN linux-2.6.7/include/linux/i2c-pxa.h linux-2.6.7-vpac1/include/linux/i2c-pxa.h --- linux-2.6.7/include/linux/i2c-pxa.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/include/linux/i2c-pxa.h 2004-06-23 02:34:41.000000000 +0200 @@ -0,0 +1,76 @@ +/* + * i2c_pxa.h + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * + * 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. + * + */ +#ifndef _I2C_PXA_H_ +#define _I2C_PXA_H_ + +struct i2c_algo_pxa_data +{ + void (*write_byte) (u8 value); + u8 (*read_byte) (void); + void (*start) (void); + void (*repeat_start) (void); + void (*stop) (void); + void (*abort) (void); + int (*wait_bus_not_busy) (void); + int (*wait_for_interrupt) (int wait_type); + void (*transfer) (int lastbyte, int receive, int midbyte); + void (*reset) (void); + + int udelay; + int timeout; +}; + +#define DEF_TIMEOUT 3 +#define BUS_ERROR (-EREMOTEIO) +#define ACK_DELAY 0 /* time to delay before checking bus error */ +#define MAX_MESSAGES 65536 /* maximum number of messages to send */ + +#define I2C_SLEEP_TIMEOUT 2 /* time to sleep for on i2c transactions */ +#define I2C_RETRY (-2000) /* an error has occurred retry transmit */ +#define I2C_TRANSMIT 1 +#define I2C_RECEIVE 0 +#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) /* ICR initialization value */ +/* ICR initialize bit values +* +* 15. FM 0 (100 Khz operation) +* 14. UR 0 (No unit reset) +* 13. SADIE 0 (Disables the unit from interrupting on slave addresses +* matching its slave address) +* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration +* in master mode) +* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode) +* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent) +* 9. IRFIE 1 (Enable interrupts from full buffer received) +* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty) +* 7. GCD 1 (Disables i2c unit response to general call messages as a slave) +* 6. IUE 0 (Disable unit until we change settings) +* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL) +* 4. MA 0 (Only send stop with the ICR stop bit) +* 3. TB 0 (We are not transmitting a byte initially) +* 2. ACKNAK 0 (Send an ACK after the unit receives a byte) +* 1. STOP 0 (Do not send a STOP) +* 0. START 0 (Do not send a START) +* +*/ + +#define I2C_ISR_INIT 0x7FF /* status register init */ +/* I2C status register init values + * + * 10. BED 1 (Clear bus error detected) + * 9. SAD 1 (Clear slave address detected) + * 7. IRF 1 (Clear IDBR Receive Full) + * 6. ITE 1 (Clear IDBR Transmit Empty) + * 5. ALD 1 (Clear Arbitration Loss Detected) + * 4. SSD 1 (Clear Slave Stop Detected) + */ + +#endif diff -urN linux-2.6.7/lib/inflate.c linux-2.6.7-vpac1/lib/inflate.c --- linux-2.6.7/lib/inflate.c 2004-06-16 07:19:22.000000000 +0200 +++ linux-2.6.7-vpac1/lib/inflate.c 2004-06-21 04:39:13.000000000 +0200 @@ -1030,8 +1030,8 @@ * **********************************************************************/ -static ulg crc_32_tab[256]; -static ulg crc; /* initialized in makecrc() so it'll reside in bss */ +STATIC ulg crc_32_tab[256]; +STATIC ulg crc; /* initialized in makecrc() so it'll reside in bss */ #define CRC_VALUE (crc ^ 0xffffffffUL) /* diff -urN linux-2.6.7/sound/oss/Kconfig linux-2.6.7-vpac1/sound/oss/Kconfig --- linux-2.6.7/sound/oss/Kconfig 2004-06-16 07:19:52.000000000 +0200 +++ linux-2.6.7-vpac1/sound/oss/Kconfig 2004-06-23 03:00:21.000000000 +0200 @@ -93,6 +93,10 @@ series) when wired as native sound drivers with AC97 codecs. If this driver does not work try the CS4232 driver. +config SOUND_PXA_AC97 + tristate "Intel PXA2xx AC97 audio" + depends on SOUND_PRIME!=n && ARCH_PXA && SOUND + config SOUND_CS4281 tristate "Crystal Sound CS4281" depends on SOUND_PRIME!=n && SOUND diff -urN linux-2.6.7/sound/oss/Makefile linux-2.6.7-vpac1/sound/oss/Makefile --- linux-2.6.7/sound/oss/Makefile 2004-06-16 07:19:03.000000000 +0200 +++ linux-2.6.7-vpac1/sound/oss/Makefile 2004-06-23 02:55:59.000000000 +0200 @@ -70,6 +70,7 @@ obj-$(CONFIG_SOUND_MAESTRO3) += maestro3.o ac97_codec.o obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o obj-$(CONFIG_SOUND_HARMONY) += harmony.o +obj-$(CONFIG_SOUND_PXA_AC97) += pxa-ac97.o pxa-audio.o ac97_codec.o obj-$(CONFIG_SOUND_EMU10K1) += ac97_codec.o obj-$(CONFIG_SOUND_RME96XX) += rme96xx.o obj-$(CONFIG_SOUND_BT878) += btaudio.o diff -urN linux-2.6.7/sound/oss/ac97_codec.c linux-2.6.7-vpac1/sound/oss/ac97_codec.c --- linux-2.6.7/sound/oss/ac97_codec.c 2004-06-16 07:18:58.000000000 +0200 +++ linux-2.6.7-vpac1/sound/oss/ac97_codec.c 2004-06-23 05:44:40.000000000 +0200 @@ -153,6 +153,7 @@ {0x44543031, "Diamond Technology DT0893", &default_ops}, {0x45838308, "ESS Allegro ES1988", &null_ops}, {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */ + {0x50534304, "Philips UCB1400", &default_ops}, {0x4e534331, "National Semiconductor LM4549", &null_ops}, {0x53494c22, "Silicon Laboratory Si3036", &null_ops}, {0x53494c23, "Silicon Laboratory Si3038", &null_ops}, diff -urN linux-2.6.7/sound/oss/pxa-ac97.c linux-2.6.7-vpac1/sound/oss/pxa-ac97.c --- linux-2.6.7/sound/oss/pxa-ac97.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/sound/oss/pxa-ac97.c 2004-06-28 09:55:56.000000000 +0200 @@ -0,0 +1,447 @@ +/* + * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip + * + * Author: Nicolas Pitre + * Created: Aug 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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. + * + * AC97 GPIO Changes:- + * In order to read/write codec GPIO bits using AC97 link slot 12, + * all IO to AC97_GPIO_STATUS must be via the Xscale modem codec + * address space. + * Liam Girdwood + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pxa-audio.h" + + +/* + * The codec register read operation requires 3 read cycles on PXA250 in order + * to guarrantee that good read data can be returned. + * _ _ _ _ + *sync: _____| |_addr______| |_data1______| |__data2___| |__data_n__ + *SDONE:__ _ _ _______________ + * |_addr1____| |__addr2_____| |__addr_n____| + * ^ + * First read begins + * ^ SDONE usually goes true in the latter half of AC link frame + * ^ Second read begins, but data from codec hasn't arrived yet! + * ^ second read ends, from 1 to 3 frames AFTER frame + * in which the address goes out! + * ^ Third read begins from one to 3 frames after the + * initial frame, data from codec guarranteed to be + * available by this time. + * ^ read cycle ends. + * Note how reads can be pipelined, possibly useful for reading touch panel + * control registers or rapid sampling of codec gpio lines. + */ + +static struct completion CAR_completion; +static DECLARE_MUTEX(CAR_mutex); + +static u16 pxa_ac97_read(struct ac97_codec *codec, u8 reg) +{ + u16 val = -1; + + down(&CAR_mutex); + if (!(CAR & CAR_CAIP)) { + volatile u32 *reg_addr; + + // if we are reading the GPIO status then this is cached + // in hardware so we don't need to read over the link. + if (reg == AC97_GPIO_STATUS) { + reg_addr = (u32 *)&PMC_REG_BASE + (reg >> 1); + val = *reg_addr; + return val; + } + + reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1); + init_completion(&CAR_completion); + (void)*reg_addr; + wait_for_completion(&CAR_completion); + init_completion(&CAR_completion); + (void)*reg_addr; // This initiates second read cycle, but codec data isn't here yet... + wait_for_completion(&CAR_completion); + if (GSR & GSR_RDCS) { + GSR |= GSR_RDCS; + printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__); + } + init_completion(&CAR_completion); + val = *reg_addr; // ahh, that's better. But we've just started another cycle... + wait_for_completion(&CAR_completion); //this, along with trailing delay, avoids hassle with CAR_CAIP bit + udelay(20); //don't come back too soon... + } else { + printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__); + } + up(&CAR_mutex); + //printk("%s(0x%02x) = 0x%04x\n", __FUNCTION__, reg, val); + return val; +} + +static void pxa_ac97_write(struct ac97_codec *codec, u8 reg, u16 val) +{ + down(&CAR_mutex); + if (!(CAR & CAR_CAIP)) { + volatile u32 *reg_addr; + + // if we are writing to the codec GPIO using slot 12 + // then we have to write to the modem register space + if (reg == AC97_GPIO_STATUS) { + reg_addr = (u32 *)&PMC_REG_BASE + (reg >> 1); + *reg_addr = val; + return; + } + + reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1); + init_completion(&CAR_completion); + *reg_addr = val; + wait_for_completion(&CAR_completion); + } else { + printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__); + } + up(&CAR_mutex); + //printk("%s(0x%02x, 0x%04x)\n", __FUNCTION__, reg, val); +} + +static irqreturn_t pxa_ac97_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + if (GSR & (GSR_SDONE|GSR_CDONE)) { + GSR = GSR_SDONE|GSR_CDONE; + complete(&CAR_completion); + } + return IRQ_HANDLED; +} + +static struct ac97_codec pxa_ac97_codec = { + codec_read: pxa_ac97_read, + codec_write: pxa_ac97_write, +}; + +static DECLARE_MUTEX(pxa_ac97_mutex); +static int pxa_ac97_refcount; + +int pxa_ac97_get(struct ac97_codec **codec) +{ + int ret; + + *codec = NULL; + down(&pxa_ac97_mutex); + + if (!pxa_ac97_refcount) { + ret = request_irq(IRQ_AC97, pxa_ac97_irq, 0, "AC97", NULL); + if (ret) + return ret; + + CKEN |= CKEN2_AC97; + pxa_gpio_mode(GPIO31_SYNC_AC97_MD); + pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); + pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); + pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); + + GCR = 0; + udelay(10); + GCR = GCR_COLD_RST|GCR_CDONE_IE|GCR_SDONE_IE; + while (!(GSR & GSR_PCR)) { + schedule(); + } + + ret = ac97_probe_codec(&pxa_ac97_codec); + if (ret != 1) { + free_irq(IRQ_AC97, NULL); + GCR = GCR_ACLINK_OFF; + CKEN &= ~CKEN2_AC97; + return ret; + } + + // need little hack for UCB1400 (should be moved elsewhere) + pxa_ac97_write(&pxa_ac97_codec,AC97_EXTENDED_STATUS,1); + //pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x1ff7); + pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x0050); + pxa_ac97_write(&pxa_ac97_codec, 0x6c, 0x0030); + } + + pxa_ac97_refcount++; + up(&pxa_ac97_mutex); + *codec = &pxa_ac97_codec; + return 0; +} + +void pxa_ac97_put(void) +{ + down(&pxa_ac97_mutex); + pxa_ac97_refcount--; + if (!pxa_ac97_refcount) { + GCR = GCR_ACLINK_OFF; + CKEN &= ~CKEN2_AC97; + free_irq(IRQ_AC97, NULL); + } + up(&pxa_ac97_mutex); +} + +EXPORT_SYMBOL(pxa_ac97_get); +EXPORT_SYMBOL(pxa_ac97_put); + + +/* + * Audio Mixer stuff + */ + +static audio_state_t ac97_audio_state; +static audio_stream_t ac97_audio_in; + +static int mixer_ioctl( struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + + ret = pxa_ac97_codec.mixer_ioctl(&pxa_ac97_codec, cmd, arg); + if (ret) + return ret; + + /* We must snoop for some commands to provide our own extra processing */ + switch (cmd) { + case SOUND_MIXER_WRITE_RECSRC: + /* + * According to the PXA250 spec, mic-in should use different + * DRCMR and different AC97 FIFO. + * Unfortunately current UCB1400 versions (up to ver 2A) don't + * produce slot 6 for the audio input frame, therefore the PXA + * AC97 mic-in FIFO is always starved. + */ +#if 0 + ret = get_user(val, (int *)arg); + if (ret) + return ret; + pxa_audio_clear_buf(&ac97_audio_in); + *ac97_audio_in.drcmr = 0; + if (val & (1 << SOUND_MIXER_MIC)) { + ac97_audio_in.dcmd = DCMD_RXMCDR; + ac97_audio_in.drcmr = &DRCMRRXMCDR; + ac97_audio_in.dev_addr = __PREG(MCDR); + } else { + ac97_audio_in.dcmd = DCMD_RXPCDR; + ac97_audio_in.drcmr = &DRCMRRXPCDR; + ac97_audio_in.dev_addr = __PREG(PCDR); + } + if (ac97_audio_state.rd_ref) + *ac97_audio_in.drcmr = + ac97_audio_in.dma_ch | DRCMR_MAPVLD; +#endif + break; + } + return 0; +} + +static struct file_operations mixer_fops = { + ioctl: mixer_ioctl, + llseek: no_llseek, + owner: THIS_MODULE +}; + +/* + * AC97 codec ioctls + */ + +static int codec_adc_rate = 48000; +static int codec_dac_rate = 48000; + +static int ac97_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + long val = 0; + + switch(cmd) { + case SNDCTL_DSP_STEREO: /* Only stereo is supported */ + return put_user(1, (int *) arg); + + case SNDCTL_DSP_CHANNELS: + case SOUND_PCM_READ_CHANNELS: /* Only stereo is supported */ + return put_user(2, (long *) arg); + + case SNDCTL_DSP_SPEED: + ret = get_user(val, (long *) arg); + if (ret) + return ret; + if (file->f_mode & FMODE_READ) + codec_adc_rate = ac97_set_adc_rate(&pxa_ac97_codec, val); + if (file->f_mode & FMODE_WRITE) + codec_dac_rate = ac97_set_dac_rate(&pxa_ac97_codec, val); + /* fall through */ + + case SOUND_PCM_READ_RATE: + if (file->f_mode & FMODE_READ) + val = codec_adc_rate; + if (file->f_mode & FMODE_WRITE) + val = codec_dac_rate; + return put_user(val, (long *) arg); + + case SNDCTL_DSP_SETFMT: + case SNDCTL_DSP_GETFMTS: /* Only one format is supported */ + return put_user(AFMT_S16_LE, (long *) arg); + + default: + /* Maybe this is meant for the mixer (As per OSS Docs) */ + return mixer_ioctl(inode, file, cmd, arg); + } + return 0; +} + + +/* + * Audio stuff + */ + +static audio_stream_t ac97_audio_out = { + name: "AC97 audio out", + dcmd: DCMD_TXPCDR, + drcmr: &DRCMRTXPCDR, + dev_addr: __PREG(PCDR), +}; + +static audio_stream_t ac97_audio_in = { + name: "AC97 audio in", + dcmd: DCMD_RXPCDR, + drcmr: &DRCMRRXPCDR, + dev_addr: __PREG(PCDR), +}; + +static audio_state_t ac97_audio_state = { + output_stream: &ac97_audio_out, + input_stream: &ac97_audio_in, + client_ioctl: ac97_ioctl, + sem: __MUTEX_INITIALIZER(ac97_audio_state.sem), +}; + +static int ac97_audio_open(struct inode *inode, struct file *file) +{ + return pxa_audio_attach(inode, file, &ac97_audio_state); +} + +static int pxa_ac97_suspend(struct device * dev, u32 state, u32 level) +{ + u16 reg, pwrmode; + + if ( level != SUSPEND_POWER_DOWN ) + return 0; + + + switch (state) { + case 1: pwrmode = AC97_PWR_D1; break; + case 2: pwrmode = AC97_PWR_D2; break; + case 3: pwrmode = AC97_PWR_D3; break; + default: return 1; + } + + reg = pxa_ac97_read(&pxa_ac97_codec, AC97_POWER_CONTROL); + reg |= (pwrmode & ~(AC97_PWR_PR6|AC97_PWR_PR5|AC97_PWR_PR4)); + pxa_ac97_write(&pxa_ac97_codec, AC97_POWER_CONTROL, reg); + udelay(500); + + reg = pxa_ac97_read(&pxa_ac97_codec, AC97_POWER_CONTROL); + reg |= pwrmode; + pxa_ac97_write(&pxa_ac97_codec, AC97_POWER_CONTROL, reg); + + GCR |= GCR_ACLINK_OFF; + CKEN &= ~CKEN2_AC97; + + return 0; +} + +static int pxa_ac97_resume(struct device * dev, u32 level) +{ + if ( level != RESUME_POWER_ON ) + return 0; + + CKEN |= CKEN2_AC97; + GCR &= ~GCR_ACLINK_OFF; + udelay(10); + GCR |= GCR_WARM_RST; + while ((GCR & GCR_WARM_RST)) + schedule(); + pxa_ac97_write(&pxa_ac97_codec, AC97_POWER_CONTROL, AC97_PWR_D0); + return 0; +} + +/* + * Missing fields of this structure will be patched with the call + * to pxa_audio_attach(). + */ + +static struct file_operations ac97_audio_fops = { + open: ac97_audio_open, + owner: THIS_MODULE +}; + + +static int __devinit pxa_ac97_probe(struct device *dev) +{ + int ret; + struct ac97_codec *dummy; + + ret = pxa_ac97_get(&dummy); + if (ret) + return ret; + + ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1); + pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1); + + return 0; +} + +static int __devexit pxa_ac97_remove(struct device *dev) +{ + unregister_sound_dsp(ac97_audio_state.dev_dsp); + unregister_sound_mixer(pxa_ac97_codec.dev_mixer); + pxa_ac97_put(); + return 0; +} + +static struct device_driver pxa_ac97_driver = { + .name = "pxa-audio", + .bus = &platform_bus_type, + .probe = pxa_ac97_probe, + .remove = __devexit_p(pxa_ac97_remove), + .suspend = pxa_ac97_suspend, + .resume = pxa_ac97_resume, +}; + +static int __init pxa_ac97_init(void) +{ + return driver_register(&pxa_ac97_driver); +} + +static void __exit pxa_ac97_exit(void) +{ + driver_unregister(&pxa_ac97_driver); +} + +module_init(pxa_ac97_init); +module_exit(pxa_ac97_exit); + +MODULE_AUTHOR("Nicolas Pitre"); +MODULE_DESCRIPTION("AC97 interface for the Cotula chip"); +MODULE_LICENSE("GPL"); diff -urN linux-2.6.7/sound/oss/pxa-audio.c linux-2.6.7-vpac1/sound/oss/pxa-audio.c --- linux-2.6.7/sound/oss/pxa-audio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/sound/oss/pxa-audio.c 2004-06-23 04:55:55.000000000 +0200 @@ -0,0 +1,866 @@ +/* + * linux/drivers/sound/pxa-audio.c -- audio interface for the Cotula chip + * + * Author: Nicolas Pitre + * Created: Aug 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pxa-audio.h" + + +#define AUDIO_NBFRAGS_DEFAULT 8 +#define AUDIO_FRAGSIZE_DEFAULT 8192 + +#define MAX_DMA_SIZE 4096 +#define DMA_DESC_SIZE sizeof(pxa_dma_desc) + + +/* + * This function frees all buffers + */ +#define audio_clear_buf pxa_audio_clear_buf + +void pxa_audio_clear_buf(audio_stream_t * s) +{ + DECLARE_WAITQUEUE(wait, current); + int frag; + + if (!s->buffers) + return; + + /* Ensure DMA isn't running */ + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&s->stop_wq, &wait); + DCSR(s->dma_ch) = DCSR_STOPIRQEN; + schedule(); + remove_wait_queue(&s->stop_wq, &wait); + + /* free DMA buffers */ + for (frag = 0; frag < s->nbfrags; frag++) { + audio_buf_t *b = &s->buffers[frag]; + if (!b->master) + continue; + //consistent_free(b->data, b->master, b->dma_desc->dsadr); + dma_free_writecombine(NULL, b->master, b->data, b->dma_desc->dsadr); + } + + /* free descriptor ring */ + if (s->buffers->dma_desc) + dma_free_writecombine(NULL, s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE, + s->buffers->dma_desc, s->dma_desc_phys); + //consistent_free(s->buffers->dma_desc, + // s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE, + // s->dma_desc_phys); + + /* free buffer structure array */ + kfree(s->buffers); + s->buffers = NULL; +} + +/* + * This function allocates the DMA descriptor array and buffer data space + * according to the current number of fragments and fragment size. + */ +static int audio_setup_buf(audio_stream_t * s) +{ + pxa_dma_desc *dma_desc; + dma_addr_t dma_desc_phys; + int nb_desc, frag, i, buf_size = 0; + char *dma_buf = NULL; + dma_addr_t dma_buf_phys = 0; + + /* FIXME - superfluous ? */ + if (s->buffers) + return -EBUSY; + + /* Our buffer structure array */ + s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL); + if (!s->buffers) + goto err; + memzero(s->buffers, sizeof(audio_buf_t) * s->nbfrags); + + /* + * Our DMA descriptor array: + * for Each fragment we have one checkpoint descriptor plus one + * descriptor per MAX_DMA_SIZE byte data blocks. + */ + nb_desc = (1 + (s->fragsize + MAX_DMA_SIZE - 1)/MAX_DMA_SIZE) * s->nbfrags; + dma_desc = dma_alloc_writecombine(NULL, nb_desc * DMA_DESC_SIZE, + &dma_desc_phys, GFP_KERNEL); + //dma_desc = consistent_alloc(GFP_KERNEL, + // nb_desc * DMA_DESC_SIZE, + // &dma_desc_phys, 0); + if (!dma_desc) + goto err; + s->descs_per_frag = nb_desc / s->nbfrags; + s->buffers->dma_desc = dma_desc; + s->dma_desc_phys = dma_desc_phys; + for (i = 0; i < nb_desc - 1; i++) + dma_desc[i].ddadr = dma_desc_phys + (i + 1) * DMA_DESC_SIZE; + dma_desc[i].ddadr = dma_desc_phys; + + /* Our actual DMA buffers */ + for (frag = 0; frag < s->nbfrags; frag++) { + audio_buf_t *b = &s->buffers[frag]; + + /* + * Let's allocate non-cached memory for DMA buffers. + * We try to allocate all memory at once. + * If this fails (a common reason is memory fragmentation), + * then we'll try allocating smaller buffers. + */ + if (!buf_size) { + buf_size = (s->nbfrags - frag) * s->fragsize; + do { + dma_buf = dma_alloc_writecombine(NULL, buf_size, &dma_buf_phys, GFP_KERNEL); + //dma_buf = consistent_alloc(GFP_KERNEL, + // buf_size, + // &dma_buf_phys, 0); + if (!dma_buf) + buf_size -= s->fragsize; + } while (!dma_buf && buf_size); + if (!dma_buf) + goto err; + b->master = buf_size; + memzero(dma_buf, buf_size); + } + + /* + * Set up our checkpoint descriptor. Since the count + * is always zero, we'll abuse the dsadr and dtadr fields + * just in case this one is picked up by the hardware + * while processing SOUND_DSP_GETPTR. + */ + dma_desc->dsadr = dma_buf_phys; + dma_desc->dtadr = dma_buf_phys; + dma_desc->dcmd = DCMD_ENDIRQEN; + if (s->output && !s->mapped) + dma_desc->ddadr |= DDADR_STOP; + b->dma_desc = dma_desc++; + + /* set up the actual data descriptors */ + for (i = 0; (i * MAX_DMA_SIZE) < s->fragsize; i++) { + dma_desc[i].dsadr = (s->output) ? + (dma_buf_phys + i*MAX_DMA_SIZE) : s->dev_addr; + dma_desc[i].dtadr = (s->output) ? + s->dev_addr : (dma_buf_phys + i*MAX_DMA_SIZE); + dma_desc[i].dcmd = s->dcmd | + ((s->fragsize < MAX_DMA_SIZE) ? + s->fragsize : MAX_DMA_SIZE); + } + dma_desc += i; + + /* handle buffer pointers */ + b->data = dma_buf; + dma_buf += s->fragsize; + dma_buf_phys += s->fragsize; + buf_size -= s->fragsize; + } + + s->usr_frag = s->dma_frag = 0; + s->bytecount = 0; + s->fragcount = 0; + sema_init(&s->sem, (s->output) ? s->nbfrags : 0); + return 0; + +err: + printk("pxa-audio: unable to allocate audio memory\n "); + audio_clear_buf(s); + return -ENOMEM; +} + +/* + * Our DMA interrupt handler + */ +static void audio_dma_irq(int ch, void *dev_id, struct pt_regs *regs) +{ + audio_stream_t *s = dev_id; + u_int dcsr; + + dcsr = DCSR(ch); + DCSR(ch) = dcsr & ~DCSR_STOPIRQEN; + + if (!s->buffers) { + printk("AC97 DMA: wow... received IRQ for channel %d but no buffer exists\n", ch); + return; + } + + if (dcsr & DCSR_BUSERR) + printk("AC97 DMA: bus error interrupt on channel %d\n", ch); + + if (dcsr & DCSR_ENDINTR) { + u_long cur_dma_desc; + u_int cur_dma_frag; + + /* + * Find out which DMA desc is current. Note that DDADR + * points to the next desc, not the current one. + */ + cur_dma_desc = DDADR(ch) - s->dma_desc_phys - DMA_DESC_SIZE; + + /* + * Let the compiler nicely optimize constant divisors into + * multiplications for the common cases which is much faster. + * Common cases: x = 1 + (1 << y) for y = [0..3] + */ + switch (s->descs_per_frag) { + case 2: cur_dma_frag = cur_dma_desc / (2*DMA_DESC_SIZE); break; + case 3: cur_dma_frag = cur_dma_desc / (3*DMA_DESC_SIZE); break; + case 5: cur_dma_frag = cur_dma_desc / (5*DMA_DESC_SIZE); break; + case 9: cur_dma_frag = cur_dma_desc / (9*DMA_DESC_SIZE); break; + default: cur_dma_frag = + cur_dma_desc / (s->descs_per_frag * DMA_DESC_SIZE); + } + + /* Account for possible wrap back of cur_dma_desc above */ + if (cur_dma_frag >= s->nbfrags) + cur_dma_frag = s->nbfrags - 1; + + while (s->dma_frag != cur_dma_frag) { + if (!s->mapped) { + /* + * This fragment is done - set the checkpoint + * descriptor to STOP until it is gets + * processed by the read or write function. + */ + s->buffers[s->dma_frag].dma_desc->ddadr |= DDADR_STOP; + up(&s->sem); + } + if (++s->dma_frag >= s->nbfrags) + s->dma_frag = 0; + + /* Accounting */ + s->bytecount += s->fragsize; + s->fragcount++; + } + + /* ... and for polling processes */ + wake_up(&s->frag_wq); + } + + if ((dcsr & DCSR_STOPIRQEN) && (dcsr & DCSR_STOPSTATE)) + wake_up(&s->stop_wq); +} + +/* + * Validate and sets up buffer fragments, etc. + */ +static int audio_set_fragments(audio_stream_t *s, int val) +{ + if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN) + return -EBUSY; + if (s->buffers) + audio_clear_buf(s); + s->nbfrags = (val >> 16) & 0x7FFF; + val &= 0xffff; + if (val < 5) + val = 5; + if (val > 15) + val = 15; + s->fragsize = 1 << val; + if (s->nbfrags < 2) + s->nbfrags = 2; + if (s->nbfrags * s->fragsize > 256 * 1024) + s->nbfrags = 256 * 1024 / s->fragsize; + if (audio_setup_buf(s)) + return -ENOMEM; + return val|(s->nbfrags << 16); +} + + +/* + * The fops functions + */ + +static int audio_write(struct file *file, const char *buffer, + size_t count, loff_t * ppos) +{ + const char *buffer0 = buffer; + audio_state_t *state = (audio_state_t *)file->private_data; + audio_stream_t *s = state->output_stream; + int chunksize, ret = 0; + + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->mapped) + return -ENXIO; + if (!s->buffers && audio_setup_buf(s)) + return -ENOMEM; + + while (count > 0) { + audio_buf_t *b = &s->buffers[s->usr_frag]; + + /* Grab a fragment */ + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + if (down_trylock(&s->sem)) + break; + } else { + ret = -ERESTARTSYS; + if (down_interruptible(&s->sem)) + break; + } + + /* Feed the current buffer */ + chunksize = s->fragsize - b->offset; + if (chunksize > count) + chunksize = count; + if (copy_from_user(b->data + b->offset, buffer, chunksize)) { + up(&s->sem); + return -EFAULT; + } + + b->offset += chunksize; + buffer += chunksize; + count -= chunksize; + if (b->offset < s->fragsize) { + //ret = 0; + up(&s->sem); + break; + } + + /* + * Activate DMA on current buffer. + * We unlock this fragment's checkpoint descriptor and + * kick DMA if it is idle. Using checkpoint descriptors + * allows for control operations without the need for + * stopping the DMA channel if it is already running. + */ + b->offset = 0; + b->dma_desc->ddadr &= ~DDADR_STOP; + if (DCSR(s->dma_ch) & DCSR_STOPSTATE) { + DDADR(s->dma_ch) = b->dma_desc->ddadr; + DCSR(s->dma_ch) = DCSR_RUN; + } + + + /* move the index to the next fragment */ + if (++s->usr_frag >= s->nbfrags) + s->usr_frag = 0; + } + + if ((buffer - buffer0)) + ret = buffer - buffer0; + return ret; +} + + +static int audio_read(struct file *file, char *buffer, + size_t count, loff_t * ppos) +{ + char *buffer0 = buffer; + audio_state_t *state = file->private_data; + audio_stream_t *s = state->input_stream; + int chunksize, ret = 0; + + if (ppos != &file->f_pos) + return -ESPIPE; + if (s->mapped) + return -ENXIO; + if (!s->buffers && audio_setup_buf(s)) + return -ENOMEM; + + while (count > 0) { + audio_buf_t *b = &s->buffers[s->usr_frag]; + + /* prime DMA */ + if (DCSR(s->dma_ch) & DCSR_STOPSTATE) { + DDADR(s->dma_ch) = + s->buffers[s->dma_frag].dma_desc->ddadr; + DCSR(s->dma_ch) = DCSR_RUN; + } + + /* Wait for a buffer to become full */ + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + if (down_trylock(&s->sem)) + break; + } else { + ret = -ERESTARTSYS; + if (down_interruptible(&s->sem)) + break; + } + + /* Grab data from current buffer */ + chunksize = s->fragsize - b->offset; + if (chunksize > count) + chunksize = count; + if (copy_to_user(buffer, b->data + b->offset, chunksize)) { + up(&s->sem); + return -EFAULT; + } + b->offset += chunksize; + buffer += chunksize; + count -= chunksize; + if (b->offset < s->fragsize) { + ret = 0; + up(&s->sem); + break; + } + + /* + * Make this buffer available for DMA again. + * We unlock this fragment's checkpoint descriptor and + * kick DMA if it is idle. Using checkpoint descriptors + * allows for control operations without the need for + * stopping the DMA channel if it is already running. + */ + b->offset = 0; + b->dma_desc->ddadr &= ~DDADR_STOP; + + /* move the index to the next fragment */ + if (++s->usr_frag >= s->nbfrags) + s->usr_frag = 0; + } + + if ((buffer - buffer0)) + ret = buffer - buffer0; + return ret; +} + + +static int audio_sync(struct file *file) +{ + audio_state_t *state = file->private_data; + audio_stream_t *s = state->output_stream; + audio_buf_t *b; + pxa_dma_desc *final_desc; + u_long dcmd_save = 0; + DECLARE_WAITQUEUE(wait, current); + + if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped) + return 0; + + /* + * Send current buffer if it contains data. Be sure to send + * a full sample count. + */ + final_desc = NULL; + b = &s->buffers[s->usr_frag]; + if (b->offset &= ~3) { + final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE]; + b->offset &= (MAX_DMA_SIZE-1); + dcmd_save = final_desc->dcmd; + final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN; + final_desc->ddadr |= DDADR_STOP; + b->offset = 0; + b->dma_desc->ddadr &= ~DDADR_STOP; + if (DCSR(s->dma_ch) & DCSR_STOPSTATE) { + DDADR(s->dma_ch) = b->dma_desc->ddadr; + DCSR(s->dma_ch) = DCSR_RUN; + } + } + + /* Wait for DMA to complete. */ + set_current_state(TASK_INTERRUPTIBLE); +#if 0 + /* + * The STOPSTATE IRQ never seem to occur if DCSR_STOPIRQEN is set + * along wotj DCSR_RUN. Silicon bug? + */ + add_wait_queue(&s->stop_wq, &wait); + DCSR(s->dma_ch) |= DCSR_STOPIRQEN; + schedule(); +#else + add_wait_queue(&s->frag_wq, &wait); + while ((DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current)) { + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } +#endif + set_current_state(TASK_RUNNING); + remove_wait_queue(&s->frag_wq, &wait); + + /* Restore the descriptor chain. */ + if (final_desc) { + final_desc->dcmd = dcmd_save; + final_desc->ddadr &= ~DDADR_STOP; + b->dma_desc->ddadr |= DDADR_STOP; + } + return 0; +} + + +static unsigned int audio_poll(struct file *file, + struct poll_table_struct *wait) +{ + audio_state_t *state = file->private_data; + audio_stream_t *is = state->input_stream; + audio_stream_t *os = state->output_stream; + unsigned int mask = 0; + + if (file->f_mode & FMODE_READ) { + /* Start audio input if not already active */ + if (!is->buffers && audio_setup_buf(is)) + return -ENOMEM; + if (DCSR(is->dma_ch) & DCSR_STOPSTATE) { + DDADR(is->dma_ch) = + is->buffers[is->dma_frag].dma_desc->ddadr; + DCSR(is->dma_ch) = DCSR_RUN; + } + poll_wait(file, &is->frag_wq, wait); + } + + if (file->f_mode & FMODE_WRITE) { + if (!os->buffers && audio_setup_buf(os)) + return -ENOMEM; + poll_wait(file, &os->frag_wq, wait); + } + + if (file->f_mode & FMODE_READ) + if (( is->mapped && is->bytecount > 0) || + (!is->mapped && atomic_read(&is->sem.count) > 0)) + mask |= POLLIN | POLLRDNORM; + + if (file->f_mode & FMODE_WRITE) + if (( os->mapped && os->bytecount > 0) || + (!os->mapped && atomic_read(&os->sem.count) > 0)) + mask |= POLLOUT | POLLWRNORM; + + return mask; +} + + +static int audio_ioctl( struct inode *inode, struct file *file, + uint cmd, ulong arg) +{ + audio_state_t *state = file->private_data; + audio_stream_t *os = state->output_stream; + audio_stream_t *is = state->input_stream; + long val; + + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, (int *)arg); + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) + return put_user(os->fragsize, (int *)arg); + else + return put_user(is->fragsize, (int *)arg); + + case SNDCTL_DSP_GETCAPS: + val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP; + if (is && os) + val |= DSP_CAP_DUPLEX; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETFRAGMENT: + if (get_user(val, (long *) arg)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + int ret = audio_set_fragments(is, val); + if (ret < 0) + return ret; + ret = put_user(ret, (int *)arg); + if (ret) + return ret; + } + if (file->f_mode & FMODE_WRITE) { + int ret = audio_set_fragments(os, val); + if (ret < 0) + return ret; + ret = put_user(ret, (int *)arg); + if (ret) + return ret; + } + return 0; + + case SNDCTL_DSP_SYNC: + return audio_sync(file); + + case SNDCTL_DSP_SETDUPLEX: + return 0; + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & FMODE_READ && DCSR(is->dma_ch) & DCSR_RUN) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & FMODE_WRITE && DCSR(os->dma_ch) & DCSR_RUN) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETTRIGGER: + if (get_user(val, (int *)arg)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!is->buffers && audio_setup_buf(is)) + return -ENOMEM; + if (!(DCSR(is->dma_ch) & DCSR_RUN)) { + audio_buf_t *b = &is->buffers[is->dma_frag]; + DDADR(is->dma_ch) = b->dma_desc->ddadr; + DCSR(is->dma_ch) = DCSR_RUN; + } + } else { + DCSR(is->dma_ch) = 0; + } + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!os->buffers && audio_setup_buf(os)) + return -ENOMEM; + if (!(DCSR(os->dma_ch) & DCSR_RUN)) { + audio_buf_t *b = &os->buffers[os->dma_frag]; + DDADR(os->dma_ch) = b->dma_desc->ddadr; + DCSR(os->dma_ch) = DCSR_RUN; + } + } else { + DCSR(os->dma_ch) = 0; + } + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + case SNDCTL_DSP_GETISPACE: + { + audio_buf_info inf = { 0, }; + audio_stream_t *s = (cmd == SNDCTL_DSP_GETOSPACE) ? os : is; + + if ((s == is && !(file->f_mode & FMODE_READ)) || + (s == os && !(file->f_mode & FMODE_WRITE))) + return -EINVAL; + if (!s->buffers && audio_setup_buf(s)) + return -ENOMEM; + inf.bytes = atomic_read(&s->sem.count) * s->fragsize; + inf.bytes -= s->buffers[s->usr_frag].offset; + inf.fragments = inf.bytes / s->fragsize; + inf.fragsize = s->fragsize; + inf.fragstotal = s->nbfrags; + return copy_to_user((void *)arg, &inf, sizeof(inf)); + } + + case SNDCTL_DSP_GETOPTR: + case SNDCTL_DSP_GETIPTR: + { + count_info inf = { 0, }; + audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is; + dma_addr_t ptr; + int bytecount, offset; + unsigned long flags; + + if ((s == is && !(file->f_mode & FMODE_READ)) || + (s == os && !(file->f_mode & FMODE_WRITE))) + return -EINVAL; + local_irq_save(flags); + if (DCSR(s->dma_ch) & DCSR_RUN) { + audio_buf_t *b; + ptr = (s->output) ? DSADR(s->dma_ch) : DTADR(s->dma_ch); + b = &s->buffers[s->dma_frag]; + offset = ptr - b->dma_desc->dsadr; + if (offset >= s->fragsize) + offset = s->fragsize - 4; + } else { + offset = 0; + } + inf.ptr = s->dma_frag * s->fragsize + offset; + bytecount = s->bytecount + offset; + s->bytecount = -offset; + inf.blocks = s->fragcount; + s->fragcount = 0; + local_irq_restore(flags); + if (bytecount < 0) + bytecount = 0; + inf.bytes = bytecount; + return copy_to_user((void *)arg, &inf, sizeof(inf)); + } + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) + audio_clear_buf(os); + if (file->f_mode & FMODE_READ) + audio_clear_buf(is); + return 0; + + default: + return state->client_ioctl ? + state->client_ioctl(inode, file, cmd, arg) : -EINVAL; + } + + return 0; +} + + +static int audio_mmap(struct file *file, struct vm_area_struct *vma) +{ + audio_state_t *state = file->private_data; + audio_stream_t *s; + unsigned long size, vma_addr; + int i, ret; + + if (vma->vm_pgoff != 0) + return -EINVAL; + + if (vma->vm_flags & VM_WRITE) { + if (!state->wr_ref) + return -EINVAL;; + s = state->output_stream; + } else if (vma->vm_flags & VM_READ) { + if (!state->rd_ref) + return -EINVAL; + s = state->input_stream; + } else return -EINVAL; + + if (s->mapped) + return -EINVAL; + size = vma->vm_end - vma->vm_start; + if (size != s->fragsize * s->nbfrags) + return -EINVAL; + if (!s->buffers && audio_setup_buf(s)) + return -ENOMEM; + vma_addr = vma->vm_start; + for (i = 0; i < s->nbfrags; i++) { + audio_buf_t *buf = &s->buffers[i]; + if (!buf->master) + continue; + ret = remap_page_range(vma, vma->vm_start, buf->dma_desc->dsadr, + buf->master, vma->vm_page_prot); + if (ret) + return ret; + vma_addr += buf->master; + } + for (i = 0; i < s->nbfrags; i++) + s->buffers[i].dma_desc->ddadr &= ~DDADR_STOP; + s->mapped = 1; + return 0; +} + + +static int audio_release(struct inode *inode, struct file *file) +{ + audio_state_t *state = file->private_data; + + down(&state->sem); + + if (file->f_mode & FMODE_READ) { + audio_clear_buf(state->input_stream); + *state->input_stream->drcmr = 0; + pxa_free_dma(state->input_stream->dma_ch); + state->rd_ref = 0; + } + + if (file->f_mode & FMODE_WRITE) { + audio_sync(file); + audio_clear_buf(state->output_stream); + *state->output_stream->drcmr = 0; + pxa_free_dma(state->output_stream->dma_ch); + state->wr_ref = 0; + } + + up(&state->sem); + return 0; +} + + +int pxa_audio_attach(struct inode *inode, struct file *file, + audio_state_t *state) +{ + audio_stream_t *is = state->input_stream; + audio_stream_t *os = state->output_stream; + int err; + + down(&state->sem); + /* access control */ + err = -ENODEV; + if ((file->f_mode & FMODE_WRITE) && !os) + goto out; + if ((file->f_mode & FMODE_READ) && !is) + goto out; + err = -EBUSY; + if ((file->f_mode & FMODE_WRITE) && state->wr_ref) + goto out; + if ((file->f_mode & FMODE_READ) && state->rd_ref) + goto out; + + /* request DMA channels */ + if (file->f_mode & FMODE_WRITE) { + err = pxa_request_dma(os->name, DMA_PRIO_LOW, + audio_dma_irq, os); + if (err < 0) + goto out; + os->dma_ch = err; + } + if (file->f_mode & FMODE_READ) { + err = pxa_request_dma(is->name, DMA_PRIO_LOW, + audio_dma_irq, is); + if (err < 0) { + if (file->f_mode & FMODE_WRITE) { + *os->drcmr = 0; + pxa_free_dma(os->dma_ch); + } + goto out; + } + is->dma_ch = err; + } + + file->private_data = state; + file->f_op->release = audio_release; + file->f_op->write = audio_write; + file->f_op->read = audio_read; + file->f_op->mmap = audio_mmap; + file->f_op->poll = audio_poll; + file->f_op->ioctl = audio_ioctl; + file->f_op->llseek = no_llseek; + + if ((file->f_mode & FMODE_WRITE)) { + state->wr_ref = 1; + os->fragsize = AUDIO_FRAGSIZE_DEFAULT; + os->nbfrags = AUDIO_NBFRAGS_DEFAULT; + os->output = 1; + os->mapped = 0; + init_waitqueue_head(&os->frag_wq); + init_waitqueue_head(&os->stop_wq); + *os->drcmr = os->dma_ch | DRCMR_MAPVLD; + } + if (file->f_mode & FMODE_READ) { + state->rd_ref = 1; + is->fragsize = AUDIO_FRAGSIZE_DEFAULT; + is->nbfrags = AUDIO_NBFRAGS_DEFAULT; + is->output = 0; + is->mapped = 0; + init_waitqueue_head(&is->frag_wq); + init_waitqueue_head(&is->stop_wq); + *is->drcmr = is->dma_ch | DRCMR_MAPVLD; + } + + err = 0; + +out: + up(&state->sem); + return err; +} + +EXPORT_SYMBOL(pxa_audio_attach); +EXPORT_SYMBOL(pxa_audio_clear_buf); + +MODULE_AUTHOR("Nicolas Pitre, MontaVista Software Inc."); +MODULE_DESCRIPTION("audio interface for the Cotula chip"); +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.7/sound/oss/pxa-audio.h linux-2.6.7-vpac1/sound/oss/pxa-audio.h --- linux-2.6.7/sound/oss/pxa-audio.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-vpac1/sound/oss/pxa-audio.h 2004-06-23 02:57:11.000000000 +0200 @@ -0,0 +1,55 @@ +/* + * linux/drivers/sound/pxa-audio.h -- audio interface for the Cotula chip + * + * Author: Nicolas Pitre + * Created: Aug 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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. + */ + +typedef struct { + int offset; /* current buffer position */ + char *data; /* actual buffer */ + pxa_dma_desc *dma_desc; /* pointer to the starting desc */ + int master; /* owner for buffer allocation, contain size whn true */ +} audio_buf_t; + +typedef struct { + char *name; /* stream identifier */ + audio_buf_t *buffers; /* pointer to audio buffer array */ + u_int usr_frag; /* user fragment index */ + u_int dma_frag; /* DMA fragment index */ + u_int fragsize; /* fragment size */ + u_int nbfrags; /* number of fragments */ + u_int dma_ch; /* DMA channel number */ + dma_addr_t dma_desc_phys; /* phys addr of descriptor ring */ + u_int descs_per_frag; /* nbr descriptors per fragment */ + int bytecount; /* nbr of processed bytes */ + int fragcount; /* nbr of fragment transitions */ + struct semaphore sem; /* account for fragment usage */ + wait_queue_head_t frag_wq; /* for poll(), etc. */ + wait_queue_head_t stop_wq; /* for users of DCSR_STOPIRQEN */ + u_long dcmd; /* DMA descriptor dcmd field */ + volatile u32 *drcmr; /* the DMA request channel to use */ + u_long dev_addr; /* device physical address for DMA */ + int mapped:1; /* mmap()'ed buffers */ + int output:1; /* 0 for input, 1 for output */ +} audio_stream_t; + +typedef struct { + audio_stream_t *output_stream; + audio_stream_t *input_stream; + int dev_dsp; /* audio device handle */ + int rd_ref:1; /* open reference for recording */ + int wr_ref:1; /* open reference for playback */ + int (*client_ioctl)(struct inode *, struct file *, uint, ulong); + struct semaphore sem; /* prevent races in attach/release */ +} audio_state_t; + +extern int pxa_audio_attach(struct inode *inode, struct file *file, + audio_state_t *state); +extern void pxa_audio_clear_buf(audio_stream_t *s); +