mirror of https://github.com/hak5/openwrt.git
add support for target 3c24xx (more known as Openmoko GTA02 "Freerunner") and merge it with the openmoko-target and the work Michael Buesch <mb> did
SVN-Revision: 13609lede-17.01
parent
4571721ec2
commit
b9dfb81f2a
|
@ -1,6 +0,0 @@
|
|||
::sysinit:/etc/init.d/rcS S boot
|
||||
::shutdown:/etc/init.d/rcS K stop
|
||||
tts/0::askfirst:/bin/ash --login
|
||||
ttyS0::askfirst:/bin/ash --login
|
||||
|
||||
ttyS2::respawn:/sbin/getty -L ttyS2 115200 vt100
|
|
@ -1,3 +0,0 @@
|
|||
src snapshots http://vlink.guthrie.homedns.org/vlink3
|
||||
dest root /
|
||||
dest ram /tmp
|
File diff suppressed because it is too large
Load Diff
|
@ -1,37 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2008 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
JFFS2_BLOCKSIZE := 128k
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
define Image/mkfs/jffs2/sub
|
||||
$(STAGING_DIR_HOST)/bin/mkfs.jffs2 --pad --little-endian --pagesize=0x800 --no-cleanmarkers -e $(patsubst %k,%KiB,$(1)) -o $(KDIR)/root.jffs2-$(1) -d $(TARGET_DIR)
|
||||
$(call add_jffs2_mark,$(KDIR)/root.jffs2-$(1))
|
||||
$(call Image/Build,jffs2-$(1))
|
||||
endef
|
||||
|
||||
define Build/Clean
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Image/Prepare
|
||||
cp $(LINUX_DIR)/arch/arm/boot/uImage $(KDIR)/uImage
|
||||
endef
|
||||
|
||||
define Image/BuildKernel
|
||||
cp $(KDIR)/uImage $(BIN_DIR)/openwrt-$(BOARD)-uImage
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
cp $(KDIR)/root.jffs2-128k $(BIN_DIR)/openwrt-$(BOARD)-rootfs
|
||||
endef
|
||||
|
||||
$(eval $(call BuildImage))
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2008 OpenWrt.org
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
|
@ -7,18 +7,19 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=arm
|
||||
BOARD:=openmoko
|
||||
BOARDNAME:=Openmoko
|
||||
FEATURES:=usb
|
||||
BOARD:=s3c24xx
|
||||
BOARDNAME:=s3c24xx
|
||||
FEATURES:=jffs2
|
||||
|
||||
LINUX_VERSION:=2.6.24.7
|
||||
LINUX_VERSION:=2.6.26
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
KERNELNAME:="uImage"
|
||||
DEVICE_TYPE=phone
|
||||
|
||||
define Target/Description
|
||||
Build fimware images for the Openmoko Smartphone.
|
||||
OpenMoko gta02
|
||||
endef
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
DEFAULT_PACKAGES += xglamo enlightenment
|
||||
|
||||
$(eval $(call BuildTarget))
|
|
@ -0,0 +1,14 @@
|
|||
# Copyright (C) 2006 OpenWrt.org
|
||||
|
||||
config interface loopback
|
||||
option ifname lo
|
||||
option proto static
|
||||
option ipaddr 127.0.0.1
|
||||
option netmask 255.0.0.0
|
||||
|
||||
config interface lan
|
||||
option ifname usb0
|
||||
option type bridge
|
||||
option proto static
|
||||
option ipaddr 192.168.1.1
|
||||
option netmask 255.255.255.0
|
|
@ -0,0 +1,5 @@
|
|||
::sysinit:/etc/init.d/rcS S boot
|
||||
::shutdown:/etc/init.d/rcS K stop
|
||||
s3c2410_serial0::askfirst:/bin/ash --login
|
||||
s3c2410_serial2::askfirst:/bin/ash --login
|
||||
tty1::askfirst:/bin/ash --login
|
|
@ -0,0 +1,78 @@
|
|||
#!/bin/sh
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||
. /etc/diag.sh
|
||||
rm -rf /dev/console
|
||||
mknod /dev/console c 204 64
|
||||
exec </dev/console > /dev/console 2>&0
|
||||
|
||||
failsafe_ip() {
|
||||
ifconfig $ifname 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 up
|
||||
}
|
||||
|
||||
failsafe() {
|
||||
[ -n "$ifname" ] && grep "$ifname" /proc/net/dev >/dev/null && {
|
||||
failsafe_ip
|
||||
netmsg 192.168.1.255 "Entering Failsafe!"
|
||||
telnetd -l /bin/login <> /dev/null 2>&1
|
||||
}
|
||||
lock /tmp/.failsafe
|
||||
ash --login
|
||||
}
|
||||
|
||||
mount none /proc -t proc
|
||||
mount none /sys -t sysfs
|
||||
|
||||
size=$(awk '/MemTotal:/ {l=5242880;mt=($2*1024);print((s=mt/2)<l)?mt-l:s}' /proc/meminfo)
|
||||
mount none /tmp -t tmpfs -o size=$size,nosuid,nodev,mode=1777
|
||||
|
||||
if grep devfs /proc/filesystems > /dev/null; then
|
||||
mount none /dev -t devfs
|
||||
M0=/dev/pty/m0
|
||||
M1=/dev/pty/m1
|
||||
HOTPLUG=/sbin/hotplug-call
|
||||
else
|
||||
mount -t tmpfs tmpfs /dev -o size=512K
|
||||
# mknod /dev/console c 5 1
|
||||
mkdir /dev/shm
|
||||
/sbin/hotplug2 --coldplug --set-rules-file /etc/hotplug2-init.rules
|
||||
/sbin/hotplug2 --no-coldplug --persistent --set-rules-file /etc/hotplug2-init.rules &
|
||||
M0=/dev/ptmx
|
||||
M1=/dev/ptmx
|
||||
HOTPLUG=
|
||||
fi
|
||||
|
||||
mkdir -p /dev/pts /dev/shm
|
||||
mount none /dev/pts -t devpts
|
||||
|
||||
# the shell really doesn't like having stdin/out closed
|
||||
# that's why we use /dev/pty/m0 and m1 as replacement
|
||||
# for /dev/console if there's no serial console available
|
||||
dd if=/dev/console of=/dev/null bs=1 count=0 >/dev/null 2>/dev/null && {
|
||||
M0=/dev/console
|
||||
M1=/dev/console
|
||||
}
|
||||
|
||||
exec <$M0 >$M1 2>&0
|
||||
|
||||
echo "- preinit -"
|
||||
trap 'FAILSAFE=true' USR1
|
||||
[ -e /etc/preinit.arch ] && . /etc/preinit.arch
|
||||
set_state preinit
|
||||
echo "$HOTPLUG" > /proc/sys/kernel/hotplug
|
||||
eval ${FAILSAFE:+failsafe}
|
||||
lock -w /tmp/.failsafe
|
||||
#mount_root
|
||||
[ -f /sysupgrade.tgz ] && {
|
||||
echo "- config restore -"
|
||||
cd /
|
||||
mv sysupgrade.tgz /tmp
|
||||
tar xzf /tmp/sysupgrade.tgz
|
||||
rm -f /tmp/sysupgrade.tgz
|
||||
sync
|
||||
}
|
||||
|
||||
echo "- init -"
|
||||
|
||||
killall hotplug2
|
||||
exec /sbin/init
|
|
@ -0,0 +1,684 @@
|
|||
CONFIG_AEABI=y
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_APM_EMULATION=y
|
||||
CONFIG_APM_POWER=y
|
||||
# CONFIG_ARCH_AAEC2000 is not set
|
||||
# CONFIG_ARCH_AT91 is not set
|
||||
# CONFIG_ARCH_BAST is not set
|
||||
# CONFIG_ARCH_CLPS711X is not set
|
||||
# CONFIG_ARCH_CLPS7500 is not set
|
||||
# CONFIG_ARCH_CO285 is not set
|
||||
# CONFIG_ARCH_DAVINCI is not set
|
||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||
# CONFIG_ARCH_EBSA110 is not set
|
||||
# CONFIG_ARCH_EP93XX is not set
|
||||
# CONFIG_ARCH_FOOTBRIDGE is not set
|
||||
# CONFIG_ARCH_H1940 is not set
|
||||
# CONFIG_ARCH_H720X is not set
|
||||
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
|
||||
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
|
||||
# CONFIG_ARCH_IMX is not set
|
||||
# CONFIG_ARCH_INTEGRATOR is not set
|
||||
# CONFIG_ARCH_IOP13XX is not set
|
||||
# CONFIG_ARCH_IOP32X is not set
|
||||
# CONFIG_ARCH_IOP33X is not set
|
||||
# CONFIG_ARCH_IXP2000 is not set
|
||||
# CONFIG_ARCH_IXP23XX is not set
|
||||
# CONFIG_ARCH_IXP4XX is not set
|
||||
# CONFIG_ARCH_KS8695 is not set
|
||||
# CONFIG_ARCH_L7200 is not set
|
||||
# CONFIG_ARCH_LH7A40X is not set
|
||||
# CONFIG_ARCH_MSM7X00A is not set
|
||||
# CONFIG_ARCH_MXC is not set
|
||||
# CONFIG_ARCH_NETX is not set
|
||||
# CONFIG_ARCH_NS9XXX is not set
|
||||
# CONFIG_ARCH_OMAP is not set
|
||||
# CONFIG_ARCH_ORION5X is not set
|
||||
# CONFIG_ARCH_PNX4008 is not set
|
||||
# CONFIG_ARCH_PXA is not set
|
||||
# CONFIG_ARCH_REALVIEW is not set
|
||||
# CONFIG_ARCH_RPC is not set
|
||||
CONFIG_ARCH_S3C2410=y
|
||||
CONFIG_ARCH_S3C2440=y
|
||||
# CONFIG_ARCH_SA1100 is not set
|
||||
# CONFIG_ARCH_SHARK is not set
|
||||
# CONFIG_ARCH_SMDK2410 is not set
|
||||
CONFIG_ARCH_SUPPORTS_AOUT=y
|
||||
# CONFIG_ARCH_SUPPORTS_MSI is not set
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
# CONFIG_ARCH_VERSATILE is not set
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_THUMB=y
|
||||
# CONFIG_ARPD is not set
|
||||
CONFIG_ATAGS_PROC=y
|
||||
# CONFIG_ATM is not set
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
# CONFIG_BACKLIGHT_CORGI is not set
|
||||
CONFIG_BACKLIGHT_GTA01=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_BASE_SMALL=0
|
||||
CONFIG_BATTERY_BQ27000_HDQ=y
|
||||
# CONFIG_BATTERY_DS2760 is not set
|
||||
# CONFIG_BINFMT_AOUT is not set
|
||||
CONFIG_BITREVERSE=y
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
# CONFIG_BLK_DEV_SR_VENDOR is not set
|
||||
# CONFIG_BONDING is not set
|
||||
CONFIG_BOUNCE=y
|
||||
# CONFIG_BRIDGE_EBT_NFLOG is not set
|
||||
CONFIG_BRIDGE_NETFILTER=y
|
||||
# CONFIG_BSD_DISKLABEL is not set
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_BNEP=y
|
||||
# CONFIG_BT_HCIBCM203X is not set
|
||||
# CONFIG_BT_HCIBFUSB is not set
|
||||
# CONFIG_BT_HCIBPA10X is not set
|
||||
# CONFIG_BT_HCIUART is not set
|
||||
CONFIG_BT_HCIUSB=y
|
||||
# CONFIG_BT_HCIVHCI is not set
|
||||
CONFIG_BT_HIDP=y
|
||||
CONFIG_BT_L2CAP=y
|
||||
CONFIG_BT_RFCOMM=y
|
||||
CONFIG_BT_SCO=y
|
||||
CONFIG_CAN_PM_TRACE=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CLASSIC_RCU=y
|
||||
CONFIG_CMDLINE="unused -- bootloader passes ATAG list"
|
||||
CONFIG_COMPAT_BRK=y
|
||||
# CONFIG_CONFIGFS_FS is not set
|
||||
CONFIG_CPU_32=y
|
||||
CONFIG_CPU_32v4T=y
|
||||
CONFIG_CPU_ABRT_EV4T=y
|
||||
CONFIG_CPU_ARM920T=y
|
||||
CONFIG_CPU_CACHE_V4WT=y
|
||||
CONFIG_CPU_CACHE_VIVT=y
|
||||
CONFIG_CPU_COPY_V4WB=y
|
||||
CONFIG_CPU_CP15=y
|
||||
CONFIG_CPU_CP15_MMU=y
|
||||
# CONFIG_CPU_DCACHE_DISABLE is not set
|
||||
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
|
||||
# CONFIG_CPU_ICACHE_DISABLE is not set
|
||||
CONFIG_CPU_LLSERIAL_S3C2410=y
|
||||
CONFIG_CPU_LLSERIAL_S3C2440=y
|
||||
CONFIG_CPU_PABRT_NOIFAR=y
|
||||
CONFIG_CPU_S3C2410=y
|
||||
CONFIG_CPU_S3C2410_DMA=y
|
||||
CONFIG_CPU_S3C2440=y
|
||||
CONFIG_CPU_S3C2442=y
|
||||
CONFIG_CPU_S3C244X=y
|
||||
CONFIG_CPU_TLB_V4WBI=y
|
||||
# CONFIG_CRC16 is not set
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
# CONFIG_CRC_ITU_T is not set
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_ALGAPI=y
|
||||
# CONFIG_CRYPTO_ANUBIS is not set
|
||||
CONFIG_CRYPTO_ARC4=y
|
||||
CONFIG_CRYPTO_BLKCIPHER=y
|
||||
CONFIG_CRYPTO_BLOWFISH=y
|
||||
# CONFIG_CRYPTO_CAMELLIA is not set
|
||||
# CONFIG_CRYPTO_CAST5 is not set
|
||||
CONFIG_CRYPTO_CAST6=y
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_DES=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
# CONFIG_CRYPTO_KHAZAD is not set
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
# CONFIG_CRYPTO_MD4 is not set
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
# CONFIG_CRYPTO_MICHAEL_MIC is not set
|
||||
# CONFIG_CRYPTO_NULL is not set
|
||||
CONFIG_CRYPTO_SERPENT=y
|
||||
CONFIG_CRYPTO_SHA1=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_TEA=y
|
||||
# CONFIG_CRYPTO_TEST is not set
|
||||
# CONFIG_CRYPTO_TGR192 is not set
|
||||
CONFIG_CRYPTO_TWOFISH=y
|
||||
CONFIG_CRYPTO_TWOFISH_COMMON=y
|
||||
# CONFIG_CRYPTO_WP512 is not set
|
||||
# CONFIG_CS89x0 is not set
|
||||
CONFIG_DAB=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_S3C_UART=2
|
||||
# CONFIG_DEBUG_USER is not set
|
||||
CONFIG_DEFAULT_TCP_CONG="cubic"
|
||||
CONFIG_DISPLAY_JBT6K74=y
|
||||
CONFIG_DISPLAY_SUPPORT=y
|
||||
# CONFIG_DM9000 is not set
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
# CONFIG_EEPROM_93CX6 is not set
|
||||
CONFIG_ELF_CORE=y
|
||||
# CONFIG_EMBEDDED is not set
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_FAT_FS=y
|
||||
CONFIG_FB=y
|
||||
# CONFIG_FB_BACKLIGHT is not set
|
||||
CONFIG_FB_CFB_COPYAREA=y
|
||||
CONFIG_FB_CFB_FILLRECT=y
|
||||
CONFIG_FB_CFB_IMAGEBLIT=y
|
||||
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
|
||||
# CONFIG_FB_DDC is not set
|
||||
# CONFIG_FB_FOREIGN_ENDIAN is not set
|
||||
# CONFIG_FB_MACMODES is not set
|
||||
# CONFIG_FB_MODE_HELPERS is not set
|
||||
# CONFIG_FB_S1D13XXX is not set
|
||||
CONFIG_FB_S3C2410=y
|
||||
# CONFIG_FB_S3C2410_DEBUG is not set
|
||||
# CONFIG_FB_SVGALIB is not set
|
||||
# CONFIG_FB_SYS_COPYAREA is not set
|
||||
# CONFIG_FB_SYS_FILLRECT is not set
|
||||
# CONFIG_FB_SYS_FOPS is not set
|
||||
# CONFIG_FB_SYS_IMAGEBLIT is not set
|
||||
# CONFIG_FB_TILEBLITTING is not set
|
||||
# CONFIG_FB_VIRTUAL is not set
|
||||
CONFIG_FIQ=y
|
||||
# CONFIG_FIRMWARE_EDID is not set
|
||||
CONFIG_FONTS=y
|
||||
# CONFIG_FONT_10x18 is not set
|
||||
CONFIG_FONT_6x11=y
|
||||
# CONFIG_FONT_7x14 is not set
|
||||
# CONFIG_FONT_8x16 is not set
|
||||
# CONFIG_FONT_8x8 is not set
|
||||
# CONFIG_FONT_ACORN_8x8 is not set
|
||||
# CONFIG_FONT_MINI_4x6 is not set
|
||||
# CONFIG_FONT_PEARL_8x8 is not set
|
||||
# CONFIG_FONT_SUN12x22 is not set
|
||||
# CONFIG_FONT_SUN8x16 is not set
|
||||
# CONFIG_FPE_FASTFPE is not set
|
||||
CONFIG_FPE_NWFPE=y
|
||||
# CONFIG_FPE_NWFPE_XP is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_FW_LOADER=m
|
||||
# CONFIG_GENERIC_CLOCKEVENTS is not set
|
||||
# CONFIG_GENERIC_FIND_FIRST_BIT is not set
|
||||
# CONFIG_GENERIC_FIND_NEXT_BIT is not set
|
||||
CONFIG_GENERIC_GPIO=y
|
||||
# CONFIG_GENERIC_TIME is not set
|
||||
CONFIG_GTA02_HDQ=y
|
||||
# CONFIG_HAMRADIO is not set
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
# CONFIG_HAVE_DMA_ATTRS is not set
|
||||
CONFIG_HAVE_IDE=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_HAVE_KRETPROBES=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
# CONFIG_HFSPLUS_FS is not set
|
||||
# CONFIG_HFS_FS is not set
|
||||
CONFIG_HID=y
|
||||
CONFIG_HID_SUPPORT=y
|
||||
CONFIG_HWMON=y
|
||||
# CONFIG_HWMON_DEBUG_CHIP is not set
|
||||
CONFIG_HW_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_HZ=200
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_S3C2410=y
|
||||
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
|
||||
# CONFIG_IBM_NEW_EMAC_RGMII is not set
|
||||
# CONFIG_IBM_NEW_EMAC_TAH is not set
|
||||
# CONFIG_IBM_NEW_EMAC_ZMII is not set
|
||||
# CONFIG_IDE is not set
|
||||
# CONFIG_IEEE80211 is not set
|
||||
CONFIG_INET_DIAG=y
|
||||
CONFIG_INET_TCP_DIAG=y
|
||||
CONFIG_INOTIFY=y
|
||||
CONFIG_INOTIFY_USER=y
|
||||
CONFIG_INPUT=y
|
||||
CONFIG_INPUT_EVBUG=m
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_INPUT_GPIO_BUTTONS is not set
|
||||
CONFIG_INPUT_KEYBOARD=y
|
||||
CONFIG_INPUT_LIS302DL=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_MOUSE=y
|
||||
CONFIG_INPUT_MOUSEDEV=y
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_INPUT_UINPUT=m
|
||||
# CONFIG_INPUT_YEALINK is not set
|
||||
CONFIG_IOSCHED_AS=m
|
||||
CONFIG_IOSCHED_CFQ=m
|
||||
# CONFIG_IP6_NF_QUEUE is not set
|
||||
# CONFIG_IP6_NF_RAW is not set
|
||||
CONFIG_IPV6_NDISC_NODETYPE=y
|
||||
# CONFIG_IPV6_ROUTER_PREF is not set
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
# CONFIG_IP_NF_ARPTABLES is not set
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
# CONFIG_IP_NF_MATCH_RECENT is not set
|
||||
# CONFIG_IP_NF_QUEUE is not set
|
||||
# CONFIG_IP_NF_RAW is not set
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_PNP=y
|
||||
# CONFIG_IP_PNP_BOOTP is not set
|
||||
# CONFIG_IP_PNP_DHCP is not set
|
||||
# CONFIG_IP_PNP_RARP is not set
|
||||
# CONFIG_IP_ROUTE_MULTIPATH is not set
|
||||
# CONFIG_IP_ROUTE_VERBOSE is not set
|
||||
# CONFIG_ISDN is not set
|
||||
# CONFIG_ISO9660_FS is not set
|
||||
# CONFIG_IWLWIFI_LEDS is not set
|
||||
CONFIG_JBD=y
|
||||
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KEXEC=y
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
CONFIG_KEYBOARD_GPIO=m
|
||||
# CONFIG_KEYBOARD_LKKBD is not set
|
||||
CONFIG_KEYBOARD_NEO1973=y
|
||||
# CONFIG_KEYBOARD_NEWTON is not set
|
||||
CONFIG_KEYBOARD_QT2410=y
|
||||
CONFIG_KEYBOARD_STOWAWAY=m
|
||||
# CONFIG_KEYBOARD_SUNKBD is not set
|
||||
# CONFIG_KEYBOARD_XTKBD is not set
|
||||
CONFIG_KMOD=y
|
||||
# CONFIG_KPROBES is not set
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
CONFIG_LCD_LTV350QV=y
|
||||
# CONFIG_LEDS_ALIX is not set
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_LEDS_NEO1973_GTA02=y
|
||||
CONFIG_LEDS_NEO1973_VIBRATOR=y
|
||||
CONFIG_LEDS_S3C24XX=m
|
||||
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
|
||||
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
|
||||
CONFIG_LIBCRC32C=y
|
||||
# CONFIG_LLC2 is not set
|
||||
CONFIG_LOCALVERSION="-mokodev"
|
||||
CONFIG_LOCK_KERNEL=y
|
||||
# CONFIG_LOGO is not set
|
||||
CONFIG_LOG_BUF_SHIFT=17
|
||||
# CONFIG_MACH_AML_M5900 is not set
|
||||
# CONFIG_MACH_ANUBIS is not set
|
||||
# CONFIG_MACH_N30 is not set
|
||||
CONFIG_MACH_NEO1973=y
|
||||
CONFIG_MACH_NEO1973_GTA01=y
|
||||
CONFIG_MACH_NEO1973_GTA02=y
|
||||
# CONFIG_MACH_NEXCODER_2440 is not set
|
||||
# CONFIG_MACH_OSIRIS is not set
|
||||
# CONFIG_MACH_OTOM is not set
|
||||
CONFIG_MACH_QT2410=y
|
||||
# CONFIG_MACH_RX3715 is not set
|
||||
CONFIG_MACH_SMDK=y
|
||||
# CONFIG_MACH_SMDK2412 is not set
|
||||
# CONFIG_MACH_SMDK2413 is not set
|
||||
# CONFIG_MACH_SMDK2443 is not set
|
||||
# CONFIG_MACH_TCT_HAMMER is not set
|
||||
# CONFIG_MACH_VR1000 is not set
|
||||
# CONFIG_MACH_VSTMS is not set
|
||||
# CONFIG_MAC_PARTITION is not set
|
||||
CONFIG_MARKERS=y
|
||||
CONFIG_MFD_GLAMO=y
|
||||
CONFIG_MFD_GLAMO_FB=y
|
||||
CONFIG_MFD_GLAMO_MCI=y
|
||||
CONFIG_MFD_GLAMO_SPI_FB=y
|
||||
CONFIG_MFD_GLAMO_SPI_GPIO=y
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_MINI_FO is not set
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
# CONFIG_MMC_BLOCK_BOUNCE is not set
|
||||
# CONFIG_MMC_DEBUG is not set
|
||||
CONFIG_MMC_S3C=y
|
||||
# CONFIG_MMC_SPI is not set
|
||||
CONFIG_MMC_UNSAFE_RESUME=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
# CONFIG_MOUSE_GPIO is not set
|
||||
# CONFIG_MOUSE_PS2 is not set
|
||||
# CONFIG_MOUSE_SERIAL is not set
|
||||
# CONFIG_MOUSE_VSXXXAA is not set
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_ABSENT=y
|
||||
# CONFIG_MTD_AFS_PARTS is not set
|
||||
# CONFIG_MTD_ALAUDA is not set
|
||||
# CONFIG_MTD_ARM_INTEGRATOR is not set
|
||||
CONFIG_MTD_BLKDEVS=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
CONFIG_MTD_CFI=y
|
||||
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
|
||||
# CONFIG_MTD_CFI_AMDSTD is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
CONFIG_MTD_CFI_I2=y
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
# CONFIG_MTD_CFI_STAA is not set
|
||||
CONFIG_MTD_CFI_UTIL=y
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
CONFIG_MTD_CONCAT=y
|
||||
# CONFIG_MTD_DEBUG is not set
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_GEN_PROBE=y
|
||||
# CONFIG_MTD_JEDECPROBE is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
# CONFIG_MTD_MTDRAM is not set
|
||||
CONFIG_MTD_NAND=y
|
||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||
# CONFIG_MTD_NAND_ECC_SMC is not set
|
||||
CONFIG_MTD_NAND_IDS=y
|
||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||
CONFIG_MTD_NAND_S3C2410=y
|
||||
# CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set
|
||||
# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
|
||||
CONFIG_MTD_NAND_S3C2410_HWECC=y
|
||||
CONFIG_MTD_NAND_VERIFY_WRITE=y
|
||||
# CONFIG_MTD_ONENAND is not set
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
|
||||
CONFIG_MTD_PHYSMAP_LEN=0
|
||||
CONFIG_MTD_PHYSMAP_START=0x0
|
||||
# CONFIG_MTD_PLATRAM is not set
|
||||
# CONFIG_MTD_RAM is not set
|
||||
# CONFIG_MTD_REDBOOT_PARTS is not set
|
||||
CONFIG_MTD_ROM=y
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
CONFIG_NAMESPACES=y
|
||||
# CONFIG_NEO1973_GTA02_2440 is not set
|
||||
# CONFIG_NETDEVICES_MULTIQUEUE is not set
|
||||
# CONFIG_NETDEV_1000 is not set
|
||||
CONFIG_NETFILTER_NETLINK=m
|
||||
CONFIG_NETFILTER_NETLINK_LOG=m
|
||||
CONFIG_NETFILTER_NETLINK_QUEUE=m
|
||||
CONFIG_NETFILTER_XTABLES=m
|
||||
# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
|
||||
# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
|
||||
# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
|
||||
# CONFIG_NETFILTER_XT_MATCH_TIME is not set
|
||||
# CONFIG_NETFILTER_XT_MATCH_U32 is not set
|
||||
# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
# CONFIG_NET_CLS_ACT is not set
|
||||
# CONFIG_NET_CLS_FLOW is not set
|
||||
# CONFIG_NET_CLS_IND is not set
|
||||
# CONFIG_NET_EMATCH is not set
|
||||
# CONFIG_NET_IPGRE_BROADCAST is not set
|
||||
CONFIG_NET_KEY_MIGRATE=y
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
# CONFIG_NF_CONNTRACK is not set
|
||||
CONFIG_NLS=y
|
||||
# CONFIG_NLS_CODEPAGE_1250 is not set
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_CODEPAGE_936=m
|
||||
CONFIG_NLS_CODEPAGE_950=m
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
# CONFIG_NLS_ISO8859_15 is not set
|
||||
# CONFIG_NLS_KOI8_R is not set
|
||||
CONFIG_NO_IDLE_HZ=y
|
||||
CONFIG_NO_IOPORT=y
|
||||
CONFIG_NR_TTY_DEVICES=4
|
||||
# CONFIG_NVRAM is not set
|
||||
CONFIG_OABI_COMPAT=y
|
||||
# CONFIG_OCF_OCF is not set
|
||||
# CONFIG_OUTER_CACHE is not set
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
# CONFIG_PCI_SYSCALL is not set
|
||||
CONFIG_PDA_POWER=y
|
||||
CONFIG_PLAT_S3C=y
|
||||
CONFIG_PLAT_S3C24XX=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM_VERBOSE=y
|
||||
CONFIG_PNP=y
|
||||
# CONFIG_PNPACPI is not set
|
||||
CONFIG_PNP_DEBUG=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_POWER_SUPPLY_DEBUG=y
|
||||
# CONFIG_PPP is not set
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_PROC_PAGE_MONITOR=y
|
||||
# CONFIG_RFKILL is not set
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DEBUG=y
|
||||
# CONFIG_RTC_DRV_CMOS is not set
|
||||
# CONFIG_RTC_DRV_DS1307 is not set
|
||||
# CONFIG_RTC_DRV_DS1374 is not set
|
||||
# CONFIG_RTC_DRV_DS1553 is not set
|
||||
# CONFIG_RTC_DRV_DS1672 is not set
|
||||
# CONFIG_RTC_DRV_DS1742 is not set
|
||||
# CONFIG_RTC_DRV_ISL1208 is not set
|
||||
# CONFIG_RTC_DRV_M41T80 is not set
|
||||
# CONFIG_RTC_DRV_M48T59 is not set
|
||||
# CONFIG_RTC_DRV_M48T86 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_S3C=m
|
||||
# CONFIG_RTC_DRV_STK17TA8 is not set
|
||||
# CONFIG_RTC_DRV_TEST is not set
|
||||
# CONFIG_RTC_DRV_V3020 is not set
|
||||
# CONFIG_RTC_DRV_X1205 is not set
|
||||
CONFIG_RTC_HCTOSYS=y
|
||||
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
|
||||
CONFIG_RTC_INTF_DEV=y
|
||||
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
|
||||
CONFIG_RTC_INTF_PROC=y
|
||||
CONFIG_RTC_INTF_SYSFS=y
|
||||
CONFIG_RTC_LIB=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
CONFIG_S3C2410_CLOCK=y
|
||||
CONFIG_S3C2410_DMA=y
|
||||
# CONFIG_S3C2410_DMA_DEBUG is not set
|
||||
CONFIG_S3C2410_GPIO=y
|
||||
CONFIG_S3C2410_PM=y
|
||||
# CONFIG_S3C2410_PM_CHECK is not set
|
||||
# CONFIG_S3C2410_PM_DEBUG is not set
|
||||
CONFIG_S3C2410_PWM=y
|
||||
CONFIG_S3C2410_WATCHDOG=m
|
||||
CONFIG_S3C2440_C_FIQ=y
|
||||
CONFIG_S3C2440_DMA=y
|
||||
# CONFIG_S3C_BOOT_ERROR_RESET is not set
|
||||
# CONFIG_S3C_BOOT_WATCHDOG is not set
|
||||
CONFIG_S3C_LOWLEVEL_UART_PORT=2
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SCSI_SCAN_ASYNC=y
|
||||
CONFIG_SCSI_WAIT_SCAN=m
|
||||
CONFIG_SDIO=y
|
||||
CONFIG_SDIO_AR6000_WLAN=y
|
||||
CONFIG_SDIO_S3C24XX=y
|
||||
CONFIG_SDIO_S3C24XX_DMA=y
|
||||
# CONFIG_SDIO_UART is not set
|
||||
# CONFIG_SENSORS_PC87360 is not set
|
||||
CONFIG_SENSORS_PCF50606=y
|
||||
CONFIG_SENSORS_PCF50633=y
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
CONFIG_SERIAL_S3C2410=y
|
||||
CONFIG_SERIAL_S3C2410_CONSOLE=y
|
||||
CONFIG_SERIO=y
|
||||
# CONFIG_SERIO_RAW is not set
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_SLABINFO=y
|
||||
# CONFIG_SLUB is not set
|
||||
# CONFIG_SMC91X is not set
|
||||
CONFIG_SMDK2440_CPU2440=y
|
||||
CONFIG_SMDK2440_CPU2442=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_HWDEP=y
|
||||
CONFIG_SND_MIXER_OSS=y
|
||||
CONFIG_SND_PCM=y
|
||||
CONFIG_SND_PCM_OSS=y
|
||||
CONFIG_SND_S3C24XX_SOC=y
|
||||
CONFIG_SND_S3C24XX_SOC_I2S=y
|
||||
# CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650 is not set
|
||||
CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753=y
|
||||
CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=y
|
||||
CONFIG_SND_SEQUENCER=y
|
||||
# CONFIG_SND_SEQUENCER_OSS is not set
|
||||
# CONFIG_SND_SEQ_DUMMY is not set
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_WM8753=y
|
||||
CONFIG_SND_TIMER=y
|
||||
# CONFIG_SND_USB_AUDIO is not set
|
||||
# CONFIG_SND_VERBOSE_PROCFS is not set
|
||||
# CONFIG_SND_VIRMIDI is not set
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_SOUND=y
|
||||
# CONFIG_SPARSEMEM_STATIC is not set
|
||||
# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_BITBANG=y
|
||||
# CONFIG_SPI_GPIO is not set
|
||||
CONFIG_SPI_MASTER=y
|
||||
# CONFIG_SPI_S3C24XX is not set
|
||||
CONFIG_SPI_S3C24XX_GPIO=y
|
||||
# CONFIG_SPI_SPIDEV is not set
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=4096
|
||||
CONFIG_SSB_POSSIBLE=y
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_SUSPEND_FREEZER=y
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_SYSVIPC_SYSCTL=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_CUBIC=y
|
||||
CONFIG_TCP_MD5SIG=y
|
||||
# CONFIG_TICK_ONESHOT is not set
|
||||
# CONFIG_TMPFS is not set
|
||||
# CONFIG_TOUCHSCREEN_ADS7846 is not set
|
||||
# CONFIG_TOUCHSCREEN_ELO is not set
|
||||
# CONFIG_TOUCHSCREEN_FUJITSU is not set
|
||||
# CONFIG_TOUCHSCREEN_GUNZE is not set
|
||||
# CONFIG_TOUCHSCREEN_MK712 is not set
|
||||
# CONFIG_TOUCHSCREEN_MTOUCH is not set
|
||||
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
|
||||
CONFIG_TOUCHSCREEN_S3C2410=y
|
||||
# CONFIG_TOUCHSCREEN_S3C2410_DEBUG is not set
|
||||
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
|
||||
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
|
||||
# CONFIG_TOUCHSCREEN_UCB1400 is not set
|
||||
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
|
||||
CONFIG_TUN=y
|
||||
# CONFIG_UDF_FS is not set
|
||||
CONFIG_UID16=y
|
||||
CONFIG_UIO=y
|
||||
# CONFIG_UIO_SMX is not set
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ACM=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
# CONFIG_USB_ARCH_HAS_EHCI is not set
|
||||
CONFIG_USB_DEVICE_CLASS=y
|
||||
CONFIG_USB_EPSON2888=y
|
||||
CONFIG_USB_ETH=y
|
||||
CONFIG_USB_ETH_RNDIS=y
|
||||
# CONFIG_USB_FILE_STORAGE is not set
|
||||
CONFIG_USB_GADGET=y
|
||||
# CONFIG_USB_GADGETFS is not set
|
||||
# CONFIG_USB_GADGET_AMD5536UDC is not set
|
||||
# CONFIG_USB_GADGET_AT91 is not set
|
||||
# CONFIG_USB_GADGET_ATMEL_USBA is not set
|
||||
# CONFIG_USB_GADGET_DEBUG_FILES is not set
|
||||
# CONFIG_USB_GADGET_DUALSPEED is not set
|
||||
# CONFIG_USB_GADGET_DUMMY_HCD is not set
|
||||
# CONFIG_USB_GADGET_FSL_USB2 is not set
|
||||
# CONFIG_USB_GADGET_GOKU is not set
|
||||
# CONFIG_USB_GADGET_LH7A40X is not set
|
||||
# CONFIG_USB_GADGET_M66592 is not set
|
||||
# CONFIG_USB_GADGET_NET2280 is not set
|
||||
# CONFIG_USB_GADGET_OMAP is not set
|
||||
# CONFIG_USB_GADGET_PXA27X is not set
|
||||
# CONFIG_USB_GADGET_PXA2XX is not set
|
||||
CONFIG_USB_GADGET_S3C2410=y
|
||||
CONFIG_USB_GADGET_SELECTED=y
|
||||
# CONFIG_USB_G_PRINTER is not set
|
||||
# CONFIG_USB_G_SERIAL is not set
|
||||
CONFIG_USB_HID=y
|
||||
# CONFIG_USB_ISIGHTFW is not set
|
||||
CONFIG_USB_KC2190=y
|
||||
CONFIG_USB_LIBUSUAL=y
|
||||
# CONFIG_USB_MIDI_GADGET is not set
|
||||
CONFIG_USB_MON=y
|
||||
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
|
||||
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
# CONFIG_USB_PRINTER is not set
|
||||
CONFIG_USB_RTL8150=m
|
||||
CONFIG_USB_S3C2410=y
|
||||
# CONFIG_USB_S3C2410_DEBUG is not set
|
||||
CONFIG_USB_SERIAL=y
|
||||
# CONFIG_USB_SERIAL_CH341 is not set
|
||||
CONFIG_USB_SERIAL_CONSOLE=y
|
||||
# CONFIG_USB_SERIAL_IUU is not set
|
||||
# CONFIG_USB_SERIAL_MOTOROLA is not set
|
||||
CONFIG_USB_SERIAL_OPTION=y
|
||||
# CONFIG_USB_SERIAL_OTI6858 is not set
|
||||
# CONFIG_USB_SERIAL_SPCP8X5 is not set
|
||||
CONFIG_USB_STORAGE=y
|
||||
# CONFIG_USB_STORAGE_ALAUDA is not set
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
|
||||
CONFIG_USB_STORAGE_ISD200=y
|
||||
CONFIG_USB_STORAGE_ONETOUCH=y
|
||||
CONFIG_USB_SUSPEND=y
|
||||
CONFIG_USB_USBNET=y
|
||||
# CONFIG_USB_ZERO is not set
|
||||
# CONFIG_USER_NS is not set
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_VFAT_FS=y
|
||||
# CONFIG_VGASTATE is not set
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
# CONFIG_VIDEO_MEDIA is not set
|
||||
CONFIG_VIDEO_OUTPUT_CONTROL=y
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_W1 is not set
|
||||
# CONFIG_WLAN_80211 is not set
|
||||
CONFIG_XFRM_MIGRATE=y
|
||||
# CONFIG_XFRM_USER is not set
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_XIP_KERNEL is not set
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
#JFFS2_BLOCKSIZE=16k
|
||||
#JFFS2OPTS += -n --faketime -x lzo
|
||||
JFFS2OPTS += --little-endian --eraseblock=0x20000 --pagesize=0x800 --no-cleanmarkers --pad -n
|
||||
MAKE += -j5
|
||||
|
||||
#:mkfs.jffs2 -x lzo --root=/data/moko/build/tmp/rootfs --faketime --output=/data/moko/build/tmp/deploy/glibc/images/fic-gta01/OpenMoko-openmoko-devel-image-glibc-P1-August-Snapshot-20070829-fic-gta01.rootfs.jffs2 --little-endian --eraseblock=0x4000 --pad -n
|
||||
|
||||
|
||||
define Image/BuildKernel
|
||||
$(TARGET_CROSS)objcopy -O binary -R .note -R .comment -S $(KDIR)/linux-2.6.26/arch/arm/boot/compressed/vmlinux linux.bin
|
||||
mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n "Openmoko Kernel Image Freerunner (Neo1973(GTA02))" -d linux.bin uImage
|
||||
|
||||
cp uImage $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-uImage
|
||||
endef
|
||||
|
||||
define Image/Build/squashfs
|
||||
$(call prepare_generic_squashfs,$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-root.$(1))
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-root.$(1)
|
||||
$(call Image/Build/$(1),$(1))
|
||||
endef
|
||||
|
||||
|
||||
$(eval $(call BuildImage))
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,29 @@
|
|||
From 0fa9c1c2fe923ca4f36573ca6e6b97e555d0802d Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:10 +0100
|
||||
Subject: [PATCH] explicitly-link-notes-section.patch
|
||||
|
||||
Since 2.6.23 kbuild produces a 3GB arch/arm/boot/Image because it includes a
|
||||
.note.gnu.build-id section at address 0 which is followed by 3GB of 0x00.
|
||||
The --build-id option is set in the toplevel Makefile.
|
||||
This patch explicitly puts the notes section after the TEXT section.
|
||||
---
|
||||
arch/arm/kernel/vmlinux.lds.S | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
|
||||
index 4898bdc..b835564 100644
|
||||
--- a/arch/arm/kernel/vmlinux.lds.S
|
||||
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||||
@@ -106,6 +106,8 @@ SECTIONS
|
||||
*(.got) /* Global offset table */
|
||||
}
|
||||
|
||||
+ NOTES
|
||||
+
|
||||
RODATA
|
||||
|
||||
_etext = .; /* End of text and rodata section */
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
From 1ef4af1f96284576aa9b7f4490c791350c99fffd Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:10 +0100
|
||||
Subject: [PATCH] gta01-no_nand_partitions.patch
|
||||
[PATCH] support mtd NAND commandline partitions for S3C2410
|
||||
|
||||
This patch adds support for the mtd NAND core standard method of passing
|
||||
partition table information from the bootloader into the kernel by using
|
||||
the kernel commandline.
|
||||
|
||||
The board specific code can still manually override and provide a fixed
|
||||
partition table, so this patch will behave backwards compatible.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
Acked-byt: Ben Dooks <ben-linux@fluff.org>
|
||||
---
|
||||
drivers/mtd/nand/s3c2410.c | 18 ++++++++++++++++--
|
||||
1 files changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
|
||||
index b34a460..101b6b5 100644
|
||||
--- a/drivers/mtd/nand/s3c2410.c
|
||||
+++ b/drivers/mtd/nand/s3c2410.c
|
||||
@@ -566,17 +566,31 @@ static int s3c2410_nand_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
+const char *part_probes[] = { "cmdlinepart", NULL };
|
||||
static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
|
||||
struct s3c2410_nand_mtd *mtd,
|
||||
struct s3c2410_nand_set *set)
|
||||
{
|
||||
+ struct mtd_partition *part_info;
|
||||
+ int nr_part = 0;
|
||||
+
|
||||
if (set == NULL)
|
||||
return add_mtd_device(&mtd->mtd);
|
||||
|
||||
- if (set->nr_partitions > 0 && set->partitions != NULL) {
|
||||
- return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);
|
||||
+ if (set->nr_partitions == 0) {
|
||||
+ mtd->mtd.name = set->name;
|
||||
+ nr_part = parse_mtd_partitions(&mtd->mtd, part_probes,
|
||||
+ &part_info, 0);
|
||||
+ } else {
|
||||
+ if (set->nr_partitions > 0 && set->partitions != NULL) {
|
||||
+ nr_part = set->nr_partitions;
|
||||
+ part_info = set->partitions;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ if (nr_part > 0 && part_info)
|
||||
+ return add_mtd_partitions(&mtd->mtd, part_info, nr_part);
|
||||
+
|
||||
return add_mtd_device(&mtd->mtd);
|
||||
}
|
||||
#else
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
From eb5cadc7ff0e6c3aedfec3323146d7bb6bdfe0f0 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:10 +0100
|
||||
Subject: [PATCH] fix-i2c-s3c2410-resume-race.patch
|
||||
fix-i2c-s3c2410-resume-race.patch
|
||||
|
||||
There is a nasty race between i2c-s3c2410 resume and resume of I2C
|
||||
driver and the client drivers -- the watchdog device actually gets to
|
||||
use the dead I2C bus before it is reinitialized by the I2C driver
|
||||
resume! This patch makes sure any customers get turned away until
|
||||
the shopkeeper has woken up.
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
drivers/i2c/busses/i2c-s3c2410.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 files changed, 33 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
|
||||
index 9e8c875..02459d7 100644
|
||||
--- a/drivers/i2c/busses/i2c-s3c2410.c
|
||||
+++ b/drivers/i2c/busses/i2c-s3c2410.c
|
||||
@@ -71,6 +71,8 @@ struct s3c24xx_i2c {
|
||||
struct resource *irq;
|
||||
struct resource *ioarea;
|
||||
struct i2c_adapter adap;
|
||||
+
|
||||
+ int suspended;
|
||||
};
|
||||
|
||||
/* default platform data to use if not supplied in the platform_device
|
||||
@@ -156,6 +158,14 @@ static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = readl(i2c->regs + S3C2410_IICCON);
|
||||
+
|
||||
+/* S3c2442 datasheet
|
||||
+ *
|
||||
+ * If the IICCON[5]=0, IICCON[4] does not operate correctly.
|
||||
+ * So, It is recommended that you should set IICCON[5]=1,
|
||||
+ * although you does not use the IIC interrupt.
|
||||
+ */
|
||||
+
|
||||
writel(tmp & ~S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
|
||||
}
|
||||
|
||||
@@ -501,6 +511,14 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int
|
||||
unsigned long timeout;
|
||||
int ret;
|
||||
|
||||
+ if (i2c->suspended) {
|
||||
+ dev_err(i2c->dev,
|
||||
+ "Hey I am still asleep (suspended: %d), retry later\n",
|
||||
+ i2c->suspended);
|
||||
+ ret = -EAGAIN;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
ret = s3c24xx_i2c_set_master(i2c);
|
||||
if (ret != 0) {
|
||||
dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
|
||||
@@ -885,6 +903,17 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
+
|
||||
+static int s3c24xx_i2c_suspend(struct platform_device *dev, pm_message_t state)
|
||||
+{
|
||||
+ struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
|
||||
+
|
||||
+ if (i2c != NULL)
|
||||
+ i2c->suspended++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int s3c24xx_i2c_resume(struct platform_device *dev)
|
||||
{
|
||||
struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
|
||||
@@ -892,6 +921,8 @@ static int s3c24xx_i2c_resume(struct platform_device *dev)
|
||||
if (i2c != NULL)
|
||||
s3c24xx_i2c_init(i2c);
|
||||
|
||||
+ i2c->suspended--;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -904,6 +935,7 @@ static int s3c24xx_i2c_resume(struct platform_device *dev)
|
||||
static struct platform_driver s3c2410_i2c_driver = {
|
||||
.probe = s3c24xx_i2c_probe,
|
||||
.remove = s3c24xx_i2c_remove,
|
||||
+ .suspend = s3c24xx_i2c_suspend,
|
||||
.resume = s3c24xx_i2c_resume,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -914,6 +946,7 @@ static struct platform_driver s3c2410_i2c_driver = {
|
||||
static struct platform_driver s3c2440_i2c_driver = {
|
||||
.probe = s3c24xx_i2c_probe,
|
||||
.remove = s3c24xx_i2c_remove,
|
||||
+ .suspend = s3c24xx_i2c_suspend,
|
||||
.resume = s3c24xx_i2c_resume,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
From 62bc0d984e5c2778e09094ba2e4d885903c6c35b Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:10 +0100
|
||||
Subject: [PATCH] resume-timers-wq.patch
|
||||
The initialization of clocks uses mutexes, but we execute the resume in
|
||||
an interrupt context. We therefore have to hand this task to a non-interrupt.
|
||||
|
||||
Adapted from a patch by Andy Green.
|
||||
---
|
||||
arch/arm/plat-s3c24xx/time.c | 18 +++++++++++++++++-
|
||||
1 files changed, 17 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
|
||||
index 766473b..f8d307b 100644
|
||||
--- a/arch/arm/plat-s3c24xx/time.c
|
||||
+++ b/arch/arm/plat-s3c24xx/time.c
|
||||
@@ -253,8 +253,24 @@ static void __init s3c2410_timer_init (void)
|
||||
setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
|
||||
}
|
||||
|
||||
+static void s3c2410_timer_resume_work(struct work_struct *work)
|
||||
+{
|
||||
+ s3c2410_timer_setup();
|
||||
+}
|
||||
+
|
||||
+static void s3c2410_timer_resume(void)
|
||||
+{
|
||||
+ static DECLARE_WORK(work, s3c2410_timer_resume_work);
|
||||
+ int res;
|
||||
+
|
||||
+ res = schedule_work(&work);
|
||||
+ if (!res)
|
||||
+ printk(KERN_ERR
|
||||
+ "s3c2410_timer_resume_work already queued ???\n");
|
||||
+}
|
||||
+
|
||||
struct sys_timer s3c24xx_timer = {
|
||||
.init = s3c2410_timer_init,
|
||||
.offset = s3c2410_gettimeoffset,
|
||||
- .resume = s3c2410_timer_setup
|
||||
+ .resume = s3c2410_timer_resume,
|
||||
};
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
From ee782e877d8c50f3ed775aee8934565699a5fc99 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:10 +0100
|
||||
Subject: [PATCH] s3c2410-bbt.patch
|
||||
[PATCH] Add Kconfig option to enable NAND bad-block-table support for s3c2410
|
||||
|
||||
This patch adds a new CONFIG_MTD_NAND_S3C2410_BBT which, if enabled,
|
||||
asks the mtd NAND core to use a bad-block table.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
drivers/mtd/nand/s3c2410.c | 6 +++++-
|
||||
include/asm-arm/plat-s3c/nand.h | 3 +++
|
||||
2 files changed, 8 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
|
||||
index 101b6b5..cd2e1da 100644
|
||||
--- a/drivers/mtd/nand/s3c2410.c
|
||||
+++ b/drivers/mtd/nand/s3c2410.c
|
||||
@@ -619,9 +619,13 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
|
||||
chip->select_chip = s3c2410_nand_select_chip;
|
||||
chip->chip_delay = 50;
|
||||
chip->priv = nmtd;
|
||||
- chip->options = 0;
|
||||
chip->controller = &info->controller;
|
||||
|
||||
+ if (set->flags & S3C2410_NAND_BBT)
|
||||
+ chip->options = NAND_USE_FLASH_BBT;
|
||||
+ else
|
||||
+ chip->options = 0;
|
||||
+
|
||||
switch (info->cpu_type) {
|
||||
case TYPE_S3C2410:
|
||||
chip->IO_ADDR_W = regs + S3C2410_NFDATA;
|
||||
diff --git a/include/asm-arm/plat-s3c/nand.h b/include/asm-arm/plat-s3c/nand.h
|
||||
index ad6bbe9..54f479e 100644
|
||||
--- a/include/asm-arm/plat-s3c/nand.h
|
||||
+++ b/include/asm-arm/plat-s3c/nand.h
|
||||
@@ -21,11 +21,14 @@
|
||||
* partitions = mtd partition list
|
||||
*/
|
||||
|
||||
+#define S3C2410_NAND_BBT 0x0001
|
||||
+
|
||||
struct s3c2410_nand_set {
|
||||
unsigned int disable_ecc : 1;
|
||||
|
||||
int nr_chips;
|
||||
int nr_partitions;
|
||||
+ unsigned int flags;
|
||||
char *name;
|
||||
int *nr_map;
|
||||
struct mtd_partition *partitions;
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,831 @@
|
|||
From 821c65f3420494eadf5260e48b54b9f59e6e865c Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:42 +0100
|
||||
Subject: [PATCH] gta01-core.patch
|
||||
This patch adds support for the FIC Neo1973 GTA01 machine type to the ARM port
|
||||
of the Linux kernel.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
MAINTAINERS | 8 +
|
||||
arch/arm/mach-s3c2410/Kconfig | 8 +
|
||||
arch/arm/mach-s3c2410/Makefile | 10 +
|
||||
arch/arm/mach-s3c2410/mach-gta01.c | 658 ++++++++++++++++++++++++++++++++++
|
||||
arch/arm/plat-s3c24xx/Kconfig | 5 +
|
||||
include/asm-arm/arch-s3c2410/gta01.h | 70 ++++
|
||||
6 files changed, 759 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/arm/mach-s3c2410/mach-gta01.c
|
||||
create mode 100644 include/asm-arm/arch-s3c2410/gta01.h
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 56a2f67..9c1a796 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1664,6 +1664,14 @@ P: Akinobu Mita
|
||||
M: akinobu.mita@gmail.com
|
||||
S: Supported
|
||||
|
||||
+FIC/OPENMOKO NEO1973 GSM PHONE
|
||||
+P: Harald Welte
|
||||
+M: laforge@openmoko.org
|
||||
+L: openmoko-kernel@lists.openmoko.org
|
||||
+W: http://wiki.openmoko.org/wiki/Kernel
|
||||
+W: http://wiki.openmoko.org/wiki/Neo1973
|
||||
+S: Maintained
|
||||
+
|
||||
FRAMEBUFFER LAYER
|
||||
P: Antonino Daplas
|
||||
M: adaplas@gmail.com
|
||||
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
|
||||
index cd3dc08..7e3a1a2 100644
|
||||
--- a/arch/arm/mach-s3c2410/Kconfig
|
||||
+++ b/arch/arm/mach-s3c2410/Kconfig
|
||||
@@ -117,5 +117,13 @@ config MACH_QT2410
|
||||
help
|
||||
Say Y here if you are using the Armzone QT2410
|
||||
|
||||
+config MACH_NEO1973_GTA01
|
||||
+ bool "FIC Neo1973 GSM Phone (GTA01 Hardware)"
|
||||
+ select CPU_S3C2410
|
||||
+ select MACH_NEO1973
|
||||
+ select SENSORS_PCF50606
|
||||
+ help
|
||||
+ Say Y here if you are using the FIC Neo1973 GSM Phone
|
||||
+
|
||||
endmenu
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
|
||||
index cabc13c..b73562f 100644
|
||||
--- a/arch/arm/mach-s3c2410/Makefile
|
||||
+++ b/arch/arm/mach-s3c2410/Makefile
|
||||
@@ -30,3 +30,13 @@ obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
|
||||
obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o
|
||||
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
|
||||
obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o
|
||||
+
|
||||
+# Common bits of machine support
|
||||
+
|
||||
+obj-$(CONFIG_SIMTEC_NOR) += nor-simtec.o
|
||||
+
|
||||
+# machine additions
|
||||
+
|
||||
+obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o
|
||||
+obj-$(CONFIG_MACH_NEO1973_GTA01)+= mach-gta01.o
|
||||
+
|
||||
diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
new file mode 100644
|
||||
index 0000000..e690ed7
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
@@ -0,0 +1,658 @@
|
||||
+/*
|
||||
+ * linux/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
+ *
|
||||
+ * S3C2410 Machine Support for the FIC Neo1973 GTA01
|
||||
+ *
|
||||
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of
|
||||
+ * the License, 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 <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/timer.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/serial_core.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+#include <linux/spi/spi_bitbang.h>
|
||||
+#include <linux/mmc/mmc.h>
|
||||
+#include <linux/mmc/host.h>
|
||||
+
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/nand.h>
|
||||
+#include <linux/mtd/nand_ecc.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+
|
||||
+#include <linux/mmc/host.h>
|
||||
+
|
||||
+#include <linux/pcf50606.h>
|
||||
+
|
||||
+#include <asm/mach/arch.h>
|
||||
+#include <asm/mach/map.h>
|
||||
+#include <asm/mach/irq.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/irq.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+
|
||||
+#include <asm/arch/regs-gpio.h>
|
||||
+#include <asm/arch/fb.h>
|
||||
+#include <asm/arch/spi.h>
|
||||
+#include <asm/arch/spi-gpio.h>
|
||||
+#include <asm/arch/usb-control.h>
|
||||
+
|
||||
+#include <asm/arch/gta01.h>
|
||||
+
|
||||
+#include <asm/plat-s3c/regs-serial.h>
|
||||
+#include <asm/plat-s3c/nand.h>
|
||||
+#include <asm/plat-s3c24xx/devs.h>
|
||||
+#include <asm/plat-s3c24xx/cpu.h>
|
||||
+#include <asm/plat-s3c24xx/pm.h>
|
||||
+#include <asm/plat-s3c24xx/udc.h>
|
||||
+
|
||||
+static struct map_desc gta01_iodesc[] __initdata = {
|
||||
+ {
|
||||
+ .virtual = 0xe0000000,
|
||||
+ .pfn = __phys_to_pfn(S3C2410_CS3+0x01000000),
|
||||
+ .length = SZ_1M,
|
||||
+ .type = MT_DEVICE
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#define UCON S3C2410_UCON_DEFAULT
|
||||
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
|
||||
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
|
||||
+
|
||||
+static struct s3c2410_uartcfg gta01_uartcfgs[] = {
|
||||
+ [0] = {
|
||||
+ .hwport = 0,
|
||||
+ .flags = 0,
|
||||
+ .ucon = UCON,
|
||||
+ .ulcon = ULCON,
|
||||
+ .ufcon = UFCON,
|
||||
+ },
|
||||
+ [1] = {
|
||||
+ .hwport = 1,
|
||||
+ .flags = 0,
|
||||
+ .ucon = UCON,
|
||||
+ .ulcon = ULCON,
|
||||
+ .ufcon = UFCON,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+/* PMU driver info */
|
||||
+
|
||||
+static int pmu_callback(struct device *dev, unsigned int feature,
|
||||
+ enum pmu_event event)
|
||||
+{
|
||||
+ switch (feature) {
|
||||
+ case PCF50606_FEAT_ACD:
|
||||
+ switch (event) {
|
||||
+ case PMU_EVT_INSERT:
|
||||
+ pcf50606_charge_fast(pcf50606_global, 1);
|
||||
+ break;
|
||||
+ case PMU_EVT_REMOVE:
|
||||
+ pcf50606_charge_fast(pcf50606_global, 0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct pcf50606_platform_data gta01_pcf_pdata = {
|
||||
+ .used_features = PCF50606_FEAT_EXTON |
|
||||
+ PCF50606_FEAT_MBC |
|
||||
+ PCF50606_FEAT_BBC |
|
||||
+ PCF50606_FEAT_RTC |
|
||||
+ PCF50606_FEAT_WDT |
|
||||
+ PCF50606_FEAT_CHGCUR |
|
||||
+ PCF50606_FEAT_BATVOLT |
|
||||
+ PCF50606_FEAT_BATTEMP,
|
||||
+ .onkey_seconds_required = 3,
|
||||
+ .cb = &pmu_callback,
|
||||
+ .r_fix_batt = 10000,
|
||||
+ .r_fix_batt_par = 10000,
|
||||
+ .r_sense_milli = 220,
|
||||
+ .rails = {
|
||||
+ [PCF50606_REGULATOR_D1REG] = {
|
||||
+ .name = "bt_3v15",
|
||||
+ .voltage = {
|
||||
+ .init = 3150,
|
||||
+ .max = 3150,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_D2REG] = {
|
||||
+ .name = "gl_2v5",
|
||||
+ .voltage = {
|
||||
+ .init = 2500,
|
||||
+ .max = 2500,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_D3REG] = {
|
||||
+ .name = "stby_1v8",
|
||||
+ .flags = PMU_VRAIL_F_SUSPEND_ON,
|
||||
+ .voltage = {
|
||||
+ .init = 1800,
|
||||
+ .max = 2100,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_DCD] = {
|
||||
+ .name = "gl_1v5",
|
||||
+ .voltage = {
|
||||
+ .init = 1500,
|
||||
+ .max = 1500,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_DCDE] = {
|
||||
+ .name = "io_3v3",
|
||||
+ .flags = PMU_VRAIL_F_SUSPEND_ON,
|
||||
+ .voltage = {
|
||||
+ .init = 3300,
|
||||
+ .max = 3330,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_DCUD] = {
|
||||
+ .name = "core_1v8",
|
||||
+ .flags = PMU_VRAIL_F_SUSPEND_ON,
|
||||
+ .voltage = {
|
||||
+ .init = 2100,
|
||||
+ .max = 2100,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_IOREG] = {
|
||||
+ .name = "codec_3v3",
|
||||
+ .voltage = {
|
||||
+ .init = 3300,
|
||||
+ .max = 3300,
|
||||
+ },
|
||||
+ },
|
||||
+ [PCF50606_REGULATOR_LPREG] = {
|
||||
+ .name = "lcm_3v3",
|
||||
+ .voltage = {
|
||||
+ .init = 3300,
|
||||
+ .max = 3300,
|
||||
+ },
|
||||
+ }
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void cfg_pmu_vrail(struct pmu_voltage_rail *vrail, char *name,
|
||||
+ unsigned int flags, unsigned int init,
|
||||
+ unsigned int max)
|
||||
+{
|
||||
+ vrail->name = name;
|
||||
+ vrail->flags = flags;
|
||||
+ vrail->voltage.init = init;
|
||||
+ vrail->voltage.max = max;
|
||||
+}
|
||||
+
|
||||
+static void mangle_pmu_pdata_by_system_rev(void)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ gta01_pcf_pdata.used_features |= PCF50606_FEAT_ACD;
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ gta01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG]
|
||||
+ .name = "user1";
|
||||
+ gta01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG]
|
||||
+ .flags &= ~PMU_VRAIL_F_SUSPEND_ON;
|
||||
+ gta01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG]
|
||||
+ .flags = PMU_VRAIL_F_UNUSED;
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCUD],
|
||||
+ "core_1v8", PMU_VRAIL_F_SUSPEND_ON, 1800, 1800);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D1REG],
|
||||
+ "vrf_3v", 0, 3000, 3000);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG],
|
||||
+ "vtcxo_2v8", 0, 2800, 2800);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCD],
|
||||
+ "gl_3v5", 0, 3500, 3500);
|
||||
+ break;
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D1REG],
|
||||
+ "vrf_3v", 0, 3000, 3000);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D2REG],
|
||||
+ "sd_3v3", 0, 3300, 3300);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_D3REG],
|
||||
+ "codec_3v3", 0, 3300, 3300);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCD],
|
||||
+ "gpsio_3v3", 0, 3300, 3300);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_DCUD],
|
||||
+ "core_1v8", PMU_VRAIL_F_SUSPEND_ON, 1800, 1800);
|
||||
+ cfg_pmu_vrail(>a01_pcf_pdata.rails[PCF50606_REGULATOR_IOREG],
|
||||
+ "vtcxo_2v8", 0, 2800, 2800);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct resource gta01_pmu_resources[] = {
|
||||
+ [0] = {
|
||||
+ .flags = IORESOURCE_IRQ,
|
||||
+ .start = GTA01_IRQ_PCF50606,
|
||||
+ .end = GTA01_IRQ_PCF50606,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device gta01_pmu_dev = {
|
||||
+ .name = "pcf50606",
|
||||
+ .num_resources = ARRAY_SIZE(gta01_pmu_resources),
|
||||
+ .resource = gta01_pmu_resources,
|
||||
+ .dev = {
|
||||
+ .platform_data = >a01_pcf_pdata,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+/* LCD driver info */
|
||||
+
|
||||
+/* Configuration for 480x640 toppoly TD028TTEC1.
|
||||
+ * Do not mark this as __initdata or it will break! */
|
||||
+static struct s3c2410fb_display gta01_displays[] = {
|
||||
+ {
|
||||
+ .type = S3C2410_LCDCON1_TFT,
|
||||
+ .width = 43,
|
||||
+ .height = 58,
|
||||
+ .xres = 480,
|
||||
+ .yres = 640,
|
||||
+ .bpp = 16,
|
||||
+
|
||||
+ .pixclock = 40000, /* HCLK/4 */
|
||||
+ .left_margin = 104,
|
||||
+ .right_margin = 8,
|
||||
+ .hsync_len = 8,
|
||||
+ .upper_margin = 2,
|
||||
+ .lower_margin = 16,
|
||||
+ .vsync_len = 2,
|
||||
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
|
||||
+ S3C2410_LCDCON5_INVVCLK |
|
||||
+ S3C2410_LCDCON5_INVVLINE |
|
||||
+ S3C2410_LCDCON5_INVVFRAME |
|
||||
+ S3C2410_LCDCON5_PWREN |
|
||||
+ S3C2410_LCDCON5_HWSWP,
|
||||
+ },
|
||||
+ {
|
||||
+ .type = S3C2410_LCDCON1_TFT,
|
||||
+ .width = 43,
|
||||
+ .height = 58,
|
||||
+ .xres = 480,
|
||||
+ .yres = 640,
|
||||
+ .bpp = 32,
|
||||
+
|
||||
+ .pixclock = 40000, /* HCLK/4 */
|
||||
+ .left_margin = 104,
|
||||
+ .right_margin = 8,
|
||||
+ .hsync_len = 8,
|
||||
+ .upper_margin = 2,
|
||||
+ .lower_margin = 16,
|
||||
+ .vsync_len = 2,
|
||||
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
|
||||
+ S3C2410_LCDCON5_INVVCLK |
|
||||
+ S3C2410_LCDCON5_INVVLINE |
|
||||
+ S3C2410_LCDCON5_INVVFRAME |
|
||||
+ S3C2410_LCDCON5_PWREN |
|
||||
+ S3C2410_LCDCON5_HWSWP,
|
||||
+ },
|
||||
+ {
|
||||
+ .type = S3C2410_LCDCON1_TFT,
|
||||
+ .width = 43,
|
||||
+ .height = 58,
|
||||
+ .xres = 240,
|
||||
+ .yres = 320,
|
||||
+ .bpp = 16,
|
||||
+
|
||||
+ .pixclock = 40000, /* HCLK/4 */
|
||||
+ .left_margin = 104,
|
||||
+ .right_margin = 8,
|
||||
+ .hsync_len = 8,
|
||||
+ .upper_margin = 2,
|
||||
+ .lower_margin = 16,
|
||||
+ .vsync_len = 2,
|
||||
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
|
||||
+ S3C2410_LCDCON5_INVVCLK |
|
||||
+ S3C2410_LCDCON5_INVVLINE |
|
||||
+ S3C2410_LCDCON5_INVVFRAME |
|
||||
+ S3C2410_LCDCON5_PWREN |
|
||||
+ S3C2410_LCDCON5_HWSWP,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct s3c2410fb_mach_info gta01_lcd_cfg __initdata = {
|
||||
+ .displays = gta01_displays,
|
||||
+ .num_displays = ARRAY_SIZE(gta01_displays),
|
||||
+ .default_display = 0,
|
||||
+
|
||||
+ .lpcsel = ((0xCE6) & ~7) | 1<<4,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device *gta01_devices[] __initdata = {
|
||||
+ &s3c_device_usb,
|
||||
+ &s3c_device_lcd,
|
||||
+ &s3c_device_wdt,
|
||||
+ &s3c_device_i2c,
|
||||
+ &s3c_device_iis,
|
||||
+ &s3c_device_sdi,
|
||||
+ &s3c_device_usbgadget,
|
||||
+ &s3c_device_nand,
|
||||
+};
|
||||
+
|
||||
+static struct s3c2410_nand_set gta01_nand_sets[] = {
|
||||
+ [0] = {
|
||||
+ .name = "neo1973-nand",
|
||||
+ .nr_chips = 1,
|
||||
+ .flags = S3C2410_NAND_BBT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct s3c2410_platform_nand gta01_nand_info = {
|
||||
+ .tacls = 20,
|
||||
+ .twrph0 = 60,
|
||||
+ .twrph1 = 20,
|
||||
+ .nr_sets = ARRAY_SIZE(gta01_nand_sets),
|
||||
+ .sets = gta01_nand_sets,
|
||||
+};
|
||||
+
|
||||
+static void gta01_udc_command(enum s3c2410_udc_cmd_e cmd)
|
||||
+{
|
||||
+ printk(KERN_DEBUG "%s(%d)\n", __func__, cmd);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case S3C2410_UDC_P_ENABLE:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_USB_PULLUP, 1);
|
||||
+ break;
|
||||
+ case S3C2410_UDC_P_DISABLE:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_USB_PULLUP, 0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* use a work queue, since I2C API inherently schedules
|
||||
+ * and we get called in hardirq context from UDC driver */
|
||||
+
|
||||
+struct vbus_draw {
|
||||
+ struct work_struct work;
|
||||
+ int ma;
|
||||
+};
|
||||
+static struct vbus_draw gta01_udc_vbus_drawer;
|
||||
+
|
||||
+static void __gta01_udc_vbus_draw(struct work_struct *work)
|
||||
+{
|
||||
+ /* this is a fix to work around boot-time ordering problems if the
|
||||
+ * s3c2410_udc is initialized before the pcf50606 driver has defined
|
||||
+ * pcf50606_global */
|
||||
+ if (!pcf50606_global)
|
||||
+ return;
|
||||
+
|
||||
+ if (gta01_udc_vbus_drawer.ma >= 500) {
|
||||
+ /* enable fast charge */
|
||||
+ printk(KERN_DEBUG "udc: enabling fast charge\n");
|
||||
+ pcf50606_charge_fast(pcf50606_global, 1);
|
||||
+ } else {
|
||||
+ /* disable fast charge */
|
||||
+ printk(KERN_DEBUG "udc: disabling fast charge\n");
|
||||
+ pcf50606_charge_fast(pcf50606_global, 0);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void gta01_udc_vbus_draw(unsigned int ma)
|
||||
+{
|
||||
+ gta01_udc_vbus_drawer.ma = ma;
|
||||
+ schedule_work(>a01_udc_vbus_drawer.work);
|
||||
+}
|
||||
+
|
||||
+static struct s3c2410_udc_mach_info gta01_udc_cfg = {
|
||||
+ .vbus_draw = gta01_udc_vbus_draw,
|
||||
+};
|
||||
+
|
||||
+/* SPI */
|
||||
+
|
||||
+static struct spi_board_info gta01_spi_board_info[] = {
|
||||
+ {
|
||||
+ .modalias = "jbt6k74",
|
||||
+ /* platform_data */
|
||||
+ /* controller_data */
|
||||
+ /* irq */
|
||||
+ .max_speed_hz = 10 * 1000 * 1000,
|
||||
+ .bus_num = 1,
|
||||
+ /* chip_select */
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
|
||||
+{
|
||||
+ switch (cs) {
|
||||
+ case BITBANG_CS_ACTIVE:
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPG3, 0);
|
||||
+ break;
|
||||
+ case BITBANG_CS_INACTIVE:
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPG3, 1);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct s3c2410_spigpio_info spi_gpio_cfg = {
|
||||
+ .pin_clk = S3C2410_GPG7,
|
||||
+ .pin_mosi = S3C2410_GPG6,
|
||||
+ .pin_miso = S3C2410_GPG5,
|
||||
+ .board_size = ARRAY_SIZE(gta01_spi_board_info),
|
||||
+ .board_info = gta01_spi_board_info,
|
||||
+ .chip_select = &spi_gpio_cs,
|
||||
+};
|
||||
+
|
||||
+static struct resource s3c_spi_lcm_resource[] = {
|
||||
+ [0] = {
|
||||
+ .start = S3C2410_GPG3,
|
||||
+ .end = S3C2410_GPG3,
|
||||
+ },
|
||||
+ [1] = {
|
||||
+ .start = S3C2410_GPG5,
|
||||
+ .end = S3C2410_GPG5,
|
||||
+ },
|
||||
+ [2] = {
|
||||
+ .start = S3C2410_GPG6,
|
||||
+ .end = S3C2410_GPG6,
|
||||
+ },
|
||||
+ [3] = {
|
||||
+ .start = S3C2410_GPG7,
|
||||
+ .end = S3C2410_GPG7,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device s3c_device_spi_lcm = {
|
||||
+ .name = "s3c24xx-spi-gpio",
|
||||
+ .id = 1,
|
||||
+ .num_resources = ARRAY_SIZE(s3c_spi_lcm_resource),
|
||||
+ .resource = s3c_spi_lcm_resource,
|
||||
+ .dev = {
|
||||
+ .platform_data = &spi_gpio_cfg,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct gta01bl_machinfo backlight_machinfo = {
|
||||
+ .default_intensity = 1,
|
||||
+ .max_intensity = 1,
|
||||
+ .limit_mask = 1,
|
||||
+};
|
||||
+
|
||||
+static struct resource gta01_bl_resources[] = {
|
||||
+ [0] = {
|
||||
+ .start = GTA01_GPIO_BACKLIGHT,
|
||||
+ .end = GTA01_GPIO_BACKLIGHT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device gta01_bl_dev = {
|
||||
+ .name = "gta01-bl",
|
||||
+ .num_resources = ARRAY_SIZE(gta01_bl_resources),
|
||||
+ .resource = gta01_bl_resources,
|
||||
+ .dev = {
|
||||
+ .platform_data = &backlight_machinfo,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct resource gta01_led_resources[] = {
|
||||
+ [0] = {
|
||||
+ .start = GTA01_GPIO_VIBRATOR_ON,
|
||||
+ .end = GTA01_GPIO_VIBRATOR_ON,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device gta01_led_dev = {
|
||||
+ .name = "neo1973-vibrator",
|
||||
+ .num_resources = ARRAY_SIZE(gta01_led_resources),
|
||||
+ .resource = gta01_led_resources,
|
||||
+};
|
||||
+
|
||||
+static struct resource gta01_button_resources[] = {
|
||||
+ [0] = {
|
||||
+ .start = GTA01_GPIO_AUX_KEY,
|
||||
+ .end = GTA01_GPIO_AUX_KEY,
|
||||
+ },
|
||||
+ [1] = {
|
||||
+ .start = GTA01_GPIO_HOLD_KEY,
|
||||
+ .end = GTA01_GPIO_HOLD_KEY,
|
||||
+ },
|
||||
+ [2] = {
|
||||
+ .start = GTA01_GPIO_JACK_INSERT,
|
||||
+ .end = GTA01_GPIO_JACK_INSERT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device gta01_button_dev = {
|
||||
+ .name = "neo1973-button",
|
||||
+ .num_resources = ARRAY_SIZE(gta01_button_resources),
|
||||
+ .resource = gta01_button_resources,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device gta01_pm_gsm_dev = {
|
||||
+ .name = "neo1973-pm-gsm",
|
||||
+};
|
||||
+
|
||||
+/* USB */
|
||||
+static struct s3c2410_hcd_info gta01_usb_info = {
|
||||
+ .port[0] = {
|
||||
+ .flags = S3C_HCDFLG_USED,
|
||||
+ },
|
||||
+ .port[1] = {
|
||||
+ .flags = 0,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void __init gta01_map_io(void)
|
||||
+{
|
||||
+ s3c24xx_init_io(gta01_iodesc, ARRAY_SIZE(gta01_iodesc));
|
||||
+ s3c24xx_init_clocks(12*1000*1000);
|
||||
+ s3c24xx_init_uarts(gta01_uartcfgs, ARRAY_SIZE(gta01_uartcfgs));
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t gta01_modem_irq(int irq, void *param)
|
||||
+{
|
||||
+ printk(KERN_DEBUG "modem wakeup interrupt\n");
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void __init gta01_machine_init(void)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ if (system_rev == GTA01v4_SYSTEM_REV ||
|
||||
+ system_rev == GTA01Bv2_SYSTEM_REV ||
|
||||
+ system_rev == GTA01Bv3_SYSTEM_REV ||
|
||||
+ system_rev == GTA01Bv4_SYSTEM_REV) {
|
||||
+ gta01_udc_cfg.udc_command = gta01_udc_command;
|
||||
+ }
|
||||
+
|
||||
+ s3c_device_usb.dev.platform_data = >a01_usb_info;
|
||||
+ s3c_device_nand.dev.platform_data = >a01_nand_info;
|
||||
+
|
||||
+ s3c24xx_fb_set_platdata(>a01_lcd_cfg);
|
||||
+
|
||||
+ INIT_WORK(>a01_udc_vbus_drawer.work, __gta01_udc_vbus_draw);
|
||||
+ s3c24xx_udc_set_platdata(>a01_udc_cfg);
|
||||
+
|
||||
+ /* Set LCD_RESET / XRES to high */
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPC6, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPC6, 1);
|
||||
+
|
||||
+ /* SPI chip select is gpio output */
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPG3, 1);
|
||||
+ platform_device_register(&s3c_device_spi_lcm);
|
||||
+
|
||||
+ platform_device_register(>a01_bl_dev);
|
||||
+ platform_device_register(>a01_button_dev);
|
||||
+ platform_device_register(>a01_pm_gsm_dev);
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ /* just use the default (GTA01_IRQ_PCF50606) */
|
||||
+ break;
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ /* just use the default (GTA01_IRQ_PCF50606) */
|
||||
+ gta01_led_resources[0].start =
|
||||
+ gta01_led_resources[0].end = GTA01Bv2_GPIO_VIBRATOR_ON;
|
||||
+ break;
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ gta01_pmu_resources[0].start =
|
||||
+ gta01_pmu_resources[0].end = GTA01Bv4_IRQ_PCF50606;
|
||||
+ gta01_led_resources[0].start =
|
||||
+ gta01_led_resources[0].end = GTA01Bv4_GPIO_VIBRATOR_ON;
|
||||
+ break;
|
||||
+ }
|
||||
+ mangle_pmu_pdata_by_system_rev();
|
||||
+ platform_device_register(>a01_pmu_dev);
|
||||
+ platform_device_register(>a01_led_dev);
|
||||
+
|
||||
+ platform_add_devices(gta01_devices, ARRAY_SIZE(gta01_devices));
|
||||
+
|
||||
+ s3c2410_pm_init();
|
||||
+
|
||||
+ set_irq_type(GTA01_IRQ_MODEM, IRQT_RISING);
|
||||
+ rc = request_irq(GTA01_IRQ_MODEM, gta01_modem_irq, IRQF_DISABLED,
|
||||
+ "modem", NULL);
|
||||
+ if (!rc)
|
||||
+ printk(KERN_ERR "GTA01: can't request GSM modem wakeup IRQ\n");
|
||||
+ enable_irq_wake(GTA01_IRQ_MODEM);
|
||||
+}
|
||||
+
|
||||
+MACHINE_START(NEO1973_GTA01, "GTA01")
|
||||
+ .phys_io = S3C2410_PA_UART,
|
||||
+ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
|
||||
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
|
||||
+ .map_io = gta01_map_io,
|
||||
+ .init_irq = s3c24xx_init_irq,
|
||||
+ .init_machine = gta01_machine_init,
|
||||
+ .timer = &s3c24xx_timer,
|
||||
+MACHINE_END
|
||||
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
|
||||
index b66fb3c..7ee4b82 100644
|
||||
--- a/arch/arm/plat-s3c24xx/Kconfig
|
||||
+++ b/arch/arm/plat-s3c24xx/Kconfig
|
||||
@@ -46,4 +46,9 @@ config MACH_SMDK
|
||||
help
|
||||
Common machine code for SMDK2410 and SMDK2440
|
||||
|
||||
+config MACH_NEO1973
|
||||
+ bool
|
||||
+ help
|
||||
+ Common machine code for Neo1973 hardware
|
||||
+
|
||||
endif
|
||||
diff --git a/include/asm-arm/arch-s3c2410/gta01.h b/include/asm-arm/arch-s3c2410/gta01.h
|
||||
new file mode 100644
|
||||
index 0000000..1cc2099
|
||||
--- /dev/null
|
||||
+++ b/include/asm-arm/arch-s3c2410/gta01.h
|
||||
@@ -0,0 +1,70 @@
|
||||
+#ifndef _GTA01_H
|
||||
+#define _GTA01_H
|
||||
+
|
||||
+#include <asm/arch/regs-gpio.h>
|
||||
+#include <asm/arch/irqs.h>
|
||||
+
|
||||
+/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
|
||||
+#define GTA01v3_SYSTEM_REV 0x00000130
|
||||
+#define GTA01v4_SYSTEM_REV 0x00000140
|
||||
+#define GTA01Bv2_SYSTEM_REV 0x00000220
|
||||
+#define GTA01Bv3_SYSTEM_REV 0x00000230
|
||||
+#define GTA01Bv4_SYSTEM_REV 0x00000240
|
||||
+
|
||||
+/* Backlight */
|
||||
+struct gta01bl_machinfo {
|
||||
+ unsigned int default_intensity;
|
||||
+ unsigned int max_intensity;
|
||||
+ unsigned int limit_mask;
|
||||
+};
|
||||
+
|
||||
+/* Definitions common to all revisions */
|
||||
+#define GTA01_GPIO_BACKLIGHT S3C2410_GPB0
|
||||
+#define GTA01_GPIO_GPS_PWRON S3C2410_GPB1
|
||||
+#define GTA01_GPIO_MODEM_RST S3C2410_GPB6
|
||||
+#define GTA01_GPIO_MODEM_ON S3C2410_GPB7
|
||||
+#define GTA01_GPIO_LCD_RESET S3C2410_GPC6
|
||||
+#define GTA01_GPIO_PMU_IRQ S3C2410_GPG8
|
||||
+#define GTA01_GPIO_JACK_INSERT S3C2410_GPF4
|
||||
+#define GTA01_GPIO_nSD_DETECT S3C2410_GPF5
|
||||
+#define GTA01_GPIO_AUX_KEY S3C2410_GPF6
|
||||
+#define GTA01_GPIO_HOLD_KEY S3C2410_GPF7
|
||||
+#define GTA01_GPIO_VIBRATOR_ON S3C2410_GPG11
|
||||
+
|
||||
+#define GTA01_IRQ_MODEM IRQ_EINT1
|
||||
+#define GTA01_IRQ_JACK_INSERT IRQ_EINT4
|
||||
+#define GTA01_IRQ_nSD_DETECT IRQ_EINT5
|
||||
+#define GTA01_IRQ_AUX_KEY IRQ_EINT6
|
||||
+#define GTA01_IRQ_PCF50606 IRQ_EINT16
|
||||
+
|
||||
+/* GTA01v3 */
|
||||
+#define GTA01v3_GPIO_nGSM_EN S3C2410_GPG9
|
||||
+
|
||||
+/* GTA01v4 */
|
||||
+#define GTA01_GPIO_MODEM_DNLOAD S3C2410_GPG0
|
||||
+
|
||||
+/* GTA01Bv2 */
|
||||
+#define GTA01Bv2_GPIO_nGSM_EN S3C2410_GPF2
|
||||
+#define GTA01Bv2_GPIO_VIBRATOR_ON S3C2410_GPB10
|
||||
+
|
||||
+/* GTA01Bv3 */
|
||||
+#define GTA01_GPIO_GPS_EN_3V3 S3C2410_GPG9
|
||||
+
|
||||
+#define GTA01_GPIO_SDMMC_ON S3C2410_GPB2
|
||||
+#define GTA01_GPIO_BT_EN S3C2410_GPB5
|
||||
+#define GTA01_GPIO_AB_DETECT S3C2410_GPB8
|
||||
+#define GTA01_GPIO_USB_PULLUP S3C2410_GPB9
|
||||
+#define GTA01_GPIO_USB_ATTACH S3C2410_GPB10
|
||||
+
|
||||
+#define GTA01_GPIO_GPS_EN_2V8 S3C2410_GPG9
|
||||
+#define GTA01_GPIO_GPS_EN_3V S3C2410_GPG10
|
||||
+#define GTA01_GPIO_GPS_RESET S3C2410_GPC0
|
||||
+
|
||||
+/* GTA01Bv4 */
|
||||
+#define GTA01Bv4_GPIO_nNAND_WP S3C2410_GPA16
|
||||
+#define GTA01Bv4_GPIO_VIBRATOR_ON S3C2410_GPB3
|
||||
+#define GTA01Bv4_GPIO_PMU_IRQ S3C2410_GPG1
|
||||
+
|
||||
+#define GTA01Bv4_IRQ_PCF50606 IRQ_EINT9
|
||||
+
|
||||
+#endif /* _GTA01_H */
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,748 @@
|
|||
From 5b0814282e6878f7f2f07b98cc8b0128e7ea423d Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:48 +0100
|
||||
Subject: [PATCH] gta01-jbt6k74.patch
|
||||
This driver adds support for the SPI-based control interface of the LCM (LCD
|
||||
Panel) found on the FIC GTA01 hardware.
|
||||
|
||||
The specific panel in this hardware is a TPO TD028TTEC1, but the driver should
|
||||
be able to drive any other diplay based on the JBT6K74-AS controller ASIC.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
arch/arm/mach-s3c2410/Kconfig | 1 +
|
||||
drivers/video/display/Kconfig | 11 +
|
||||
drivers/video/display/Makefile | 1 +
|
||||
drivers/video/display/jbt6k74.c | 678 +++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 691 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/video/display/jbt6k74.c
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
|
||||
index 7e3a1a2..58519e6 100644
|
||||
--- a/arch/arm/mach-s3c2410/Kconfig
|
||||
+++ b/arch/arm/mach-s3c2410/Kconfig
|
||||
@@ -114,6 +114,7 @@ config MACH_VR1000
|
||||
config MACH_QT2410
|
||||
bool "QT2410"
|
||||
select CPU_S3C2410
|
||||
+ select DISPLAY_JBT6K74
|
||||
help
|
||||
Say Y here if you are using the Armzone QT2410
|
||||
|
||||
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
|
||||
index f99af93..f0da483 100644
|
||||
--- a/drivers/video/display/Kconfig
|
||||
+++ b/drivers/video/display/Kconfig
|
||||
@@ -21,4 +21,15 @@ config DISPLAY_SUPPORT
|
||||
comment "Display hardware drivers"
|
||||
depends on DISPLAY_SUPPORT
|
||||
|
||||
+config DISPLAY_JBT6K74
|
||||
+ tristate "TPO JBT6K74-AS TFT display ASIC control interface"
|
||||
+ depends on SPI_MASTER && SYSFS
|
||||
+ help
|
||||
+ SPI driver for the control interface of TFT panels containing
|
||||
+ the TPO JBT6K74-AS controller ASIC, such as the TPO TD028TTEC1
|
||||
+ TFT diplay module used in the FIC/OpenMoko Neo1973 GSM phones.
|
||||
+
|
||||
+ The control interface is required for display operation, as it
|
||||
+ controls power management, display timing and gamma calibration.
|
||||
+
|
||||
endmenu
|
||||
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
|
||||
index c0ea832..011b69d 100644
|
||||
--- a/drivers/video/display/Makefile
|
||||
+++ b/drivers/video/display/Makefile
|
||||
@@ -3,4 +3,5 @@
|
||||
display-objs := display-sysfs.o
|
||||
|
||||
obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
|
||||
+obj-$(CONFIG_DISPLAY_JBT6K74) += jbt6k74.o
|
||||
|
||||
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
|
||||
new file mode 100644
|
||||
index 0000000..d021d7e
|
||||
--- /dev/null
|
||||
+++ b/drivers/video/display/jbt6k74.c
|
||||
@@ -0,0 +1,678 @@
|
||||
+/* Linux kernel driver for the tpo JBT6K74-AS LCM ASIC
|
||||
+ *
|
||||
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>,
|
||||
+ * Stefan Schmidt <stefan@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of
|
||||
+ * the License, 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 <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/delay.h>
|
||||
+
|
||||
+#include <linux/spi/spi.h>
|
||||
+
|
||||
+enum jbt_register {
|
||||
+ JBT_REG_SLEEP_IN = 0x10,
|
||||
+ JBT_REG_SLEEP_OUT = 0x11,
|
||||
+
|
||||
+ JBT_REG_DISPLAY_OFF = 0x28,
|
||||
+ JBT_REG_DISPLAY_ON = 0x29,
|
||||
+
|
||||
+ JBT_REG_RGB_FORMAT = 0x3a,
|
||||
+ JBT_REG_QUAD_RATE = 0x3b,
|
||||
+
|
||||
+ JBT_REG_POWER_ON_OFF = 0xb0,
|
||||
+ JBT_REG_BOOSTER_OP = 0xb1,
|
||||
+ JBT_REG_BOOSTER_MODE = 0xb2,
|
||||
+ JBT_REG_BOOSTER_FREQ = 0xb3,
|
||||
+ JBT_REG_OPAMP_SYSCLK = 0xb4,
|
||||
+ JBT_REG_VSC_VOLTAGE = 0xb5,
|
||||
+ JBT_REG_VCOM_VOLTAGE = 0xb6,
|
||||
+ JBT_REG_EXT_DISPL = 0xb7,
|
||||
+ JBT_REG_OUTPUT_CONTROL = 0xb8,
|
||||
+ JBT_REG_DCCLK_DCEV = 0xb9,
|
||||
+ JBT_REG_DISPLAY_MODE1 = 0xba,
|
||||
+ JBT_REG_DISPLAY_MODE2 = 0xbb,
|
||||
+ JBT_REG_DISPLAY_MODE = 0xbc,
|
||||
+ JBT_REG_ASW_SLEW = 0xbd,
|
||||
+ JBT_REG_DUMMY_DISPLAY = 0xbe,
|
||||
+ JBT_REG_DRIVE_SYSTEM = 0xbf,
|
||||
+
|
||||
+ JBT_REG_SLEEP_OUT_FR_A = 0xc0,
|
||||
+ JBT_REG_SLEEP_OUT_FR_B = 0xc1,
|
||||
+ JBT_REG_SLEEP_OUT_FR_C = 0xc2,
|
||||
+ JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
|
||||
+ JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
|
||||
+ JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
|
||||
+ JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
|
||||
+
|
||||
+ JBT_REG_GAMMA1_FINE_1 = 0xc7,
|
||||
+ JBT_REG_GAMMA1_FINE_2 = 0xc8,
|
||||
+ JBT_REG_GAMMA1_INCLINATION = 0xc9,
|
||||
+ JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
|
||||
+
|
||||
+ /* VGA */
|
||||
+ JBT_REG_BLANK_CONTROL = 0xcf,
|
||||
+ JBT_REG_BLANK_TH_TV = 0xd0,
|
||||
+ JBT_REG_CKV_ON_OFF = 0xd1,
|
||||
+ JBT_REG_CKV_1_2 = 0xd2,
|
||||
+ JBT_REG_OEV_TIMING = 0xd3,
|
||||
+ JBT_REG_ASW_TIMING_1 = 0xd4,
|
||||
+ JBT_REG_ASW_TIMING_2 = 0xd5,
|
||||
+
|
||||
+ /* QVGA */
|
||||
+ JBT_REG_BLANK_CONTROL_QVGA = 0xd6,
|
||||
+ JBT_REG_BLANK_TH_TV_QVGA = 0xd7,
|
||||
+ JBT_REG_CKV_ON_OFF_QVGA = 0xd8,
|
||||
+ JBT_REG_CKV_1_2_QVGA = 0xd9,
|
||||
+ JBT_REG_OEV_TIMING_QVGA = 0xde,
|
||||
+ JBT_REG_ASW_TIMING_1_QVGA = 0xdf,
|
||||
+ JBT_REG_ASW_TIMING_2_QVGA = 0xe0,
|
||||
+
|
||||
+
|
||||
+ JBT_REG_HCLOCK_VGA = 0xec,
|
||||
+ JBT_REG_HCLOCK_QVGA = 0xed,
|
||||
+
|
||||
+};
|
||||
+
|
||||
+enum jbt_state {
|
||||
+ JBT_STATE_DEEP_STANDBY,
|
||||
+ JBT_STATE_SLEEP,
|
||||
+ JBT_STATE_NORMAL,
|
||||
+ JBT_STATE_QVGA_NORMAL,
|
||||
+};
|
||||
+
|
||||
+static const char *jbt_state_names[] = {
|
||||
+ [JBT_STATE_DEEP_STANDBY] = "deep-standby",
|
||||
+ [JBT_STATE_SLEEP] = "sleep",
|
||||
+ [JBT_STATE_NORMAL] = "normal",
|
||||
+ [JBT_STATE_QVGA_NORMAL] = "qvga-normal",
|
||||
+};
|
||||
+
|
||||
+struct jbt_info {
|
||||
+ enum jbt_state state, last_state;
|
||||
+ struct spi_device *spi_dev;
|
||||
+ struct mutex lock; /* protects tx_buf and reg_cache */
|
||||
+ u16 tx_buf[8];
|
||||
+ u16 reg_cache[0xEE];
|
||||
+};
|
||||
+
|
||||
+#define JBT_COMMAND 0x000
|
||||
+#define JBT_DATA 0x100
|
||||
+
|
||||
+static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ mutex_lock(&jbt->lock);
|
||||
+
|
||||
+ jbt->tx_buf[0] = JBT_COMMAND | reg;
|
||||
+ rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf,
|
||||
+ 1*sizeof(u16));
|
||||
+ if (rc == 0)
|
||||
+ jbt->reg_cache[reg] = 0;
|
||||
+
|
||||
+ mutex_unlock(&jbt->lock);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int jbt_reg_write(struct jbt_info *jbt, u8 reg, u8 data)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ mutex_lock(&jbt->lock);
|
||||
+
|
||||
+ jbt->tx_buf[0] = JBT_COMMAND | reg;
|
||||
+ jbt->tx_buf[1] = JBT_DATA | data;
|
||||
+ rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf,
|
||||
+ 2*sizeof(u16));
|
||||
+ if (rc == 0)
|
||||
+ jbt->reg_cache[reg] = data;
|
||||
+
|
||||
+ mutex_unlock(&jbt->lock);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int jbt_reg_write16(struct jbt_info *jbt, u8 reg, u16 data)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ mutex_lock(&jbt->lock);
|
||||
+
|
||||
+ jbt->tx_buf[0] = JBT_COMMAND | reg;
|
||||
+ jbt->tx_buf[1] = JBT_DATA | (data >> 8);
|
||||
+ jbt->tx_buf[2] = JBT_DATA | (data & 0xff);
|
||||
+
|
||||
+ rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf,
|
||||
+ 3*sizeof(u16));
|
||||
+ if (rc == 0)
|
||||
+ jbt->reg_cache[reg] = data;
|
||||
+
|
||||
+ mutex_unlock(&jbt->lock);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int jbt_init_regs(struct jbt_info *jbt, int qvga)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n", qvga ? 'Q' : ' ');
|
||||
+
|
||||
+ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE2, 0x00);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_RGB_FORMAT, 0x60);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_DRIVE_SYSTEM, 0x10);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_OP, 0x56);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_MODE, 0x33);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_OPAMP_SYSCLK, 0x02);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_VSC_VOLTAGE, 0x2b);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_VCOM_VOLTAGE, 0x40);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_EXT_DISPL, 0x03);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_DCCLK_DCEV, 0x04);
|
||||
+ /*
|
||||
+ * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
|
||||
+ * to avoid red / blue flicker
|
||||
+ */
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_ASW_SLEW, 0x04);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0x00);
|
||||
+
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_A, 0x11);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_B, 0x11);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_C, 0x11);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
|
||||
+
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_GAMMA1_FINE_1, 0x5533);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_FINE_2, 0x00);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_INCLINATION, 0x00);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
|
||||
+
|
||||
+ if (!qvga) {
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_VGA, 0x1f0);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL, 0x02);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804);
|
||||
+
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF, 0x01);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2, 0x0000);
|
||||
+
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING, 0x0d0e);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1, 0x11a4);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2, 0x0e);
|
||||
+ } else {
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL_QVGA, 0x02);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV_QVGA, 0x0804);
|
||||
+
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF_QVGA, 0x01);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2_QVGA, 0x0008);
|
||||
+
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING_QVGA, 0x050a);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1_QVGA, 0x0a19);
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2_QVGA, 0x0a);
|
||||
+ }
|
||||
+
|
||||
+ return rc ? -EIO : 0;
|
||||
+}
|
||||
+
|
||||
+static int standby_to_sleep(struct jbt_info *jbt)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ /* three times command zero */
|
||||
+ rc = jbt_reg_write_nodata(jbt, 0x00);
|
||||
+ mdelay(1);
|
||||
+ rc |= jbt_reg_write_nodata(jbt, 0x00);
|
||||
+ mdelay(1);
|
||||
+ rc |= jbt_reg_write_nodata(jbt, 0x00);
|
||||
+ mdelay(1);
|
||||
+
|
||||
+ /* deep standby out */
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x17);
|
||||
+
|
||||
+ return rc ? -EIO : 0;
|
||||
+}
|
||||
+
|
||||
+static int sleep_to_normal(struct jbt_info *jbt)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */
|
||||
+ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80);
|
||||
+
|
||||
+ /* Quad mode off */
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00);
|
||||
+
|
||||
+ /* AVDD on, XVDD on */
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16);
|
||||
+
|
||||
+ /* Output control */
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9);
|
||||
+
|
||||
+ /* Sleep mode off */
|
||||
+ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT);
|
||||
+
|
||||
+ /* initialize register set */
|
||||
+ rc |= jbt_init_regs(jbt, 0);
|
||||
+
|
||||
+ return rc ? -EIO : 0;
|
||||
+}
|
||||
+
|
||||
+static int sleep_to_qvga_normal(struct jbt_info *jbt)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */
|
||||
+ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81);
|
||||
+
|
||||
+ /* Quad mode on */
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22);
|
||||
+
|
||||
+ /* AVDD on, XVDD on */
|
||||
+ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16);
|
||||
+
|
||||
+ /* Output control */
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9);
|
||||
+
|
||||
+ /* Sleep mode off */
|
||||
+ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT);
|
||||
+
|
||||
+ /* initialize register set for qvga*/
|
||||
+ rc |= jbt_init_regs(jbt, 1);
|
||||
+
|
||||
+ return rc ? -EIO : 0;
|
||||
+}
|
||||
+
|
||||
+static int normal_to_sleep(struct jbt_info *jbt)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
|
||||
+ rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8002);
|
||||
+ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN);
|
||||
+
|
||||
+ return rc ? -EIO : 0;
|
||||
+}
|
||||
+
|
||||
+static int sleep_to_standby(struct jbt_info *jbt)
|
||||
+{
|
||||
+ return jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00);
|
||||
+}
|
||||
+
|
||||
+/* frontend function */
|
||||
+int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state)
|
||||
+{
|
||||
+ int rc = -EINVAL;
|
||||
+
|
||||
+ dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%u, "
|
||||
+ "new_state=%u)\n", jbt->state, new_state);
|
||||
+
|
||||
+ switch (jbt->state) {
|
||||
+ case JBT_STATE_DEEP_STANDBY:
|
||||
+ switch (new_state) {
|
||||
+ case JBT_STATE_DEEP_STANDBY:
|
||||
+ rc = 0;
|
||||
+ break;
|
||||
+ case JBT_STATE_SLEEP:
|
||||
+ rc = standby_to_sleep(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ /* first transition into sleep */
|
||||
+ rc = standby_to_sleep(jbt);
|
||||
+ /* then transition into normal */
|
||||
+ rc |= sleep_to_normal(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ /* first transition into sleep */
|
||||
+ rc = standby_to_sleep(jbt);
|
||||
+ /* then transition into normal */
|
||||
+ rc |= sleep_to_qvga_normal(jbt);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case JBT_STATE_SLEEP:
|
||||
+ switch (new_state) {
|
||||
+ case JBT_STATE_SLEEP:
|
||||
+ rc = 0;
|
||||
+ break;
|
||||
+ case JBT_STATE_DEEP_STANDBY:
|
||||
+ rc = sleep_to_standby(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ rc = sleep_to_normal(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ rc = sleep_to_qvga_normal(jbt);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ switch (new_state) {
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ rc = 0;
|
||||
+ break;
|
||||
+ case JBT_STATE_DEEP_STANDBY:
|
||||
+ /* first transition into sleep */
|
||||
+ rc = normal_to_sleep(jbt);
|
||||
+ /* then transition into deep standby */
|
||||
+ rc |= sleep_to_standby(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_SLEEP:
|
||||
+ rc = normal_to_sleep(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ /* first transition into sleep */
|
||||
+ rc = normal_to_sleep(jbt);
|
||||
+ /* second transition into deep standby */
|
||||
+ rc |= sleep_to_standby(jbt);
|
||||
+ /* third transition into sleep */
|
||||
+ rc |= standby_to_sleep(jbt);
|
||||
+ /* fourth transition into normal */
|
||||
+ rc |= sleep_to_qvga_normal(jbt);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ switch (new_state) {
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ rc = 0;
|
||||
+ break;
|
||||
+ case JBT_STATE_DEEP_STANDBY:
|
||||
+ /* first transition into sleep */
|
||||
+ rc = normal_to_sleep(jbt);
|
||||
+ /* then transition into deep standby */
|
||||
+ rc |= sleep_to_standby(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_SLEEP:
|
||||
+ rc = normal_to_sleep(jbt);
|
||||
+ break;
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ /* first transition into sleep */
|
||||
+ rc = normal_to_sleep(jbt);
|
||||
+ /* second transition into deep standby */
|
||||
+ rc |= sleep_to_standby(jbt);
|
||||
+ /* third transition into sleep */
|
||||
+ rc |= standby_to_sleep(jbt);
|
||||
+ /* fourth transition into normal */
|
||||
+ rc |= sleep_to_normal(jbt);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ if (rc == 0)
|
||||
+ jbt->state = new_state;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(jbt6k74_enter_state);
|
||||
+
|
||||
+int jbt6k74_display_onoff(struct jbt_info *jbt, int on)
|
||||
+{
|
||||
+ if (on)
|
||||
+ return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON);
|
||||
+ else
|
||||
+ return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(jbt6k74_display_onoff);
|
||||
+
|
||||
+static ssize_t state_read(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(dev);
|
||||
+
|
||||
+ if (jbt->state >= ARRAY_SIZE(jbt_state_names))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ return sprintf(buf, "%s\n", jbt_state_names[jbt->state]);
|
||||
+}
|
||||
+
|
||||
+static ssize_t state_write(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(dev);
|
||||
+ int i, rc;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(jbt_state_names); i++) {
|
||||
+ if (!strncmp(buf, jbt_state_names[i],
|
||||
+ strlen(jbt_state_names[i]))) {
|
||||
+ rc = jbt6k74_enter_state(jbt, i);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ switch (i) {
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ /* Enable display again after deep-standby */
|
||||
+ rc = jbt6k74_display_onoff(jbt, 1);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return count;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(state, 0644, state_read, state_write);
|
||||
+
|
||||
+static int reg_by_string(const char *name)
|
||||
+{
|
||||
+ if (!strcmp(name, "gamma_fine1"))
|
||||
+ return JBT_REG_GAMMA1_FINE_1;
|
||||
+ else if (!strcmp(name, "gamma_fine2"))
|
||||
+ return JBT_REG_GAMMA1_FINE_2;
|
||||
+ else if (!strcmp(name, "gamma_inclination"))
|
||||
+ return JBT_REG_GAMMA1_INCLINATION;
|
||||
+ else
|
||||
+ return JBT_REG_GAMMA1_BLUE_OFFSET;
|
||||
+}
|
||||
+
|
||||
+static ssize_t gamma_read(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(dev);
|
||||
+ int reg = reg_by_string(attr->attr.name);
|
||||
+ u16 val;
|
||||
+
|
||||
+ mutex_lock(&jbt->lock);
|
||||
+ val = jbt->reg_cache[reg];
|
||||
+ mutex_unlock(&jbt->lock);
|
||||
+
|
||||
+ return sprintf(buf, "0x%04x\n", val);
|
||||
+}
|
||||
+
|
||||
+static ssize_t gamma_write(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(dev);
|
||||
+ int reg = reg_by_string(attr->attr.name);
|
||||
+ unsigned long val = simple_strtoul(buf, NULL, 10);
|
||||
+
|
||||
+ jbt_reg_write(jbt, reg, val & 0xff);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(gamma_fine1, 0644, gamma_read, gamma_write);
|
||||
+static DEVICE_ATTR(gamma_fine2, 0644, gamma_read, gamma_write);
|
||||
+static DEVICE_ATTR(gamma_inclination, 0644, gamma_read, gamma_write);
|
||||
+static DEVICE_ATTR(gamma_blue_offset, 0644, gamma_read, gamma_write);
|
||||
+
|
||||
+static struct attribute *jbt_sysfs_entries[] = {
|
||||
+ &dev_attr_state.attr,
|
||||
+ &dev_attr_gamma_fine1.attr,
|
||||
+ &dev_attr_gamma_fine2.attr,
|
||||
+ &dev_attr_gamma_inclination.attr,
|
||||
+ &dev_attr_gamma_blue_offset.attr,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group jbt_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = jbt_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+/* linux device model infrastructure */
|
||||
+
|
||||
+static int __devinit jbt_probe(struct spi_device *spi)
|
||||
+{
|
||||
+ int rc;
|
||||
+ struct jbt_info *jbt;
|
||||
+
|
||||
+ /* the controller doesn't have a MISO pin; we can't do detection */
|
||||
+
|
||||
+ spi->mode = SPI_CPOL | SPI_CPHA;
|
||||
+ spi->bits_per_word = 9;
|
||||
+
|
||||
+ rc = spi_setup(spi);
|
||||
+ if (rc < 0) {
|
||||
+ dev_err(&spi->dev,
|
||||
+ "error during spi_setup of jbt6k74 driver\n");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ jbt = kzalloc(sizeof(*jbt), GFP_KERNEL);
|
||||
+ if (!jbt)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ jbt->spi_dev = spi;
|
||||
+ jbt->state = JBT_STATE_DEEP_STANDBY;
|
||||
+ mutex_init(&jbt->lock);
|
||||
+
|
||||
+ dev_set_drvdata(&spi->dev, jbt);
|
||||
+
|
||||
+ rc = jbt6k74_enter_state(jbt, JBT_STATE_NORMAL);
|
||||
+ if (rc < 0) {
|
||||
+ dev_err(&spi->dev, "cannot enter NORMAL state\n");
|
||||
+ goto err_free_drvdata;
|
||||
+ }
|
||||
+
|
||||
+ rc = jbt6k74_display_onoff(jbt, 1);
|
||||
+ if (rc < 0) {
|
||||
+ dev_err(&spi->dev, "cannot switch display on\n");
|
||||
+ goto err_standby;
|
||||
+ }
|
||||
+
|
||||
+ rc = sysfs_create_group(&spi->dev.kobj, &jbt_attr_group);
|
||||
+ if (rc < 0) {
|
||||
+ dev_err(&spi->dev, "cannot create sysfs group\n");
|
||||
+ goto err_off;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_off:
|
||||
+ jbt6k74_display_onoff(jbt, 0);
|
||||
+err_standby:
|
||||
+ jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
||||
+err_free_drvdata:
|
||||
+ dev_set_drvdata(&spi->dev, NULL);
|
||||
+ kfree(jbt);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int __devexit jbt_remove(struct spi_device *spi)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ /* We don't want to switch off the display in case the user
|
||||
+ * accidentially onloads the module (whose use count normally is 0) */
|
||||
+
|
||||
+ sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group);
|
||||
+ dev_set_drvdata(&spi->dev, NULL);
|
||||
+ kfree(jbt);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int jbt_suspend(struct spi_device *spi, pm_message_t state)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ /* Save mode for resume */
|
||||
+ jbt->last_state = jbt->state;
|
||||
+ jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jbt_resume(struct spi_device *spi)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ jbt6k74_enter_state(jbt, jbt->last_state);
|
||||
+
|
||||
+ switch (jbt->last_state) {
|
||||
+ case JBT_STATE_NORMAL:
|
||||
+ case JBT_STATE_QVGA_NORMAL:
|
||||
+ jbt6k74_display_onoff(jbt, 1);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define jbt_suspend NULL
|
||||
+#define jbt_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct spi_driver jbt6k74_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "jbt6k74",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+
|
||||
+ .probe = jbt_probe,
|
||||
+ .remove = __devexit_p(jbt_remove),
|
||||
+ .suspend = jbt_suspend,
|
||||
+ .resume = jbt_resume,
|
||||
+};
|
||||
+
|
||||
+static int __init jbt_init(void)
|
||||
+{
|
||||
+ return spi_register_driver(&jbt6k74_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit jbt_exit(void)
|
||||
+{
|
||||
+ spi_unregister_driver(&jbt6k74_driver);
|
||||
+}
|
||||
+
|
||||
+MODULE_DESCRIPTION("SPI driver for tpo JBT6K74-AS LCM control interface");
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+module_init(jbt_init);
|
||||
+module_exit(jbt_exit);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
From db36b757a45cf8d9088727d975d93917021b1171 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:48 +0100
|
||||
Subject: [PATCH] gta01-inputdevice.patch
|
||||
This provides support for the GTA01 keyboard
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
drivers/input/keyboard/Kconfig | 12 ++
|
||||
drivers/input/keyboard/Makefile | 1 +
|
||||
drivers/input/keyboard/neo1973kbd.c | 242 +++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 255 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/input/keyboard/neo1973kbd.c
|
||||
|
||||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
|
||||
index efd70a9..b8ecca9 100644
|
||||
--- a/drivers/input/keyboard/Kconfig
|
||||
+++ b/drivers/input/keyboard/Kconfig
|
||||
@@ -323,4 +323,16 @@ config KEYBOARD_SH_KEYSC
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sh_keysc.
|
||||
+config KEYBOARD_NEO1973
|
||||
+ tristate "FIC Neo1973 buttons"
|
||||
+ depends on MACH_NEO1973
|
||||
+ default y
|
||||
+ help
|
||||
+ Say Y here to enable the buttons on the FIC Neo1973
|
||||
+ GSM phone.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called neo1973kbd.
|
||||
+
|
||||
+
|
||||
endif
|
||||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
|
||||
index 0edc8f2..b3aa339 100644
|
||||
--- a/drivers/input/keyboard/Makefile
|
||||
+++ b/drivers/input/keyboard/Makefile
|
||||
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
|
||||
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
|
||||
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
|
||||
+obj-$(CONFIG_KEYBOARD_NEO1973) += neo1973kbd.o
|
||||
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
|
||||
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
|
||||
diff --git a/drivers/input/keyboard/neo1973kbd.c b/drivers/input/keyboard/neo1973kbd.c
|
||||
new file mode 100644
|
||||
index 0000000..917d5ae
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/keyboard/neo1973kbd.c
|
||||
@@ -0,0 +1,242 @@
|
||||
+/*
|
||||
+ * Keyboard driver for FIC Neo1973 GSM phone
|
||||
+ *
|
||||
+ * (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * inspired by corkgbd.c by Richard Purdie
|
||||
+ *
|
||||
+ * 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/delay.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+
|
||||
+struct neo1973kbd {
|
||||
+ struct input_dev *input;
|
||||
+ unsigned int suspended;
|
||||
+ unsigned long suspend_jiffies;
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd_data = dev_id;
|
||||
+
|
||||
+ /* FIXME: use GPIO from platform_dev resources */
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_AUX_KEY))
|
||||
+ input_report_key(neo1973kbd_data->input, KEY_PHONE, 0);
|
||||
+ else
|
||||
+ input_report_key(neo1973kbd_data->input, KEY_PHONE, 1);
|
||||
+
|
||||
+ input_sync(neo1973kbd_data->input);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t neo1973kbd_hold_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd_data = dev_id;
|
||||
+
|
||||
+ /* FIXME: use GPIO from platform_dev resources */
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_HOLD_KEY))
|
||||
+ input_report_key(neo1973kbd_data->input, KEY_PAUSE, 1);
|
||||
+ else
|
||||
+ input_report_key(neo1973kbd_data->input, KEY_PAUSE, 0);
|
||||
+
|
||||
+ input_sync(neo1973kbd_data->input);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t neo1973kbd_headphone_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd_data = dev_id;
|
||||
+
|
||||
+ /* FIXME: use GPIO from platform_dev resources */
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_JACK_INSERT))
|
||||
+ input_report_switch(neo1973kbd_data->input,
|
||||
+ SW_HEADPHONE_INSERT, 1);
|
||||
+ else
|
||||
+ input_report_switch(neo1973kbd_data->input,
|
||||
+ SW_HEADPHONE_INSERT, 0);
|
||||
+
|
||||
+ input_sync(neo1973kbd_data->input);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int neo1973kbd_suspend(struct platform_device *dev, pm_message_t state)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd = platform_get_drvdata(dev);
|
||||
+
|
||||
+ neo1973kbd->suspended = 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973kbd_resume(struct platform_device *dev)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd = platform_get_drvdata(dev);
|
||||
+
|
||||
+ neo1973kbd->suspended = 0;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define neo1973kbd_suspend NULL
|
||||
+#define neo1973kbd_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static int neo1973kbd_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd;
|
||||
+ struct input_dev *input_dev;
|
||||
+ int rc, irq_aux, irq_hold, irq_jack;
|
||||
+
|
||||
+ neo1973kbd = kzalloc(sizeof(struct neo1973kbd), GFP_KERNEL);
|
||||
+ input_dev = input_allocate_device();
|
||||
+ if (!neo1973kbd || !input_dev) {
|
||||
+ kfree(neo1973kbd);
|
||||
+ input_free_device(input_dev);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if (pdev->resource[0].flags != 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ irq_aux = s3c2410_gpio_getirq(pdev->resource[0].start);
|
||||
+ if (irq_aux < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ irq_hold = s3c2410_gpio_getirq(pdev->resource[1].start);
|
||||
+ if (irq_hold < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ irq_jack = s3c2410_gpio_getirq(pdev->resource[2].start);
|
||||
+ if (irq_jack < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, neo1973kbd);
|
||||
+
|
||||
+ neo1973kbd->input = input_dev;
|
||||
+
|
||||
+ input_dev->name = "Neo1973 Buttons";
|
||||
+ input_dev->phys = "neo1973kbd/input0";
|
||||
+ input_dev->id.bustype = BUS_HOST;
|
||||
+ input_dev->id.vendor = 0x0001;
|
||||
+ input_dev->id.product = 0x0001;
|
||||
+ input_dev->id.version = 0x0100;
|
||||
+ input_dev->cdev.dev = &pdev->dev;
|
||||
+ input_dev->private = neo1973kbd;
|
||||
+
|
||||
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_SW);
|
||||
+ set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
|
||||
+ set_bit(KEY_PHONE, input_dev->keybit);
|
||||
+ set_bit(KEY_PAUSE, input_dev->keybit);
|
||||
+
|
||||
+ rc = input_register_device(neo1973kbd->input);
|
||||
+ if (rc)
|
||||
+ goto out_register;
|
||||
+
|
||||
+ if (request_irq(irq_aux, neo1973kbd_aux_irq, IRQF_DISABLED |
|
||||
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
+ "Neo1973 AUX button", neo1973kbd)) {
|
||||
+ dev_err(&pdev->dev, "Can't get IRQ %u\n", irq_aux);
|
||||
+ goto out_aux;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * GTA01 revisions before Bv4 can't be resumed by the PMU, so we use
|
||||
+ * resume by AUX.
|
||||
+ */
|
||||
+ if (machine_is_neo1973_gta01())
|
||||
+ enable_irq_wake(irq_aux);
|
||||
+
|
||||
+ if (request_irq(irq_hold, neo1973kbd_hold_irq, IRQF_DISABLED |
|
||||
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
+ "Neo1973 HOLD button", neo1973kbd)) {
|
||||
+ dev_err(&pdev->dev, "Can't get IRQ %u\n", irq_hold);
|
||||
+ goto out_hold;
|
||||
+ }
|
||||
+
|
||||
+ if (request_irq(irq_jack, neo1973kbd_headphone_irq, IRQF_DISABLED |
|
||||
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
+ "Neo1973 Headphone Jack", neo1973kbd)) {
|
||||
+ dev_err(&pdev->dev, "Can't get IRQ %u\n", irq_jack);
|
||||
+ goto out_jack;
|
||||
+ }
|
||||
+ enable_irq_wake(irq_jack);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_jack:
|
||||
+ free_irq(irq_hold, neo1973kbd);
|
||||
+out_hold:
|
||||
+ free_irq(irq_aux, neo1973kbd);
|
||||
+out_aux:
|
||||
+ input_unregister_device(neo1973kbd->input);
|
||||
+out_register:
|
||||
+ input_free_device(neo1973kbd->input);
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+ kfree(neo1973kbd);
|
||||
+
|
||||
+ return -ENODEV;
|
||||
+}
|
||||
+
|
||||
+static int neo1973kbd_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct neo1973kbd *neo1973kbd = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ free_irq(s3c2410_gpio_getirq(pdev->resource[2].start), neo1973kbd);
|
||||
+ free_irq(s3c2410_gpio_getirq(pdev->resource[1].start), neo1973kbd);
|
||||
+ free_irq(s3c2410_gpio_getirq(pdev->resource[0].start), neo1973kbd);
|
||||
+
|
||||
+ input_unregister_device(neo1973kbd->input);
|
||||
+ input_free_device(neo1973kbd->input);
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+ kfree(neo1973kbd);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver neo1973kbd_driver = {
|
||||
+ .probe = neo1973kbd_probe,
|
||||
+ .remove = neo1973kbd_remove,
|
||||
+ .suspend = neo1973kbd_suspend,
|
||||
+ .resume = neo1973kbd_resume,
|
||||
+ .driver = {
|
||||
+ .name = "neo1973-button",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __devinit neo1973kbd_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&neo1973kbd_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit neo1973kbd_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&neo1973kbd_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(neo1973kbd_init);
|
||||
+module_exit(neo1973kbd_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION("FIC Neo1973 buttons input driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,976 @@
|
|||
From 0739383d85822b93831803abb207794c16eedd79 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:48 +0100
|
||||
Subject: [PATCH] gta01-power_control.patch
|
||||
[PATCH] Neo1973 GPS / GSM / Bluetooth power control via sysfs
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
arch/arm/plat-s3c24xx/Makefile | 1 +
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_bt.c | 152 +++++++++
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_gps.c | 560 ++++++++++++++++++++++++++++++++
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_gsm.c | 217 ++++++++++++
|
||||
4 files changed, 930 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
create mode 100644 arch/arm/plat-s3c24xx/neo1973_pm_gps.c
|
||||
create mode 100644 arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
|
||||
|
||||
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
|
||||
index 131d202..6f43aca 100644
|
||||
--- a/arch/arm/plat-s3c24xx/Makefile
|
||||
+++ b/arch/arm/plat-s3c24xx/Makefile
|
||||
@@ -29,3 +29,4 @@ obj-$(CONFIG_PM) += pm.o
|
||||
obj-$(CONFIG_PM) += sleep.o
|
||||
obj-$(CONFIG_S3C2410_DMA) += dma.o
|
||||
obj-$(CONFIG_MACH_SMDK) += common-smdk.o
|
||||
+obj-$(CONFIG_MACH_NEO1973) += neo1973_pm_gsm.o neo1973_pm_gps.o neo1973_pm_bt.o
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
new file mode 100644
|
||||
index 0000000..b1af441
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
@@ -0,0 +1,152 @@
|
||||
+/*
|
||||
+ * Bluetooth PM code for the FIC Neo1973 GSM Phone
|
||||
+ *
|
||||
+ * (C) 2007 by OpenMoko Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <linux/pcf50606.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+
|
||||
+#define DRVMSG "FIC Neo1973 Bluetooth Power Management"
|
||||
+
|
||||
+static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ if (!strcmp(attr->attr.name, "power_on")) {
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG) == 3100)
|
||||
+ goto out_1;
|
||||
+ } else if (!strcmp(attr->attr.name, "reset")) {
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0)
|
||||
+ goto out_1;
|
||||
+ }
|
||||
+
|
||||
+ return strlcpy(buf, "0\n", 3);
|
||||
+out_1:
|
||||
+ return strlcpy(buf, "1\n", 3);
|
||||
+}
|
||||
+
|
||||
+static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ unsigned long on = simple_strtoul(buf, NULL, 10);
|
||||
+
|
||||
+ if (!strcmp(attr->attr.name, "power_on")) {
|
||||
+ /* if we are powering up, assert reset, then power, then
|
||||
+ * release reset */
|
||||
+ if (on) {
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG,
|
||||
+ 3100);
|
||||
+ }
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG, on);
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on);
|
||||
+ } else if (!strcmp(attr->attr.name, "reset")) {
|
||||
+ /* reset is low-active, so we need to invert */
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(power_on, 0644, bt_read, bt_write);
|
||||
+static DEVICE_ATTR(reset, 0644, bt_read, bt_write);
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta01_bt_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ dev_dbg(&pdev->dev, DRVMSG ": suspending\n");
|
||||
+ /* FIXME: The PMU should save the PMU status, and the GPIO code should
|
||||
+ * preserve the GPIO level, so there shouldn't be anything left to do
|
||||
+ * for us, should there? */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01_bt_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ dev_dbg(&pdev->dev, DRVMSG ": resuming\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define gta01_bt_suspend NULL
|
||||
+#define gta01_bt_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct attribute *gta01_bt_sysfs_entries[] = {
|
||||
+ &dev_attr_power_on.attr,
|
||||
+ &dev_attr_reset.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group gta01_bt_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = gta01_bt_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+static int __init gta01_bt_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ dev_info(&pdev->dev, DRVMSG ": starting\n");
|
||||
+
|
||||
+ /* we make sure that the voltage is off */
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG, 0);
|
||||
+ /* we pull reset to low to make sure that the chip doesn't
|
||||
+ * drain power through the reset line */
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
+
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, >a01_bt_attr_group);
|
||||
+}
|
||||
+
|
||||
+static int gta01_bt_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, >a01_bt_attr_group);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta01_bt_driver = {
|
||||
+ .probe = gta01_bt_probe,
|
||||
+ .remove = gta01_bt_remove,
|
||||
+ .suspend = gta01_bt_suspend,
|
||||
+ .resume = gta01_bt_resume,
|
||||
+ .driver = {
|
||||
+ .name = "neo1973-pm-bt",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __devinit gta01_bt_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a01_bt_driver);
|
||||
+}
|
||||
+
|
||||
+static void gta01_bt_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a01_bt_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta01_bt_init);
|
||||
+module_exit(gta01_bt_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION(DRVMSG);
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
|
||||
new file mode 100644
|
||||
index 0000000..f8cf719
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
|
||||
@@ -0,0 +1,560 @@
|
||||
+/*
|
||||
+ * GPS Power Management code for the FIC Neo1973 GSM Phone
|
||||
+ *
|
||||
+ * (C) 2007 by OpenMoko Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <linux/pcf50606.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+
|
||||
+/* This is the 2.8V supply for the RTC crystal, the mail clock crystal and
|
||||
+ * the input to VDD_RF */
|
||||
+static void gps_power_2v8_set(int on)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ if (on)
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_IOREG, 2800);
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_IOREG, on);
|
||||
+ break;
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_2V8, on);
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int gps_power_2v8_get(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_IOREG) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_IOREG) == 2800)
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_2V8))
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* This is the 3V supply (AVDD) for the external RF frontend (LNA bias) */
|
||||
+static void gps_power_3v_set(int on)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ if (on)
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG, 3000);
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG, on);
|
||||
+ break;
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_3V, on);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int gps_power_3v_get(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG) == 3000)
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_3V))
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* This is the 3.3V supply for VDD_IO and VDD_LPREG input */
|
||||
+static void gps_power_3v3_set(int on)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ if (on)
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD, 3300);
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD, on);
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_3V3, on);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int gps_power_3v3_get(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD) == 3300)
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_3V3))
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* This is the 2.5V supply for VDD_PLLREG and VDD_COREREG input */
|
||||
+static void gps_power_2v5_set(int on)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ /* This is CORE_1V8 and cannot be disabled */
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (on)
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG, 2500);
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG, on);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int gps_power_2v5_get(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ /* This is CORE_1V8 and cannot be disabled */
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG) == 2500)
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* This is the 1.5V supply for VDD_CORE */
|
||||
+static void gps_power_1v5_set(int on)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ /* This is switched via 2v5 */
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (on)
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD, 1500);
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD, on);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int gps_power_1v5_get(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ /* This is switched via 2v5 */
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_DCD) == 1500)
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* This is the POWERON pin */
|
||||
+static void gps_pwron_set(int on)
|
||||
+{
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_GPS_PWRON, on);
|
||||
+}
|
||||
+
|
||||
+static int gps_pwron_get(void)
|
||||
+{
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON))
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* This is the nRESET pin */
|
||||
+static void gps_rst_set(int on)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ pcf50606_gpo0_set(pcf50606_global, on);
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_GPS_RESET, on);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int gps_rst_get(void)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ if (pcf50606_gpo0_get(pcf50606_global))
|
||||
+ return 1;
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_RESET))
|
||||
+ return 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t power_gps_read(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!strcmp(attr->attr.name, "power_tcxo_2v8")) {
|
||||
+ ret = gps_power_2v8_get();
|
||||
+ } else if (!strcmp(attr->attr.name, "power_avdd_3v")) {
|
||||
+ ret = gps_power_3v_get();
|
||||
+ } else if (!strcmp(attr->attr.name, "pwron")) {
|
||||
+ ret = gps_pwron_get();
|
||||
+ } else if (!strcmp(attr->attr.name, "reset")) {
|
||||
+ ret = gps_rst_get();
|
||||
+ } else if (!strcmp(attr->attr.name, "power_lp_io_3v3")) {
|
||||
+ ret = gps_power_3v3_get();
|
||||
+ } else if (!strcmp(attr->attr.name, "power_pll_core_2v5")) {
|
||||
+ ret = gps_power_2v5_get();
|
||||
+ } else if (!strcmp(attr->attr.name, "power_core_1v5") ||
|
||||
+ !strcmp(attr->attr.name, "power_vdd_core_1v5")) {
|
||||
+ ret = gps_power_1v5_get();
|
||||
+ }
|
||||
+
|
||||
+ if (ret)
|
||||
+ return strlcpy(buf, "1\n", 3);
|
||||
+ else
|
||||
+ return strlcpy(buf, "0\n", 3);
|
||||
+}
|
||||
+
|
||||
+static ssize_t power_gps_write(struct device *dev,
|
||||
+ struct device_attribute *attr, const char *buf,
|
||||
+ size_t count)
|
||||
+{
|
||||
+ unsigned long on = simple_strtoul(buf, NULL, 10);
|
||||
+
|
||||
+ if (!strcmp(attr->attr.name, "power_tcxo_2v8")) {
|
||||
+ gps_power_2v8_set(on);
|
||||
+ } else if (!strcmp(attr->attr.name, "power_avdd_3v")) {
|
||||
+ gps_power_3v_set(on);
|
||||
+ } else if (!strcmp(attr->attr.name, "pwron")) {
|
||||
+ gps_pwron_set(on);
|
||||
+ } else if (!strcmp(attr->attr.name, "reset")) {
|
||||
+ gps_rst_set(on);
|
||||
+ } else if (!strcmp(attr->attr.name, "power_lp_io_3v3")) {
|
||||
+ gps_power_3v3_set(on);
|
||||
+ } else if (!strcmp(attr->attr.name, "power_pll_core_2v5")) {
|
||||
+ gps_power_2v5_set(on);
|
||||
+ } else if (!strcmp(attr->attr.name, "power_core_1v5") ||
|
||||
+ !strcmp(attr->attr.name, "power_vdd_core_1v5")) {
|
||||
+ gps_power_1v5_set(on);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static void gps_power_sequence_up(void)
|
||||
+{
|
||||
+ /* According to PMB2520 Data Sheet, Rev. 2006-06-05,
|
||||
+ * Chapter 4.2.2 */
|
||||
+
|
||||
+ /* nRESET must be asserted low */
|
||||
+ gps_rst_set(0);
|
||||
+
|
||||
+ /* POWERON must be de-asserted (low) */
|
||||
+ gps_pwron_set(0);
|
||||
+
|
||||
+ /* Apply VDD_IO and VDD_LPREG_IN */
|
||||
+ gps_power_3v3_set(1);
|
||||
+
|
||||
+ /* VDD_COREREG_IN, VDD_PLLREG_IN */
|
||||
+ gps_power_1v5_set(1);
|
||||
+ gps_power_2v5_set(1);
|
||||
+
|
||||
+ /* and VDD_RF may be applied */
|
||||
+ gps_power_2v8_set(1);
|
||||
+
|
||||
+ /* We need to enable AVDD, since in GTA01Bv3 it is
|
||||
+ * shared with RFREG_IN */
|
||||
+ gps_power_3v_set(1);
|
||||
+
|
||||
+ msleep(3); /* Is 3ms enough? */
|
||||
+
|
||||
+ /* De-asert nRESET */
|
||||
+ gps_rst_set(1);
|
||||
+
|
||||
+ /* Switch power on */
|
||||
+ gps_pwron_set(1);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void gps_power_sequence_down(void)
|
||||
+{
|
||||
+ /* According to PMB2520 Data Sheet, Rev. 2006-06-05,
|
||||
+ * Chapter 4.2.3.1 */
|
||||
+ gps_pwron_set(0);
|
||||
+
|
||||
+ /* Don't disable AVDD before PWRON is cleared, since
|
||||
+ * in GTA01Bv3, AVDD and RFREG_IN are shared */
|
||||
+ gps_power_3v_set(0);
|
||||
+
|
||||
+ /* Remove VDD_COREREG_IN, VDD_PLLREG_IN and VDD_REFREG_IN */
|
||||
+ gps_power_1v5_set(0);
|
||||
+ gps_power_2v5_set(0);
|
||||
+ gps_power_2v8_set(0);
|
||||
+
|
||||
+ /* Remove VDD_LPREG_IN and VDD_IO */
|
||||
+ gps_power_3v3_set(0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static ssize_t power_sequence_read(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ return strlcpy(buf, "power_up power_down\n", PAGE_SIZE);
|
||||
+}
|
||||
+
|
||||
+static ssize_t power_sequence_write(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ dev_dbg(dev, "wrote: '%s'\n", buf);
|
||||
+
|
||||
+ if (!strncmp(buf, "power_up", 8))
|
||||
+ gps_power_sequence_up();
|
||||
+ else if (!strncmp(buf, "power_down", 10))
|
||||
+ gps_power_sequence_down();
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(power_tcxo_2v8, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(power_avdd_3v, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(pwron, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(reset, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(power_lp_io_3v3, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(power_pll_core_2v5, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(power_core_1v5, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(power_vdd_core_1v5, 0644, power_gps_read, power_gps_write);
|
||||
+static DEVICE_ATTR(power_sequence, 0644, power_sequence_read,
|
||||
+ power_sequence_write);
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta01_pm_gps_suspend(struct platform_device *pdev,
|
||||
+ pm_message_t state)
|
||||
+{
|
||||
+ /* FIXME */
|
||||
+ gps_power_sequence_down();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01_pm_gps_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ /* FIXME */
|
||||
+ gps_power_sequence_up();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define gta01_pm_gps_suspend NULL
|
||||
+#define gta01_pm_gps_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct attribute *gta01_gps_sysfs_entries[] = {
|
||||
+ &dev_attr_power_avdd_3v.attr,
|
||||
+ &dev_attr_pwron.attr,
|
||||
+ &dev_attr_reset.attr,
|
||||
+ &dev_attr_power_lp_io_3v3.attr,
|
||||
+ &dev_attr_power_pll_core_2v5.attr,
|
||||
+ &dev_attr_power_sequence.attr,
|
||||
+ NULL, /* power_core_1v5 */
|
||||
+ NULL, /* power_vdd_core_1v5 */
|
||||
+ NULL /* terminating entry */
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group gta01_gps_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = gta01_gps_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+static int __init gta01_pm_gps_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT);
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, S3C2410_GPIO_OUTPUT);
|
||||
+ /* fallthrough */
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
|
||||
+ "AGPS PM features not available!!!\n",
|
||||
+ system_rev);
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ gps_power_sequence_down();
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
|
||||
+ &dev_attr_power_tcxo_2v8.attr;
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
|
||||
+ &dev_attr_power_core_1v5.attr;
|
||||
+ gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-2] =
|
||||
+ &dev_attr_power_vdd_core_1v5.attr;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, >a01_gps_attr_group);
|
||||
+}
|
||||
+
|
||||
+static int gta01_pm_gps_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ gps_power_sequence_down();
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta01_pm_gps_driver = {
|
||||
+ .probe = gta01_pm_gps_probe,
|
||||
+ .remove = gta01_pm_gps_remove,
|
||||
+ .suspend = gta01_pm_gps_suspend,
|
||||
+ .resume = gta01_pm_gps_resume,
|
||||
+ .driver = {
|
||||
+ .name = "neo1973-pm-gps",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __devinit gta01_pm_gps_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a01_pm_gps_driver);
|
||||
+}
|
||||
+
|
||||
+static void gta01_pm_gps_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a01_pm_gps_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta01_pm_gps_init);
|
||||
+module_exit(gta01_pm_gps_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION("FIC Neo1973 GPS Power Management");
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
|
||||
new file mode 100644
|
||||
index 0000000..a1615f8
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
|
||||
@@ -0,0 +1,217 @@
|
||||
+/*
|
||||
+ * GSM Management code for the FIC Neo1973 GSM Phone
|
||||
+ *
|
||||
+ * (C) 2007 by OpenMoko Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/console.h>
|
||||
+#include <linux/errno.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+
|
||||
+struct gta01pm_priv {
|
||||
+ int gpio_ngsm_en;
|
||||
+ struct console *con;
|
||||
+};
|
||||
+
|
||||
+static struct gta01pm_priv gta01_gsm;
|
||||
+
|
||||
+static struct console *find_s3c24xx_console(void)
|
||||
+{
|
||||
+ struct console *con;
|
||||
+
|
||||
+ acquire_console_sem();
|
||||
+
|
||||
+ for (con = console_drivers; con; con = con->next) {
|
||||
+ if (!strcmp(con->name, "ttySAC"))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ release_console_sem();
|
||||
+
|
||||
+ return con;
|
||||
+}
|
||||
+
|
||||
+static ssize_t gsm_read(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ if (!strcmp(attr->attr.name, "power_on")) {
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_ON))
|
||||
+ goto out_1;
|
||||
+ } else if (!strcmp(attr->attr.name, "reset")) {
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_RST))
|
||||
+ goto out_1;
|
||||
+ } else if (!strcmp(attr->attr.name, "download")) {
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD))
|
||||
+ goto out_1;
|
||||
+ }
|
||||
+
|
||||
+ return strlcpy(buf, "0\n", 3);
|
||||
+out_1:
|
||||
+ return strlcpy(buf, "1\n", 3);
|
||||
+}
|
||||
+
|
||||
+static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ unsigned long on = simple_strtoul(buf, NULL, 10);
|
||||
+
|
||||
+ if (!strcmp(attr->attr.name, "power_on")) {
|
||||
+ if (on) {
|
||||
+ dev_info(dev, "powering up GSM, thus disconnecting "
|
||||
+ "serial console\n");
|
||||
+
|
||||
+ if (gta01_gsm.con)
|
||||
+ console_stop(gta01_gsm.con);
|
||||
+
|
||||
+ if (gta01_gsm.gpio_ngsm_en)
|
||||
+ s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 0);
|
||||
+
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_MODEM_ON, 1);
|
||||
+ } else {
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_MODEM_ON, 0);
|
||||
+
|
||||
+ if (gta01_gsm.gpio_ngsm_en)
|
||||
+ s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 1);
|
||||
+
|
||||
+ if (gta01_gsm.con)
|
||||
+ console_start(gta01_gsm.con);
|
||||
+
|
||||
+ dev_info(dev, "powered down GSM, thus enabling "
|
||||
+ "serial console\n");
|
||||
+ }
|
||||
+ } else if (!strcmp(attr->attr.name, "reset")) {
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_MODEM_RST, on);
|
||||
+ } else if (!strcmp(attr->attr.name, "download")) {
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(power_on, 0644, gsm_read, gsm_write);
|
||||
+static DEVICE_ATTR(reset, 0644, gsm_read, gsm_write);
|
||||
+static DEVICE_ATTR(download, 0644, gsm_read, gsm_write);
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta01_gsm_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ /* GPIO state is saved/restored by S3C2410 core GPIO driver, so we
|
||||
+ * don't need to do anything here */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01_gsm_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ /* GPIO state is saved/restored by S3C2410 core GPIO driver, so we
|
||||
+ * don't need to do anything here */
|
||||
+
|
||||
+ /* Make sure that the kernel console on the serial port is still
|
||||
+ * disabled. FIXME: resume ordering race with serial driver! */
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_ON) && gta01_gsm.con)
|
||||
+ console_stop(gta01_gsm.con);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define gta01_gsm_suspend NULL
|
||||
+#define gta01_gsm_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct attribute *gta01_gsm_sysfs_entries[] = {
|
||||
+ &dev_attr_power_on.attr,
|
||||
+ &dev_attr_reset.attr,
|
||||
+ NULL,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group gta01_gsm_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = gta01_gsm_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+static int __init gta01_gsm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ gta01_gsm.gpio_ngsm_en = GTA01v3_GPIO_nGSM_EN;
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ gta01_gsm.gpio_ngsm_en = 0;
|
||||
+ break;
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ gta01_gsm.gpio_ngsm_en = GTA01Bv2_GPIO_nGSM_EN;
|
||||
+ s3c2410_gpio_setpin(GTA01v3_GPIO_nGSM_EN, 0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
|
||||
+ "some PM features not available!!!\n",
|
||||
+ system_rev);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ gta01_gsm_sysfs_entries[ARRAY_SIZE(gta01_gsm_sysfs_entries)-2] =
|
||||
+ &dev_attr_download.attr;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ gta01_gsm.con = find_s3c24xx_console();
|
||||
+ if (!gta01_gsm.con)
|
||||
+ dev_warn(&pdev->dev, "cannot find S3C24xx console driver\n");
|
||||
+
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, >a01_gsm_attr_group);
|
||||
+}
|
||||
+
|
||||
+static int gta01_gsm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, >a01_gsm_attr_group);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta01_gsm_driver = {
|
||||
+ .probe = gta01_gsm_probe,
|
||||
+ .remove = gta01_gsm_remove,
|
||||
+ .suspend = gta01_gsm_suspend,
|
||||
+ .resume = gta01_gsm_resume,
|
||||
+ .driver = {
|
||||
+ .name = "neo1973-pm-gsm",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __devinit gta01_gsm_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a01_gsm_driver);
|
||||
+}
|
||||
+
|
||||
+static void gta01_gsm_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a01_gsm_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta01_gsm_init);
|
||||
+module_exit(gta01_gsm_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION("FIC Neo1973 GSM Power Management");
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
From 2b1ccb68bdc0e1454be0e769896862bf0c7f95f9 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:49 +0100
|
||||
Subject: [PATCH] s3c2410-pwm.patch
|
||||
This patch adds a PWM api abstraction for the S3C2410 SoC
|
||||
|
||||
Signed-off-by: Javi Roman <javiroman@kernel-labs.org>
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
arch/arm/mach-s3c2410/Kconfig | 7 +
|
||||
arch/arm/mach-s3c2410/Makefile | 1 +
|
||||
arch/arm/mach-s3c2410/pwm.c | 214 ++++++++++++++++++++++++++++++++++++
|
||||
include/asm-arm/arch-s3c2410/pwm.h | 40 +++++++
|
||||
4 files changed, 262 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/arm/mach-s3c2410/pwm.c
|
||||
create mode 100644 include/asm-arm/arch-s3c2410/pwm.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
|
||||
index 58519e6..3e9ec50 100644
|
||||
--- a/arch/arm/mach-s3c2410/Kconfig
|
||||
+++ b/arch/arm/mach-s3c2410/Kconfig
|
||||
@@ -9,6 +9,7 @@ config CPU_S3C2410
|
||||
depends on ARCH_S3C2410
|
||||
select S3C2410_CLOCK
|
||||
select S3C2410_GPIO
|
||||
+ select S3C2410_PWM
|
||||
select CPU_LLSERIAL_S3C2410
|
||||
select S3C2410_PM if PM
|
||||
help
|
||||
@@ -38,6 +39,12 @@ config S3C2410_CLOCK
|
||||
Clock code for the S3C2410, and similar processors
|
||||
|
||||
|
||||
+config S3C2410_PWM
|
||||
+ bool
|
||||
+ help
|
||||
+ PWM timer code for the S3C2410, and similar processors
|
||||
+
|
||||
+
|
||||
menu "S3C2410 Machines"
|
||||
|
||||
config ARCH_SMDK2410
|
||||
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
|
||||
index b73562f..2a12a6a 100644
|
||||
--- a/arch/arm/mach-s3c2410/Makefile
|
||||
+++ b/arch/arm/mach-s3c2410/Makefile
|
||||
@@ -16,6 +16,7 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
|
||||
obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_S3C2410_GPIO) += gpio.o
|
||||
obj-$(CONFIG_S3C2410_CLOCK) += clock.o
|
||||
+obj-$(CONFIG_S3C2410_PWM) += pwm.o
|
||||
|
||||
# Machine support
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/pwm.c b/arch/arm/mach-s3c2410/pwm.c
|
||||
new file mode 100644
|
||||
index 0000000..8a07359
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-s3c2410/pwm.c
|
||||
@@ -0,0 +1,214 @@
|
||||
+/*
|
||||
+ * arch/arm/mach-s3c2410/3c2410-pwm.c
|
||||
+ *
|
||||
+ * Copyright (c) by Javi Roman <javiroman@kernel-labs.org>
|
||||
+ * for the OpenMoko Project.
|
||||
+ *
|
||||
+ * S3C2410A SoC PWM support
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * 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 <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+#include <asm/arch/pwm.h>
|
||||
+
|
||||
+int s3c2410_pwm_disable(struct s3c2410_pwm *pwm)
|
||||
+{
|
||||
+ unsigned long tcon;
|
||||
+
|
||||
+ /* stop timer */
|
||||
+ tcon = __raw_readl(S3C2410_TCON);
|
||||
+ tcon &= 0xffffff00;
|
||||
+ __raw_writel(tcon, S3C2410_TCON);
|
||||
+
|
||||
+ clk_disable(pwm->pclk);
|
||||
+ clk_put(pwm->pclk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_disable);
|
||||
+
|
||||
+int s3c2410_pwm_init(struct s3c2410_pwm *pwm)
|
||||
+{
|
||||
+ pwm->pclk = clk_get(NULL, "timers");
|
||||
+ if (IS_ERR(pwm->pclk))
|
||||
+ return PTR_ERR(pwm->pclk);
|
||||
+
|
||||
+ clk_enable(pwm->pclk);
|
||||
+ pwm->pclk_rate = clk_get_rate(pwm->pclk);
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_init);
|
||||
+
|
||||
+int s3c2410_pwm_enable(struct s3c2410_pwm *pwm)
|
||||
+{
|
||||
+ unsigned long tcfg0, tcfg1, tcnt, tcmp;
|
||||
+
|
||||
+ /* control registers bits */
|
||||
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
|
||||
+ tcfg0 = __raw_readl(S3C2410_TCFG0);
|
||||
+
|
||||
+ /* divider & scaler slection */
|
||||
+ switch (pwm->timerid) {
|
||||
+ case PWM0:
|
||||
+ tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
|
||||
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
|
||||
+ break;
|
||||
+ case PWM1:
|
||||
+ tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK;
|
||||
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
|
||||
+ break;
|
||||
+ case PWM2:
|
||||
+ tcfg1 &= ~S3C2410_TCFG1_MUX2_MASK;
|
||||
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
|
||||
+ break;
|
||||
+ case PWM3:
|
||||
+ tcfg1 &= ~S3C2410_TCFG1_MUX3_MASK;
|
||||
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
|
||||
+ break;
|
||||
+ case PWM4:
|
||||
+ /* timer four is not capable of doing PWM */
|
||||
+ break;
|
||||
+ default:
|
||||
+ clk_disable(pwm->pclk);
|
||||
+ clk_put(pwm->pclk);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* divider & scaler values */
|
||||
+ tcfg1 |= pwm->divider;
|
||||
+ __raw_writel(tcfg1, S3C2410_TCFG1);
|
||||
+
|
||||
+ switch (pwm->timerid) {
|
||||
+ case PWM0:
|
||||
+ case PWM1:
|
||||
+ tcfg0 |= pwm->prescaler;
|
||||
+ __raw_writel(tcfg0, S3C2410_TCFG0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ if ((tcfg0 | pwm->prescaler) != tcfg0) {
|
||||
+ printk(KERN_WARNING "not changing prescaler of PWM %u,"
|
||||
+ " since it's shared with timer4 (clock tick)\n",
|
||||
+ pwm->timerid);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* timer count and compare buffer initial values */
|
||||
+ tcnt = pwm->counter;
|
||||
+ tcmp = pwm->comparer;
|
||||
+
|
||||
+ __raw_writel(tcnt, S3C2410_TCNTB(pwm->timerid));
|
||||
+ __raw_writel(tcmp, S3C2410_TCMPB(pwm->timerid));
|
||||
+
|
||||
+ /* ensure timer is stopped */
|
||||
+ s3c2410_pwm_stop(pwm);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_enable);
|
||||
+
|
||||
+int s3c2410_pwm_start(struct s3c2410_pwm *pwm)
|
||||
+{
|
||||
+ unsigned long tcon;
|
||||
+
|
||||
+ tcon = __raw_readl(S3C2410_TCON);
|
||||
+
|
||||
+ switch (pwm->timerid) {
|
||||
+ case PWM0:
|
||||
+ tcon |= S3C2410_TCON_T0START;
|
||||
+ tcon &= ~S3C2410_TCON_T0MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM1:
|
||||
+ tcon |= S3C2410_TCON_T1START;
|
||||
+ tcon &= ~S3C2410_TCON_T1MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM2:
|
||||
+ tcon |= S3C2410_TCON_T2START;
|
||||
+ tcon &= ~S3C2410_TCON_T2MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM3:
|
||||
+ tcon |= S3C2410_TCON_T3START;
|
||||
+ tcon &= ~S3C2410_TCON_T3MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM4:
|
||||
+ /* timer four is not capable of doing PWM */
|
||||
+ default:
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ __raw_writel(tcon, S3C2410_TCON);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_start);
|
||||
+
|
||||
+int s3c2410_pwm_stop(struct s3c2410_pwm *pwm)
|
||||
+{
|
||||
+ unsigned long tcon;
|
||||
+
|
||||
+ tcon = __raw_readl(S3C2410_TCON);
|
||||
+
|
||||
+ switch (pwm->timerid) {
|
||||
+ case PWM0:
|
||||
+ tcon &= ~0x00000000;
|
||||
+ tcon |= S3C2410_TCON_T0RELOAD;
|
||||
+ tcon |= S3C2410_TCON_T0MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM1:
|
||||
+ tcon &= ~0x00000080;
|
||||
+ tcon |= S3C2410_TCON_T1RELOAD;
|
||||
+ tcon |= S3C2410_TCON_T1MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM2:
|
||||
+ tcon &= ~0x00000800;
|
||||
+ tcon |= S3C2410_TCON_T2RELOAD;
|
||||
+ tcon |= S3C2410_TCON_T2MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM3:
|
||||
+ tcon &= ~0x00008000;
|
||||
+ tcon |= S3C2410_TCON_T3RELOAD;
|
||||
+ tcon |= S3C2410_TCON_T3MANUALUPD;
|
||||
+ break;
|
||||
+ case PWM4:
|
||||
+ /* timer four is not capable of doing PWM */
|
||||
+ default:
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ __raw_writel(tcon, S3C2410_TCON);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_stop);
|
||||
+
|
||||
+int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *pwm)
|
||||
+{
|
||||
+ __raw_writel(reg_value, S3C2410_TCMPB(pwm->timerid));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_duty_cycle);
|
||||
+
|
||||
+int s3c2410_pwm_dumpregs(void)
|
||||
+{
|
||||
+ printk(KERN_INFO "TCON: %08lx, TCFG0: %08lx, TCFG1: %08lx\n",
|
||||
+ (unsigned long) __raw_readl(S3C2410_TCON),
|
||||
+ (unsigned long) __raw_readl(S3C2410_TCFG0),
|
||||
+ (unsigned long) __raw_readl(S3C2410_TCFG1));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(s3c2410_pwm_dumpregs);
|
||||
diff --git a/include/asm-arm/arch-s3c2410/pwm.h b/include/asm-arm/arch-s3c2410/pwm.h
|
||||
new file mode 100644
|
||||
index 0000000..a797ec3
|
||||
--- /dev/null
|
||||
+++ b/include/asm-arm/arch-s3c2410/pwm.h
|
||||
@@ -0,0 +1,40 @@
|
||||
+#ifndef __S3C2410_PWM_H
|
||||
+#define __S3C2410_PWM_H
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#include <asm-arm/io.h>
|
||||
+#include <asm/arch/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+
|
||||
+enum pwm_timer {
|
||||
+ PWM0,
|
||||
+ PWM1,
|
||||
+ PWM2,
|
||||
+ PWM3,
|
||||
+ PWM4
|
||||
+};
|
||||
+
|
||||
+struct s3c2410_pwm {
|
||||
+ enum pwm_timer timerid;
|
||||
+ struct clk *pclk;
|
||||
+ unsigned long pclk_rate;
|
||||
+ unsigned long prescaler;
|
||||
+ unsigned long divider;
|
||||
+ unsigned long counter;
|
||||
+ unsigned long comparer;
|
||||
+};
|
||||
+
|
||||
+int s3c2410_pwm_init(struct s3c2410_pwm *s3c2410_pwm);
|
||||
+int s3c2410_pwm_enable(struct s3c2410_pwm *s3c2410_pwm);
|
||||
+int s3c2410_pwm_disable(struct s3c2410_pwm *s3c2410_pwm);
|
||||
+int s3c2410_pwm_start(struct s3c2410_pwm *s3c2410_pwm);
|
||||
+int s3c2410_pwm_stop(struct s3c2410_pwm *s3c2410_pwm);
|
||||
+int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *s3c2410_pwm);
|
||||
+int s3c2410_pwm_dumpregs(void);
|
||||
+
|
||||
+#endif /* __S3C2410_PWM_H */
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
From 51990833d84bdff24a384119a9ba0cf815edd683 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:49 +0100
|
||||
Subject: [PATCH] gta01-vibrator.patch
|
||||
This patch adds driver support for the vibator device of the FIC/OpenMoko
|
||||
Neo1973 GSM phone. The driver uses the existing LED class driver framework,
|
||||
since there's a lot of similarity between the LED and the vibrator function.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
drivers/leds/Kconfig | 8 ++-
|
||||
drivers/leds/Makefile | 1 +
|
||||
drivers/leds/leds-neo1973-vibrator.c | 181 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 189 insertions(+), 1 deletions(-)
|
||||
create mode 100644 drivers/leds/leds-neo1973-vibrator.c
|
||||
|
||||
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
|
||||
index 86a369b..8c7d949 100644
|
||||
--- a/drivers/leds/Kconfig
|
||||
+++ b/drivers/leds/Kconfig
|
||||
@@ -47,7 +47,7 @@ config LEDS_SPITZ
|
||||
|
||||
config LEDS_S3C24XX
|
||||
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
|
||||
- depends on LEDS_CLASS && ARCH_S3C2410
|
||||
+ depends on LEDS_CLASS && ARCH_S3C2410 && S3C2410_PWM
|
||||
help
|
||||
This option enables support for LEDs connected to GPIO lines
|
||||
on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
|
||||
@@ -147,6 +147,12 @@ config LEDS_CLEVO_MAIL
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called leds-clevo-mail.
|
||||
|
||||
+config LEDS_NEO1973_VIBRATOR
|
||||
+ tristate "Vibrator Support for the FIC Neo1973 GSM phone"
|
||||
+ depends on LEDS_CLASS && MACH_NEO1973
|
||||
+ help
|
||||
+ This option enables support for the vibrator on the FIC Neo1973.
|
||||
+
|
||||
comment "LED Triggers"
|
||||
|
||||
config LEDS_TRIGGERS
|
||||
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
|
||||
index 973d626..148fe51 100644
|
||||
--- a/drivers/leds/Makefile
|
||||
+++ b/drivers/leds/Makefile
|
||||
@@ -21,6 +21,7 @@ obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
|
||||
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
|
||||
obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
|
||||
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
|
||||
+obj-$(CONFIG_LEDS_NEO1973_VIBRATOR) += leds-neo1973-vibrator.o
|
||||
|
||||
# LED Triggers
|
||||
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
|
||||
diff --git a/drivers/leds/leds-neo1973-vibrator.c b/drivers/leds/leds-neo1973-vibrator.c
|
||||
new file mode 100644
|
||||
index 0000000..0336e36
|
||||
--- /dev/null
|
||||
+++ b/drivers/leds/leds-neo1973-vibrator.c
|
||||
@@ -0,0 +1,181 @@
|
||||
+/*
|
||||
+ * LED driver for the vibrator of the FIC Neo1973 GSM Phone
|
||||
+ *
|
||||
+ * (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Javi Roman <javiroman@kernel-labs.org>:
|
||||
+ * Implement PWM support for GTA01Bv4 and later
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+#include <asm/arch/pwm.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+
|
||||
+#define COUNTER 64
|
||||
+
|
||||
+struct neo1973_vib_priv {
|
||||
+ struct led_classdev cdev;
|
||||
+ unsigned int gpio;
|
||||
+ struct mutex mutex;
|
||||
+ unsigned int has_pwm;
|
||||
+ struct s3c2410_pwm pwm;
|
||||
+};
|
||||
+
|
||||
+static void neo1973_vib_vib_set(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value)
|
||||
+{
|
||||
+ struct neo1973_vib_priv *vp =
|
||||
+ container_of(led_cdev, struct neo1973_vib_priv, cdev);
|
||||
+
|
||||
+ /*
|
||||
+ * value == 255 -> 99% duty cycle (full power)
|
||||
+ * value == 128 -> 50% duty cycle (medium power)
|
||||
+ * value == 0 -> 0% duty cycle (zero power)
|
||||
+ */
|
||||
+ mutex_lock(&vp->mutex);
|
||||
+ if (vp->has_pwm)
|
||||
+ s3c2410_pwm_duty_cycle(value/4, &vp->pwm);
|
||||
+ else {
|
||||
+ if (value)
|
||||
+ s3c2410_gpio_setpin(vp->gpio, 1);
|
||||
+ else
|
||||
+ s3c2410_gpio_setpin(vp->gpio, 0);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&vp->mutex);
|
||||
+}
|
||||
+
|
||||
+static struct neo1973_vib_priv neo1973_vib_led = {
|
||||
+ .cdev = {
|
||||
+ .name = "neo1973:vibrator",
|
||||
+ .brightness_set = neo1973_vib_vib_set,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int neo1973_vib_init_hw(struct neo1973_vib_priv *vp)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = s3c2410_pwm_init(&vp->pwm);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ vp->pwm.timerid = PWM3;
|
||||
+ /* use same prescaler as arch/arm/plat-s3c24xx/time.c */
|
||||
+ vp->pwm.prescaler = (6 - 1) / 2;
|
||||
+ vp->pwm.divider = S3C2410_TCFG1_MUX3_DIV2;
|
||||
+ vp->pwm.counter = COUNTER;
|
||||
+ vp->pwm.comparer = COUNTER;
|
||||
+
|
||||
+ rc = s3c2410_pwm_enable(&vp->pwm);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ s3c2410_pwm_start(&vp->pwm);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int neo1973_vib_suspend(struct platform_device *dev, pm_message_t state)
|
||||
+{
|
||||
+ led_classdev_suspend(&neo1973_vib_led.cdev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_vib_resume(struct platform_device *dev)
|
||||
+{
|
||||
+ struct neo1973_vib_priv *vp = platform_get_drvdata(dev);
|
||||
+
|
||||
+ if (vp->has_pwm)
|
||||
+ neo1973_vib_init_hw(vp);
|
||||
+
|
||||
+ led_classdev_resume(&neo1973_vib_led.cdev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_PM */
|
||||
+
|
||||
+static int __init neo1973_vib_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *r;
|
||||
+ int rc;
|
||||
+
|
||||
+ if (!machine_is_neo1973_gta01())
|
||||
+ return -EIO;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, 0, 0);
|
||||
+ if (!r || !r->start)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ neo1973_vib_led.gpio = r->start;
|
||||
+ platform_set_drvdata(pdev, &neo1973_vib_led);
|
||||
+
|
||||
+ /* TOUT3 */
|
||||
+ if (neo1973_vib_led.gpio == S3C2410_GPB3) {
|
||||
+ rc = neo1973_vib_init_hw(&neo1973_vib_led);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ s3c2410_pwm_duty_cycle(0, &neo1973_vib_led.pwm);
|
||||
+ s3c2410_gpio_cfgpin(neo1973_vib_led.gpio, S3C2410_GPB3_TOUT3);
|
||||
+ neo1973_vib_led.has_pwm = 1;
|
||||
+ }
|
||||
+
|
||||
+ mutex_init(&neo1973_vib_led.mutex);
|
||||
+
|
||||
+ return led_classdev_register(&pdev->dev, &neo1973_vib_led.cdev);
|
||||
+}
|
||||
+
|
||||
+static int neo1973_vib_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ if (neo1973_vib_led.has_pwm)
|
||||
+ s3c2410_pwm_disable(&neo1973_vib_led.pwm);
|
||||
+
|
||||
+ led_classdev_unregister(&neo1973_vib_led.cdev);
|
||||
+
|
||||
+ mutex_destroy(&neo1973_vib_led.mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver neo1973_vib_driver = {
|
||||
+ .probe = neo1973_vib_probe,
|
||||
+ .remove = neo1973_vib_remove,
|
||||
+#ifdef CONFIG_PM
|
||||
+ .suspend = neo1973_vib_suspend,
|
||||
+ .resume = neo1973_vib_resume,
|
||||
+#endif
|
||||
+ .driver = {
|
||||
+ .name = "neo1973-vibrator",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init neo1973_vib_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&neo1973_vib_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit neo1973_vib_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&neo1973_vib_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(neo1973_vib_init);
|
||||
+module_exit(neo1973_vib_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION("FIC Neo1973 vibrator driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
From deee418974cd5cc3b1aa9b1329d91b50f8bb7baf Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:49 +0100
|
||||
Subject: [PATCH] gta01-backlight.patch
|
||||
This is a backlight driver for the FIC/OpenMoko Neo1973 GTA01 GSM Phone
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
drivers/video/backlight/Kconfig | 7 +
|
||||
drivers/video/backlight/Makefile | 1 +
|
||||
drivers/video/backlight/gta01_bl.c | 255 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 263 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/video/backlight/gta01_bl.c
|
||||
|
||||
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
|
||||
index dcd8073..475db76 100644
|
||||
--- a/drivers/video/backlight/Kconfig
|
||||
+++ b/drivers/video/backlight/Kconfig
|
||||
@@ -89,6 +89,13 @@ config BACKLIGHT_OMAP1
|
||||
the PWL module of OMAP1 processors. Say Y if your board
|
||||
uses this hardware.
|
||||
|
||||
+config BACKLIGHT_GTA01
|
||||
+ tristate "FIC Neo1973 GTA01 Backlight Driver"
|
||||
+ depends on BACKLIGHT_CLASS_DEVICE && MACH_NEO1973_GTA01
|
||||
+ default y
|
||||
+ help
|
||||
+ If you have a FIC Neo1973 GTA01, say y to enable the backlight driver.
|
||||
+
|
||||
config BACKLIGHT_HP680
|
||||
tristate "HP Jornada 680 Backlight Driver"
|
||||
depends on BACKLIGHT_CLASS_DEVICE && SH_HP6XX
|
||||
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
|
||||
index 33f6c7c..aee9f46 100644
|
||||
--- a/drivers/video/backlight/Makefile
|
||||
+++ b/drivers/video/backlight/Makefile
|
||||
@@ -5,6 +5,7 @@ obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
|
||||
|
||||
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
|
||||
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
|
||||
+obj-$(CONFIG_BACKLIGHT_GTA01) += gta01_bl.o
|
||||
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
|
||||
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
|
||||
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
|
||||
diff --git a/drivers/video/backlight/gta01_bl.c b/drivers/video/backlight/gta01_bl.c
|
||||
new file mode 100644
|
||||
index 0000000..c2bf0c9
|
||||
--- /dev/null
|
||||
+++ b/drivers/video/backlight/gta01_bl.c
|
||||
@@ -0,0 +1,255 @@
|
||||
+/*
|
||||
+ * Backlight Driver for FIC GTA01 (Neo1973) GSM Phone
|
||||
+ *
|
||||
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * based on corgi_cl.c, Copyright (c) 2004-2006 Richard Purdie
|
||||
+ *
|
||||
+ * 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, version 2.
|
||||
+ *
|
||||
+ * 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
|
||||
+ *
|
||||
+ * Javi Roman <javiroman@kernel-labs.org>:
|
||||
+ * implement PWM, instead of simple on/off switching
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/fb.h>
|
||||
+#include <linux/backlight.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#include <asm/arch/hardware.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+#include <asm/arch/pwm.h>
|
||||
+
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+
|
||||
+static struct backlight_properties gta01bl_prop;
|
||||
+static struct backlight_device *gta01_backlight_device;
|
||||
+static struct gta01bl_machinfo *bl_machinfo;
|
||||
+
|
||||
+static unsigned long gta01bl_flags;
|
||||
+
|
||||
+struct gta01bl_data {
|
||||
+ int intensity;
|
||||
+ struct mutex mutex;
|
||||
+ struct clk *clk;
|
||||
+ struct s3c2410_pwm pwm;
|
||||
+};
|
||||
+
|
||||
+static struct gta01bl_data gta01bl;
|
||||
+
|
||||
+#define GTA01BL_SUSPENDED 0x01
|
||||
+#define GTA01BL_BATTLOW 0x02
|
||||
+
|
||||
+/* On the GTA01 / Neo1973, we use a 50 or 66MHz PCLK, which gives
|
||||
+ * us a 6.25..8.25MHz DIV8 clock, which is further divided by a
|
||||
+ * prescaler of 4, resulting in a 1.56..2.06MHz tick. This results in a
|
||||
+ * minimum frequency of 24..31Hz. At 400Hz, we need to set the count
|
||||
+ * to something like 3906..5156, providing us a way sufficient resolution
|
||||
+ * for display brightness adjustment. */
|
||||
+#define GTA01BL_COUNTER 5156
|
||||
+
|
||||
+static int gta01bl_send_intensity(struct backlight_device *bd)
|
||||
+{
|
||||
+ int intensity = bd->props.brightness;
|
||||
+
|
||||
+ if (bd->props.power != FB_BLANK_UNBLANK)
|
||||
+ intensity = 0;
|
||||
+ if (bd->props.fb_blank != FB_BLANK_UNBLANK)
|
||||
+ intensity = 0;
|
||||
+ if (gta01bl_flags & GTA01BL_SUSPENDED)
|
||||
+ intensity = 0;
|
||||
+ if (gta01bl_flags & GTA01BL_BATTLOW)
|
||||
+ intensity &= bl_machinfo->limit_mask;
|
||||
+
|
||||
+ mutex_lock(>a01bl.mutex);
|
||||
+#ifdef GTA01_BACKLIGHT_ONOFF_ONLY
|
||||
+ if (intensity)
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BACKLIGHT, 1);
|
||||
+ else
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BACKLIGHT, 0);
|
||||
+#else
|
||||
+ if (intensity == bd->props.max_brightness) {
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BACKLIGHT, 1);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT);
|
||||
+ } else {
|
||||
+ s3c2410_pwm_duty_cycle(intensity & 0xffff, >a01bl.pwm);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPB0_TOUT0);
|
||||
+ }
|
||||
+#endif
|
||||
+ mutex_unlock(>a01bl.mutex);
|
||||
+
|
||||
+ gta01bl.intensity = intensity;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01bl_init_hw(void)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = s3c2410_pwm_init(>a01bl.pwm);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ gta01bl.pwm.timerid = PWM0;
|
||||
+ gta01bl.pwm.prescaler = (4 - 1);
|
||||
+ gta01bl.pwm.divider = S3C2410_TCFG1_MUX0_DIV8;
|
||||
+ gta01bl.pwm.counter = GTA01BL_COUNTER;
|
||||
+ gta01bl.pwm.comparer = gta01bl.pwm.counter;
|
||||
+
|
||||
+ rc = s3c2410_pwm_enable(>a01bl.pwm);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ s3c2410_pwm_start(>a01bl.pwm);
|
||||
+
|
||||
+ gta01bl_prop.max_brightness = gta01bl.pwm.counter;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta01bl_suspend(struct platform_device *dev, pm_message_t state)
|
||||
+{
|
||||
+ gta01bl_flags |= GTA01BL_SUSPENDED;
|
||||
+ gta01bl_send_intensity(gta01_backlight_device);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01bl_resume(struct platform_device *dev)
|
||||
+{
|
||||
+ mutex_lock(>a01bl.mutex);
|
||||
+ gta01bl_init_hw();
|
||||
+ mutex_unlock(>a01bl.mutex);
|
||||
+
|
||||
+ gta01bl_flags &= ~GTA01BL_SUSPENDED;
|
||||
+ gta01bl_send_intensity(gta01_backlight_device);
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define gta01bl_suspend NULL
|
||||
+#define gta01bl_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static int gta01bl_get_intensity(struct backlight_device *bd)
|
||||
+{
|
||||
+ return gta01bl.intensity;
|
||||
+}
|
||||
+
|
||||
+static int gta01bl_set_intensity(struct backlight_device *bd)
|
||||
+{
|
||||
+ gta01bl_send_intensity(gta01_backlight_device);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Called when the battery is low to limit the backlight intensity.
|
||||
+ * If limit==0 clear any limit, otherwise limit the intensity
|
||||
+ */
|
||||
+void gta01bl_limit_intensity(int limit)
|
||||
+{
|
||||
+ if (limit)
|
||||
+ gta01bl_flags |= GTA01BL_BATTLOW;
|
||||
+ else
|
||||
+ gta01bl_flags &= ~GTA01BL_BATTLOW;
|
||||
+ gta01bl_send_intensity(gta01_backlight_device);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(gta01bl_limit_intensity);
|
||||
+
|
||||
+
|
||||
+static struct backlight_ops gta01bl_ops = {
|
||||
+ .get_brightness = gta01bl_get_intensity,
|
||||
+ .update_status = gta01bl_set_intensity,
|
||||
+};
|
||||
+
|
||||
+static int __init gta01bl_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct gta01bl_machinfo *machinfo = pdev->dev.platform_data;
|
||||
+ int rc;
|
||||
+
|
||||
+#ifdef GTA01_BACKLIGHT_ONOFF_ONLY
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT);
|
||||
+ gta01bl_prop.max_brightness = 1;
|
||||
+#else
|
||||
+ rc = gta01bl_init_hw();
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
+#endif
|
||||
+ mutex_init(>a01bl.mutex);
|
||||
+
|
||||
+ if (!machinfo->limit_mask)
|
||||
+ machinfo->limit_mask = -1;
|
||||
+
|
||||
+ gta01_backlight_device = backlight_device_register("gta01-bl",
|
||||
+ &pdev->dev, NULL,
|
||||
+ >a01bl_ops);
|
||||
+ if (IS_ERR(gta01_backlight_device))
|
||||
+ return PTR_ERR(gta01_backlight_device);
|
||||
+
|
||||
+ gta01bl_prop.power = FB_BLANK_UNBLANK;
|
||||
+ gta01bl_prop.brightness = gta01bl_prop.max_brightness;
|
||||
+ memcpy(>a01_backlight_device->props,
|
||||
+ >a01bl_prop, sizeof(gta01bl_prop));
|
||||
+ gta01bl_send_intensity(gta01_backlight_device);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01bl_remove(struct platform_device *dev)
|
||||
+{
|
||||
+#ifndef GTA01_BACKLIGHT_ONOFF_ONLY
|
||||
+ s3c2410_pwm_disable(>a01bl.pwm);
|
||||
+#endif
|
||||
+ backlight_device_unregister(gta01_backlight_device);
|
||||
+ mutex_destroy(>a01bl.mutex);
|
||||
+
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BACKLIGHT, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta01bl_driver = {
|
||||
+ .probe = gta01bl_probe,
|
||||
+ .remove = gta01bl_remove,
|
||||
+ .suspend = gta01bl_suspend,
|
||||
+ .resume = gta01bl_resume,
|
||||
+ .driver = {
|
||||
+ .name = "gta01-bl",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init gta01bl_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a01bl_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit gta01bl_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a01bl_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta01bl_init);
|
||||
+module_exit(gta01bl_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("FIC GTA01 (Neo1973) Backlight Driver");
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,636 @@
|
|||
From fc5d5366335469828d78898e2e74f8f80aa1d076 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:49 +0100
|
||||
Subject: [PATCH] s3c2410_touchscreen.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2410/mach-h1940.c | 8 +
|
||||
arch/arm/plat-s3c24xx/devs.c | 18 ++
|
||||
arch/arm/plat-s3c24xx/s3c244x.c | 1 +
|
||||
drivers/input/touchscreen/Kconfig | 18 ++
|
||||
drivers/input/touchscreen/Makefile | 1 +
|
||||
drivers/input/touchscreen/s3c2410_ts.c | 437 ++++++++++++++++++++++++++++++++
|
||||
include/asm-arm/arch-s3c2410/ts.h | 28 ++
|
||||
include/asm-arm/plat-s3c24xx/devs.h | 1 +
|
||||
8 files changed, 512 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/input/touchscreen/s3c2410_ts.c
|
||||
create mode 100644 include/asm-arm/arch-s3c2410/ts.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
|
||||
index 7c1145e..93cd8c8 100644
|
||||
--- a/arch/arm/mach-s3c2410/mach-h1940.c
|
||||
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <asm/arch/h1940.h>
|
||||
#include <asm/arch/h1940-latch.h>
|
||||
#include <asm/arch/fb.h>
|
||||
+#include <asm/arch/tc.h>
|
||||
#include <asm/plat-s3c24xx/udc.h>
|
||||
|
||||
#include <asm/plat-s3c24xx/clock.h>
|
||||
@@ -129,6 +130,11 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
|
||||
.vbus_pin_inverted = 1,
|
||||
};
|
||||
|
||||
+static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
|
||||
+ .delay = 10000,
|
||||
+ .presc = 49,
|
||||
+ .oversampling_shift = 2,
|
||||
+};
|
||||
|
||||
/**
|
||||
* Set lcd on or off
|
||||
@@ -186,6 +192,7 @@ static struct platform_device *h1940_devices[] __initdata = {
|
||||
&s3c_device_i2c,
|
||||
&s3c_device_iis,
|
||||
&s3c_device_usbgadget,
|
||||
+ &s3c_device_ts,
|
||||
&s3c_device_leds,
|
||||
&s3c_device_bluetooth,
|
||||
};
|
||||
@@ -214,6 +221,7 @@ static void __init h1940_init(void)
|
||||
u32 tmp;
|
||||
|
||||
s3c24xx_fb_set_platdata(&h1940_fb_info);
|
||||
+ set_s3c2410ts_info(&h1940_ts_cfg);
|
||||
s3c24xx_udc_set_platdata(&h1940_udc_cfg);
|
||||
|
||||
/* Turn off suspend on both USB ports, and switch the
|
||||
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
|
||||
index e546e93..c1fbe2d 100644
|
||||
--- a/arch/arm/plat-s3c24xx/devs.c
|
||||
+++ b/arch/arm/plat-s3c24xx/devs.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/arch/fb.h>
|
||||
+#include <asm/arch/ts.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@@ -207,6 +208,23 @@ struct platform_device s3c_device_nand = {
|
||||
|
||||
EXPORT_SYMBOL(s3c_device_nand);
|
||||
|
||||
+/* Touchscreen */
|
||||
+struct platform_device s3c_device_ts = {
|
||||
+ .name = "s3c2410-ts",
|
||||
+ .id = -1,
|
||||
+};
|
||||
+
|
||||
+EXPORT_SYMBOL(s3c_device_ts);
|
||||
+
|
||||
+static struct s3c2410_ts_mach_info s3c2410ts_info;
|
||||
+
|
||||
+void set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
|
||||
+{
|
||||
+ memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));
|
||||
+ s3c_device_ts.dev.platform_data = &s3c2410ts_info;
|
||||
+}
|
||||
+EXPORT_SYMBOL(set_s3c2410ts_info);
|
||||
+
|
||||
/* USB Device (Gadget)*/
|
||||
|
||||
static struct resource s3c_usbgadget_resource[] = {
|
||||
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
|
||||
index 2f01af5..7a1a12d 100644
|
||||
--- a/arch/arm/plat-s3c24xx/s3c244x.c
|
||||
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
|
||||
@@ -68,6 +68,7 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
|
||||
s3c_device_sdi.name = "s3c2440-sdi";
|
||||
s3c_device_i2c.name = "s3c2440-i2c";
|
||||
s3c_device_nand.name = "s3c2440-nand";
|
||||
+ s3c_device_ts.name = "s3c2440-ts";
|
||||
s3c_device_usbgadget.name = "s3c2440-usbgadget";
|
||||
}
|
||||
|
||||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
|
||||
index 565ec71..52de2b0 100644
|
||||
--- a/drivers/input/touchscreen/Kconfig
|
||||
+++ b/drivers/input/touchscreen/Kconfig
|
||||
@@ -67,6 +67,24 @@ config TOUCHSCREEN_FUJITSU
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called fujitsu-ts.
|
||||
|
||||
+config TOUCHSCREEN_S3C2410
|
||||
+ tristate "Samsung S3C2410 touchscreen input driver"
|
||||
+ depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN
|
||||
+ select SERIO
|
||||
+ help
|
||||
+ Say Y here if you have the s3c2410 touchscreen.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called s3c2410_ts.
|
||||
+
|
||||
+config TOUCHSCREEN_S3C2410_DEBUG
|
||||
+ boolean "Samsung S3C2410 touchscreen debug messages"
|
||||
+ depends on TOUCHSCREEN_S3C2410
|
||||
+ help
|
||||
+ Select this if you want debug messages
|
||||
+
|
||||
config TOUCHSCREEN_GUNZE
|
||||
tristate "Gunze AHL-51S touchscreen"
|
||||
select SERIO
|
||||
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
|
||||
index 3c096d7..7c3bd1c 100644
|
||||
--- a/drivers/input/touchscreen/Makefile
|
||||
+++ b/drivers/input/touchscreen/Makefile
|
||||
@@ -26,3 +26,4 @@ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
|
||||
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
|
||||
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
|
||||
+obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
|
||||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
|
||||
new file mode 100644
|
||||
index 0000000..68071c2
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/touchscreen/s3c2410_ts.c
|
||||
@@ -0,0 +1,437 @@
|
||||
+/*
|
||||
+ * 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
|
||||
+ *
|
||||
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
|
||||
+ * iPAQ H1940 touchscreen support
|
||||
+ *
|
||||
+ * ChangeLog
|
||||
+ *
|
||||
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
|
||||
+ * - added clock (de-)allocation code
|
||||
+ *
|
||||
+ * 2005-03-06: Arnaud Patard <arnaud.patard@rtp-net.org>
|
||||
+ * - h1940_ -> s3c2410 (this driver is now also used on the n30
|
||||
+ * machines :P)
|
||||
+ * - Debug messages are now enabled with the config option
|
||||
+ * TOUCHSCREEN_S3C2410_DEBUG
|
||||
+ * - Changed the way the value are read
|
||||
+ * - Input subsystem should now work
|
||||
+ * - Use ioremap and readl/writel
|
||||
+ *
|
||||
+ * 2005-03-23: Arnaud Patard <arnaud.patard@rtp-net.org>
|
||||
+ * - Make use of some undocumented features of the touchscreen
|
||||
+ * controller
|
||||
+ *
|
||||
+ * 2007-05-23: Harald Welte <laforge@openmoko.org>
|
||||
+ * - Add proper support for S32440
|
||||
+ */
|
||||
+
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/serio.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/irq.h>
|
||||
+
|
||||
+#include <asm/arch/regs-gpio.h>
|
||||
+#include <asm/arch/ts.h>
|
||||
+
|
||||
+#include <asm/plat-s3c/regs-adc.h>
|
||||
+
|
||||
+/* For ts.dev.id.version */
|
||||
+#define S3C2410TSVERSION 0x0101
|
||||
+
|
||||
+#define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
|
||||
+
|
||||
+#define WAIT4INT(x) (((x)<<8) | \
|
||||
+ S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
|
||||
+ S3C2410_ADCTSC_XY_PST(3))
|
||||
+
|
||||
+#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
|
||||
+ S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))
|
||||
+
|
||||
+#define DEBUG_LVL KERN_DEBUG
|
||||
+
|
||||
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
|
||||
+MODULE_DESCRIPTION("s3c2410 touchscreen driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+/*
|
||||
+ * Definitions & global arrays.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+static char *s3c2410ts_name = "s3c2410 TouchScreen";
|
||||
+
|
||||
+/*
|
||||
+ * Per-touchscreen data.
|
||||
+ */
|
||||
+
|
||||
+struct s3c2410ts {
|
||||
+ struct input_dev *dev;
|
||||
+ long xp;
|
||||
+ long yp;
|
||||
+ int count;
|
||||
+ int shift;
|
||||
+};
|
||||
+
|
||||
+static struct s3c2410ts ts;
|
||||
+static void __iomem *base_addr;
|
||||
+
|
||||
+static inline void s3c2410_ts_connect(void)
|
||||
+{
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
|
||||
+}
|
||||
+
|
||||
+static void touch_timer_fire(unsigned long data)
|
||||
+{
|
||||
+ unsigned long data0;
|
||||
+ unsigned long data1;
|
||||
+ int updown;
|
||||
+
|
||||
+ data0 = readl(base_addr+S3C2410_ADCDAT0);
|
||||
+ data1 = readl(base_addr+S3C2410_ADCDAT1);
|
||||
+
|
||||
+ updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
|
||||
+
|
||||
+ if (updown) {
|
||||
+ if (ts.count != 0) {
|
||||
+ ts.xp >>= ts.shift;
|
||||
+ ts.yp >>= ts.shift;
|
||||
+
|
||||
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
|
||||
+ {
|
||||
+ struct timeval tv;
|
||||
+ do_gettimeofday(&tv);
|
||||
+ printk(DEBUG_LVL "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts.xp, ts.yp);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ input_report_abs(ts.dev, ABS_X, ts.xp);
|
||||
+ input_report_abs(ts.dev, ABS_Y, ts.yp);
|
||||
+
|
||||
+ input_report_key(ts.dev, BTN_TOUCH, 1);
|
||||
+ input_report_abs(ts.dev, ABS_PRESSURE, 1);
|
||||
+ input_sync(ts.dev);
|
||||
+ }
|
||||
+
|
||||
+ ts.xp = 0;
|
||||
+ ts.yp = 0;
|
||||
+ ts.count = 0;
|
||||
+
|
||||
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
|
||||
+ writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
|
||||
+ } else {
|
||||
+ ts.count = 0;
|
||||
+
|
||||
+ input_report_key(ts.dev, BTN_TOUCH, 0);
|
||||
+ input_report_abs(ts.dev, ABS_PRESSURE, 0);
|
||||
+ input_sync(ts.dev);
|
||||
+
|
||||
+ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct timer_list touch_timer =
|
||||
+ TIMER_INITIALIZER(touch_timer_fire, 0, 0);
|
||||
+
|
||||
+static irqreturn_t stylus_updown(int irq, void *dev_id)
|
||||
+{
|
||||
+ unsigned long data0;
|
||||
+ unsigned long data1;
|
||||
+ int updown;
|
||||
+
|
||||
+ data0 = readl(base_addr+S3C2410_ADCDAT0);
|
||||
+ data1 = readl(base_addr+S3C2410_ADCDAT1);
|
||||
+
|
||||
+ updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
|
||||
+
|
||||
+ /* TODO we should never get an interrupt with updown set while
|
||||
+ * the timer is running, but maybe we ought to verify that the
|
||||
+ * timer isn't running anyways. */
|
||||
+
|
||||
+ if (updown)
|
||||
+ touch_timer_fire(0);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static irqreturn_t stylus_action(int irq, void *dev_id)
|
||||
+{
|
||||
+ unsigned long data0;
|
||||
+ unsigned long data1;
|
||||
+
|
||||
+ data0 = readl(base_addr+S3C2410_ADCDAT0);
|
||||
+ data1 = readl(base_addr+S3C2410_ADCDAT1);
|
||||
+
|
||||
+ ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
|
||||
+ ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
|
||||
+ ts.count++;
|
||||
+
|
||||
+ if (ts.count < (1<<ts.shift)) {
|
||||
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
|
||||
+ writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
|
||||
+ } else {
|
||||
+ mod_timer(&touch_timer, jiffies+1);
|
||||
+ writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static struct clk *adc_clock;
|
||||
+
|
||||
+/*
|
||||
+ * The functions for inserting/removing us as a module.
|
||||
+ */
|
||||
+
|
||||
+static int __init s3c2410ts_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int rc;
|
||||
+ struct s3c2410_ts_mach_info *info;
|
||||
+ struct input_dev *input_dev;
|
||||
+
|
||||
+ info = ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data;
|
||||
+
|
||||
+ if (!info)
|
||||
+ {
|
||||
+ printk(KERN_ERR "Hm... too bad : no platform data for ts\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
|
||||
+ printk(DEBUG_LVL "Entering s3c2410ts_init\n");
|
||||
+#endif
|
||||
+
|
||||
+ adc_clock = clk_get(NULL, "adc");
|
||||
+ if (!adc_clock) {
|
||||
+ printk(KERN_ERR "failed to get adc clock source\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+ clk_enable(adc_clock);
|
||||
+
|
||||
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
|
||||
+ printk(DEBUG_LVL "got and enabled clock\n");
|
||||
+#endif
|
||||
+
|
||||
+ base_addr = ioremap(S3C2410_PA_ADC,0x20);
|
||||
+ if (base_addr == NULL) {
|
||||
+ printk(KERN_ERR "Failed to remap register block\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* If we acutally are a S3C2410: Configure GPIOs */
|
||||
+ if (!strcmp(pdev->name, "s3c2410-ts"))
|
||||
+ s3c2410_ts_connect();
|
||||
+
|
||||
+ if ((info->presc&0xff) > 0)
|
||||
+ writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
|
||||
+ base_addr+S3C2410_ADCCON);
|
||||
+ else
|
||||
+ writel(0,base_addr+S3C2410_ADCCON);
|
||||
+
|
||||
+
|
||||
+ /* Initialise registers */
|
||||
+ if ((info->delay&0xffff) > 0)
|
||||
+ writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY);
|
||||
+
|
||||
+ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
|
||||
+
|
||||
+ /* Initialise input stuff */
|
||||
+ memset(&ts, 0, sizeof(struct s3c2410ts));
|
||||
+ input_dev = input_allocate_device();
|
||||
+
|
||||
+ if (!input_dev) {
|
||||
+ printk(KERN_ERR "Unable to allocate the input device !!\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ts.dev = input_dev;
|
||||
+ ts.dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) |
|
||||
+ BIT_MASK(EV_ABS);
|
||||
+ ts.dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
+ input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);
|
||||
+ input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);
|
||||
+ input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);
|
||||
+
|
||||
+ ts.dev->private = &ts;
|
||||
+ ts.dev->name = s3c2410ts_name;
|
||||
+ ts.dev->id.bustype = BUS_RS232;
|
||||
+ ts.dev->id.vendor = 0xDEAD;
|
||||
+ ts.dev->id.product = 0xBEEF;
|
||||
+ ts.dev->id.version = S3C2410TSVERSION;
|
||||
+
|
||||
+ ts.shift = info->oversampling_shift;
|
||||
+
|
||||
+ /* Get irqs */
|
||||
+ if (request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM,
|
||||
+ "s3c2410_action", ts.dev)) {
|
||||
+ printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");
|
||||
+ iounmap(base_addr);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
|
||||
+ "s3c2410_action", ts.dev)) {
|
||||
+ printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");
|
||||
+ free_irq(IRQ_ADC, ts.dev);
|
||||
+ iounmap(base_addr);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);
|
||||
+
|
||||
+ /* All went ok, so register to the input system */
|
||||
+ rc = input_register_device(ts.dev);
|
||||
+ if (rc) {
|
||||
+ free_irq(IRQ_TC, ts.dev);
|
||||
+ free_irq(IRQ_ADC, ts.dev);
|
||||
+ clk_disable(adc_clock);
|
||||
+ iounmap(base_addr);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int s3c2410ts_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ disable_irq(IRQ_ADC);
|
||||
+ disable_irq(IRQ_TC);
|
||||
+ free_irq(IRQ_TC,ts.dev);
|
||||
+ free_irq(IRQ_ADC,ts.dev);
|
||||
+
|
||||
+ if (adc_clock) {
|
||||
+ clk_disable(adc_clock);
|
||||
+ clk_put(adc_clock);
|
||||
+ adc_clock = NULL;
|
||||
+ }
|
||||
+
|
||||
+ input_unregister_device(ts.dev);
|
||||
+ iounmap(base_addr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int s3c2410ts_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ writel(TSC_SLEEP, base_addr+S3C2410_ADCTSC);
|
||||
+ writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_STDBM,
|
||||
+ base_addr+S3C2410_ADCCON);
|
||||
+
|
||||
+ disable_irq(IRQ_ADC);
|
||||
+ disable_irq(IRQ_TC);
|
||||
+
|
||||
+ clk_disable(adc_clock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int s3c2410ts_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct s3c2410_ts_mach_info *info =
|
||||
+ ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data;
|
||||
+
|
||||
+ clk_enable(adc_clock);
|
||||
+ msleep(1);
|
||||
+
|
||||
+ enable_irq(IRQ_ADC);
|
||||
+ enable_irq(IRQ_TC);
|
||||
+
|
||||
+ if ((info->presc&0xff) > 0)
|
||||
+ writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
|
||||
+ base_addr+S3C2410_ADCCON);
|
||||
+ else
|
||||
+ writel(0,base_addr+S3C2410_ADCCON);
|
||||
+
|
||||
+ /* Initialise registers */
|
||||
+ if ((info->delay&0xffff) > 0)
|
||||
+ writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY);
|
||||
+
|
||||
+ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+#define s3c2410ts_suspend NULL
|
||||
+#define s3c2410ts_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct platform_driver s3c2410ts_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "s3c2410-ts",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+ .probe = s3c2410ts_probe,
|
||||
+ .remove = s3c2410ts_remove,
|
||||
+ .suspend = s3c2410ts_suspend,
|
||||
+ .resume = s3c2410ts_resume,
|
||||
+
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver s3c2440ts_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "s3c2440-ts",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+ .probe = s3c2410ts_probe,
|
||||
+ .remove = s3c2410ts_remove,
|
||||
+ .suspend = s3c2410ts_suspend,
|
||||
+ .resume = s3c2410ts_resume,
|
||||
+
|
||||
+};
|
||||
+
|
||||
+static int __init s3c2410ts_init(void)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = platform_driver_register(&s3c2410ts_driver);
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = platform_driver_register(&s3c2440ts_driver);
|
||||
+ if (rc < 0)
|
||||
+ platform_driver_unregister(&s3c2410ts_driver);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static void __exit s3c2410ts_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&s3c2440ts_driver);
|
||||
+ platform_driver_unregister(&s3c2410ts_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(s3c2410ts_init);
|
||||
+module_exit(s3c2410ts_exit);
|
||||
+
|
||||
+/*
|
||||
+ Local variables:
|
||||
+ compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.."
|
||||
+ c-basic-offset: 8
|
||||
+ End:
|
||||
+*/
|
||||
diff --git a/include/asm-arm/arch-s3c2410/ts.h b/include/asm-arm/arch-s3c2410/ts.h
|
||||
new file mode 100644
|
||||
index 0000000..593632a
|
||||
--- /dev/null
|
||||
+++ b/include/asm-arm/arch-s3c2410/ts.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* linux/include/asm/arch-s3c2410/ts.h
|
||||
+ *
|
||||
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.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.
|
||||
+ *
|
||||
+ *
|
||||
+ * Changelog:
|
||||
+ * 24-Mar-2005 RTP Created file
|
||||
+ * 03-Aug-2005 RTP Renamed to ts.h
|
||||
+ */
|
||||
+
|
||||
+#ifndef __ASM_ARM_TS_H
|
||||
+#define __ASM_ARM_TS_H
|
||||
+
|
||||
+struct s3c2410_ts_mach_info {
|
||||
+ int delay;
|
||||
+ int presc;
|
||||
+ int oversampling_shift;
|
||||
+};
|
||||
+
|
||||
+void set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info);
|
||||
+
|
||||
+#endif /* __ASM_ARM_TS_H */
|
||||
+
|
||||
diff --git a/include/asm-arm/plat-s3c24xx/devs.h b/include/asm-arm/plat-s3c24xx/devs.h
|
||||
index f9d6f03..43de9cc 100644
|
||||
--- a/include/asm-arm/plat-s3c24xx/devs.h
|
||||
+++ b/include/asm-arm/plat-s3c24xx/devs.h
|
||||
@@ -42,6 +42,7 @@ extern struct platform_device s3c_device_timer2;
|
||||
extern struct platform_device s3c_device_timer3;
|
||||
|
||||
extern struct platform_device s3c_device_usbgadget;
|
||||
+extern struct platform_device s3c_device_ts;
|
||||
|
||||
/* s3c2440 specific devices */
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From 4c5bb8608de01a165a32432a4091613bb12303fc Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:49 +0100
|
||||
Subject: [PATCH] s3c2410_ts-gta01.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2410/mach-gta01.c | 9 +++++++++
|
||||
1 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
index e690ed7..3462c7f 100644
|
||||
--- a/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
+++ b/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_core.h>
|
||||
+#include <asm/arch/ts.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
@@ -362,6 +363,7 @@ static struct platform_device *gta01_devices[] __initdata = {
|
||||
&s3c_device_sdi,
|
||||
&s3c_device_usbgadget,
|
||||
&s3c_device_nand,
|
||||
+ &s3c_device_ts,
|
||||
};
|
||||
|
||||
static struct s3c2410_nand_set gta01_nand_sets[] = {
|
||||
@@ -434,6 +436,12 @@ static struct s3c2410_udc_mach_info gta01_udc_cfg = {
|
||||
.vbus_draw = gta01_udc_vbus_draw,
|
||||
};
|
||||
|
||||
+static struct s3c2410_ts_mach_info gta01_ts_cfg = {
|
||||
+ .delay = 10000,
|
||||
+ .presc = 65,
|
||||
+ .oversampling_shift = 5,
|
||||
+};
|
||||
+
|
||||
/* SPI */
|
||||
|
||||
static struct spi_board_info gta01_spi_board_info[] = {
|
||||
@@ -599,6 +607,7 @@ static void __init gta01_machine_init(void)
|
||||
|
||||
INIT_WORK(>a01_udc_vbus_drawer.work, __gta01_udc_vbus_draw);
|
||||
s3c24xx_udc_set_platdata(>a01_udc_cfg);
|
||||
+ set_s3c2410ts_info(>a01_ts_cfg);
|
||||
|
||||
/* Set LCD_RESET / XRES to high */
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPC6, S3C2410_GPIO_OUTPUT);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
From 839b25d6bcef4b1609aaa53d018cdbc59ea4efa7 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] i2c-permit_invalid_addrs.patch
|
||||
We need this stupid workaround since our amplifier chip uses a 'reserved' I2C
|
||||
address
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
drivers/i2c/i2c-core.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
|
||||
index d0175f4..bb0c5e5 100644
|
||||
--- a/drivers/i2c/i2c-core.c
|
||||
+++ b/drivers/i2c/i2c-core.c
|
||||
@@ -1026,11 +1026,11 @@ static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind,
|
||||
int err;
|
||||
|
||||
/* Make sure the address is valid */
|
||||
- if (addr < 0x03 || addr > 0x77) {
|
||||
+ /*if (addr < 0x03 || addr > 0x77) {
|
||||
dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
|
||||
addr);
|
||||
return -EINVAL;
|
||||
- }
|
||||
+ }*/
|
||||
|
||||
/* Skip if already in use */
|
||||
if (i2c_check_addr(adapter, addr))
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
From c03d30af20838833c54f9e9684f38b7048e369d3 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] g_ether-highpower.patch
|
||||
|
||||
---
|
||||
drivers/usb/gadget/ether.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
|
||||
index 8d61ea6..066a3e7 100644
|
||||
--- a/drivers/usb/gadget/ether.c
|
||||
+++ b/drivers/usb/gadget/ether.c
|
||||
@@ -464,7 +464,7 @@ eth_config = {
|
||||
.bConfigurationValue = DEV_CONFIG_VALUE,
|
||||
.iConfiguration = STRING_CDC,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
- .bMaxPower = 50,
|
||||
+ .bMaxPower = 250,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_ETH_RNDIS
|
||||
@@ -478,7 +478,7 @@ rndis_config = {
|
||||
.bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
|
||||
.iConfiguration = STRING_RNDIS,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
- .bMaxPower = 50,
|
||||
+ .bMaxPower = 250,
|
||||
};
|
||||
#endif
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
From 5ca57da3402b856986ac1e1ce316937207f6cbad Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] g_ether-vendor_product.patch
|
||||
Use FIC's own USB Vendor ID rather than NetChip's
|
||||
|
||||
Yes, we could solve this by some modprobe.conf parameters, but I'd like to
|
||||
rather not rely on this.
|
||||
---
|
||||
drivers/usb/gadget/ether.c | 11 ++++-------
|
||||
1 files changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
|
||||
index 066a3e7..a474b0d 100644
|
||||
--- a/drivers/usb/gadget/ether.c
|
||||
+++ b/drivers/usb/gadget/ether.c
|
||||
@@ -134,11 +134,8 @@ struct eth_dev {
|
||||
* Instead: allocate your own, using normal USB-IF procedures.
|
||||
*/
|
||||
|
||||
-/* Thanks to NetChip Technologies for donating this product ID.
|
||||
- * It's for devices with only CDC Ethernet configurations.
|
||||
- */
|
||||
-#define CDC_VENDOR_NUM 0x0525 /* NetChip */
|
||||
-#define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */
|
||||
+#define CDC_VENDOR_NUM 0x1457 /* First International Computer */
|
||||
+#define CDC_PRODUCT_NUM 0x5117 /* Linux-USB Ethernet Gadget */
|
||||
|
||||
/* For hardware that can't talk CDC, we use the same vendor ID that
|
||||
* ARM Linux has used for ethernet-over-usb, both with sa1100 and
|
||||
@@ -159,8 +156,8 @@ struct eth_dev {
|
||||
* used with CDC Ethernet, Linux 2.4 hosts will need updates to choose
|
||||
* the non-RNDIS configuration.
|
||||
*/
|
||||
-#define RNDIS_VENDOR_NUM 0x0525 /* NetChip */
|
||||
-#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
|
||||
+#define RNDIS_VENDOR_NUM 0x1457 /* NetChip */
|
||||
+#define RNDIS_PRODUCT_NUM 0x5122 /* Ethernet/RNDIS Gadget */
|
||||
|
||||
|
||||
/* Some systems will want different product identifers published in the
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
|||
From d63b12e946e83c7db8c9f94ae9d5d9d420a6f907 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] s3c_mci-gta01.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2410/mach-gta01.c | 56 ++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 56 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
index 3462c7f..87bb189 100644
|
||||
--- a/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
+++ b/arch/arm/mach-s3c2410/mach-gta01.c
|
||||
@@ -59,6 +59,7 @@
|
||||
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/fb.h>
|
||||
+#include <asm/arch/mci.h>
|
||||
#include <asm/arch/spi.h>
|
||||
#include <asm/arch/spi-gpio.h>
|
||||
#include <asm/arch/usb-control.h>
|
||||
@@ -382,6 +383,59 @@ static struct s3c2410_platform_nand gta01_nand_info = {
|
||||
.sets = gta01_nand_sets,
|
||||
};
|
||||
|
||||
+static void gta01_mmc_set_power(unsigned char power_mode, unsigned short vdd)
|
||||
+{
|
||||
+ int bit;
|
||||
+ int mv = 1700; /* 1.7V for MMC_VDD_165_195 */
|
||||
+
|
||||
+ printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u\n",
|
||||
+ power_mode, vdd);
|
||||
+
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ switch (power_mode) {
|
||||
+ case MMC_POWER_OFF:
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG, 0);
|
||||
+ break;
|
||||
+ case MMC_POWER_ON:
|
||||
+ /* translate MMC_VDD_* VDD bit to mv */
|
||||
+ for (bit = 8; bit != 24; bit++)
|
||||
+ if (vdd == (1 << bit))
|
||||
+ mv += 100 * (bit - 4);
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG, mv);
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D2REG, 1);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ switch (power_mode) {
|
||||
+ case MMC_POWER_OFF:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_SDMMC_ON, 1);
|
||||
+ break;
|
||||
+ case MMC_POWER_ON:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_SDMMC_ON, 0);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct s3c24xx_mci_pdata gta01_mmc_cfg = {
|
||||
+ .gpio_detect = GTA01_GPIO_nSD_DETECT,
|
||||
+ .set_power = >a01_mmc_set_power,
|
||||
+ .ocr_avail = MMC_VDD_165_195|MMC_VDD_20_21|
|
||||
+ MMC_VDD_21_22|MMC_VDD_22_23|MMC_VDD_23_24|
|
||||
+ MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
|
||||
+ MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
|
||||
+ MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33,
|
||||
+};
|
||||
+
|
||||
static void gta01_udc_command(enum s3c2410_udc_cmd_e cmd)
|
||||
{
|
||||
printk(KERN_DEBUG "%s(%d)\n", __func__, cmd);
|
||||
@@ -598,10 +652,12 @@ static void __init gta01_machine_init(void)
|
||||
system_rev == GTA01Bv3_SYSTEM_REV ||
|
||||
system_rev == GTA01Bv4_SYSTEM_REV) {
|
||||
gta01_udc_cfg.udc_command = gta01_udc_command;
|
||||
+ gta01_mmc_cfg.ocr_avail = MMC_VDD_32_33;
|
||||
}
|
||||
|
||||
s3c_device_usb.dev.platform_data = >a01_usb_info;
|
||||
s3c_device_nand.dev.platform_data = >a01_nand_info;
|
||||
+ s3c_device_sdi.dev.platform_data = >a01_mmc_cfg;
|
||||
|
||||
s3c24xx_fb_set_platdata(>a01_lcd_cfg);
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From 68108d95040732cebf06296affaaeaaf76029c3d Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] s3c24xx-nand-largepage.patch
|
||||
MTD: S3C24XX large page NAND support
|
||||
|
||||
This adds support for using large page NAND devices
|
||||
with the S3C24XX NAND controller. This also adds the
|
||||
file Documentation/arm/Samsung-S3C24XX/NAND.txt to
|
||||
describe the differences.
|
||||
|
||||
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
|
||||
---
|
||||
drivers/mtd/nand/s3c2410.c | 28 ++++++++++++++++++++++++++++
|
||||
1 files changed, 28 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
|
||||
index cd2e1da..6e7a5b9 100644
|
||||
--- a/drivers/mtd/nand/s3c2410.c
|
||||
+++ b/drivers/mtd/nand/s3c2410.c
|
||||
@@ -726,6 +726,34 @@ static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
|
||||
}
|
||||
}
|
||||
|
||||
+/* s3c2410_nand_update_chip
|
||||
+ *
|
||||
+ * post-probe chip update, to change any items, such as the
|
||||
+ * layout for large page nand
|
||||
+ */
|
||||
+
|
||||
+static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
|
||||
+ struct s3c2410_nand_mtd *nmtd)
|
||||
+{
|
||||
+ struct nand_chip *chip = &nmtd->chip;
|
||||
+
|
||||
+ printk("%s: chip %p: %d\n", __func__, chip, chip->page_shift);
|
||||
+
|
||||
+ if (hardware_ecc) {
|
||||
+ /* change the behaviour depending on wether we are using
|
||||
+ * the large or small page nand device */
|
||||
+
|
||||
+ if (chip->page_shift > 10) {
|
||||
+ chip->ecc.size = 256;
|
||||
+ chip->ecc.bytes = 3;
|
||||
+ } else {
|
||||
+ chip->ecc.size = 512;
|
||||
+ chip->ecc.bytes = 3;
|
||||
+ chip->ecc.layout = &nand_hw_eccoob;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* s3c2410_nand_probe
|
||||
*
|
||||
* called by device layer when it finds a device matching
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
From 5207363cc9d50f99a2ad490eff5efa913b1c10ba Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] s3c2410_udc-2440_dual_packet-workaround.patch
|
||||
This is a patch that seems to make the USB hangs on the S3C2440 go away. At
|
||||
least a good amount of ping torture didn't make them come back so far.
|
||||
|
||||
The issue is that, if there are several back-to-back packets,
|
||||
sometimes no interrupt is generated for one of them. This
|
||||
seems to be caused by the mysterious dual packet mode, which
|
||||
the USB hardware enters automatically if the endpoint size is
|
||||
half that of the FIFO. (On the 2440, this is the normal
|
||||
situation for bulk data endpoints.)
|
||||
|
||||
There is also a timing factor in this. I think what happens is
|
||||
that the USB hardware automatically sends an acknowledgement
|
||||
if there is only one packet in the FIFO (the FIFO has space
|
||||
for two). If another packet arrives before the host has
|
||||
retrieved and acknowledged the previous one, no interrupt is
|
||||
generated for that second one.
|
||||
|
||||
However, there may be an indication. There is one undocumented
|
||||
bit (none of the 244x manuals document it), OUT_CRS1_REG[1],
|
||||
that seems to be set suspiciously often when this condition
|
||||
occurs. There is also CLR_DATA_TOGGLE, OUT_CRS1_REG[7], which
|
||||
may have a function related to this. (The Samsung manual is
|
||||
rather terse on that, as usual.)
|
||||
|
||||
This needs to be examined further. For now, the patch seems to do the
|
||||
trick.
|
||||
|
||||
Note that this is not a clean solution by any means, because we
|
||||
might potentially get stuck in that interrupt for quite a while.
|
||||
---
|
||||
drivers/usb/gadget/s3c2410_udc.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
|
||||
index 6b1ef48..c1a4379 100644
|
||||
--- a/drivers/usb/gadget/s3c2410_udc.c
|
||||
+++ b/drivers/usb/gadget/s3c2410_udc.c
|
||||
@@ -845,6 +845,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
|
||||
u32 ep_csr1;
|
||||
u32 idx;
|
||||
|
||||
+handle_ep_again:
|
||||
if (likely (!list_empty(&ep->queue)))
|
||||
req = list_entry(ep->queue.next,
|
||||
struct s3c2410_request, queue);
|
||||
@@ -884,6 +885,8 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
|
||||
|
||||
if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
|
||||
s3c2410_udc_read_fifo(ep,req);
|
||||
+ if (s3c2410_udc_fifo_count_out())
|
||||
+ goto handle_ep_again;
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
From ca652d910f40692ce558d525b61911b66202d908 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] s3c2442b-cpuid.patch
|
||||
Add the Samsung S3C2442B CPU idcode to the samsung s3c24xx platform code
|
||||
and fix a Kconfig typo related tot the 2442.
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2442/Kconfig | 2 +-
|
||||
arch/arm/plat-s3c24xx/cpu.c | 10 ++++++++++
|
||||
2 files changed, 11 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
|
||||
index 26d131a..6cc68a1 100644
|
||||
--- a/arch/arm/mach-s3c2442/Kconfig
|
||||
+++ b/arch/arm/mach-s3c2442/Kconfig
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
config CPU_S3C2442
|
||||
bool
|
||||
- depends on ARCH_S3C2410
|
||||
+ depends on ARCH_S3C2440
|
||||
select S3C2410_CLOCK
|
||||
select S3C2410_GPIO
|
||||
select S3C2410_PM if PM
|
||||
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
|
||||
index f5699ca..05fb61d 100644
|
||||
--- a/arch/arm/plat-s3c24xx/cpu.c
|
||||
+++ b/arch/arm/plat-s3c24xx/cpu.c
|
||||
@@ -72,6 +72,7 @@ static const char name_s3c2410[] = "S3C2410";
|
||||
static const char name_s3c2412[] = "S3C2412";
|
||||
static const char name_s3c2440[] = "S3C2440";
|
||||
static const char name_s3c2442[] = "S3C2442";
|
||||
+static const char name_s3c2442b[] = "S3C2442B";
|
||||
static const char name_s3c2443[] = "S3C2443";
|
||||
static const char name_s3c2410a[] = "S3C2410A";
|
||||
static const char name_s3c2440a[] = "S3C2440A";
|
||||
@@ -123,6 +124,15 @@ static struct cpu_table cpu_ids[] __initdata = {
|
||||
.name = name_s3c2442
|
||||
},
|
||||
{
|
||||
+ .idcode = 0x32440aab,
|
||||
+ .idmask = 0xffffffff,
|
||||
+ .map_io = s3c244x_map_io,
|
||||
+ .init_clocks = s3c244x_init_clocks,
|
||||
+ .init_uarts = s3c244x_init_uarts,
|
||||
+ .init = s3c2442_init,
|
||||
+ .name = name_s3c2442b
|
||||
+ },
|
||||
+ {
|
||||
.idcode = 0x32412001,
|
||||
.idmask = 0xffffffff,
|
||||
.map_io = s3c2412_map_io,
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,45 @@
|
|||
From c96b850a977e3b7018c5ef1b145a3c11cb160265 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:44:50 +0100
|
||||
Subject: [PATCH] pcf50633-suspend-hacks.patch
|
||||
|
||||
---
|
||||
drivers/i2c/chips/pcf50633.c | 22 ++++++++++++++++++++--
|
||||
1 files changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||||
index 5488084..0cf5e53 100644
|
||||
--- a/drivers/i2c/chips/pcf50633.c
|
||||
+++ b/drivers/i2c/chips/pcf50633.c
|
||||
@@ -567,8 +567,26 @@ static void pcf50633_work(struct work_struct *work)
|
||||
*/
|
||||
ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50633_REG_INT1, 5,
|
||||
pcfirq);
|
||||
- if (ret != 5)
|
||||
- DEBUGP("Oh crap PMU IRQ register read failed %d\n", ret);
|
||||
+ if (ret != 5) {
|
||||
+ DEBUGP("Oh crap PMU IRQ register read failed -- "
|
||||
+ "retrying later %d\n", ret);
|
||||
+ /*
|
||||
+ * this situation can happen during resume, just defer
|
||||
+ * handling the interrupt until enough I2C is up we can
|
||||
+ * actually talk to the PMU. We can't just ignore this
|
||||
+ * because we are on a falling edge interrupt and our
|
||||
+ * PMU interrupt source does not clear until we read these
|
||||
+ * interrupt source registers.
|
||||
+ */
|
||||
+ if (!schedule_work(&pcf->work) && !pcf->working)
|
||||
+ dev_dbg(&pcf->client.dev, "work item may be lost\n");
|
||||
+
|
||||
+ /* we don't put the device here, hold it for next time */
|
||||
+ mutex_unlock(&pcf->working_lock);
|
||||
+ /* don't spew, delaying whatever else is happening */
|
||||
+ msleep(1);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (!pcf->coldplug_done) {
|
||||
DEBUGP("PMU Coldplug init\n");
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,586 @@
|
|||
From 70a0c17968f5151ce4f468785860e04bbc7a9d3c Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:56 +0100
|
||||
Subject: [PATCH] gta02-power_control.patch
|
||||
|
||||
---
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_bt.c | 84 +++++++++---
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_gps.c | 217 ++++++++++++++++++++++++--------
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_gsm.c | 97 ++++++++++++--
|
||||
3 files changed, 309 insertions(+), 89 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
index b1af441..d685ef7 100644
|
||||
--- a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
@@ -19,7 +19,9 @@
|
||||
#include <linux/pcf50606.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
#include <asm/arch/gta01.h>
|
||||
+#include <asm/arch/gta02.h>
|
||||
|
||||
#define DRVMSG "FIC Neo1973 Bluetooth Power Management"
|
||||
|
||||
@@ -27,14 +29,30 @@ static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!strcmp(attr->attr.name, "power_on")) {
|
||||
- if (pcf50606_onoff_get(pcf50606_global,
|
||||
- PCF50606_REGULATOR_D1REG) &&
|
||||
- pcf50606_voltage_get(pcf50606_global,
|
||||
- PCF50606_REGULATOR_D1REG) == 3100)
|
||||
- goto out_1;
|
||||
+ switch (machine_arch_type) {
|
||||
+ case MACH_TYPE_NEO1973_GTA01:
|
||||
+ if (pcf50606_onoff_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG) &&
|
||||
+ pcf50606_voltage_get(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG) == 3100)
|
||||
+ goto out_1;
|
||||
+ break;
|
||||
+ case MACH_TYPE_NEO1973_GTA02:
|
||||
+ if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN))
|
||||
+ goto out_1;
|
||||
+ break;
|
||||
+ }
|
||||
} else if (!strcmp(attr->attr.name, "reset")) {
|
||||
- if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0)
|
||||
- goto out_1;
|
||||
+ switch (machine_arch_type) {
|
||||
+ case MACH_TYPE_NEO1973_GTA01:
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0)
|
||||
+ goto out_1;
|
||||
+ break;
|
||||
+ case MACH_TYPE_NEO1973_GTA02:
|
||||
+ if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == 0)
|
||||
+ goto out_1;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
return strlcpy(buf, "0\n", 3);
|
||||
@@ -48,20 +66,37 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
|
||||
unsigned long on = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
if (!strcmp(attr->attr.name, "power_on")) {
|
||||
- /* if we are powering up, assert reset, then power, then
|
||||
- * release reset */
|
||||
- if (on) {
|
||||
- s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
- pcf50606_voltage_set(pcf50606_global,
|
||||
- PCF50606_REGULATOR_D1REG,
|
||||
- 3100);
|
||||
+ switch (machine_arch_type) {
|
||||
+ case MACH_TYPE_NEO1973_GTA01:
|
||||
+ /* if we are powering up, assert reset, then power,
|
||||
+ * then release reset */
|
||||
+ if (on) {
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
+ pcf50606_voltage_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG,
|
||||
+ 3100);
|
||||
+ }
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG, on);
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on);
|
||||
+ break;
|
||||
+ case MACH_TYPE_NEO1973_GTA02:
|
||||
+ if (on)
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 0);
|
||||
+ else
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 1);
|
||||
+ break;
|
||||
}
|
||||
- pcf50606_onoff_set(pcf50606_global,
|
||||
- PCF50606_REGULATOR_D1REG, on);
|
||||
- s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on);
|
||||
} else if (!strcmp(attr->attr.name, "reset")) {
|
||||
/* reset is low-active, so we need to invert */
|
||||
- s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1);
|
||||
+ switch (machine_arch_type) {
|
||||
+ case MACH_TYPE_NEO1973_GTA01:
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1);
|
||||
+ break;
|
||||
+ case MACH_TYPE_NEO1973_GTA02:
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, on ? 0 : 1);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -107,9 +142,16 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
|
||||
{
|
||||
dev_info(&pdev->dev, DRVMSG ": starting\n");
|
||||
|
||||
- /* we make sure that the voltage is off */
|
||||
- pcf50606_onoff_set(pcf50606_global,
|
||||
- PCF50606_REGULATOR_D1REG, 0);
|
||||
+ switch (machine_arch_type) {
|
||||
+ case MACH_TYPE_NEO1973_GTA01:
|
||||
+ /* we make sure that the voltage is off */
|
||||
+ pcf50606_onoff_set(pcf50606_global,
|
||||
+ PCF50606_REGULATOR_D1REG, 0);
|
||||
+ break;
|
||||
+ case MACH_TYPE_NEO1973_GTA02:
|
||||
+ /* FIXME: implementation */
|
||||
+ break;
|
||||
+ }
|
||||
/* we pull reset to low to make sure that the chip doesn't
|
||||
* drain power through the reset line */
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
|
||||
index f8cf719..6bd8054 100644
|
||||
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
|
||||
@@ -17,10 +17,18 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
-#include <linux/pcf50606.h>
|
||||
-
|
||||
#include <asm/hardware.h>
|
||||
+
|
||||
+#include <asm/mach-types.h>
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
#include <asm/arch/gta01.h>
|
||||
+#include <linux/pcf50606.h>
|
||||
+#endif
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+#include <asm/arch/gta02.h>
|
||||
+#include <linux/pcf50633.h>
|
||||
+#endif
|
||||
|
||||
/* This is the 2.8V supply for the RTC crystal, the mail clock crystal and
|
||||
* the input to VDD_RF */
|
||||
@@ -248,15 +256,42 @@ static int gps_power_1v5_get(void)
|
||||
/* This is the POWERON pin */
|
||||
static void gps_pwron_set(int on)
|
||||
{
|
||||
- s3c2410_gpio_setpin(GTA01_GPIO_GPS_PWRON, on);
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01())
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_GPS_PWRON, on);
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02()) {
|
||||
+ if (on)
|
||||
+ pcf50633_voltage_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO5, 3000);
|
||||
+ pcf50633_onoff_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO5, on);
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
}
|
||||
|
||||
static int gps_pwron_get(void)
|
||||
{
|
||||
- if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON))
|
||||
- return 1;
|
||||
- else
|
||||
- return 0;
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01()) {
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON))
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02()) {
|
||||
+ if (pcf50633_onoff_get(pcf50633_global, PCF50633_REGULATOR_LDO5))
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
/* This is the nRESET pin */
|
||||
@@ -441,17 +476,40 @@ static DEVICE_ATTR(power_sequence, 0644, power_sequence_read,
|
||||
static int gta01_pm_gps_suspend(struct platform_device *pdev,
|
||||
pm_message_t state)
|
||||
{
|
||||
- /* FIXME */
|
||||
- gps_power_sequence_down();
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01()) {
|
||||
+ /* FIXME */
|
||||
+ gps_power_sequence_down();
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02()) {
|
||||
+ /* FIXME */
|
||||
+ pcf50633_onoff_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO5, 0);
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gta01_pm_gps_resume(struct platform_device *pdev)
|
||||
{
|
||||
- /* FIXME */
|
||||
- gps_power_sequence_up();
|
||||
-
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01()) {
|
||||
+ /* FIXME */
|
||||
+ gps_power_sequence_up();
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02()) {
|
||||
+ /* FIXME */
|
||||
+ pcf50633_onoff_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO5, 1);
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@@ -476,59 +534,110 @@ static struct attribute_group gta01_gps_attr_group = {
|
||||
.attrs = gta01_gps_sysfs_entries,
|
||||
};
|
||||
|
||||
+static struct attribute *gta02_gps_sysfs_entries[] = {
|
||||
+ &dev_attr_pwron.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group gta02_gps_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = gta02_gps_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
static int __init gta01_pm_gps_probe(struct platform_device *pdev)
|
||||
{
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT);
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01()) {
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT);
|
||||
|
||||
- switch (system_rev) {
|
||||
- case GTA01v3_SYSTEM_REV:
|
||||
- break;
|
||||
- case GTA01v4_SYSTEM_REV:
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
|
||||
- break;
|
||||
- case GTA01Bv3_SYSTEM_REV:
|
||||
- case GTA01Bv4_SYSTEM_REV:
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, S3C2410_GPIO_OUTPUT);
|
||||
- /* fallthrough */
|
||||
- case GTA01Bv2_SYSTEM_REV:
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, S3C2410_GPIO_OUTPUT);
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, S3C2410_GPIO_OUTPUT);
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
|
||||
- break;
|
||||
- default:
|
||||
- dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
|
||||
- "AGPS PM features not available!!!\n",
|
||||
- system_rev);
|
||||
- return -1;
|
||||
- break;
|
||||
- }
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ break;
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, S3C2410_GPIO_OUTPUT);
|
||||
+ /* fallthrough */
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
|
||||
+ "AGPS PM features not available!!!\n",
|
||||
+ system_rev);
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- gps_power_sequence_down();
|
||||
+ gps_power_sequence_down();
|
||||
|
||||
- switch (system_rev) {
|
||||
- case GTA01v3_SYSTEM_REV:
|
||||
- case GTA01v4_SYSTEM_REV:
|
||||
- case GTA01Bv2_SYSTEM_REV:
|
||||
- gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
|
||||
- &dev_attr_power_tcxo_2v8.attr;
|
||||
- break;
|
||||
- case GTA01Bv3_SYSTEM_REV:
|
||||
- case GTA01Bv4_SYSTEM_REV:
|
||||
- gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
|
||||
- &dev_attr_power_core_1v5.attr;
|
||||
- gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-2] =
|
||||
- &dev_attr_power_vdd_core_1v5.attr;
|
||||
- break;
|
||||
- }
|
||||
+ switch (system_rev) {
|
||||
+ case GTA01v3_SYSTEM_REV:
|
||||
+ case GTA01v4_SYSTEM_REV:
|
||||
+ case GTA01Bv2_SYSTEM_REV:
|
||||
+ gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
|
||||
+ &dev_attr_power_tcxo_2v8.attr;
|
||||
+ break;
|
||||
+ case GTA01Bv3_SYSTEM_REV:
|
||||
+ case GTA01Bv4_SYSTEM_REV:
|
||||
+ gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
|
||||
+ &dev_attr_power_core_1v5.attr;
|
||||
+ gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-2] =
|
||||
+ &dev_attr_power_vdd_core_1v5.attr;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- return sysfs_create_group(&pdev->dev.kobj, >a01_gps_attr_group);
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, >a01_gps_attr_group);
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02()) {
|
||||
+ switch (system_rev) {
|
||||
+ case GTA02v2_SYSTEM_REV:
|
||||
+ case GTA02v3_SYSTEM_REV:
|
||||
+ case GTA02v4_SYSTEM_REV:
|
||||
+ case GTA02v5_SYSTEM_REV:
|
||||
+ case GTA02v6_SYSTEM_REV:
|
||||
+ pcf50633_voltage_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO5, 3000);
|
||||
+ pcf50633_onoff_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO5, 0);
|
||||
+ dev_info(&pdev->dev, "FIC Neo1973 GPS Power Managerment:"
|
||||
+ "starting\n");
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_warn(&pdev->dev, "Unknown GTA02 Revision 0x%x, "
|
||||
+ "AGPS PM features not available!!!\n",
|
||||
+ system_rev);
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, >a02_gps_attr_group);
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
static int gta01_pm_gps_remove(struct platform_device *pdev)
|
||||
{
|
||||
- gps_power_sequence_down();
|
||||
- sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group);
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01()) {
|
||||
+ gps_power_sequence_down();
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group);
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02()) {
|
||||
+ pcf50633_onoff_set(pcf50633_global, PCF50633_REGULATOR_LDO5, 0);
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, >a02_gps_attr_group);
|
||||
+ }
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
|
||||
index a1615f8..13cb45b 100644
|
||||
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
|
||||
@@ -19,8 +19,15 @@
|
||||
#include <linux/errno.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
#include <asm/arch/gta01.h>
|
||||
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+#include <asm/arch/gta02.h>
|
||||
+#include <linux/pcf50633.h>
|
||||
+#include <asm/arch/regs-gpioj.h>
|
||||
+#endif
|
||||
+
|
||||
struct gta01pm_priv {
|
||||
int gpio_ngsm_en;
|
||||
struct console *con;
|
||||
@@ -54,8 +61,16 @@ static ssize_t gsm_read(struct device *dev, struct device_attribute *attr,
|
||||
if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_RST))
|
||||
goto out_1;
|
||||
} else if (!strcmp(attr->attr.name, "download")) {
|
||||
- if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD))
|
||||
- goto out_1;
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01())
|
||||
+ if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD))
|
||||
+ goto out_1;
|
||||
+#endif
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02())
|
||||
+ if (s3c2410_gpio_getpin(GTA02_GPIO_nDL_GSM))
|
||||
+ goto out_1;
|
||||
+#endif
|
||||
}
|
||||
|
||||
return strlcpy(buf, "0\n", 3);
|
||||
@@ -70,32 +85,67 @@ static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
if (!strcmp(attr->attr.name, "power_on")) {
|
||||
if (on) {
|
||||
- dev_info(dev, "powering up GSM, thus disconnecting "
|
||||
- "serial console\n");
|
||||
+ if (gta01_gsm.con) {
|
||||
+ dev_info(dev, "powering up GSM, thus "
|
||||
+ "disconnecting serial console\n");
|
||||
|
||||
- if (gta01_gsm.con)
|
||||
console_stop(gta01_gsm.con);
|
||||
+ }
|
||||
|
||||
if (gta01_gsm.gpio_ngsm_en)
|
||||
s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 0);
|
||||
|
||||
+ switch (system_rev) {
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ case GTA02v2_SYSTEM_REV:
|
||||
+ case GTA02v3_SYSTEM_REV:
|
||||
+ case GTA02v4_SYSTEM_REV:
|
||||
+ case GTA02v5_SYSTEM_REV:
|
||||
+ case GTA02v6_SYSTEM_REV:
|
||||
+ pcf50633_gpio_set(pcf50633_global,
|
||||
+ PCF50633_GPIO2, 1);
|
||||
+ break;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_MODEM_ON, 1);
|
||||
} else {
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_MODEM_ON, 0);
|
||||
|
||||
+ switch (system_rev) {
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ case GTA02v2_SYSTEM_REV:
|
||||
+ case GTA02v3_SYSTEM_REV:
|
||||
+ case GTA02v4_SYSTEM_REV:
|
||||
+ case GTA02v5_SYSTEM_REV:
|
||||
+ case GTA02v6_SYSTEM_REV:
|
||||
+ pcf50633_gpio_set(pcf50633_global,
|
||||
+ PCF50633_GPIO2, 0);
|
||||
+ break;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
if (gta01_gsm.gpio_ngsm_en)
|
||||
s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 1);
|
||||
|
||||
- if (gta01_gsm.con)
|
||||
+ if (gta01_gsm.con) {
|
||||
console_start(gta01_gsm.con);
|
||||
|
||||
- dev_info(dev, "powered down GSM, thus enabling "
|
||||
- "serial console\n");
|
||||
+ dev_info(dev, "powered down GSM, thus enabling "
|
||||
+ "serial console\n");
|
||||
+ }
|
||||
}
|
||||
} else if (!strcmp(attr->attr.name, "reset")) {
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_MODEM_RST, on);
|
||||
} else if (!strcmp(attr->attr.name, "download")) {
|
||||
- s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on);
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ if (machine_is_neo1973_gta01())
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on);
|
||||
+#endif
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ if (machine_is_neo1973_gta02())
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, on);
|
||||
+#endif
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -111,6 +161,9 @@ static int gta01_gsm_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
/* GPIO state is saved/restored by S3C2410 core GPIO driver, so we
|
||||
* don't need to do anything here */
|
||||
|
||||
+ /* disable DL GSM to prevent jack_insert becoming flaoting */
|
||||
+ if (machine_is_neo1973_gta02())
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -124,6 +177,8 @@ static int gta01_gsm_resume(struct platform_device *pdev)
|
||||
if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_ON) && gta01_gsm.con)
|
||||
console_stop(gta01_gsm.con);
|
||||
|
||||
+ if (machine_is_neo1973_gta02())
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@@ -134,7 +189,7 @@ static int gta01_gsm_resume(struct platform_device *pdev)
|
||||
static struct attribute *gta01_gsm_sysfs_entries[] = {
|
||||
&dev_attr_power_on.attr,
|
||||
&dev_attr_reset.attr,
|
||||
- NULL,
|
||||
+ &dev_attr_download.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -158,8 +213,18 @@ static int __init gta01_gsm_probe(struct platform_device *pdev)
|
||||
gta01_gsm.gpio_ngsm_en = GTA01Bv2_GPIO_nGSM_EN;
|
||||
s3c2410_gpio_setpin(GTA01v3_GPIO_nGSM_EN, 0);
|
||||
break;
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+ case GTA02v1_SYSTEM_REV:
|
||||
+ case GTA02v2_SYSTEM_REV:
|
||||
+ case GTA02v3_SYSTEM_REV:
|
||||
+ case GTA02v4_SYSTEM_REV:
|
||||
+ case GTA02v5_SYSTEM_REV:
|
||||
+ case GTA02v6_SYSTEM_REV:
|
||||
+ gta01_gsm.gpio_ngsm_en = 0;
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
- dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
|
||||
+ dev_warn(&pdev->dev, "Unknown Neo1973 Revision 0x%x, "
|
||||
"some PM features not available!!!\n",
|
||||
system_rev);
|
||||
break;
|
||||
@@ -175,9 +240,13 @@ static int __init gta01_gsm_probe(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
|
||||
- gta01_gsm.con = find_s3c24xx_console();
|
||||
- if (!gta01_gsm.con)
|
||||
- dev_warn(&pdev->dev, "cannot find S3C24xx console driver\n");
|
||||
+ if (machine_is_neo1973_gta01()) {
|
||||
+ gta01_gsm.con = find_s3c24xx_console();
|
||||
+ if (!gta01_gsm.con)
|
||||
+ dev_warn(&pdev->dev,
|
||||
+ "cannot find S3C24xx console driver\n");
|
||||
+ } else
|
||||
+ gta01_gsm.con = NULL;
|
||||
|
||||
return sysfs_create_group(&pdev->dev.kobj, >a01_gsm_attr_group);
|
||||
}
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,778 @@
|
|||
From c03e9f46b9f15afc3e8980ae28666ff30907b173 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:56 +0100
|
||||
Subject: [PATCH] gta02-sound.patch
|
||||
|
||||
---
|
||||
include/sound/soc-dapm.h | 7 +
|
||||
sound/soc/s3c24xx/Kconfig | 9 +
|
||||
sound/soc/s3c24xx/Makefile | 3 +
|
||||
sound/soc/s3c24xx/neo1973_gta02_wm8753.c | 667 ++++++++++++++++++++++++++++++
|
||||
sound/soc/soc-dapm.c | 24 ++
|
||||
5 files changed, 710 insertions(+), 0 deletions(-)
|
||||
create mode 100644 sound/soc/s3c24xx/neo1973_gta02_wm8753.c
|
||||
|
||||
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
|
||||
index a105b01..e867447 100644
|
||||
--- a/include/sound/soc-dapm.h
|
||||
+++ b/include/sound/soc-dapm.h
|
||||
@@ -225,6 +225,13 @@ int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec,
|
||||
char *pin, int status);
|
||||
int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec);
|
||||
|
||||
+/* dapm audio endpoint control */
|
||||
+int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec,
|
||||
+ char *pin, int status);
|
||||
+int snd_soc_dapm_get_endpoint(struct snd_soc_codec *codec,
|
||||
+ char *pin);
|
||||
+int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec);
|
||||
+
|
||||
/* dapm widget types */
|
||||
enum snd_soc_dapm_type {
|
||||
snd_soc_dapm_input = 0, /* input pin */
|
||||
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
|
||||
index 1f6dbfc..3155c43 100644
|
||||
--- a/sound/soc/s3c24xx/Kconfig
|
||||
+++ b/sound/soc/s3c24xx/Kconfig
|
||||
@@ -28,6 +28,15 @@ config SND_S3C24XX_SOC_NEO1973_WM8753
|
||||
Say Y if you want to add support for SoC audio on smdk2440
|
||||
with the WM8753.
|
||||
|
||||
+config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753
|
||||
+ tristate "SoC I2S Audio support for NEO1973 GTA02 - WM8753"
|
||||
+ depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02
|
||||
+ select SND_S3C24XX_SOC_I2S
|
||||
+ select SND_SOC_WM8753
|
||||
+ help
|
||||
+ Say Y if you want to add support for SoC audio on neo1973 gta02
|
||||
+ with the WM8753 codec
|
||||
+
|
||||
config SND_S3C24XX_SOC_SMDK2443_WM9710
|
||||
tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
|
||||
depends on SND_S3C24XX_SOC && MACH_SMDK2443
|
||||
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
|
||||
index 0aa5fb0..f154cb1 100644
|
||||
--- a/sound/soc/s3c24xx/Makefile
|
||||
+++ b/sound/soc/s3c24xx/Makefile
|
||||
@@ -13,7 +13,10 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
|
||||
snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
|
||||
snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
|
||||
snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
|
||||
+snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
|
||||
|
||||
obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
|
||||
obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
|
||||
obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
|
||||
+obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
|
||||
+
|
||||
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
|
||||
new file mode 100644
|
||||
index 0000000..f32cba3
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
|
||||
@@ -0,0 +1,667 @@
|
||||
+/*
|
||||
+ * neo1973_gta02_wm8753.c -- SoC audio for Neo1973
|
||||
+ *
|
||||
+ * Copyright 2007 OpenMoko Inc
|
||||
+ * Author: Graeme Gregory <graeme@openmoko.org>
|
||||
+ * Copyright 2007 Wolfson Microelectronics PLC.
|
||||
+ * Author: Graeme Gregory <linux@wolfsonmicro.com>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Revision history
|
||||
+ * 06th Nov 2007 Changed from GTA01 to GTA02
|
||||
+ * 20th Jan 2007 Initial version.
|
||||
+ * 05th Feb 2007 Rename all to Neo1973
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/moduleparam.h>
|
||||
+#include <linux/timer.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <sound/driver.h>
|
||||
+#include <sound/core.h>
|
||||
+#include <sound/pcm.h>
|
||||
+#include <sound/soc.h>
|
||||
+#include <sound/soc-dapm.h>
|
||||
+
|
||||
+#include <asm/mach-types.h>
|
||||
+#include <asm/hardware/scoop.h>
|
||||
+#include <asm/plat-s3c24xx/regs-iis.h>
|
||||
+#include <asm/arch/regs-clock.h>
|
||||
+#include <asm/arch/regs-gpio.h>
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/arch/audio.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/arch/spi-gpio.h>
|
||||
+#include <asm/arch/regs-gpioj.h>
|
||||
+#include <asm/arch/gta02.h>
|
||||
+#include "../codecs/wm8753.h"
|
||||
+#include "s3c24xx-pcm.h"
|
||||
+#include "s3c24xx-i2s.h"
|
||||
+
|
||||
+/* define the scenarios */
|
||||
+#define NEO_AUDIO_OFF 0
|
||||
+#define NEO_GSM_CALL_AUDIO_HANDSET 1
|
||||
+#define NEO_GSM_CALL_AUDIO_HEADSET 2
|
||||
+#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3
|
||||
+#define NEO_STEREO_TO_SPEAKERS 4
|
||||
+#define NEO_STEREO_TO_HEADPHONES 5
|
||||
+#define NEO_CAPTURE_HANDSET 6
|
||||
+#define NEO_CAPTURE_HEADSET 7
|
||||
+#define NEO_CAPTURE_BLUETOOTH 8
|
||||
+#define NEO_STEREO_TO_HANDSET_SPK 9
|
||||
+
|
||||
+static struct snd_soc_machine neo1973_gta02;
|
||||
+
|
||||
+static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
+ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
|
||||
+ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
+ unsigned int pll_out = 0, bclk = 0;
|
||||
+ int ret = 0;
|
||||
+ unsigned long iis_clkrate;
|
||||
+
|
||||
+ iis_clkrate = s3c24xx_i2s_get_clockrate();
|
||||
+
|
||||
+ switch (params_rate(params)) {
|
||||
+ case 8000:
|
||||
+ case 16000:
|
||||
+ pll_out = 12288000;
|
||||
+ break;
|
||||
+ case 48000:
|
||||
+ bclk = WM8753_BCLK_DIV_4;
|
||||
+ pll_out = 12288000;
|
||||
+ break;
|
||||
+ case 96000:
|
||||
+ bclk = WM8753_BCLK_DIV_2;
|
||||
+ pll_out = 12288000;
|
||||
+ break;
|
||||
+ case 11025:
|
||||
+ bclk = WM8753_BCLK_DIV_16;
|
||||
+ pll_out = 11289600;
|
||||
+ break;
|
||||
+ case 22050:
|
||||
+ bclk = WM8753_BCLK_DIV_8;
|
||||
+ pll_out = 11289600;
|
||||
+ break;
|
||||
+ case 44100:
|
||||
+ bclk = WM8753_BCLK_DIV_4;
|
||||
+ pll_out = 11289600;
|
||||
+ break;
|
||||
+ case 88200:
|
||||
+ bclk = WM8753_BCLK_DIV_2;
|
||||
+ pll_out = 11289600;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* set codec DAI configuration */
|
||||
+ ret = codec_dai->dai_ops.set_fmt(codec_dai,
|
||||
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_CBM_CFM);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set cpu DAI configuration */
|
||||
+ ret = cpu_dai->dai_ops.set_fmt(cpu_dai,
|
||||
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_CBM_CFM);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set the codec system clock for DAC and ADC */
|
||||
+ ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out,
|
||||
+ SND_SOC_CLOCK_IN);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set MCLK division for sample rate */
|
||||
+ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
|
||||
+ S3C2410_IISMOD_32FS );
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set codec BCLK division for sample rate */
|
||||
+ ret = codec_dai->dai_ops.set_clkdiv(codec_dai,
|
||||
+ WM8753_BCLKDIV, bclk);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set prescaler division for sample rate */
|
||||
+ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
|
||||
+ S3C24XX_PRESCALE(4,4));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* codec PLL input is PCLK/4 */
|
||||
+ ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1,
|
||||
+ iis_clkrate / 4, pll_out);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
+ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
|
||||
+
|
||||
+ /* disable the PLL */
|
||||
+ return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Neo1973 WM8753 HiFi DAI opserations.
|
||||
+ */
|
||||
+static struct snd_soc_ops neo1973_gta02_hifi_ops = {
|
||||
+ .hw_params = neo1973_gta02_hifi_hw_params,
|
||||
+ .hw_free = neo1973_gta02_hifi_hw_free,
|
||||
+};
|
||||
+
|
||||
+static int neo1973_gta02_voice_hw_params(
|
||||
+ struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
+ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
|
||||
+ unsigned int pcmdiv = 0;
|
||||
+ int ret = 0;
|
||||
+ unsigned long iis_clkrate;
|
||||
+
|
||||
+ iis_clkrate = s3c24xx_i2s_get_clockrate();
|
||||
+
|
||||
+ if (params_rate(params) != 8000)
|
||||
+ return -EINVAL;
|
||||
+ if (params_channels(params) != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
|
||||
+
|
||||
+ /* todo: gg check mode (DSP_B) against CSR datasheet */
|
||||
+ /* set codec DAI configuration */
|
||||
+ ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
|
||||
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set the codec system clock for DAC and ADC */
|
||||
+ ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK,
|
||||
+ 12288000, SND_SOC_CLOCK_IN);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* set codec PCM division for sample rate */
|
||||
+ ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV,
|
||||
+ pcmdiv);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* configue and enable PLL for 12.288MHz output */
|
||||
+ ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2,
|
||||
+ iis_clkrate / 4, 12288000);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
+ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
|
||||
+
|
||||
+ /* disable the PLL */
|
||||
+ return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0);
|
||||
+}
|
||||
+
|
||||
+static struct snd_soc_ops neo1973_gta02_voice_ops = {
|
||||
+ .hw_params = neo1973_gta02_voice_hw_params,
|
||||
+ .hw_free = neo1973_gta02_voice_hw_free,
|
||||
+};
|
||||
+
|
||||
+#define LM4853_AMP 1
|
||||
+#define LM4853_SPK 2
|
||||
+
|
||||
+static u8 lm4853_state=0;
|
||||
+
|
||||
+static int lm4853_set_state(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ if(val) {
|
||||
+ lm4853_state |= LM4853_AMP;
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT,0);
|
||||
+ } else {
|
||||
+ lm4853_state &= ~LM4853_AMP;
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT,1);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lm4853_get_state(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ if(val) {
|
||||
+ lm4853_state |= LM4853_SPK;
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_HP_IN,0);
|
||||
+ } else {
|
||||
+ lm4853_state &= ~LM4853_SPK;
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_HP_IN,1);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_set_stereo_out(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Stereo Out", val);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_get_stereo_out(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+
|
||||
+ ucontrol->value.integer.value[0] =
|
||||
+ snd_soc_dapm_get_endpoint(codec, "Stereo Out");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int neo1973_gta02_set_gsm_out(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ snd_soc_dapm_set_endpoint(codec, "GSM Line Out", val);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_get_gsm_out(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+
|
||||
+ ucontrol->value.integer.value[0] =
|
||||
+ snd_soc_dapm_get_endpoint(codec, "GSM Line Out");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_set_gsm_in(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ snd_soc_dapm_set_endpoint(codec, "GSM Line In", val);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_get_gsm_in(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+
|
||||
+ ucontrol->value.integer.value[0] =
|
||||
+ snd_soc_dapm_get_endpoint(codec, "GSM Line In");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_set_headset_mic(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Headset Mic", val);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_get_headset_mic(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+
|
||||
+ ucontrol->value.integer.value[0] =
|
||||
+ snd_soc_dapm_get_endpoint(codec, "Headset Mic");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_set_handset_mic(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Handset Mic", val);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_get_handset_mic(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+
|
||||
+ ucontrol->value.integer.value[0] =
|
||||
+ snd_soc_dapm_get_endpoint(codec, "Handset Mic");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_set_handset_spk(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+ int val = ucontrol->value.integer.value[0];
|
||||
+
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Handset Spk", val);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int neo1973_gta02_get_handset_spk(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
+
|
||||
+ ucontrol->value.integer.value[0] =
|
||||
+ snd_soc_dapm_get_endpoint(codec, "Handset Spk");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
|
||||
+ SND_SOC_DAPM_LINE("Stereo Out", NULL),
|
||||
+ SND_SOC_DAPM_LINE("GSM Line Out", NULL),
|
||||
+ SND_SOC_DAPM_LINE("GSM Line In", NULL),
|
||||
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
+ SND_SOC_DAPM_MIC("Handset Mic", NULL),
|
||||
+ SND_SOC_DAPM_SPK("Handset Spk", NULL),
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* example machine audio_mapnections */
|
||||
+static const char* audio_map[][3] = {
|
||||
+
|
||||
+ /* Connections to the lm4853 amp */
|
||||
+ {"Stereo Out", NULL, "LOUT1"},
|
||||
+ {"Stereo Out", NULL, "ROUT1"},
|
||||
+
|
||||
+ /* Connections to the GSM Module */
|
||||
+ {"GSM Line Out", NULL, "MONO1"},
|
||||
+ {"GSM Line Out", NULL, "MONO2"},
|
||||
+ {"RXP", NULL, "GSM Line In"},
|
||||
+ {"RXN", NULL, "GSM Line In"},
|
||||
+
|
||||
+ /* Connections to Headset */
|
||||
+ {"MIC1", NULL, "Mic Bias"},
|
||||
+ {"Mic Bias", NULL, "Headset Mic"},
|
||||
+
|
||||
+ /* Call Mic */
|
||||
+ {"MIC2", NULL, "Mic Bias"},
|
||||
+ {"MIC2N", NULL, "Mic Bias"},
|
||||
+ {"Mic Bias", NULL, "Handset Mic"},
|
||||
+
|
||||
+ /* Call Speaker */
|
||||
+ {"Handset Spk", NULL, "LOUT2"},
|
||||
+ {"Handset Spk", NULL, "ROUT2"},
|
||||
+
|
||||
+ /* Connect the ALC pins */
|
||||
+ {"ACIN", NULL, "ACOP"},
|
||||
+
|
||||
+ {NULL, NULL, NULL},
|
||||
+};
|
||||
+
|
||||
+static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
|
||||
+ SOC_SINGLE_EXT("DAPM Stereo Out Switch", 0, 0, 1, 0,
|
||||
+ neo1973_gta02_get_stereo_out,
|
||||
+ neo1973_gta02_set_stereo_out),
|
||||
+ SOC_SINGLE_EXT("DAPM GSM Line Out Switch", 1, 0, 1, 0,
|
||||
+ neo1973_gta02_get_gsm_out,
|
||||
+ neo1973_gta02_set_gsm_out),
|
||||
+ SOC_SINGLE_EXT("DAPM GSM Line In Switch", 2, 0, 1, 0,
|
||||
+ neo1973_gta02_get_gsm_in,
|
||||
+ neo1973_gta02_set_gsm_in),
|
||||
+ SOC_SINGLE_EXT("DAPM Headset Mic Switch", 3, 0, 1, 0,
|
||||
+ neo1973_gta02_get_headset_mic,
|
||||
+ neo1973_gta02_set_headset_mic),
|
||||
+ SOC_SINGLE_EXT("DAPM Handset Mic Switch", 4, 0, 1, 0,
|
||||
+ neo1973_gta02_get_handset_mic,
|
||||
+ neo1973_gta02_set_handset_mic),
|
||||
+ SOC_SINGLE_EXT("DAPM Handset Spk Switch", 5, 0, 1, 0,
|
||||
+ neo1973_gta02_get_handset_spk,
|
||||
+ neo1973_gta02_set_handset_spk),
|
||||
+ SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0,
|
||||
+ lm4853_get_state,
|
||||
+ lm4853_set_state),
|
||||
+ SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0,
|
||||
+ lm4853_get_spk,
|
||||
+ lm4853_set_spk),
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * This is an example machine initialisation for a wm8753 connected to a
|
||||
+ * neo1973 GTA02.
|
||||
+ */
|
||||
+static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
|
||||
+{
|
||||
+ int i, err;
|
||||
+
|
||||
+ /* set up NC codec pins */
|
||||
+ snd_soc_dapm_set_endpoint(codec, "OUT3", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "OUT4", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "LINE1", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "LINE2", 0);
|
||||
+
|
||||
+ /* Add neo1973 gta02 specific widgets */
|
||||
+ for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++)
|
||||
+ snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]);
|
||||
+
|
||||
+ /* add neo1973 gta02 specific controls */
|
||||
+ for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_gta02_controls); i++) {
|
||||
+ err = snd_ctl_add(codec->card,
|
||||
+ snd_soc_cnew(&wm8753_neo1973_gta02_controls[i],
|
||||
+ codec, NULL));
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ /* set up neo1973 gta02 specific audio path audio_mapnects */
|
||||
+ for (i = 0; audio_map[i][0] != NULL; i++) {
|
||||
+ snd_soc_dapm_connect_input(codec, audio_map[i][0],
|
||||
+ audio_map[i][1], audio_map[i][2]);
|
||||
+ }
|
||||
+
|
||||
+ /* set endpoints to default off mode */
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Stereo Out", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "GSM Line Out",0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Handset Mic", 0);
|
||||
+ snd_soc_dapm_set_endpoint(codec, "Handset Spk", 0);
|
||||
+
|
||||
+ snd_soc_dapm_sync_endpoints(codec);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * BT Codec DAI
|
||||
+ */
|
||||
+static struct snd_soc_cpu_dai bt_dai =
|
||||
+{ .name = "Bluetooth",
|
||||
+ .id = 0,
|
||||
+ .type = SND_SOC_DAI_PCM,
|
||||
+ .playback = {
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 1,
|
||||
+ .rates = SNDRV_PCM_RATE_8000,
|
||||
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
|
||||
+ .capture = {
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 1,
|
||||
+ .rates = SNDRV_PCM_RATE_8000,
|
||||
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
|
||||
+};
|
||||
+
|
||||
+static struct snd_soc_dai_link neo1973_gta02_dai[] = {
|
||||
+{ /* Hifi Playback - for similatious use with voice below */
|
||||
+ .name = "WM8753",
|
||||
+ .stream_name = "WM8753 HiFi",
|
||||
+ .cpu_dai = &s3c24xx_i2s_dai,
|
||||
+ .codec_dai = &wm8753_dai[WM8753_DAI_HIFI],
|
||||
+ .init = neo1973_gta02_wm8753_init,
|
||||
+ .ops = &neo1973_gta02_hifi_ops,
|
||||
+},
|
||||
+{ /* Voice via BT */
|
||||
+ .name = "Bluetooth",
|
||||
+ .stream_name = "Voice",
|
||||
+ .cpu_dai = &bt_dai,
|
||||
+ .codec_dai = &wm8753_dai[WM8753_DAI_VOICE],
|
||||
+ .ops = &neo1973_gta02_voice_ops,
|
||||
+},
|
||||
+};
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+int neo1973_gta02_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int neo1973_gta02_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ if(lm4853_state & LM4853_AMP)
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define neo1973_gta02_suspend NULL
|
||||
+#define neo1973_gta02_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct snd_soc_machine neo1973_gta02 = {
|
||||
+ .name = "neo1973-gta02",
|
||||
+ .suspend_pre = neo1973_gta02_suspend,
|
||||
+ .resume_post = neo1973_gta02_resume,
|
||||
+ .dai_link = neo1973_gta02_dai,
|
||||
+ .num_links = ARRAY_SIZE(neo1973_gta02_dai),
|
||||
+};
|
||||
+
|
||||
+static struct wm8753_setup_data neo1973_gta02_wm8753_setup = {
|
||||
+ .i2c_address = 0x1a,
|
||||
+};
|
||||
+
|
||||
+static struct snd_soc_device neo1973_gta02_snd_devdata = {
|
||||
+ .machine = &neo1973_gta02,
|
||||
+ .platform = &s3c24xx_soc_platform,
|
||||
+ .codec_dev = &soc_codec_dev_wm8753,
|
||||
+ .codec_data = &neo1973_gta02_wm8753_setup,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device *neo1973_gta02_snd_device;
|
||||
+
|
||||
+static int __init neo1973_gta02_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!machine_is_neo1973_gta02()) {
|
||||
+ printk(KERN_INFO
|
||||
+ "Only GTA02 hardware supported by ASoc driver\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
+ if (!neo1973_gta02_snd_device)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(neo1973_gta02_snd_device,
|
||||
+ &neo1973_gta02_snd_devdata);
|
||||
+ neo1973_gta02_snd_devdata.dev = &neo1973_gta02_snd_device->dev;
|
||||
+ ret = platform_device_add(neo1973_gta02_snd_device);
|
||||
+
|
||||
+ if (ret)
|
||||
+ platform_device_put(neo1973_gta02_snd_device);
|
||||
+
|
||||
+ /* Initialise GPIOs used by amp */
|
||||
+ s3c2410_gpio_cfgpin(GTA02_GPIO_HP_IN, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_cfgpin(GTA02_GPIO_AMP_SHUT, S3C2410_GPIO_OUTPUT);
|
||||
+
|
||||
+ /* Amp off by default */
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT, 1);
|
||||
+
|
||||
+ /* Speaker off by default */
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_HP_IN, 1);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit neo1973_gta02_exit(void)
|
||||
+{
|
||||
+ platform_device_unregister(neo1973_gta02_snd_device);
|
||||
+}
|
||||
+
|
||||
+module_init(neo1973_gta02_init);
|
||||
+module_exit(neo1973_gta02_exit);
|
||||
+
|
||||
+/* Module information */
|
||||
+MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org");
|
||||
+MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
|
||||
index af3326c..95df1ff 100644
|
||||
--- a/sound/soc/soc-dapm.c
|
||||
+++ b/sound/soc/soc-dapm.c
|
||||
@@ -1343,6 +1343,30 @@ int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec,
|
||||
EXPORT_SYMBOL_GPL(snd_soc_dapm_set_endpoint);
|
||||
|
||||
/**
|
||||
+ * snd_soc_dapm_get_endpoint - get audio endpoint status
|
||||
+ * @codec: audio codec
|
||||
+ * @endpoint: audio signal endpoint (or start point)
|
||||
+ *
|
||||
+ * Get audio endpoint status - connected or disconnected.
|
||||
+ *
|
||||
+ * Returns status
|
||||
+ */
|
||||
+int snd_soc_dapm_get_endpoint(struct snd_soc_codec *codec,
|
||||
+ char *endpoint)
|
||||
+{
|
||||
+ struct snd_soc_dapm_widget *w;
|
||||
+
|
||||
+ list_for_each_entry(w, &codec->dapm_widgets, list) {
|
||||
+ if (!strcmp(w->name, endpoint)) {
|
||||
+ return w->connected;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(snd_soc_dapm_get_endpoint);
|
||||
+
|
||||
+/**
|
||||
* snd_soc_dapm_free - free dapm resources
|
||||
* @socdev: SoC device
|
||||
*
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,781 @@
|
|||
From 65c5d85b4cf89969d2e2e981c018bf0ef1c03a2a Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:56 +0100
|
||||
Subject: [PATCH] lis302dl.patch
|
||||
This is a Linux driver for the STmicro LIS302DL 3-axis accelerometer.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 46 +++-
|
||||
drivers/input/misc/Kconfig | 9 +
|
||||
drivers/input/misc/Makefile | 2 +
|
||||
drivers/input/misc/lis302dl.c | 633 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/lis302dl.h | 11 +
|
||||
5 files changed, 700 insertions(+), 1 deletions(-)
|
||||
create mode 100644 drivers/input/misc/lis302dl.c
|
||||
create mode 100644 include/linux/lis302dl.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index f72a5ae..d11da10 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <linux/mtd/physmap.h>
|
||||
|
||||
#include <linux/pcf50633.h>
|
||||
+#include <linux/lis302dl.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
@@ -463,7 +464,7 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = {
|
||||
.oversampling_shift = 5,
|
||||
};
|
||||
|
||||
-/* SPI */
|
||||
+/* SPI: LCM control interface attached to Glamo3362 */
|
||||
|
||||
static struct spi_board_info gta02_spi_board_info[] = {
|
||||
{
|
||||
@@ -504,6 +505,48 @@ static struct platform_device gta01_led_dev = {
|
||||
.resource = gta01_led_resources,
|
||||
};
|
||||
|
||||
+/* SPI: Accelerometers attached to SPI of s3c244x */
|
||||
+
|
||||
+static void gta02_spi_acc_set_cs(struct s3c2410_spi_info *spi, int cs, int pol)
|
||||
+{
|
||||
+ s3c2410_gpio_setpin(cs, pol);
|
||||
+}
|
||||
+
|
||||
+static const struct lis302dl_platform_data lis302_pdata[] = {
|
||||
+ {
|
||||
+ .name = "lis302-1 (top)"
|
||||
+ }, {
|
||||
+ .name = "lis302-2 (bottom)"
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct spi_board_info gta02_spi_acc_bdinfo[] = {
|
||||
+ {
|
||||
+ .modalias = "lis302dl",
|
||||
+ .platform_data = &lis302_pdata[0],
|
||||
+ .irq = GTA02_IRQ_GSENSOR_1,
|
||||
+ .max_speed_hz = 400 * 1000,
|
||||
+ .bus_num = 1,
|
||||
+ .chip_select = S3C2410_GPD12,
|
||||
+ .mode = SPI_MODE_3,
|
||||
+ },
|
||||
+ {
|
||||
+ .modalias = "lis302dl",
|
||||
+ .platform_data = &lis302_pdata[1],
|
||||
+ .irq = GTA02_IRQ_GSENSOR_2,
|
||||
+ .max_speed_hz = 400 * 1000,
|
||||
+ .bus_num = 1,
|
||||
+ .chip_select = S3C2410_GPD13,
|
||||
+ .mode = SPI_MODE_3,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct s3c2410_spi_info gta02_spi_acc_cfg = {
|
||||
+ .set_cs = gta02_spi_acc_set_cs,
|
||||
+ .board_size = ARRAY_SIZE(gta02_spi_acc_bdinfo),
|
||||
+ .board_info = gta02_spi_acc_bdinfo,
|
||||
+};
|
||||
+
|
||||
static struct resource gta02_led_resources[] = {
|
||||
{
|
||||
.name = "gta02-power:orange",
|
||||
@@ -746,6 +789,7 @@ static void __init gta02_machine_init(void)
|
||||
s3c_device_usb.dev.platform_data = >a02_usb_info;
|
||||
s3c_device_nand.dev.platform_data = >a02_nand_info;
|
||||
s3c_device_sdi.dev.platform_data = >a02_mmc_cfg;
|
||||
+ s3c_device_spi1.dev.platform_data = >a02_spi_acc_cfg;
|
||||
|
||||
/* Only GTA02v1 has a SD_DETECT GPIO. Since the slot is not
|
||||
* hot-pluggable, this is not required anyway */
|
||||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
|
||||
index 432699d..ac8bcf4 100644
|
||||
--- a/drivers/input/misc/Kconfig
|
||||
+++ b/drivers/input/misc/Kconfig
|
||||
@@ -197,4 +197,13 @@ config HP_SDC_RTC
|
||||
Say Y here if you want to support the built-in real time clock
|
||||
of the HP SDC controller.
|
||||
|
||||
+config INPUT_LIS302DL
|
||||
+ tristate "STmicro LIS302DL 3-axis accelerometer"
|
||||
+ depends on SPI_MASTER
|
||||
+ help
|
||||
+ SPI driver for the STmicro LIS302DL 3-axis accelerometer.
|
||||
+
|
||||
+ The userspece interface is a 3-axis (X/Y/Z) relative movement
|
||||
+ Linux input device, reporting REL_[XYZ] events.
|
||||
+
|
||||
endif
|
||||
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
|
||||
index ebd39f2..0d223ba 100644
|
||||
--- a/drivers/input/misc/Makefile
|
||||
+++ b/drivers/input/misc/Makefile
|
||||
@@ -20,3 +20,4 @@
|
||||
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
|
||||
obj-$(CONFIG_INPUT_APANEL) += apanel.o
|
||||
obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o
|
||||
+obj-$(CONFIG_INPUT_LIS302DL) += lis302dl.o
|
||||
diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
|
||||
new file mode 100644
|
||||
index 0000000..45c41c8
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/misc/lis302dl.c
|
||||
@@ -0,0 +1,633 @@
|
||||
+/* Linux kernel driver for the ST LIS302D 3-axis accelerometer
|
||||
+ *
|
||||
+ * Copyright (C) 2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of
|
||||
+ * the License, 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
|
||||
+ *
|
||||
+ * TODO
|
||||
+ * * statistics for overflow events
|
||||
+ * * configuration interface (sysfs) for
|
||||
+ * * enable/disable x/y/z axis data ready
|
||||
+ * * enable/disable resume from freee fall / click
|
||||
+ * * free fall / click parameters
|
||||
+ * * high pass filter parameters
|
||||
+ */
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/sysfs.h>
|
||||
+
|
||||
+#include <linux/lis302dl.h>
|
||||
+
|
||||
+#include <linux/spi/spi.h>
|
||||
+
|
||||
+#define LIS302DL_WHO_AM_I_MAGIC 0x3b
|
||||
+
|
||||
+enum lis302dl_reg {
|
||||
+ LIS302DL_REG_WHO_AM_I = 0x0f,
|
||||
+ LIS302DL_REG_CTRL1 = 0x20,
|
||||
+ LIS302DL_REG_CTRL2 = 0x21,
|
||||
+ LIS302DL_REG_CTRL3 = 0x22,
|
||||
+ LIS302DL_REG_HP_FILTER_RESET = 0x23,
|
||||
+ LIS302DL_REG_STATUS = 0x27,
|
||||
+ LIS302DL_REG_OUT_X = 0x29,
|
||||
+ LIS302DL_REG_OUT_Y = 0x2b,
|
||||
+ LIS302DL_REG_OUT_Z = 0x2d,
|
||||
+ LIS302DL_REG_FF_WU_CFG_1 = 0x30,
|
||||
+ LIS302DL_REG_FF_WU_SRC_1 = 0x31,
|
||||
+ LIS302DL_REG_FF_WU_THS_1 = 0x32,
|
||||
+ LIS302DL_REG_FF_WU_DURATION_1 = 0x33,
|
||||
+ LIS302DL_REG_FF_WU_CFG_2 = 0x34,
|
||||
+ LIS302DL_REG_FF_WU_SRC_2 = 0x35,
|
||||
+ LIS302DL_REG_FF_WU_THS_2 = 0x36,
|
||||
+ LIS302DL_REG_FF_WU_DURATION_2 = 0x37,
|
||||
+ LIS302DL_REG_CLICK_CFG = 0x38,
|
||||
+ LIS302DL_REG_CLICK_SRC = 0x39,
|
||||
+ LIS302DL_REG_CLICK_THSY_X = 0x3b,
|
||||
+ LIS302DL_REG_CLICK_THSZ = 0x3c,
|
||||
+ LIS302DL_REG_CLICK_TIME_LIMIT = 0x3d,
|
||||
+ LIS302DL_REG_CLICK_LATENCY = 0x3e,
|
||||
+ LIS302DL_REG_CLICK_WINDOW = 0x3f,
|
||||
+};
|
||||
+
|
||||
+enum lis302dl_reg_ctrl1 {
|
||||
+ LIS302DL_CTRL1_Xen = 0x01,
|
||||
+ LIS302DL_CTRL1_Yen = 0x02,
|
||||
+ LIS302DL_CTRL1_Zen = 0x04,
|
||||
+ LIS302DL_CTRL1_STM = 0x08,
|
||||
+ LIS302DL_CTRL1_STP = 0x10,
|
||||
+ LIS302DL_CTRL1_FS = 0x20,
|
||||
+ LIS302DL_CTRL1_PD = 0x40,
|
||||
+ LIS302DL_CTRL1_DR = 0x80,
|
||||
+};
|
||||
+
|
||||
+enum lis302dl_reg_ctrl3 {
|
||||
+ LIS302DL_CTRL3_PP_OD = 0x40,
|
||||
+};
|
||||
+
|
||||
+enum lis302dl_reg_status {
|
||||
+ LIS302DL_STATUS_XDA = 0x01,
|
||||
+ LIS302DL_STATUS_YDA = 0x02,
|
||||
+ LIS302DL_STATUS_ZDA = 0x04,
|
||||
+ LIS302DL_STATUS_XYZDA = 0x08,
|
||||
+ LIS302DL_STATUS_XOR = 0x10,
|
||||
+ LIS302DL_STATUS_YOR = 0x20,
|
||||
+ LIS302DL_STATUS_ZOR = 0x40,
|
||||
+ LIS302DL_STATUS_XYZOR = 0x80,
|
||||
+};
|
||||
+
|
||||
+enum lis302dl_reg_ffwusrc1 {
|
||||
+ LIS302DL_FFWUSRC1_XL = 0x01,
|
||||
+ LIS302DL_FFWUSRC1_XH = 0x02,
|
||||
+ LIS302DL_FFWUSRC1_YL = 0x04,
|
||||
+ LIS302DL_FFWUSRC1_YH = 0x08,
|
||||
+ LIS302DL_FFWUSRC1_ZL = 0x10,
|
||||
+ LIS302DL_FFWUSRC1_ZH = 0x20,
|
||||
+ LIS302DL_FFWUSRC1_IA = 0x40,
|
||||
+};
|
||||
+
|
||||
+enum lis302dl_reg_cloik_src {
|
||||
+ LIS302DL_CLICKSRC_SINGLE_X = 0x01,
|
||||
+ LIS302DL_CLICKSRC_DOUBLE_X = 0x02,
|
||||
+ LIS302DL_CLICKSRC_SINGLE_Y = 0x04,
|
||||
+ LIS302DL_CLICKSRC_DOUBLE_Y = 0x08,
|
||||
+ LIS302DL_CLICKSRC_SINGLE_Z = 0x10,
|
||||
+ LIS302DL_CLICKSRC_DOUBLE_Z = 0x20,
|
||||
+ LIS302DL_CLICKSRC_IA = 0x40,
|
||||
+};
|
||||
+
|
||||
+struct lis302dl_info {
|
||||
+ struct spi_device *spi_dev;
|
||||
+ struct input_dev *input_dev;
|
||||
+ struct mutex lock;
|
||||
+ struct work_struct work;
|
||||
+ unsigned int flags;
|
||||
+ unsigned int working;
|
||||
+ u_int8_t regs[0x40];
|
||||
+};
|
||||
+
|
||||
+#define LIS302DL_F_WUP_FF 0x0001 /* wake up from free fall */
|
||||
+#define LIS302DL_F_WUP_CLICK 0x0002
|
||||
+#define LIS302DL_F_POWER 0x0010
|
||||
+#define LIS302DL_F_FS 0x0020 /* ADC full scale */
|
||||
+
|
||||
+/* lowlevel register access functions */
|
||||
+
|
||||
+#define READ_BIT 0x01
|
||||
+#define MS_BIT 0x02
|
||||
+#define ADDR_SHIFT 2
|
||||
+
|
||||
+static inline u_int8_t __reg_read(struct lis302dl_info *lis, u_int8_t reg)
|
||||
+{
|
||||
+ int rc;
|
||||
+ u_int8_t cmd;
|
||||
+
|
||||
+ cmd = (reg << ADDR_SHIFT) | READ_BIT;
|
||||
+
|
||||
+ rc = spi_w8r8(lis->spi_dev, cmd);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static u_int8_t reg_read(struct lis302dl_info *lis, u_int8_t reg)
|
||||
+{
|
||||
+ u_int8_t ret;
|
||||
+
|
||||
+ mutex_lock(&lis->lock);
|
||||
+ ret = __reg_read(lis, reg);
|
||||
+ mutex_unlock(&lis->lock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static inline int __reg_write(struct lis302dl_info *lis, u_int8_t reg, u_int8_t val)
|
||||
+{
|
||||
+ u_int8_t buf[2];
|
||||
+
|
||||
+ buf[0] = (reg << ADDR_SHIFT);
|
||||
+ buf[1] = val;
|
||||
+
|
||||
+ return spi_write(lis->spi_dev, buf, sizeof(buf));
|
||||
+}
|
||||
+
|
||||
+static int reg_write(struct lis302dl_info *lis, u_int8_t reg, u_int8_t val)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ mutex_lock(&lis->lock);
|
||||
+ ret = __reg_write(lis, reg, val);
|
||||
+ mutex_unlock(&lis->lock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int reg_set_bit_mask(struct lis302dl_info *lis,
|
||||
+ u_int8_t reg, u_int8_t mask, u_int8_t val)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u_int8_t tmp;
|
||||
+
|
||||
+ val &= mask;
|
||||
+
|
||||
+ mutex_lock(&lis->lock);
|
||||
+
|
||||
+ tmp = __reg_read(lis, reg);
|
||||
+ tmp &= ~mask;
|
||||
+ tmp |= val;
|
||||
+ ret = __reg_write(lis, reg, tmp);
|
||||
+
|
||||
+ mutex_unlock(&lis->lock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* interrupt handling related */
|
||||
+
|
||||
+enum lis302dl_intmode {
|
||||
+ LIS302DL_INTMODE_GND = 0x00,
|
||||
+ LIS302DL_INTMODE_FF_WU_1 = 0x01,
|
||||
+ LIX302DL_INTMODE_FF_WU_2 = 0x02,
|
||||
+ LIX302DL_INTMODE_FF_WU_12 = 0x03,
|
||||
+ LIX302DL_INTMODE_DATA_READY = 0x04,
|
||||
+ LIX302DL_INTMODE_CLICK = 0x07,
|
||||
+};
|
||||
+
|
||||
+static void lis302dl_int_mode(struct spi_device *spi, int int_pin,
|
||||
+ enum lis302dl_intmode mode)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ if (int_pin == 1)
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode);
|
||||
+ else if (int_pin == 2)
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3);
|
||||
+}
|
||||
+
|
||||
+static void _report_btn_single(struct input_dev *inp, int btn)
|
||||
+{
|
||||
+ input_report_key(inp, btn, 1);
|
||||
+ input_sync(inp);
|
||||
+ input_report_key(inp, btn, 0);
|
||||
+}
|
||||
+
|
||||
+static void _report_btn_double(struct input_dev *inp, int btn)
|
||||
+{
|
||||
+ input_report_key(inp, btn, 1);
|
||||
+ input_sync(inp);
|
||||
+ input_report_key(inp, btn, 0);
|
||||
+ input_sync(inp);
|
||||
+ input_report_key(inp, btn, 1);
|
||||
+ input_sync(inp);
|
||||
+ input_report_key(inp, btn, 0);
|
||||
+}
|
||||
+
|
||||
+static void lis302dl_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct lis302dl_info *lis =
|
||||
+ container_of(work, struct lis302dl_info, work);
|
||||
+
|
||||
+ u_int8_t status, ff_wu_src_1, click_src;
|
||||
+ u_int8_t val;
|
||||
+
|
||||
+ lis->working = 1;
|
||||
+
|
||||
+ status = reg_read(lis, LIS302DL_REG_STATUS);
|
||||
+ ff_wu_src_1 = reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
|
||||
+ click_src = reg_read(lis, LIS302DL_REG_CLICK_SRC);
|
||||
+
|
||||
+ if (status & LIS302DL_STATUS_XDA) {
|
||||
+ val = reg_read(lis, LIS302DL_REG_OUT_X);
|
||||
+ if (lis->flags & LIS302DL_F_FS)
|
||||
+ val = val << 2;
|
||||
+ input_report_rel(lis->input_dev, REL_X, val);
|
||||
+ }
|
||||
+
|
||||
+ if (status & LIS302DL_STATUS_YDA) {
|
||||
+ val = reg_read(lis, LIS302DL_REG_OUT_Y);
|
||||
+ if (lis->flags & LIS302DL_F_FS)
|
||||
+ val = val << 2;
|
||||
+ input_report_rel(lis->input_dev, REL_Y, val);
|
||||
+ }
|
||||
+
|
||||
+ if (status & LIS302DL_STATUS_ZDA) {
|
||||
+ val = reg_read(lis, LIS302DL_REG_OUT_Z);
|
||||
+ if (lis->flags & LIS302DL_F_FS)
|
||||
+ val = val << 2;
|
||||
+ input_report_rel(lis->input_dev, REL_Z, val);
|
||||
+ }
|
||||
+
|
||||
+ if (status & 0xf0)
|
||||
+ dev_dbg(&lis->spi_dev->dev, "overrun!\n");
|
||||
+
|
||||
+ /* FIXME: implement overrun statistics */
|
||||
+
|
||||
+ if (ff_wu_src_1 & LIS302DL_FFWUSRC1_IA) {
|
||||
+ /* FIXME: free fall interrupt handling */
|
||||
+ }
|
||||
+
|
||||
+ if (click_src & LIS302DL_CLICKSRC_IA) {
|
||||
+ if (click_src & LIS302DL_CLICKSRC_SINGLE_X)
|
||||
+ _report_btn_single(lis->input_dev, BTN_X);
|
||||
+ if (click_src & LIS302DL_CLICKSRC_DOUBLE_X)
|
||||
+ _report_btn_double(lis->input_dev, BTN_X);
|
||||
+
|
||||
+ if (click_src & LIS302DL_CLICKSRC_SINGLE_Y)
|
||||
+ _report_btn_single(lis->input_dev, BTN_Y);
|
||||
+ if (click_src & LIS302DL_CLICKSRC_DOUBLE_Y)
|
||||
+ _report_btn_double(lis->input_dev, BTN_Y);
|
||||
+
|
||||
+ if (click_src & LIS302DL_CLICKSRC_SINGLE_Z)
|
||||
+ _report_btn_single(lis->input_dev, BTN_Z);
|
||||
+ if (click_src & LIS302DL_CLICKSRC_DOUBLE_Z)
|
||||
+ _report_btn_double(lis->input_dev, BTN_Z);
|
||||
+ }
|
||||
+
|
||||
+ lis->working = 0;
|
||||
+ input_sync(lis->input_dev);
|
||||
+ put_device(&lis->spi_dev->dev);
|
||||
+
|
||||
+ enable_irq(lis->spi_dev->irq);
|
||||
+}
|
||||
+
|
||||
+static void lis302dl_schedule_work(struct lis302dl_info *lis)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ get_device(&lis->spi_dev->dev);
|
||||
+ status = schedule_work(&lis->work);
|
||||
+ if (!status && !lis->working)
|
||||
+ dev_dbg(&lis->spi_dev->dev, "work item may be lost\n");
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t lis302dl_interrupt(int irq, void *_lis)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = _lis;
|
||||
+
|
||||
+ lis302dl_schedule_work(lis);
|
||||
+
|
||||
+ /* Disable any further interrupts until we have processed
|
||||
+ * the current one */
|
||||
+ disable_irq(lis->spi_dev->irq);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+/* sysfs */
|
||||
+
|
||||
+static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(dev);
|
||||
+ u_int8_t ctrl1 = reg_read(lis, LIS302DL_REG_CTRL1);
|
||||
+
|
||||
+ return sprintf(buf, "%d\n", ctrl1 & LIS302DL_CTRL1_DR ? 400 : 100);
|
||||
+}
|
||||
+
|
||||
+static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(dev);
|
||||
+
|
||||
+ if (!strcmp(buf, "400\n"))
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
|
||||
+ LIS302DL_CTRL1_DR);
|
||||
+ else
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, 0);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(sample_rate, S_IRUGO | S_IWUSR, show_rate, set_rate);
|
||||
+
|
||||
+static ssize_t show_scale(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(dev);
|
||||
+ u_int8_t ctrl1 = reg_read(lis, LIS302DL_REG_CTRL1);
|
||||
+
|
||||
+ return sprintf(buf, "%s\n", ctrl1 & LIS302DL_CTRL1_FS ? "9.2" : "2.3");
|
||||
+}
|
||||
+
|
||||
+static ssize_t set_scale(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(dev);
|
||||
+
|
||||
+ if (!strcmp(buf, "9.2\n"))
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
|
||||
+ LIS302DL_CTRL1_FS);
|
||||
+ else
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, 0);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale);
|
||||
+
|
||||
+static struct attribute *lis302dl_sysfs_entries[] = {
|
||||
+ &dev_attr_sample_rate.attr,
|
||||
+ &dev_attr_full_scale.attr,
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group lis302dl_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = lis302dl_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+/* input device handling and driver core interaction */
|
||||
+
|
||||
+static int lis302dl_input_open(struct input_dev *inp)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = inp->private;
|
||||
+ u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen |
|
||||
+ LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen;
|
||||
+
|
||||
+ /* make sure we're powered up and generate data ready */
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void lis302dl_input_close(struct input_dev *inp)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = inp->private;
|
||||
+ u_int8_t ctrl1 = LIS302DL_CTRL1_Xen | LIS302DL_CTRL1_Yen |
|
||||
+ LIS302DL_CTRL1_Zen;
|
||||
+
|
||||
+ /* since the input core already serializes access and makes sure we
|
||||
+ * only see close() for the close of the lastre user, we can safely
|
||||
+ * disable the data ready events */
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00);
|
||||
+
|
||||
+ /* however, don't power down the whole device if still needed */
|
||||
+ if (!(lis->flags & LIS302DL_F_WUP_FF ||
|
||||
+ lis->flags & LIS302DL_F_WUP_CLICK)) {
|
||||
+ reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD,
|
||||
+ 0x00);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int __devinit lis302dl_probe(struct spi_device *spi)
|
||||
+{
|
||||
+ int rc;
|
||||
+ struct lis302dl_info *lis;
|
||||
+ u_int8_t wai;
|
||||
+
|
||||
+ lis = kzalloc(sizeof(*lis), GFP_KERNEL);
|
||||
+ if (!lis)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mutex_init(&lis->lock);
|
||||
+ INIT_WORK(&lis->work, lis302dl_work);
|
||||
+ lis->spi_dev = spi;
|
||||
+
|
||||
+ spi_set_drvdata(spi, lis);
|
||||
+
|
||||
+ rc = spi_setup(spi);
|
||||
+ if (rc < 0) {
|
||||
+ printk(KERN_ERR "error durign spi_setup of lis302dl driver\n");
|
||||
+ dev_set_drvdata(&spi->dev, NULL);
|
||||
+ kfree(lis);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ wai = reg_read(lis, LIS302DL_REG_WHO_AM_I);
|
||||
+ if (wai != LIS302DL_WHO_AM_I_MAGIC) {
|
||||
+ printk(KERN_ERR "unknown who_am_i signature 0x%02x\n", wai);
|
||||
+ dev_set_drvdata(&spi->dev, NULL);
|
||||
+ kfree(lis);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* switch interrupt to open collector */
|
||||
+ reg_write(lis, LIS302DL_CTRL3_PP_OD, 0x7c);
|
||||
+
|
||||
+ rc = request_irq(lis->spi_dev->irq, lis302dl_interrupt, IRQF_DISABLED,
|
||||
+ "lis302dl", NULL);
|
||||
+ if (rc < 0) {
|
||||
+ dev_err(&spi->dev, "error requesting IRQ %d\n",
|
||||
+ lis->spi_dev->irq);
|
||||
+ /* FIXME */
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ rc = sysfs_create_group(&spi->dev.kobj, &lis302dl_attr_group);
|
||||
+ if (rc) {
|
||||
+ dev_err(&spi->dev, "error creating sysfs group\n");
|
||||
+ /* FIXME */
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* initialize input layer details */
|
||||
+ lis->input_dev = input_allocate_device();
|
||||
+ if (!lis->input_dev) {
|
||||
+ dev_err(&spi->dev, "Unable to allocate input device\n");
|
||||
+ /* FIXME */
|
||||
+ }
|
||||
+
|
||||
+ set_bit(EV_REL, lis->input_dev->evbit);
|
||||
+ set_bit(EV_KEY, lis->input_dev->evbit);
|
||||
+ set_bit(BTN_X, lis->input_dev->keybit);
|
||||
+ set_bit(BTN_Y, lis->input_dev->keybit);
|
||||
+ set_bit(BTN_Z, lis->input_dev->keybit);
|
||||
+
|
||||
+ lis->input_dev->private = lis;
|
||||
+ lis->input_dev->name = "lis302dl"; /* FIXME: platform data */
|
||||
+ lis->input_dev->id.bustype = BUS_I2C; /* FIXME: SPI Bus */
|
||||
+ lis->input_dev->open = lis302dl_input_open;
|
||||
+ lis->input_dev->close = lis302dl_input_close;
|
||||
+
|
||||
+ input_register_device(lis->input_dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __devexit lis302dl_remove(struct spi_device *spi)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ /* power down the device */
|
||||
+ reg_write(lis, LIS302DL_REG_CTRL1, 0x00);
|
||||
+ sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group);
|
||||
+ input_unregister_device(lis->input_dev);
|
||||
+ dev_set_drvdata(&spi->dev, NULL);
|
||||
+ kfree(lis);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int lis302dl_suspend(struct spi_device *spi, pm_message_t state)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ /* save registers */
|
||||
+ lis->regs[LIS302DL_REG_CTRL1] = reg_read(lis, LIS302DL_REG_CTRL1);
|
||||
+ lis->regs[LIS302DL_REG_CTRL2] = reg_read(lis, LIS302DL_REG_CTRL2);
|
||||
+ lis->regs[LIS302DL_REG_CTRL3] = reg_read(lis, LIS302DL_REG_CTRL3);
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_CFG_1] =
|
||||
+ reg_read(lis, LIS302DL_REG_FF_WU_CFG_1);
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_THS_1] =
|
||||
+ reg_read(lis, LIS302DL_REG_FF_WU_THS_1);
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_DURATION_1] =
|
||||
+ reg_read(lis, LIS302DL_REG_FF_WU_DURATION_1);
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_CFG_2] =
|
||||
+ reg_read(lis, LIS302DL_REG_FF_WU_CFG_2);
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_THS_2] =
|
||||
+ reg_read(lis, LIS302DL_REG_FF_WU_THS_2);
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_DURATION_2] =
|
||||
+ reg_read(lis, LIS302DL_REG_FF_WU_DURATION_2);
|
||||
+ lis->regs[LIS302DL_REG_CLICK_CFG] =
|
||||
+ reg_read(lis, LIS302DL_REG_CLICK_CFG);
|
||||
+ lis->regs[LIS302DL_REG_CLICK_THSY_X] =
|
||||
+ reg_read(lis, LIS302DL_REG_CLICK_THSY_X);
|
||||
+ lis->regs[LIS302DL_REG_CLICK_THSZ] =
|
||||
+ reg_read(lis, LIS302DL_REG_CLICK_THSZ);
|
||||
+ lis->regs[LIS302DL_REG_CLICK_TIME_LIMIT] =
|
||||
+ reg_read(lis, LIS302DL_REG_CLICK_TIME_LIMIT);
|
||||
+ lis->regs[LIS302DL_REG_CLICK_LATENCY] =
|
||||
+ reg_read(lis, LIS302DL_REG_CLICK_LATENCY);
|
||||
+ lis->regs[LIS302DL_REG_CLICK_WINDOW] =
|
||||
+ reg_read(lis, LIS302DL_REG_CLICK_WINDOW);
|
||||
+
|
||||
+ /* determine if we want to wake up from the accel. */
|
||||
+ if (!(lis->flags & LIS302DL_F_WUP_FF ||
|
||||
+ lis->flags & LIS302DL_F_WUP_CLICK)) {
|
||||
+ /* power down */
|
||||
+ u_int8_t tmp;
|
||||
+ tmp = reg_read(lis, LIS302DL_REG_CTRL1);
|
||||
+ tmp &= ~LIS302DL_CTRL1_PD;
|
||||
+ reg_write(lis, LIS302DL_REG_CTRL1, tmp);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lis302dl_resume(struct spi_device *spi)
|
||||
+{
|
||||
+ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev);
|
||||
+
|
||||
+ /* restore registers after resume */
|
||||
+ reg_write(lis, LIS302DL_REG_CTRL1, lis->regs[LIS302DL_REG_CTRL1]);
|
||||
+ reg_write(lis, LIS302DL_REG_CTRL2, lis->regs[LIS302DL_REG_CTRL2]);
|
||||
+ reg_write(lis, LIS302DL_REG_CTRL3, lis->regs[LIS302DL_REG_CTRL3]);
|
||||
+ reg_write(lis, LIS302DL_REG_FF_WU_CFG_1,
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_CFG_1]);
|
||||
+ reg_write(lis, LIS302DL_REG_FF_WU_THS_1,
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_THS_1]);
|
||||
+ reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_DURATION_1]);
|
||||
+ reg_write(lis, LIS302DL_REG_FF_WU_CFG_2,
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_CFG_2]);
|
||||
+ reg_write(lis, LIS302DL_REG_FF_WU_THS_2,
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_THS_2]);
|
||||
+ reg_write(lis, LIS302DL_REG_FF_WU_DURATION_2,
|
||||
+ lis->regs[LIS302DL_REG_FF_WU_DURATION_2]);
|
||||
+ reg_write(lis, LIS302DL_REG_CLICK_CFG,
|
||||
+ lis->regs[LIS302DL_REG_CLICK_CFG]);
|
||||
+ reg_write(lis, LIS302DL_REG_CLICK_THSY_X,
|
||||
+ lis->regs[LIS302DL_REG_CLICK_THSY_X]);
|
||||
+ reg_write(lis, LIS302DL_REG_CLICK_THSZ,
|
||||
+ lis->regs[LIS302DL_REG_CLICK_THSZ]);
|
||||
+ reg_write(lis, LIS302DL_REG_CLICK_TIME_LIMIT,
|
||||
+ lis->regs[LIS302DL_REG_CLICK_TIME_LIMIT]);
|
||||
+ reg_write(lis, LIS302DL_REG_CLICK_LATENCY,
|
||||
+ lis->regs[LIS302DL_REG_CLICK_LATENCY]);
|
||||
+ reg_write(lis, LIS302DL_REG_CLICK_WINDOW,
|
||||
+ lis->regs[LIS302DL_REG_CLICK_WINDOW]);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define lis302dl_suspend NULL
|
||||
+#define lis302dl_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct spi_driver lis302dl_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "lis302dl",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+
|
||||
+ .probe = lis302dl_probe,
|
||||
+ .remove = __devexit_p(lis302dl_remove),
|
||||
+ .suspend = lis302dl_suspend,
|
||||
+ .resume = lis302dl_resume,
|
||||
+};
|
||||
+
|
||||
+static int __init lis302dl_init(void)
|
||||
+{
|
||||
+ return spi_register_driver(&lis302dl_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit lis302dl_exit(void)
|
||||
+{
|
||||
+ spi_unregister_driver(&lis302dl_driver);
|
||||
+}
|
||||
+
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+module_init(lis302dl_init);
|
||||
+module_exit(lis302dl_exit);
|
||||
diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
|
||||
new file mode 100644
|
||||
index 0000000..d0f31be
|
||||
--- /dev/null
|
||||
+++ b/include/linux/lis302dl.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+#ifndef _LINUX_LIS302DL_H
|
||||
+#define _LINUX_LIS302DL_H
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+struct lis302dl_platform_data {
|
||||
+ char *name;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_LIS302DL_H */
|
||||
+
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
From fc22d87d11df9053f1a1b41b7b450c3af07b5059 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:56 +0100
|
||||
Subject: [PATCH] gta02-leds.patch
|
||||
|
||||
---
|
||||
drivers/leds/Kconfig | 6 +
|
||||
drivers/leds/Makefile | 1 +
|
||||
drivers/leds/leds-neo1973-gta02.c | 226 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 233 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/leds/leds-neo1973-gta02.c
|
||||
|
||||
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
|
||||
index 8c7d949..b6b1211 100644
|
||||
--- a/drivers/leds/Kconfig
|
||||
+++ b/drivers/leds/Kconfig
|
||||
@@ -153,6 +153,12 @@ config LEDS_NEO1973_VIBRATOR
|
||||
help
|
||||
This option enables support for the vibrator on the FIC Neo1973.
|
||||
|
||||
+config LEDS_NEO1973_GTA02
|
||||
+ tristate "LED Support for the FIC Neo1973 (GTA02)"
|
||||
+ depends on LEDS_CLASS && MACH_NEO1973_GTA02
|
||||
+ help
|
||||
+ This option enables support for the LEDs on the FIC Neo1973.
|
||||
+
|
||||
comment "LED Triggers"
|
||||
|
||||
config LEDS_TRIGGERS
|
||||
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
|
||||
index 148fe51..3a9df6a 100644
|
||||
--- a/drivers/leds/Makefile
|
||||
+++ b/drivers/leds/Makefile
|
||||
@@ -22,6 +22,7 @@ obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
|
||||
obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
|
||||
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
|
||||
obj-$(CONFIG_LEDS_NEO1973_VIBRATOR) += leds-neo1973-vibrator.o
|
||||
+obj-$(CONFIG_LEDS_NEO1973_GTA02) += leds-neo1973-gta02.o
|
||||
|
||||
# LED Triggers
|
||||
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
|
||||
diff --git a/drivers/leds/leds-neo1973-gta02.c b/drivers/leds/leds-neo1973-gta02.c
|
||||
new file mode 100644
|
||||
index 0000000..bf1d540
|
||||
--- /dev/null
|
||||
+++ b/drivers/leds/leds-neo1973-gta02.c
|
||||
@@ -0,0 +1,226 @@
|
||||
+/*
|
||||
+ * LED driver for the FIC Neo1973 GTA02 GSM phone
|
||||
+ *
|
||||
+ * (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+#include <asm/arch/pwm.h>
|
||||
+#include <asm/arch/gta02.h>
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+
|
||||
+#define MAX_LEDS 3
|
||||
+#define COUNTER 256
|
||||
+
|
||||
+struct gta02_led_priv
|
||||
+{
|
||||
+ struct mutex mutex;
|
||||
+ struct led_classdev cdev;
|
||||
+ struct s3c2410_pwm pwm;
|
||||
+ unsigned int gpio;
|
||||
+ unsigned int has_pwm;
|
||||
+};
|
||||
+
|
||||
+struct gta02_led_bundle
|
||||
+{
|
||||
+ int num_leds;
|
||||
+ struct gta02_led_priv led[MAX_LEDS];
|
||||
+};
|
||||
+
|
||||
+static inline struct gta02_led_priv *to_priv(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ return container_of(led_cdev, struct gta02_led_priv, cdev);
|
||||
+}
|
||||
+
|
||||
+static inline struct gta02_led_bundle *to_bundle(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ return dev_get_drvdata(led_cdev->dev);
|
||||
+}
|
||||
+
|
||||
+static void gta02led_set(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value)
|
||||
+{
|
||||
+ struct gta02_led_priv *lp = to_priv(led_cdev);
|
||||
+
|
||||
+ /*
|
||||
+ * value == 255 -> 99% duty cycle (full power)
|
||||
+ * value == 128 -> 50% duty cycle (medium power)
|
||||
+ * value == 0 -> 0% duty cycle (zero power)
|
||||
+ */
|
||||
+ mutex_lock(&lp->mutex);
|
||||
+ if (lp->has_pwm) {
|
||||
+ s3c2410_pwm_duty_cycle(value, &lp->pwm);
|
||||
+ } else {
|
||||
+ if (value)
|
||||
+ s3c2410_gpio_setpin(lp->gpio, 1);
|
||||
+ else
|
||||
+ s3c2410_gpio_setpin(lp->gpio, 0);
|
||||
+ }
|
||||
+ mutex_unlock(&lp->mutex);
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta02led_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ struct gta02_led_bundle *bundle = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < bundle->num_leds; i++)
|
||||
+ led_classdev_suspend(&bundle->led[i].cdev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta02led_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct gta02_led_bundle *bundle = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < bundle->num_leds; i++)
|
||||
+ led_classdev_resume(&bundle->led[i].cdev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static int __init gta02led_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int i, rc;
|
||||
+ struct gta02_led_bundle *bundle;
|
||||
+
|
||||
+ if (!machine_is_neo1973_gta02())
|
||||
+ return -EIO;
|
||||
+
|
||||
+ bundle = kzalloc(sizeof(struct gta02_led_bundle), GFP_KERNEL);
|
||||
+ if (!bundle)
|
||||
+ return -ENOMEM;
|
||||
+ platform_set_drvdata(pdev, bundle);
|
||||
+
|
||||
+ for (i = 0; i < pdev->num_resources; i++) {
|
||||
+ struct gta02_led_priv *lp;
|
||||
+ struct resource *r;
|
||||
+
|
||||
+ if (i >= MAX_LEDS)
|
||||
+ break;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, 0, i);
|
||||
+ if (!r || !r->start || !r->name)
|
||||
+ continue;
|
||||
+
|
||||
+ lp = &bundle->led[i];
|
||||
+
|
||||
+ lp->gpio = r->start;
|
||||
+ lp->cdev.name = r->name;
|
||||
+ lp->cdev.brightness_set = gta02led_set;
|
||||
+
|
||||
+ switch (lp->gpio) {
|
||||
+ case S3C2410_GPB0:
|
||||
+ lp->has_pwm = 1;
|
||||
+ lp->pwm.timerid = PWM0;
|
||||
+ s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB0_TOUT0);
|
||||
+ break;
|
||||
+ case S3C2410_GPB1:
|
||||
+ lp->has_pwm = 1;
|
||||
+ lp->pwm.timerid = PWM1;
|
||||
+ s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB1_TOUT1);
|
||||
+ break;
|
||||
+ case S3C2410_GPB2:
|
||||
+ lp->has_pwm = 1;
|
||||
+ lp->pwm.timerid = PWM2;
|
||||
+ s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB2_TOUT2);
|
||||
+ break;
|
||||
+ case S3C2410_GPB3:
|
||||
+ lp->has_pwm = 1;
|
||||
+ lp->pwm.timerid = PWM3;
|
||||
+ s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB3_TOUT3);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ lp->pwm.prescaler = 0;
|
||||
+ lp->pwm.divider = S3C2410_TCFG1_MUX3_DIV8;
|
||||
+ lp->pwm.counter = COUNTER;
|
||||
+ lp->pwm.comparer = COUNTER;
|
||||
+ s3c2410_pwm_enable(&lp->pwm);
|
||||
+ s3c2410_pwm_start(&lp->pwm);
|
||||
+
|
||||
+ switch (lp->gpio) {
|
||||
+ case S3C2410_GPB0:
|
||||
+ case S3C2410_GPB1:
|
||||
+ case S3C2410_GPB2:
|
||||
+ lp->has_pwm = 0;
|
||||
+ s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPIO_OUTPUT);
|
||||
+ s3c2410_gpio_setpin(lp->gpio, 0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ mutex_init(&lp->mutex);
|
||||
+ rc = led_classdev_register(&pdev->dev, &lp->cdev);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta02led_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct gta02_led_bundle *bundle = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < bundle->num_leds; i++) {
|
||||
+ struct gta02_led_priv *lp = &bundle->led[i];
|
||||
+ if (lp->has_pwm)
|
||||
+ s3c2410_pwm_disable(&lp->pwm);
|
||||
+
|
||||
+ led_classdev_unregister(&lp->cdev);
|
||||
+ mutex_destroy(&lp->mutex);
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+ kfree(bundle);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta02led_driver = {
|
||||
+ .probe = gta02led_probe,
|
||||
+ .remove = gta02led_remove,
|
||||
+#ifdef CONFIG_PM
|
||||
+ .suspend = gta02led_suspend,
|
||||
+ .resume = gta02led_resume,
|
||||
+#endif
|
||||
+ .driver = {
|
||||
+ .name = "gta02-led",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init gta02led_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a02led_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit gta02led_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a02led_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta02led_init);
|
||||
+module_exit(gta02led_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION("FIC Neo1973 GTA02 LED driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,200 @@
|
|||
From 4ced79a6699eb5828c71b5438826fb44e3b41997 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:56 +0100
|
||||
Subject: [PATCH] pcf506xx.patch
|
||||
Moved shared PMU code from pcf50606.h and pcf50633.h (which prevented inclusion
|
||||
of both at the same time) to pcf506xx.h
|
||||
|
||||
- include/linux/pcf50606.h (struct pmu_voltage_rail, enum pmu_event, pmu_cb):
|
||||
moved to pcf506xx.h
|
||||
- include/linux/pcf50633.h (struct pmu_voltage_rail, enum pmu_event, pmu_cb):
|
||||
moved to pcf506xx.h
|
||||
|
||||
Signed off-by: Werner Almesberger <werner@openmoko.org>
|
||||
---
|
||||
drivers/i2c/chips/pcf50606.c | 28 +++++++++++++++++++++++++++-
|
||||
include/linux/pcf50606.h | 23 +++--------------------
|
||||
include/linux/pcf50633.h | 27 +++------------------------
|
||||
include/linux/pcf506xx.h | 31 +++++++++++++++++++++++++++++++
|
||||
4 files changed, 64 insertions(+), 45 deletions(-)
|
||||
create mode 100644 include/linux/pcf506xx.h
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
|
||||
index 6626c68..b530583 100644
|
||||
--- a/drivers/i2c/chips/pcf50606.c
|
||||
+++ b/drivers/i2c/chips/pcf50606.c
|
||||
@@ -102,6 +102,7 @@ struct pcf50606_data {
|
||||
int allow_close;
|
||||
int onkey_seconds;
|
||||
int irq;
|
||||
+ int coldplug_done;
|
||||
#ifdef CONFIG_PM
|
||||
struct {
|
||||
u_int8_t dcdc1, dcdc2;
|
||||
@@ -573,6 +574,30 @@ static void pcf50606_work(struct work_struct *work)
|
||||
if (ret != 3)
|
||||
DEBUGPC("Oh crap PMU IRQ register read failed %d\n", ret);
|
||||
|
||||
+ if (!pcf->coldplug_done) {
|
||||
+ DEBUGPC("PMU Coldplug init\n");
|
||||
+
|
||||
+ /* we used SECOND to kick ourselves started -- turn it off */
|
||||
+ pcfirq[0] &= ~PCF50606_INT1_SECOND;
|
||||
+ reg_set_bit_mask(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND,
|
||||
+ PCF50606_INT1_SECOND);
|
||||
+
|
||||
+ /* coldplug the USB if present */
|
||||
+ if (__reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON) {
|
||||
+ /* Charger inserted */
|
||||
+ DEBUGPC("COLD CHGINS ");
|
||||
+ input_report_key(pcf->input_dev, KEY_BATTERY, 1);
|
||||
+ apm_queue_event(APM_POWER_STATUS_CHANGE);
|
||||
+ pcf->flags |= PCF50606_F_CHG_PRESENT;
|
||||
+ if (pcf->pdata->cb)
|
||||
+ pcf->pdata->cb(&pcf->client.dev,
|
||||
+ PCF50606_FEAT_MBC, PMU_EVT_INSERT);
|
||||
+ }
|
||||
+
|
||||
+ pcf->coldplug_done = 1;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
dev_dbg(&pcf->client.dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x:",
|
||||
pcfirq[0], pcfirq[1], pcfirq[2]);
|
||||
|
||||
@@ -1642,7 +1667,8 @@ static int pcf50606_detect(struct i2c_adapter *adapter, int address, int kind)
|
||||
pm_power_off = &pcf50606_go_standby;
|
||||
|
||||
/* configure interrupt mask */
|
||||
- reg_write(data, PCF50606_REG_INT1M, PCF50606_INT1_SECOND);
|
||||
+ /* we don't mask SECOND here, because we want one to do coldplug with */
|
||||
+ reg_write(data, PCF50606_REG_INT1M, 0x00);
|
||||
reg_write(data, PCF50606_REG_INT2M, 0x00);
|
||||
reg_write(data, PCF50606_REG_INT3M, PCF50606_INT3_TSCPRES);
|
||||
|
||||
diff --git a/include/linux/pcf50606.h b/include/linux/pcf50606.h
|
||||
index bc98e47..167328f 100644
|
||||
--- a/include/linux/pcf50606.h
|
||||
+++ b/include/linux/pcf50606.h
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef _LINUX_PCF50606_H
|
||||
#define _LINUX_PCF50606_H
|
||||
|
||||
+#include <linux/pcf506xx.h>
|
||||
+
|
||||
+
|
||||
/* public in-kernel pcf50606 api */
|
||||
enum pcf50606_regulator_id {
|
||||
PCF50606_REGULATOR_DCD,
|
||||
@@ -48,26 +51,6 @@ pcf50606_onoff_set(struct pcf50606_data *pcf,
|
||||
extern void
|
||||
pcf50606_charge_fast(struct pcf50606_data *pcf, int on);
|
||||
|
||||
-#define PMU_VRAIL_F_SUSPEND_ON 0x00000001 /* Remains on during suspend */
|
||||
-#define PMU_VRAIL_F_UNUSED 0x00000002 /* This rail is not used */
|
||||
-struct pmu_voltage_rail {
|
||||
- char *name;
|
||||
- unsigned int flags;
|
||||
- struct {
|
||||
- unsigned int init;
|
||||
- unsigned int max;
|
||||
- } voltage;
|
||||
-};
|
||||
-
|
||||
-enum pmu_event {
|
||||
- PMU_EVT_NONE,
|
||||
- PMU_EVT_INSERT,
|
||||
- PMU_EVT_REMOVE,
|
||||
- __NUM_PMU_EVTS
|
||||
-};
|
||||
-
|
||||
-typedef int pmu_cb(struct device *dev, unsigned int feature,
|
||||
- enum pmu_event event);
|
||||
|
||||
#define PCF50606_FEAT_EXTON 0x00000001 /* not yet supported */
|
||||
#define PCF50606_FEAT_MBC 0x00000002
|
||||
diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
|
||||
index 5f32004..bf50fe4 100644
|
||||
--- a/include/linux/pcf50633.h
|
||||
+++ b/include/linux/pcf50633.h
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef _LINUX_PCF50633_H
|
||||
#define _LINUX_PCF50633_H
|
||||
|
||||
+#include <linux/pcf506xx.h>
|
||||
+
|
||||
+
|
||||
/* public in-kernel pcf50633 api */
|
||||
enum pcf50633_regulator_id {
|
||||
PCF50633_REGULATOR_AUTO,
|
||||
@@ -57,30 +60,6 @@ pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma);
|
||||
extern void
|
||||
pcf50633_charge_enable(struct pcf50633_data *pcf, int on);
|
||||
|
||||
-/* FIXME: sharded with pcf50606 */
|
||||
-#define PMU_VRAIL_F_SUSPEND_ON 0x00000001 /* Remains on during suspend */
|
||||
-#define PMU_VRAIL_F_UNUSED 0x00000002 /* This rail is not used */
|
||||
-struct pmu_voltage_rail {
|
||||
- char *name;
|
||||
- unsigned int flags;
|
||||
- struct {
|
||||
- unsigned int init;
|
||||
- unsigned int max;
|
||||
- } voltage;
|
||||
-};
|
||||
-
|
||||
-enum pmu_event {
|
||||
- PMU_EVT_NONE,
|
||||
- PMU_EVT_INSERT,
|
||||
- PMU_EVT_REMOVE,
|
||||
- PMU_EVT_USB_INSERT,
|
||||
- PMU_EVT_USB_REMOVE,
|
||||
- __NUM_PMU_EVTS
|
||||
-};
|
||||
-
|
||||
-typedef int pmu_cb(struct device *dev, unsigned int feature,
|
||||
- enum pmu_event event);
|
||||
-
|
||||
#define PCF50633_FEAT_EXTON 0x00000001 /* not yet supported */
|
||||
#define PCF50633_FEAT_MBC 0x00000002
|
||||
#define PCF50633_FEAT_BBC 0x00000004 /* not yet supported */
|
||||
diff --git a/include/linux/pcf506xx.h b/include/linux/pcf506xx.h
|
||||
new file mode 100644
|
||||
index 0000000..33be73e
|
||||
--- /dev/null
|
||||
+++ b/include/linux/pcf506xx.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+#ifndef _LINUX_PCF506XX_H
|
||||
+#define _LINUX_PCF506XX_H
|
||||
+
|
||||
+
|
||||
+#define PMU_VRAIL_F_SUSPEND_ON 0x00000001 /* Remains on during suspend */
|
||||
+#define PMU_VRAIL_F_UNUSED 0x00000002 /* This rail is not used */
|
||||
+struct pmu_voltage_rail {
|
||||
+ char *name;
|
||||
+ unsigned int flags;
|
||||
+ struct {
|
||||
+ unsigned int init;
|
||||
+ unsigned int max;
|
||||
+ } voltage;
|
||||
+};
|
||||
+
|
||||
+enum pmu_event {
|
||||
+ PMU_EVT_NONE,
|
||||
+ PMU_EVT_INSERT,
|
||||
+ PMU_EVT_REMOVE,
|
||||
+#ifdef CONFIG_SENSORS_PCF50633
|
||||
+ PMU_EVT_USB_INSERT,
|
||||
+ PMU_EVT_USB_REMOVE,
|
||||
+#endif
|
||||
+ __NUM_PMU_EVTS
|
||||
+};
|
||||
+
|
||||
+typedef int pmu_cb(struct device *dev, unsigned int feature,
|
||||
+ enum pmu_event event);
|
||||
+
|
||||
+
|
||||
+#endif /* !_LINUX_PCF506XX_H */
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
From d4d6e6229c94cfe2bd8f29b4ebc0d60b8ad29455 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:57 +0100
|
||||
Subject: [PATCH] gta02-bt-fixes.patch
|
||||
Modify GTA02 power manager for bluetooth.
|
||||
|
||||
1. Default power value isn't correct. Now we set pcf50633 LDO4 to 3.2 voltage.
|
||||
|
||||
2. Separate GTA01 and GTA02 source code.
|
||||
|
||||
3. Add pcf50633 API for enable register.
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 4 +-
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_bt.c | 71 ++++++++++++++++++++++++++++----
|
||||
include/linux/pcf50633.h | 1 +
|
||||
3 files changed, 65 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index 3fbb131..46acede 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -213,10 +213,10 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
|
||||
},
|
||||
},
|
||||
[PCF50633_REGULATOR_LDO4] = {
|
||||
- .name = "gl_2v5",
|
||||
+ .name = "bt_3v2",
|
||||
.voltage = {
|
||||
.init = 2500,
|
||||
- .max = 2500,
|
||||
+ .max = 3300,
|
||||
},
|
||||
},
|
||||
[PCF50633_REGULATOR_LDO5] = {
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
index d685ef7..8f5be88 100644
|
||||
--- a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
|
||||
@@ -16,12 +16,19 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
-#include <linux/pcf50606.h>
|
||||
-
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
#include <asm/arch/gta01.h>
|
||||
+#include <linux/pcf50606.h>
|
||||
+#endif
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
#include <asm/arch/gta02.h>
|
||||
+#include <linux/pcf50633.h>
|
||||
+#endif
|
||||
+
|
||||
|
||||
#define DRVMSG "FIC Neo1973 Bluetooth Power Management"
|
||||
|
||||
@@ -30,6 +37,8 @@ static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
|
||||
{
|
||||
if (!strcmp(attr->attr.name, "power_on")) {
|
||||
switch (machine_arch_type) {
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
case MACH_TYPE_NEO1973_GTA01:
|
||||
if (pcf50606_onoff_get(pcf50606_global,
|
||||
PCF50606_REGULATOR_D1REG) &&
|
||||
@@ -37,21 +46,33 @@ static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
|
||||
PCF50606_REGULATOR_D1REG) == 3100)
|
||||
goto out_1;
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
case MACH_TYPE_NEO1973_GTA02:
|
||||
if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN))
|
||||
goto out_1;
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+
|
||||
}
|
||||
} else if (!strcmp(attr->attr.name, "reset")) {
|
||||
switch (machine_arch_type) {
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
case MACH_TYPE_NEO1973_GTA01:
|
||||
if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0)
|
||||
goto out_1;
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
case MACH_TYPE_NEO1973_GTA02:
|
||||
if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == 0)
|
||||
goto out_1;
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,9 +85,12 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long on = simple_strtoul(buf, NULL, 10);
|
||||
+ unsigned int vol;
|
||||
|
||||
if (!strcmp(attr->attr.name, "power_on")) {
|
||||
switch (machine_arch_type) {
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
case MACH_TYPE_NEO1973_GTA01:
|
||||
/* if we are powering up, assert reset, then power,
|
||||
* then release reset */
|
||||
@@ -80,22 +104,39 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
|
||||
PCF50606_REGULATOR_D1REG, on);
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on);
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
case MACH_TYPE_NEO1973_GTA02:
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, on ? 0 : 1);
|
||||
if (on)
|
||||
- s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 0);
|
||||
- else
|
||||
- s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 1);
|
||||
+ pcf50633_voltage_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO4, 3200);
|
||||
+ pcf50633_onoff_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO4, on);
|
||||
+ vol = pcf50633_voltage_get(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO4);
|
||||
+ dev_info(dev, "GTA02 Set PCF50633 LDO4 = %d\n", vol);
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+
|
||||
}
|
||||
} else if (!strcmp(attr->attr.name, "reset")) {
|
||||
/* reset is low-active, so we need to invert */
|
||||
switch (machine_arch_type) {
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
case MACH_TYPE_NEO1973_GTA01:
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1);
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
case MACH_TYPE_NEO1973_GTA02:
|
||||
s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, on ? 0 : 1);
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,18 +184,30 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
|
||||
dev_info(&pdev->dev, DRVMSG ": starting\n");
|
||||
|
||||
switch (machine_arch_type) {
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
case MACH_TYPE_NEO1973_GTA01:
|
||||
/* we make sure that the voltage is off */
|
||||
pcf50606_onoff_set(pcf50606_global,
|
||||
PCF50606_REGULATOR_D1REG, 0);
|
||||
+ /* we pull reset to low to make sure that the chip doesn't
|
||||
+ * drain power through the reset line */
|
||||
+ s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
case MACH_TYPE_NEO1973_GTA02:
|
||||
- /* FIXME: implementation */
|
||||
+ /* we make sure that the voltage is off */
|
||||
+ pcf50633_onoff_set(pcf50633_global,
|
||||
+ PCF50633_REGULATOR_LDO4, 0);
|
||||
+ /* we pull reset to low to make sure that the chip doesn't
|
||||
+ * drain power through the reset line */
|
||||
+ s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 0);
|
||||
break;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA02 */
|
||||
+
|
||||
}
|
||||
- /* we pull reset to low to make sure that the chip doesn't
|
||||
- * drain power through the reset line */
|
||||
- s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
|
||||
|
||||
return sysfs_create_group(&pdev->dev.kobj, >a01_bt_attr_group);
|
||||
}
|
||||
diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
|
||||
index bf50fe4..b6a67ee 100644
|
||||
--- a/include/linux/pcf50633.h
|
||||
+++ b/include/linux/pcf50633.h
|
||||
@@ -46,6 +46,7 @@ pcf50633_voltage_set(struct pcf50633_data *pcf,
|
||||
extern unsigned int
|
||||
pcf50633_voltage_get(struct pcf50633_data *pcf,
|
||||
enum pcf50633_regulator_id reg);
|
||||
+
|
||||
extern int
|
||||
pcf50633_onoff_get(struct pcf50633_data *pcf,
|
||||
enum pcf50633_regulator_id reg);
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,60 @@
|
|||
From 18dc67c2500cc825b8f726e90aa1ce4b765f28da Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:57 +0100
|
||||
Subject: [PATCH] config-nr-tty-devices.patch
|
||||
|
||||
---
|
||||
drivers/char/Kconfig | 12 ++++++++++++
|
||||
include/linux/vt.h | 11 +++++++++++
|
||||
2 files changed, 23 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
|
||||
index 2d854bb..04afc16 100644
|
||||
--- a/drivers/char/Kconfig
|
||||
+++ b/drivers/char/Kconfig
|
||||
@@ -58,6 +58,18 @@ config VT_CONSOLE
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
+config NR_TTY_DEVICES
|
||||
+ int "Maximum tty device number"
|
||||
+ depends on VT
|
||||
+ default 63
|
||||
+ ---help---
|
||||
+ This is the highest numbered device created in /dev. You will actually have
|
||||
+ NR_TTY_DEVICES+1 devices in /dev. The default is 63, which will result in
|
||||
+ 64 /dev entries. The lowest number you can set is 11, anything below that,
|
||||
+ and it will default to 11. 63 is also the upper limit so we don't overrun
|
||||
+ the serial consoles.
|
||||
+
|
||||
+
|
||||
config HW_CONSOLE
|
||||
bool
|
||||
depends on VT && !S390 && !UML
|
||||
diff --git a/include/linux/vt.h b/include/linux/vt.h
|
||||
index 02c1c02..2ba4d21 100644
|
||||
--- a/include/linux/vt.h
|
||||
+++ b/include/linux/vt.h
|
||||
@@ -18,8 +18,19 @@ extern int unregister_vt_notifier(struct notifier_block *nb);
|
||||
* resizing).
|
||||
*/
|
||||
#define MIN_NR_CONSOLES 1 /* must be at least 1 */
|
||||
+#if (CONFIG_NR_TTY_DEVICES < 4)
|
||||
+/* Lower Limit */
|
||||
+#define MAX_NR_CONSOLES 4 /* serial lines start at 64 */
|
||||
+#define MAX_NR_USER_CONSOLES 4 /* must be root to allocate above this */
|
||||
+#elif (CONFIG_NR_TTY_DEVICES > 63)
|
||||
+/* Upper Limit */
|
||||
#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
|
||||
#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
|
||||
+#else
|
||||
+/* They chose a sensible number */
|
||||
+#define MAX_NR_CONSOLES CONFIG_NR_TTY_DEVICES
|
||||
+#define MAX_NR_USER_CONSOLES CONFIG_NR_TTY_DEVICES
|
||||
+#endif
|
||||
/* Note: the ioctl VT_GETSTATE does not work for
|
||||
consoles 16 and higher (since it returns a short) */
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
From 4d5727829b4589a1e2c209ea562a057e758ec556 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Wed, 16 Jul 2008 14:46:57 +0100
|
||||
Subject: [PATCH] pm-debug_less_verbose.patch
|
||||
|
||||
---
|
||||
drivers/base/power/main.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
|
||||
index 45cc3d9..524f1a2 100644
|
||||
--- a/drivers/base/power/main.c
|
||||
+++ b/drivers/base/power/main.c
|
||||
@@ -64,9 +64,9 @@ int device_pm_add(struct device *dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
- pr_debug("PM: Adding info for %s:%s\n",
|
||||
+ /* pr_debug("PM: Adding info for %s:%s\n",
|
||||
dev->bus ? dev->bus->name : "No Bus",
|
||||
- kobject_name(&dev->kobj));
|
||||
+ kobject_name(&dev->kobj)); */
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
if ((dev->parent && dev->parent->power.sleeping) || all_sleeping) {
|
||||
if (dev->parent->power.sleeping)
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
From 1611aca52fd831b0a90a854ef71f07ed341bd987 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:03 +0100
|
||||
Subject: [PATCH] s3c2410_serial-nodebug.patch
|
||||
|
||||
---
|
||||
drivers/serial/s3c2410.c | 8 --------
|
||||
1 files changed, 0 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
|
||||
index 2b6a013..7117110 100644
|
||||
--- a/drivers/serial/s3c2410.c
|
||||
+++ b/drivers/serial/s3c2410.c
|
||||
@@ -708,10 +708,6 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
|
||||
int calc_deviation;
|
||||
|
||||
for (sptr = res; sptr < resptr; sptr++) {
|
||||
- printk(KERN_DEBUG
|
||||
- "found clk %p (%s) quot %d, calc %d\n",
|
||||
- sptr->clksrc, sptr->clksrc->name,
|
||||
- sptr->quot, sptr->calc);
|
||||
|
||||
calc_deviation = baud - sptr->calc;
|
||||
if (calc_deviation < 0)
|
||||
@@ -723,12 +719,8 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
|
||||
}
|
||||
}
|
||||
|
||||
- printk(KERN_DEBUG "best %p (deviation %d)\n", best, deviation);
|
||||
}
|
||||
|
||||
- printk(KERN_DEBUG "selected clock %p (%s) quot %d, calc %d\n",
|
||||
- best->clksrc, best->clksrc->name, best->quot, best->calc);
|
||||
-
|
||||
/* store results to pass back */
|
||||
|
||||
*clksrc = best->clksrc;
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
From 95bdfec0f2515b7f1cd8dd959e49e950a814868b Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] input-nots-mousedev.patch
|
||||
This patch disables the reporting of touchscreen-like devices via
|
||||
/dev/input/mice. In the Neo1973 (much like other handheld devices),
|
||||
we need this to distinguish between the touchscreen (which uses tslib)
|
||||
and optional additional usb/bluetooth mice that might be attached.
|
||||
|
||||
Signed-off-by: Harald Welte <laforge@openmoko.org>
|
||||
---
|
||||
drivers/input/mousedev.c | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
|
||||
index b989748..685917e 100644
|
||||
--- a/drivers/input/mousedev.c
|
||||
+++ b/drivers/input/mousedev.c
|
||||
@@ -1009,6 +1009,7 @@ static const struct input_device_id mousedev_ids[] = {
|
||||
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
|
||||
.relbit = { BIT_MASK(REL_WHEEL) },
|
||||
}, /* A separate scrollwheel */
|
||||
+#if 0
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_KEYBIT |
|
||||
@@ -1018,6 +1019,7 @@ static const struct input_device_id mousedev_ids[] = {
|
||||
.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
|
||||
}, /* A tablet like device, at least touch detection,
|
||||
two absolute axes */
|
||||
+#endif
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_KEYBIT |
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
From bc0d09dd89a8837b9a4eeb63585caded6b290cf9 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] s3c2440-nand-disable-hwecc.patch
|
||||
Disable the hardware ECC checking on S3C2440 based platforms (HXD8, SMDK2440,
|
||||
GTA02) for the time being, since our u-boot doesn't yet support it for 2k page
|
||||
size NAND
|
||||
|
||||
---
|
||||
drivers/mtd/nand/s3c2410.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
|
||||
index 6e7a5b9..8e1e482 100644
|
||||
--- a/drivers/mtd/nand/s3c2410.c
|
||||
+++ b/drivers/mtd/nand/s3c2410.c
|
||||
@@ -665,7 +665,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
|
||||
nmtd->mtd.owner = THIS_MODULE;
|
||||
nmtd->set = set;
|
||||
|
||||
- if (hardware_ecc) {
|
||||
+ if (info->cpu_type == TYPE_S3C2410 && hardware_ecc) {
|
||||
chip->ecc.calculate = s3c2410_nand_calculate_ecc;
|
||||
chip->ecc.correct = s3c2410_nand_correct_data;
|
||||
chip->ecc.mode = NAND_ECC_HW;
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
From 0ed3724f733b7049d5efea9c44f5e6f0c6beae06 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] qt2410-cs8900.patch
|
||||
|
||||
---
|
||||
drivers/net/Kconfig | 4 ++--
|
||||
drivers/net/cs89x0.c | 14 +++++++++++++-
|
||||
2 files changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
|
||||
index f4182cf..8caa04a 100644
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -1248,7 +1248,7 @@ source "drivers/net/ibm_newemac/Kconfig"
|
||||
|
||||
config NET_PCI
|
||||
bool "EISA, VLB, PCI and on board controllers"
|
||||
- depends on ISA || EISA || PCI
|
||||
+ depends on ISA || EISA || PCI || MACH_QT2410
|
||||
help
|
||||
This is another class of network cards which attach directly to the
|
||||
bus. If you have one of those, say Y and read the Ethernet-HOWTO,
|
||||
@@ -1410,7 +1410,7 @@ config FORCEDETH_NAPI
|
||||
|
||||
config CS89x0
|
||||
tristate "CS89x0 support"
|
||||
- depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X)
|
||||
+ depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X || MACH_QT2410)
|
||||
---help---
|
||||
Support for CS89x0 chipset based Ethernet cards. If you have a
|
||||
network (Ethernet) card of this type, say Y and read the
|
||||
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
|
||||
index fba87ab..d94a790 100644
|
||||
--- a/drivers/net/cs89x0.c
|
||||
+++ b/drivers/net/cs89x0.c
|
||||
@@ -194,6 +194,10 @@ static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
|
||||
#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
|
||||
static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
|
||||
static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
|
||||
+#elif defined(CONFIG_MACH_QT2410)
|
||||
+#include <asm/arch/irqs.h>
|
||||
+static unsigned int netcard_portlist [] __initdata = { 0xe0000300, 0 };
|
||||
+static unsigned int cs8900_irq_map[] = { IRQ_EINT9, 0, 0, 0 };
|
||||
#else
|
||||
static unsigned int netcard_portlist[] __used __initdata =
|
||||
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
|
||||
@@ -829,6 +833,14 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
|
||||
printk(" IRQ %d", dev->irq);
|
||||
|
||||
+ dev->dev_addr[0] = 0x00;
|
||||
+ dev->dev_addr[1] = 0x00;
|
||||
+ dev->dev_addr[2] = 0xc0;
|
||||
+ dev->dev_addr[3] = 0xff;
|
||||
+ dev->dev_addr[4] = 0xee;
|
||||
+ dev->dev_addr[5] = 0x08;
|
||||
+ set_mac_address(dev, dev->dev_addr);
|
||||
+
|
||||
#if ALLOW_DMA
|
||||
if (lp->use_dma) {
|
||||
get_dma_channel(dev);
|
||||
@@ -1304,7 +1316,7 @@ net_open(struct net_device *dev)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
|
||||
+#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X) && !defined(CONFIG_MACH_QT2410)
|
||||
if (((1 << dev->irq) & lp->irq_map) == 0) {
|
||||
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
|
||||
dev->name, dev->irq, lp->irq_map);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
From a63a227ece28df06d4c8f04eec51c7649ef28aea Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] s3c2410-qt2410-buttons.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2410/mach-qt2410.c | 18 +++
|
||||
drivers/input/keyboard/Kconfig | 5 +
|
||||
drivers/input/keyboard/Makefile | 1 +
|
||||
drivers/input/keyboard/qt2410kbd.c | 233 +++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 257 insertions(+), 0 deletions(-)
|
||||
create mode 100644 drivers/input/keyboard/qt2410kbd.c
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
|
||||
index 6f7b56d..daf94cd 100644
|
||||
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
|
||||
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
|
||||
@@ -321,6 +321,24 @@ static int __init qt2410_tft_setup(char *str)
|
||||
|
||||
__setup("tft=", qt2410_tft_setup);
|
||||
|
||||
+static struct resource qt2410_button_resources[] = {
|
||||
+ [0] = {
|
||||
+ .start = S3C2410_GPF0,
|
||||
+ .end = S3C2410_GPF0,
|
||||
+ },
|
||||
+ [1] = {
|
||||
+ .start = S3C2410_GPF2,
|
||||
+ .end = S3C2410_GPF2,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device qt2410_button_dev = {
|
||||
+ .name ="qt2410-button",
|
||||
+ .num_resources = ARRAY_SIZE(qt2410_button_resources),
|
||||
+ .resource = qt2410_button_resources,
|
||||
+};
|
||||
+
|
||||
+
|
||||
static void __init qt2410_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
|
||||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
|
||||
index b8ecca9..bc7aac3 100644
|
||||
--- a/drivers/input/keyboard/Kconfig
|
||||
+++ b/drivers/input/keyboard/Kconfig
|
||||
@@ -334,5 +334,10 @@ config KEYBOARD_NEO1973
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called neo1973kbd.
|
||||
|
||||
+config KEYBOARD_QT2410
|
||||
+ tristate "QT2410 buttons"
|
||||
+ depends on MACH_QT2410
|
||||
+ default y
|
||||
+
|
||||
|
||||
endif
|
||||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
|
||||
index b3aa339..63a8972 100644
|
||||
--- a/drivers/input/keyboard/Makefile
|
||||
+++ b/drivers/input/keyboard/Makefile
|
||||
@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
|
||||
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
|
||||
obj-$(CONFIG_KEYBOARD_NEO1973) += neo1973kbd.o
|
||||
+obj-$(CONFIG_KEYBOARD_QT2410) += qt2410kbd.o
|
||||
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
|
||||
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
|
||||
diff --git a/drivers/input/keyboard/qt2410kbd.c b/drivers/input/keyboard/qt2410kbd.c
|
||||
new file mode 100644
|
||||
index 0000000..4d497a3
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/keyboard/qt2410kbd.c
|
||||
@@ -0,0 +1,233 @@
|
||||
+/*
|
||||
+ * Keyboard driver for Armzone QT2410
|
||||
+ *
|
||||
+ * (C) 2006 by OpenMoko, Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/arch/gta01.h>
|
||||
+
|
||||
+struct gta01kbd {
|
||||
+ struct input_dev *input;
|
||||
+ unsigned int suspended;
|
||||
+ unsigned long suspend_jiffies;
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t gta01kbd_interrupt(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct gta01kbd *gta01kbd_data = dev_id;
|
||||
+
|
||||
+ /* FIXME: use GPIO from platform_dev resources */
|
||||
+ if (s3c2410_gpio_getpin(S3C2410_GPF0))
|
||||
+ input_report_key(gta01kbd_data->input, KEY_PHONE, 1);
|
||||
+ else
|
||||
+ input_report_key(gta01kbd_data->input, KEY_PHONE, 0);
|
||||
+
|
||||
+ input_sync(gta01kbd_data->input);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta01kbd_suspend(struct platform_device *dev, pm_message_t state)
|
||||
+{
|
||||
+ struct gta01kbd *gta01kbd = platform_get_drvdata(dev);
|
||||
+
|
||||
+ gta01kbd->suspended = 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta01kbd_resume(struct platform_device *dev)
|
||||
+{
|
||||
+ struct gta01kbd *gta01kbd = platform_get_drvdata(dev);
|
||||
+
|
||||
+ gta01kbd->suspended = 0;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define gta01kbd_suspend NULL
|
||||
+#define gta01kbd_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static int gta01kbd_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct gta01kbd *gta01kbd;
|
||||
+ struct input_dev *input_dev;
|
||||
+ int irq_911;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ gta01kbd = kzalloc(sizeof(struct gta01kbd), GFP_KERNEL);
|
||||
+ if (!gta01kbd) {
|
||||
+ rc = -ENOMEM;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+ input_dev = input_allocate_device();
|
||||
+ if (!gta01kbd || !input_dev) {
|
||||
+ rc = -ENOMEM;
|
||||
+ goto bail_free;
|
||||
+ }
|
||||
+
|
||||
+ if (pdev->resource[0].flags != 0) {\
|
||||
+ rc = -EINVAL;
|
||||
+ goto bail_free_dev;
|
||||
+ }
|
||||
+
|
||||
+ irq_911 = s3c2410_gpio_getirq(pdev->resource[0].start);
|
||||
+ if (irq_911 < 0) {
|
||||
+ rc = -EINVAL;
|
||||
+ goto bail_free_dev;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, gta01kbd);
|
||||
+
|
||||
+ gta01kbd->input = input_dev;
|
||||
+
|
||||
+#if 0
|
||||
+ spin_lock_init(>a01kbd->lock);
|
||||
+ /* Init Keyboard rescan timer */
|
||||
+ init_timer(&corgikbd->timer);
|
||||
+ corgikbd->timer.function = corgikbd_timer_callback;
|
||||
+ corgikbd->timer.data = (unsigned long) corgikbd;
|
||||
+
|
||||
+ /* Init Hinge Timer */
|
||||
+ init_timer(&corgikbd->htimer);
|
||||
+ corgikbd->htimer.function = corgikbd_hinge_timer;
|
||||
+ corgikbd->htimer.data = (unsigned long) corgikbd;
|
||||
+
|
||||
+ corgikbd->suspend_jiffies=jiffies;
|
||||
+
|
||||
+ memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
|
||||
+#endif
|
||||
+
|
||||
+ input_dev->name = "QT2410 Buttons";
|
||||
+ input_dev->phys = "qt2410kbd/input0";
|
||||
+ input_dev->id.bustype = BUS_HOST;
|
||||
+ input_dev->id.vendor = 0x0001;
|
||||
+ input_dev->id.product = 0x0001;
|
||||
+ input_dev->id.version = 0x0100;
|
||||
+ input_dev->cdev.dev = &pdev->dev;
|
||||
+ input_dev->private = gta01kbd;
|
||||
+
|
||||
+ input_dev->evbit[0] = BIT(EV_KEY);
|
||||
+#if 0
|
||||
+ input_dev->keycode = gta01kbd->keycode;
|
||||
+ input_dev->keycodesize = sizeof(unsigned char);
|
||||
+ input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
|
||||
+ set_bit(corgikbd->keycode[i], input_dev->keybit);
|
||||
+ clear_bit(0, input_dev->keybit);
|
||||
+ set_bit(SW_LID, input_dev->swbit);
|
||||
+ set_bit(SW_TABLET_MODE, input_dev->swbit);
|
||||
+ set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
|
||||
+#endif
|
||||
+
|
||||
+ rc = input_register_device(gta01kbd->input);
|
||||
+ if (rc)
|
||||
+ goto bail_free_dev;
|
||||
+
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0);
|
||||
+ if (request_irq(irq_911, gta01kbd_interrupt,
|
||||
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
|
||||
+ IRQF_TRIGGER_FALLING, "qt2410kbd_eint0", gta01kbd))
|
||||
+ printk(KERN_WARNING "gta01kbd: Can't get IRQ\n");
|
||||
+ enable_irq_wake(irq_911);
|
||||
+
|
||||
+ /* FIXME: headphone insert */
|
||||
+
|
||||
+#if 0
|
||||
+ mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
|
||||
+
|
||||
+ /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
|
||||
+ for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) {
|
||||
+ pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN);
|
||||
+ if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt,
|
||||
+ SA_INTERRUPT | SA_TRIGGER_RISING,
|
||||
+ "corgikbd", corgikbd))
|
||||
+ printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i);
|
||||
+ }
|
||||
+
|
||||
+ /* Set Strobe lines as outputs - set high */
|
||||
+ for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
|
||||
+ pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
|
||||
+
|
||||
+ /* Setup the headphone jack as an input */
|
||||
+ pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN);
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+bail_free_dev:
|
||||
+ input_free_device(input_dev);
|
||||
+bail_free:
|
||||
+ kfree(gta01kbd);
|
||||
+bail:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int gta01kbd_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct gta01kbd *gta01kbd = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ free_irq(s3c2410_gpio_getirq(pdev->resource[0].start), gta01kbd);
|
||||
+#if 0
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < CORGI_KEY_SENSE_NUM; i++)
|
||||
+ free_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd);
|
||||
+
|
||||
+ del_timer_sync(&corgikbd->htimer);
|
||||
+ del_timer_sync(&corgikbd->timer);
|
||||
+#endif
|
||||
+ input_unregister_device(gta01kbd->input);
|
||||
+
|
||||
+ kfree(gta01kbd);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta01kbd_driver = {
|
||||
+ .probe = gta01kbd_probe,
|
||||
+ .remove = gta01kbd_remove,
|
||||
+ .suspend = gta01kbd_suspend,
|
||||
+ .resume = gta01kbd_resume,
|
||||
+ .driver = {
|
||||
+ .name = "qt2410-button",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __devinit gta01kbd_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a01kbd_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit gta01kbd_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a01kbd_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta01kbd_init);
|
||||
+module_exit(gta01kbd_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
+MODULE_DESCRIPTION("Armzone QT2410 Buttons Driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From 10042752e49358e1ef5ccfbb4e1c27875f3f43c5 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] fail-unless-uimage.patch
|
||||
Fail the build noisily if "mkimage" can't be found, e.g., if we forgot to add
|
||||
the u-boot directory to PATH.
|
||||
|
||||
---
|
||||
scripts/mkuboot.sh | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh
|
||||
index 2e3d3cd..446739c 100755
|
||||
--- a/scripts/mkuboot.sh
|
||||
+++ b/scripts/mkuboot.sh
|
||||
@@ -11,7 +11,7 @@ if [ -z "${MKIMAGE}" ]; then
|
||||
if [ -z "${MKIMAGE}" ]; then
|
||||
# Doesn't exist
|
||||
echo '"mkimage" command not found - U-Boot images will not be built' >&2
|
||||
- exit 0;
|
||||
+ exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,587 @@
|
|||
From 6a2c7de90f47b7eb74f3cb2d181f950ece22b3fb Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] introduce-fiq-basis.patch
|
||||
Adds a C-based FIQ ISR which is very convenient (and unusual --
|
||||
normally you have to do FIQ ISR in assembler only).
|
||||
Based on my article:
|
||||
|
||||
http://warmcat.com/_wp/2007/09/17/at91rm9200-fiq-faq-and-simple-example-code-patch/
|
||||
|
||||
Implemented as a platform device and driver.
|
||||
|
||||
Suspend / resume is tested and works.
|
||||
|
||||
Signed-off-by: Andy Green <andy@warmcat.com>
|
||||
---
|
||||
arch/arm/mach-s3c2440/Kconfig | 7 +
|
||||
arch/arm/mach-s3c2440/Makefile | 1 +
|
||||
arch/arm/mach-s3c2440/fiq_c_isr.c | 250 ++++++++++++++++++++++++++
|
||||
arch/arm/mach-s3c2440/fiq_c_isr.h | 64 +++++++
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 22 +++
|
||||
arch/arm/plat-s3c24xx/irq.c | 32 +++-
|
||||
include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h | 28 +++
|
||||
include/asm-arm/plat-s3c24xx/irq.h | 20 ++
|
||||
8 files changed, 422 insertions(+), 2 deletions(-)
|
||||
create mode 100644 arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
create mode 100644 arch/arm/mach-s3c2440/fiq_c_isr.h
|
||||
create mode 100644 include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
|
||||
index 6b317d1..3015aaf 100644
|
||||
--- a/arch/arm/mach-s3c2440/Kconfig
|
||||
+++ b/arch/arm/mach-s3c2440/Kconfig
|
||||
@@ -22,6 +22,13 @@ config S3C2440_DMA
|
||||
help
|
||||
Support for S3C2440 specific DMA code5A
|
||||
|
||||
+config S3C2440_C_FIQ
|
||||
+ bool "FIQ ISR support in C"
|
||||
+ depends on ARCH_S3C2410
|
||||
+ select FIQ
|
||||
+ help
|
||||
+ Support for S3C2440 FIQ support in C -- see
|
||||
+ ./arch/arm/macs3c2440/fiq_c_isr.c
|
||||
|
||||
menu "S3C2440 Machines"
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
|
||||
index 1a4defd..4932232 100644
|
||||
--- a/arch/arm/mach-s3c2440/Makefile
|
||||
+++ b/arch/arm/mach-s3c2440/Makefile
|
||||
@@ -13,6 +13,7 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
|
||||
obj-$(CONFIG_CPU_S3C2440) += irq.o
|
||||
obj-$(CONFIG_CPU_S3C2440) += clock.o
|
||||
obj-$(CONFIG_S3C2440_DMA) += dma.o
|
||||
+obj-$(CONFIG_S3C2440_C_FIQ) += fiq_c_isr.o
|
||||
|
||||
# Machine support
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.c b/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
new file mode 100644
|
||||
index 0000000..12f4527
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
@@ -0,0 +1,250 @@
|
||||
+/*
|
||||
+ * Copyright 2007 Andy Green <andy@warmcat.com>
|
||||
+ * S3C modfifications
|
||||
+ * Copyright 2008 Andy Green <andy@openmoko.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/fiq.h>
|
||||
+#include "fiq_c_isr.h"
|
||||
+#include <linux/sysfs.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <asm/io.h>
|
||||
+
|
||||
+#include <asm/plat-s3c24xx/cpu.h>
|
||||
+#include <asm/plat-s3c24xx/irq.h>
|
||||
+
|
||||
+/*
|
||||
+ * Major Caveats for using FIQ
|
||||
+ * ---------------------------
|
||||
+ *
|
||||
+ * 1) it CANNOT touch any vmalloc()'d memory, only memory
|
||||
+ * that was kmalloc()'d. Static allocations in the monolithic kernel
|
||||
+ * are kmalloc()'d so they are okay. You can touch memory-mapped IO, but
|
||||
+ * the pointer for it has to have been stored in kmalloc'd memory. The
|
||||
+ * reason for this is simple: every now and then Linux turns off interrupts
|
||||
+ * and reorders the paging tables. If a FIQ happens during this time, the
|
||||
+ * virtual memory space can be partly or entirely disordered or missing.
|
||||
+ *
|
||||
+ * 2) Because vmalloc() is used when a module is inserted, THIS FIQ
|
||||
+ * ISR HAS TO BE IN THE MONOLITHIC KERNEL, not a module. But the way
|
||||
+ * it is set up, you can all to enable and disable it from your module
|
||||
+ * and intercommunicate with it through struct fiq_ipc
|
||||
+ * fiq_ipc which you can define in
|
||||
+ * asm/archfiq_ipc_type.h. The reason is the same as above, a
|
||||
+ * FIQ could happen while even the ISR is not present in virtual memory
|
||||
+ * space due to pagetables being changed at the time.
|
||||
+ *
|
||||
+ * 3) You can't call any Linux API code except simple macros
|
||||
+ * - understand that FIQ can come in at any time, no matter what
|
||||
+ * state of undress the kernel may privately be in, thinking it
|
||||
+ * locked the door by turning off interrupts... FIQ is an
|
||||
+ * unstoppable monster force (which is its value)
|
||||
+ * - they are not vmalloc()'d memory safe
|
||||
+ * - they might do crazy stuff like sleep: FIQ pisses fire and
|
||||
+ * is not interested in 'sleep' that the weak seem to need
|
||||
+ * - calling APIs from FIQ can re-enter un-renterable things
|
||||
+ * - summary: you cannot interoperate with linux APIs directly in the FIQ ISR
|
||||
+ *
|
||||
+ * If you follow these rules, it is fantastic, an extremely powerful, solid,
|
||||
+ * genuine hard realtime feature.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/* more than enough to cover our jump instruction to the isr */
|
||||
+#define SIZEOF_FIQ_JUMP 8
|
||||
+/* more than enough to cover s3c2440_fiq_isr() in 4K blocks */
|
||||
+#define SIZEOF_FIQ_ISR 0x2000
|
||||
+/* increase the size of the stack that is active during FIQ as needed */
|
||||
+static u8 u8aFiqStack[4096];
|
||||
+
|
||||
+/* only one FIQ ISR possible, okay to do these here */
|
||||
+u32 _fiq_ack_mask; /* used by isr exit define */
|
||||
+unsigned long _fiq_count_fiqs; /* used by isr exit define */
|
||||
+static int _fiq_irq; /* private ; irq index we were started with, or 0 */
|
||||
+
|
||||
+/* this function must live in the monolithic kernel somewhere! A module is
|
||||
+ * NOT good enough!
|
||||
+ */
|
||||
+extern void __attribute__ ((naked)) s3c2440_fiq_isr(void);
|
||||
+
|
||||
+/* this is copied into the hard FIQ vector during init */
|
||||
+
|
||||
+static void __attribute__ ((naked)) s3c2440_FIQ_Branch(void)
|
||||
+{
|
||||
+ asm __volatile__ (
|
||||
+ "mov pc, r8 ; "
|
||||
+ );
|
||||
+}
|
||||
+
|
||||
+/* sysfs */
|
||||
+
|
||||
+static ssize_t show_count(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ return sprintf(buf, "%ld\n", _fiq_count_fiqs);
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(count, 0444, show_count, NULL);
|
||||
+
|
||||
+static struct attribute *s3c2440_fiq_sysfs_entries[] = {
|
||||
+ &dev_attr_count.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group s3c2440_fiq_attr_group = {
|
||||
+ .name = "fiq",
|
||||
+ .attrs = s3c2440_fiq_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * call this from your kernel module to set up the FIQ ISR to service FIQs,
|
||||
+ * You need to have configured your FIQ input pin before anything will happen
|
||||
+ *
|
||||
+ * call it with, eg, IRQ_TIMER3 from asm-arm/arch-s3c2410/irqs.h
|
||||
+ *
|
||||
+ * you still need to clear the source interrupt in S3C2410_INTMSK to get
|
||||
+ * anything good happening
|
||||
+ */
|
||||
+static void fiq_init_irq_source(int irq_index_fiq)
|
||||
+{
|
||||
+ if (!irq_index_fiq) /* no interrupt */
|
||||
+ return;
|
||||
+
|
||||
+ printk(KERN_INFO"Enabling FIQ using int idx %d\n",
|
||||
+ irq_index_fiq - S3C2410_CPUIRQ_OFFSET);
|
||||
+ local_fiq_disable();
|
||||
+
|
||||
+ _fiq_irq = irq_index_fiq;
|
||||
+ _fiq_ack_mask = 1 << (irq_index_fiq - S3C2410_CPUIRQ_OFFSET);
|
||||
+
|
||||
+ /* let our selected interrupt be a magic FIQ interrupt */
|
||||
+ __raw_writel(_fiq_ack_mask, S3C2410_INTMOD);
|
||||
+
|
||||
+ /* it's ready to go as soon as we unmask the source in S3C2410_INTMSK */
|
||||
+ local_fiq_enable();
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* call this from your kernel module to disable generation of FIQ actions */
|
||||
+static void fiq_disable_irq_source(void)
|
||||
+{
|
||||
+ /* nothing makes FIQ any more */
|
||||
+ __raw_writel(0, S3C2410_INTMOD);
|
||||
+ local_fiq_disable();
|
||||
+ _fiq_irq = 0; /* no active source interrupt now either */
|
||||
+}
|
||||
+
|
||||
+/* this starts FIQ timer events... they continue until the FIQ ISR sees that
|
||||
+ * its work is done and it turns off the timer. After setting up the fiq_ipc
|
||||
+ * struct with new work, you call this to start FIQ timer actions up again.
|
||||
+ * Only the FIQ ISR decides when it is done and controls turning off the
|
||||
+ * timer events.
|
||||
+ */
|
||||
+void fiq_kick(void)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ /* we have to take care about FIQ because this modification is
|
||||
+ * non-atomic, FIQ could come in after the read and before the
|
||||
+ * writeback and its changes to the register would be lost
|
||||
+ * (platform INTMSK mod code is taken care of already)
|
||||
+ */
|
||||
+ local_save_flags(flags);
|
||||
+ local_fiq_disable();
|
||||
+ __raw_writel(__raw_readl(S3C2410_INTMSK) &
|
||||
+ ~(1 << (_fiq_irq - S3C2410_CPUIRQ_OFFSET)),
|
||||
+ S3C2410_INTMSK);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(fiq_kick);
|
||||
+
|
||||
+
|
||||
+
|
||||
+static int __init sc32440_fiq_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
+
|
||||
+ if (!r)
|
||||
+ return -EIO;
|
||||
+ /* configure for the interrupt we are meant to use */
|
||||
+ fiq_init_irq_source(r->start);
|
||||
+
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, &s3c2440_fiq_attr_group);
|
||||
+}
|
||||
+
|
||||
+static int sc32440_fiq_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ fiq_disable_irq_source();
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, &s3c2440_fiq_attr_group);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void fiq_set_vector_and_regs(void)
|
||||
+{
|
||||
+ struct pt_regs regs;
|
||||
+
|
||||
+ /* prep the special FIQ mode regs */
|
||||
+ memset(®s, 0, sizeof(regs));
|
||||
+ regs.ARM_r8 = (unsigned long)s3c2440_fiq_isr;
|
||||
+ regs.ARM_sp = (unsigned long)u8aFiqStack + sizeof(u8aFiqStack) - 4;
|
||||
+ /* set up the special FIQ-mode-only registers from our regs */
|
||||
+ set_fiq_regs(®s);
|
||||
+ /* copy our jump to the real ISR into the hard vector address */
|
||||
+ set_fiq_handler(s3c2440_FIQ_Branch, SIZEOF_FIQ_JUMP);
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int sc32440_fiq_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ /* nothing makes FIQ any more */
|
||||
+ __raw_writel(0, S3C2410_INTMOD);
|
||||
+ local_fiq_disable();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sc32440_fiq_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ fiq_set_vector_and_regs();
|
||||
+ fiq_init_irq_source(_fiq_irq);
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define sc32440_fiq_suspend NULL
|
||||
+#define sc32440_fiq_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static struct platform_driver sc32440_fiq_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "sc32440_fiq",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+
|
||||
+ .probe = sc32440_fiq_probe,
|
||||
+ .remove = __devexit_p(sc32440_fiq_remove),
|
||||
+ .suspend = sc32440_fiq_suspend,
|
||||
+ .resume = sc32440_fiq_resume,
|
||||
+};
|
||||
+
|
||||
+static int __init sc32440_fiq_init(void)
|
||||
+{
|
||||
+ fiq_set_vector_and_regs();
|
||||
+
|
||||
+ return platform_driver_register(&sc32440_fiq_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit sc32440_fiq_exit(void)
|
||||
+{
|
||||
+ fiq_disable_irq_source();
|
||||
+}
|
||||
+
|
||||
+MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+module_init(sc32440_fiq_init);
|
||||
+module_exit(sc32440_fiq_exit);
|
||||
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.h b/arch/arm/mach-s3c2440/fiq_c_isr.h
|
||||
new file mode 100644
|
||||
index 0000000..f08740e
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.h
|
||||
@@ -0,0 +1,64 @@
|
||||
+#ifndef _LINUX_FIQ_C_ISR_H
|
||||
+#define _LINUX_FIQ_C_ISR_H
|
||||
+
|
||||
+#include <asm/arch-s3c2410/regs-irq.h>
|
||||
+
|
||||
+extern unsigned long _fiq_count_fiqs;
|
||||
+extern u32 _fiq_ack_mask;
|
||||
+
|
||||
+/* This CANNOT be implemented in a module -- it has to be used in code
|
||||
+ * included in the monolithic kernel
|
||||
+ */
|
||||
+
|
||||
+#define FIQ_HANDLER_START() \
|
||||
+void __attribute__ ((naked)) s3c2440_fiq_isr(void) \
|
||||
+{\
|
||||
+ /*\
|
||||
+ * you can declare local vars here, take care to set the frame size\
|
||||
+ * below accordingly if there are more than a few dozen bytes of them\
|
||||
+ */\
|
||||
+
|
||||
+/* stick your locals here :-)
|
||||
+ * Do NOT initialize them here! define them and initialize them after
|
||||
+ * FIQ_HANDLER_ENTRY() is done.
|
||||
+ */
|
||||
+
|
||||
+#define FIQ_HANDLER_ENTRY(LOCALS, FRAME) \
|
||||
+ const int _FIQ_FRAME_SIZE = FRAME; \
|
||||
+ /* entry takes care to store registers we will be treading on here */\
|
||||
+ asm __volatile__ (\
|
||||
+ "mov ip, sp ;"\
|
||||
+ /* stash FIQ and r0-r8 normal regs */\
|
||||
+ "stmdb sp!, {r0-r12, lr};"\
|
||||
+ /* allow SP to get some space */\
|
||||
+ "sub sp, sp, %1 ;"\
|
||||
+ /* !! THIS SETS THE FRAME, adjust to > sizeof locals */\
|
||||
+ "sub fp, sp, %0 ;"\
|
||||
+ :\
|
||||
+ : "rI" (LOCALS), "rI" (FRAME)\
|
||||
+ :"r9"\
|
||||
+ );
|
||||
+
|
||||
+/* stick your ISR code here and then end with... */
|
||||
+
|
||||
+#define FIQ_HANDLER_END() \
|
||||
+ _fiq_count_fiqs++;\
|
||||
+ __raw_writel(_fiq_ack_mask, S3C2410_SRCPND);\
|
||||
+\
|
||||
+ /* exit back to normal mode restoring everything */\
|
||||
+ asm __volatile__ (\
|
||||
+ /* pop our allocation */\
|
||||
+ "add sp, sp, %0 ;"\
|
||||
+ /* return FIQ regs back to pristine state\
|
||||
+ * and get normal regs back\
|
||||
+ */\
|
||||
+ "ldmia sp!, {r0-r12, lr};"\
|
||||
+\
|
||||
+ /* return */\
|
||||
+ "subs pc, lr, #4;"\
|
||||
+ : \
|
||||
+ : "rI" (_FIQ_FRAME_SIZE) \
|
||||
+ );\
|
||||
+}
|
||||
+
|
||||
+#endif /* _LINUX_FIQ_C_ISR_H */
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index 46acede..0bdd0e0 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -78,9 +78,31 @@
|
||||
|
||||
#include <linux/glamofb.h>
|
||||
|
||||
+#include <asm/arch/fiq_ipc_gta02.h>
|
||||
+#include "fiq_c_isr.h"
|
||||
+
|
||||
/* arbitrates which sensor IRQ owns the shared SPI bus */
|
||||
static spinlock_t motion_irq_lock;
|
||||
|
||||
+/* define FIQ IPC struct */
|
||||
+/*
|
||||
+ * contains stuff FIQ ISR modifies and normal kernel code can see and use
|
||||
+ * this is defined in <asm/arch/fiq_ipc_gta02.h>, you should customize
|
||||
+ * the definition in there and include the same definition in your kernel
|
||||
+ * module that wants to interoperate with your FIQ code.
|
||||
+ */
|
||||
+struct fiq_ipc fiq_ipc;
|
||||
+EXPORT_SYMBOL(fiq_ipc);
|
||||
+
|
||||
+/* define FIQ ISR */
|
||||
+
|
||||
+FIQ_HANDLER_START()
|
||||
+/* define your locals here -- no initializers though */
|
||||
+FIQ_HANDLER_ENTRY(256, 512)
|
||||
+/* Your ISR here :-) */
|
||||
+FIQ_HANDLER_END()
|
||||
+
|
||||
+
|
||||
static struct map_desc gta02_iodesc[] __initdata = {
|
||||
{
|
||||
.virtual = 0xe0000000,
|
||||
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
|
||||
index ae2c5d7..9887db1 100644
|
||||
--- a/arch/arm/plat-s3c24xx/irq.c
|
||||
+++ b/arch/arm/plat-s3c24xx/irq.c
|
||||
@@ -133,12 +133,20 @@ static void
|
||||
s3c_irq_mask(unsigned int irqno)
|
||||
{
|
||||
unsigned long mask;
|
||||
-
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ unsigned long flags;
|
||||
+#endif
|
||||
irqno -= IRQ_EINT0;
|
||||
-
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_save_flags(flags);
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
mask = __raw_readl(S3C2410_INTMSK);
|
||||
mask |= 1UL << irqno;
|
||||
__raw_writel(mask, S3C2410_INTMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_irq_restore(flags);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -155,9 +163,19 @@ s3c_irq_maskack(unsigned int irqno)
|
||||
{
|
||||
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
|
||||
unsigned long mask;
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ unsigned long flags;
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_save_flags(flags);
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
mask = __raw_readl(S3C2410_INTMSK);
|
||||
__raw_writel(mask|bitval, S3C2410_INTMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_irq_restore(flags);
|
||||
+#endif
|
||||
|
||||
__raw_writel(bitval, S3C2410_SRCPND);
|
||||
__raw_writel(bitval, S3C2410_INTPND);
|
||||
@@ -168,15 +186,25 @@ static void
|
||||
s3c_irq_unmask(unsigned int irqno)
|
||||
{
|
||||
unsigned long mask;
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ unsigned long flags;
|
||||
+#endif
|
||||
|
||||
if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
|
||||
irqdbf2("s3c_irq_unmask %d\n", irqno);
|
||||
|
||||
irqno -= IRQ_EINT0;
|
||||
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_save_flags(flags);
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
mask = __raw_readl(S3C2410_INTMSK);
|
||||
mask &= ~(1UL << irqno);
|
||||
__raw_writel(mask, S3C2410_INTMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_irq_restore(flags);
|
||||
+#endif
|
||||
}
|
||||
|
||||
struct irq_chip s3c_irq_level_chip = {
|
||||
diff --git a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
new file mode 100644
|
||||
index 0000000..341f2bb
|
||||
--- /dev/null
|
||||
+++ b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+#ifndef _LINUX_FIQ_IPC_H
|
||||
+#define _LINUX_FIQ_IPC_H
|
||||
+
|
||||
+/*
|
||||
+ * this defines the struct which is used to communicate between the FIQ
|
||||
+ * world and the normal linux kernel world. One of these structs is
|
||||
+ * statically defined for you in the monolithic kernel so the FIQ ISR code
|
||||
+ * can safely touch it any any time.
|
||||
+ *
|
||||
+ * You also want to include this file in your kernel module that wants to
|
||||
+ * communicate with your FIQ code. Add any kinds of vars that are used by
|
||||
+ * the FIQ ISR and the module in here.
|
||||
+ *
|
||||
+ * To get you started there is just an int that is incremented every FIQ
|
||||
+ * you can remove this when you are ready to customize, but it is useful
|
||||
+ * for testing
|
||||
+ */
|
||||
+
|
||||
+struct fiq_ipc {
|
||||
+ u8 u8a[0]; /* placeholder */
|
||||
+};
|
||||
+
|
||||
+/* actual definition lives in arch/arm/mach-s3c2440/fiq_c_isr.c */
|
||||
+extern struct fiq_ipc fiq_ipc;
|
||||
+
|
||||
+extern void fiq_kick(void); /* provoke a FIQ "immediately" */
|
||||
+
|
||||
+#endif /* _LINUX_FIQ_IPC_H */
|
||||
diff --git a/include/asm-arm/plat-s3c24xx/irq.h b/include/asm-arm/plat-s3c24xx/irq.h
|
||||
index 45746a9..bf15e1c 100644
|
||||
--- a/include/asm-arm/plat-s3c24xx/irq.h
|
||||
+++ b/include/asm-arm/plat-s3c24xx/irq.h
|
||||
@@ -25,8 +25,15 @@ s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
|
||||
{
|
||||
unsigned long mask;
|
||||
unsigned long submask;
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ unsigned long flags;
|
||||
+#endif
|
||||
|
||||
submask = __raw_readl(S3C2410_INTSUBMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_save_flags(flags);
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
mask = __raw_readl(S3C2410_INTMSK);
|
||||
|
||||
submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
|
||||
@@ -39,6 +46,9 @@ s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
|
||||
|
||||
/* write back masks */
|
||||
__raw_writel(submask, S3C2410_INTSUBMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_irq_restore(flags);
|
||||
+#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -47,8 +57,15 @@ s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
|
||||
{
|
||||
unsigned long mask;
|
||||
unsigned long submask;
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ unsigned long flags;
|
||||
+#endif
|
||||
|
||||
submask = __raw_readl(S3C2410_INTSUBMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_save_flags(flags);
|
||||
+ local_fiq_disable();
|
||||
+#endif
|
||||
mask = __raw_readl(S3C2410_INTMSK);
|
||||
|
||||
submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
|
||||
@@ -57,6 +74,9 @@ s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
|
||||
/* write back masks */
|
||||
__raw_writel(submask, S3C2410_INTSUBMSK);
|
||||
__raw_writel(mask, S3C2410_INTMSK);
|
||||
+#ifdef CONFIG_S3C2440_C_FIQ
|
||||
+ local_irq_restore(flags);
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
220
target/linux/s3c24xx/patches/0046-introduce-fiq-use-timer3-as-source.patch.patch
Executable file
220
target/linux/s3c24xx/patches/0046-introduce-fiq-use-timer3-as-source.patch.patch
Executable file
|
@ -0,0 +1,220 @@
|
|||
From 26fa0c816d5e1b593128477c7e200fafe3caae18 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:22 +0100
|
||||
Subject: [PATCH] introduce-fiq-use-timer3-as-source.patch
|
||||
|
||||
This makes the FIQ stuff specific to one of the timers on the
|
||||
s3c244x and adds the platform stuff for fiq in the gta02 init
|
||||
|
||||
Currently one sysfs node is exposed, a count of FIQ events
|
||||
|
||||
cat /sys/devices/platform/sc32440_fiq.0/fiq/count
|
||||
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
arch/arm/mach-s3c2440/fiq_c_isr.c | 56 +++++++++++++++++++++----
|
||||
arch/arm/mach-s3c2440/fiq_c_isr.h | 2 +
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 17 ++++++++
|
||||
include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h | 2 +-
|
||||
4 files changed, 67 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.c b/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
index 12f4527..a71a234 100644
|
||||
--- a/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
@@ -18,6 +18,9 @@
|
||||
#include <asm/plat-s3c24xx/cpu.h>
|
||||
#include <asm/plat-s3c24xx/irq.h>
|
||||
|
||||
+#include <asm/arch/pwm.h>
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+
|
||||
/*
|
||||
* Major Caveats for using FIQ
|
||||
* ---------------------------
|
||||
@@ -66,6 +69,10 @@ static u8 u8aFiqStack[4096];
|
||||
u32 _fiq_ack_mask; /* used by isr exit define */
|
||||
unsigned long _fiq_count_fiqs; /* used by isr exit define */
|
||||
static int _fiq_irq; /* private ; irq index we were started with, or 0 */
|
||||
+struct s3c2410_pwm pwm_timer_fiq;
|
||||
+int _fiq_timer_index;
|
||||
+u16 _fiq_timer_divisor;
|
||||
+
|
||||
|
||||
/* this function must live in the monolithic kernel somewhere! A module is
|
||||
* NOT good enough!
|
||||
@@ -110,23 +117,45 @@ static struct attribute_group s3c2440_fiq_attr_group = {
|
||||
* you still need to clear the source interrupt in S3C2410_INTMSK to get
|
||||
* anything good happening
|
||||
*/
|
||||
-static void fiq_init_irq_source(int irq_index_fiq)
|
||||
+static int fiq_init_irq_source(int irq_index_fiq)
|
||||
{
|
||||
+ int rc = 0;
|
||||
+
|
||||
if (!irq_index_fiq) /* no interrupt */
|
||||
- return;
|
||||
+ goto bail;
|
||||
|
||||
- printk(KERN_INFO"Enabling FIQ using int idx %d\n",
|
||||
- irq_index_fiq - S3C2410_CPUIRQ_OFFSET);
|
||||
local_fiq_disable();
|
||||
|
||||
_fiq_irq = irq_index_fiq;
|
||||
_fiq_ack_mask = 1 << (irq_index_fiq - S3C2410_CPUIRQ_OFFSET);
|
||||
+ timer_index = (irq_index_fiq - IRQ_TIMER0);
|
||||
+
|
||||
+ /* set up the timer to operate as a pwm device */
|
||||
+
|
||||
+ rc = s3c2410_pwm_init(&pwm_timer_fiq);
|
||||
+ if (rc)
|
||||
+ goto bail;
|
||||
+
|
||||
+ pwm_timer_fiq.timerid = PWM0 + timer_index;
|
||||
+ pwm_timer_fiq.prescaler = (6 - 1) / 2;
|
||||
+ pwm_timer_fiq.divider = S3C2410_TCFG1_MUX3_DIV2;
|
||||
+ /* default rate == ~32us */
|
||||
+ pwm_timer_fiq.counter = pwm_timer_fiq.comparer =
|
||||
+ timer_divisor = 64;
|
||||
+
|
||||
+ rc = s3c2410_pwm_enable(&pwm_timer_fiq);
|
||||
+ if (rc)
|
||||
+ goto bail;
|
||||
+
|
||||
+ s3c2410_pwm_start(&pwm_timer_fiq);
|
||||
|
||||
/* let our selected interrupt be a magic FIQ interrupt */
|
||||
__raw_writel(_fiq_ack_mask, S3C2410_INTMOD);
|
||||
|
||||
/* it's ready to go as soon as we unmask the source in S3C2410_INTMSK */
|
||||
local_fiq_enable();
|
||||
+bail:
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,15 +168,13 @@ static void fiq_disable_irq_source(void)
|
||||
_fiq_irq = 0; /* no active source interrupt now either */
|
||||
}
|
||||
|
||||
-/* this starts FIQ timer events... they continue until the FIQ ISR sees that
|
||||
- * its work is done and it turns off the timer. After setting up the fiq_ipc
|
||||
- * struct with new work, you call this to start FIQ timer actions up again.
|
||||
- * Only the FIQ ISR decides when it is done and controls turning off the
|
||||
- * timer events.
|
||||
+/*
|
||||
+ * fiq_kick() forces a FIQ event to happen shortly after leaving the routine
|
||||
*/
|
||||
void fiq_kick(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
+ u32 tcon;
|
||||
|
||||
/* we have to take care about FIQ because this modification is
|
||||
* non-atomic, FIQ could come in after the read and before the
|
||||
@@ -156,15 +183,24 @@ void fiq_kick(void)
|
||||
*/
|
||||
local_save_flags(flags);
|
||||
local_fiq_disable();
|
||||
+ /* allow FIQs to resume */
|
||||
__raw_writel(__raw_readl(S3C2410_INTMSK) &
|
||||
~(1 << (_fiq_irq - S3C2410_CPUIRQ_OFFSET)),
|
||||
S3C2410_INTMSK);
|
||||
+ tcon = __raw_readl(S3C2410_TCON) & ~S3C2410_TCON_T3START;
|
||||
+ /* fake the timer to a count of 1 */
|
||||
+ __raw_writel(1, S3C2410_TCNTB(timer_index));
|
||||
+ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD, S3C2410_TCON);
|
||||
+ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD | S3C2410_TCON_T3START,
|
||||
+ S3C2410_TCON);
|
||||
+ __raw_writel(tcon | S3C2410_TCON_T3START, S3C2410_TCON);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fiq_kick);
|
||||
|
||||
|
||||
|
||||
+
|
||||
static int __init sc32440_fiq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
@@ -172,6 +208,8 @@ static int __init sc32440_fiq_probe(struct platform_device *pdev)
|
||||
if (!r)
|
||||
return -EIO;
|
||||
/* configure for the interrupt we are meant to use */
|
||||
+ printk(KERN_INFO"Enabling FIQ using irq %d\n", r->start);
|
||||
+
|
||||
fiq_init_irq_source(r->start);
|
||||
|
||||
return sysfs_create_group(&pdev->dev.kobj, &s3c2440_fiq_attr_group);
|
||||
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.h b/arch/arm/mach-s3c2440/fiq_c_isr.h
|
||||
index f08740e..0c45eb7 100644
|
||||
--- a/arch/arm/mach-s3c2440/fiq_c_isr.h
|
||||
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.h
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
extern unsigned long _fiq_count_fiqs;
|
||||
extern u32 _fiq_ack_mask;
|
||||
+extern int _fiq_timer_index;
|
||||
+extern u16 _fiq_timer_divisor;
|
||||
|
||||
/* This CANNOT be implemented in a module -- it has to be used in code
|
||||
* included in the monolithic kernel
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index 0bdd0e0..cb839b2 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
+#include <asm/arch-s3c2410/regs-irq.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/regs-gpioj.h>
|
||||
#include <asm/arch/fb.h>
|
||||
@@ -336,6 +337,21 @@ struct platform_device gta02_pmu_dev = {
|
||||
},
|
||||
};
|
||||
|
||||
+/* FIQ */
|
||||
+
|
||||
+static struct resource sc32440_fiq_resources[] = {
|
||||
+ [0] = {
|
||||
+ .flags = IORESOURCE_IRQ,
|
||||
+ .start = IRQ_TIMER3,
|
||||
+ .end = IRQ_TIMER3,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device sc32440_fiq_device = {
|
||||
+ .name = "sc32440_fiq",
|
||||
+ .num_resources = 1,
|
||||
+ .resource = sc32440_fiq_resources,
|
||||
+};
|
||||
|
||||
/* NOR Flash */
|
||||
|
||||
@@ -403,6 +419,7 @@ static struct platform_device *gta02_devices[] __initdata = {
|
||||
&s3c_device_nand,
|
||||
&s3c_device_ts,
|
||||
>a02_nor_flash,
|
||||
+ &sc32440_fiq_device,
|
||||
};
|
||||
|
||||
static struct s3c2410_nand_set gta02_nand_sets[] = {
|
||||
diff --git a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
index 341f2bb..6cbd8e4 100644
|
||||
--- a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
+++ b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
@@ -22,7 +22,7 @@ struct fiq_ipc {
|
||||
|
||||
/* actual definition lives in arch/arm/mach-s3c2440/fiq_c_isr.c */
|
||||
extern struct fiq_ipc fiq_ipc;
|
||||
-
|
||||
+extern unsigned long _fiq_count_fiqs;
|
||||
extern void fiq_kick(void); /* provoke a FIQ "immediately" */
|
||||
|
||||
#endif /* _LINUX_FIQ_IPC_H */
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
From b740b1200958baf4b5675017531c773bad5b64d0 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:23 +0100
|
||||
Subject: [PATCH] introduce-fiq-migrate-vibrator-gta02-only.patch
|
||||
|
||||
On GTA02 we use FIQ to manage the vibrator IO now. That
|
||||
is necessary because we stole timer3 from doing hw pwm
|
||||
for vibrator. This keeps the same UI in /sys but does
|
||||
"bitbang pwm" on the same vibrator GPIO
|
||||
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
arch/arm/mach-s3c2440/fiq_c_isr.c | 13 +++++---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 38 ++++++++++++++++++++++++++
|
||||
drivers/leds/Kconfig | 1 +
|
||||
drivers/leds/leds-neo1973-vibrator.c | 24 +++++++++++++++-
|
||||
include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h | 9 +++++-
|
||||
5 files changed, 77 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.c b/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
index a71a234..38692fc 100644
|
||||
--- a/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.c
|
||||
@@ -79,6 +79,7 @@ u16 _fiq_timer_divisor;
|
||||
*/
|
||||
extern void __attribute__ ((naked)) s3c2440_fiq_isr(void);
|
||||
|
||||
+
|
||||
/* this is copied into the hard FIQ vector during init */
|
||||
|
||||
static void __attribute__ ((naked)) s3c2440_FIQ_Branch(void)
|
||||
@@ -128,7 +129,7 @@ static int fiq_init_irq_source(int irq_index_fiq)
|
||||
|
||||
_fiq_irq = irq_index_fiq;
|
||||
_fiq_ack_mask = 1 << (irq_index_fiq - S3C2410_CPUIRQ_OFFSET);
|
||||
- timer_index = (irq_index_fiq - IRQ_TIMER0);
|
||||
+ _fiq_timer_index = (irq_index_fiq - IRQ_TIMER0);
|
||||
|
||||
/* set up the timer to operate as a pwm device */
|
||||
|
||||
@@ -136,12 +137,11 @@ static int fiq_init_irq_source(int irq_index_fiq)
|
||||
if (rc)
|
||||
goto bail;
|
||||
|
||||
- pwm_timer_fiq.timerid = PWM0 + timer_index;
|
||||
+ pwm_timer_fiq.timerid = PWM0 + _fiq_timer_index;
|
||||
pwm_timer_fiq.prescaler = (6 - 1) / 2;
|
||||
pwm_timer_fiq.divider = S3C2410_TCFG1_MUX3_DIV2;
|
||||
/* default rate == ~32us */
|
||||
- pwm_timer_fiq.counter = pwm_timer_fiq.comparer =
|
||||
- timer_divisor = 64;
|
||||
+ pwm_timer_fiq.counter = pwm_timer_fiq.comparer = 3000;
|
||||
|
||||
rc = s3c2410_pwm_enable(&pwm_timer_fiq);
|
||||
if (rc)
|
||||
@@ -149,6 +149,8 @@ static int fiq_init_irq_source(int irq_index_fiq)
|
||||
|
||||
s3c2410_pwm_start(&pwm_timer_fiq);
|
||||
|
||||
+ _fiq_timer_divisor = 0xffff; /* so kick will work initially */
|
||||
+
|
||||
/* let our selected interrupt be a magic FIQ interrupt */
|
||||
__raw_writel(_fiq_ack_mask, S3C2410_INTMOD);
|
||||
|
||||
@@ -189,7 +191,7 @@ void fiq_kick(void)
|
||||
S3C2410_INTMSK);
|
||||
tcon = __raw_readl(S3C2410_TCON) & ~S3C2410_TCON_T3START;
|
||||
/* fake the timer to a count of 1 */
|
||||
- __raw_writel(1, S3C2410_TCNTB(timer_index));
|
||||
+ __raw_writel(1, S3C2410_TCNTB(_fiq_timer_index));
|
||||
__raw_writel(tcon | S3C2410_TCON_T3MANUALUPD, S3C2410_TCON);
|
||||
__raw_writel(tcon | S3C2410_TCON_T3MANUALUPD | S3C2410_TCON_T3START,
|
||||
S3C2410_TCON);
|
||||
@@ -207,6 +209,7 @@ static int __init sc32440_fiq_probe(struct platform_device *pdev)
|
||||
|
||||
if (!r)
|
||||
return -EIO;
|
||||
+
|
||||
/* configure for the interrupt we are meant to use */
|
||||
printk(KERN_INFO"Enabling FIQ using irq %d\n", r->start);
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index cb839b2..8c7bbe7 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -95,12 +95,50 @@ static spinlock_t motion_irq_lock;
|
||||
struct fiq_ipc fiq_ipc;
|
||||
EXPORT_SYMBOL(fiq_ipc);
|
||||
|
||||
+#define DIVISOR_FROM_US(x) ((x) << 1)
|
||||
+
|
||||
+#define FIQ_DIVISOR_VIBRATOR DIVISOR_FROM_US(100)
|
||||
+
|
||||
/* define FIQ ISR */
|
||||
|
||||
FIQ_HANDLER_START()
|
||||
/* define your locals here -- no initializers though */
|
||||
+ u16 divisor;
|
||||
FIQ_HANDLER_ENTRY(256, 512)
|
||||
/* Your ISR here :-) */
|
||||
+ divisor = 0xffff;
|
||||
+
|
||||
+ /* Vibrator servicing */
|
||||
+
|
||||
+ if (fiq_ipc.vib_pwm_latched || fiq_ipc.vib_pwm) { /* not idle */
|
||||
+ if (((u8)_fiq_count_fiqs) == fiq_ipc.vib_pwm_latched)
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.vib_gpio_pin, 0);
|
||||
+ if (((u8)_fiq_count_fiqs) == 0) {
|
||||
+ fiq_ipc.vib_pwm_latched = fiq_ipc.vib_pwm;
|
||||
+ if (fiq_ipc.vib_pwm_latched)
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.vib_gpio_pin, 1);
|
||||
+ }
|
||||
+ divisor = FIQ_DIVISOR_VIBRATOR;
|
||||
+ }
|
||||
+
|
||||
+ /* TODO: HDQ servicing */
|
||||
+
|
||||
+
|
||||
+
|
||||
+ /* disable further timer interrupts if nobody has any work
|
||||
+ * or adjust rate according to who still has work
|
||||
+ *
|
||||
+ * CAUTION: it means forground code must disable FIQ around
|
||||
+ * its own non-atomic S3C2410_INTMSK changes... not common
|
||||
+ * thankfully and taken care of by the fiq-basis patch
|
||||
+ */
|
||||
+ if (divisor == 0xffff) /* mask the fiq irq source */
|
||||
+ __raw_writel(__raw_readl(S3C2410_INTMSK) | _fiq_ack_mask,
|
||||
+ S3C2410_INTMSK);
|
||||
+ else /* still working, maybe at a different rate */
|
||||
+ __raw_writel(divisor, S3C2410_TCNTB(_fiq_timer_index));
|
||||
+ _fiq_timer_divisor = divisor;
|
||||
+
|
||||
FIQ_HANDLER_END()
|
||||
|
||||
|
||||
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
|
||||
index b6b1211..5a0aa9c 100644
|
||||
--- a/drivers/leds/Kconfig
|
||||
+++ b/drivers/leds/Kconfig
|
||||
@@ -150,6 +150,7 @@ config LEDS_CLEVO_MAIL
|
||||
config LEDS_NEO1973_VIBRATOR
|
||||
tristate "Vibrator Support for the FIC Neo1973 GSM phone"
|
||||
depends on LEDS_CLASS && MACH_NEO1973
|
||||
+ select S3C2440_C_FIQ
|
||||
help
|
||||
This option enables support for the vibrator on the FIC Neo1973.
|
||||
|
||||
diff --git a/drivers/leds/leds-neo1973-vibrator.c b/drivers/leds/leds-neo1973-vibrator.c
|
||||
index c943a6a..36ed216 100644
|
||||
--- a/drivers/leds/leds-neo1973-vibrator.c
|
||||
+++ b/drivers/leds/leds-neo1973-vibrator.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <asm/arch/gta01.h>
|
||||
#include <asm/plat-s3c/regs-timer.h>
|
||||
|
||||
+#include <asm/arch-s3c2410/fiq_ipc_gta02.h>
|
||||
+
|
||||
#define COUNTER 64
|
||||
|
||||
struct neo1973_vib_priv {
|
||||
@@ -39,6 +41,11 @@ static void neo1973_vib_vib_set(struct led_classdev *led_cdev,
|
||||
struct neo1973_vib_priv *vp =
|
||||
container_of(led_cdev, struct neo1973_vib_priv, cdev);
|
||||
|
||||
+ if (machine_is_neo1973_gta02()) { /* use FIQ to control GPIO */
|
||||
+ fiq_ipc.vib_pwm = value; /* set it for FIQ */
|
||||
+ fiq_kick(); /* start up FIQs if not already going */
|
||||
+ return;
|
||||
+ }
|
||||
/*
|
||||
* value == 255 -> 99% duty cycle (full power)
|
||||
* value == 128 -> 50% duty cycle (medium power)
|
||||
@@ -46,7 +53,7 @@ static void neo1973_vib_vib_set(struct led_classdev *led_cdev,
|
||||
*/
|
||||
mutex_lock(&vp->mutex);
|
||||
if (vp->has_pwm)
|
||||
- s3c2410_pwm_duty_cycle(value/4, &vp->pwm);
|
||||
+ s3c2410_pwm_duty_cycle(value / 4, &vp->pwm);
|
||||
else {
|
||||
if (value)
|
||||
s3c2410_gpio_setpin(vp->gpio, 1);
|
||||
@@ -123,6 +130,15 @@ static int __init neo1973_vib_probe(struct platform_device *pdev)
|
||||
neo1973_vib_led.gpio = r->start;
|
||||
platform_set_drvdata(pdev, &neo1973_vib_led);
|
||||
|
||||
+ if (machine_is_neo1973_gta02()) { /* use FIQ to control GPIO */
|
||||
+ s3c2410_gpio_setpin(neo1973_vib_led.gpio, 0); /* off */
|
||||
+ s3c2410_gpio_cfgpin(neo1973_vib_led.gpio, S3C2410_GPIO_OUTPUT);
|
||||
+ /* safe, kmalloc'd copy needed for FIQ ISR */
|
||||
+ fiq_ipc.vib_gpio_pin = neo1973_vib_led.gpio;
|
||||
+ fiq_ipc.vib_pwm = 0; /* off */
|
||||
+ goto configured;
|
||||
+ }
|
||||
+
|
||||
/* TOUT3 */
|
||||
if (neo1973_vib_led.gpio == S3C2410_GPB3) {
|
||||
rc = neo1973_vib_init_hw(&neo1973_vib_led);
|
||||
@@ -133,7 +149,7 @@ static int __init neo1973_vib_probe(struct platform_device *pdev)
|
||||
s3c2410_gpio_cfgpin(neo1973_vib_led.gpio, S3C2410_GPB3_TOUT3);
|
||||
neo1973_vib_led.has_pwm = 1;
|
||||
}
|
||||
-
|
||||
+configured:
|
||||
mutex_init(&neo1973_vib_led.mutex);
|
||||
|
||||
return led_classdev_register(&pdev->dev, &neo1973_vib_led.cdev);
|
||||
@@ -141,6 +157,10 @@ static int __init neo1973_vib_probe(struct platform_device *pdev)
|
||||
|
||||
static int neo1973_vib_remove(struct platform_device *pdev)
|
||||
{
|
||||
+ if (machine_is_neo1973_gta02()) /* use FIQ to control GPIO */
|
||||
+ fiq_ipc.vib_pwm = 0; /* off */
|
||||
+ /* would only need kick if already off so no kick needed */
|
||||
+
|
||||
if (neo1973_vib_led.has_pwm)
|
||||
s3c2410_pwm_disable(&neo1973_vib_led.pwm);
|
||||
|
||||
diff --git a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
index 6cbd8e4..507d235 100644
|
||||
--- a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
+++ b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
@@ -16,8 +16,15 @@
|
||||
* for testing
|
||||
*/
|
||||
|
||||
+#include <asm/arch/pwm.h>
|
||||
+#include <asm/plat-s3c/regs-timer.h>
|
||||
+
|
||||
+
|
||||
struct fiq_ipc {
|
||||
- u8 u8a[0]; /* placeholder */
|
||||
+ /* vibrator */
|
||||
+ unsigned long vib_gpio_pin; /* which pin to meddle with */
|
||||
+ u8 vib_pwm; /* 0 = OFF -- will ensure GPIO deasserted and stop FIQ */
|
||||
+ u8 vib_pwm_latched;
|
||||
};
|
||||
|
||||
/* actual definition lives in arch/arm/mach-s3c2440/fiq_c_isr.c */
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,606 @@
|
|||
From d183fa083737f2b042ecf92166951c30fd83fe61 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:23 +0100
|
||||
Subject: [PATCH] fiq-hdq.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 204 +++++++++++++++++++++-
|
||||
drivers/power/Kconfig | 8 +
|
||||
drivers/power/Makefile | 2 +
|
||||
drivers/power/gta02_hdq.c | 250 ++++++++++++++++++++++++++
|
||||
include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h | 23 +++
|
||||
include/asm-arm/arch-s3c2410/gta02.h | 1 +
|
||||
include/linux/gta02_hdq.h | 8 +
|
||||
7 files changed, 495 insertions(+), 1 deletions(-)
|
||||
create mode 100644 drivers/power/gta02_hdq.c
|
||||
create mode 100644 include/linux/gta02_hdq.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index 8c7bbe7..cea76e7 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -99,6 +99,19 @@ EXPORT_SYMBOL(fiq_ipc);
|
||||
|
||||
#define FIQ_DIVISOR_VIBRATOR DIVISOR_FROM_US(100)
|
||||
|
||||
+#ifdef CONFIG_GTA02_HDQ
|
||||
+/* HDQ specific */
|
||||
+#define HDQ_SAMPLE_PERIOD_US 20
|
||||
+/* private HDQ FSM state -- all other info interesting for caller in fiq_ipc */
|
||||
+static enum hdq_bitbang_states hdq_state;
|
||||
+static u8 hdq_ctr;
|
||||
+static u8 hdq_ctr2;
|
||||
+static u8 hdq_bit;
|
||||
+static u8 hdq_shifter;
|
||||
+static u8 hdq_tx_data_done;
|
||||
+
|
||||
+#define FIQ_DIVISOR_HDQ DIVISOR_FROM_US(HDQ_SAMPLE_PERIOD_US)
|
||||
+#endif
|
||||
/* define FIQ ISR */
|
||||
|
||||
FIQ_HANDLER_START()
|
||||
@@ -121,9 +134,171 @@ FIQ_HANDLER_ENTRY(256, 512)
|
||||
divisor = FIQ_DIVISOR_VIBRATOR;
|
||||
}
|
||||
|
||||
- /* TODO: HDQ servicing */
|
||||
+#ifdef CONFIG_GTA02_HDQ
|
||||
+ /* HDQ servicing */
|
||||
+
|
||||
+ switch (hdq_state) {
|
||||
+ case HDQB_IDLE:
|
||||
+ if (fiq_ipc.hdq_request_ctr == fiq_ipc.hdq_transaction_ctr)
|
||||
+ break;
|
||||
+ hdq_ctr = 210 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 0);
|
||||
+ s3c2410_gpio_cfgpin(fiq_ipc.hdq_gpio_pin, S3C2410_GPIO_OUTPUT);
|
||||
+ hdq_tx_data_done = 0;
|
||||
+ hdq_state = HDQB_TX_BREAK;
|
||||
+ break;
|
||||
+
|
||||
+ case HDQB_TX_BREAK: /* issue low for > 190us */
|
||||
+ if (--hdq_ctr == 0) {
|
||||
+ hdq_ctr = 60 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ hdq_state = HDQB_TX_BREAK_RECOVERY;
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 1);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case HDQB_TX_BREAK_RECOVERY: /* issue low for > 40us */
|
||||
+ if (--hdq_ctr)
|
||||
+ break;
|
||||
+ hdq_shifter = fiq_ipc.hdq_ads;
|
||||
+ hdq_bit = 8; /* 8 bits of ads / rw */
|
||||
+ hdq_tx_data_done = 0; /* doing ads */
|
||||
+ /* fallthru on last one */
|
||||
+ case HDQB_ADS_CALC:
|
||||
+ if (hdq_shifter & 1)
|
||||
+ hdq_ctr = 50 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ else
|
||||
+ hdq_ctr = 120 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ /* carefully precompute the other phase length */
|
||||
+ hdq_ctr2 = (210 - (hdq_ctr * HDQ_SAMPLE_PERIOD_US)) /
|
||||
+ HDQ_SAMPLE_PERIOD_US;
|
||||
+ hdq_state = HDQB_ADS_LOW;
|
||||
+ hdq_shifter >>= 1;
|
||||
+ hdq_bit--;
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 0);
|
||||
+ break;
|
||||
+
|
||||
+ case HDQB_ADS_LOW:
|
||||
+ if (--hdq_ctr)
|
||||
+ break;
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 1);
|
||||
+ hdq_state = HDQB_ADS_HIGH;
|
||||
+ break;
|
||||
+
|
||||
+ case HDQB_ADS_HIGH:
|
||||
+ if (--hdq_ctr2 > 1) /* account for HDQB_ADS_CALC */
|
||||
+ break;
|
||||
+ if (hdq_bit) { /* more bits to do */
|
||||
+ hdq_state = HDQB_ADS_CALC;
|
||||
+ break;
|
||||
+ }
|
||||
+ /* no more bits, wait it out until hdq_ctr2 exhausted */
|
||||
+ if (hdq_ctr2)
|
||||
+ break;
|
||||
+ /* ok no more bits and very last state */
|
||||
+ hdq_ctr = 60 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ /* FIXME 0 = read */
|
||||
+ if (fiq_ipc.hdq_ads & 0x80) { /* write the byte out */
|
||||
+ /* set delay before payload */
|
||||
+ hdq_ctr = 300 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ /* already high, no need to write */
|
||||
+ hdq_state = HDQB_WAIT_TX;
|
||||
+ break;
|
||||
+ }
|
||||
+ /* read the next byte */
|
||||
+ hdq_bit = 8; /* 8 bits of data */
|
||||
+ hdq_ctr = 3000 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ hdq_state = HDQB_WAIT_RX;
|
||||
+ s3c2410_gpio_cfgpin(fiq_ipc.hdq_gpio_pin, S3C2410_GPIO_INPUT);
|
||||
+ break;
|
||||
+
|
||||
+ case HDQB_WAIT_TX: /* issue low for > 40us */
|
||||
+ if (--hdq_ctr)
|
||||
+ break;
|
||||
+ if (!hdq_tx_data_done) { /* was that the data sent? */
|
||||
+ hdq_tx_data_done++;
|
||||
+ hdq_shifter = fiq_ipc.hdq_tx_data;
|
||||
+ hdq_bit = 8; /* 8 bits of data */
|
||||
+ hdq_state = HDQB_ADS_CALC; /* start sending */
|
||||
+ break;
|
||||
+ }
|
||||
+ fiq_ipc.hdq_error = 0;
|
||||
+ fiq_ipc.hdq_transaction_ctr++;
|
||||
+ hdq_state = HDQB_IDLE; /* all tx is done */
|
||||
+ /* idle in input mode, it's pulled up by 10K */
|
||||
+ s3c2410_gpio_cfgpin(fiq_ipc.hdq_gpio_pin, S3C2410_GPIO_INPUT);
|
||||
+ break;
|
||||
+
|
||||
+ case HDQB_WAIT_RX: /* wait for battery to talk to us */
|
||||
+ if (s3c2410_gpio_getpin(fiq_ipc.hdq_gpio_pin) == 0) {
|
||||
+ /* it talks to us! */
|
||||
+ hdq_ctr2 = 1;
|
||||
+ hdq_bit = 8; /* 8 bits of data */
|
||||
+ /* timeout */
|
||||
+ hdq_ctr = 300 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ hdq_state = HDQB_DATA_RX_LOW;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (--hdq_ctr == 0) { /* timed out, error */
|
||||
+ fiq_ipc.hdq_error = 1;
|
||||
+ fiq_ipc.hdq_transaction_ctr++;
|
||||
+ hdq_state = HDQB_IDLE; /* abort */
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ /*
|
||||
+ * HDQ basically works by measuring the low time of the bit cell
|
||||
+ * 32-50us --> '1', 80 - 145us --> '0'
|
||||
+ */
|
||||
+
|
||||
+ case HDQB_DATA_RX_LOW:
|
||||
+ if (s3c2410_gpio_getpin(fiq_ipc.hdq_gpio_pin)) {
|
||||
+ fiq_ipc.hdq_rx_data >>= 1;
|
||||
+ if (hdq_ctr2 <= (65 / HDQ_SAMPLE_PERIOD_US))
|
||||
+ fiq_ipc.hdq_rx_data |= 0x80;
|
||||
+
|
||||
+ if (--hdq_bit == 0) {
|
||||
+ fiq_ipc.hdq_error = 0;
|
||||
+ fiq_ipc.hdq_transaction_ctr++; /* done */
|
||||
+ hdq_state = HDQB_IDLE;
|
||||
+ } else
|
||||
+ hdq_state = HDQB_DATA_RX_HIGH;
|
||||
+ /* timeout */
|
||||
+ hdq_ctr = 1000 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ hdq_ctr2 = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ hdq_ctr2++;
|
||||
+ if (--hdq_ctr)
|
||||
+ break;
|
||||
+ /* timed out, error */
|
||||
+ fiq_ipc.hdq_error = 2;
|
||||
+ fiq_ipc.hdq_transaction_ctr++;
|
||||
+ hdq_state = HDQB_IDLE; /* abort */
|
||||
+ break;
|
||||
|
||||
+ case HDQB_DATA_RX_HIGH:
|
||||
+ if (!s3c2410_gpio_getpin(fiq_ipc.hdq_gpio_pin)) {
|
||||
+ /* it talks to us! */
|
||||
+ hdq_ctr2 = 1;
|
||||
+ /* timeout */
|
||||
+ hdq_ctr = 400 / HDQ_SAMPLE_PERIOD_US;
|
||||
+ hdq_state = HDQB_DATA_RX_LOW;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (--hdq_ctr)
|
||||
+ break;
|
||||
+ /* timed out, error */
|
||||
+ fiq_ipc.hdq_error = 3;
|
||||
+ fiq_ipc.hdq_transaction_ctr++;
|
||||
+ /* we're in input mode already */
|
||||
+ hdq_state = HDQB_IDLE; /* abort */
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
+ if (hdq_state != HDQB_IDLE) /* ie, not idle */
|
||||
+ if (divisor > FIQ_DIVISOR_HDQ)
|
||||
+ divisor = FIQ_DIVISOR_HDQ; /* keep us going */
|
||||
+#endif
|
||||
|
||||
/* disable further timer interrupts if nobody has any work
|
||||
* or adjust rate according to who still has work
|
||||
@@ -391,6 +566,23 @@ struct platform_device sc32440_fiq_device = {
|
||||
.resource = sc32440_fiq_resources,
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_GTA02_HDQ
|
||||
+/* HDQ */
|
||||
+
|
||||
+static struct resource gta02_hdq_resources[] = {
|
||||
+ [0] = {
|
||||
+ .start = GTA02v5_GPIO_HDQ,
|
||||
+ .end = GTA02v5_GPIO_HDQ,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct platform_device gta02_hdq_device = {
|
||||
+ .name = "gta02-hdq",
|
||||
+ .num_resources = 1,
|
||||
+ .resource = gta02_hdq_resources,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
/* NOR Flash */
|
||||
|
||||
#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
|
||||
@@ -1074,6 +1266,16 @@ static void __init gta02_machine_init(void)
|
||||
|
||||
platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
|
||||
|
||||
+#ifdef CONFIG_GTA02_HDQ
|
||||
+ switch (system_rev) {
|
||||
+ case GTA02v5_SYSTEM_REV:
|
||||
+ case GTA02v6_SYSTEM_REV:
|
||||
+ platform_device_register(>a02_hdq_device);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+#endif
|
||||
s3c2410_pm_init();
|
||||
|
||||
/* Set LCD_RESET / XRES to high */
|
||||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
||||
index 58c806e..0a4515d 100644
|
||||
--- a/drivers/power/Kconfig
|
||||
+++ b/drivers/power/Kconfig
|
||||
@@ -50,3 +50,11 @@ config BATTERY_OLPC
|
||||
Say Y to enable support for the battery on the OLPC laptop.
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
+
|
||||
+config GTA02_HDQ
|
||||
+ tristate "Neo Freerunner HDQ"
|
||||
+ depends on MACH_NEO1973_GTA02 && FIQ && S3C2440_C_FIQ
|
||||
+ help
|
||||
+ Say Y to enable support for communicating with an HDQ battery
|
||||
+ on the Neo Freerunner. You probably want to select
|
||||
+ at least BATTERY_BQ27000_HDQ as well
|
||||
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
|
||||
index 6413ded..88f227f 100644
|
||||
--- a/drivers/power/Makefile
|
||||
+++ b/drivers/power/Makefile
|
||||
@@ -20,3 +20,5 @@ obj-$(CONFIG_APM_POWER) += apm_power.o
|
||||
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
|
||||
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
|
||||
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
|
||||
+
|
||||
+obj-$(CONFIG_GTA02_HDQ) += gta02_hdq.o
|
||||
diff --git a/drivers/power/gta02_hdq.c b/drivers/power/gta02_hdq.c
|
||||
new file mode 100644
|
||||
index 0000000..12c742e
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/gta02_hdq.c
|
||||
@@ -0,0 +1,250 @@
|
||||
+/*
|
||||
+ * HDQ driver for the FIC Neo1973 GTA02 GSM phone
|
||||
+ *
|
||||
+ * (C) 2006-2007 by OpenMoko, Inc.
|
||||
+ * Author: Andy Green <andy@openmoko.com>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+#include <asm/arch/gta02.h>
|
||||
+#include <asm/arch/fiq_ipc_gta02.h>
|
||||
+
|
||||
+
|
||||
+
|
||||
+#define HDQ_READ 0
|
||||
+#define HDQ_WRITE 0x80
|
||||
+
|
||||
+
|
||||
+int gta02hdq_initialized(void)
|
||||
+{
|
||||
+ return fiq_ipc.hdq_probed;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(gta02hdq_initialized);
|
||||
+
|
||||
+int gta02hdq_read(int address)
|
||||
+{
|
||||
+ int count_sleeps = 5;
|
||||
+ int ret = -ETIME;
|
||||
+
|
||||
+ mutex_lock(&fiq_ipc.hdq_lock);
|
||||
+
|
||||
+ fiq_ipc.hdq_ads = address | HDQ_READ;
|
||||
+ fiq_ipc.hdq_request_ctr++;
|
||||
+ fiq_kick();
|
||||
+ /*
|
||||
+ * FIQ takes care of it while we block our calling process
|
||||
+ * But we're not spinning -- other processes run normally while
|
||||
+ * we wait for the result
|
||||
+ */
|
||||
+ while (count_sleeps--) {
|
||||
+ msleep(10); /* valid transaction always completes in < 10ms */
|
||||
+
|
||||
+ if (fiq_ipc.hdq_request_ctr != fiq_ipc.hdq_transaction_ctr)
|
||||
+ continue;
|
||||
+
|
||||
+ if (fiq_ipc.hdq_error)
|
||||
+ goto done; /* didn't see a response in good time */
|
||||
+
|
||||
+ ret = fiq_ipc.hdq_rx_data;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ ret = -EINVAL;
|
||||
+
|
||||
+done:
|
||||
+ mutex_unlock(&fiq_ipc.hdq_lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(gta02hdq_read);
|
||||
+
|
||||
+int gta02hdq_write(int address, u8 data)
|
||||
+{
|
||||
+ int count_sleeps = 5;
|
||||
+ int ret = -ETIME;
|
||||
+
|
||||
+ mutex_lock(&fiq_ipc.hdq_lock);
|
||||
+
|
||||
+ fiq_ipc.hdq_ads = address | HDQ_WRITE;
|
||||
+ fiq_ipc.hdq_tx_data = data;
|
||||
+ fiq_ipc.hdq_request_ctr++;
|
||||
+ fiq_kick();
|
||||
+ /*
|
||||
+ * FIQ takes care of it while we block our calling process
|
||||
+ * But we're not spinning -- other processes run normally while
|
||||
+ * we wait for the result
|
||||
+ */
|
||||
+ while (count_sleeps--) {
|
||||
+ msleep(10); /* valid transaction always completes in < 10ms */
|
||||
+
|
||||
+ if (fiq_ipc.hdq_request_ctr != fiq_ipc.hdq_transaction_ctr)
|
||||
+ continue; /* something bad with FIQ */
|
||||
+
|
||||
+ if (fiq_ipc.hdq_error)
|
||||
+ goto done; /* didn't see a response in good time */
|
||||
+ }
|
||||
+ ret = -EINVAL;
|
||||
+
|
||||
+done:
|
||||
+ mutex_unlock(&fiq_ipc.hdq_lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(gta02hdq_write);
|
||||
+
|
||||
+/* sysfs */
|
||||
+
|
||||
+static ssize_t hdq_sysfs_dump(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ int n;
|
||||
+ int v;
|
||||
+ u8 u8a[128]; /* whole address space for HDQ */
|
||||
+ char *end = buf;
|
||||
+
|
||||
+ /* the dump does not take care about 16 bit regs, because at this
|
||||
+ * bus level we don't know about the chip details
|
||||
+ */
|
||||
+ for (n = 0; n < sizeof(u8a); n++) {
|
||||
+ v = gta02hdq_read(n);
|
||||
+ if (v < 0)
|
||||
+ goto bail;
|
||||
+ u8a[n] = v;
|
||||
+ }
|
||||
+
|
||||
+ for (n = 0; n < sizeof(u8a); n += 16) {
|
||||
+ hex_dump_to_buffer(u8a + n, sizeof(u8a), 16, 1, end, 4096, 0);
|
||||
+ end += strlen(end);
|
||||
+ *end++ = '\n';
|
||||
+ *end = '\0';
|
||||
+ }
|
||||
+ return (end - buf);
|
||||
+
|
||||
+bail:
|
||||
+ return sprintf(buf, "ERROR %d\n", v);
|
||||
+}
|
||||
+
|
||||
+/* you write by <address> <data>, eg, "34 128" */
|
||||
+
|
||||
+#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
|
||||
+
|
||||
+static ssize_t hdq_sysfs_write(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ const char *end = buf + count;
|
||||
+ int address = atoi(buf);
|
||||
+
|
||||
+ while ((buf != end) && (*buf != ' '))
|
||||
+ buf++;
|
||||
+ if (buf >= end)
|
||||
+ return 0;
|
||||
+ while ((buf < end) && (*buf == ' '))
|
||||
+ buf++;
|
||||
+ if (buf >= end)
|
||||
+ return 0;
|
||||
+
|
||||
+ gta02hdq_write(address, atoi(buf));
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(dump, 0400, hdq_sysfs_dump, NULL);
|
||||
+static DEVICE_ATTR(write, 0600, NULL, hdq_sysfs_write);
|
||||
+
|
||||
+static struct attribute *gta02hdq_sysfs_entries[] = {
|
||||
+ &dev_attr_dump.attr,
|
||||
+ &dev_attr_write.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group gta02hdq_attr_group = {
|
||||
+ .name = "hdq",
|
||||
+ .attrs = gta02hdq_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int gta02hdq_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ /* after 18s of this, the battery monitor will also go to sleep */
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 0);
|
||||
+ s3c2410_gpio_cfgpin(fiq_ipc.hdq_gpio_pin, S3C2410_GPIO_OUTPUT);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int gta02hdq_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 1);
|
||||
+ s3c2410_gpio_cfgpin(fiq_ipc.hdq_gpio_pin, S3C2410_GPIO_OUTPUT);
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static int __init gta02hdq_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *r = platform_get_resource(pdev, 0, 0);
|
||||
+
|
||||
+ if (!machine_is_neo1973_gta02())
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (!r)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+
|
||||
+ mutex_init(&fiq_ipc.hdq_lock);
|
||||
+
|
||||
+ /* set our HDQ comms pin from the platform data */
|
||||
+ fiq_ipc.hdq_gpio_pin = r->start;
|
||||
+
|
||||
+ s3c2410_gpio_setpin(fiq_ipc.hdq_gpio_pin, 1);
|
||||
+ s3c2410_gpio_cfgpin(fiq_ipc.hdq_gpio_pin, S3C2410_GPIO_OUTPUT);
|
||||
+
|
||||
+ fiq_ipc.hdq_probed = 1; /* we are ready to do stuff now */
|
||||
+
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, >a02hdq_attr_group);
|
||||
+}
|
||||
+
|
||||
+static int gta02hdq_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, >a02hdq_attr_group);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gta02hdq_driver = {
|
||||
+ .probe = gta02hdq_probe,
|
||||
+ .remove = gta02hdq_remove,
|
||||
+#ifdef CONFIG_PM
|
||||
+ .suspend = gta02hdq_suspend,
|
||||
+ .resume = gta02hdq_resume,
|
||||
+#endif
|
||||
+ .driver = {
|
||||
+ .name = "gta02-hdq",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init gta02hdq_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(>a02hdq_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit gta02hdq_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(>a02hdq_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(gta02hdq_init);
|
||||
+module_exit(gta02hdq_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
|
||||
+MODULE_DESCRIPTION("GTA02 HDQ driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff --git a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
index 507d235..c5eb3df 100644
|
||||
--- a/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
+++ b/include/asm-arm/arch-s3c2410/fiq_ipc_gta02.h
|
||||
@@ -19,12 +19,35 @@
|
||||
#include <asm/arch/pwm.h>
|
||||
#include <asm/plat-s3c/regs-timer.h>
|
||||
|
||||
+enum hdq_bitbang_states {
|
||||
+ HDQB_IDLE = 0,
|
||||
+ HDQB_TX_BREAK,
|
||||
+ HDQB_TX_BREAK_RECOVERY,
|
||||
+ HDQB_ADS_CALC,
|
||||
+ HDQB_ADS_LOW,
|
||||
+ HDQB_ADS_HIGH,
|
||||
+ HDQB_WAIT_RX,
|
||||
+ HDQB_DATA_RX_LOW,
|
||||
+ HDQB_DATA_RX_HIGH,
|
||||
+ HDQB_WAIT_TX,
|
||||
+};
|
||||
|
||||
struct fiq_ipc {
|
||||
/* vibrator */
|
||||
unsigned long vib_gpio_pin; /* which pin to meddle with */
|
||||
u8 vib_pwm; /* 0 = OFF -- will ensure GPIO deasserted and stop FIQ */
|
||||
u8 vib_pwm_latched;
|
||||
+
|
||||
+ /* hdq */
|
||||
+ u8 hdq_probed; /* nonzero after HDQ driver probed */
|
||||
+ struct mutex hdq_lock; /* if you want to use hdq, you have to take lock */
|
||||
+ unsigned long hdq_gpio_pin; /* GTA02 = GPD14 which pin to meddle with */
|
||||
+ u8 hdq_ads; /* b7..b6 = register address, b0 = r/w */
|
||||
+ u8 hdq_tx_data; /* data to tx for write action */
|
||||
+ u8 hdq_rx_data; /* data received in read action */
|
||||
+ u8 hdq_request_ctr; /* incremented by "user" to request a transfer */
|
||||
+ u8 hdq_transaction_ctr; /* incremented after each transfer */
|
||||
+ u8 hdq_error; /* 0 = no error */
|
||||
};
|
||||
|
||||
/* actual definition lives in arch/arm/mach-s3c2440/fiq_c_isr.c */
|
||||
diff --git a/include/asm-arm/arch-s3c2410/gta02.h b/include/asm-arm/arch-s3c2410/gta02.h
|
||||
index fa49d93..f686a7a 100644
|
||||
--- a/include/asm-arm/arch-s3c2410/gta02.h
|
||||
+++ b/include/asm-arm/arch-s3c2410/gta02.h
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#define GTA02v3_GPIO_nG1_CS S3C2410_GPD12 /* v3 + v4 only */
|
||||
#define GTA02v3_GPIO_nG2_CS S3C2410_GPD13 /* v3 + v4 only */
|
||||
+#define GTA02v5_GPIO_HDQ S3C2410_GPD14 /* v5 + */
|
||||
|
||||
#define GTA02_GPIO_nG1_INT S3C2410_GPF0
|
||||
#define GTA02_GPIO_IO1 S3C2410_GPF1
|
||||
diff --git a/include/linux/gta02_hdq.h b/include/linux/gta02_hdq.h
|
||||
new file mode 100644
|
||||
index 0000000..2f43a62
|
||||
--- /dev/null
|
||||
+++ b/include/linux/gta02_hdq.h
|
||||
@@ -0,0 +1,8 @@
|
||||
+#ifndef __GTA02HDQ_H__
|
||||
+#define __GTA02HDQ_H__
|
||||
+
|
||||
+int gta02hdq_read(int address);
|
||||
+int gta02hdq_write(int address, u8 data);
|
||||
+int gta02hdq_initialized(void);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
From 2bab304b10f077cb88d5b5f5bd7e50c16aac2132 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:23 +0100
|
||||
Subject: [PATCH] bq27000-battery-driver.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2440/Kconfig | 2 +
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 21 ++
|
||||
drivers/power/Kconfig | 7 +-
|
||||
drivers/power/Makefile | 1 +
|
||||
drivers/power/bq27000_battery.c | 375 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/bq27000_battery.h | 12 ++
|
||||
6 files changed, 417 insertions(+), 1 deletions(-)
|
||||
create mode 100644 drivers/power/bq27000_battery.c
|
||||
create mode 100644 include/linux/bq27000_battery.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
|
||||
index 3015aaf..b417f8e 100644
|
||||
--- a/arch/arm/mach-s3c2440/Kconfig
|
||||
+++ b/arch/arm/mach-s3c2440/Kconfig
|
||||
@@ -79,6 +79,8 @@ config MACH_NEO1973_GTA02
|
||||
bool "FIC Neo1973 GSM Phone (GTA02 Hardware)"
|
||||
select CPU_S3C2442
|
||||
select SENSORS_PCF50633
|
||||
+ select POWER_SUPPLY
|
||||
+ select GTA02_HDQ
|
||||
help
|
||||
Say Y here if you are using the FIC Neo1973 GSM Phone
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index cea76e7..3816ea5 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -81,6 +81,8 @@
|
||||
|
||||
#include <asm/arch/fiq_ipc_gta02.h>
|
||||
#include "fiq_c_isr.h"
|
||||
+#include <linux/gta02_hdq.h>
|
||||
+#include <linux/bq27000_battery.h>
|
||||
|
||||
/* arbitrates which sensor IRQ owns the shared SPI bus */
|
||||
static spinlock_t motion_irq_lock;
|
||||
@@ -583,6 +585,24 @@ struct platform_device gta02_hdq_device = {
|
||||
};
|
||||
#endif
|
||||
|
||||
+/* BQ27000 Battery */
|
||||
+
|
||||
+struct bq27000_platform_data bq27000_pdata = {
|
||||
+ .name = "bat",
|
||||
+ .rsense_mohms = 20,
|
||||
+ .hdq_read = gta02hdq_read,
|
||||
+ .hdq_write = gta02hdq_write,
|
||||
+ .hdq_initialized = gta02hdq_initialized,
|
||||
+};
|
||||
+
|
||||
+struct platform_device bq27000_battery_device = {
|
||||
+ .name = "bq27000-battery",
|
||||
+ .dev = {
|
||||
+ .platform_data = &bq27000_pdata,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+
|
||||
/* NOR Flash */
|
||||
|
||||
#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
|
||||
@@ -1271,6 +1291,7 @@ static void __init gta02_machine_init(void)
|
||||
case GTA02v5_SYSTEM_REV:
|
||||
case GTA02v6_SYSTEM_REV:
|
||||
platform_device_register(>a02_hdq_device);
|
||||
+ platform_device_register(&bq27000_battery_device);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
||||
index 0a4515d..feb8b0a 100644
|
||||
--- a/drivers/power/Kconfig
|
||||
+++ b/drivers/power/Kconfig
|
||||
@@ -49,7 +49,10 @@ config BATTERY_OLPC
|
||||
help
|
||||
Say Y to enable support for the battery on the OLPC laptop.
|
||||
|
||||
-endif # POWER_SUPPLY
|
||||
+config BATTERY_BQ27000_HDQ
|
||||
+ tristate "BQ27000 HDQ battery monitor driver"
|
||||
+ help
|
||||
+ Say Y to enable support for the battery on the Neo Freerunner
|
||||
|
||||
config GTA02_HDQ
|
||||
tristate "Neo Freerunner HDQ"
|
||||
@@ -58,3 +61,5 @@ config GTA02_HDQ
|
||||
Say Y to enable support for communicating with an HDQ battery
|
||||
on the Neo Freerunner. You probably want to select
|
||||
at least BATTERY_BQ27000_HDQ as well
|
||||
+
|
||||
+endif # POWER_SUPPLY
|
||||
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
|
||||
index 88f227f..d7e87ad 100644
|
||||
--- a/drivers/power/Makefile
|
||||
+++ b/drivers/power/Makefile
|
||||
@@ -20,5 +20,6 @@ obj-$(CONFIG_APM_POWER) += apm_power.o
|
||||
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
|
||||
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
|
||||
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
|
||||
+obj-$(CONFIG_BATTERY_BQ27000_HDQ) += bq27000_battery.o
|
||||
|
||||
obj-$(CONFIG_GTA02_HDQ) += gta02_hdq.o
|
||||
diff --git a/drivers/power/bq27000_battery.c b/drivers/power/bq27000_battery.c
|
||||
new file mode 100644
|
||||
index 0000000..d19186a
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/bq27000_battery.c
|
||||
@@ -0,0 +1,375 @@
|
||||
+/*
|
||||
+ * Driver for batteries with bq27000 chips inside via HDQ
|
||||
+ *
|
||||
+ * Copyright 2008 Openmoko, Inc
|
||||
+ * Andy Green <andy@openmoko.com>
|
||||
+ *
|
||||
+ * based on ds2760 driver, original copyright notice for that --->
|
||||
+ *
|
||||
+ * Copyright © 2007 Anton Vorontsov
|
||||
+ * 2004-2007 Matt Reimer
|
||||
+ * 2004 Szabolcs Gyurko
|
||||
+ *
|
||||
+ * Use consistent with the GNU GPL is permitted,
|
||||
+ * provided that this copyright notice is
|
||||
+ * preserved in its entirety in all copies and derived works.
|
||||
+ *
|
||||
+ * Author: Anton Vorontsov <cbou@mail.ru>
|
||||
+ * February 2007
|
||||
+ *
|
||||
+ * Matt Reimer <mreimer@vpop.net>
|
||||
+ * April 2004, 2005, 2007
|
||||
+ *
|
||||
+ * Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
|
||||
+ * September 2004
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/param.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/pm.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/power_supply.h>
|
||||
+#include <linux/bq27000_battery.h>
|
||||
+
|
||||
+enum bq27000_regs {
|
||||
+ /* RAM regs */
|
||||
+ /* read-write after this */
|
||||
+ BQ27000_CTRL = 0, /* Device Control Register */
|
||||
+ BQ27000_MODE, /* Device Mode Register */
|
||||
+ BQ27000_AR_L, /* At-Rate H L */
|
||||
+ BQ27000_AR_H,
|
||||
+ /* read-only after this */
|
||||
+ BQ27000_ARTTE_L, /* At-Rate Time To Empty H L */
|
||||
+ BQ27000_ARTTE_H,
|
||||
+ BQ27000_TEMP_L, /* Reported Temperature H L */
|
||||
+ BQ27000_TEMP_H,
|
||||
+ BQ27000_VOLT_L, /* Reported Voltage H L */
|
||||
+ BQ27000_VOLT_H,
|
||||
+ BQ27000_FLAGS, /* Status Flags */
|
||||
+ BQ27000_RSOC, /* Relative State of Charge */
|
||||
+ BQ27000_NAC_L, /* Nominal Available Capacity H L */
|
||||
+ BQ27000_NAC_H,
|
||||
+ BQ27000_CACD_L, /* Discharge Compensated H L */
|
||||
+ BQ27000_CACD_H,
|
||||
+ BQ27000_CACT_L, /* Temperature Compensated H L */
|
||||
+ BQ27000_CACT_H,
|
||||
+ BQ27000_LMD_L, /* Last measured discharge H L */
|
||||
+ BQ27000_LMD_H,
|
||||
+ BQ27000_AI_L, /* Average Current H L */
|
||||
+ BQ27000_AI_H,
|
||||
+ BQ27000_TTE_L, /* Time to Empty H L */
|
||||
+ BQ27000_TTE_H,
|
||||
+ BQ27000_TTF_L, /* Time to Full H L */
|
||||
+ BQ27000_TTF_H,
|
||||
+ BQ27000_SI_L, /* Standby Current H L */
|
||||
+ BQ27000_SI_H,
|
||||
+ BQ27000_STTE_L, /* Standby Time To Empty H L */
|
||||
+ BQ27000_STTE_H,
|
||||
+ BQ27000_MLI_L, /* Max Load Current H L */
|
||||
+ BQ27000_MLI_H,
|
||||
+ BQ27000_MLTTE_L, /* Max Load Time To Empty H L */
|
||||
+ BQ27000_MLTTE_H,
|
||||
+ BQ27000_SAE_L, /* Available Energy H L */
|
||||
+ BQ27000_SAE_H,
|
||||
+ BQ27000_AP_L, /* Available Power H L */
|
||||
+ BQ27000_AP_H,
|
||||
+ BQ27000_TTECP_L, /* Time to Empty at Constant Power H L */
|
||||
+ BQ27000_TTECP_H,
|
||||
+ BQ27000_CYCL_L, /* Cycle count since learning cycle H L */
|
||||
+ BQ27000_CYCL_H,
|
||||
+ BQ27000_CYCT_L, /* Cycle Count Total H L */
|
||||
+ BQ27000_CYCT_H,
|
||||
+ BQ27000_CSOC, /* Compensated State Of Charge */
|
||||
+ /* EEPROM regs */
|
||||
+ /* read-write after this */
|
||||
+ BQ27000_EE_EE_EN = 0x6e, /* EEPROM Program Enable */
|
||||
+ BQ27000_EE_ILMD = 0x76, /* Initial Last Measured Discharge High Byte */
|
||||
+ BQ27000_EE_SEDVF, /* Scaled EDVF Threshold */
|
||||
+ BQ27000_EE_SEDV1, /* Scaled EDV1 Threshold */
|
||||
+ BQ27000_EE_ISLC, /* Initial Standby Load Current */
|
||||
+ BQ27000_EE_DMFSD, /* Digital Magnitude Filter and Self Discharge */
|
||||
+ BQ27000_EE_TAPER, /* Aging Estimate Enable, Charge Termination Taper */
|
||||
+ BQ27000_EE_PKCFG, /* Pack Configuration Values */
|
||||
+ BQ27000_EE_IMLC, /* Initial Max Load Current or ID #3 */
|
||||
+ BQ27000_EE_DCOMP, /* Discharge rate compensation constants or ID #2 */
|
||||
+ BQ27000_EE_TCOMP, /* Temperature Compensation constants or ID #1 */
|
||||
+};
|
||||
+
|
||||
+enum bq27000_status_flags {
|
||||
+ BQ27000_STATUS_CHGS = 0x80, /* 1 = being charged */
|
||||
+ BQ27000_STATUS_NOACT = 0x40, /* 1 = no activity */
|
||||
+ BQ27000_STATUS_IMIN = 0x20, /* 1 = Lion taper current mode */
|
||||
+ BQ27000_STATUS_CI = 0x10, /* 1 = capacity likely innacurate */
|
||||
+ BQ27000_STATUS_CALIP = 0x08, /* 1 = calibration in progress */
|
||||
+ BQ27000_STATUS_VDQ = 0x04, /* 1 = capacity should be accurate */
|
||||
+ BQ27000_STATUS_EDV1 = 0x02, /* 1 = end of discharge.. <6% left */
|
||||
+ BQ27000_STATUS_EDVF = 0x01, /* 1 = no, it's really empty now */
|
||||
+};
|
||||
+
|
||||
+#define NANOVOLTS_UNIT 3750
|
||||
+
|
||||
+struct bq27000_device_info {
|
||||
+ struct device *dev;
|
||||
+ struct power_supply bat;
|
||||
+
|
||||
+ int rsense_mohms; /* from platform */
|
||||
+
|
||||
+ int (*hdq_initialized)(void); /* from platform */
|
||||
+ int (*hdq_read)(int); /* from platform */
|
||||
+ int (*hdq_write)(int, u8); /* from platform */
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * reading 16 bit values over HDQ has a special hazard where the
|
||||
+ * hdq device firmware can update the 16-bit register during the time we
|
||||
+ * read the two halves. TI document SLUS556D recommends the algorithm here
|
||||
+ * to avoid trouble
|
||||
+ */
|
||||
+
|
||||
+static int hdq_read16(struct bq27000_device_info *di, int address)
|
||||
+{
|
||||
+ int acc;
|
||||
+ int high;
|
||||
+ int retries = 3;
|
||||
+
|
||||
+ while (retries--) {
|
||||
+
|
||||
+ high = (di->hdq_read)(address + 1); /* high part */
|
||||
+
|
||||
+ if (high < 0)
|
||||
+ return high;
|
||||
+ acc = (di->hdq_read)(address);
|
||||
+ if (acc < 0)
|
||||
+ return acc;
|
||||
+
|
||||
+ /* confirm high didn't change between reading it and low */
|
||||
+ if (high == (di->hdq_read)(address + 1))
|
||||
+ return (high << 8) | acc;
|
||||
+ }
|
||||
+
|
||||
+ return -ETIME;
|
||||
+}
|
||||
+
|
||||
+#define to_bq27000_device_info(x) container_of((x), \
|
||||
+ struct bq27000_device_info, \
|
||||
+ bat);
|
||||
+
|
||||
+static void bq27000_battery_external_power_changed(struct power_supply *psy)
|
||||
+{
|
||||
+ struct bq27000_device_info *di = to_bq27000_device_info(psy);
|
||||
+
|
||||
+ dev_dbg(di->dev, "%s\n", __FUNCTION__);
|
||||
+}
|
||||
+
|
||||
+static int bq27000_battery_get_property(struct power_supply *psy,
|
||||
+ enum power_supply_property psp,
|
||||
+ union power_supply_propval *val)
|
||||
+{
|
||||
+ int v, n;
|
||||
+ struct bq27000_device_info *di = to_bq27000_device_info(psy);
|
||||
+
|
||||
+ if (!(di->hdq_initialized)())
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ switch (psp) {
|
||||
+ case POWER_SUPPLY_PROP_STATUS:
|
||||
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
+ v = hdq_read16(di, BQ27000_AI_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ if (v < 2) { /* no real activity on the battery */
|
||||
+ if (!hdq_read16(di, BQ27000_TTF_L))
|
||||
+ val->intval = POWER_SUPPLY_STATUS_FULL;
|
||||
+ else
|
||||
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
+ break;
|
||||
+ }
|
||||
+ /* power is actually going in or out... */
|
||||
+ v = (di->hdq_read)(BQ27000_FLAGS);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ if (v & BQ27000_STATUS_CHGS)
|
||||
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
|
||||
+ else
|
||||
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
+ v = hdq_read16(di, BQ27000_VOLT_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ val->intval = v * 1000; /* mV -> uV */
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
+ v = (di->hdq_read)(BQ27000_FLAGS);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ if (v & BQ27000_STATUS_CHGS)
|
||||
+ n = -NANOVOLTS_UNIT;
|
||||
+ else
|
||||
+ n = NANOVOLTS_UNIT;
|
||||
+ v = hdq_read16(di, BQ27000_AI_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ val->intval = (v * n) / di->rsense_mohms;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
|
||||
+ v = hdq_read16(di, BQ27000_LMD_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ val->intval = (v * 3570) / di->rsense_mohms;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_TEMP:
|
||||
+ v = hdq_read16(di, BQ27000_TEMP_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ /* K (in 0.25K units) is 273.15 up from C (in 0.1C)*/
|
||||
+ /* 10926 = 27315 * 4 / 10 */
|
||||
+ val->intval = (((long)v * 10l) - 10926) / 4;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
|
||||
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_CAPACITY:
|
||||
+ val->intval = (di->hdq_read)(BQ27000_RSOC);
|
||||
+ if (val->intval < 0)
|
||||
+ return val->intval;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_PRESENT:
|
||||
+ v = (di->hdq_read)(BQ27000_RSOC);
|
||||
+ val->intval = !(v < 0);
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
|
||||
+ v = hdq_read16(di, BQ27000_TTE_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ val->intval = 60 * v;
|
||||
+ break;
|
||||
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
|
||||
+ v = hdq_read16(di, BQ27000_TTF_L);
|
||||
+ if (v < 0)
|
||||
+ return v;
|
||||
+ val->intval = 60 * v;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static enum power_supply_property bq27000_battery_props[] = {
|
||||
+ POWER_SUPPLY_PROP_STATUS,
|
||||
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
+ POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
+ POWER_SUPPLY_PROP_CHARGE_FULL,
|
||||
+ POWER_SUPPLY_PROP_TEMP,
|
||||
+ POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
+ POWER_SUPPLY_PROP_PRESENT,
|
||||
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
|
||||
+ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
|
||||
+ POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
+ POWER_SUPPLY_PROP_CAPACITY
|
||||
+};
|
||||
+
|
||||
+static int bq27000_battery_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int retval = 0;
|
||||
+ struct bq27000_device_info *di;
|
||||
+ struct bq27000_platform_data *pdata;
|
||||
+
|
||||
+ dev_info(&pdev->dev, "BQ27000 Battery Driver (C) 2008 Openmoko, Inc\n");
|
||||
+
|
||||
+ di = kzalloc(sizeof(*di), GFP_KERNEL);
|
||||
+ if (!di) {
|
||||
+ retval = -ENOMEM;
|
||||
+ goto di_alloc_failed;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, di);
|
||||
+
|
||||
+ pdata = pdev->dev.platform_data;
|
||||
+ di->dev = &pdev->dev;
|
||||
+ /* di->w1_dev = pdev->dev.parent; */
|
||||
+ di->bat.name = pdata->name;
|
||||
+ di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
+ di->bat.properties = bq27000_battery_props;
|
||||
+ di->bat.num_properties = ARRAY_SIZE(bq27000_battery_props);
|
||||
+ di->bat.get_property = bq27000_battery_get_property;
|
||||
+ di->bat.external_power_changed =
|
||||
+ bq27000_battery_external_power_changed;
|
||||
+ di->hdq_read = pdata->hdq_read;
|
||||
+ di->hdq_write = pdata->hdq_write;
|
||||
+ di->rsense_mohms = pdata->rsense_mohms;
|
||||
+ di->hdq_initialized = pdata->hdq_initialized;
|
||||
+
|
||||
+ retval = power_supply_register(&pdev->dev, &di->bat);
|
||||
+ if (retval) {
|
||||
+ dev_err(di->dev, "failed to register battery\n");
|
||||
+ goto batt_failed;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+batt_failed:
|
||||
+ kfree(di);
|
||||
+di_alloc_failed:
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int bq27000_battery_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct bq27000_device_info *di = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ power_supply_unregister(&di->bat);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+
|
||||
+static int bq27000_battery_suspend(struct platform_device *pdev,
|
||||
+ pm_message_t state)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bq27000_battery_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define bq27000_battery_suspend NULL
|
||||
+#define bq27000_battery_resume NULL
|
||||
+
|
||||
+#endif /* CONFIG_PM */
|
||||
+
|
||||
+static struct platform_driver bq27000_battery_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "bq27000-battery",
|
||||
+ },
|
||||
+ .probe = bq27000_battery_probe,
|
||||
+ .remove = bq27000_battery_remove,
|
||||
+ .suspend = bq27000_battery_suspend,
|
||||
+ .resume = bq27000_battery_resume,
|
||||
+};
|
||||
+
|
||||
+static int __init bq27000_battery_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&bq27000_battery_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit bq27000_battery_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&bq27000_battery_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(bq27000_battery_init);
|
||||
+module_exit(bq27000_battery_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
|
||||
+MODULE_DESCRIPTION("bq27000 battery driver");
|
||||
diff --git a/include/linux/bq27000_battery.h b/include/linux/bq27000_battery.h
|
||||
new file mode 100644
|
||||
index 0000000..36b4f20
|
||||
--- /dev/null
|
||||
+++ b/include/linux/bq27000_battery.h
|
||||
@@ -0,0 +1,12 @@
|
||||
+#ifndef __BQ27000_BATTERY_H__
|
||||
+#define __BQ27000_BATTERY_H__
|
||||
+
|
||||
+struct bq27000_platform_data {
|
||||
+ const char *name;
|
||||
+ int rsense_mohms;
|
||||
+ int (*hdq_read)(int);
|
||||
+ int (*hdq_write)(int, u8);
|
||||
+ int (*hdq_initialized)(void);
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
From 6294c84872b0d26111bdd1b9e5fec41c8a087443 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:23 +0100
|
||||
Subject: [PATCH] fix-EVIOCGRAB-semantics.patch
|
||||
|
||||
---
|
||||
drivers/input/evdev.c | 32 +++++++++++++++-----------------
|
||||
1 files changed, 15 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
|
||||
index b32984b..499ffe1 100644
|
||||
--- a/drivers/input/evdev.c
|
||||
+++ b/drivers/input/evdev.c
|
||||
@@ -28,7 +28,7 @@ struct evdev {
|
||||
char name[16];
|
||||
struct input_handle handle;
|
||||
wait_queue_head_t wait;
|
||||
- struct evdev_client *grab;
|
||||
+ int *grab;
|
||||
struct list_head client_list;
|
||||
spinlock_t client_lock; /* protects client_list */
|
||||
struct mutex mutex;
|
||||
@@ -39,6 +39,7 @@ struct evdev_client {
|
||||
struct input_event buffer[EVDEV_BUFFER_SIZE];
|
||||
int head;
|
||||
int tail;
|
||||
+ int grab;
|
||||
spinlock_t buffer_lock; /* protects access to buffer, head and tail */
|
||||
struct fasync_struct *fasync;
|
||||
struct evdev *evdev;
|
||||
@@ -79,12 +80,8 @@ static void evdev_event(struct input_handle *handle,
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
- client = rcu_dereference(evdev->grab);
|
||||
- if (client)
|
||||
+ list_for_each_entry_rcu(client, &evdev->client_list, node)
|
||||
evdev_pass_event(client, &event);
|
||||
- else
|
||||
- list_for_each_entry_rcu(client, &evdev->client_list, node)
|
||||
- evdev_pass_event(client, &event);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
@@ -136,14 +133,15 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
|
||||
{
|
||||
int error;
|
||||
|
||||
- if (evdev->grab)
|
||||
+ if (client->grab)
|
||||
return -EBUSY;
|
||||
|
||||
- error = input_grab_device(&evdev->handle);
|
||||
- if (error)
|
||||
- return error;
|
||||
-
|
||||
- rcu_assign_pointer(evdev->grab, client);
|
||||
+ if (!evdev->grab++) {
|
||||
+ error = input_grab_device(&evdev->handle);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+ }
|
||||
+ client->grab = 1;
|
||||
synchronize_rcu();
|
||||
|
||||
return 0;
|
||||
@@ -151,12 +149,12 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
|
||||
|
||||
static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client)
|
||||
{
|
||||
- if (evdev->grab != client)
|
||||
+ if (!client->grab)
|
||||
return -EINVAL;
|
||||
|
||||
- rcu_assign_pointer(evdev->grab, NULL);
|
||||
- synchronize_rcu();
|
||||
- input_release_device(&evdev->handle);
|
||||
+ if (!--evdev->grab && evdev->exist)
|
||||
+ input_release_device(&evdev->handle);
|
||||
+ client->grab = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -231,7 +229,7 @@ static int evdev_release(struct inode *inode, struct file *file)
|
||||
struct evdev *evdev = client->evdev;
|
||||
|
||||
mutex_lock(&evdev->mutex);
|
||||
- if (evdev->grab == client)
|
||||
+ if (client->grab)
|
||||
evdev_ungrab(evdev, client);
|
||||
mutex_unlock(&evdev->mutex);
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
From 7cb1e9a0797dd5d372f943f0ed971a5b432d16aa Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:23 +0100
|
||||
Subject: [PATCH] s3c2410-usb-switch.patch
|
||||
|
||||
---
|
||||
drivers/usb/host/ohci-s3c2410.c | 43 +++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 43 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
|
||||
index 3c7a740..5877fc9 100644
|
||||
--- a/drivers/usb/host/ohci-s3c2410.c
|
||||
+++ b/drivers/usb/host/ohci-s3c2410.c
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/usb-control.h>
|
||||
+#include <asm/arch/regs-gpio.h>
|
||||
|
||||
#define valid_port(idx) ((idx) == 1 || (idx) == 2)
|
||||
|
||||
@@ -308,6 +309,40 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
+/* switching of USB pads */
|
||||
+static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ if (__raw_readl(S3C24XX_MISCCR) & S3C2410_MISCCR_USBHOST)
|
||||
+ return sprintf(buf, "host\n");
|
||||
+
|
||||
+ return sprintf(buf, "device\n");
|
||||
+}
|
||||
+
|
||||
+static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ if (!strncmp(buf, "host", 4)) {
|
||||
+ printk("s3c2410: changing usb to host\n");
|
||||
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST,
|
||||
+ S3C2410_MISCCR_USBHOST);
|
||||
+ /* FIXME:
|
||||
+ * - call machine-specific disable-pullup function i
|
||||
+ * - enable +Vbus (if hardware supports it)
|
||||
+ */
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPB9, 0);
|
||||
+ } else if (!strncmp(buf, "device", 6)) {
|
||||
+ printk("s3c2410: changing usb to device\n");
|
||||
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0);
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPB9, 1);
|
||||
+ } else
|
||||
+ printk("s3c2410: unknown mode\n");
|
||||
+ return -EINVAL;
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode);
|
||||
+
|
||||
/* may be called without controller electrically present */
|
||||
/* may be called with controller, bus, and devices active */
|
||||
|
||||
@@ -325,6 +360,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
|
||||
static void
|
||||
usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
|
||||
{
|
||||
+ device_remove_file(&dev->dev, &dev_attr_usb_mode);
|
||||
usb_remove_hcd(hcd);
|
||||
s3c2410_stop_hc(dev);
|
||||
iounmap(hcd->regs);
|
||||
@@ -392,8 +428,15 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
|
||||
if (retval != 0)
|
||||
goto err_ioremap;
|
||||
|
||||
+ retval = device_create_file(&dev->dev, &dev_attr_usb_mode);
|
||||
+ if (retval != 0)
|
||||
+ goto err_hcd;
|
||||
+
|
||||
return 0;
|
||||
|
||||
+ err_hcd:
|
||||
+ usb_remove_hcd(hcd);
|
||||
+
|
||||
err_ioremap:
|
||||
s3c2410_stop_hc(dev);
|
||||
iounmap(hcd->regs);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
From 60018d983c0e7e8cc2f3b1669338b05c5b5356f8 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:24 +0100
|
||||
Subject: [PATCH] pnp_fixes.patch
|
||||
|
||||
---
|
||||
drivers/pnp/Kconfig | 2 +-
|
||||
drivers/pnp/resource.c | 2 ++
|
||||
2 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
|
||||
index 821933f..f9313cf 100644
|
||||
--- a/drivers/pnp/Kconfig
|
||||
+++ b/drivers/pnp/Kconfig
|
||||
@@ -5,7 +5,7 @@
|
||||
menuconfig PNP
|
||||
bool "Plug and Play support"
|
||||
depends on HAS_IOMEM
|
||||
- depends on ISA || ACPI
|
||||
+ depends on ISA || ACPI || SDIO
|
||||
---help---
|
||||
Plug and Play (PnP) is a standard for peripherals which allows those
|
||||
peripherals to be configured by software, e.g. assign IRQ's or other
|
||||
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
|
||||
index 390b500..3aabbf6 100644
|
||||
--- a/drivers/pnp/resource.c
|
||||
+++ b/drivers/pnp/resource.c
|
||||
@@ -468,6 +468,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
|
||||
}
|
||||
}
|
||||
|
||||
+#if 0
|
||||
/* check if the resource is already in use, skip if the
|
||||
* device is active because it itself may be in use */
|
||||
if (!dev->active) {
|
||||
@@ -475,6 +476,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
|
||||
return 0;
|
||||
free_dma(*dma);
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* check for conflicts with other pnp devices */
|
||||
pnp_for_each_dev(tdev) {
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
|||
From 1b629ded094c800293cf694e85d0c5b66cc9fcfd Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:25 +0100
|
||||
Subject: [PATCH] fix-hwecc-2410.patch
|
||||
S3C24xx ECC mis-calculates the bit to flip:
|
||||
http://lists.infradead.org/pipermail/linux-mtd/2007-October/019586.html
|
||||
If the error couldn't be corrected, we returned "no problem" :-(
|
||||
http://lists.infradead.org/pipermail/linux-mtd/2007-October/019615.html
|
||||
|
||||
Signed-off-by: Werner Almesberger <werner@openmoko.org>
|
||||
---
|
||||
drivers/mtd/nand/s3c2410.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
|
||||
index 8e1e482..4f747b1 100644
|
||||
--- a/drivers/mtd/nand/s3c2410.c
|
||||
+++ b/drivers/mtd/nand/s3c2410.c
|
||||
@@ -406,7 +406,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
|
||||
if ((diff0 & ~(1<<fls(diff0))) == 0)
|
||||
return 1;
|
||||
|
||||
- return -1;
|
||||
+ return -EBADMSG;
|
||||
}
|
||||
|
||||
/* ECC functions
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
From 835002d2e751c0d35b744ceec5bef726b9778b7b Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:25 +0100
|
||||
Subject: [PATCH] fix-pcf50606-LOWBAT-kill-init.patch
|
||||
|
||||
---
|
||||
drivers/i2c/chips/pcf50606.c | 53 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 files changed, 46 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
|
||||
index b530583..a1c92d3 100644
|
||||
--- a/drivers/i2c/chips/pcf50606.c
|
||||
+++ b/drivers/i2c/chips/pcf50606.c
|
||||
@@ -654,8 +654,20 @@ static void pcf50606_work(struct work_struct *work)
|
||||
if (pcf->onkey_seconds >=
|
||||
pcf->pdata->onkey_seconds_required) {
|
||||
/* Ask init to do 'ctrlaltdel' */
|
||||
- DEBUGPC("SIGINT(init) ");
|
||||
- kill_proc(1, SIGINT, 1);
|
||||
+ /*
|
||||
+ * currently Linux reacts badly to issuing a
|
||||
+ * signal to PID #1 before init is started.
|
||||
+ * What happens is that the next kernel thread
|
||||
+ * to start, which is the JFFS2 Garbage
|
||||
+ * collector in our case, gets the signal
|
||||
+ * instead and proceeds to fail to fork --
|
||||
+ * which is very bad. Therefore we confirm
|
||||
+ * PID #1 exists before issuing the signal
|
||||
+ */
|
||||
+ if (find_task_by_pid(1)) {
|
||||
+ kill_proc(1, SIGINT, 1);
|
||||
+ DEBUGPC("SIGINT(init) ");
|
||||
+ }
|
||||
/* FIXME: what to do if userspace doesn't
|
||||
* shut down? Do we want to force it? */
|
||||
}
|
||||
@@ -749,11 +761,38 @@ static void pcf50606_work(struct work_struct *work)
|
||||
}
|
||||
/* FIXME: TSCPRES */
|
||||
if (pcfirq[2] & PCF50606_INT3_LOWBAT) {
|
||||
- /* Really low battery voltage, we have 8 seconds left */
|
||||
- DEBUGPC("LOWBAT ");
|
||||
- apm_queue_event(APM_LOW_BATTERY);
|
||||
- DEBUGPC("SIGPWR(init) ");
|
||||
- kill_proc(1, SIGPWR, 1);
|
||||
+ if (__reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON) {
|
||||
+ /*
|
||||
+ * hey no need to freak out, we have some kind of
|
||||
+ * valid charger power
|
||||
+ */
|
||||
+ DEBUGPC("(NO)BAT ");
|
||||
+ } else {
|
||||
+ /* Really low battery voltage, we have 8 seconds left */
|
||||
+ DEBUGPC("LOWBAT ");
|
||||
+ /*
|
||||
+ * currently Linux reacts badly to issuing a signal to
|
||||
+ * PID #1 before init is started. What happens is that
|
||||
+ * the next kernel thread to start, which is the JFFS2
|
||||
+ * Garbage collector in our case, gets the signal
|
||||
+ * instead and proceeds to fail to fork -- which is
|
||||
+ * very bad. Therefore we confirm PID #1 exists
|
||||
+ * before issuing SPIGPWR
|
||||
+ */
|
||||
+ if (find_task_by_pid(1)) {
|
||||
+ apm_queue_event(APM_LOW_BATTERY);
|
||||
+ DEBUGPC("SIGPWR(init) ");
|
||||
+ kill_proc(1, SIGPWR, 1);
|
||||
+ } else
|
||||
+ /*
|
||||
+ * well, our situation is like this: we do not
|
||||
+ * have any external power, we have a low
|
||||
+ * battery and since PID #1 doesn't exist yet,
|
||||
+ * we are early in the boot, likely before
|
||||
+ * rootfs mount. We should just call it a day
|
||||
+ */
|
||||
+ apm_queue_event(APM_CRITICAL_SUSPEND);
|
||||
+ }
|
||||
/* Tell PMU we are taking care of this */
|
||||
reg_set_bit_mask(pcf, PCF50606_REG_OOCC1,
|
||||
PCF50606_OOCC1_TOTRST,
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
From 6d3172ba9f1b4a650c8fdb3b6e11dc71852fe6d1 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 22:21:25 +0100
|
||||
Subject: [PATCH] fix-pcf50633-LOWBAT-kill-init.patch
|
||||
|
||||
---
|
||||
drivers/i2c/chips/pcf50633.c | 56 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 files changed, 49 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||||
index 0cf5e53..fc1262e 100644
|
||||
--- a/drivers/i2c/chips/pcf50633.c
|
||||
+++ b/drivers/i2c/chips/pcf50633.c
|
||||
@@ -690,8 +690,20 @@ static void pcf50633_work(struct work_struct *work)
|
||||
if (pcf->onkey_seconds >=
|
||||
pcf->pdata->onkey_seconds_sig_init) {
|
||||
/* Ask init to do 'ctrlaltdel' */
|
||||
- DEBUGPC("SIGINT(init) ");
|
||||
- kill_proc(1, SIGINT, 1);
|
||||
+ /*
|
||||
+ * currently Linux reacts badly to issuing a
|
||||
+ * signal to PID #1 before init is started.
|
||||
+ * What happens is that the next kernel thread
|
||||
+ * to start, which is the JFFS2 Garbage
|
||||
+ * collector in our case, gets the signal
|
||||
+ * instead and proceeds to fail to fork --
|
||||
+ * which is very bad. Therefore we confirm
|
||||
+ * PID #1 exists before issuing the signal
|
||||
+ */
|
||||
+ if (find_task_by_pid(1)) {
|
||||
+ DEBUGPC("SIGINT(init) ");
|
||||
+ kill_proc(1, SIGINT, 1);
|
||||
+ }
|
||||
/* FIXME: what if userspace doesn't shut down? */
|
||||
}
|
||||
if (pcf->onkey_seconds >=
|
||||
@@ -790,11 +802,41 @@ static void pcf50633_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (pcfirq[3] & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) {
|
||||
- /* Really low battery voltage, we have 8 seconds left */
|
||||
- DEBUGPC("LOWBAT ");
|
||||
- apm_queue_event(APM_LOW_BATTERY);
|
||||
- DEBUGPC("SIGPWR(init) ");
|
||||
- kill_proc(1, SIGPWR, 1);
|
||||
+ if ((__reg_read(pcf, PCF50633_REG_MBCS1) &
|
||||
+ (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) ==
|
||||
+ (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) {
|
||||
+ /*
|
||||
+ * hey no need to freak out, we have some kind of
|
||||
+ * valid charger power
|
||||
+ */
|
||||
+ DEBUGPC("(NO)BAT ");
|
||||
+ } else {
|
||||
+ /* Really low battery voltage, we have 8 seconds left */
|
||||
+ DEBUGPC("LOWBAT ");
|
||||
+ /*
|
||||
+ * currently Linux reacts badly to issuing a signal to
|
||||
+ * PID #1 before init is started. What happens is that
|
||||
+ * the next kernel thread to start, which is the JFFS2
|
||||
+ * Garbage collector in our case, gets the signal
|
||||
+ * instead and proceeds to fail to fork -- which is
|
||||
+ * very bad. Therefore we confirm PID #1 exists
|
||||
+ * before issuing SPIGPWR
|
||||
+ */
|
||||
+ if (find_task_by_pid(1)) {
|
||||
+ apm_queue_event(APM_LOW_BATTERY);
|
||||
+ DEBUGPC("SIGPWR(init) ");
|
||||
+ kill_proc(1, SIGPWR, 1);
|
||||
+ } else
|
||||
+ /*
|
||||
+ * well, our situation is like this: we do not
|
||||
+ * have any external power, we have a low
|
||||
+ * battery and since PID #1 doesn't exist yet,
|
||||
+ * we are early in the boot, likely before
|
||||
+ * rootfs mount. We should just call it a day
|
||||
+ */
|
||||
+ apm_queue_event(APM_CRITICAL_SUSPEND);
|
||||
+ }
|
||||
+
|
||||
/* Tell PMU we are taking care of this */
|
||||
reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
|
||||
PCF50633_OOCSHDWN_TOTRST,
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
From 2e7d18a213b94e4aeded7f35b7cd0d02b9b661cd Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 23:04:37 +0100
|
||||
Subject: [PATCH] gta01-dehang-printk.patch
|
||||
This is a temporary work-around Mike Westerhof for this bug:
|
||||
http://bugzilla.openmoko.org/cgi-bin/bugzilla/show_bug.cgi?id=788
|
||||
|
||||
See also
|
||||
http://lists.openmoko.org/pipermail/openmoko-kernel/2008-February/000804.html
|
||||
|
||||
(It's the 2nd option.)
|
||||
|
||||
We may settle on a different solution in the future, depending on
|
||||
feedback from upstream.
|
||||
---
|
||||
drivers/serial/s3c2410.c | 9 +++++++++
|
||||
1 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
|
||||
index 7117110..bd87c79 100644
|
||||
--- a/drivers/serial/s3c2410.c
|
||||
+++ b/drivers/serial/s3c2410.c
|
||||
@@ -1720,9 +1720,18 @@ static void
|
||||
s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
|
||||
{
|
||||
unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
|
||||
+ unsigned int umcon = rd_regl(cons_uart, S3C2410_UMCON);
|
||||
+
|
||||
+ /* If auto HW flow control enabled, temporarily turn it off */
|
||||
+ if (umcon & S3C2410_UMCOM_AFC)
|
||||
+ wr_regl(port, S3C2410_UMCON, (umcon & !S3C2410_UMCOM_AFC));
|
||||
+
|
||||
while (!s3c24xx_serial_console_txrdy(port, ufcon))
|
||||
barrier();
|
||||
wr_regb(cons_uart, S3C2410_UTXH, ch);
|
||||
+
|
||||
+ if (umcon & S3C2410_UMCOM_AFC)
|
||||
+ wr_regl(port, S3C2410_UMCON, umcon);
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
From a158085e182617f31960599ab1f468668c3161d4 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 23:05:18 +0100
|
||||
Subject: [PATCH] suspend-prelim1.patch
|
||||
|
||||
---
|
||||
drivers/i2c/chips/pcf50633.c | 5 +++++
|
||||
drivers/i2c/i2c-core.c | 13 ++++++++++++-
|
||||
drivers/mfd/glamo/glamo-core.c | 2 ++
|
||||
3 files changed, 19 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||||
index fc1262e..e23c540 100644
|
||||
--- a/drivers/i2c/chips/pcf50633.c
|
||||
+++ b/drivers/i2c/chips/pcf50633.c
|
||||
@@ -1901,6 +1901,9 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* turn off the backlight */
|
||||
+ __reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
|
||||
+
|
||||
pcf->standby_regs.int1m = __reg_read(pcf, PCF50633_REG_INT1M);
|
||||
pcf->standby_regs.int2m = __reg_read(pcf, PCF50633_REG_INT2M);
|
||||
pcf->standby_regs.int3m = __reg_read(pcf, PCF50633_REG_INT3M);
|
||||
@@ -1925,6 +1928,8 @@ static int pcf50633_resume(struct device *dev)
|
||||
|
||||
mutex_lock(&pcf->lock);
|
||||
|
||||
+ __reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
|
||||
+
|
||||
/* Resume all saved registers that don't "survive" standby state */
|
||||
__reg_write(pcf, PCF50633_REG_INT1M, pcf->standby_regs.int1m);
|
||||
__reg_write(pcf, PCF50633_REG_INT2M, pcf->standby_regs.int2m);
|
||||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
|
||||
index bb0c5e5..c300975 100644
|
||||
--- a/drivers/i2c/i2c-core.c
|
||||
+++ b/drivers/i2c/i2c-core.c
|
||||
@@ -1,4 +1,3 @@
|
||||
-/* i2c-core.c - a device driver for the iic-bus interface */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Copyright (C) 1995-99 Simon G. Vogl
|
||||
|
||||
@@ -160,10 +159,16 @@ static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
|
||||
|
||||
if (!dev->driver)
|
||||
return 0;
|
||||
+#if 0
|
||||
driver = to_i2c_driver(dev->driver);
|
||||
if (!driver->suspend)
|
||||
return 0;
|
||||
return driver->suspend(to_i2c_client(dev), mesg);
|
||||
+#else
|
||||
+ if (!dev->driver->suspend)
|
||||
+ return 0;
|
||||
+ return dev->driver->suspend(dev, mesg);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int i2c_device_resume(struct device * dev)
|
||||
@@ -172,10 +177,16 @@ static int i2c_device_resume(struct device * dev)
|
||||
|
||||
if (!dev->driver)
|
||||
return 0;
|
||||
+#if 0
|
||||
driver = to_i2c_driver(dev->driver);
|
||||
if (!driver->resume)
|
||||
return 0;
|
||||
return driver->resume(to_i2c_client(dev));
|
||||
+#else
|
||||
+ if (!dev->driver->resume)
|
||||
+ return 0;
|
||||
+ return dev->driver->resume(dev);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void i2c_client_release(struct device *dev)
|
||||
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
|
||||
index 8497de2..ffa4945 100644
|
||||
--- a/drivers/mfd/glamo/glamo-core.c
|
||||
+++ b/drivers/mfd/glamo/glamo-core.c
|
||||
@@ -1125,11 +1125,13 @@ static int glamo_remove(struct platform_device *pdev)
|
||||
#ifdef CONFIG_PM
|
||||
static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
+ glamo_power(glamo_handle, GLAMO_POWER_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int glamo_resume(struct platform_device *pdev)
|
||||
{
|
||||
+ glamo_power(glamo_handle, GLAMO_POWER_ON);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
From 4df411aa6f42be6fe5881d7b2fb88aae9d9a56a8 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 23:05:21 +0100
|
||||
Subject: [PATCH] gta02-sound-bandaid.patch
|
||||
http://bugzilla.openmoko.org/cgi-bin/bugzilla/show_bug.cgi?id=1172
|
||||
|
||||
This patch seems to alleviate the symptoms but doesn't cure them.
|
||||
Keep it to keep development going, until we have a proper solution.
|
||||
---
|
||||
sound/soc/codecs/wm8753.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
|
||||
index fb41826..72baf3d 100644
|
||||
--- a/sound/soc/codecs/wm8753.c
|
||||
+++ b/sound/soc/codecs/wm8753.c
|
||||
@@ -1589,6 +1589,9 @@ static int wm8753_init(struct snd_soc_device *socdev)
|
||||
schedule_delayed_work(&codec->delayed_work,
|
||||
msecs_to_jiffies(caps_charge));
|
||||
|
||||
+ /* Fix reg WM8753_ADCTL2 */
|
||||
+ wm8753_write(codec, WM8753_ADCTL2, 0x0000);
|
||||
+
|
||||
/* set the update bits */
|
||||
reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
|
||||
wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
From 08f211e0775ee1e29993fd072968e17a51c5ec14 Mon Sep 17 00:00:00 2001
|
||||
From: mokopatches <mokopatches@openmoko.org>
|
||||
Date: Fri, 25 Jul 2008 23:05:22 +0100
|
||||
Subject: [PATCH] glamo-cmdqueue-bandaid.patch
|
||||
[ Stop kernel from hanging every once in a while during Glamo
|
||||
initialization. ]
|
||||
|
||||
debug-glamo-fb-cmdqueue-wait-timeout.patch
|
||||
|
||||
From: warmcat <andy@warmcat.com>
|
||||
---
|
||||
drivers/mfd/glamo/glamo-fb.c | 30 +++++++++++++++++++++++++++---
|
||||
1 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
|
||||
index 394a0ad..f0d7600 100644
|
||||
--- a/drivers/mfd/glamo/glamo-fb.c
|
||||
+++ b/drivers/mfd/glamo/glamo-fb.c
|
||||
@@ -553,12 +553,20 @@ static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
|
||||
|
||||
void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
|
||||
{
|
||||
+ int timeout = 2000;
|
||||
+
|
||||
dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on);
|
||||
if (on) {
|
||||
dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
|
||||
__FUNCTION__);
|
||||
- while (!glamofb_cmdq_empty(gfb))
|
||||
+ while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
|
||||
yield();
|
||||
+ if (timeout < 0) {
|
||||
+ printk(KERN_ERR"*************"
|
||||
+ "glamofb cmd_queue never got empty"
|
||||
+ "*************\n");
|
||||
+ return;
|
||||
+ }
|
||||
dev_dbg(gfb->dev, "empty!\n");
|
||||
|
||||
/* display the entire frame then switch to command */
|
||||
@@ -568,8 +576,16 @@ void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
|
||||
|
||||
/* wait until LCD is idle */
|
||||
dev_dbg(gfb->dev, "waiting for LCD idle: ");
|
||||
- while (!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12))
|
||||
+ timeout = 2000;
|
||||
+ while ((!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) &&
|
||||
+ (timeout--))
|
||||
yield();
|
||||
+ if (timeout < 0) {
|
||||
+ printk(KERN_ERR"*************"
|
||||
+ "glamofb lcd never idle"
|
||||
+ "*************\n");
|
||||
+ return;
|
||||
+ }
|
||||
dev_dbg(gfb->dev, "idle!\n");
|
||||
|
||||
msleep(90);
|
||||
@@ -589,10 +605,18 @@ EXPORT_SYMBOL_GPL(glamofb_cmd_mode);
|
||||
|
||||
int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
|
||||
{
|
||||
+ int timeout = 2000;
|
||||
+
|
||||
dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n",
|
||||
__FUNCTION__);
|
||||
- while (!glamofb_cmdq_empty(gfb))
|
||||
+ while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
|
||||
yield();
|
||||
+ if (timeout < 0) {
|
||||
+ printk(KERN_ERR"*************"
|
||||
+ "glamofb cmd_queue never got empty"
|
||||
+ "*************\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val);
|
||||
|
||||
reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
From 38801452b334d3591eddadbfa4a31529b8957513 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:24 +0100
|
||||
Subject: [PATCH] fix-wm8753-DBG.patch
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
sound/soc/s3c24xx/neo1973_wm8753.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
|
||||
index 4ab6f63..2bc813f 100644
|
||||
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
|
||||
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
|
||||
@@ -671,7 +671,7 @@ static int __init neo1973_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
- DBG("Entered %s\n", __func__);
|
||||
+ printk(KERN_DEBUG "Entered %s\n", __func__);
|
||||
|
||||
if (!machine_is_neo1973_gta01()) {
|
||||
printk(KERN_INFO
|
||||
--
|
||||
1.5.6.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
|||
From bd559c9f37baa73f7220b8158909ce6d7264d4d3 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:59 +0100
|
||||
Subject: [PATCH] local-build-scripts.patch
|
||||
|
||||
Add a couple of handy scripts to crossmake and send over dfu
|
||||
|
||||
From: warmcat <andy@warmcat.com>
|
||||
---
|
||||
build | 14 ++++++++++++++
|
||||
dfu-kern | 9 +++++++++
|
||||
2 files changed, 23 insertions(+), 0 deletions(-)
|
||||
create mode 100755 build
|
||||
create mode 100755 dfu-kern
|
||||
|
||||
diff --git a/build b/build
|
||||
new file mode 100755
|
||||
index 0000000..7e61ea2
|
||||
--- /dev/null
|
||||
+++ b/build
|
||||
@@ -0,0 +1,14 @@
|
||||
+#!/bin/sh
|
||||
+
|
||||
+set -x
|
||||
+
|
||||
+export CROSS_COMPILE=../../cross/bin/arm-angstrom-linux-gnueabi-
|
||||
+make ARCH=arm silentoldconfig
|
||||
+if make -j5 ARCH=arm; then
|
||||
+ ${CROSS_COMPILE}objcopy -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux linux.bin
|
||||
+ mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n "OpenMoko Kernel Image Neo1973(GTA02)" -d linux.bin uImage.bin
|
||||
+ exit 0
|
||||
+else
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
diff --git a/dfu-kern b/dfu-kern
|
||||
new file mode 100755
|
||||
index 0000000..990abdd
|
||||
--- /dev/null
|
||||
+++ b/dfu-kern
|
||||
@@ -0,0 +1,9 @@
|
||||
+#!/bin/bash
|
||||
+../../dfu-util/src/dfu-util -a 3 -d 0x1457:0x5119 -D uImage.bin
|
||||
+if [ $? -eq 1 ] ; then
|
||||
+../../dfu-util/src/dfu-util -a 3 -d 0x1457:0x5120 -D uImage.bin
|
||||
+../../dfu-util/src/dfu-util -a 3 -d 0x1457:0x5119 -D uImage.bin
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
From 11b5692836d6e70af1da2acf4c61f45838b6be83 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:59 +0100
|
||||
Subject: [PATCH] local-build-new-dfu-vid.patch
|
||||
|
||||
Update to new DFU VID for A5
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
dfu-kern | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dfu-kern b/dfu-kern
|
||||
index 990abdd..b7ed2c3 100755
|
||||
--- a/dfu-kern
|
||||
+++ b/dfu-kern
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
-../../dfu-util/src/dfu-util -a 3 -d 0x1457:0x5119 -D uImage.bin
|
||||
+../../dfu-util/src/dfu-util -a 3 -d 0x1d50:0x5119 -D uImage.bin
|
||||
if [ $? -eq 1 ] ; then
|
||||
-../../dfu-util/src/dfu-util -a 3 -d 0x1457:0x5120 -D uImage.bin
|
||||
-../../dfu-util/src/dfu-util -a 3 -d 0x1457:0x5119 -D uImage.bin
|
||||
+../../dfu-util/src/dfu-util -a 3 -d 0x1d50:0x5120 -D uImage.bin
|
||||
+../../dfu-util/src/dfu-util -a 3 -d 0x1d50:0x5119 -D uImage.bin
|
||||
|
||||
fi
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
1836
target/linux/s3c24xx/patches/0067-local-update-defconfig-for-2.6-dev.patch.patch
Executable file
1836
target/linux/s3c24xx/patches/0067-local-update-defconfig-for-2.6-dev.patch.patch
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,72 @@
|
|||
From 46b7ab304f0f5fcdfa1ab6d2034438928ab68f97 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:59 +0100
|
||||
Subject: [PATCH] local-config-add-vfat-nls-to-kern.patch
|
||||
|
||||
SD Card / VFAT in monolithic kernel
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
defconfig-2.6.24 | 18 +++++++++---------
|
||||
1 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 48644ac..b0ef327 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
-# Linux kernel version: 2.6.24-rc6
|
||||
-# Tue Jan 8 11:16:56 2008
|
||||
+# Linux kernel version: 2.6.24-rc7
|
||||
+# Sun Jan 13 21:40:55 2008
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
@@ -1034,7 +1034,7 @@ CONFIG_SPI_MASTER=y
|
||||
#
|
||||
CONFIG_SPI_BITBANG=y
|
||||
CONFIG_SPI_S3C24XX=y
|
||||
-CONFIG_SPI_S3C24XX_GPIO=y
|
||||
+# CONFIG_SPI_S3C24XX_GPIO is not set
|
||||
|
||||
#
|
||||
# SPI Protocol Masters
|
||||
@@ -1587,9 +1587,9 @@ CONFIG_JOLIET=y
|
||||
#
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
-CONFIG_FAT_FS=m
|
||||
-CONFIG_MSDOS_FS=m
|
||||
-CONFIG_VFAT_FS=m
|
||||
+CONFIG_FAT_FS=y
|
||||
+CONFIG_MSDOS_FS=y
|
||||
+CONFIG_VFAT_FS=y
|
||||
CONFIG_FAT_DEFAULT_CODEPAGE=437
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
|
||||
# CONFIG_NTFS_FS is not set
|
||||
@@ -1649,9 +1649,9 @@ CONFIG_CRAMFS=y
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
-CONFIG_NLS=m
|
||||
+CONFIG_NLS=y
|
||||
CONFIG_NLS_DEFAULT="iso8859-1"
|
||||
-CONFIG_NLS_CODEPAGE_437=m
|
||||
+CONFIG_NLS_CODEPAGE_437=y
|
||||
# CONFIG_NLS_CODEPAGE_737 is not set
|
||||
# CONFIG_NLS_CODEPAGE_775 is not set
|
||||
CONFIG_NLS_CODEPAGE_850=m
|
||||
@@ -1675,7 +1675,7 @@ CONFIG_NLS_CODEPAGE_950=m
|
||||
# CONFIG_NLS_CODEPAGE_1250 is not set
|
||||
# CONFIG_NLS_CODEPAGE_1251 is not set
|
||||
# CONFIG_NLS_ASCII is not set
|
||||
-CONFIG_NLS_ISO8859_1=m
|
||||
+CONFIG_NLS_ISO8859_1=y
|
||||
# CONFIG_NLS_ISO8859_2 is not set
|
||||
# CONFIG_NLS_ISO8859_3 is not set
|
||||
# CONFIG_NLS_ISO8859_4 is not set
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
From 5e63b0173c4f096c43f9320c1ea910710b11eaad Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:59 +0100
|
||||
Subject: [PATCH] local-config-add-bluetooth-monolithic.patch
|
||||
|
||||
Add Bluetooth in monolithic kernel
|
||||
---
|
||||
defconfig-2.6.24 | 10 ++--------
|
||||
1 files changed, 2 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index b0ef327..5b3e5e9 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1275,16 +1275,10 @@ CONFIG_HID=y
|
||||
#
|
||||
# USB Input Devices
|
||||
#
|
||||
-CONFIG_USB_HID=m
|
||||
+CONFIG_USB_HID=y
|
||||
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
|
||||
# CONFIG_HID_FF is not set
|
||||
# CONFIG_USB_HIDDEV is not set
|
||||
-
|
||||
-#
|
||||
-# USB HID Boot Protocol drivers
|
||||
-#
|
||||
-# CONFIG_USB_KBD is not set
|
||||
-# CONFIG_USB_MOUSE is not set
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USB_ARCH_HAS_HCD=y
|
||||
CONFIG_USB_ARCH_HAS_OHCI=y
|
||||
@@ -1306,7 +1300,7 @@ CONFIG_USB_PERSIST=y
|
||||
# USB Host Controller Drivers
|
||||
#
|
||||
# CONFIG_USB_ISP116X_HCD is not set
|
||||
-CONFIG_USB_OHCI_HCD=m
|
||||
+CONFIG_USB_OHCI_HCD=y
|
||||
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
|
||||
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
|
||||
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
From c21c82ef59cc77008ab05448ff001ae4a72396ba Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:59 +0100
|
||||
Subject: [PATCH] local-config-wlan-config-changes.patch
|
||||
|
||||
---
|
||||
defconfig-2.6.24 | 47 ++++++++++++++++++++++++++++++++---------------
|
||||
1 files changed, 32 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 5b3e5e9..140fbfa 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
-# Linux kernel version: 2.6.24-rc7
|
||||
-# Sun Jan 13 21:40:55 2008
|
||||
+# Linux kernel version: 2.6.24-rc8
|
||||
+# Tue Jan 22 11:47:25 2008
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
@@ -322,7 +322,7 @@ CONFIG_NET=y
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
-CONFIG_PACKET=m
|
||||
+CONFIG_PACKET=y
|
||||
CONFIG_PACKET_MMAP=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM=y
|
||||
@@ -595,20 +595,20 @@ CONFIG_NET_SCH_FIFO=y
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
# CONFIG_HAMRADIO is not set
|
||||
# CONFIG_IRDA is not set
|
||||
-CONFIG_BT=m
|
||||
-CONFIG_BT_L2CAP=m
|
||||
-CONFIG_BT_SCO=m
|
||||
-CONFIG_BT_RFCOMM=m
|
||||
+CONFIG_BT=y
|
||||
+CONFIG_BT_L2CAP=y
|
||||
+CONFIG_BT_SCO=y
|
||||
+CONFIG_BT_RFCOMM=y
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
-CONFIG_BT_BNEP=m
|
||||
+CONFIG_BT_BNEP=y
|
||||
CONFIG_BT_BNEP_MC_FILTER=y
|
||||
CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
-CONFIG_BT_HIDP=m
|
||||
+CONFIG_BT_HIDP=y
|
||||
|
||||
#
|
||||
# Bluetooth device drivers
|
||||
#
|
||||
-CONFIG_BT_HCIUSB=m
|
||||
+CONFIG_BT_HCIUSB=y
|
||||
CONFIG_BT_HCIUSB_SCO=y
|
||||
# CONFIG_BT_HCIBTSDIO is not set
|
||||
# CONFIG_BT_HCIUART is not set
|
||||
@@ -623,7 +623,7 @@ CONFIG_FIB_RULES=y
|
||||
# Wireless
|
||||
#
|
||||
# CONFIG_CFG80211 is not set
|
||||
-# CONFIG_WIRELESS_EXT is not set
|
||||
+CONFIG_WIRELESS_EXT=y
|
||||
# CONFIG_MAC80211 is not set
|
||||
# CONFIG_IEEE80211 is not set
|
||||
# CONFIG_RFKILL is not set
|
||||
@@ -737,6 +737,13 @@ CONFIG_MTD_NAND_S3C2410_HWECC=y
|
||||
#
|
||||
# CONFIG_MTD_UBI is not set
|
||||
# CONFIG_PARPORT is not set
|
||||
+CONFIG_PNP=y
|
||||
+CONFIG_PNP_DEBUG=y
|
||||
+
|
||||
+#
|
||||
+# Protocols
|
||||
+#
|
||||
+# CONFIG_PNPACPI is not set
|
||||
CONFIG_BLK_DEV=y
|
||||
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
@@ -814,9 +821,10 @@ CONFIG_NETDEVICES=y
|
||||
# CONFIG_EQUALIZER is not set
|
||||
CONFIG_TUN=m
|
||||
# CONFIG_VETH is not set
|
||||
+# CONFIG_NET_SB1000 is not set
|
||||
# CONFIG_PHYLIB is not set
|
||||
CONFIG_NET_ETHERNET=y
|
||||
-CONFIG_MII=m
|
||||
+CONFIG_MII=y
|
||||
# CONFIG_AX88796 is not set
|
||||
# CONFIG_SMC91X is not set
|
||||
# CONFIG_DM9000 is not set
|
||||
@@ -843,7 +851,7 @@ CONFIG_USB_CATC=m
|
||||
CONFIG_USB_KAWETH=m
|
||||
CONFIG_USB_PEGASUS=m
|
||||
CONFIG_USB_RTL8150=m
|
||||
-CONFIG_USB_USBNET=m
|
||||
+CONFIG_USB_USBNET=y
|
||||
CONFIG_USB_NET_AX8817X=m
|
||||
CONFIG_USB_NET_CDCETHER=m
|
||||
CONFIG_USB_NET_DM9601=m
|
||||
@@ -1436,6 +1444,7 @@ CONFIG_USB_IOWARRIOR=m
|
||||
CONFIG_USB_GADGET=y
|
||||
# CONFIG_USB_GADGET_DEBUG is not set
|
||||
# CONFIG_USB_GADGET_DEBUG_FILES is not set
|
||||
+# CONFIG_USB_GADGET_DEBUG_FS is not set
|
||||
CONFIG_USB_GADGET_SELECTED=y
|
||||
# CONFIG_USB_GADGET_AMD5536UDC is not set
|
||||
# CONFIG_USB_GADGET_ATMEL_USBA is not set
|
||||
@@ -1459,6 +1468,14 @@ CONFIG_USB_ETH_RNDIS=y
|
||||
# CONFIG_USB_FILE_STORAGE is not set
|
||||
# CONFIG_USB_G_SERIAL is not set
|
||||
# CONFIG_USB_MIDI_GADGET is not set
|
||||
+
|
||||
+#
|
||||
+# SDIO support
|
||||
+#
|
||||
+CONFIG_SDIO=y
|
||||
+CONFIG_SDIO_S3C24XX=y
|
||||
+CONFIG_SDIO_S3C24XX_DMA=y
|
||||
+CONFIG_SDIO_AR6000_WLAN=y
|
||||
CONFIG_MMC=y
|
||||
# CONFIG_MMC_DEBUG is not set
|
||||
# CONFIG_MMC_UNSAFE_RESUME is not set
|
||||
@@ -1475,7 +1492,6 @@ CONFIG_MMC_BLOCK=y
|
||||
#
|
||||
# CONFIG_MMC_SPI is not set
|
||||
# CONFIG_MMC_S3C is not set
|
||||
-CONFIG_MMC_GLAMO=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
|
||||
@@ -1554,6 +1570,7 @@ CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
# CONFIG_EXT4DEV_FS is not set
|
||||
CONFIG_JBD=y
|
||||
+# CONFIG_JBD_DEBUG is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
@@ -1696,7 +1713,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
-# CONFIG_DEBUG_FS is not set
|
||||
+CONFIG_DEBUG_FS=y
|
||||
# CONFIG_HEADERS_CHECK is not set
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_SHIRQ=y
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
From cdefa3c7722774152538c4ac5ea9290c441d6a4b Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:05:59 +0100
|
||||
Subject: [PATCH] local-config-defconfig-motion-sensor-gpio.patch
|
||||
|
||||
---
|
||||
defconfig-2.6.24 | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 140fbfa..8b428b1 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.24-rc8
|
||||
-# Tue Jan 22 11:47:25 2008
|
||||
+# Wed Jan 23 10:00:57 2008
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
@@ -1041,8 +1041,8 @@ CONFIG_SPI_MASTER=y
|
||||
# SPI Master Controller Drivers
|
||||
#
|
||||
CONFIG_SPI_BITBANG=y
|
||||
-CONFIG_SPI_S3C24XX=y
|
||||
-# CONFIG_SPI_S3C24XX_GPIO is not set
|
||||
+# CONFIG_SPI_S3C24XX is not set
|
||||
+CONFIG_SPI_S3C24XX_GPIO=y
|
||||
|
||||
#
|
||||
# SPI Protocol Masters
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
From cdb9d4e048f43bb19bd50713b88b1594ae60abf7 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] local-config-pmu.patch
|
||||
|
||||
---
|
||||
defconfig-2.6.24 | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 8b428b1..270c4f9 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -308,7 +308,7 @@ CONFIG_BINFMT_ELF=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_LEGACY=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
-# CONFIG_PM_VERBOSE is not set
|
||||
+CONFIG_PM_VERBOSE=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_SUSPEND_UP_POSSIBLE=y
|
||||
CONFIG_SUSPEND=y
|
||||
@@ -1056,6 +1056,8 @@ CONFIG_POWER_SUPPLY_DEBUG=y
|
||||
CONFIG_PDA_POWER=y
|
||||
CONFIG_APM_POWER=y
|
||||
# CONFIG_BATTERY_DS2760 is not set
|
||||
+CONFIG_BATTERY_BQ27000_HDQ=y
|
||||
+CONFIG_GTA02_HDQ=y
|
||||
CONFIG_HWMON=y
|
||||
# CONFIG_HWMON_VID is not set
|
||||
# CONFIG_SENSORS_AD7418 is not set
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
From e2cf46fcd393bcba106d610fae6d0a56e646328b Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] local-config-ext2.patch
|
||||
|
||||
---
|
||||
defconfig-2.6.24 | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 270c4f9..833e15e 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1565,7 +1565,7 @@ CONFIG_RTC_DRV_S3C=m
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
-CONFIG_EXT2_FS=m
|
||||
+CONFIG_EXT2_FS=y
|
||||
# CONFIG_EXT2_FS_XATTR is not set
|
||||
# CONFIG_EXT2_FS_XIP is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
|
||||
index a1c92d3..aaec6e8 100644
|
||||
--- a/drivers/i2c/chips/pcf50606.c
|
||||
+++ b/drivers/i2c/chips/pcf50606.c
|
||||
@@ -72,12 +72,19 @@ static unsigned short normal_i2c[] = { 0x08, I2C_CLIENT_END };
|
||||
|
||||
I2C_CLIENT_INSMOD_1(pcf50606);
|
||||
|
||||
-#define PCF50606_F_CHG_FAST 0x00000001 /* Charger Fast allowed */
|
||||
-#define PCF50606_F_CHG_PRESENT 0x00000002 /* Charger present */
|
||||
-#define PCF50606_F_CHG_FOK 0x00000004 /* Fast OK for battery */
|
||||
-#define PCF50606_F_CHG_ERR 0x00000008 /* Charger Error */
|
||||
-#define PCF50606_F_CHG_PROT 0x00000010 /* Charger Protection */
|
||||
-#define PCF50606_F_CHG_READY 0x00000020 /* Charging completed */
|
||||
+#define PCF50606_B_CHG_FAST 0 /* Charger Fast allowed */
|
||||
+#define PCF50606_B_CHG_PRESENT 1 /* Charger present */
|
||||
+#define PCF50606_B_CHG_FOK 2 /* Fast OK for battery */
|
||||
+#define PCF50606_B_CHG_ERR 3 /* Charger Error */
|
||||
+#define PCF50606_B_CHG_PROT 4 /* Charger Protection */
|
||||
+#define PCF50606_B_CHG_READY 5 /* Charging completed */
|
||||
+
|
||||
+#define PCF50606_F_CHG_FAST (1<<PCF50606_B_CHG_FAST) /* Charger Fast allowed */
|
||||
+#define PCF50606_F_CHG_PRESENT (1<<PCF50606_B_CHG_PRESENT) /* Charger present */
|
||||
+#define PCF50606_F_CHG_FOK (1<<PCF50606_B_CHG_FOK) /* Fast OK for battery */
|
||||
+#define PCF50606_F_CHG_ERR (1<<PCF50606_B_CHG_ERR) /* Charger Error */
|
||||
+#define PCF50606_F_CHG_PROT (1<<PCF50606_B_CHG_PROT) /* Charger Protection */
|
||||
+#define PCF50606_F_CHG_READY (1<<PCF50606_B_CHG_READY) /* Charging completed */
|
||||
#define PCF50606_F_CHG_MASK 0x000000fc
|
||||
|
||||
#define PCF50606_F_PWR_PRESSED 0x00000100
|
||||
@@ -1087,12 +1094,12 @@ static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr,
|
||||
static DEVICE_ATTR(chgmode, S_IRUGO | S_IWUSR, show_chgmode, set_chgmode);
|
||||
|
||||
static const char *chgstate_names[] = {
|
||||
- [PCF50606_F_CHG_FAST] = "fast_enabled",
|
||||
- [PCF50606_F_CHG_PRESENT] = "present",
|
||||
- [PCF50606_F_CHG_FOK] = "fast_ok",
|
||||
- [PCF50606_F_CHG_ERR] = "error",
|
||||
- [PCF50606_F_CHG_PROT] = "protection",
|
||||
- [PCF50606_F_CHG_READY] = "ready",
|
||||
+ [PCF50606_B_CHG_FAST] = "fast_enabled",
|
||||
+ [PCF50606_B_CHG_PRESENT] = "present",
|
||||
+ [PCF50606_B_CHG_FOK] = "fast_ok",
|
||||
+ [PCF50606_B_CHG_ERR] = "error",
|
||||
+ [PCF50606_B_CHG_PROT] = "protection",
|
||||
+ [PCF50606_B_CHG_READY] = "ready",
|
||||
};
|
||||
|
||||
static ssize_t show_chgstate(struct device *dev, struct device_attribute *attr,
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
From 25a9f8ef682fcc215a345202defb3884c2be080f Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] bugfix-deglitch-gpio-output-enable.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index 3816ea5..e32294b 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -1258,9 +1258,9 @@ static void __init gta02_machine_init(void)
|
||||
s3c2410_gpio_setpin(GTA02_CHIP_PWD, 0);
|
||||
break;
|
||||
default:
|
||||
- s3c2410_gpio_cfgpin(GTA02_GPIO_nWLAN_RESET, S3C2410_GPIO_OUTPUT);
|
||||
/* Chip is in reset state */
|
||||
s3c2410_gpio_setpin(GTA02_GPIO_nWLAN_RESET, 0);
|
||||
+ s3c2410_gpio_cfgpin(GTA02_GPIO_nWLAN_RESET, S3C2410_GPIO_OUTPUT);
|
||||
mdelay(100);
|
||||
/* Power is up */
|
||||
s3c2410_gpio_setpin(GTA02_CHIP_PWD, 0);
|
||||
@@ -1300,8 +1300,14 @@ static void __init gta02_machine_init(void)
|
||||
s3c2410_pm_init();
|
||||
|
||||
/* Set LCD_RESET / XRES to high */
|
||||
- s3c2410_gpio_cfgpin(GTA01_GPIO_LCD_RESET, S3C2410_GPIO_OUTPUT);
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_LCD_RESET, 1);
|
||||
+ s3c2410_gpio_cfgpin(GTA01_GPIO_LCD_RESET, S3C2410_GPIO_OUTPUT);
|
||||
+
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPD12, 1);
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPD12, S3C2410_GPIO_OUTPUT);
|
||||
+
|
||||
+ s3c2410_gpio_setpin(S3C2410_GPD13, 1);
|
||||
+ s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPIO_OUTPUT);
|
||||
|
||||
/* Make sure the modem can wake us up */
|
||||
set_irq_type(GTA02_IRQ_MODEM, IRQT_RISING);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
From 60e00c0c6a69c302d73093ccaf09697f94d6e7c2 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] clean-snip-gpio-reinit.patch
|
||||
These are initialized already
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 6 ------
|
||||
1 files changed, 0 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index e32294b..f2b1b66 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -1303,12 +1303,6 @@ static void __init gta02_machine_init(void)
|
||||
s3c2410_gpio_setpin(GTA01_GPIO_LCD_RESET, 1);
|
||||
s3c2410_gpio_cfgpin(GTA01_GPIO_LCD_RESET, S3C2410_GPIO_OUTPUT);
|
||||
|
||||
- s3c2410_gpio_setpin(S3C2410_GPD12, 1);
|
||||
- s3c2410_gpio_cfgpin(S3C2410_GPD12, S3C2410_GPIO_OUTPUT);
|
||||
-
|
||||
- s3c2410_gpio_setpin(S3C2410_GPD13, 1);
|
||||
- s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPIO_OUTPUT);
|
||||
-
|
||||
/* Make sure the modem can wake us up */
|
||||
set_irq_type(GTA02_IRQ_MODEM, IRQT_RISING);
|
||||
rc = request_irq(GTA02_IRQ_MODEM, gta02_modem_irq, IRQF_DISABLED,
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
From 46f0b99a7b0e52e8dee4cdfe2e3599814f0388ed Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] introduce-fiq-hdq.patch
|
||||
|
||||
This adds a platform driver and device which performs HDQ
|
||||
battery protocol using a single GPIO pin which is set
|
||||
through platform data.
|
||||
|
||||
HDQ has some hard latency requirements which can't
|
||||
be met if interrupts are enabled, so normally using
|
||||
a GPIO for this will require blocking out all other
|
||||
interrupts and processes for several milliseconds
|
||||
per register being read or written.
|
||||
|
||||
This HDQ protocol engine is a FSM implemented inside the
|
||||
the FIQ ISR and regulated by timer interrupts happening
|
||||
at 20us intervals. The path through the FSM on any
|
||||
"clock" is very short and should be over with in ~
|
||||
1us. Because FIQ has guaranteed latencies of <1us,
|
||||
it means we can service the HDQ protocol without
|
||||
blocking interrupts or any other process other than
|
||||
the caller that is waiting for the result. It's pretty
|
||||
cool performance from 1 GPIO ;-)
|
||||
|
||||
Due to it being hard to do locking from the FIQ ISR
|
||||
the code simply sleeps 10ms or whatever the scheduler
|
||||
gives it and checks if the transfer took place yet.
|
||||
|
||||
This platform driver doesn't have any knowledge about
|
||||
the device it is talking to, it just knows it is a
|
||||
HDQ device. It exports three functions for read, write
|
||||
and confirming HDQ is initialized. It also exports two
|
||||
/sys nodes that are usable by humans, one dumps the whole
|
||||
127 register HDQ register space
|
||||
|
||||
# cat /sys/devices/platform/gta02-hdq.0/hdq/dump
|
||||
00 44 55 00 00 00 ba 04 a2 0d 50 00 00 00 00 00
|
||||
00 00 9a 1a 00 00 ff ff ff ff 29 00 00 00 80 2b
|
||||
00 00 00 00 00 00 ff ff 00 00 00 00 00 32 af 06
|
||||
a0 d8 37 4e 00 00 00 00 00 00 00 34 2e 03 b4 e7
|
||||
00 00 06 00 41 00 4c 02 00 00 00 00 00 00 00 00
|
||||
83 02 00 00 94 09 59 b9 a5 0d 7f 21 00 00 7a ff
|
||||
df ff 62 ff a7 04 2e 05 00 00 00 01 00 07 00 00
|
||||
2a 78 36 67 7b b5 1b a9 af 19 38 89 63 57 42 7c
|
||||
#
|
||||
|
||||
and the other allows to set one register
|
||||
|
||||
# echo 2 170 > /sys/devices/platform/gta02-hdq.0/hdq/write
|
||||
|
||||
writes 0xAA into register 2.
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
defconfig-2.6.24 | 1 +
|
||||
drivers/power/Kconfig | 8 ++++++++
|
||||
2 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 833e15e..6d750a5 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1825,3 +1825,4 @@ CONFIG_TEXTSEARCH_FSM=m
|
||||
CONFIG_PLIST=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
+CONFIG_GTA02_HDQ=y
|
||||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
||||
index feb8b0a..5ace872 100644
|
||||
--- a/drivers/power/Kconfig
|
||||
+++ b/drivers/power/Kconfig
|
||||
@@ -63,3 +63,11 @@ config GTA02_HDQ
|
||||
at least BATTERY_BQ27000_HDQ as well
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
+
|
||||
+config GTA02_HDQ
|
||||
+ tristate "Neo Freerunner HDQ"
|
||||
+ depends on MACH_NEO1973_GTA02 && FIQ && S3C2440_C_FIQ
|
||||
+ help
|
||||
+ Say Y to enable support for communicating with an HDQ battery
|
||||
+ on the Neo Freerunner. You probably want to select
|
||||
+ at least BATTERY_BQ27000_HDQ as well
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
From ee70eb69aca0855f8deea2d6792bca29f5f64c8d Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] introduce-bq27000-battery-driver.patch
|
||||
|
||||
This is a driver for the bq27000 found in the Highcell A5
|
||||
battery, and the platform device stuff for it for GTA02. It
|
||||
is a Power Supply Class battery device.
|
||||
|
||||
The driver doesn't contain an HDQ engine but accepts pointers
|
||||
from the platform data to the HDQ action routines; our
|
||||
platform data plugs it into the FIQ HDQ engine stuff.
|
||||
|
||||
The Power Supply class exposes the battery down /sys so you
|
||||
can find out battery status by doing the equivalent of this
|
||||
bash command
|
||||
|
||||
for i in capacity charge_full current_now present status technology temp time_to_empty_now time_to_full_now type voltage_now ; do echo -n "$i " ; cat /sys/devices/platform/bq27000-battery.0/power_supply/bat/$i ; done
|
||||
|
||||
Here is the kind of result you get from a battery discharging
|
||||
|
||||
capacity 0
|
||||
charge_full 1215585
|
||||
current_now 183375
|
||||
present 1
|
||||
status Discharging
|
||||
technology Li-ion
|
||||
temp 276
|
||||
time_to_empty_now 0
|
||||
time_to_full_now 3932100
|
||||
type Battery
|
||||
voltage_now 2761000
|
||||
|
||||
Note that temp is in 1/10 degrees C, other values are in uV,
|
||||
uA, uW. The time_to_* reported are bogus, but that is what
|
||||
the battery actually reports.
|
||||
|
||||
We can make more mappings to entries in power_supply class
|
||||
but this is enough to get started with.
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
defconfig-2.6.24 | 1 +
|
||||
drivers/power/Kconfig | 7 -------
|
||||
2 files changed, 1 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 6d750a5..9467f4b 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1826,3 +1826,4 @@ CONFIG_PLIST=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_GTA02_HDQ=y
|
||||
+CONFIG_BATTERY_BQ27000_HDQ=y
|
||||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
||||
index 5ace872..8c50ecb 100644
|
||||
--- a/drivers/power/Kconfig
|
||||
+++ b/drivers/power/Kconfig
|
||||
@@ -64,10 +64,3 @@ config GTA02_HDQ
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
|
||||
-config GTA02_HDQ
|
||||
- tristate "Neo Freerunner HDQ"
|
||||
- depends on MACH_NEO1973_GTA02 && FIQ && S3C2440_C_FIQ
|
||||
- help
|
||||
- Say Y to enable support for communicating with an HDQ battery
|
||||
- on the Neo Freerunner. You probably want to select
|
||||
- at least BATTERY_BQ27000_HDQ as well
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,452 @@
|
|||
From c6eeaaf1c19526e7ceb535663c3b8143c19b8cc7 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] debug-suspend-dump-gpio-states-add-GPA.patch
|
||||
|
||||
Add support for GPA[] GPIO bus since we have some NCs
|
||||
but they seem to output-only IO cells so no matter
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
arch/arm/plat-s3c24xx/gpio.c | 421 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 421 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
|
||||
index ee99dcc..4e94801 100644
|
||||
--- a/arch/arm/plat-s3c24xx/gpio.c
|
||||
+++ b/arch/arm/plat-s3c24xx/gpio.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
+#include <asm/arch/regs-gpioj.h>
|
||||
|
||||
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
|
||||
{
|
||||
@@ -215,3 +216,423 @@ int s3c2410_gpio_irq2pin(unsigned int irq)
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(s3c2410_gpio_irq2pin);
|
||||
+
|
||||
+static void pretty_dump(u32 cfg, u32 state, u32 pull,
|
||||
+ const char ** function_names_2,
|
||||
+ const char ** function_names_3,
|
||||
+ const char * prefix,
|
||||
+ int count)
|
||||
+{
|
||||
+ int n;
|
||||
+ const char *tag_type = NULL,
|
||||
+ *tag_state = NULL,
|
||||
+ *tag_pulldown = NULL,
|
||||
+ * level0 = "0",
|
||||
+ * level1 = "1";
|
||||
+
|
||||
+ for (n = 0; n < count; n++) {
|
||||
+ switch ((cfg >> (2 * n)) & 3) {
|
||||
+ case 0:
|
||||
+ tag_type = "input ";
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ tag_type = "OUTPUT ";
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ if (function_names_2) {
|
||||
+ if (function_names_2[n])
|
||||
+ tag_type = function_names_2[n];
|
||||
+ else
|
||||
+ tag_type = "*** ILLEGAL CFG (2) *** ";
|
||||
+ } else
|
||||
+ tag_type = "(function) ";
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (function_names_3) {
|
||||
+ if (function_names_3[n])
|
||||
+ tag_type = function_names_3[n];
|
||||
+ else
|
||||
+ tag_type = "*** ILLEGAL CFG (3) *** ";
|
||||
+ } else
|
||||
+ tag_type = "(function) ";
|
||||
+ break;
|
||||
+ }
|
||||
+ if ((state >> n) & 1)
|
||||
+ tag_state = level1;
|
||||
+ else
|
||||
+ tag_state = level0;
|
||||
+
|
||||
+ if (((pull >> n) & 1))
|
||||
+ tag_pulldown = "";
|
||||
+ else
|
||||
+ tag_pulldown = "(pulldown)";
|
||||
+
|
||||
+ printk(KERN_INFO"%s%02d: %s %s %s\n", prefix, n, tag_type,
|
||||
+ tag_state, tag_pulldown);
|
||||
+ }
|
||||
+ printk(KERN_INFO"\n");
|
||||
+}
|
||||
+
|
||||
+static void pretty_dump_a(u32 cfg, u32 state,
|
||||
+ const char ** function_names,
|
||||
+ const char * prefix,
|
||||
+ int count)
|
||||
+{
|
||||
+ int n;
|
||||
+ const char *tag_type = NULL,
|
||||
+ *tag_state = NULL,
|
||||
+ * level0 = "0",
|
||||
+ * level1 = "1";
|
||||
+
|
||||
+ for (n = 0; n < count; n++) {
|
||||
+ switch ((cfg >> n) & 1) {
|
||||
+ case 0:
|
||||
+ tag_type = "OUTPUT ";
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (function_names) {
|
||||
+ if (function_names[n])
|
||||
+ tag_type = function_names[n];
|
||||
+ else
|
||||
+ tag_type = "*** ILLEGAL CFG *** ";
|
||||
+ } else
|
||||
+ tag_type = "(function) ";
|
||||
+ break;
|
||||
+ }
|
||||
+ if ((state >> n) & 1)
|
||||
+ tag_state = level1;
|
||||
+ else
|
||||
+ tag_state = level0;
|
||||
+
|
||||
+ printk(KERN_INFO"%s%02d: %s %s\n", prefix, n, tag_type,
|
||||
+ tag_state);
|
||||
+ }
|
||||
+ printk(KERN_INFO"\n");
|
||||
+}
|
||||
+
|
||||
+static const char * funcs_a[] = {
|
||||
+ "ADDR0 ",
|
||||
+ "ADDR16 ",
|
||||
+ "ADDR17 ",
|
||||
+ "ADDR18 ",
|
||||
+ "ADDR19 ",
|
||||
+ "ADDR20 ",
|
||||
+ "ADDR21 ",
|
||||
+ "ADDR22 ",
|
||||
+ "ADDR23 ",
|
||||
+ "ADDR24 ",
|
||||
+ "ADDR25 ",
|
||||
+ "ADDR26 ",
|
||||
+ "nGCS[1] ",
|
||||
+ "nGCS[2] ",
|
||||
+ "nGCS[3] ",
|
||||
+ "nGCS[4] ",
|
||||
+ "nGCS[5] ",
|
||||
+ "CLE ",
|
||||
+ "ALE ",
|
||||
+ "nFWE ",
|
||||
+ "nFRE ",
|
||||
+ "nRSTOUT ",
|
||||
+ "nFCE ",
|
||||
+ NULL,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static const char * funcs_b2[] = {
|
||||
+ "TOUT0 ",
|
||||
+ "TOUT1 ",
|
||||
+ "TOUT2 ",
|
||||
+ "TOUT3 ",
|
||||
+ "TCLK[0] ",
|
||||
+ "nXBACK ",
|
||||
+ "nXBREQ ",
|
||||
+ "nXDACK1 ",
|
||||
+ "nXDREQ1 ",
|
||||
+ "nXDACK0 ",
|
||||
+ "nXDREQ0 ",
|
||||
+};
|
||||
+static const char * funcs_b3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const char * funcs_c2[] = {
|
||||
+ "LEND ",
|
||||
+ "VCLK ",
|
||||
+ "VLINE ",
|
||||
+ "VFRAME ",
|
||||
+ "VM ",
|
||||
+ "LCD_LPCOE ",
|
||||
+ "LCD_LPCREV ",
|
||||
+ "LCD_LPCREVB",
|
||||
+ "VD[0] ",
|
||||
+ "VD[1] ",
|
||||
+ "VD[2] ",
|
||||
+ "VD[3] ",
|
||||
+ "VD[4] ",
|
||||
+ "VD[5] ",
|
||||
+ "VD[6] ",
|
||||
+ "VD[7] ",
|
||||
+};
|
||||
+static const char * funcs_c3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ "I2SSDI ",
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const char * funcs_d2[] = {
|
||||
+ "VD[8] ",
|
||||
+ "VD[9] ",
|
||||
+ "VD[10] ",
|
||||
+ "VD[11] ",
|
||||
+ "VD[12] ",
|
||||
+ "VD[13] ",
|
||||
+ "VD[14] ",
|
||||
+ "VD[15] ",
|
||||
+ "VD[16] ",
|
||||
+ "VD[17] ",
|
||||
+ "VD[18] ",
|
||||
+ "VD[19] ",
|
||||
+ "VD[20] ",
|
||||
+ "VD[21] ",
|
||||
+ "VD[22] ",
|
||||
+ "VD[23] ",
|
||||
+};
|
||||
+static const char * funcs_d3[] = {
|
||||
+ "nSPICS1 ",
|
||||
+ "SPICLK1 ",
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ "SPIMISO1 ",
|
||||
+ "SPIMOSI1 ",
|
||||
+ "SPICLK1 ",
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ "nSS1 ",
|
||||
+ "nSS0 ",
|
||||
+};
|
||||
+
|
||||
+static const char * funcs_e2[] = {
|
||||
+ "I2SLRCK ",
|
||||
+ "I2SSCLK ",
|
||||
+ "CDCLK ",
|
||||
+ "I2SDI ",
|
||||
+ "I2SDO ",
|
||||
+ "SDCLK ",
|
||||
+ "SDCMD ",
|
||||
+ "SDDAT0 ",
|
||||
+ "SDDAT1 ",
|
||||
+ "SDDAT2 ",
|
||||
+ "SDDAT3 ",
|
||||
+ "SPIMISO0 ",
|
||||
+ "SPIMOSI0 ",
|
||||
+ "SPICLK0 ",
|
||||
+ "IICSCL ",
|
||||
+ "IICSDA ",
|
||||
+};
|
||||
+static const char * funcs_e3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const char * funcs_f2[] = {
|
||||
+ "EINT[0] ",
|
||||
+ "EINT[1] ",
|
||||
+ "EINT[2] ",
|
||||
+ "EINT[3] ",
|
||||
+ "EINT[4] ",
|
||||
+ "EINT[5] ",
|
||||
+ "EINT[6] ",
|
||||
+ "EINT[7] ",
|
||||
+};
|
||||
+static const char * funcs_f3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static const char * funcs_g2[] = {
|
||||
+ "EINT[8] ",
|
||||
+ "EINT[9] ",
|
||||
+ "EINT[10] ",
|
||||
+ "EINT[11] ",
|
||||
+ "EINT[12] ",
|
||||
+ "EINT[13] ",
|
||||
+ "EINT[14] ",
|
||||
+ "EINT[15] ",
|
||||
+ "EINT[16] ",
|
||||
+ "EINT[17] ",
|
||||
+ "EINT[18] ",
|
||||
+ "EINT[19] ",
|
||||
+ "EINT[20] ",
|
||||
+ "EINT[21] ",
|
||||
+ "EINT[22] ",
|
||||
+ "EINT[23] ",
|
||||
+};
|
||||
+static const char * funcs_g3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ "nSS0 ",
|
||||
+ "nSS1 ",
|
||||
+ "LCD_PWRDN ",
|
||||
+ "SPIMISO1 ",
|
||||
+ "SPIMOSI1 ",
|
||||
+ "SPICLK1 ",
|
||||
+ NULL,
|
||||
+ "nRTS1 ",
|
||||
+ "nCTS1 ",
|
||||
+ "TCLK[1] ",
|
||||
+ "nSPICS0 ",
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const char * funcs_h2[] = {
|
||||
+ "nCTS0 ",
|
||||
+ "nRTS0 ",
|
||||
+ "TXD[0] ",
|
||||
+ "RXD[0] ",
|
||||
+ "TXD[1] ",
|
||||
+ "RXD[1] ",
|
||||
+ "TXD[2] ",
|
||||
+ "RXD[2] ",
|
||||
+ "UEXTCLK ",
|
||||
+ "CLKOUT0 ",
|
||||
+ "CLKOUT1 ",
|
||||
+};
|
||||
+static const char * funcs_h3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ "nRTS1 ",
|
||||
+ "nCTS1 ",
|
||||
+ NULL,
|
||||
+ "nSPICS0 ",
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const char * funcs_j2[] = {
|
||||
+ "CAMDATA[0] ",
|
||||
+ "CAMDATA[1] ",
|
||||
+ "CAMDATA[2] ",
|
||||
+ "CAMDATA[3] ",
|
||||
+ "CAMDATA[4] ",
|
||||
+ "CAMDATA[5] ",
|
||||
+ "CAMDATA[6] ",
|
||||
+ "CAMDATA[7] ",
|
||||
+ "CAMPCLK ",
|
||||
+ "CAMVSYNC ",
|
||||
+ "CAMHREF ",
|
||||
+ "CAMCLKOUT ",
|
||||
+ "CAMRESET ",
|
||||
+};
|
||||
+static const char * funcs_j3[] = {
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+/* used to dump GPIO states at suspend */
|
||||
+void s3c24xx_dump_gpio_states(void)
|
||||
+{
|
||||
+ pretty_dump_a(__raw_readl(S3C2410_GPACON),
|
||||
+ __raw_readl(S3C2410_GPADAT),
|
||||
+ funcs_a, "GPA", 25);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPBCON),
|
||||
+ __raw_readl(S3C2410_GPBDAT),
|
||||
+ __raw_readl(S3C2410_GPBUP),
|
||||
+ funcs_b2, funcs_b3, "GPB", 11);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPCCON),
|
||||
+ __raw_readl(S3C2410_GPCDAT),
|
||||
+ __raw_readl(S3C2410_GPCUP),
|
||||
+ funcs_c2, funcs_c3, "GPC", 16);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPDCON),
|
||||
+ __raw_readl(S3C2410_GPDDAT),
|
||||
+ __raw_readl(S3C2410_GPDUP),
|
||||
+ funcs_d2, funcs_d3, "GPD", 16);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPECON),
|
||||
+ __raw_readl(S3C2410_GPEDAT),
|
||||
+ __raw_readl(S3C2410_GPEUP),
|
||||
+ funcs_e2, funcs_e3, "GPE", 16);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPFCON),
|
||||
+ __raw_readl(S3C2410_GPFDAT),
|
||||
+ __raw_readl(S3C2410_GPFUP),
|
||||
+ funcs_f2, funcs_f3, "GPF", 8);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPGCON),
|
||||
+ __raw_readl(S3C2410_GPGDAT),
|
||||
+ __raw_readl(S3C2410_GPGUP),
|
||||
+ funcs_g2, funcs_g3, "GPG", 16);
|
||||
+ pretty_dump(__raw_readl(S3C2410_GPHCON),
|
||||
+ __raw_readl(S3C2410_GPHDAT),
|
||||
+ __raw_readl(S3C2410_GPHUP),
|
||||
+ funcs_h2, funcs_h3, "GPH", 11);
|
||||
+ pretty_dump(__raw_readl(S3C2440_GPJCON),
|
||||
+ __raw_readl(S3C2440_GPJDAT),
|
||||
+ __raw_readl(S3C2440_GPJUP),
|
||||
+ funcs_j2, funcs_j3, "GPJ", 13);
|
||||
+
|
||||
+}
|
||||
+EXPORT_SYMBOL(s3c24xx_dump_gpio_states);
|
||||
+
|
||||
--
|
||||
1.5.6.3
|
||||
|
128
target/linux/s3c24xx/patches/0080-fix-s3c2410_timer_setup-resume-BUG.patch.patch
Executable file
128
target/linux/s3c24xx/patches/0080-fix-s3c2410_timer_setup-resume-BUG.patch.patch
Executable file
|
@ -0,0 +1,128 @@
|
|||
From 1da7d81ddc35e3527d10abbc411bc09c81340d70 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:00 +0100
|
||||
Subject: [PATCH] fix-s3c2410_timer_setup-resume-BUG.patch
|
||||
|
||||
---
|
||||
arch/arm/plat-s3c24xx/time.c | 33 +++++++++++++++++++++++++++++++++
|
||||
drivers/i2c/chips/pcf50633.c | 9 +++++++--
|
||||
2 files changed, 40 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
|
||||
index f8d307b..59e5382 100644
|
||||
--- a/arch/arm/plat-s3c24xx/time.c
|
||||
+++ b/arch/arm/plat-s3c24xx/time.c
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
static unsigned long timer_startval;
|
||||
static unsigned long timer_usec_ticks;
|
||||
+static struct work_struct resume_work;
|
||||
|
||||
#define TIMER_USEC_SHIFT 16
|
||||
|
||||
@@ -199,9 +200,12 @@ static void s3c2410_timer_setup (void)
|
||||
|
||||
pclk = clk_get_rate(clk);
|
||||
|
||||
+ printk("pclk = %d\n", pclk);
|
||||
+
|
||||
/* configure clock tick */
|
||||
|
||||
timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
|
||||
+ printk("timer_usec_ticks = %d\n", timer_usec_ticks);
|
||||
|
||||
tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
|
||||
tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
|
||||
@@ -210,6 +214,11 @@ static void s3c2410_timer_setup (void)
|
||||
tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
|
||||
|
||||
tcnt = (pclk / 6) / HZ;
|
||||
+
|
||||
+ /* start the timer running */
|
||||
+ tcon |= S3C2410_TCON_T4START | S3C2410_TCON_T4RELOAD;
|
||||
+ tcon &= ~S3C2410_TCON_T4MANUALUPD;
|
||||
+ __raw_writel(tcon, S3C2410_TCON);
|
||||
}
|
||||
|
||||
/* timers reload after counting zero, so reduce the count by 1 */
|
||||
@@ -245,10 +254,34 @@ static void s3c2410_timer_setup (void)
|
||||
tcon |= S3C2410_TCON_T4START;
|
||||
tcon &= ~S3C2410_TCON_T4MANUALUPD;
|
||||
__raw_writel(tcon, S3C2410_TCON);
|
||||
+
|
||||
+ __raw_writel(__raw_readl(S3C2410_INTMSK) & (~(1UL << 14)),
|
||||
+ S3C2410_INTMSK);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void timer_resume_work(struct work_struct *work)
|
||||
+{
|
||||
+ s3c2410_timer_setup();
|
||||
+}
|
||||
+
|
||||
+/* ooh a nasty situation arises if we try to call s3c2410_timer_setup() from
|
||||
+ * the resume handler. It is called in atomic context but the clock APIs
|
||||
+ * try to lock a mutex which may sleep. We are in a bit of an unusual
|
||||
+ * situation because we don't have a tick source right now, but it should be
|
||||
+ * okay to try to schedule a work item... hopefully
|
||||
+ */
|
||||
+
|
||||
+static void s3c2410_timer_resume_atomic(void)
|
||||
+{
|
||||
+ int ret = schedule_work(&resume_work);
|
||||
+ if (!ret)
|
||||
+ printk(KERN_INFO"Failed to schedule_work tick ctr (%d)\n", ret);
|
||||
}
|
||||
|
||||
static void __init s3c2410_timer_init (void)
|
||||
{
|
||||
+ INIT_WORK(&resume_work, timer_resume_work);
|
||||
s3c2410_timer_setup();
|
||||
setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
|
||||
}
|
||||
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||||
index e23c540..91b9ac3 100644
|
||||
--- a/drivers/i2c/chips/pcf50633.c
|
||||
+++ b/drivers/i2c/chips/pcf50633.c
|
||||
@@ -1926,9 +1926,11 @@ static int pcf50633_resume(struct device *dev)
|
||||
struct pcf50633_data *pcf = i2c_get_clientdata(client);
|
||||
int i;
|
||||
|
||||
- mutex_lock(&pcf->lock);
|
||||
+ printk(KERN_INFO"a\n");
|
||||
+ /* mutex_lock(&pcf->lock); */ /* resume in atomic context */
|
||||
|
||||
__reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
|
||||
+ printk(KERN_INFO"b\n");
|
||||
|
||||
/* Resume all saved registers that don't "survive" standby state */
|
||||
__reg_write(pcf, PCF50633_REG_INT1M, pcf->standby_regs.int1m);
|
||||
@@ -1936,6 +1938,7 @@ static int pcf50633_resume(struct device *dev)
|
||||
__reg_write(pcf, PCF50633_REG_INT3M, pcf->standby_regs.int3m);
|
||||
__reg_write(pcf, PCF50633_REG_INT4M, pcf->standby_regs.int4m);
|
||||
__reg_write(pcf, PCF50633_REG_INT5M, pcf->standby_regs.int5m);
|
||||
+ printk(KERN_INFO"c\n");
|
||||
|
||||
__reg_write(pcf, PCF50633_REG_OOCTIM2, pcf->standby_regs.ooctim2);
|
||||
__reg_write(pcf, PCF50633_REG_AUTOOUT, pcf->standby_regs.autoout);
|
||||
@@ -1949,14 +1952,16 @@ static int pcf50633_resume(struct device *dev)
|
||||
__reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
|
||||
__reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
|
||||
__reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
|
||||
+ printk(KERN_INFO"d\n");
|
||||
/* FIXME: one big read? */
|
||||
for (i = 0; i < 7; i++) {
|
||||
u_int8_t reg_out = PCF50633_REG_LDO1OUT + 2*i;
|
||||
__reg_write(pcf, reg_out, pcf->standby_regs.ldo[i].out);
|
||||
__reg_write(pcf, reg_out+1, pcf->standby_regs.ldo[i].ena);
|
||||
}
|
||||
+ printk(KERN_INFO"e\n");
|
||||
|
||||
- mutex_unlock(&pcf->lock);
|
||||
+ /* mutex_unlock(&pcf->lock); */ /* resume in atomic context */
|
||||
|
||||
pcf50633_irq(pcf->irq, pcf);
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
From eb890d62a201337536f18f8d2ea44df744155552 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] config-add-alsa.patch
|
||||
|
||||
---
|
||||
defconfig-2.6.24 | 34 +++++++++++++++++-----------------
|
||||
1 files changed, 17 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
|
||||
index 9467f4b..e57081a 100644
|
||||
--- a/defconfig-2.6.24
|
||||
+++ b/defconfig-2.6.24
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
-# Linux kernel version: 2.6.24-rc8
|
||||
-# Wed Jan 23 10:00:57 2008
|
||||
+# Linux kernel version: 2.6.24
|
||||
+# Fri Feb 22 22:38:48 2008
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
@@ -22,6 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_ZONE_DMA=y
|
||||
+CONFIG_FIQ=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
@@ -44,7 +45,7 @@ CONFIG_SYSVIPC_SYSCTL=y
|
||||
# CONFIG_PID_NS is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
-CONFIG_LOG_BUF_SHIFT=14
|
||||
+CONFIG_LOG_BUF_SHIFT=16
|
||||
# CONFIG_CGROUPS is not set
|
||||
CONFIG_FAIR_GROUP_SCHED=y
|
||||
CONFIG_FAIR_USER_SCHED=y
|
||||
@@ -195,6 +196,7 @@ CONFIG_MACH_NEO1973_GTA01=y
|
||||
# CONFIG_MACH_VSTMS is not set
|
||||
CONFIG_CPU_S3C2440=y
|
||||
CONFIG_S3C2440_DMA=y
|
||||
+CONFIG_S3C2440_C_FIQ=y
|
||||
|
||||
#
|
||||
# S3C2440 Machines
|
||||
@@ -1221,15 +1223,15 @@ CONFIG_SOUND=y
|
||||
#
|
||||
# Advanced Linux Sound Architecture
|
||||
#
|
||||
-CONFIG_SND=m
|
||||
-CONFIG_SND_TIMER=m
|
||||
-CONFIG_SND_PCM=m
|
||||
-CONFIG_SND_HWDEP=m
|
||||
-CONFIG_SND_RAWMIDI=m
|
||||
+CONFIG_SND=y
|
||||
+CONFIG_SND_TIMER=y
|
||||
+CONFIG_SND_PCM=y
|
||||
+CONFIG_SND_HWDEP=y
|
||||
+CONFIG_SND_RAWMIDI=y
|
||||
# CONFIG_SND_SEQUENCER is not set
|
||||
CONFIG_SND_OSSEMUL=y
|
||||
-CONFIG_SND_MIXER_OSS=m
|
||||
-CONFIG_SND_PCM_OSS=m
|
||||
+CONFIG_SND_MIXER_OSS=y
|
||||
+CONFIG_SND_PCM_OSS=y
|
||||
CONFIG_SND_PCM_OSS_PLUGINS=y
|
||||
# CONFIG_SND_DYNAMIC_MINORS is not set
|
||||
CONFIG_SND_SUPPORT_OLD_API=y
|
||||
@@ -1262,11 +1264,11 @@ CONFIG_SND_USB_AUDIO=m
|
||||
#
|
||||
# System on Chip audio support
|
||||
#
|
||||
-CONFIG_SND_SOC=m
|
||||
-CONFIG_SND_S3C24XX_SOC=m
|
||||
-CONFIG_SND_S3C24XX_SOC_I2S=m
|
||||
-CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=m
|
||||
-CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753=m
|
||||
+CONFIG_SND_SOC=y
|
||||
+CONFIG_SND_S3C24XX_SOC=y
|
||||
+CONFIG_SND_S3C24XX_SOC_I2S=y
|
||||
+CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=y
|
||||
+CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753=y
|
||||
|
||||
#
|
||||
# SoC Audio support for SuperH
|
||||
@@ -1825,5 +1827,3 @@ CONFIG_TEXTSEARCH_FSM=m
|
||||
CONFIG_PLIST=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
-CONFIG_GTA02_HDQ=y
|
||||
-CONFIG_BATTERY_BQ27000_HDQ=y
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
From adeb466de3bb306dc68468c64be3ebc61960d788 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] fix-glamo-mci-defeat-ops-during-suspend.patch
|
||||
|
||||
We need to be able to use the config option CONFIG_MMC_UNSAFE_RESUME that allows the rootfs
|
||||
to live on SD. But when we use this, it tries to send a reset command to the SD card during
|
||||
suspend -- and unfortunately many things like Power have suspended by then.
|
||||
|
||||
This patch again rejects IO on the MMC device during suspend of the MMC device, and it
|
||||
gives the result the rootfs on SD card works okay.
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
drivers/mfd/glamo/glamo-mci.c | 14 ++++++++++++++
|
||||
drivers/mfd/glamo/glamo-mci.h | 2 ++
|
||||
2 files changed, 16 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
|
||||
index f559e5e..bbbbe4d 100644
|
||||
--- a/drivers/mfd/glamo/glamo-mci.c
|
||||
+++ b/drivers/mfd/glamo/glamo-mci.c
|
||||
@@ -406,6 +406,14 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
|
||||
u16 status;
|
||||
int n;
|
||||
|
||||
+ if (host->suspending) {
|
||||
+ cmd->error = -EIO;
|
||||
+ if (cmd->data)
|
||||
+ cmd->data->error = -EIO;
|
||||
+ mmc_request_done(mmc, mrq);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
host->ccnt++;
|
||||
/*
|
||||
* somehow 2.6.24 MCI manages to issue MMC_WRITE_BLOCK *without* the
|
||||
@@ -792,6 +800,9 @@ static int glamo_mci_remove(struct platform_device *pdev)
|
||||
static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
struct mmc_host *mmc = platform_get_drvdata(dev);
|
||||
+ struct glamo_mci_host *host = mmc_priv(mmc);
|
||||
+
|
||||
+ host->suspending++;
|
||||
|
||||
return mmc_suspend_host(mmc, state);
|
||||
}
|
||||
@@ -799,6 +810,9 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int glamo_mci_resume(struct platform_device *dev)
|
||||
{
|
||||
struct mmc_host *mmc = platform_get_drvdata(dev);
|
||||
+ struct glamo_mci_host *host = mmc_priv(mmc);
|
||||
+
|
||||
+ host->suspending--;
|
||||
|
||||
return mmc_resume_host(mmc);
|
||||
}
|
||||
diff --git a/drivers/mfd/glamo/glamo-mci.h b/drivers/mfd/glamo/glamo-mci.h
|
||||
index 40c3e24..55852e7 100644
|
||||
--- a/drivers/mfd/glamo/glamo-mci.h
|
||||
+++ b/drivers/mfd/glamo/glamo-mci.h
|
||||
@@ -34,6 +34,8 @@ struct glamo_mci_host {
|
||||
int dma;
|
||||
int data_max_size;
|
||||
|
||||
+ int suspending;
|
||||
+
|
||||
int power_mode_current;
|
||||
unsigned int vdd_current;
|
||||
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
From 3d71204efba10914e339b411471877b81cf1e5d9 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] fix-lcm-reinit-post-resume.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 12 +++++++++
|
||||
drivers/mfd/glamo/glamo-core.c | 15 ++++++++++-
|
||||
drivers/mfd/glamo/glamo-spi-gpio.c | 38 ++++++++++++++++++++++++++--
|
||||
drivers/video/display/jbt6k74.c | 47 ++++++++++++++++++++++++++++++++----
|
||||
include/linux/glamofb.h | 1 +
|
||||
include/linux/jbt6k74.h | 8 ++++++
|
||||
6 files changed, 111 insertions(+), 10 deletions(-)
|
||||
create mode 100644 include/linux/jbt6k74.h
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index f2b1b66..750fd97 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -76,6 +76,7 @@
|
||||
#include <asm/plat-s3c24xx/cpu.h>
|
||||
#include <asm/plat-s3c24xx/pm.h>
|
||||
#include <asm/plat-s3c24xx/udc.h>
|
||||
+#include <linux/jbt6k74.h>
|
||||
|
||||
#include <linux/glamofb.h>
|
||||
|
||||
@@ -756,10 +757,21 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = {
|
||||
|
||||
/* SPI: LCM control interface attached to Glamo3362 */
|
||||
|
||||
+void gta02_jbt6k74_reset(int devidx, int level)
|
||||
+{
|
||||
+ glamo_lcm_reset(level);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+const struct jbt6k74_platform_data jbt6k74_pdata = {
|
||||
+ .reset = gta02_jbt6k74_reset,
|
||||
+};
|
||||
+
|
||||
static struct spi_board_info gta02_spi_board_info[] = {
|
||||
{
|
||||
.modalias = "jbt6k74",
|
||||
/* platform_data */
|
||||
+ .platform_data = &jbt6k74_pdata,
|
||||
/* controller_data */
|
||||
/* irq */
|
||||
.max_speed_hz = 10 * 1000 * 1000,
|
||||
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
|
||||
index ffa4945..2076e61 100644
|
||||
--- a/drivers/mfd/glamo/glamo-core.c
|
||||
+++ b/drivers/mfd/glamo/glamo-core.c
|
||||
@@ -513,6 +513,17 @@ void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(glamo_engine_reset);
|
||||
|
||||
+void glamo_lcm_reset(int level)
|
||||
+{
|
||||
+ if (!glamo_handle)
|
||||
+ return;
|
||||
+
|
||||
+ glamo_gpio_setpin(glamo_handle, GLAMO_GPIO4, level);
|
||||
+ glamo_gpio_cfgpin(glamo_handle, GLAMO_GPIO4_OUTPUT);
|
||||
+
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(glamo_lcm_reset);
|
||||
+
|
||||
enum glamo_pll {
|
||||
GLAMO_PLL1,
|
||||
GLAMO_PLL2,
|
||||
@@ -1142,8 +1153,8 @@ static int glamo_resume(struct platform_device *pdev)
|
||||
static struct platform_driver glamo_driver = {
|
||||
.probe = glamo_probe,
|
||||
.remove = glamo_remove,
|
||||
- .suspend = glamo_suspend,
|
||||
- .resume = glamo_resume,
|
||||
+ .suspend_late = glamo_suspend,
|
||||
+ .resume_early = glamo_resume,
|
||||
.driver = {
|
||||
.name = "glamo3362",
|
||||
.owner = THIS_MODULE,
|
||||
diff --git a/drivers/mfd/glamo/glamo-spi-gpio.c b/drivers/mfd/glamo/glamo-spi-gpio.c
|
||||
index 73926bd..eda7322 100644
|
||||
--- a/drivers/mfd/glamo/glamo-spi-gpio.c
|
||||
+++ b/drivers/mfd/glamo/glamo-spi-gpio.c
|
||||
@@ -224,14 +224,46 @@ static int glamo_spigpio_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define glamo_spigpio_suspend NULL
|
||||
+/*#define glamo_spigpio_suspend NULL
|
||||
#define glamo_spigpio_resume NULL
|
||||
+*/
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int glamo_spigpio_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int glamo_spigpio_resume(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct glamo_spigpio *sp = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (!sp)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* set state of spi pins */
|
||||
+ glamo_gpio_setpin(sp->glamo, sp->info->pin_clk, 0);
|
||||
+ glamo_gpio_setpin(sp->glamo, sp->info->pin_mosi, 0);
|
||||
+ glamo_gpio_setpin(sp->glamo, sp->info->pin_cs, 1);
|
||||
+
|
||||
+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_clk);
|
||||
+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_mosi);
|
||||
+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_cs);
|
||||
+ if (sp->info->pin_miso)
|
||||
+ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_miso);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static struct platform_driver glamo_spi_drv = {
|
||||
.probe = glamo_spigpio_probe,
|
||||
.remove = glamo_spigpio_remove,
|
||||
- .suspend = glamo_spigpio_suspend,
|
||||
- .resume = glamo_spigpio_resume,
|
||||
+#ifdef CONFIG_PM
|
||||
+ .suspend_late = glamo_spigpio_suspend,
|
||||
+ .resume_early = glamo_spigpio_resume,
|
||||
+#endif
|
||||
.driver = {
|
||||
.name = "glamo-spi-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
|
||||
index d021d7e..d7e9442 100644
|
||||
--- a/drivers/video/display/jbt6k74.c
|
||||
+++ b/drivers/video/display/jbt6k74.c
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+#include <linux/jbt6k74.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
@@ -114,11 +116,15 @@ struct jbt_info {
|
||||
struct mutex lock; /* protects tx_buf and reg_cache */
|
||||
u16 tx_buf[8];
|
||||
u16 reg_cache[0xEE];
|
||||
+ struct work_struct work;
|
||||
};
|
||||
|
||||
#define JBT_COMMAND 0x000
|
||||
#define JBT_DATA 0x100
|
||||
|
||||
+static void jbt_resume_work(struct work_struct *work);
|
||||
+
|
||||
+
|
||||
static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg)
|
||||
{
|
||||
int rc;
|
||||
@@ -130,6 +136,9 @@ static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg)
|
||||
1*sizeof(u16));
|
||||
if (rc == 0)
|
||||
jbt->reg_cache[reg] = 0;
|
||||
+ else
|
||||
+ printk(KERN_ERR"jbt_reg_write_nodata spi_write ret %d\n",
|
||||
+ rc);
|
||||
|
||||
mutex_unlock(&jbt->lock);
|
||||
|
||||
@@ -149,6 +158,8 @@ static int jbt_reg_write(struct jbt_info *jbt, u8 reg, u8 data)
|
||||
2*sizeof(u16));
|
||||
if (rc == 0)
|
||||
jbt->reg_cache[reg] = data;
|
||||
+ else
|
||||
+ printk(KERN_ERR"jbt_reg_write spi_write ret %d\n", rc);
|
||||
|
||||
mutex_unlock(&jbt->lock);
|
||||
|
||||
@@ -169,6 +180,8 @@ static int jbt_reg_write16(struct jbt_info *jbt, u8 reg, u16 data)
|
||||
3*sizeof(u16));
|
||||
if (rc == 0)
|
||||
jbt->reg_cache[reg] = data;
|
||||
+ else
|
||||
+ printk(KERN_ERR"jbt_reg_write16 spi_write ret %d\n", rc);
|
||||
|
||||
mutex_unlock(&jbt->lock);
|
||||
|
||||
@@ -563,6 +576,8 @@ static int __devinit jbt_probe(struct spi_device *spi)
|
||||
if (!jbt)
|
||||
return -ENOMEM;
|
||||
|
||||
+ INIT_WORK(&jbt->work, jbt_resume_work);
|
||||
+
|
||||
jbt->spi_dev = spi;
|
||||
jbt->state = JBT_STATE_DEEP_STANDBY;
|
||||
mutex_init(&jbt->lock);
|
||||
@@ -618,28 +633,50 @@ static int __devexit jbt_remove(struct spi_device *spi)
|
||||
static int jbt_suspend(struct spi_device *spi, pm_message_t state)
|
||||
{
|
||||
struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||||
+ struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
|
||||
|
||||
/* Save mode for resume */
|
||||
jbt->last_state = jbt->state;
|
||||
jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
||||
|
||||
+ (jbt6k74_pdata->reset)(0, 0);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int jbt_resume(struct spi_device *spi)
|
||||
+static void jbt_resume_work(struct work_struct *work)
|
||||
{
|
||||
- struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||||
+ struct jbt_info *jbt = container_of(work, struct jbt_info, work);
|
||||
+
|
||||
+ printk(KERN_INFO"jbt_resume_work waiting...\n");
|
||||
+ msleep(2000);
|
||||
+ printk(KERN_INFO"jbt_resume_work GO...\n");
|
||||
|
||||
- jbt6k74_enter_state(jbt, jbt->last_state);
|
||||
+ jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
|
||||
+ msleep(100);
|
||||
|
||||
switch (jbt->last_state) {
|
||||
- case JBT_STATE_NORMAL:
|
||||
case JBT_STATE_QVGA_NORMAL:
|
||||
- jbt6k74_display_onoff(jbt, 1);
|
||||
+ jbt6k74_enter_state(jbt, JBT_STATE_QVGA_NORMAL);
|
||||
break;
|
||||
default:
|
||||
+ jbt6k74_enter_state(jbt, JBT_STATE_NORMAL);
|
||||
break;
|
||||
}
|
||||
+ jbt6k74_display_onoff(jbt, 1);
|
||||
+
|
||||
+ printk(KERN_INFO"jbt_resume_work done...\n");
|
||||
+}
|
||||
+
|
||||
+static int jbt_resume(struct spi_device *spi)
|
||||
+{
|
||||
+ struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
|
||||
+ struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
|
||||
+
|
||||
+ (jbt6k74_pdata->reset)(0, 1);
|
||||
+
|
||||
+ if (!schedule_work(&jbt->work))
|
||||
+ dev_err(&spi->dev, "Unable to schedule LCM wakeup work\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h
|
||||
index 24742a2..75eefef 100644
|
||||
--- a/include/linux/glamofb.h
|
||||
+++ b/include/linux/glamofb.h
|
||||
@@ -35,5 +35,6 @@ struct glamofb_platform_data {
|
||||
|
||||
void glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
|
||||
int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val);
|
||||
+void glamo_lcm_reset(int level);
|
||||
|
||||
#endif
|
||||
diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h
|
||||
new file mode 100644
|
||||
index 0000000..3fbe178
|
||||
--- /dev/null
|
||||
+++ b/include/linux/jbt6k74.h
|
||||
@@ -0,0 +1,8 @@
|
||||
+#ifndef __JBT6K74_H__
|
||||
+#define __JBT6K74_H__
|
||||
+
|
||||
+struct jbt6k74_platform_data {
|
||||
+ void (* reset)(int devindex, int level);
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
From f26eee35ae154c2be8a6e23f3e6a45f01f50f7a7 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] fix-glamo-mci-fake-reset-opcode-in-suspend.patch
|
||||
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 4 ++--
|
||||
drivers/mfd/glamo/glamo-core.c | 16 +++++++++-------
|
||||
drivers/mfd/glamo/glamo-mci.c | 29 +++++++++++++++++++++--------
|
||||
3 files changed, 32 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index 750fd97..f18c8fd 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -1281,6 +1281,8 @@ static void __init gta02_machine_init(void)
|
||||
s3c2410_gpio_setpin(GTA02_GPIO_nWLAN_RESET, 1);
|
||||
break;
|
||||
}
|
||||
+ mangle_glamo_res_by_system_rev();
|
||||
+ platform_device_register(>a02_glamo_dev);
|
||||
|
||||
platform_device_register(&s3c_device_spi_acc);
|
||||
platform_device_register(>a01_button_dev);
|
||||
@@ -1291,8 +1293,6 @@ static void __init gta02_machine_init(void)
|
||||
platform_device_register(>a01_led_dev);
|
||||
platform_device_register(>a02_led_dev);
|
||||
|
||||
- mangle_glamo_res_by_system_rev();
|
||||
- platform_device_register(>a02_glamo_dev);
|
||||
|
||||
platform_device_register(>a02_sdio_dev);
|
||||
|
||||
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
|
||||
index 2076e61..4d8e47f 100644
|
||||
--- a/drivers/mfd/glamo/glamo-core.c
|
||||
+++ b/drivers/mfd/glamo/glamo-core.c
|
||||
@@ -822,6 +822,8 @@ static void glamo_power(struct glamo_core *glamo,
|
||||
{
|
||||
spin_lock(&glamo->lock);
|
||||
|
||||
+ dev_dbg(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state);
|
||||
+
|
||||
switch (new_state) {
|
||||
case GLAMO_POWER_ON:
|
||||
/* power up PLL1 and PLL2 */
|
||||
@@ -1026,13 +1028,6 @@ static int __init glamo_probe(struct platform_device *pdev)
|
||||
glamo_mci_def_pdata.glamo_irq_is_wired =
|
||||
glamo->pdata->glamo_irq_is_wired;
|
||||
|
||||
- glamo_mmc_dev.dev.parent = &pdev->dev;
|
||||
- /* we need it later to give to the engine enable and disable */
|
||||
- glamo_mci_def_pdata.pglamo = glamo;
|
||||
- mangle_mem_resources(glamo_mmc_dev.resource,
|
||||
- glamo_mmc_dev.num_resources, glamo->mem);
|
||||
- platform_device_register(&glamo_mmc_dev);
|
||||
-
|
||||
glamo_2d_dev.dev.parent = &pdev->dev;
|
||||
mangle_mem_resources(glamo_2d_dev.resource,
|
||||
glamo_2d_dev.num_resources, glamo->mem);
|
||||
@@ -1065,6 +1060,13 @@ static int __init glamo_probe(struct platform_device *pdev)
|
||||
glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
|
||||
platform_device_register(&glamo_spigpio_dev);
|
||||
|
||||
+ glamo_mmc_dev.dev.parent = &pdev->dev;
|
||||
+ /* we need it later to give to the engine enable and disable */
|
||||
+ glamo_mci_def_pdata.pglamo = glamo;
|
||||
+ mangle_mem_resources(glamo_mmc_dev.resource,
|
||||
+ glamo_mmc_dev.num_resources, glamo->mem);
|
||||
+ platform_device_register(&glamo_mmc_dev);
|
||||
+
|
||||
/* only request the generic, hostbus and memory controller MMIO */
|
||||
glamo->mem = request_mem_region(glamo->mem->start,
|
||||
GLAMO_REGOFS_VIDCAP, "glamo-core");
|
||||
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
|
||||
index bbbbe4d..d8847c5 100644
|
||||
--- a/drivers/mfd/glamo/glamo-mci.c
|
||||
+++ b/drivers/mfd/glamo/glamo-mci.c
|
||||
@@ -405,11 +405,11 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
|
||||
u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1);
|
||||
u16 status;
|
||||
int n;
|
||||
+ int timeout = 100000000;
|
||||
|
||||
if (host->suspending) {
|
||||
- cmd->error = -EIO;
|
||||
- if (cmd->data)
|
||||
- cmd->data->error = -EIO;
|
||||
+ dev_err(&host->pdev->dev, "faking cmd %d "
|
||||
+ "during suspend\n", cmd->opcode);
|
||||
mmc_request_done(mmc, mrq);
|
||||
return;
|
||||
}
|
||||
@@ -502,10 +502,23 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
|
||||
* our own INT# line"
|
||||
*/
|
||||
if (!glamo_mci_def_pdata.pglamo->irq_works) {
|
||||
- /* we have faith we will get an "interrupt"... */
|
||||
- while (!(readw_dly(glamo_mci_def_pdata.pglamo->base +
|
||||
- GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC))
|
||||
+ /*
|
||||
+ * we have faith we will get an "interrupt"...
|
||||
+ * but something insane like suspend problems can mean
|
||||
+ * we spin here forever, so we timeout after a LONG time
|
||||
+ */
|
||||
+ while ((!(readw_dly(glamo_mci_def_pdata.pglamo->base +
|
||||
+ GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC)) &&
|
||||
+ (timeout--))
|
||||
;
|
||||
+
|
||||
+ if (timeout < 0) {
|
||||
+ if (cmd->data->error)
|
||||
+ cmd->data->error = -ETIMEDOUT;
|
||||
+ dev_err(&host->pdev->dev, "Payload timeout\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* yay we are an interrupt controller! -- call the ISR */
|
||||
glamo_mci_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC),
|
||||
irq_desc + IRQ_GLAMO(GLAMO_IRQIDX_MMC));
|
||||
@@ -529,6 +542,7 @@ static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
|
||||
static void glamo_mci_reset(struct glamo_mci_host *host)
|
||||
{
|
||||
+ dev_dbg(&host->pdev->dev, "******* glamo_mci_reset\n");
|
||||
/* reset MMC controller */
|
||||
writew_dly(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK |
|
||||
GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
|
||||
@@ -803,8 +817,7 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
|
||||
struct glamo_mci_host *host = mmc_priv(mmc);
|
||||
|
||||
host->suspending++;
|
||||
-
|
||||
- return mmc_suspend_host(mmc, state);
|
||||
+ return mmc_suspend_host(mmc, state);
|
||||
}
|
||||
|
||||
static int glamo_mci_resume(struct platform_device *dev)
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 39f011b7788caa6800c5779eeb51f1877de9cfc4 Mon Sep 17 00:00:00 2001
|
||||
From: Willie <willie_chen@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] use gpio control leds
|
||||
|
||||
---
|
||||
drivers/leds/leds-neo1973-gta02.c | 9 ++++-----
|
||||
1 files changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/leds/leds-neo1973-gta02.c b/drivers/leds/leds-neo1973-gta02.c
|
||||
index bf1d540..e442e48 100644
|
||||
--- a/drivers/leds/leds-neo1973-gta02.c
|
||||
+++ b/drivers/leds/leds-neo1973-gta02.c
|
||||
@@ -127,22 +127,22 @@ static int __init gta02led_probe(struct platform_device *pdev)
|
||||
|
||||
switch (lp->gpio) {
|
||||
case S3C2410_GPB0:
|
||||
- lp->has_pwm = 1;
|
||||
+ lp->has_pwm = 0;
|
||||
lp->pwm.timerid = PWM0;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB0_TOUT0);
|
||||
break;
|
||||
case S3C2410_GPB1:
|
||||
- lp->has_pwm = 1;
|
||||
+ lp->has_pwm = 0;
|
||||
lp->pwm.timerid = PWM1;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB1_TOUT1);
|
||||
break;
|
||||
case S3C2410_GPB2:
|
||||
- lp->has_pwm = 1;
|
||||
+ lp->has_pwm = 0;
|
||||
lp->pwm.timerid = PWM2;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB2_TOUT2);
|
||||
break;
|
||||
case S3C2410_GPB3:
|
||||
- lp->has_pwm = 1;
|
||||
+ lp->has_pwm = 0;
|
||||
lp->pwm.timerid = PWM3;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB3_TOUT3);
|
||||
break;
|
||||
@@ -167,7 +167,6 @@ static int __init gta02led_probe(struct platform_device *pdev)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
- }
|
||||
|
||||
mutex_init(&lp->mutex);
|
||||
rc = led_classdev_register(&pdev->dev, &lp->cdev);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From 3488a253e7a20d491d180313340f39cf6fd043a9 Mon Sep 17 00:00:00 2001
|
||||
From: warmcat <andy@warmcat.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] fix-gpio-led-patch-still-pwm-t3.patch
|
||||
|
||||
Starting up all the PWMs seems to be needed for PWM3 operation
|
||||
and FIQ / HDQ / VIB operation. But after starting, turn the
|
||||
LEDs to GPIO-only.
|
||||
|
||||
Applies on top of Willie's patch
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
drivers/leds/leds-neo1973-gta02.c | 9 +++++----
|
||||
1 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/leds/leds-neo1973-gta02.c b/drivers/leds/leds-neo1973-gta02.c
|
||||
index e442e48..bf1d540 100644
|
||||
--- a/drivers/leds/leds-neo1973-gta02.c
|
||||
+++ b/drivers/leds/leds-neo1973-gta02.c
|
||||
@@ -127,22 +127,22 @@ static int __init gta02led_probe(struct platform_device *pdev)
|
||||
|
||||
switch (lp->gpio) {
|
||||
case S3C2410_GPB0:
|
||||
- lp->has_pwm = 0;
|
||||
+ lp->has_pwm = 1;
|
||||
lp->pwm.timerid = PWM0;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB0_TOUT0);
|
||||
break;
|
||||
case S3C2410_GPB1:
|
||||
- lp->has_pwm = 0;
|
||||
+ lp->has_pwm = 1;
|
||||
lp->pwm.timerid = PWM1;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB1_TOUT1);
|
||||
break;
|
||||
case S3C2410_GPB2:
|
||||
- lp->has_pwm = 0;
|
||||
+ lp->has_pwm = 1;
|
||||
lp->pwm.timerid = PWM2;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB2_TOUT2);
|
||||
break;
|
||||
case S3C2410_GPB3:
|
||||
- lp->has_pwm = 0;
|
||||
+ lp->has_pwm = 1;
|
||||
lp->pwm.timerid = PWM3;
|
||||
s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPB3_TOUT3);
|
||||
break;
|
||||
@@ -167,6 +167,7 @@ static int __init gta02led_probe(struct platform_device *pdev)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
+ }
|
||||
|
||||
mutex_init(&lp->mutex);
|
||||
rc = led_classdev_register(&pdev->dev, &lp->cdev);
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
From a2f39c5197fbea18417722e5c7d362eaa3bc6210 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] introduce-usb-host-power-control.patch
|
||||
|
||||
Unless I really really missed the point, there is no support for enabling
|
||||
USB Host power for USB host mode. This patch adds a /sys node for GTA02
|
||||
that allows control of the charge pump for 5V out on the USB mini connector
|
||||
It doesn't change any logical mode in the CPU, just enables (1) and disables
|
||||
(0) USB host power.
|
||||
|
||||
# cat /sys/devices/platform/neo1973-pm-host.0/hostmode
|
||||
0
|
||||
# echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
arch/arm/mach-s3c2440/mach-gta02.c | 6 ++
|
||||
arch/arm/plat-s3c24xx/Makefile | 2 +-
|
||||
arch/arm/plat-s3c24xx/neo1973_pm_host.c | 101 +++++++++++++++++++++++++++++++
|
||||
3 files changed, 108 insertions(+), 1 deletions(-)
|
||||
create mode 100644 arch/arm/plat-s3c24xx/neo1973_pm_host.c
|
||||
|
||||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
index f18c8fd..5bd68a6 100644
|
||||
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||||
@@ -1030,6 +1030,11 @@ static struct platform_device gta01_pm_gsm_dev = {
|
||||
.name = "neo1973-pm-gsm",
|
||||
};
|
||||
|
||||
+static struct platform_device gta02_pm_usbhost_dev = {
|
||||
+ .name = "neo1973-pm-host",
|
||||
+};
|
||||
+
|
||||
+
|
||||
/* USB */
|
||||
static struct s3c2410_hcd_info gta02_usb_info = {
|
||||
.port[0] = {
|
||||
@@ -1287,6 +1292,7 @@ static void __init gta02_machine_init(void)
|
||||
platform_device_register(&s3c_device_spi_acc);
|
||||
platform_device_register(>a01_button_dev);
|
||||
platform_device_register(>a01_pm_gsm_dev);
|
||||
+ platform_device_register(>a02_pm_usbhost_dev);
|
||||
|
||||
mangle_pmu_pdata_by_system_rev();
|
||||
platform_device_register(>a02_pmu_dev);
|
||||
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
|
||||
index 6f43aca..d58265f 100644
|
||||
--- a/arch/arm/plat-s3c24xx/Makefile
|
||||
+++ b/arch/arm/plat-s3c24xx/Makefile
|
||||
@@ -29,4 +29,4 @@ obj-$(CONFIG_PM) += pm.o
|
||||
obj-$(CONFIG_PM) += sleep.o
|
||||
obj-$(CONFIG_S3C2410_DMA) += dma.o
|
||||
obj-$(CONFIG_MACH_SMDK) += common-smdk.o
|
||||
-obj-$(CONFIG_MACH_NEO1973) += neo1973_pm_gsm.o neo1973_pm_gps.o neo1973_pm_bt.o
|
||||
+obj-$(CONFIG_MACH_NEO1973) += neo1973_pm_host.o neo1973_pm_gsm.o neo1973_pm_gps.o neo1973_pm_bt.o
|
||||
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_host.c b/arch/arm/plat-s3c24xx/neo1973_pm_host.c
|
||||
new file mode 100644
|
||||
index 0000000..4eae341
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_host.c
|
||||
@@ -0,0 +1,101 @@
|
||||
+/*
|
||||
+ * Bluetooth PM code for the FIC Neo1973 GSM Phone
|
||||
+ *
|
||||
+ * (C) 2007 by OpenMoko Inc.
|
||||
+ * Author: Harald Welte <laforge@openmoko.org>
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <asm/hardware.h>
|
||||
+#include <asm/mach-types.h>
|
||||
+
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA02
|
||||
+#include <asm/arch/gta02.h>
|
||||
+#include <linux/pcf50633.h>
|
||||
+
|
||||
+static ssize_t pm_host_read(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ return sprintf(buf, "%d\n",
|
||||
+ pcf50633_gpio_get(pcf50633_global, PCF50633_GPO));
|
||||
+}
|
||||
+
|
||||
+static ssize_t pm_host_write(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ unsigned long on = simple_strtoul(buf, NULL, 10);
|
||||
+
|
||||
+ pcf50633_gpio_set(pcf50633_global, PCF50633_GPO, on);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(hostmode, 0644, pm_host_read, pm_host_write);
|
||||
+
|
||||
+static struct attribute *neo1973_pm_host_sysfs_entries[] = {
|
||||
+ &dev_attr_hostmode.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group neo1973_pm_host_attr_group = {
|
||||
+ .name = NULL,
|
||||
+ .attrs = neo1973_pm_host_sysfs_entries,
|
||||
+};
|
||||
+
|
||||
+static int __init neo1973_pm_host_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ dev_info(&pdev->dev, "starting\n");
|
||||
+
|
||||
+ switch (machine_arch_type) {
|
||||
+#ifdef CONFIG_MACH_NEO1973_GTA01
|
||||
+ case MACH_TYPE_NEO1973_GTA01:
|
||||
+ return -EINVAL;
|
||||
+#endif /* CONFIG_MACH_NEO1973_GTA01 */
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return sysfs_create_group(&pdev->dev.kobj, &neo1973_pm_host_attr_group);
|
||||
+}
|
||||
+
|
||||
+static int neo1973_pm_host_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, &neo1973_pm_host_attr_group);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver neo1973_pm_host_driver = {
|
||||
+ .probe = neo1973_pm_host_probe,
|
||||
+ .remove = neo1973_pm_host_remove,
|
||||
+ .driver = {
|
||||
+ .name = "neo1973-pm-host",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __devinit neo1973_pm_host_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&neo1973_pm_host_driver);
|
||||
+}
|
||||
+
|
||||
+static void neo1973_pm_host_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&neo1973_pm_host_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(neo1973_pm_host_init);
|
||||
+module_exit(neo1973_pm_host_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
|
||||
+MODULE_DESCRIPTION("Neo1973 USB Host Power Management");
|
||||
+#endif
|
||||
--
|
||||
1.5.6.3
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
From f78f3a4decb7e67b5349a2c088449342398d2114 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Green <andy@openmoko.com>
|
||||
Date: Fri, 25 Jul 2008 23:06:01 +0100
|
||||
Subject: [PATCH] fix-charging-deassert-host-power-1a-detect.patch
|
||||
|
||||
We don't take care to stop driving generated USB host power even
|
||||
when we have a 1A charger connected on the same pins.
|
||||
|
||||
Signed-off-by: Andy Green <andy@openmoko.com>
|
||||
---
|
||||
drivers/i2c/chips/pcf50633.c | 9 +++++++++
|
||||
1 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||||
index 91b9ac3..c14fad0 100644
|
||||
--- a/drivers/i2c/chips/pcf50633.c
|
||||
+++ b/drivers/i2c/chips/pcf50633.c
|
||||
@@ -523,6 +523,15 @@ static void configure_pmu_for_charger(struct pcf50633_data *pcf,
|
||||
break;
|
||||
case CHARGER_TYPE_1A:
|
||||
__reg_write(pcf, PCF50633_REG_MBCC7, PCF50633_MBCC7_USB_1000mA);
|
||||
+ /*
|
||||
+ * stop GPO / EN_HOSTUSB power driving out on the same
|
||||
+ * USB power pins we have a 1A charger on right now!
|
||||
+ */
|
||||
+ dev_info(&pcf->client.dev, "Charger -> CHARGER_TYPE_1A\n");
|
||||
+ __reg_write(pcf, PCF50633_GPO - PCF50633_GPIO1 +
|
||||
+ PCF50633_REG_GPIO1CFG,
|
||||
+ __reg_read(pcf, PCF50633_GPO - PCF50633_GPIO1 +
|
||||
+ PCF50633_REG_GPIO1CFG) & 0xf0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.5.6.3
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue