diff -urN linux-2.6.19/Makefile linux-2.6.19-vpac1/Makefile --- linux-2.6.19/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/Makefile 2007-01-03 12:26:49.000000000 +0100 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 19 -EXTRAVERSION = +EXTRAVERSION = -vpac1 NAME=Avast! A bilge rat! # *DOCUMENTATION* @@ -179,8 +179,9 @@ # 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- +#CROSS_COMPILE = arm-none-linux-gnueabi- # Architecture as present in compile.h UTS_MACHINE := $(ARCH) diff -urN linux-2.6.19/arch/arm/Kconfig linux-2.6.19-vpac1/arch/arm/Kconfig --- linux-2.6.19/arch/arm/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/Kconfig 2007-01-03 12:26:49.000000000 +0100 @@ -716,7 +716,7 @@ endmenu -if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP) +if (ARCH_SA1100 || ARCH_PXA || ARCH_INTEGRATOR || ARCH_OMAP) menu "CPU Frequency scaling" @@ -732,6 +732,11 @@ depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3) default y +config CPU_FREQ_PXA + bool + depends on CPU_FREQ && ARCH_PXA + default y + config CPU_FREQ_INTEGRATOR tristate "CPUfreq driver for ARM Integrator CPUs" depends on ARCH_INTEGRATOR && CPU_FREQ diff -urN linux-2.6.19/arch/arm/Makefile linux-2.6.19-vpac1/arch/arm/Makefile --- linux-2.6.19/arch/arm/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/Makefile 2007-01-03 12:26:49.000000000 +0100 @@ -18,7 +18,7 @@ # Do not use arch/arm/defconfig - it's always outdated. # Select a platform tht is kept up-to-date -KBUILD_DEFCONFIG := versatile_defconfig +KBUILD_DEFCONFIG := vpac270_defconfig # defines filename extension depending memory manement type. ifeq ($(CONFIG_MMU),) diff -urN linux-2.6.19/arch/arm/boot/compressed/head-xscale.S linux-2.6.19-vpac1/arch/arm/boot/compressed/head-xscale.S --- linux-2.6.19/arch/arm/boot/compressed/head-xscale.S 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/boot/compressed/head-xscale.S 2007-01-03 12:26:49.000000000 +0100 @@ -41,6 +41,11 @@ mov r7, #MACH_TYPE_COTULLA_IDP #endif +#ifdef CONFIG_MACH_VPAC270 + mov r7, #(MACH_TYPE_VPAC270 & 0xFF00) + add r7, r7, #(MACH_TYPE_VPAC270 & 0xFF) +#endif + #ifdef CONFIG_MACH_GTWX5715 mov r7, #(MACH_TYPE_GTWX5715 & 0xff) orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) diff -urN linux-2.6.19/arch/arm/configs/vpac270_defconfig linux-2.6.19-vpac1/arch/arm/configs/vpac270_defconfig --- linux-2.6.19/arch/arm/configs/vpac270_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/configs/vpac270_defconfig 2007-01-03 15:38:53.000000000 +0100 @@ -0,0 +1,1109 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-vpac1 +# Wed Jan 3 14:12:26 2007 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_UID16 is not set +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_SHMEM is not set +CONFIG_SLAB=y +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_RT_MUTEXES=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 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_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 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 + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +# CONFIG_MACH_TRIZEPS4 is not set +CONFIG_MACH_VPAC270=y +CONFIG_PXA27x=y +CONFIG_IWMMXT=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x20000 +CONFIG_ZBOOT_ROM_BSS=0xa0800000 +CONFIG_ZBOOT_ROM=y +CONFIG_CMDLINE="mem=32M root=/dev/nfs ip=dhcp console=ttyS0,38400" + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_PXA=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +# CONFIG_PACKET 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_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD 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_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM 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 +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# 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 +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC 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=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# 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 +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_VPAC270=y +# CONFIG_MTD_SHARP_SL is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD 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 + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_SMC91X is not set +CONFIG_DM9000=y +# CONFIG_SMC911X is not set + +# +# 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 +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# 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 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_KEYBOARD_STOWAWAY is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_VPAC270=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING 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 is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_PXA=y +# CONFIG_I2C_PXA_SLAVE is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# 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 + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_VPAC270=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_VGA is not set +CONFIG_FB_PXA_SVGA=y +# CONFIG_FB_PXA_XGA is not set +# CONFIG_FB_PXA_BPP8 is not set +CONFIG_FB_PXA_BPP16=y +# CONFIG_FB_PXA_PARAMETERS is not set +# CONFIG_FB_MBX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_OSS_OBSOLETE_DRIVER is not set +CONFIG_SOUND_PXA_AC97=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +# CONFIG_RTC_INTF_PROC is not set +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_SA1100 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_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_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# 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_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y diff -urN linux-2.6.19/arch/arm/mach-pxa/Kconfig linux-2.6.19-vpac1/arch/arm/mach-pxa/Kconfig --- linux-2.6.19/arch/arm/mach-pxa/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/mach-pxa/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -39,6 +39,11 @@ bool "Keith und Koep Trizeps4 DIMM-Module" select PXA27x +config MACH_VPAC270 + bool "Voipac PXA270 Module" + select PXA27x + select IWMMXT + endchoice if PXA_SHARPSL diff -urN linux-2.6.19/arch/arm/mach-pxa/Makefile linux-2.6.19-vpac1/arch/arm/mach-pxa/Makefile --- linux-2.6.19/arch/arm/mach-pxa/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/mach-pxa/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -18,6 +18,7 @@ obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o obj-$(CONFIG_MACH_TOSA) += tosa.o +obj-$(CONFIG_MACH_VPAC270) += vpac270.o # Support for blinky lights led-y := leds.o @@ -28,6 +29,9 @@ obj-$(CONFIG_LEDS) += $(led-y) +# CPU Frequency scaling +obj-$(CONFIG_CPU_FREQ_PXA) += cpu-pxa.o + # Misc features obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PXA_SSP) += ssp.o diff -urN linux-2.6.19/arch/arm/mach-pxa/cpu-pxa.c linux-2.6.19-vpac1/arch/arm/mach-pxa/cpu-pxa.c --- linux-2.6.19/arch/arm/mach-pxa/cpu-pxa.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/mach-pxa/cpu-pxa.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,417 @@ +/* + * linux/arch/arm/mach-pxa/cpu-pxa.c + * + * Copyright (C) 2002,2003 Intrinsyc Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * History: + * 31-Jul-2002 : Initial version [FB] + * 29-Jan-2003 : added PXA255 support [FB] + * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) + * 11-Jan-2006 : v2.6, support for PXA27x processor up to 624MHz (Bill Reese, Hewlett Packard) + * + * Note: + * This driver may change the memory bus clock rate, but will not do any + * platform specific access timing changes... for example if you have flash + * memory connected to CS0, you will need to register a platform specific + * notifier which will adjust the memory access strobes to maintain a + * minimum strobe width. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include + +/* + * This comes from generic.h in this directory. + */ +extern unsigned int get_clk_frequency_khz(int info); + +//#define DEBUG 7 + +#ifdef DEBUG + static unsigned int freq_debug = DEBUG; + module_param(freq_debug, int, 0644); + MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); +#else + #define freq_debug 0 +#endif + +typedef struct +{ + unsigned int khz; /* CPU frequency */ + unsigned int membus; /* memory bus frequency */ + unsigned int cccr; /* new CCLKCFG setting */ + unsigned int div2; /* alter memory controller settings to divide by 2 */ + unsigned int cclkcfg; /* new CCLKCFG setting */ +} pxa_freqs_t; + +/* Define the refresh period in mSec for the SDRAM and the number of rows */ +#define SDRAM_TREF 64 /* standard 64ms SDRAM */ +#if defined(CONFIG_MACH_H4700) || defined(CONFIG_ARCH_H2200) +#define SDRAM_ROWS 8192 /* hx4700 uses 2 64Mb DRAMs, 8912 rows */ +#else +#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ +#endif +#define MDREFR_DRI(x) (((x*SDRAM_TREF/SDRAM_ROWS - 31)/32)) + +#define CCLKCFG_TURBO 0x1 +#define CCLKCFG_FCS 0x2 +#define CCLKCFG_HALFTURBO 0x4 +#define CCLKCFG_FASTBUS 0x8 +#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) +#define MDREFR_DRI_MASK 0xFFF +#define PXA25x_CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS + +/* + * For the PXA27x: + * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG. + * + * A = 0 => memory controller clock from table 3-7, + * A = 1 => memory controller clock = system bus clock + * Run mode frequency = 13 MHz * L + * Turbo mode frequency = 13 MHz * L * N + * System bus frequency = 13 MHz * L / (B + 1) + * System initialized by bootldr to: + * + * In CCCR: + * A = 1 + * L = 16 oscillator to run mode ratio + * 2N = 6 2 * (turbo mode to run mode ratio) + * + * In CCLKCFG: + * B = 1 Fast bus mode + * HT = 0 Half-Turbo mode + * T = 1 Turbo mode + * + * For now, just support some of the combinations in table 3-7 of + * PXA27x Processor Family Developer's Manual to simplify frequency + * change sequences. + * + * Specify 2N in the PXA27x_CCCR macro, not N! + */ +#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L) +#define PXA27x_CCLKCFG(B, HT, T) (B << 3 | HT << 2 | CCLKCFG_FCS | T) + +/* + * Valid frequency assignments + */ +static pxa_freqs_t pxa2xx_freqs[] = +{ + /* CPU MEMBUS CCCR DIV2*/ +#if defined(CONFIG_PXA25x) +#if defined(CONFIG_PXA25x_ALTERNATE_FREQS) + { 99500, 99500, 0x121, 1, PXA25x_CCLKCFG}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ + {199100, 99500, 0x221, 0, PXA25x_CCLKCFG}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ + {298500, 99500, 0x321, 0, PXA25x_CCLKCFG}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ + {298600, 99500, 0x1c1, 0, PXA25x_CCLKCFG}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ + {398100, 99500, 0x241, 0, PXA25x_CCLKCFG} /* run=199, turbo=398, PXbus=99, SDRAM=99 */ +#else + { 99500, 99500, 0x121, 1, PXA25x_CCLKCFG}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ + {132700, 132700, 0x123, 1, PXA25x_CCLKCFG}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ + {199100, 99500, 0x141, 0, PXA25x_CCLKCFG}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ + {265400, 132700, 0x143, 1, PXA25x_CCLKCFG}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ + {331800, 165900, 0x145, 1, PXA25x_CCLKCFG}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ + {398100, 99500, 0x161, 0, PXA25x_CCLKCFG} /* run=398, turbo=398, PXbus=196, SDRAM=99 */ +#endif +#elif defined(CONFIG_PXA27x) + {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, PXA27x_CCLKCFG(1, 0, 1)}, + {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, PXA27x_CCLKCFG(1, 1, 1)}, + {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, PXA27x_CCLKCFG(0, 0, 1)}, + {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, PXA27x_CCLKCFG(1, 0, 1)}, + {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, PXA27x_CCLKCFG(1, 0, 1)}, + {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, PXA27x_CCLKCFG(1, 0, 1)}, + {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, PXA27x_CCLKCFG(1, 0, 1)} +#endif +}; +#define NUM_FREQS (sizeof(pxa2xx_freqs)/sizeof(pxa_freqs_t)) + +static struct cpufreq_frequency_table pxa2xx_freq_table[NUM_FREQS+1]; + +/* find a valid frequency point */ +static int pxa_verify_policy(struct cpufreq_policy *policy) +{ + int ret; + + ret=cpufreq_frequency_table_verify(policy, pxa2xx_freq_table); + + if(freq_debug) { + printk("Verified CPU policy: %dKhz min to %dKhz max\n", + policy->min, policy->max); + } + + return ret; +} + +static int pxa_set_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + int idx; + cpumask_t cpus_allowed, allowedcpuset; + int cpu = policy->cpu; + struct cpufreq_freqs freqs; + unsigned long flags; + unsigned int unused; + unsigned int preset_mdrefr, postset_mdrefr, cclkcfg; + + if(freq_debug) { + printk ("CPU PXA: target freq %d\n", target_freq); + printk ("CPU PXA: relation %d\n", relation); + } + + /* + * Save this threads cpus_allowed mask. + */ + cpus_allowed = current->cpus_allowed; + + /* + * Bind to the specified CPU. When this call returns, + * we should be running on the right CPU. + */ + cpus_clear (allowedcpuset); + cpu_set (cpu, allowedcpuset); + set_cpus_allowed(current, allowedcpuset); + BUG_ON(cpu != smp_processor_id()); + + /* Lookup the next frequency */ + if (cpufreq_frequency_table_target(policy, pxa2xx_freq_table, + target_freq, relation, &idx)) { + return -EINVAL; + } + + freqs.old = policy->cur; + freqs.new = pxa2xx_freqs[idx].khz; + freqs.cpu = policy->cpu; + if(freq_debug) { + printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", + freqs.new/1000, (pxa2xx_freqs[idx].div2) ? + (pxa2xx_freqs[idx].membus/2000) : + (pxa2xx_freqs[idx].membus/1000)); + } + + /* + * Tell everyone what we're about to do... + * you should add a notify client with any platform specific + * Vcc changing capability + */ + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* Calculate the next MDREFR. If we're slowing down the SDRAM clock + * we need to preset the smaller DRI before the change. If we're speeding + * up we need to set the larger DRI value after the change. + */ + preset_mdrefr = postset_mdrefr = MDREFR; + if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa2xx_freqs[idx].membus)) { + preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) | + MDREFR_DRI(pxa2xx_freqs[idx].membus); + } + postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | + MDREFR_DRI(pxa2xx_freqs[idx].membus); + + /* If we're dividing the memory clock by two for the SDRAM clock, this + * must be set prior to the change. Clearing the divide must be done + * after the change. + */ + if(pxa2xx_freqs[idx].div2) { + /* + * Potentially speeding up memory clock, so slow down the memory + * before speeding up the clock. + */ + preset_mdrefr |= MDREFR_DB2_MASK | MDREFR_K0DB4; + preset_mdrefr &= ~MDREFR_K0DB2; + + postset_mdrefr |= MDREFR_DB2_MASK | MDREFR_K0DB4; + postset_mdrefr &= ~MDREFR_K0DB2; + } else { + /* + * Potentially slowing down memory clock. Wait until after the change + * to speed up the memory. + */ + postset_mdrefr &= ~MDREFR_DB2_MASK; + postset_mdrefr &= ~MDREFR_K0DB4; + postset_mdrefr |= MDREFR_K0DB2; + } + + cclkcfg = pxa2xx_freqs[idx].cclkcfg; + + if (freq_debug) { + printk (KERN_INFO "CPU PXA writing 0x%08x to CCCR\n", + pxa2xx_freqs[idx].cccr); + printk (KERN_INFO "CPU PXA writing 0x%08x to CCLKCFG\n", + pxa2xx_freqs[idx].cclkcfg); + printk (KERN_INFO "CPU PXA writing 0x%08x to MDREFR before change\n", + preset_mdrefr); + printk (KERN_INFO "CPU PXA writing 0x%08x to MDREFR after change\n", + postset_mdrefr); + } + + local_irq_save(flags); + + /* Set new the CCCR */ + CCCR = pxa2xx_freqs[idx].cccr; + + /* + * Should really set both of PMCR[xIDAE] while changing the core frequency + */ + + /* + * TODO: On the PXA27x: If we're setting half-turbo mode and changing the + * core frequency at the same time we must split it up into two operations. + * The current values in the pxa2xx_freqs table don't do this, so the code + * is unimplemented. + */ + + __asm__ __volatile__(" \ + ldr r4, [%1] ; /* load MDREFR */ \ + b 2f ; \ + .align 5 ; \ +1: \ + str %3, [%1] ; /* preset the MDREFR */ \ + mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \ + str %4, [%1] ; /* postset the MDREFR */ \ + \ + b 3f ; \ +2: b 1b ; \ +3: nop ; \ + " + : "=&r" (unused) + : "r" (&MDREFR), "r" (cclkcfg), \ + "r" (preset_mdrefr), "r" (postset_mdrefr) + : "r4", "r5"); + local_irq_restore(flags); + + if (freq_debug) { + printk (KERN_INFO "CPU PXA Frequency change successful\n"); + printk (KERN_INFO "CPU PXA new CCSR 0x%08x\n", CCSR); + } + + /* + * Restore the CPUs allowed mask. + */ + set_cpus_allowed(current, cpus_allowed); + + /* + * Tell everyone what we've just done... + * you should add a notify client with any platform specific + * SDRAM refresh timer adjustments + */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +static int pxa_cpufreq_init(struct cpufreq_policy *policy) +{ + cpumask_t cpus_allowed, allowedcpuset; + unsigned int cpu = policy->cpu; + int i; + unsigned int cclkcfg; + + cpus_allowed = current->cpus_allowed; + + cpus_clear (allowedcpuset); + cpu_set (cpu, allowedcpuset); + set_cpus_allowed(current, allowedcpuset); + BUG_ON(cpu != smp_processor_id()); + + /* set default governor and cpuinfo */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ + policy->cur = get_clk_frequency_khz(0); /* current freq */ + + /* Generate the cpufreq_frequency_table struct */ + for(i=0;icpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(cpu != smp_processor_id()); + + cur_freq = get_clk_frequency_khz(0); + + set_cpus_allowed(current, cpumask_saved); + + return cur_freq; +} + +static struct cpufreq_driver pxa_cpufreq_driver = { + .verify = pxa_verify_policy, + .target = pxa_set_target, + .init = pxa_cpufreq_init, + .get = pxa_cpufreq_get, +#if defined(CONFIG_PXA25x) + .name = "PXA25x", +#elif defined(CONFIG_PXA27x) + .name = "PXA27x", +#endif +}; + +static int __init pxa_cpu_init(void) +{ + return cpufreq_register_driver(&pxa_cpufreq_driver); +} + +static void __exit pxa_cpu_exit(void) +{ + cpufreq_unregister_driver(&pxa_cpufreq_driver); +} + + +MODULE_AUTHOR ("Intrinsyc Software Inc."); +MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture"); +MODULE_LICENSE("GPL"); +module_init(pxa_cpu_init); +module_exit(pxa_cpu_exit); + diff -urN linux-2.6.19/arch/arm/mach-pxa/vpac270.c linux-2.6.19-vpac1/arch/arm/mach-pxa/vpac270.c --- linux-2.6.19/arch/arm/mach-pxa/vpac270.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/mach-pxa/vpac270.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,356 @@ + /* + * linux/arch/arm/mach-pxa/vpac270.c + * + * Support for Voipac PXA270 module + * + * Copyright (c) 2006 Voipac Technologies + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "generic.h" + +#include + + +static void __init vpac270_init_irq(void) +{ + pxa_init_irq(); + + /* setup extra vpac270 irqs */ + set_irq_type(VPAC270_ETH_IRQ, IRQT_RISING); + set_irq_type(VPAC270_IDE_IRQ, IRQT_RISING); +} + +static struct resource dm9000_resources[] = { + [0] = { + .start = (VPAC270_ETH_PHYS + 0x300), + .end = (VPAC270_ETH_PHYS + 0x300 + VPAC270_ETH_SIZE - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (VPAC270_ETH_IRQ), + .end = (VPAC270_ETH_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct dm9000_plat_data dm9000_setup = { + .flags = 0 //DM9000_PLATF_16BITONLY +}; + +static struct platform_device dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(dm9000_resources), + .resource = dm9000_resources, + .dev = { + .platform_data = &dm9000_setup, + } +}; +#ifdef CONFIG_SND_PXA2XX_AC97 +static struct platform_device pxa_audio_device = { + .name = "pxa2xx-ac97", + .id = -1, +}; +#else +static struct platform_device pxa_audio_device = { + .name = "pxa-audio", + .id = 0, +}; +#endif +static struct platform_device vpac270kbd_device = { + .name = "vpac270ps2", + .id = -1, +}; + +static struct platform_device vpac270led_device = { + .name = "vpac270-led", + .id = -1, +}; + +static struct platform_device *devices[] __initdata = { + &dm9000_device, + &pxa_audio_device, + &vpac270kbd_device, + &vpac270led_device, +}; + +/* + * MMC/SD Device + * + */ +static struct pxamci_platform_data vpac270_mci_platform_data; + +static int vpac270_mci_init(struct device *dev, irqreturn_t (*detect_int)(int, void *), void *data) +{ + int err; + + printk("Voipac PXA270 MMC/SD setup "); + /* setup GPIO for PXA25x MMC controller */ + pxa_gpio_mode(GPIO_MMCCLK_AF); + pxa_gpio_mode(GPIO_MMCCMD_AF); + pxa_gpio_mode(GPIO_MMCDAT0_AF); + pxa_gpio_mode(GPIO_MMCDAT1_AF); + pxa_gpio_mode(GPIO_MMCDAT2_AF); + pxa_gpio_mode(GPIO_MMCDAT3_AF); +// pxa_gpio_mode(GPIO_MMCCS0_AF); + + pxa_gpio_mode(GPIO_MMC_CD_IRQ | GPIO_IN); +// pxa_gpio_mode(52 | GPIO_IN); + + vpac270_mci_platform_data.detect_delay = msecs_to_jiffies(250); + + err = request_irq(VPAC270_MMC_CD_IRQ, detect_int, SA_INTERRUPT, + "MMC card detect", data); + if (err) { + printk(KERN_ERR "vpac270_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + return -1; + } + + set_irq_type(VPAC270_MMC_CD_IRQ, IRQT_BOTHEDGE); + + printk("done.\n"); + return 0; +} + +static struct pxamci_platform_data vpac270_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = vpac270_mci_init, +}; + +#ifdef CONFIG_FB_PXA + +#ifdef CONFIG_FB_PXA_BPP8 +#define FB_PXA_BPP 8 +#else +#define FB_PXA_BPP 16 +#endif + +static struct pxafb_mode_info vpac270_fb_mode_info[] __initdata = { +#if defined(CONFIG_FB_PXA_VGA) +/* VGA 640x480 16bit, pclk=26MHz */ +{ + .pixclock = 40000, + .xres = 640, + .yres = 480, + .bpp = FB_PXA_BPP, + .hsync_len = 64, + .left_margin = 96, + .right_margin = 48, + .vsync_len = 2, + .upper_margin = 33, + .lower_margin = 10, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, +}, +#elif defined(CONFIG_FB_PXA_SVGA) +/* SVGA 800x600 16bit, pclk=34.6MHz */ +{ + .pixclock = 28846, + .xres = 800, + .yres = 600, + .bpp = FB_PXA_BPP, + .hsync_len = 8, + .left_margin = 128, + .right_margin = 48, + .vsync_len = 1, + .upper_margin = 33, + .lower_margin = 1, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, +}, +#elif defined(CONFIG_FB_PXA_XGA) +/* XGA 1024x768 16bit, pclk=52.0MHz */ +{ + .pixclock = 19230, + .xres = 1024, + .yres = 768, + .bpp = FB_PXA_BPP, + .hsync_len = 63, + .left_margin = 220, + .right_margin = 8, + .vsync_len = 1, + .upper_margin = 33, + .lower_margin = 2, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, +}, +#endif +}; + +static struct pxafb_mach_info vpac270_fb_mach_info __initdata = { + .modes = vpac270_fb_mode_info, + .num_modes = ARRAY_SIZE(vpac270_fb_mode_info), + .lccr0 = 0x043008f8, + .lccr3 = 0x0040ff00, +}; +#endif // CONFIG_FB_PXA + +static int vpac270_ohci_init(struct device *dev) +{ + /* setup Port1 GPIO pin. */ + pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ + pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ + pxa_gpio_mode(119 | GPIO_ALT_FN_1_IN); + pxa_gpio_mode(120 | GPIO_ALT_FN_2_OUT); + + /* Set the Power Control Polarity Low and Power Sense + Polarity Low to active low. */ + UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & + ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); + + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; + + return 0; +} + +static struct pxaohci_platform_data vpac270_ohci_platform_data = { + .port_mode = PMM_GLOBAL_MODE, //PMM_PERPORT_MODE, PMM_NPS_MODE, + .init = vpac270_ohci_init, +}; + +/* USB Device Controller */ + +static int +udc_detect(void) +{ + printk ("UDC detect\n"); +// if (core_funcs.udc_detect != NULL) +// return core_funcs.udc_detect(); +// else + return 0; +} + +static void +udc_enable(int cmd) +{ + switch (cmd) + { + case PXA2XX_UDC_CMD_DISCONNECT: + printk (KERN_NOTICE "UDC cmd disconnect\n"); + + UP2OCR = (UP2OCR | UP2OCR_HXS| UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE) & + ~(UP2OCR_DPPUE | UP2OCR_DMPUE | UP2OCR_DPPUBE | UP2OCR_DMPUBE); + break; + + case PXA2XX_UDC_CMD_CONNECT: + printk (KERN_NOTICE "UDC cmd connect\n"); + + UP2OCR = (UP2OCR | UP2OCR_HXOE | UP2OCR_DPPUE) & + ~(UP2OCR_HXS | UP2OCR_DMPUE | UP2OCR_DPPUBE | + UP2OCR_DMPUBE | UP2OCR_DPPDE | UP2OCR_DMPDE); + break; + } +} + +static struct pxa2xx_udc_mach_info hx4700_udc_mach_info = { + .udc_is_connected = udc_detect, + .udc_command = udc_enable, +}; + +static void __init vpac270_init(void) +{ + /* reset UCB1400 */ + GPSR2 &= ~(1u << 31); + pxa_gpio_mode(GPIO_AC97_RESET | GPIO_OUT); + udelay(12); + pxa_set_mci_info(&vpac270_mci_platform_data); + platform_add_devices(devices, ARRAY_SIZE(devices)); +#ifdef CONFIG_FB_PXA + set_pxa_fb_info(&vpac270_fb_mach_info); +#endif + pxa_set_ohci_info(&vpac270_ohci_platform_data); + pxa_set_udc_info( &hx4700_udc_mach_info ); + + GPDR(VPAC270_LCD_BLO_GPIO) |= GPIO_bit(VPAC270_LCD_BLO_GPIO); + GPSR(VPAC270_LCD_BLO_GPIO) |= GPIO_bit(VPAC270_LCD_BLO_GPIO); +} + +static struct map_desc vpac270_io_desc[] __initdata = { + /* virtual physical length type */ +/*{ VPAC270_FLASH, VPAC270_FLASH_PHYS, VPAC270_FLASH_SIZE, MT_DEVICE }, + { VPAC270_ETH_BASE, VPAC270_ETH_PHYS, VPAC270_ETH_SIZE, MT_DEVICE },*/ +// { 0xf0000000, __phys_to_pfn(0x0c000000), 0x04000000, MT_DEVICE }, +}; + +static void __init vpac270_map_io(void) +{ + pxa_map_io(); + iotable_init(vpac270_io_desc, ARRAY_SIZE(vpac270_io_desc)); + + /* enabling FFUART */ + CKEN |= CKEN6_FFUART; + pxa_gpio_mode(GPIO34_FFRXD_MD); + pxa_gpio_mode(GPIO100_FFCTS_MD); + pxa_gpio_mode(GPIO10_FFDCD_MD); + pxa_gpio_mode(GPIO33_FFDSR_MD); + pxa_gpio_mode(GPIO38_FFRI_MD); + pxa_gpio_mode(GPIO39_FFTXD_MD); + pxa_gpio_mode(GPIO40_FFDTR_MD); + pxa_gpio_mode(GPIO27_FFRTS_MD); + + /* enabling BTUART */ + CKEN |= CKEN7_BTUART; + pxa_gpio_mode(GPIO42_BTRXD_MD); + pxa_gpio_mode(GPIO43_BTTXD_MD); + pxa_gpio_mode(GPIO44_BTCTS_MD); + pxa_gpio_mode(GPIO45_BTRTS_MD); + + /* This is for the Davicom chip select */ + pxa_gpio_mode(GPIO78_nCS_2_MD); + + /* setup sleep mode values */ + PWER = 0x00000002; + PFER = 0x00000000; + PRER = 0x00000002; + PGSR0 = 0x00008000; + PGSR1 = 0x003F0202; + PGSR2 = 0x0001C000; + PCFR |= PCFR_OPDE; +} + +MACHINE_START(VPAC270, "Voipac PXA270 Module") + /* Maintainer: Voipac Technologies */ + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = vpac270_map_io, + .init_irq = vpac270_init_irq, + .timer = &pxa_timer, + .init_machine = vpac270_init, +MACHINE_END + diff -urN linux-2.6.19/arch/arm/tools/mach-types linux-2.6.19-vpac1/arch/arm/tools/mach-types --- linux-2.6.19/arch/arm/tools/mach-types 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/arch/arm/tools/mach-types 2007-01-03 12:38:21.000000000 +0100 @@ -1171,3 +1171,4 @@ cdcs_quoll MACH_CDCS_QUOLL CDCS_QUOLL 1158 quicksilver MACH_QUICKSILVER QUICKSILVER 1159 uplat926 MACH_UPLAT926 UPLAT926 1160 +vpac270 MACH_VPAC270 VPAC270 1227 diff -urN linux-2.6.19/drivers/cpufreq/Kconfig linux-2.6.19-vpac1/drivers/cpufreq/Kconfig --- linux-2.6.19/drivers/cpufreq/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/cpufreq/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -52,7 +52,7 @@ choice prompt "Default CPUFreq governor" - default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 + default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 || CPU_FREQ_PXA27x default CPU_FREQ_DEFAULT_GOV_PERFORMANCE help This option sets which CPUFreq governor shall be loaded at diff -urN linux-2.6.19/drivers/ide/Kconfig linux-2.6.19-vpac1/drivers/ide/Kconfig --- linux-2.6.19/drivers/ide/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/ide/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -843,6 +843,11 @@ Say Y here if you want to support the onboard IDE channels on the Simtec BAST or the Thorcom VR1000 +config BLK_DEV_IDE_VPAC270 + tristate "Voipac PXA270 IDE support" + depends on ARM && (ARCH_PXA || MACH_VPAC270) + select BLK_DEV_IDEDMA + config BLK_DEV_GAYLE bool "Amiga Gayle IDE interface support" depends on AMIGA diff -urN linux-2.6.19/drivers/ide/arm/Makefile linux-2.6.19-vpac1/drivers/ide/arm/Makefile --- linux-2.6.19/drivers/ide/arm/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/ide/arm/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -2,5 +2,6 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o +obj-$(CONFIG_BLK_DEV_IDE_VPAC270) += vpac270-ide.o EXTRA_CFLAGS := -Idrivers/ide diff -urN linux-2.6.19/drivers/ide/arm/vpac270-ide.c linux-2.6.19-vpac1/drivers/ide/arm/vpac270-ide.c --- linux-2.6.19/drivers/ide/arm/vpac270-ide.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/ide/arm/vpac270-ide.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,337 @@ +/* linux/drivers/ide/arm/vpac270-ide.c + * + * Copyright (c) 2006 Voipac Technologies + * + * 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 +#include + +#include + +/* list of registered interfaces */ +static ide_hwif_t *vpac270_hwif; + +#define IDE_BASE_PHYS 0x0c000000 +//#define DMA_IRQ_DETECT IRQ_GPIO(80) +#define GPIO80_DREQ_1_MD (80 | GPIO_ALT_FN_1_IN) + +static int vpac270_set_speed(ide_drive_t *drive, u8 xfer_mode) +{ + int on = 0, cycle_time = 0, use_dma_info = 0; + + if (xfer_mode > XFER_MW_DMA_2) + xfer_mode = XFER_MW_DMA_2; + + switch (xfer_mode) { + case XFER_MW_DMA_2: + cycle_time = 120; + use_dma_info = 1; + break; + + case XFER_MW_DMA_1: + cycle_time = 250; + use_dma_info = 1; + break; + + case XFER_MW_DMA_0: + cycle_time = 480; + break; + + case XFER_SW_DMA_2: + case XFER_SW_DMA_1: + case XFER_SW_DMA_0: + cycle_time = 480; + break; + } + + if (use_dma_info && drive->id->eide_dma_time > cycle_time) + cycle_time = drive->id->eide_dma_time; + + drive->drive_data = cycle_time; + + if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0) + on = 1; + else + drive->drive_data = 480; + + printk("%s: %s selected (peak %dMB/s)\n", drive->name, + ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); + + drive->current_speed = xfer_mode; + + return on; +} + +static int vpac270_dma_host_off(ide_drive_t *drive) +{ + return 0; +} + +static int vpac270_dma_off_quietly(ide_drive_t *drive) +{ + drive->using_dma = 0; + return vpac270_dma_host_off(drive); +} + +static int vpac270_dma_host_on(ide_drive_t *drive) +{ + return 0; +} + +static int vpac270_dma_on(ide_drive_t *drive) +{ + drive->using_dma = 1; + return vpac270_dma_host_on(drive); +} + +static int vpac270_dma_check(ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + int xfer_mode = XFER_PIO_2; + + if (!(id->capability & 1) || !hwif->autodma) + goto out; + + // consult the list of known "bad" drives + if (__ide_dma_bad_drive(drive)) + goto out; + + // enable DMA on any drive that has multiword DMA + if (id->field_valid & 2) { + xfer_mode = ide_dma_speed(drive, 0); + goto out; + } + + // consult the list of known "good" drives + if (__ide_dma_good_drive(drive)) { + if (id->eide_dma_time > 150) + goto out; + xfer_mode = XFER_MW_DMA_1; + } + +out: + if( vpac270_set_speed(drive, xfer_mode)) + return vpac270_dma_on(drive); + + return vpac270_dma_off_quietly(drive); +} + +static int vpac270_dma_setup(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct request *rq = hwif->hwgroup->rq; + + blk_queue_max_segment_size( drive->queue, (DCMD_LENGTH & 0xfffffe00) ); + ide_map_sg(drive, rq); + + hwif->sg_dma_direction = (rq_data_dir(rq) == READ)? + DMA_FROM_DEVICE : DMA_TO_DEVICE; + + if( hwif->sg_nents > 0) + { + int i = 0; + int dma = hwif->hw.dma; + struct scatterlist *sg = hwif->sg_table; + + pxa_dma_desc *ddadr = (void *) hwif->dmatable_dma; + pxa_dma_desc *ddptr = (void *) hwif->dmatable_cpu; + + DCSR(dma) = 0; + + do + { + u32 length = sg->length; + + sg->dma_address = dma_map_page( NULL, sg->page, sg->offset, + length, hwif->sg_dma_direction); + + ddptr->ddadr = (u32) ++ddadr; // next DDADR + + if(hwif->sg_dma_direction == DMA_FROM_DEVICE) + { + ddptr->dsadr = 0xc000020; // DSADR + ddptr->dtadr = sg->dma_address; // DTADR + ddptr->dcmd = (DCMD_INCTRGADDR | DCMD_BURST32 | DCMD_FLOWSRC | + DCMD_WIDTH2 | (DCMD_LENGTH & length)); + } + else + { + ddptr->dsadr = sg->dma_address; // DSADR + ddptr->dtadr = 0xc000020; // DTADR + ddptr->dcmd = (DCMD_INCSRCADDR | DCMD_BURST32 | DCMD_FLOWTRG | + DCMD_WIDTH2 | (DCMD_LENGTH & length)); + } + sg++; + } + while( ++i < hwif->sg_nents && ddptr++); + + ddptr->ddadr = DDADR_STOP; + + DDADR(dma) = hwif->dmatable_dma; + + DRQSR1 = DRQSR_REQCLR; + DRCMR1 = dma | DRCMR_MAPVLD; + + DCSR(dma) = DCSR_RUN; + drive->waiting_for_dma = 1; + } + return 0; +} + +static void vpac270_dma_exec_cmd(ide_drive_t *drive, u8 cmd) +{ + ide_execute_command(drive, cmd, &ide_dma_intr, 2 * WAIT_CMD, NULL); +} + +static void vpac270_dma_start(ide_drive_t *drive) +{ +} + +static int vpac270_dma_end(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + int dma = hwif->hw.dma; + + drive->waiting_for_dma = 0; + + while (!(DCSR(dma) & DCSR_STOPSTATE)) + cpu_relax(); + DCSR(dma) = 0; + + dma_unmap_sg( NULL, hwif->sg_table, hwif->sg_nents, + hwif->sg_dma_direction); + return 0; +} + +static int vpac270_dma_test_irq(ide_drive_t *drive) +{ + return (GPLR(GPIO_IDE_IRQ) & GPIO_bit(GPIO_IDE_IRQ)); +} + +static int vpac270_dma_timeout(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + int dma = hwif->hw.dma; +printk("%s:%d\n",__FUNCTION__,__LINE__); +printk("%s:%d DCSR(%d)=%08x\n",__FUNCTION__,__LINE__,dma,DCSR(dma)); + printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); + + if (vpac270_dma_test_irq(drive)) + return 0; + + ide_dump_status(drive, "DMA timeout", + HWIF(drive)->INB(IDE_STATUS_REG)); + + return vpac270_dma_end(drive); +} + +static int vpac270_dma_lostirq(ide_drive_t *drive) +{ +printk("%s:%d\n",__FUNCTION__,__LINE__); + printk(KERN_ERR "%s: IRQ lost\n", drive->name); + return 1; +} + +static void vpac270_pxa_dma_irq(int dma, void *dummy) +{ +printk("%s:%d DCSR(%d)=%08x\n",__FUNCTION__,__LINE__,dma,DCSR(dma)); +printk("%s:%d DRQSR1=0x%08x\n",__FUNCTION__,__LINE__,DRQSR1); + + DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; +} + +static void vpac270_dma_init(ide_hwif_t *hwif) +{ + printk(" %s: SG-DMA", hwif->name); + + pxa_gpio_mode(GPIO80_DREQ_1_MD); + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 7; + hwif->swdma_mask = 7; + + hwif->dmatable_cpu = NULL; + hwif->dmatable_dma = 0; + hwif->speedproc = vpac270_set_speed; + hwif->autodma = 1; + + hwif->ide_dma_check = vpac270_dma_check; + hwif->ide_dma_host_off = vpac270_dma_host_off; + hwif->ide_dma_off_quietly = vpac270_dma_off_quietly; + hwif->ide_dma_host_on = vpac270_dma_host_on; + hwif->ide_dma_on = vpac270_dma_on; + hwif->dma_setup = vpac270_dma_setup; + hwif->dma_exec_cmd = vpac270_dma_exec_cmd; + hwif->dma_start = vpac270_dma_start; + hwif->ide_dma_end = vpac270_dma_end; + hwif->ide_dma_test_irq = vpac270_dma_test_irq; + hwif->ide_dma_timeout = vpac270_dma_timeout; + hwif->ide_dma_lostirq = vpac270_dma_lostirq; + + hwif->drives[0].autodma = hwif->autodma; + + hwif->noprobe = 0; + hwif->chipset = ide_unknown; + hwif->channel = 0; + hwif->serialized = 1; + hwif->hw.dma = pxa_request_dma( hwif->name, DMA_PRIO_LOW, + vpac270_pxa_dma_irq, NULL); + + hwif->dmatable_cpu = dma_alloc_coherent( NULL, (PRD_ENTRIES * 4 * sizeof(u32)), + &hwif->dmatable_dma, GFP_ATOMIC); + + printk(" capable, dma=%d%s\n", hwif->hw.dma, hwif->autodma ? ", auto-enable" : ""); +} + +static int __init vpac270_ide_init(void) +{ + u32 base = (u32) ioremap( IDE_BASE_PHYS, 0x200);; + + printk("Voipac PXA270 IDE driver, (c) 2006 Voipac Technologies\n"); + + if( base) + { + int i; + hw_regs_t hw; + + memset(&hw, 0, sizeof(hw)); + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) + hw.io_ports[i] = (base + 0x120 + 2*i); + + hw.io_ports[IDE_CONTROL_OFFSET] = (base + 0x15c); + hw.irq = VPAC270_IDE_IRQ; + + ide_register_hw(&hw, &vpac270_hwif); + + vpac270_dma_init( vpac270_hwif); + } + return 0; +} + +module_init(vpac270_ide_init); + +MODULE_AUTHOR("Voipac Technologies "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Voipac PXA270 IDE driver"); + diff -urN linux-2.6.19/drivers/input/serio/Kconfig linux-2.6.19-vpac1/drivers/input/serio/Kconfig --- linux-2.6.19/drivers/input/serio/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/input/serio/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -88,6 +88,17 @@ To compile this driver as a module, choose M here: the module will be called rpckbd. +config SERIO_VPAC270 + tristate "Voipac PXA270 PS/2 controller" + depends on MACH_VPAC270 + default y + help + Say Y here if you have the Voipac PXA270 board and want to use + an AT keyboard/mouse connected to its PS/2 controller. + + To compile this driver as a module, choose M here: the + module will be called vpac270ps2. + config SERIO_AMBAKMI tristate "AMBA KMI keyboard controller" depends on ARM_AMBA diff -urN linux-2.6.19/drivers/input/serio/Makefile linux-2.6.19-vpac1/drivers/input/serio/Makefile --- linux-2.6.19/drivers/input/serio/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/input/serio/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -10,6 +10,7 @@ obj-$(CONFIG_SERIO_SERPORT) += serport.o obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o +obj-$(CONFIG_SERIO_VPAC270) += vpac270ps2.o obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o diff -urN linux-2.6.19/drivers/input/serio/vpac270ps2.c linux-2.6.19-vpac1/drivers/input/serio/vpac270ps2.c --- linux-2.6.19/drivers/input/serio/vpac270ps2.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/input/serio/vpac270ps2.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,215 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define VPAC270_SCL1_GPIO 14 +#define VPAC270_SCL1_IRQ IRQ_GPIO(VPAC270_SCL1_GPIO) +#define VPAC270_SDA1_GPIO 19 + +static int parity; +static int bitcount; +static unsigned char scan; // holds the received scan code + +static int vpac270ps2_write(struct serio *port, unsigned char val) +{ +//printk("%s:%d val=%x\n",__FUNCTION__,__LINE__,val); + + // setup clk gpio pin as output and set it to low + GPDR0 |= GPIO_bit(VPAC270_SCL1_GPIO); + GPCR0 |= GPIO_bit(VPAC270_SCL1_GPIO); + + // wait min 100us + udelay(120); + + // setup data gpio pin as output and set it to low + GPDR0 |= GPIO_bit(VPAC270_SDA1_GPIO); + GPCR0 |= GPIO_bit(VPAC270_SDA1_GPIO); + + // set scan and setup tx mode + parity = 0; + bitcount = -11; + scan = val; + + // setup clk gpio pin as input (clk transitions to high by pullup) + GPDR0 &= ~GPIO_bit(VPAC270_SCL1_GPIO); + + return 0; +} + +static irqreturn_t vpac270kbd_interrupt(int irq, void *dev_id) +{ + struct serio *port = dev_id; +//printk("%s:%d\n",__FUNCTION__,__LINE__); + if( bitcount > 0) + { + if(--bitcount > 0) // all bits received + { + // bit 3 to 10 is data, parity bit, start and stop bits are ignored + if(bitcount < 10 && bitcount > 1) + { + scan = (scan >> 1); + // keyboard data is connected to PORT3, bit3 + if(GPLR0 & GPIO_bit(VPAC270_SDA1_GPIO)) + scan = scan | 0x80; + } + } + else + { + bitcount = 11; +// printk("%s:%d scan=%x\n",__FUNCTION__,__LINE__,scan); + serio_interrupt(port, scan, 0); + } + } + else + { + if( ++bitcount < 0) // all bits received + { + if( bitcount == -2) + scan = ~parity; + + // 8 data bits and parity bit + if( bitcount < -1) + { + // set/reset data line + if( scan & 0x01) + { + parity++; + GPSR0 |= GPIO_bit(VPAC270_SDA1_GPIO); + } + else + GPCR0 |= GPIO_bit(VPAC270_SDA1_GPIO); + scan = (scan >> 1); + } + else + { + // handle stop condition + GPDR0 &= ~GPIO_bit(VPAC270_SDA1_GPIO); + } + } + else + { + // setup rx mode + GPDR0 &= ~GPIO_bit(VPAC270_SDA1_GPIO); + bitcount = 11; + +// printk("%s:%d tx complete\n",__FUNCTION__,__LINE__); + } + } + return IRQ_HANDLED; +} + +static int vpac270ps2_open(struct serio *port) +{ +//printk("%s:%d\n",__FUNCTION__,__LINE__); + pxa_gpio_mode(VPAC270_SCL1_GPIO | GPIO_IN); + pxa_gpio_mode(VPAC270_SDA1_GPIO | GPIO_IN); + + if (request_irq( VPAC270_SCL1_IRQ, vpac270kbd_interrupt, + SA_INTERRUPT, "vpac270kbd", port)) + { + printk(KERN_WARNING "vpac270kbd: failed to request IRQ: %d!\n", VPAC270_SCL1_IRQ); + } + + set_irq_type(VPAC270_SCL1_IRQ, IRQT_FALLING); + + parity = 0; + bitcount = 11; + + return 0; +} + +static void vpac270ps2_close(struct serio *port) +{ +//printk("%s:%d\n",__FUNCTION__,__LINE__); + free_irq( VPAC270_SCL1_IRQ, port); +} + +/* + * Allocate and initialize serio structure for subsequent registration + * with serio core. + */ +static int __devinit vpac270ps2_probe(struct platform_device *dev) +{ + struct serio *serio; +//printk("%s:%d\n",__FUNCTION__,__LINE__); + + serio = kmalloc(sizeof(struct serio), GFP_KERNEL); + if (!serio) + return -ENOMEM; + + memset(serio, 0, sizeof(struct serio)); + serio->id.type = SERIO_8042; + serio->write = vpac270ps2_write; + serio->open = vpac270ps2_open; + serio->close = vpac270ps2_close; + serio->dev.parent = &dev->dev; + strlcpy(serio->name, "Voipac PXA270 PS/2 kbd port", sizeof(serio->name)); + strlcpy(serio->phys, "vpac270/serio0", sizeof(serio->phys)); + + platform_set_drvdata(dev, serio); + serio_register_port(serio); + + return 0; +} + +static int __devexit vpac270ps2_remove(struct platform_device *dev) +{ + struct serio *serio = platform_get_drvdata(dev); + + serio_unregister_port(serio); + + return 0; +} + +static struct platform_driver vpac270ps2_driver = { + .probe = vpac270ps2_probe, + .remove = __devexit_p(vpac270ps2_remove), + .driver = { + .name = "vpac270ps2", + }, +}; + +static int __init vpac270ps2_init(void) +{ + return platform_driver_register(&vpac270ps2_driver); +} + +static void __exit vpac270ps2_exit(void) +{ + platform_driver_unregister(&vpac270ps2_driver); +} + +module_init(vpac270ps2_init); +module_exit(vpac270ps2_exit); + +MODULE_AUTHOR("Voipac Technologies "); +MODULE_DESCRIPTION("Voipac PXA270 PS/2 controller driver"); +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.19/drivers/leds/Kconfig linux-2.6.19-vpac1/drivers/leds/Kconfig --- linux-2.6.19/drivers/leds/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/leds/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -19,6 +19,13 @@ comment "LED drivers" +config LEDS_VPAC270 + tristate "LED Support for the Voipac PXA270 baseboard" + depends LEDS_CLASS && MACH_VPAC270 + help + This option enables support for the LED on Voipac + Technologies PXA270 developement baseboard. + config LEDS_CORGI tristate "LED Support for the Sharp SL-C7x0 series" depends LEDS_CLASS && PXA_SHARP_C7xx diff -urN linux-2.6.19/drivers/leds/Makefile linux-2.6.19-vpac1/drivers/leds/Makefile --- linux-2.6.19/drivers/leds/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/leds/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -5,6 +5,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o # LED Platform Drivers +obj-$(CONFIG_LEDS_VPAC270) += leds-vpac270.o obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o diff -urN linux-2.6.19/drivers/leds/leds-vpac270.c linux-2.6.19-vpac1/drivers/leds/leds-vpac270.c --- linux-2.6.19/drivers/leds/leds-vpac270.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/leds/leds-vpac270.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,90 @@ +/* + * LED Triggers Core + * + * Copyright (c) 2006 Voipac Technologies + * + * 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 + +#define VPAC270_GPIO_LED_ORANGE GPIO15_nCS_1 + +static void vpac270led_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + if (value) + GPSR0 = GPIO_bit(VPAC270_GPIO_LED_ORANGE); + else + GPCR0 = GPIO_bit(VPAC270_GPIO_LED_ORANGE); +} + +static struct led_classdev vpac270_orange_led = { + .name = "vpac270:orange", + .default_trigger = "heartbeat", + .brightness_set = vpac270led_set, +}; + +#ifdef CONFIG_PM +static int vpac270led_suspend(struct platform_device *dev, pm_message_t state) +{ + led_classdev_suspend(&vpac270_orange_led); + return 0; +} + +static int vpac270led_resume(struct platform_device *dev) +{ + led_classdev_resume(&vpac270_orange_led); + return 0; +} +#endif + +static int vpac270led_probe(struct platform_device *pdev) +{ + return led_classdev_register(&pdev->dev, &vpac270_orange_led); +} + +static int vpac270led_remove(struct platform_device *pdev) +{ + led_classdev_unregister(&vpac270_orange_led); + return 0; +} + +static struct platform_driver vpac270led_driver = { + .probe = vpac270led_probe, + .remove = vpac270led_remove, +#ifdef CONFIG_PM + .suspend = vpac270led_suspend, + .resume = vpac270led_resume, +#endif + .driver = { + .name = "vpac270-led", + }, +}; + +static int __init vpac270led_init(void) +{ + return platform_driver_register(&vpac270led_driver); +} + +static void __exit vpac270led_exit(void) +{ + platform_driver_unregister(&vpac270led_driver); +} + +module_init(vpac270led_init); +module_exit(vpac270led_exit); + +MODULE_AUTHOR("Voipac Technologies "); +MODULE_DESCRIPTION("Voipac PXA270 LED driver"); +MODULE_LICENSE("GPL"); diff -urN linux-2.6.19/drivers/mtd/maps/Kconfig linux-2.6.19-vpac1/drivers/mtd/maps/Kconfig --- linux-2.6.19/drivers/mtd/maps/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/mtd/maps/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -515,6 +515,13 @@ This enables access to the flash chips on the Hynix evaluation boards. If you have such a board, say 'Y'. +config MTD_VPAC270 + tristate "Voipac PXA270 module flash mapping" + depends on MACH_VPAC270 && MTD_CFI && MTD_PARTITIONS + help + This enables access to the flash memory on the Voipac PXA270 module. + If you have such a module, say 'Y'. + config MTD_MPC1211 tristate "CFI Flash device mapped on Interface MPC-1211" depends on SH_MPC1211 && MTD_CFI diff -urN linux-2.6.19/drivers/mtd/maps/Makefile linux-2.6.19-vpac1/drivers/mtd/maps/Makefile --- linux-2.6.19/drivers/mtd/maps/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/mtd/maps/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -70,3 +70,4 @@ obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o obj-$(CONFIG_MTD_TQM834x) += tqm834x.o +obj-$(CONFIG_MTD_VPAC270) += vpac270.o diff -urN linux-2.6.19/drivers/mtd/maps/vpac270.c linux-2.6.19-vpac1/drivers/mtd/maps/vpac270.c --- linux-2.6.19/drivers/mtd/maps/vpac270.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/mtd/maps/vpac270.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,142 @@ +/* + * Map driver for the Voipac PXA270 module + * + * Modified from drivers/mtd/maps/iq80310.c + * Orignal Author: Nicolas Pitre + * + * Copyright: (C) 2001 MontaVista Software Inc. + * Copyright (c) 2006 Voipac Technologies + * + * 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 + + +#define ROM_ADDR 0x00000000 +#define WINDOW_SIZE 32*1024*1024 + +#ifdef CONFIG_PM +struct pm_dev *flash_pmdev; +#endif + +static struct map_info vpac270_map = { + .name = "Voipac PXA270 Flash", + .size = WINDOW_SIZE, + .bankwidth = 2, + .phys = ROM_ADDR +}; + +static struct mtd_partition vpac270_partitions[] = { + { + name: "Bootloader", + size: 0x00020000, /* 128kB u-boot and config params */ + offset: 0, + /*mask_flags: MTD_WRITEABLE force read-only */ + },{ + name: "Kernel", + size: 0x000e0000, /* 896kB for kernel */ + offset: 0x00020000, + },{ + name: "Filesystem", + size: MTDPART_SIZ_FULL, + offset: 0x00100000 + } +}; + +static struct mtd_info *mymtd; + +#ifdef VPAC270_PARTS_PARSING +static struct mtd_partition *parsed_parts; +static int nr_parsed_parts; + +static const char* probes[] = { "RedBoot", "cmdlinepart", NULL }; +#endif + +#include + +static int __init init_vpac270(void) +{ + printk( "Probing Voipac PXA270 flash at physical address 0x%08lx (%d-bit buswidth)\n", + vpac270_map.phys, vpac270_map.bankwidth * 8 ); + + vpac270_map.virt = ioremap(vpac270_map.phys, vpac270_map.size); + if (!vpac270_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&vpac270_map); + + mymtd = do_map_probe("cfi_probe", &vpac270_map); + if (!mymtd) { + iounmap((void *)vpac270_map.virt); + return -ENXIO; + } + mymtd->owner = THIS_MODULE; + +#ifdef DO_FLASH_UNLOCK + /* Unlock the flash device. */ + for (i = 0; i < mymtd->numeraseregions; i++) { + int j; + for( j = 0; j < mymtd->eraseregions[i].numblocks; j++) { + mymtd->unlock(mymtd, mymtd->eraseregions[i].offset + + j * mymtd->eraseregions[i].erasesize, + mymtd->eraseregions[i].erasesize); + } + } +#endif + +#ifdef VPAC270_PARTS_PARSING + ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0); + + if (ret > 0) + nr_parsed_parts = ret; +#endif + + if (!mymtd) { + printk(KERN_WARNING "%s is absent. Skipping\n", vpac270_map.name); +#ifdef VPAC270_PARTS_PARSING + } else if (nr_parsed_parts) { + add_mtd_partitions(mymtd, parsed_parts, nr_parsed_parts); +#endif + } else { + add_mtd_partitions(mymtd, vpac270_partitions, ARRAY_SIZE(vpac270_partitions)); + } + + return 0; +} + +static void __exit cleanup_vpac270(void) +{ + if (mymtd) { +#ifdef VPAC270_PARTS_PARSING + if (nr_parsed_parts) + del_mtd_partitions(mymtd); + else +#endif + del_mtd_device(mymtd); + + map_destroy(mymtd); +#ifdef VPAC270_PARTS_PARSING + if (parsed_parts) + kfree(parsed_parts); +#endif + } + + if (vpac270_map.virt) + iounmap((void *)vpac270_map.virt); +} + +module_init(init_vpac270); +module_exit(cleanup_vpac270); + diff -urN linux-2.6.19/drivers/net/dm9000.c linux-2.6.19-vpac1/drivers/net/dm9000.c --- linux-2.6.19/drivers/net/dm9000.c 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/net/dm9000.c 2007-01-03 12:26:50.000000000 +0100 @@ -422,9 +422,10 @@ ret = -ENODEV; goto out; } else if (pdev->num_resources == 2) { - base = pdev->resource[0].start; + iosize = 4; + base = (unsigned long) ioremap(pdev->resource[0].start, 8); - if (!request_mem_region(base, 4, ndev->name)) { + if (!request_mem_region(base, 8, ndev->name)) { ret = -EBUSY; goto out; } @@ -432,7 +433,7 @@ ndev->base_addr = base; ndev->irq = pdev->resource[1].start; db->io_addr = (void __iomem *)base; - db->io_data = (void __iomem *)(base + 4); + db->io_data = (void __iomem *)(base + iosize); } else { db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -486,11 +487,11 @@ ndev->base_addr = (unsigned long)db->io_addr; ndev->irq = db->irq_res->start; - - /* ensure at least we have a default set of IO routines */ - dm9000_set_io(db, iosize); } + /* ensure at least we have a default set of IO routines */ + dm9000_set_io(db, iosize); + /* check to see if anything is being over-ridden */ if (pdata != NULL) { /* check to see if the driver wants to over-ride the diff -urN linux-2.6.19/drivers/pcmcia/Makefile linux-2.6.19-vpac1/drivers/pcmcia/Makefile --- linux-2.6.19/drivers/pcmcia/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/pcmcia/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -69,4 +69,5 @@ pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o +pxa2xx_cs-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o diff -urN linux-2.6.19/drivers/pcmcia/pxa2xx_vpac270.c linux-2.6.19-vpac1/drivers/pcmcia/pxa2xx_vpac270.c --- linux-2.6.19/drivers/pcmcia/pxa2xx_vpac270.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/pcmcia/pxa2xx_vpac270.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,248 @@ +/* + * linux26/drivers/pcmcia/pxa2xx_vpac270.c + * + * 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. + * + * Copyright (c) 2002 Accelent Systems, Inc. All Rights Reserved + * Copyright (c) 2006 Voipac Technologies + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "soc_common.h" + +//#define DEBUG_COL_PCMCIA + +#ifdef DEBUG_COL_PCMCIA +#define MARK printk(KERN_INFO "%s: %d\n", __FUNCTION__, __LINE__); +#else +//#define MARK (0) +#endif +#ifdef PCMCIA_DEBUG +int pc_debug = PCMCIA_DEBUG; +#endif + +static struct pcmcia_irqs irqs[] = { + { 0, VPAC270_PCMCIA0_CD_IRQ, "CF CD"}, + { 1, VPAC270_PCMCIA1_CD_IRQ, "PCMCIA CD"}, +}; + + +static int vpac270_pcmcia_init_dev(struct soc_pcmcia_socket *skt) +{ + printk("Voipac PXA270 PCMCIA\n"); + /* set power GPIO; switch off */ + GPCR(GPIO_PCMCIA_POW_EN) |= GPIO_bit(GPIO_PCMCIA_POW_EN); + GPDR(GPIO_PCMCIA_POW_EN) |= GPIO_bit(GPIO_PCMCIA_POW_EN); + + /* set PCMCIA AFs */ + GPSR(GPIO_PCMCIA_NPOE) |= GPIO_bit(GPIO_PCMCIA_NPOE); + pxa_gpio_mode(GPIO_PCMCIA_NPOE | GPIO_PCMCIA_NPOE_AF); + + GPSR(GPIO_PCMCIA_NPIOR) |= GPIO_bit(GPIO_PCMCIA_NPIOR); + pxa_gpio_mode(GPIO_PCMCIA_NPIOR | GPIO_PCMCIA_NPIOR_AF); + + GPSR(GPIO_PCMCIA_NPIOW) |= GPIO_bit(GPIO_PCMCIA_NPIOW); + pxa_gpio_mode(GPIO_PCMCIA_NPIOW | GPIO_PCMCIA_NPIOW_AF); + + GPSR(GPIO_PCMCIA_NPCE1) |= GPIO_bit(GPIO_PCMCIA_NPCE1); + pxa_gpio_mode(GPIO_PCMCIA_NPCE1 | GPIO_PCMCIA_NPCE1_AF); + + GPCR(GPIO_PCMCIA_NPCE2) |= GPIO_bit(GPIO_PCMCIA_NPCE2); + pxa_gpio_mode(GPIO_PCMCIA_NPCE2 | GPIO_PCMCIA_NPCE2_AF); + + GPSR(GPIO_PCMCIA_NPREG) |= GPIO_bit(GPIO_PCMCIA_NPREG); + pxa_gpio_mode(GPIO_PCMCIA_NPREG | GPIO_PCMCIA_NPREG_AF); + + pxa_gpio_mode(GPIO_PCMCIA_NPWAIT | GPIO_PCMCIA_NPWAIT_AF); + + pxa_gpio_mode(GPIO_PCMCIA_NPIOIS16 | GPIO_PCMCIA_NPIOIS16_AF); + + GPSR(GPIO_PCMCIA_PSKTSEL) |= GPIO_bit(GPIO_PCMCIA_PSKTSEL); + pxa_gpio_mode(GPIO_PCMCIA_PSKTSEL | GPIO_PCMCIA_PSKTSEL_AF); + + /* set other PCMCIA GPIOs */ + GPCR(GPIO_PCMCIA0_RESET) |= GPIO_bit(GPIO_PCMCIA0_RESET); + GPDR(GPIO_PCMCIA0_RESET) |= GPIO_bit(GPIO_PCMCIA0_RESET); + GPCR(GPIO_PCMCIA1_RESET) |= GPIO_bit(GPIO_PCMCIA1_RESET); + GPDR(GPIO_PCMCIA1_RESET) |= GPIO_bit(GPIO_PCMCIA1_RESET); + +// GPDR(GPIO_PCMCIA0_BVD1) &= ~GPIO_bit(GPIO_PCMCIA0_BVD1); +// GPDR(GPIO_PCMCIA0_BVD2) &= ~GPIO_bit(GPIO_PCMCIA0_BVD2); + + /* switch power on */ + PCC_PWR_ON(); + + /* reset the PCMCIA controller */ + GPSR(GPIO_PCMCIA0_RESET) |= GPIO_bit(GPIO_PCMCIA0_RESET); + GPSR(GPIO_PCMCIA1_RESET) |= GPIO_bit(GPIO_PCMCIA1_RESET); + udelay(500); + /* un-reset it again */ + GPCR(GPIO_PCMCIA0_RESET) |= GPIO_bit(GPIO_PCMCIA0_RESET); + GPCR(GPIO_PCMCIA1_RESET) |= GPIO_bit(GPIO_PCMCIA1_RESET); + + /* set interrupts */ + GPDR(GPIO_PCMCIA0_CD_IRQ) &= ~GPIO_bit(GPIO_PCMCIA0_CD_IRQ); + set_irq_type(GPIO_PCMCIA0_CD_IRQ, VPAC270_PCMCIA_CD_EDGE); + + GPDR(GPIO_PCMCIA0_RDY_IRQ) &= ~GPIO_bit(GPIO_PCMCIA0_RDY_IRQ); + set_irq_type(GPIO_PCMCIA0_RDY_IRQ, VPAC270_PCMCIA_RDY_EDGE); + + GPDR(GPIO_PCMCIA1_CD_IRQ) &= ~GPIO_bit(GPIO_PCMCIA1_CD_IRQ); + set_irq_type(GPIO_PCMCIA1_CD_IRQ, VPAC270_PCMCIA_CD_EDGE); + + GPDR(GPIO_PCMCIA1_RDY_IRQ) &= ~GPIO_bit(GPIO_PCMCIA1_RDY_IRQ); + set_irq_type(GPIO_PCMCIA1_RDY_IRQ, VPAC270_PCMCIA_RDY_EDGE); + + if (skt->irq == NO_IRQ) + skt->irq = skt->nr ? VPAC270_PCMCIA1_RDY_IRQ : VPAC270_PCMCIA0_RDY_IRQ; + + return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); +// skt->irq = VPAC270_PCMCIA0_RDY_IRQ; +// return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); +} + +static void vpac270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) +{ + soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + + /* switch power off */ + PCC_PWR_OFF(); +} + +static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + //memset(state, 0, sizeof(*state)); + + switch( skt->nr) + { + case 0: + state->detect = (PCC0_DETECT) ? 0 : 1; + state->ready = (PCC0_READY) ? 1 : 0; + break; + + case 1: + state->detect = (PCC1_DETECT) ? 0 : 1; + state->ready = (PCC1_READY) ? 1 : 0; + break; + + default: + return -1; + } +/* + printk(KERN_INFO "CF status: detect: %u, ready: %u\n", + GPLR(84) & GPIO_bit(84), + GPLR(1) & GPIO_bit(1)); +*/ + + state->bvd1 = 1; //PCC_BVD1() ? 1 : 0; + state->bvd2 = 1; //PCC_BVD2() ? 1 : 0; + state->wrprot = 0; /* r/w all the time */ + state->vs_3v = PCC_VS3V() ? 1 : 0; + state->vs_Xv = PCC_VS5V() ? 1 : 0; +} + +static int vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + socket_state_t const *state) +{ + unsigned long flags; + + local_irq_save(flags); + /* configure Vcc and Vpp */ + if (state->Vcc == 0 && state->Vpp == 0) + { + PCC_PWR_OFF(); + } + else if (state->Vcc == 33 && state->Vpp < 50) + { + PCC_PWR_ON(); + } + else + { + printk(KERN_ERR "%s(): unsupported Vcc %u Vpp %u combination\n", + __FUNCTION__, state->Vcc, state->Vpp); + return -1; + } + + /* reset PCMCIA if requested */ +// if (state->flags & SS_RESET) +// { +// GPSR(GPIO_PCMCIA0_RESET) |= GPIO_bit(GPIO_PCMCIA0_RESET); +// } + + local_irq_restore(flags); + udelay(200); + + return 0; +} + +static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +struct pcmcia_low_level vpac270_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = vpac270_pcmcia_init_dev, + .hw_shutdown = vpac270_pcmcia_shutdown, + .socket_state = vpac270_pcmcia_socket_state, + .configure_socket = vpac270_pcmcia_configure_socket, + .socket_init = vpac270_pcmcia_socket_init, + .socket_suspend = vpac270_pcmcia_socket_suspend, + .first = 0, + .nr = 2 +}; + +static struct platform_device *vpac270_pcmcia_device; + +static int __init vpac270_pcmcia_init(void) +{ + int ret; + + vpac270_pcmcia_device = kmalloc(sizeof(*vpac270_pcmcia_device), GFP_KERNEL); + if (!vpac270_pcmcia_device) + return -ENOMEM; + memset(vpac270_pcmcia_device, 0, sizeof(*vpac270_pcmcia_device)); + vpac270_pcmcia_device->name = "pxa2xx-pcmcia"; + vpac270_pcmcia_device->dev.platform_data = &vpac270_pcmcia_ops; + + ret = platform_device_register(vpac270_pcmcia_device); + if (ret) + kfree(vpac270_pcmcia_device); + + return ret; +} + +static void __exit vpac270_pcmcia_exit(void) +{ + /* Are there still references to vpac270_pcmcia_device? + * I don't know, so I'd better not free it. + * Actually, I don't really care, as I don't really support + * this driver as module anyway... + */ + platform_device_unregister(vpac270_pcmcia_device); +} + +module_init(vpac270_pcmcia_init); +module_exit(vpac270_pcmcia_exit); + +MODULE_DESCRIPTION("Voipac PXA270 CF Support"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Voipac Technologies "); diff -urN linux-2.6.19/drivers/video/Kconfig linux-2.6.19-vpac1/drivers/video/Kconfig --- linux-2.6.19/drivers/video/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/video/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -1520,6 +1520,37 @@ If unsure, say N. +choice + + depends on FB_PXA + prompt "PXA framebuffer resolution" + default FB_PXA_VGA + +config FB_PXA_VGA + bool "VGA 640x480" + +config FB_PXA_SVGA + bool "SVGA 800x600" + +config FB_PXA_XGA + bool "XGA 1024x768" + +endchoice + +choice + + depends on FB_PXA + prompt "PXA framebuffer bits per pixel" + default FB_PXA_BPP16 + +config FB_PXA_BPP8 + bool "8 bpp" + +config FB_PXA_BPP16 + bool "16 bpp" + +endchoice + config FB_PXA_PARAMETERS bool "PXA LCD command line parameters" default n diff -urN linux-2.6.19/drivers/video/pxafb.c linux-2.6.19-vpac1/drivers/video/pxafb.c --- linux-2.6.19/drivers/video/pxafb.c 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/drivers/video/pxafb.c 2007-01-03 12:26:50.000000000 +0100 @@ -517,7 +517,7 @@ pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock; do_div(pcd, 100000000 * 2); /* no need for this, since we should subtract 1 anyway. they cancel */ - /* pcd += 1; */ /* make up for integer math truncations */ + pcd += 1; /* make up for integer math truncations */ return (unsigned int)pcd; } @@ -806,6 +806,7 @@ pxa_set_cken(CKEN16_LCD, 1); /* Sequence from 11.7.10 */ + LCCR4 = (fbi->fb.var.bits_per_pixel < 16)? 0x800b0000 : 0x800a0000; LCCR3 = fbi->reg_lccr3; LCCR2 = fbi->reg_lccr2; LCCR1 = fbi->reg_lccr1; @@ -821,6 +822,7 @@ pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1); pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2); pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3); + pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4); } static void pxafb_disable_controller(struct pxafb_info *fbi) @@ -1337,7 +1339,7 @@ goto failed; #endif -#ifdef DEBUG_VAR +#if DEBUG_VAR /* Check for various illegal bit-combinations. Currently only * a warning is given. */ diff -urN linux-2.6.19/include/asm-arm/arch-pxa/hardware.h linux-2.6.19-vpac1/include/asm-arm/arch-pxa/hardware.h --- linux-2.6.19/include/asm-arm/arch-pxa/hardware.h 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/include/asm-arm/arch-pxa/hardware.h 2007-01-03 12:26:50.000000000 +0100 @@ -44,12 +44,24 @@ #ifndef __ASSEMBLY__ +#if 0 # define __REG(x) (*((volatile u32 *)io_p2v(x))) +#else +/* + * This __REG() version gives the same results as the one above, except + * that we are fooling gcc somehow so it generates far better and smaller + * assembly code for access to contigous registers. It's a shame that gcc + * doesn't guess this by itself. + */ +#include +typedef struct { volatile u32 offset[4096]; } __regbase; +# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2] +# define __REG(x) __REGP(io_p2v(x)) +#endif /* With indexed regs we don't want to feed the index through io_p2v() especially if it is a variable, otherwise horrible code will result. */ -# define __REG2(x,y) \ - (*(volatile u32 *)((u32)&__REG(x) + (y))) +# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) # define __PREG(x) (io_v2p((u32)&(x))) @@ -80,4 +92,8 @@ #endif +#ifdef CONFIG_MACH_VPAC270 +#include "vpac270.h" +#endif + #endif /* _ASM_ARCH_HARDWARE_H */ diff -urN linux-2.6.19/include/asm-arm/arch-pxa/pxa-regs.h linux-2.6.19-vpac1/include/asm-arm/arch-pxa/pxa-regs.h --- linux-2.6.19/include/asm-arm/arch-pxa/pxa-regs.h 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/include/asm-arm/arch-pxa/pxa-regs.h 2007-01-03 12:26:50.000000000 +0100 @@ -108,6 +108,14 @@ #define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */ #define DALGN __REG(0x400000a0) /* DMA Alignment Register */ + +#define DRQSR0 __REG(0x400000e0) /* DMA Request Status Register 0 */ +#define DRQSR1 __REG(0x400000e4) /* DMA Request Status Register 1 */ +#define DRQSR2 __REG(0x400000e8) /* DMA Request Status Register 2 */ + +#define DRQSR_REQCLR (1 << 8) /* Clear Pending Requests */ +#define DRQSR_REQPEND 0x0000001f + #define DINT __REG(0x400000f0) /* DMA Interrupt Register */ #define DRCMR(n) __REG2(0x40000100, (n)<<2) @@ -273,6 +281,10 @@ #define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */ #define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ +/* default combinations */ +#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) +#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) +#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4) /* * UARTs @@ -1129,7 +1141,6 @@ #define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ #define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ - /* * General Purpose I/O */ @@ -1322,6 +1333,7 @@ #define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ #define GPIO78_nCS_2 78 /* chip select 2 */ #define GPIO79_nCS_3 79 /* chip select 3 */ +#define GPIO79_pSKTSEL 79 /* pSKTSEL - PC Card Socket select (PXA27xx)*/ #define GPIO80_nCS_4 80 /* chip select 4 */ #define GPIO81_NSCLK 81 /* NSSP clock */ #define GPIO82_NSFRM 82 /* NSSP Frame */ @@ -1361,6 +1373,7 @@ #define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) #define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) #define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) +#define GPIO10_FFDCD_MD (10 | GPIO_ALT_FN_1_IN) #define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) #define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) #define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) @@ -1376,6 +1389,7 @@ #define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) #define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) #define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) +#define GPIO27_FFRTS_MD (27 | GPIO_ALT_FN_3_OUT) #define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) #define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) #define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) @@ -1389,6 +1403,7 @@ #define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) #define GPIO32_MMCCLK_MD ( 32 | GPIO_ALT_FN_2_OUT) #define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) +#define GPIO33_FFDSR_MD (33 | GPIO_ALT_FN_2_IN) #define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) #define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) #define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) @@ -1472,6 +1487,7 @@ #define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) #define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) +#define GPIO100_FFCTS_MD (100 | GPIO_ALT_FN_2_IN) #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) #define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) @@ -1485,6 +1501,7 @@ #define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) + /* * Power Manager */ @@ -1845,6 +1862,7 @@ #define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */ #define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */ #define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */ +#define LCCR4 __REG(0x44000010) /* LCD Controller Control Register 4 */ #define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */ #define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */ #define LCSR __REG(0x44000038) /* LCD Controller Status Register */ @@ -1857,6 +1875,7 @@ #define LCCR3_4BPP (2 << 24) #define LCCR3_8BPP (3 << 24) #define LCCR3_16BPP (4 << 24) +#define LCCR3_18BPP (5 << 24) #define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ #define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */ diff -urN linux-2.6.19/include/asm-arm/arch-pxa/vpac270.h linux-2.6.19-vpac1/include/asm-arm/arch-pxa/vpac270.h --- linux-2.6.19/include/asm-arm/arch-pxa/vpac270.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/include/asm-arm/arch-pxa/vpac270.h 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,253 @@ +/* + * linux/include/asm-arm/arch-pxa/vpac270.h + * + * 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. + * + * Copyright (c) 2006 Voipac Technologies + * + */ + +#include +#include + + +/* + * Note: include file for assembler and C + */ + +/* + * Video settings + */ + +#define VPAC270_ANALOG_VGA +//#define VPAC270_LCD_PHILIPSLB + +#ifdef VPAC270_ANALOG_VGA +/* set to 1 if you want these settings to be active */ +#define VPAC270_LCD_SETTINGS 1 + +/* set to GPIO that switches on the backlight */ +#define VPAC270_LCD_BLO_GPIO 81 + +/* set to 1 if the LCD is an active panel (TFT) or for VGA */ +#define VPAC270_LCD_ACTIVE 1 + +/* set to 1 if the LCD panel is a dual-scan panel */ +#define VPAC270_LCD_DUAL 0 + +/* set to 1 if the LCD BIAS pin should be active low (OEP) */ +#define VPAC270_BIAS_ACTIVE_LOW 0 + +/* set to 1 if the data is sampled on the falling edge of the pixel clock PCP*/ +#define VPAC270_PIX_CLK_FALLING 0 + +/* set to 3 if more than 16 bpp (PDFOR) */ +#define VPAC270_PIXEL_DATA_FORMAT 3 + +/* the following settings can also be set using fbset */ +/* these are settings are for analog VGA */ +#define LCD_PIXCLOCK 40000 +#define LCD_XRES 640 +#define LCD_YRES 480 +#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 64 +#define LCD_VERTICAL_SYNC_PULSE_WIDTH 2 +#define LCD_BEGIN_OF_LINE_WAIT_COUNT 96 +#define LCD_BEGIN_FRAME_WAIT_COUNT 33 +#define LCD_END_OF_LINE_WAIT_COUNT 48 +#define LCD_END_OF_FRAME_WAIT_COUNT 10 +#define LCD_SYNC 0 + + +/* VGA timings: +pixclk 0x1801050 Hz (25MHz) = 40000ps +640x480 18BPP +LCD_HORIZONTAL_SYNC_PULSE_WIDTH HSPW 0x40 +LCD_BEGIN_OF_LINE_WAIT_COUNT BLW 0x60 +LCD_END_OF_LINE_WAIT_COUNT ELW 0x30 +LCD_VERTICAL_SYNC_PULSE_WIDTH VSW 0x2 +LCD_BEGIN_FRAME_WAIT_COUNT BFW 0x21 +LCD_END_OF_FRAME_WAIT_COUNT EFW 0xa +VPAC270_PIX_CLK_FALLING PCP 0 +FB_SYNC_HOR_HIGH_ACT_LOW HSP 1 +FB_SYNC_VERT_HIGH_ACT_LOW VSP 1 +VPAC270_LCD_DUAL SDS 0 +VPAC270_LCD_ACTIVE PAS 1 +VPAC270_BIAS_ACTIVE_LOW OEP 0 +*/ + +#elif defined VPAC270_LCD_PHILIPSLB + +/* set to 1 if you want these settings to be active */ +#define VPAC270_LCD_SETTINGS 1 + +/* set to GPIO that switches on the backlight */ +#define VPAC270_LCD_BLO_GPIO 81 + +/* set to 1 if the LCD is an active panel (TFT) or for VGA */ +#define VPAC270_LCD_ACTIVE 1 + +/* set to 1 if the LCD panel is a dual-scan panel */ +#define VPAC270_LCD_DUAL 0 + +/* set to 1 if the LCD BIAS pin should be active low (OEP) */ +#define VPAC270_BIAS_ACTIVE_LOW 0 + +/* set to 1 if the data is sampled on the falling edge of the pixel clock PCP*/ +#define VPAC270_PIX_CLK_FALLING 1 + +/* set to 3 if more than 16 bpp (PDFOR) */ +#define VPAC270_PIXEL_DATA_FORMAT 3 + +/* the following settings can also be set using fbset */ +/* these are settings are for analog VGA */ +#define LCD_PIXCLOCK 40000 +#define LCD_XRES 640 +#define LCD_YRES 480 +#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 2 +#define LCD_VERTICAL_SYNC_PULSE_WIDTH 45 +#define LCD_BEGIN_OF_LINE_WAIT_COUNT 160 +#define LCD_BEGIN_FRAME_WAIT_COUNT 0 +#define LCD_END_OF_LINE_WAIT_COUNT 2 +#define LCD_END_OF_FRAME_WAIT_COUNT 0 +#define LCD_SYNC (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT) + +/* Philips LB064V02-A1 timings: +pixclk 0x1801050 Hz (25MHz) = 40000ps +640x480 18BPP +LCD_HORIZONTAL_SYNC_PULSE_WIDTH HSPW 2 +LCD_BEGIN_OF_LINE_WAIT_COUNT BLW 160 +LCD_END_OF_LINE_WAIT_COUNT ELW 2 +LCD_VERTICAL_SYNC_PULSE_WIDTH VSW 45 +LCD_BEGIN_FRAME_WAIT_COUNT BFW 0 +LCD_END_OF_FRAME_WAIT_COUNT EFW 0 +VPAC270_PIX_CLK_FALLING PCP 1 +FB_SYNC_HOR_HIGH_ACT_LOW HSP 0 +FB_SYNC_VERT_HIGH_ACT_LOW VSP 0 +VPAC270_LCD_DUAL SDS 0 +VPAC270_LCD_ACTIVE PAS 1 +VPAC270_BIAS_ACTIVE_LOW OEP 0 +*/ +#endif + + +/* + * physical memory map + */ + +#define VPAC270_FLASH_PHYS PXA_CS0_PHYS /* 0x00000000 */ +#define VPAC270_FLASH_SIZE (0x02000000) + +#define VPAC270_ETH_PHYS PXA_CS2_PHYS /* 0x08000000 */ +//#define VPAC270_CPLD_PHYS PXA_CS3_PHYS /* 0x0c000000 */ +#define VPAC270_BCR_PHYS 0x0e000000 + +/* + * virtual memory map + */ + +#define VPAC270_FLASH 0x00000000 +//#define VPAC270_ETH_BASE 0xf4000000 +#define VPAC270_ETH_SIZE 8 + +//#define VPAC270_CPLD_BASE 0xf0000000 +//#define VPAC270_CPLD_SIZE 0x04000000 +#define VPAC270_CF_OFFSET 0x00000000 +#define VPAC270_BCR_OFFSET 0x02000000 +#define VPAC270_IRDA_OFFSET 0x02400000 +#define VPAC270_UPS_OFFSET 0x02800000 +#define VPAC270_DCR_OFFSET 0x03800000 + +//#ifndef __ASSEMBLY__ +//# define CPLD_REG(x) (*((volatile unsigned short *)(VPAC270_CPLD_BASE + (x)))) +//#else +//# define CPLD_REG(x) (VPAC270_CPLD_BASE + (x)) +//#endif + + +//#define DM9000_BASE VPAC270_ETH_BASE +//#define DM9000_MMIO 1 +//#define DM9000_ADDRFROMTAG 1 + +#define VPAC270_CF0_STATUS CPLD_REG(VPAC270_CF_OFFSET) +#define VPAC270_BCR_CONTROL CPLD_REG(VPAC270_BCR_OFFSET) +#define VPAC270_DCR CPLD_REG(VPAC270_DCR_OFFSET) + +/* + * interrupts + */ +/* Ethernet */ +#define GPIO_ETH_IRQ 114 +#define VPAC270_ETH_IRQ IRQ_GPIO(GPIO_ETH_IRQ) +#define DM9000_IRQ VPAC270_ETH_IRQ + +/* IDE */ +#define GPIO_IDE_IRQ 36 +#define VPAC270_IDE_IRQ IRQ_GPIO(GPIO_IDE_IRQ) + +/* Compact Flash/PCMCIA */ +#define GPIO_PCMCIA0_CD_IRQ 84 +#define VPAC270_PCMCIA0_CD_IRQ IRQ_GPIO(GPIO_PCMCIA0_CD_IRQ) +#define GPIO_PCMCIA1_CD_IRQ 17 +#define VPAC270_PCMCIA1_CD_IRQ IRQ_GPIO(GPIO_PCMCIA1_CD_IRQ) +#define VPAC270_PCMCIA_CD_EDGE IRQT_BOTHEDGE +#define GPIO_PCMCIA0_RDY_IRQ 35 +#define VPAC270_PCMCIA0_RDY_IRQ IRQ_GPIO(GPIO_PCMCIA0_RDY_IRQ) +#define GPIO_PCMCIA1_RDY_IRQ 12 +#define VPAC270_PCMCIA1_RDY_IRQ IRQ_GPIO(GPIO_PCMCIA1_RDY_IRQ) +#define VPAC270_PCMCIA_RDY_EDGE IRQT_FALLING +#define GPIO_PCMCIA_POW_EN 107 +#define GPIO_PCMCIA_NPOE 48 +#define GPIO_PCMCIA_NPOE_AF GPIO_ALT_FN_2_OUT +#define GPIO_PCMCIA_NPIOR 50 +#define GPIO_PCMCIA_NPIOR_AF GPIO_ALT_FN_2_OUT +#define GPIO_PCMCIA_NPIOW 51 +#define GPIO_PCMCIA_NPIOW_AF GPIO_ALT_FN_2_OUT +#define GPIO_PCMCIA_NPCE1 85 +#define GPIO_PCMCIA_NPCE1_AF GPIO_ALT_FN_1_OUT +#define GPIO_PCMCIA_NPCE2 54 +#define GPIO_PCMCIA_NPCE2_AF GPIO_ALT_FN_2_OUT +#define GPIO_PCMCIA_NPREG 55 +#define GPIO_PCMCIA_NPREG_AF GPIO_ALT_FN_2_OUT +#define GPIO_PCMCIA_NPWAIT 56 +#define GPIO_PCMCIA_NPWAIT_AF GPIO_ALT_FN_1_IN +#define GPIO_PCMCIA_NPIOIS16 57 +#define GPIO_PCMCIA_NPIOIS16_AF GPIO_ALT_FN_1_IN +#define GPIO_PCMCIA_PSKTSEL 104 +#define GPIO_PCMCIA_PSKTSEL_AF GPIO_ALT_FN_1_OUT +#define GPIO_PCMCIA0_RESET 11 +#define GPIO_PCMCIA1_RESET 16 +//#define GPIO_PCMCIA0_BVD1 83 +//#define GPIO_PCMCIA0_BVD2 82 + +#define PCC0_DETECT (GPLR(GPIO_PCMCIA0_CD_IRQ) & GPIO_bit(GPIO_PCMCIA0_CD_IRQ)) +#define PCC0_READY (GPLR(GPIO_PCMCIA0_RDY_IRQ) & GPIO_bit(GPIO_PCMCIA0_RDY_IRQ)) +#define PCC1_DETECT (GPLR(GPIO_PCMCIA1_CD_IRQ) & GPIO_bit(GPIO_PCMCIA1_CD_IRQ)) +#define PCC1_READY (GPLR(GPIO_PCMCIA1_RDY_IRQ) & GPIO_bit(GPIO_PCMCIA1_RDY_IRQ)) +#define PCC_BVD1() (GPLR(GPIO_PCMCIA0_BVD1) & GPIO_bit(GPIO_PCMCIA0_BVD1)) +#define PCC_BVD2() (GPLR(GPIO_PCMCIA0_BVD2) & GPIO_bit(GPIO_PCMCIA0_BVD2)) +#define PCC_VS3V() 1 /* only 3.3V supported */ +#define PCC_VS5V() 0 /* only 3.3V supported */ +#define PCC_PWR_ON() (GPCR(GPIO_PCMCIA_POW_EN) |= GPIO_bit(GPIO_PCMCIA_POW_EN)) +#define PCC_PWR_OFF() (GPSR(GPIO_PCMCIA_POW_EN) |= GPIO_bit(GPIO_PCMCIA_POW_EN)) + +/* MMC/SD */ +#define GPIO_MMC_CD_IRQ 53 +#define VPAC270_MMC_CD_IRQ IRQ_GPIO(GPIO_MMC_CD_IRQ) +#define GPIO_MMCCLK_AF GPIO32_MMCCLK_MD +#define GPIO_MMCDAT0_AF GPIO92_MMCDAT0 +#define GPIO_MMCDAT1_AF GPIO109_MMCDAT1 +#define GPIO_MMCDAT2_AF GPIO110_MMCDAT2 +#define GPIO_MMCDAT3_AF GPIO111_MMCDAT3 +#define GPIO_MMCCMD_AF GPIO112_MMCCMD_MD +#define GPIO_MMCCS0_AF GPIO110_MMCCS0_MD + +/* TouchScreen and Sound */ +#define GPIO_TOUCH_IRQ 113 +#define VPAC270_TOUCH_IRQ IRQ_GPIO(GPIO_TOUCH_IRQ) + +#define GPIO_AC97_RESET 95 +#define GPIO_AC97_RST_AF GPIO_ALT_FN_1_OUT +#define GPIO_AC97_SYSCLK 98 +#define GPIO_AC97_SYSCLK_AF GPIO_ALT_FN_1_OUT diff -urN linux-2.6.19/include/linux/fs.h linux-2.6.19-vpac1/include/linux/fs.h --- linux-2.6.19/include/linux/fs.h 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/include/linux/fs.h 2007-01-03 12:26:50.000000000 +0100 @@ -728,7 +728,7 @@ } f_u; struct dentry *f_dentry; struct vfsmount *f_vfsmnt; - const struct file_operations *f_op; + struct file_operations *f_op; atomic_t f_count; unsigned int f_flags; mode_t f_mode; diff -urN linux-2.6.19/sound/arm/pxa2xx-ac97.c linux-2.6.19-vpac1/sound/arm/pxa2xx-ac97.c --- linux-2.6.19/sound/arm/pxa2xx-ac97.c 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/sound/arm/pxa2xx-ac97.c 2007-01-03 12:26:50.000000000 +0100 @@ -133,10 +133,12 @@ #ifdef CONFIG_PXA27x /* warm reset broken on Bulverde, so manually keep AC97 reset high */ - pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); +// pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); + pxa_gpio_mode( 95 | GPIO_OUT | GPIO_DFLT_HIGH); udelay(10); GCR |= GCR_WARM_RST; - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); +// pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); + pxa_gpio_mode(GPIO_AC97_RESET | GPIO_AC97_RST_AF); udelay(500); #else GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN; @@ -148,6 +150,9 @@ __FUNCTION__, gsr_bits); } + pxa2xx_ac97_write(ac97, 0x6a, 0x0050); + pxa2xx_ac97_write(ac97, 0x6c, 0x0030); + GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); GCR |= GCR_SDONE_IE|GCR_CDONE_IE; } @@ -335,7 +340,9 @@ pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); #ifdef CONFIG_PXA27x /* Use GPIO 113 as AC97 Reset on Bulverde */ - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); +// pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); + pxa_gpio_mode(GPIO_AC97_RESET | GPIO_AC97_RST_AF); + pxa_gpio_mode(GPIO_AC97_SYSCLK | GPIO_AC97_SYSCLK_AF); #endif pxa_set_cken(CKEN2_AC97, 1); diff -urN linux-2.6.19/sound/oss/Kconfig linux-2.6.19-vpac1/sound/oss/Kconfig --- linux-2.6.19/sound/oss/Kconfig 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/sound/oss/Kconfig 2007-01-03 12:26:50.000000000 +0100 @@ -19,6 +19,10 @@ If unsure, say N. +config SOUND_PXA_AC97 + tristate "Intel PXA2xx AC97 audio" + depends on SOUND_PRIME && ARCH_PXA && SOUND + config SOUND_BT878 tristate "BT878 audio dma" depends on SOUND_PRIME && PCI diff -urN linux-2.6.19/sound/oss/Makefile linux-2.6.19-vpac1/sound/oss/Makefile --- linux-2.6.19/sound/oss/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/sound/oss/Makefile 2007-01-03 12:26:50.000000000 +0100 @@ -7,6 +7,7 @@ obj-$(CONFIG_SOUND_OSS) += sound.o obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o +obj-$(CONFIG_SOUND_PXA_AC97) += pxa-ac97.o pxa-audio.o ac97_codec.o # Please leave it as is, cause the link order is significant ! diff -urN linux-2.6.19/sound/oss/ac97_codec.c linux-2.6.19-vpac1/sound/oss/ac97_codec.c --- linux-2.6.19/sound/oss/ac97_codec.c 2006-11-29 22:57:37.000000000 +0100 +++ linux-2.6.19-vpac1/sound/oss/ac97_codec.c 2007-01-03 12:26:50.000000000 +0100 @@ -162,6 +162,7 @@ {0x45838308, "ESS Allegro ES1988", &null_ops}, {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */ {0x4e534331, "National Semiconductor LM4549", &null_ops}, + {0x50534304, "Philips UCB1400", &default_ops}, {0x53494c22, "Silicon Laboratory Si3036", &null_ops}, {0x53494c23, "Silicon Laboratory Si3038", &null_ops}, {0x545200FF, "TriTech TR?????", &tritech_m_ops}, diff -urN linux-2.6.19/sound/oss/pxa-ac97.c linux-2.6.19-vpac1/sound/oss/pxa-ac97.c --- linux-2.6.19/sound/oss/pxa-ac97.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/sound/oss/pxa-ac97.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,363 @@ +/* + * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip + * + * Author: Nicolas Pitre + * Created: Aug 15, 2001 + * Copyright: MontaVista Software Inc. + * + * Forward ported to 2.6 by Ian Molton 15/09/2003 + * + * 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 +#include +#include +#include +#include + +#include "pxa-audio.h" + +static struct completion CAR_completion; +static int waitingForMask; +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 = (u32 *)&PAC_REG_BASE + (reg >> 1); + + waitingForMask=GSR_SDONE; + + init_completion(&CAR_completion); + (void)*reg_addr; //start read access across the ac97 link + wait_for_completion(&CAR_completion); + + if (GSR & GSR_RDCS) { + GSR = GSR_RDCS; //write a 1 to clear + printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__); + } + + init_completion(&CAR_completion); + val = *reg_addr; //valid data now but we've just started another cycle... + 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); + 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 = (u32 *)&PAC_REG_BASE + (reg >> 1); + + waitingForMask=GSR_CDONE; + 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) +{ + int gsr = GSR; + GSR = gsr & (GSR_SDONE|GSR_CDONE); //write a 1 to clear + if (gsr & waitingForMask) + 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; + +/* + * 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. + * But since UCB1400 is not the only audio CODEC out there, + * this is still enabled by default. + */ +static void update_audio_in (void) +{ +#if 1 + long val; + + /* Use the value stuffed by ac97_recmask_io() + * into recording select register + */ + val = pxa_ac97_codec.codec_read(&pxa_ac97_codec, AC97_RECORD_SELECT); + pxa_audio_clear_buf(&ac97_audio_in); + *ac97_audio_in.drcmr = 0; + if (val == 0) { + 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 +} + +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: + update_audio_in (); + 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: + ret = get_user(val, (int *) arg); + if (ret) + return ret; + /* FIXME: do we support mono? */ + ret = (val == 0) ? -EINVAL : 1; + return put_user(ret, (int *) arg); + + case SNDCTL_DSP_CHANNELS: + case SOUND_PCM_READ_CHANNELS: + /* FIXME: do we support mono? */ + 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: + /* FIXME: can we do other fmts? */ + 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: __SEMAPHORE_INIT(ac97_audio_state.sem,1), +}; + +static int ac97_audio_open(struct inode *inode, struct file *file) +{ + return pxa_audio_attach(inode, file, &ac97_audio_state); +} + +/* + * 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 __init pxa_ac97_init(void) +{ + int ret; + struct ac97_codec *dummy; + + ret = pxa_ac97_get(&dummy); + if (ret) + return ret; + + update_audio_in (); + + 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 void __exit pxa_ac97_exit(void) +{ + unregister_sound_dsp(ac97_audio_state.dev_dsp); + unregister_sound_mixer(pxa_ac97_codec.dev_mixer); + pxa_ac97_put(); +} + + +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.19/sound/oss/pxa-audio.c linux-2.6.19-vpac1/sound/oss/pxa-audio.c --- linux-2.6.19/sound/oss/pxa-audio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/sound/oss/pxa-audio.c 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,856 @@ +/* + * 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 + +#include "pxa-audio.h" +#define io_remap_page_range(vma, vaddr, paddr, size, prot) \ + remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + + +#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; + 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); + + /* 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; + + 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); + + 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); + 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) +{ + 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 (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 (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 = io_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.19/sound/oss/pxa-audio.h linux-2.6.19-vpac1/sound/oss/pxa-audio.h --- linux-2.6.19/sound/oss/pxa-audio.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.19-vpac1/sound/oss/pxa-audio.h 2007-01-03 12:26:50.000000000 +0100 @@ -0,0 +1,54 @@ +/* + * 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);