Merge branch 'pxa-palm' into pxa-machines

Conflicts:

	drivers/mfd/Kconfig
	drivers/pcmcia/Makefile
This commit is contained in:
Russell King 2008-10-07 19:07:22 +01:00 committed by Russell King
commit 1543966a07
20 changed files with 2464 additions and 513 deletions

View file

@ -623,6 +623,12 @@ M: marek.vasut@gmail.com
W: http://hackndev.com
S: Maintained
ARM/PALMZ72 SUPPORT
P: Sergey Lapin
M: slapin@ossfans.org
W: http://hackndev.com
S: Maintained
ARM/PLEB SUPPORT
P: Peter Chubb
M: pleb@gelato.unsw.edu.au

View file

@ -0,0 +1,951 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.27-rc4
# Sun Aug 24 02:29:27 2008
#
CONFIG_ARM=y
CONFIG_HAVE_PWM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_ZONE_DMA=y
CONFIG_ARCH_MTD_XIP=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
# CONFIG_HAVE_IOREMAP_PROT is not set
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
# CONFIG_HAVE_ARCH_TRACEHOOK is not set
# CONFIG_HAVE_DMA_ATTRS is not set
# CONFIG_USE_GENERIC_SMP_HELPERS is not set
CONFIG_HAVE_CLK=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_CLASSIC_RCU=y
#
# 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_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_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
# CONFIG_ARCH_KIRKWOOD is not set
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_ORION5X 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_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_MSM7X00A is not set
#
# Intel PXA2xx/PXA3xx Implementations
#
# CONFIG_ARCH_GUMSTIX is not set
# 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_ARCH_PXA_ESERIES is not set
# CONFIG_MACH_TRIZEPS4 is not set
# CONFIG_MACH_EM_X270 is not set
# CONFIG_MACH_COLIBRI is not set
# CONFIG_MACH_ZYLONITE is not set
# CONFIG_MACH_LITTLETON is not set
# CONFIG_MACH_TAVOREVB is not set
# CONFIG_MACH_SAAR is not set
# CONFIG_MACH_ARMCORE is not set
# CONFIG_MACH_MAGICIAN is not set
# CONFIG_MACH_PCM027 is not set
CONFIG_ARCH_PXA_PALM=y
# CONFIG_MACH_PALMTX is not set
CONFIG_MACH_PALMZ72=y
# CONFIG_PXA_EZX is not set
CONFIG_PXA27x=y
CONFIG_PXA_PWM=y
#
# Boot options
#
#
# Power management
#
#
# Processor Type
#
CONFIG_CPU_32=y
CONFIG_CPU_XSCALE=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_PABRT_NOIFAR=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=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_OUTER_CACHE is not set
CONFIG_IWMMXT=y
CONFIG_XSCALE_PMU=y
#
# Bus support
#
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
#
# Kernel Features
#
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
# 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_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_ALIGNMENT_TRAP=y
#
# Boot options
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="mem=32M console=tty root=/dev/mmcblk0"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
#
# 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
#
# Power management options
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_APM_EMULATION=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP 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=y
# CONFIG_IP_PNP_DHCP is not set
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_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_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# 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
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
#
# Wireless
#
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MISC_DEVICES is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_NETDEVICES is not set
# CONFIG_ISDN is not set
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ATKBD is not set
# 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_KEYBOARD_PXA27x=y
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_PXA is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
#
# I2C Hardware Bus support
#
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
CONFIG_I2C_PXA=y
# CONFIG_I2C_PXA_SLAVE is not set
# CONFIG_I2C_SIMTEC is not set
#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
# CONFIG_AT24 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 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
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
#
# SPI Master Controller Drivers
#
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_PXA2XX is not set
#
# SPI Protocol Masters
#
# CONFIG_SPI_AT25 is not set
CONFIG_SPI_SPIDEV=y
# CONFIG_SPI_TLE62X0 is not set
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
#
# I2C GPIO expanders:
#
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
#
# PCI GPIO expanders:
#
#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
# CONFIG_W1 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PDA_POWER=y
# CONFIG_APM_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_HWMON is not set
# CONFIG_WATCHDOG is not set
#
# Sonics Silicon Backplane
#
CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
#
# Multimedia devices
#
#
# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_VIDEO_MEDIA is not set
#
# Multimedia drivers
#
# CONFIG_DAB is not set
#
# Graphics support
#
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_FOREIGN_ENDIAN is not set
# CONFIG_FB_SYS_FOPS is not set
# CONFIG_FB_SVGALIB is not set
# 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
#
# Frame buffer hardware drivers
#
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_PXA=y
# CONFIG_FB_PXA_SMARTPANEL is not set
# CONFIG_FB_PXA_PARAMETERS is not set
# CONFIG_FB_MBX is not set
# CONFIG_FB_W100 is not set
# CONFIG_FB_AM200EPD is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_CORGI is not set
CONFIG_BACKLIGHT_PWM=y
#
# Display device support
#
CONFIG_DISPLAY_SUPPORT=y
#
# Display hardware drivers
#
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
# CONFIG_FONT_8x16 is not set
# 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
# CONFIG_LOGO is not set
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
CONFIG_MMC_DEBUG=y
# CONFIG_MMC_UNSAFE_RESUME is not set
#
# MMC/SD Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set
#
# MMC/SD Host Controller Drivers
#
CONFIG_MMC_PXA=y
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_SPI is not set
# CONFIG_NEW_LEDS is not set
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=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set
#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_SA1100=y
# CONFIG_DMADEVICES is not set
#
# Voltage and Current regulators
#
# CONFIG_REGULATOR is not set
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
# CONFIG_REGULATOR_BQ24022 is not set
# CONFIG_UIO is not set
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# 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_OCFS2_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA 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_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=866
CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# 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_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
CONFIG_NLS_CODEPAGE_866=y
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
# CONFIG_DLM is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_FRAME_POINTER=y
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
# CONFIG_FTRACE is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_DEBUG_USER=y
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_GENERIC_FIND_FIRST_BIT is not set
# CONFIG_GENERIC_FIND_NEXT_BIT is not set
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC_T10DIF=y
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y

View file

@ -288,6 +288,16 @@ config MACH_PALMTX
Say Y here if you intend to run this kernel on a Palm T|X
handheld computer.
config MACH_PALMZ72
bool "Palm Zire 72"
default y
depends on ARCH_PXA_PALM
select PXA27x
select IWMMXT
help
Say Y here if you intend to run this kernel on Palm Zire 72
handheld computer.
config MACH_PCM990_BASEBOARD
bool "PHYTEC PCM-990 development board"
select HAVE_PWM

View file

@ -45,6 +45,7 @@ obj-$(CONFIG_MACH_E750) += e750_lcd.o
obj-$(CONFIG_MACH_E400) += e400_lcd.o
obj-$(CONFIG_MACH_E800) += e800_lcd.o
obj-$(CONFIG_MACH_PALMTX) += palmtx.o
obj-$(CONFIG_MACH_PALMZ72) += palmz72.o
ifeq ($(CONFIG_MACH_ZYLONITE),y)
obj-y += zylonite.o

View file

@ -0,0 +1,67 @@
/*
* GPIOs and interrupts for Palm Zire72 Handheld Computer
*
* Authors: Alex Osborne <bobofdoom@gmail.com>
* Jan Herman <2hp@seznam.cz>
* Sergey Lapin <slapin@ossfans.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef _INCLUDE_PALMZ72_H_
#define _INCLUDE_PALMZ72_H_
/* Power and control */
#define GPIO_NR_PALMZ72_GPIO_RESET 1
#define GPIO_NR_PALMZ72_POWER_DETECT 0
/* SD/MMC */
#define GPIO_NR_PALMZ72_SD_DETECT_N 14
#define GPIO_NR_PALMZ72_SD_POWER_N 98
#define GPIO_NR_PALMZ72_SD_RO 115
/* Touchscreen */
#define GPIO_NR_PALMZ72_WM9712_IRQ 27
/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
#define GPIO_NR_PALMZ72_IR_DISABLE 49
/* USB */
#define GPIO_NR_PALMZ72_USB_DETECT_N 15
#define GPIO_NR_PALMZ72_USB_POWER 95
#define GPIO_NR_PALMZ72_USB_PULLUP 12
/* LCD/Backlight */
#define GPIO_NR_PALMZ72_BL_POWER 20
#define GPIO_NR_PALMZ72_LCD_POWER 96
/* LED */
#define GPIO_NR_PALMZ72_LED_GREEN 88
/* Bluetooth */
#define GPIO_NR_PALMZ72_BT_POWER 17
#define GPIO_NR_PALMZ72_BT_RESET 83
/** Initial values **/
/* Battery */
#define PALMZ72_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
#define PALMZ72_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
#define PALMZ72_BAT_MAX_CURRENT 0 /* unknokn */
#define PALMZ72_BAT_MIN_CURRENT 0 /* unknown */
#define PALMZ72_BAT_MAX_CHARGE 1 /* unknown */
#define PALMZ72_BAT_MIN_CHARGE 1 /* unknown */
#define PALMZ72_MAX_LIFE_MINS 360 /* on-life in minutes */
/* Backlight */
#define PALMZ72_MAX_INTENSITY 0xFE
#define PALMZ72_DEFAULT_INTENSITY 0x7E
#define PALMZ72_LIMIT_MASK 0x7F
#define PALMZ72_PRESCALER 0x3F
#define PALMZ72_PERIOD_NS 3500
#endif

View file

@ -25,6 +25,8 @@
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -339,6 +341,23 @@ static struct platform_device power_supply = {
},
};
/******************************************************************************
* WM97xx battery
******************************************************************************/
static struct wm97xx_batt_info wm97xx_batt_pdata = {
.batt_aux = WM97XX_AUX_ID3,
.temp_aux = WM97XX_AUX_ID2,
.charge_gpio = -1,
.max_voltage = PALMTX_BAT_MAX_VOLTAGE,
.min_voltage = PALMTX_BAT_MIN_VOLTAGE,
.batt_mult = 1000,
.batt_div = 414,
.temp_mult = 1,
.temp_div = 1,
.batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
.batt_name = "main-batt",
};
/******************************************************************************
* Framebuffer
******************************************************************************/
@ -401,6 +420,7 @@ static void __init palmtx_init(void)
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&palmtx_ficp_platform_data);
pxa_set_keypad_info(&palmtx_keypad_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
platform_add_devices(devices, ARRAY_SIZE(devices));
}

480
arch/arm/mach-pxa/palmz72.c Normal file
View file

@ -0,0 +1,480 @@
/*
* Hardware definitions for Palm Zire72
*
* Authors:
* Vladimir "Farcaller" Pouzanov <farcaller@gmail.com>
* Sergey Lapin <slapin@ossfans.org>
* Alex Osborne <bobofdoom@gmail.com>
* Jan Herman <2hp@seznam.cz>
*
* Rewrite for mainline:
* Marek Vasut <marek.vasut@gmail.com>
*
* 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.
*
* (find more info at www.hackndev.com)
*
*/
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/power_supply.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/audio.h>
#include <mach/palmz72.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#include <mach/mfp-pxa27x.h>
#include <mach/irda.h>
#include <mach/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/pm.h>
#include "generic.h"
#include "devices.h"
/******************************************************************************
* Pin configuration
******************************************************************************/
static unsigned long palmz72_pin_config[] __initdata = {
/* MMC */
GPIO32_MMC_CLK,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
GPIO112_MMC_CMD,
GPIO14_GPIO, /* SD detect */
GPIO115_GPIO, /* SD RO */
GPIO98_GPIO, /* SD power */
/* AC97 */
GPIO28_AC97_BITCLK,
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
/* IrDA */
GPIO49_GPIO, /* ir disable */
GPIO46_FICP_RXD,
GPIO47_FICP_TXD,
/* PWM */
GPIO16_PWM0_OUT,
/* USB */
GPIO15_GPIO, /* usb detect */
GPIO12_GPIO, /* usb pullup */
GPIO95_GPIO, /* usb power */
/* Matrix keypad */
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
/* LCD */
GPIO58_LCD_LDD_0,
GPIO59_LCD_LDD_1,
GPIO60_LCD_LDD_2,
GPIO61_LCD_LDD_3,
GPIO62_LCD_LDD_4,
GPIO63_LCD_LDD_5,
GPIO64_LCD_LDD_6,
GPIO65_LCD_LDD_7,
GPIO66_LCD_LDD_8,
GPIO67_LCD_LDD_9,
GPIO68_LCD_LDD_10,
GPIO69_LCD_LDD_11,
GPIO70_LCD_LDD_12,
GPIO71_LCD_LDD_13,
GPIO72_LCD_LDD_14,
GPIO73_LCD_LDD_15,
GPIO74_LCD_FCLK,
GPIO75_LCD_LCLK,
GPIO76_LCD_PCLK,
GPIO77_LCD_BIAS,
GPIO20_GPIO, /* bl power */
GPIO21_GPIO, /* LCD border switch */
GPIO22_GPIO, /* LCD border color */
GPIO96_GPIO, /* lcd power */
/* Misc. */
GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */
GPIO88_GPIO, /* green led */
GPIO27_GPIO, /* WM9712 IRQ */
};
/******************************************************************************
* SD/MMC card controller
******************************************************************************/
static int palmz72_mci_init(struct device *dev,
irq_handler_t palmz72_detect_int, void *data)
{
int err = 0;
/* Setup an interrupt for detecting card insert/remove events */
err = gpio_request(GPIO_NR_PALMZ72_SD_DETECT_N, "SD IRQ");
if (err)
goto err;
err = gpio_direction_input(GPIO_NR_PALMZ72_SD_DETECT_N);
if (err)
goto err2;
err = request_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N),
palmz72_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
"SD/MMC card detect", data);
if (err) {
printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
__func__);
goto err2;
}
/* SD_POWER is not actually power, but it is more like chip
* select, i.e. it is inverted */
err = gpio_request(GPIO_NR_PALMZ72_SD_POWER_N, "SD_POWER");
if (err)
goto err3;
err = gpio_direction_output(GPIO_NR_PALMZ72_SD_POWER_N, 0);
if (err)
goto err4;
err = gpio_request(GPIO_NR_PALMZ72_SD_RO, "SD_RO");
if (err)
goto err4;
err = gpio_direction_input(GPIO_NR_PALMZ72_SD_RO);
if (err)
goto err5;
printk(KERN_DEBUG "%s: irq registered\n", __func__);
return 0;
err5:
gpio_free(GPIO_NR_PALMZ72_SD_RO);
err4:
gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
err3:
free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
err2:
gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
err:
return err;
}
static void palmz72_mci_exit(struct device *dev, void *data)
{
gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
gpio_free(GPIO_NR_PALMZ72_SD_RO);
}
static void palmz72_mci_power(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data *p_d = dev->platform_data;
if (p_d->ocr_mask & (1 << vdd))
gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 0);
else
gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 1);
}
static int palmz72_mci_ro(struct device *dev)
{
return gpio_get_value(GPIO_NR_PALMZ72_SD_RO);
}
static struct pxamci_platform_data palmz72_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.setpower = palmz72_mci_power,
.get_ro = palmz72_mci_ro,
.init = palmz72_mci_init,
.exit = palmz72_mci_exit,
};
/******************************************************************************
* GPIO keyboard
******************************************************************************/
static unsigned int palmz72_matrix_keys[] = {
KEY(0, 0, KEY_POWER),
KEY(0, 1, KEY_F1),
KEY(0, 2, KEY_ENTER),
KEY(1, 0, KEY_F2),
KEY(1, 1, KEY_F3),
KEY(1, 2, KEY_F4),
KEY(2, 0, KEY_UP),
KEY(2, 2, KEY_DOWN),
KEY(3, 0, KEY_RIGHT),
KEY(3, 2, KEY_LEFT),
};
static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
.matrix_key_rows = 4,
.matrix_key_cols = 3,
.matrix_key_map = palmz72_matrix_keys,
.matrix_key_map_size = ARRAY_SIZE(palmz72_matrix_keys),
.debounce_interval = 30,
};
/******************************************************************************
* Backlight
******************************************************************************/
static int palmz72_backlight_init(struct device *dev)
{
int ret;
ret = gpio_request(GPIO_NR_PALMZ72_BL_POWER, "BL POWER");
if (ret)
goto err;
ret = gpio_direction_output(GPIO_NR_PALMZ72_BL_POWER, 0);
if (ret)
goto err2;
ret = gpio_request(GPIO_NR_PALMZ72_LCD_POWER, "LCD POWER");
if (ret)
goto err2;
ret = gpio_direction_output(GPIO_NR_PALMZ72_LCD_POWER, 0);
if (ret)
goto err3;
return 0;
err3:
gpio_free(GPIO_NR_PALMZ72_LCD_POWER);
err2:
gpio_free(GPIO_NR_PALMZ72_BL_POWER);
err:
return ret;
}
static int palmz72_backlight_notify(int brightness)
{
gpio_set_value(GPIO_NR_PALMZ72_BL_POWER, brightness);
gpio_set_value(GPIO_NR_PALMZ72_LCD_POWER, brightness);
return brightness;
}
static void palmz72_backlight_exit(struct device *dev)
{
gpio_free(GPIO_NR_PALMZ72_BL_POWER);
gpio_free(GPIO_NR_PALMZ72_LCD_POWER);
}
static struct platform_pwm_backlight_data palmz72_backlight_data = {
.pwm_id = 0,
.max_brightness = PALMZ72_MAX_INTENSITY,
.dft_brightness = PALMZ72_MAX_INTENSITY,
.pwm_period_ns = PALMZ72_PERIOD_NS,
.init = palmz72_backlight_init,
.notify = palmz72_backlight_notify,
.exit = palmz72_backlight_exit,
};
static struct platform_device palmz72_backlight = {
.name = "pwm-backlight",
.dev = {
.parent = &pxa27x_device_pwm0.dev,
.platform_data = &palmz72_backlight_data,
},
};
/******************************************************************************
* IrDA
******************************************************************************/
static int palmz72_irda_startup(struct device *dev)
{
int err;
err = gpio_request(GPIO_NR_PALMZ72_IR_DISABLE, "IR DISABLE");
if (err)
goto err;
err = gpio_direction_output(GPIO_NR_PALMZ72_IR_DISABLE, 1);
if (err)
gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
err:
return err;
}
static void palmz72_irda_shutdown(struct device *dev)
{
gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
}
static void palmz72_irda_transceiver_mode(struct device *dev, int mode)
{
gpio_set_value(GPIO_NR_PALMZ72_IR_DISABLE, mode & IR_OFF);
pxa2xx_transceiver_mode(dev, mode);
}
static struct pxaficp_platform_data palmz72_ficp_platform_data = {
.startup = palmz72_irda_startup,
.shutdown = palmz72_irda_shutdown,
.transceiver_cap = IR_SIRMODE | IR_OFF,
.transceiver_mode = palmz72_irda_transceiver_mode,
};
/******************************************************************************
* LEDs
******************************************************************************/
static struct gpio_led gpio_leds[] = {
{
.name = "palmz72:green:led",
.default_trigger = "none",
.gpio = GPIO_NR_PALMZ72_LED_GREEN,
},
};
static struct gpio_led_platform_data gpio_led_info = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
static struct platform_device palmz72_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &gpio_led_info,
}
};
/******************************************************************************
* Power supply
******************************************************************************/
static int power_supply_init(struct device *dev)
{
int ret;
ret = gpio_request(GPIO_NR_PALMZ72_POWER_DETECT, "CABLE_STATE_AC");
if (ret)
goto err1;
ret = gpio_direction_input(GPIO_NR_PALMZ72_POWER_DETECT);
if (ret)
goto err2;
ret = gpio_request(GPIO_NR_PALMZ72_USB_DETECT_N, "CABLE_STATE_USB");
if (ret)
goto err2;
ret = gpio_direction_input(GPIO_NR_PALMZ72_USB_DETECT_N);
if (ret)
goto err3;
return 0;
err3:
gpio_free(GPIO_NR_PALMZ72_USB_DETECT_N);
err2:
gpio_free(GPIO_NR_PALMZ72_POWER_DETECT);
err1:
return ret;
}
static int palmz72_is_ac_online(void)
{
return gpio_get_value(GPIO_NR_PALMZ72_POWER_DETECT);
}
static int palmz72_is_usb_online(void)
{
return !gpio_get_value(GPIO_NR_PALMZ72_USB_DETECT_N);
}
static void power_supply_exit(struct device *dev)
{
gpio_free(GPIO_NR_PALMZ72_USB_DETECT_N);
gpio_free(GPIO_NR_PALMZ72_POWER_DETECT);
}
static char *palmz72_supplicants[] = {
"main-battery",
};
static struct pda_power_pdata power_supply_info = {
.init = power_supply_init,
.is_ac_online = palmz72_is_ac_online,
.is_usb_online = palmz72_is_usb_online,
.exit = power_supply_exit,
.supplied_to = palmz72_supplicants,
.num_supplicants = ARRAY_SIZE(palmz72_supplicants),
};
static struct platform_device power_supply = {
.name = "pda-power",
.id = -1,
.dev = {
.platform_data = &power_supply_info,
},
};
/******************************************************************************
* Framebuffer
******************************************************************************/
static struct pxafb_mode_info palmz72_lcd_modes[] = {
{
.pixclock = 115384,
.xres = 320,
.yres = 320,
.bpp = 16,
.left_margin = 27,
.right_margin = 7,
.upper_margin = 7,
.lower_margin = 8,
.hsync_len = 6,
.vsync_len = 1,
},
};
static struct pxafb_mach_info palmz72_lcd_screen = {
.modes = palmz72_lcd_modes,
.num_modes = ARRAY_SIZE(palmz72_lcd_modes),
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};
/******************************************************************************
* Machine init
******************************************************************************/
static struct platform_device *devices[] __initdata = {
&palmz72_backlight,
&palmz72_leds,
&power_supply,
};
static void __init palmz72_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
set_pxa_fb_info(&palmz72_lcd_screen);
pxa_set_mci_info(&palmz72_mci_platform_data);
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&palmz72_ficp_platform_data);
pxa_set_keypad_info(&palmz72_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
MACHINE_START(PALMZ72, "Palm Zire72")
.phys_io = 0x40000000,
.io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = palmz72_init
MACHINE_END

View file

@ -220,6 +220,7 @@ config TOUCHSCREEN_ATMEL_TSADCC
config TOUCHSCREEN_UCB1400
tristate "Philips UCB1400 touchscreen"
select AC97_BUS
depends on UCB1400_CORE
help
This enables support for the Philips UCB1400 touchscreen interface.
The UCB1400 is an AC97 audio codec. The touchscreen interface

View file

@ -5,6 +5,10 @@
* Created: September 25, 2006
* Copyright: MontaVista Software, Inc.
*
* Spliting done by: Marek Vasut <marek.vasut@gmail.com>
* If something doesnt work and it worked before spliting, e-mail me,
* dont bother Nicolas please ;-)
*
* 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.
@ -25,124 +29,16 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <sound/core.h>
#include <sound/ac97_codec.h>
/*
* Interesting UCB1400 AC-link registers
*/
#define UCB_IE_RIS 0x5e
#define UCB_IE_FAL 0x60
#define UCB_IE_STATUS 0x62
#define UCB_IE_CLEAR 0x62
#define UCB_IE_ADC (1 << 11)
#define UCB_IE_TSPX (1 << 12)
#define UCB_TS_CR 0x64
#define UCB_TS_CR_TSMX_POW (1 << 0)
#define UCB_TS_CR_TSPX_POW (1 << 1)
#define UCB_TS_CR_TSMY_POW (1 << 2)
#define UCB_TS_CR_TSPY_POW (1 << 3)
#define UCB_TS_CR_TSMX_GND (1 << 4)
#define UCB_TS_CR_TSPX_GND (1 << 5)
#define UCB_TS_CR_TSMY_GND (1 << 6)
#define UCB_TS_CR_TSPY_GND (1 << 7)
#define UCB_TS_CR_MODE_INT (0 << 8)
#define UCB_TS_CR_MODE_PRES (1 << 8)
#define UCB_TS_CR_MODE_POS (2 << 8)
#define UCB_TS_CR_BIAS_ENA (1 << 11)
#define UCB_TS_CR_TSPX_LOW (1 << 12)
#define UCB_TS_CR_TSMX_LOW (1 << 13)
#define UCB_ADC_CR 0x66
#define UCB_ADC_SYNC_ENA (1 << 0)
#define UCB_ADC_VREFBYP_CON (1 << 1)
#define UCB_ADC_INP_TSPX (0 << 2)
#define UCB_ADC_INP_TSMX (1 << 2)
#define UCB_ADC_INP_TSPY (2 << 2)
#define UCB_ADC_INP_TSMY (3 << 2)
#define UCB_ADC_INP_AD0 (4 << 2)
#define UCB_ADC_INP_AD1 (5 << 2)
#define UCB_ADC_INP_AD2 (6 << 2)
#define UCB_ADC_INP_AD3 (7 << 2)
#define UCB_ADC_EXT_REF (1 << 5)
#define UCB_ADC_START (1 << 7)
#define UCB_ADC_ENA (1 << 15)
#define UCB_ADC_DATA 0x68
#define UCB_ADC_DAT_VALID (1 << 15)
#define UCB_ADC_DAT_VALUE(x) ((x) & 0x3ff)
#define UCB_ID 0x7e
#define UCB_ID_1400 0x4304
struct ucb1400 {
struct snd_ac97 *ac97;
struct input_dev *ts_idev;
int irq;
wait_queue_head_t ts_wait;
struct task_struct *ts_task;
unsigned int irq_pending; /* not bit field shared */
unsigned int ts_restart:1;
unsigned int adcsync:1;
};
#include <linux/ucb1400.h>
static int adcsync;
static int ts_delay = 55; /* us */
static int ts_delay_pressure; /* us */
static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg)
{
return ucb->ac97->bus->ops->read(ucb->ac97, reg);
}
static inline void ucb1400_reg_write(struct ucb1400 *ucb, u16 reg, u16 val)
{
ucb->ac97->bus->ops->write(ucb->ac97, reg, val);
}
static inline void ucb1400_adc_enable(struct ucb1400 *ucb)
{
ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
}
static unsigned int ucb1400_adc_read(struct ucb1400 *ucb, u16 adc_channel)
{
unsigned int val;
if (ucb->adcsync)
adc_channel |= UCB_ADC_SYNC_ENA;
ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel);
ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | UCB_ADC_START);
for (;;) {
val = ucb1400_reg_read(ucb, UCB_ADC_DATA);
if (val & UCB_ADC_DAT_VALID)
break;
/* yield to other processes */
schedule_timeout_uninterruptible(1);
}
return UCB_ADC_DAT_VALUE(val);
}
static inline void ucb1400_adc_disable(struct ucb1400 *ucb)
{
ucb1400_reg_write(ucb, UCB_ADC_CR, 0);
}
/* Switch to interrupt mode. */
static inline void ucb1400_ts_mode_int(struct ucb1400 *ucb)
static inline void ucb1400_ts_mode_int(struct snd_ac97 *ac97)
{
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ac97, UCB_TS_CR,
UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
UCB_TS_CR_MODE_INT);
@ -152,14 +48,14 @@ static inline void ucb1400_ts_mode_int(struct ucb1400 *ucb)
* Switch to pressure mode, and read pressure. We don't need to wait
* here, since both plates are being driven.
*/
static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb)
static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400_ts *ucb)
{
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
udelay(ts_delay_pressure);
return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY);
return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPY, adcsync);
}
/*
@ -168,21 +64,21 @@ static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb)
* gives a faster response time. Even so, we need to wait about 55us
* for things to stabilise.
*/
static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb)
static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400_ts *ucb)
{
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
udelay(ts_delay);
return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY);
return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPY, adcsync);
}
/*
@ -191,63 +87,63 @@ static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb)
* gives a faster response time. Even so, we need to wait about 55us
* for things to stabilise.
*/
static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb)
static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400_ts *ucb)
{
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
udelay(ts_delay);
return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX);
return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPX, adcsync);
}
/*
* Switch to X plate resistance mode. Set MX to ground, PX to
* supply. Measure current.
*/
static inline unsigned int ucb1400_ts_read_xres(struct ucb1400 *ucb)
static inline unsigned int ucb1400_ts_read_xres(struct ucb1400_ts *ucb)
{
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
return ucb1400_adc_read(ucb, 0);
return ucb1400_adc_read(ucb->ac97, 0, adcsync);
}
/*
* Switch to Y plate resistance mode. Set MY to ground, PY to
* supply. Measure current.
*/
static inline unsigned int ucb1400_ts_read_yres(struct ucb1400 *ucb)
static inline unsigned int ucb1400_ts_read_yres(struct ucb1400_ts *ucb)
{
ucb1400_reg_write(ucb, UCB_TS_CR,
ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
return ucb1400_adc_read(ucb, 0);
return ucb1400_adc_read(ucb->ac97, 0, adcsync);
}
static inline int ucb1400_ts_pen_down(struct ucb1400 *ucb)
static inline int ucb1400_ts_pen_down(struct snd_ac97 *ac97)
{
unsigned short val = ucb1400_reg_read(ucb, UCB_TS_CR);
return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
unsigned short val = ucb1400_reg_read(ac97, UCB_TS_CR);
return val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW);
}
static inline void ucb1400_ts_irq_enable(struct ucb1400 *ucb)
static inline void ucb1400_ts_irq_enable(struct snd_ac97 *ac97)
{
ucb1400_reg_write(ucb, UCB_IE_CLEAR, UCB_IE_TSPX);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_TSPX);
ucb1400_reg_write(ac97, UCB_IE_CLEAR, UCB_IE_TSPX);
ucb1400_reg_write(ac97, UCB_IE_CLEAR, 0);
ucb1400_reg_write(ac97, UCB_IE_FAL, UCB_IE_TSPX);
}
static inline void ucb1400_ts_irq_disable(struct ucb1400 *ucb)
static inline void ucb1400_ts_irq_disable(struct snd_ac97 *ac97)
{
ucb1400_reg_write(ucb, UCB_IE_FAL, 0);
ucb1400_reg_write(ac97, UCB_IE_FAL, 0);
}
static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16 y)
@ -264,25 +160,24 @@ static void ucb1400_ts_event_release(struct input_dev *idev)
input_sync(idev);
}
static void ucb1400_handle_pending_irq(struct ucb1400 *ucb)
static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb)
{
unsigned int isr;
isr = ucb1400_reg_read(ucb, UCB_IE_STATUS);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, isr);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
isr = ucb1400_reg_read(ucb->ac97, UCB_IE_STATUS);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
if (isr & UCB_IE_TSPX)
ucb1400_ts_irq_disable(ucb);
else
if (isr & UCB_IE_TSPX) {
ucb1400_ts_irq_disable(ucb->ac97);
enable_irq(ucb->irq);
} else
printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
enable_irq(ucb->irq);
}
static int ucb1400_ts_thread(void *_ucb)
{
struct ucb1400 *ucb = _ucb;
struct ucb1400_ts *ucb = _ucb;
struct task_struct *tsk = current;
int valid = 0;
struct sched_param param = { .sched_priority = 1 };
@ -301,19 +196,19 @@ static int ucb1400_ts_thread(void *_ucb)
ucb1400_handle_pending_irq(ucb);
}
ucb1400_adc_enable(ucb);
ucb1400_adc_enable(ucb->ac97);
x = ucb1400_ts_read_xpos(ucb);
y = ucb1400_ts_read_ypos(ucb);
p = ucb1400_ts_read_pressure(ucb);
ucb1400_adc_disable(ucb);
ucb1400_adc_disable(ucb->ac97);
/* Switch back to interrupt mode. */
ucb1400_ts_mode_int(ucb);
ucb1400_ts_mode_int(ucb->ac97);
msleep(10);
if (ucb1400_ts_pen_down(ucb)) {
ucb1400_ts_irq_enable(ucb);
if (ucb1400_ts_pen_down(ucb->ac97)) {
ucb1400_ts_irq_enable(ucb->ac97);
/*
* If we spat out a valid sample set last time,
@ -332,8 +227,8 @@ static int ucb1400_ts_thread(void *_ucb)
}
wait_event_freezable_timeout(ucb->ts_wait,
ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
timeout);
ucb->irq_pending || ucb->ts_restart ||
kthread_should_stop(), timeout);
}
/* Send the "pen off" if we are stopping with the pen still active */
@ -356,7 +251,7 @@ static int ucb1400_ts_thread(void *_ucb)
*/
static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid)
{
struct ucb1400 *ucb = devid;
struct ucb1400_ts *ucb = devid;
if (irqnr == ucb->irq) {
disable_irq(ucb->irq);
@ -369,7 +264,7 @@ static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid)
static int ucb1400_ts_open(struct input_dev *idev)
{
struct ucb1400 *ucb = input_get_drvdata(idev);
struct ucb1400_ts *ucb = input_get_drvdata(idev);
int ret = 0;
BUG_ON(ucb->ts_task);
@ -385,19 +280,143 @@ static int ucb1400_ts_open(struct input_dev *idev)
static void ucb1400_ts_close(struct input_dev *idev)
{
struct ucb1400 *ucb = input_get_drvdata(idev);
struct ucb1400_ts *ucb = input_get_drvdata(idev);
if (ucb->ts_task)
kthread_stop(ucb->ts_task);
ucb1400_ts_irq_disable(ucb);
ucb1400_reg_write(ucb, UCB_TS_CR, 0);
ucb1400_ts_irq_disable(ucb->ac97);
ucb1400_reg_write(ucb->ac97, UCB_TS_CR, 0);
}
#ifndef NO_IRQ
#define NO_IRQ 0
#endif
/*
* Try to probe our interrupt, rather than relying on lots of
* hard-coded machine dependencies.
*/
static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
{
unsigned long mask, timeout;
mask = probe_irq_on();
/* Enable the ADC interrupt. */
ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, UCB_IE_ADC);
ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, UCB_IE_ADC);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
/* Cause an ADC interrupt. */
ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA);
ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
/* Wait for the conversion to complete. */
timeout = jiffies + HZ/2;
while (!(ucb1400_reg_read(ucb->ac97, UCB_ADC_DATA) &
UCB_ADC_DAT_VALID)) {
cpu_relax();
if (time_after(jiffies, timeout)) {
printk(KERN_ERR "ucb1400: timed out in IRQ probe\n");
probe_irq_off(mask);
return -ENODEV;
}
}
ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, 0);
/* Disable and clear interrupt. */
ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, 0);
ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, 0);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
/* Read triggered interrupt. */
ucb->irq = probe_irq_off(mask);
if (ucb->irq < 0 || ucb->irq == NO_IRQ)
return -ENODEV;
return 0;
}
static int ucb1400_ts_probe(struct platform_device *dev)
{
int error, x_res, y_res;
struct ucb1400_ts *ucb = dev->dev.platform_data;
ucb->ts_idev = input_allocate_device();
if (!ucb->ts_idev) {
error = -ENOMEM;
goto err;
}
error = ucb1400_ts_detect_irq(ucb);
if (error) {
printk(KERN_ERR "UCB1400: IRQ probe failed\n");
goto err_free_devs;
}
init_waitqueue_head(&ucb->ts_wait);
error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
"UCB1400", ucb);
if (error) {
printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
ucb->irq, error);
goto err_free_devs;
}
printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);
input_set_drvdata(ucb->ts_idev, ucb);
ucb->ts_idev->dev.parent = &dev->dev;
ucb->ts_idev->name = "UCB1400 touchscreen interface";
ucb->ts_idev->id.vendor = ucb1400_reg_read(ucb->ac97,
AC97_VENDOR_ID1);
ucb->ts_idev->id.product = ucb->id;
ucb->ts_idev->open = ucb1400_ts_open;
ucb->ts_idev->close = ucb1400_ts_close;
ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS);
ucb1400_adc_enable(ucb->ac97);
x_res = ucb1400_ts_read_xres(ucb);
y_res = ucb1400_ts_read_yres(ucb);
ucb1400_adc_disable(ucb->ac97);
printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);
input_set_abs_params(ucb->ts_idev, ABS_X, 0, x_res, 0, 0);
input_set_abs_params(ucb->ts_idev, ABS_Y, 0, y_res, 0, 0);
input_set_abs_params(ucb->ts_idev, ABS_PRESSURE, 0, 0, 0, 0);
error = input_register_device(ucb->ts_idev);
if (error)
goto err_free_irq;
return 0;
err_free_irq:
free_irq(ucb->irq, ucb);
err_free_devs:
input_free_device(ucb->ts_idev);
err:
return error;
}
static int ucb1400_ts_remove(struct platform_device *dev)
{
struct ucb1400_ts *ucb = dev->dev.platform_data;
free_irq(ucb->irq, ucb);
input_unregister_device(ucb->ts_idev);
return 0;
}
#ifdef CONFIG_PM
static int ucb1400_ts_resume(struct device *dev)
static int ucb1400_ts_resume(struct platform_device *dev)
{
struct ucb1400 *ucb = dev_get_drvdata(dev);
struct ucb1400_ts *ucb = platform_get_drvdata(dev);
if (ucb->ts_task) {
/*
@ -414,169 +433,36 @@ static int ucb1400_ts_resume(struct device *dev)
#define ucb1400_ts_resume NULL
#endif
#ifndef NO_IRQ
#define NO_IRQ 0
#endif
/*
* Try to probe our interrupt, rather than relying on lots of
* hard-coded machine dependencies.
*/
static int ucb1400_detect_irq(struct ucb1400 *ucb)
{
unsigned long mask, timeout;
mask = probe_irq_on();
/* Enable the ADC interrupt. */
ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
/* Cause an ADC interrupt. */
ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
/* Wait for the conversion to complete. */
timeout = jiffies + HZ/2;
while (!(ucb1400_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VALID)) {
cpu_relax();
if (time_after(jiffies, timeout)) {
printk(KERN_ERR "ucb1400: timed out in IRQ probe\n");
probe_irq_off(mask);
return -ENODEV;
}
}
ucb1400_reg_write(ucb, UCB_ADC_CR, 0);
/* Disable and clear interrupt. */
ucb1400_reg_write(ucb, UCB_IE_RIS, 0);
ucb1400_reg_write(ucb, UCB_IE_FAL, 0);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
/* Read triggered interrupt. */
ucb->irq = probe_irq_off(mask);
if (ucb->irq < 0 || ucb->irq == NO_IRQ)
return -ENODEV;
return 0;
}
static int ucb1400_ts_probe(struct device *dev)
{
struct ucb1400 *ucb;
struct input_dev *idev;
int error, id, x_res, y_res;
ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
idev = input_allocate_device();
if (!ucb || !idev) {
error = -ENOMEM;
goto err_free_devs;
}
ucb->ts_idev = idev;
ucb->adcsync = adcsync;
ucb->ac97 = to_ac97_t(dev);
init_waitqueue_head(&ucb->ts_wait);
id = ucb1400_reg_read(ucb, UCB_ID);
if (id != UCB_ID_1400) {
error = -ENODEV;
goto err_free_devs;
}
error = ucb1400_detect_irq(ucb);
if (error) {
printk(KERN_ERR "UCB1400: IRQ probe failed\n");
goto err_free_devs;
}
error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
"UCB1400", ucb);
if (error) {
printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
ucb->irq, error);
goto err_free_devs;
}
printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);
input_set_drvdata(idev, ucb);
idev->dev.parent = dev;
idev->name = "UCB1400 touchscreen interface";
idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1);
idev->id.product = id;
idev->open = ucb1400_ts_open;
idev->close = ucb1400_ts_close;
idev->evbit[0] = BIT_MASK(EV_ABS);
ucb1400_adc_enable(ucb);
x_res = ucb1400_ts_read_xres(ucb);
y_res = ucb1400_ts_read_yres(ucb);
ucb1400_adc_disable(ucb);
printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);
input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0);
input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0);
input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0);
error = input_register_device(idev);
if (error)
goto err_free_irq;
dev_set_drvdata(dev, ucb);
return 0;
err_free_irq:
free_irq(ucb->irq, ucb);
err_free_devs:
input_free_device(idev);
kfree(ucb);
return error;
}
static int ucb1400_ts_remove(struct device *dev)
{
struct ucb1400 *ucb = dev_get_drvdata(dev);
free_irq(ucb->irq, ucb);
input_unregister_device(ucb->ts_idev);
dev_set_drvdata(dev, NULL);
kfree(ucb);
return 0;
}
static struct device_driver ucb1400_ts_driver = {
.name = "ucb1400_ts",
.owner = THIS_MODULE,
.bus = &ac97_bus_type,
.probe = ucb1400_ts_probe,
.remove = ucb1400_ts_remove,
.resume = ucb1400_ts_resume,
static struct platform_driver ucb1400_ts_driver = {
.probe = ucb1400_ts_probe,
.remove = ucb1400_ts_remove,
.resume = ucb1400_ts_resume,
.driver = {
.name = "ucb1400_ts",
},
};
static int __init ucb1400_ts_init(void)
{
return driver_register(&ucb1400_ts_driver);
return platform_driver_register(&ucb1400_ts_driver);
}
static void __exit ucb1400_ts_exit(void)
{
driver_unregister(&ucb1400_ts_driver);
platform_driver_unregister(&ucb1400_ts_driver);
}
module_param(adcsync, bool, 0444);
MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
module_param(ts_delay, int, 0444);
MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us.");
MODULE_PARM_DESC(ts_delay, "Delay between panel setup and"
" position read. Default = 55us.");
module_param(ts_delay_pressure, int, 0444);
MODULE_PARM_DESC(ts_delay_pressure,
"delay between panel setup and pressure read. Default = 0us.");
"delay between panel setup and pressure read."
" Default = 0us.");
module_init(ucb1400_ts_init);
module_exit(ucb1400_ts_exit);

View file

@ -50,6 +50,15 @@ config HTC_PASIC3
HTC Magician devices, respectively. Actual functionality is
handled by the leds-pasic3 and ds1wm drivers.
config UCB1400_CORE
tristate "Philips UCB1400 Core driver"
help
This enables support for the Philips UCB1400 core functions.
The UCB1400 is an AC97 audio codec.
To compile this driver as a module, choose M here: the
module will be called ucb1400_core.
config MFD_TMIO
bool
default n

View file

@ -22,3 +22,4 @@ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
ifeq ($(CONFIG_SA1100_ASSABET),y)
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
endif
obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o

106
drivers/mfd/ucb1400_core.c Normal file
View file

@ -0,0 +1,106 @@
/*
* Core functions for:
* Philips UCB1400 multifunction chip
*
* Based on ucb1400_ts.c:
* Author: Nicolas Pitre
* Created: September 25, 2006
* Copyright: MontaVista Software, Inc.
*
* Spliting done by: Marek Vasut <marek.vasut@gmail.com>
* If something doesnt work and it worked before spliting, e-mail me,
* dont bother Nicolas please ;-)
*
* 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.
*
* This code is heavily based on ucb1x00-*.c copyrighted by Russell King
* covering the UCB1100, UCB1200 and UCB1300.. Support for the UCB1400 has
* been made separate from ucb1x00-core/ucb1x00-ts on Russell's request.
*/
#include <linux/module.h>
#include <linux/ucb1400.h>
static int ucb1400_core_probe(struct device *dev)
{
int err;
struct ucb1400 *ucb;
struct ucb1400_ts ucb_ts;
struct snd_ac97 *ac97;
memset(&ucb_ts, 0, sizeof(ucb_ts));
ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
if (!ucb) {
err = -ENOMEM;
goto err;
}
dev_set_drvdata(dev, ucb);
ac97 = to_ac97_t(dev);
ucb_ts.id = ucb1400_reg_read(ac97, UCB_ID);
if (ucb_ts.id != UCB_ID_1400) {
err = -ENODEV;
goto err0;
}
/* TOUCHSCREEN */
ucb_ts.ac97 = ac97;
ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
if (!ucb->ucb1400_ts) {
err = -ENOMEM;
goto err0;
}
err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts,
sizeof(ucb_ts));
if (err)
goto err1;
err = platform_device_add(ucb->ucb1400_ts);
if (err)
goto err1;
return 0;
err1:
platform_device_put(ucb->ucb1400_ts);
err0:
kfree(ucb);
err:
return err;
}
static int ucb1400_core_remove(struct device *dev)
{
struct ucb1400 *ucb = dev_get_drvdata(dev);
platform_device_unregister(ucb->ucb1400_ts);
kfree(ucb);
return 0;
}
static struct device_driver ucb1400_core_driver = {
.name = "ucb1400_core",
.bus = &ac97_bus_type,
.probe = ucb1400_core_probe,
.remove = ucb1400_core_remove,
};
static int __init ucb1400_core_init(void)
{
return driver_register(&ucb1400_core_driver);
}
static void __exit ucb1400_core_exit(void)
{
driver_unregister(&ucb1400_core_driver);
}
module_init(ucb1400_core_init);
module_exit(ucb1400_core_exit);
MODULE_DESCRIPTION("Philips UCB1400 driver");
MODULE_LICENSE("GPL");

View file

@ -73,5 +73,6 @@ pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
pxa2xx_cs-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
pxa2xx_cs-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o

View file

@ -0,0 +1,151 @@
/*
* linux/drivers/pcmcia/pxa2xx_palmld.c
*
* Driver for Palm LifeDrive PCMCIA
*
* Copyright (C) 2006 Alex Osborne <ato@meshy.org>
* Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
*
* 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 <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <mach/palmld.h>
#include "soc_common.h"
static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
if (ret)
goto err1;
ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
if (ret)
goto err2;
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
if (ret)
goto err2;
ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
if (ret)
goto err3;
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
if (ret)
goto err3;
ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
if (ret)
goto err4;
skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
return 0;
err4:
gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
err3:
gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
err2:
gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
err1:
return ret;
}
static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
}
static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
state->detect = 1; /* always inserted */
state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1;
state->vs_Xv = 0;
}
static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
!!(state->flags & SS_RESET));
return 0;
}
static void palmld_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
}
static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
}
static struct pcmcia_low_level palmld_pcmcia_ops = {
.owner = THIS_MODULE,
.first = 0,
.nr = 2,
.hw_init = palmld_pcmcia_hw_init,
.hw_shutdown = palmld_pcmcia_hw_shutdown,
.socket_state = palmld_pcmcia_socket_state,
.configure_socket = palmld_pcmcia_configure_socket,
.socket_init = palmld_pcmcia_socket_init,
.socket_suspend = palmld_pcmcia_socket_suspend,
};
static struct platform_device *palmld_pcmcia_device;
static int __init palmld_pcmcia_init(void)
{
int ret;
if (!machine_is_palmld())
return -ENODEV;
palmld_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
if (!palmld_pcmcia_device)
return -ENOMEM;
ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
sizeof(palmld_pcmcia_ops));
if (!ret)
ret = platform_device_add(palmld_pcmcia_device);
if (ret)
platform_device_put(palmld_pcmcia_device);
return ret;
}
static void __exit palmld_pcmcia_exit(void)
{
platform_device_unregister(palmld_pcmcia_device);
}
module_init(palmld_pcmcia_init);
module_exit(palmld_pcmcia_exit);
MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
" Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
MODULE_LICENSE("GPL");

View file

@ -56,10 +56,10 @@ config BATTERY_TOSA
Say Y to enable support for the battery on the Sharp Zaurus
SL-6000 (tosa) models.
config BATTERY_PALMTX
tristate "Palm T|X battery"
depends on MACH_PALMTX
config BATTERY_WM97XX
bool "WM97xx generic battery driver"
depends on TOUCHSCREEN_WM97XX
help
Say Y to enable support for the battery in Palm T|X.
Say Y to enable support for battery measured by WM97xx aux port.
endif # POWER_SUPPLY

View file

@ -21,4 +21,4 @@ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_PALMTX) += palmtx_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o

View file

@ -1,198 +0,0 @@
/*
* linux/drivers/power/palmtx_battery.c
*
* Battery measurement code for Palm T|X Handheld computer
*
* based on tosa_battery.c
*
* Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
*
* 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/power_supply.h>
#include <linux/wm97xx.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <mach/palmtx.h>
static DEFINE_MUTEX(bat_lock);
static struct work_struct bat_work;
struct mutex work_lock;
int bat_status = POWER_SUPPLY_STATUS_DISCHARGING;
static unsigned long palmtx_read_bat(struct power_supply *bat_ps)
{
return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
WM97XX_AUX_ID3) * 1000 / 414;
}
static unsigned long palmtx_read_temp(struct power_supply *bat_ps)
{
return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
WM97XX_AUX_ID2);
}
static int palmtx_bat_get_property(struct power_supply *bat_ps,
enum power_supply_property psp,
union power_supply_propval *val)
{
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = bat_status;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = palmtx_read_bat(bat_ps);
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
val->intval = PALMTX_BAT_MAX_VOLTAGE;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
val->intval = PALMTX_BAT_MIN_VOLTAGE;
break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = palmtx_read_temp(bat_ps);
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
default:
return -EINVAL;
}
return 0;
}
static void palmtx_bat_external_power_changed(struct power_supply *bat_ps)
{
schedule_work(&bat_work);
}
static char *status_text[] = {
[POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
[POWER_SUPPLY_STATUS_CHARGING] = "Charging",
[POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
};
static void palmtx_bat_update(struct power_supply *bat_ps)
{
int old_status = bat_status;
mutex_lock(&work_lock);
bat_status = gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT) ?
POWER_SUPPLY_STATUS_CHARGING :
POWER_SUPPLY_STATUS_DISCHARGING;
if (old_status != bat_status) {
pr_debug("%s %s -> %s\n", bat_ps->name,
status_text[old_status],
status_text[bat_status]);
power_supply_changed(bat_ps);
}
mutex_unlock(&work_lock);
}
static enum power_supply_property palmtx_bat_main_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_PRESENT,
};
struct power_supply bat_ps = {
.name = "main-battery",
.type = POWER_SUPPLY_TYPE_BATTERY,
.properties = palmtx_bat_main_props,
.num_properties = ARRAY_SIZE(palmtx_bat_main_props),
.get_property = palmtx_bat_get_property,
.external_power_changed = palmtx_bat_external_power_changed,
.use_for_apm = 1,
};
static void palmtx_bat_work(struct work_struct *work)
{
palmtx_bat_update(&bat_ps);
}
#ifdef CONFIG_PM
static int palmtx_bat_suspend(struct platform_device *dev, pm_message_t state)
{
flush_scheduled_work();
return 0;
}
static int palmtx_bat_resume(struct platform_device *dev)
{
schedule_work(&bat_work);
return 0;
}
#else
#define palmtx_bat_suspend NULL
#define palmtx_bat_resume NULL
#endif
static int __devinit palmtx_bat_probe(struct platform_device *dev)
{
int ret = 0;
if (!machine_is_palmtx())
return -ENODEV;
mutex_init(&work_lock);
INIT_WORK(&bat_work, palmtx_bat_work);
ret = power_supply_register(&dev->dev, &bat_ps);
if (!ret)
schedule_work(&bat_work);
return ret;
}
static int __devexit palmtx_bat_remove(struct platform_device *dev)
{
power_supply_unregister(&bat_ps);
return 0;
}
static struct platform_driver palmtx_bat_driver = {
.driver.name = "wm97xx-battery",
.driver.owner = THIS_MODULE,
.probe = palmtx_bat_probe,
.remove = __devexit_p(palmtx_bat_remove),
.suspend = palmtx_bat_suspend,
.resume = palmtx_bat_resume,
};
static int __init palmtx_bat_init(void)
{
return platform_driver_register(&palmtx_bat_driver);
}
static void __exit palmtx_bat_exit(void)
{
platform_driver_unregister(&palmtx_bat_driver);
}
module_init(palmtx_bat_init);
module_exit(palmtx_bat_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("Palm T|X battery driver");

View file

@ -0,0 +1,272 @@
/*
* linux/drivers/power/wm97xx_battery.c
*
* Battery measurement code for WM97xx
*
* based on tosa_battery.c
*
* Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
*
* 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 <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/wm97xx.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
static DEFINE_MUTEX(bat_lock);
static struct work_struct bat_work;
struct mutex work_lock;
static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
static struct wm97xx_batt_info *pdata;
static enum power_supply_property *prop;
static unsigned long wm97xx_read_bat(struct power_supply *bat_ps)
{
return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
pdata->batt_aux) * pdata->batt_mult /
pdata->batt_div;
}
static unsigned long wm97xx_read_temp(struct power_supply *bat_ps)
{
return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
pdata->temp_aux) * pdata->temp_mult /
pdata->temp_div;
}
static int wm97xx_bat_get_property(struct power_supply *bat_ps,
enum power_supply_property psp,
union power_supply_propval *val)
{
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = bat_status;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = pdata->batt_tech;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
if (pdata->batt_aux >= 0)
val->intval = wm97xx_read_bat(bat_ps);
else
return -EINVAL;
break;
case POWER_SUPPLY_PROP_TEMP:
if (pdata->temp_aux >= 0)
val->intval = wm97xx_read_temp(bat_ps);
else
return -EINVAL;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
if (pdata->max_voltage >= 0)
val->intval = pdata->max_voltage;
else
return -EINVAL;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
if (pdata->min_voltage >= 0)
val->intval = pdata->min_voltage;
else
return -EINVAL;
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
default:
return -EINVAL;
}
return 0;
}
static void wm97xx_bat_external_power_changed(struct power_supply *bat_ps)
{
schedule_work(&bat_work);
}
static void wm97xx_bat_update(struct power_supply *bat_ps)
{
int old_status = bat_status;
mutex_lock(&work_lock);
bat_status = (pdata->charge_gpio >= 0) ?
(gpio_get_value(pdata->charge_gpio) ?
POWER_SUPPLY_STATUS_DISCHARGING :
POWER_SUPPLY_STATUS_CHARGING) :
POWER_SUPPLY_STATUS_UNKNOWN;
if (old_status != bat_status) {
pr_debug("%s: %i -> %i\n", bat_ps->name, old_status,
bat_status);
power_supply_changed(bat_ps);
}
mutex_unlock(&work_lock);
}
static struct power_supply bat_ps = {
.type = POWER_SUPPLY_TYPE_BATTERY,
.get_property = wm97xx_bat_get_property,
.external_power_changed = wm97xx_bat_external_power_changed,
.use_for_apm = 1,
};
static void wm97xx_bat_work(struct work_struct *work)
{
wm97xx_bat_update(&bat_ps);
}
#ifdef CONFIG_PM
static int wm97xx_bat_suspend(struct platform_device *dev, pm_message_t state)
{
flush_scheduled_work();
return 0;
}
static int wm97xx_bat_resume(struct platform_device *dev)
{
schedule_work(&bat_work);
return 0;
}
#else
#define wm97xx_bat_suspend NULL
#define wm97xx_bat_resume NULL
#endif
static int __devinit wm97xx_bat_probe(struct platform_device *dev)
{
int ret = 0;
int props = 1; /* POWER_SUPPLY_PROP_PRESENT */
int i = 0;
if (dev->id != -1)
return -EINVAL;
mutex_init(&work_lock);
if (!pdata) {
dev_err(&dev->dev, "Please use wm97xx_bat_set_pdata\n");
return -EINVAL;
}
if (pdata->charge_gpio >= 0 && gpio_is_valid(pdata->charge_gpio)) {
ret = gpio_request(pdata->charge_gpio, "BATT CHRG");
if (ret)
goto err;
ret = gpio_direction_input(pdata->charge_gpio);
if (ret)
goto err2;
props++; /* POWER_SUPPLY_PROP_STATUS */
}
if (pdata->batt_tech >= 0)
props++; /* POWER_SUPPLY_PROP_TECHNOLOGY */
if (pdata->temp_aux >= 0)
props++; /* POWER_SUPPLY_PROP_TEMP */
if (pdata->batt_aux >= 0)
props++; /* POWER_SUPPLY_PROP_VOLTAGE_NOW */
if (pdata->max_voltage >= 0)
props++; /* POWER_SUPPLY_PROP_VOLTAGE_MAX */
if (pdata->min_voltage >= 0)
props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */
prop = kzalloc(props * sizeof(*prop), GFP_KERNEL);
if (!prop)
goto err2;
prop[i++] = POWER_SUPPLY_PROP_PRESENT;
if (pdata->charge_gpio >= 0)
prop[i++] = POWER_SUPPLY_PROP_STATUS;
if (pdata->batt_tech >= 0)
prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY;
if (pdata->temp_aux >= 0)
prop[i++] = POWER_SUPPLY_PROP_TEMP;
if (pdata->batt_aux >= 0)
prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW;
if (pdata->max_voltage >= 0)
prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX;
if (pdata->min_voltage >= 0)
prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN;
INIT_WORK(&bat_work, wm97xx_bat_work);
if (!pdata->batt_name) {
dev_info(&dev->dev, "Please consider setting proper battery "
"name in platform definition file, falling "
"back to name \"wm97xx-batt\"\n");
bat_ps.name = "wm97xx-batt";
} else
bat_ps.name = pdata->batt_name;
bat_ps.properties = prop;
bat_ps.num_properties = props;
ret = power_supply_register(&dev->dev, &bat_ps);
if (!ret)
schedule_work(&bat_work);
else
goto err3;
return 0;
err3:
kfree(prop);
err2:
gpio_free(pdata->charge_gpio);
err:
return ret;
}
static int __devexit wm97xx_bat_remove(struct platform_device *dev)
{
if (pdata && pdata->charge_gpio && pdata->charge_gpio >= 0)
gpio_free(pdata->charge_gpio);
flush_scheduled_work();
power_supply_unregister(&bat_ps);
kfree(prop);
return 0;
}
static struct platform_driver wm97xx_bat_driver = {
.driver = {
.name = "wm97xx-battery",
.owner = THIS_MODULE,
},
.probe = wm97xx_bat_probe,
.remove = __devexit_p(wm97xx_bat_remove),
.suspend = wm97xx_bat_suspend,
.resume = wm97xx_bat_resume,
};
static int __init wm97xx_bat_init(void)
{
return platform_driver_register(&wm97xx_bat_driver);
}
static void __exit wm97xx_bat_exit(void)
{
platform_driver_unregister(&wm97xx_bat_driver);
}
void __init wm97xx_bat_set_pdata(struct wm97xx_batt_info *data)
{
pdata = data;
}
EXPORT_SYMBOL_GPL(wm97xx_bat_set_pdata);
module_init(wm97xx_bat_init);
module_exit(wm97xx_bat_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("WM97xx battery driver");

161
include/linux/ucb1400.h Normal file
View file

@ -0,0 +1,161 @@
/*
* Register definitions and functions for:
* Philips UCB1400 driver
*
* Based on ucb1400_ts:
* Author: Nicolas Pitre
* Created: September 25, 2006
* Copyright: MontaVista Software, Inc.
*
* Spliting done by: Marek Vasut <marek.vasut@gmail.com>
* If something doesnt work and it worked before spliting, e-mail me,
* dont bother Nicolas please ;-)
*
* 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.
*
* This code is heavily based on ucb1x00-*.c copyrighted by Russell King
* covering the UCB1100, UCB1200 and UCB1300.. Support for the UCB1400 has
* been made separate from ucb1x00-core/ucb1x00-ts on Russell's request.
*/
#ifndef _LINUX__UCB1400_H
#define _LINUX__UCB1400_H
#include <sound/ac97_codec.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
/*
* UCB1400 AC-link registers
*/
#define UCB_IO_DATA 0x5a
#define UCB_IO_DIR 0x5c
#define UCB_IE_RIS 0x5e
#define UCB_IE_FAL 0x60
#define UCB_IE_STATUS 0x62
#define UCB_IE_CLEAR 0x62
#define UCB_IE_ADC (1 << 11)
#define UCB_IE_TSPX (1 << 12)
#define UCB_TS_CR 0x64
#define UCB_TS_CR_TSMX_POW (1 << 0)
#define UCB_TS_CR_TSPX_POW (1 << 1)
#define UCB_TS_CR_TSMY_POW (1 << 2)
#define UCB_TS_CR_TSPY_POW (1 << 3)
#define UCB_TS_CR_TSMX_GND (1 << 4)
#define UCB_TS_CR_TSPX_GND (1 << 5)
#define UCB_TS_CR_TSMY_GND (1 << 6)
#define UCB_TS_CR_TSPY_GND (1 << 7)
#define UCB_TS_CR_MODE_INT (0 << 8)
#define UCB_TS_CR_MODE_PRES (1 << 8)
#define UCB_TS_CR_MODE_POS (2 << 8)
#define UCB_TS_CR_BIAS_ENA (1 << 11)
#define UCB_TS_CR_TSPX_LOW (1 << 12)
#define UCB_TS_CR_TSMX_LOW (1 << 13)
#define UCB_ADC_CR 0x66
#define UCB_ADC_SYNC_ENA (1 << 0)
#define UCB_ADC_VREFBYP_CON (1 << 1)
#define UCB_ADC_INP_TSPX (0 << 2)
#define UCB_ADC_INP_TSMX (1 << 2)
#define UCB_ADC_INP_TSPY (2 << 2)
#define UCB_ADC_INP_TSMY (3 << 2)
#define UCB_ADC_INP_AD0 (4 << 2)
#define UCB_ADC_INP_AD1 (5 << 2)
#define UCB_ADC_INP_AD2 (6 << 2)
#define UCB_ADC_INP_AD3 (7 << 2)
#define UCB_ADC_EXT_REF (1 << 5)
#define UCB_ADC_START (1 << 7)
#define UCB_ADC_ENA (1 << 15)
#define UCB_ADC_DATA 0x68
#define UCB_ADC_DAT_VALID (1 << 15)
#define UCB_ADC_DAT_MASK 0x3ff
#define UCB_ID 0x7e
#define UCB_ID_1400 0x4304
struct ucb1400_ts {
struct input_dev *ts_idev;
struct task_struct *ts_task;
int id;
wait_queue_head_t ts_wait;
unsigned int ts_restart:1;
int irq;
unsigned int irq_pending; /* not bit field shared */
struct snd_ac97 *ac97;
};
struct ucb1400 {
struct platform_device *ucb1400_ts;
};
static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg)
{
return ac97->bus->ops->read(ac97, reg);
}
static inline void ucb1400_reg_write(struct snd_ac97 *ac97, u16 reg, u16 val)
{
ac97->bus->ops->write(ac97, reg, val);
}
static inline u16 ucb1400_gpio_get_value(struct snd_ac97 *ac97, u16 gpio)
{
return ucb1400_reg_read(ac97, UCB_IO_DATA) & (1 << gpio);
}
static inline void ucb1400_gpio_set_value(struct snd_ac97 *ac97, u16 gpio,
u16 val)
{
ucb1400_reg_write(ac97, UCB_IO_DATA, val ?
ucb1400_reg_read(ac97, UCB_IO_DATA) | (1 << gpio) :
ucb1400_reg_read(ac97, UCB_IO_DATA) & ~(1 << gpio));
}
static inline u16 ucb1400_gpio_get_direction(struct snd_ac97 *ac97, u16 gpio)
{
return ucb1400_reg_read(ac97, UCB_IO_DIR) & (1 << gpio);
}
static inline void ucb1400_gpio_set_direction(struct snd_ac97 *ac97, u16 gpio,
u16 dir)
{
ucb1400_reg_write(ac97, UCB_IO_DIR, dir ?
ucb1400_reg_read(ac97, UCB_IO_DIR) | (1 << gpio) :
ucb1400_reg_read(ac97, UCB_IO_DIR) & ~(1 << gpio));
}
static inline void ucb1400_adc_enable(struct snd_ac97 *ac97)
{
ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA);
}
static unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
int adcsync)
{
unsigned int val;
if (adcsync)
adc_channel |= UCB_ADC_SYNC_ENA;
ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel);
ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel |
UCB_ADC_START);
while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA))
& UCB_ADC_DAT_VALID))
schedule_timeout_uninterruptible(1);
return val & UCB_ADC_DAT_MASK;
}
static inline void ucb1400_adc_disable(struct snd_ac97 *ac97)
{
ucb1400_reg_write(ac97, UCB_ADC_CR, 0);
}
#endif

View file

@ -0,0 +1,26 @@
#ifndef _LINUX_WM97XX_BAT_H
#define _LINUX_WM97XX_BAT_H
#include <linux/wm97xx.h>
struct wm97xx_batt_info {
int batt_aux;
int temp_aux;
int charge_gpio;
int min_voltage;
int max_voltage;
int batt_div;
int batt_mult;
int temp_div;
int temp_mult;
int batt_tech;
char *batt_name;
};
#ifdef CONFIG_BATTERY_WM97XX
void __init wm97xx_bat_set_pdata(struct wm97xx_batt_info *data);
#else
static inline void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data) {}
#endif
#endif