Date:2011-06-04 20:27:14 (12 years 9 months ago)
Author:florian
Commit:b5a33bb5d58805d5b1d84a4cf47feeca52984705
Message:[ep93xx] update to 2.6.39.1

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27114 3c298f89-4303-0410-b956-a3cf2f4a3e73
Files: target/linux/ep93xx/Makefile (1 diff)
target/linux/ep93xx/config-2.6.39 (1 diff)
target/linux/ep93xx/patches-2.6.39/001-ep93xx_cpuinfo.patch (1 diff)
target/linux/ep93xx/patches-2.6.39/002-mmc_spi_fix_sdhc.patch (1 diff)
target/linux/ep93xx/patches-2.6.39/003-ep93xx_touchscreen.patch (1 diff)
target/linux/ep93xx/patches-2.6.39/004-simone_add_mmc_spi.patch (1 diff)

Change Details

target/linux/ep93xx/Makefile
1313CFLAGS:=-Os -pipe -march=armv4t -fno-caller-saves
1414MAINTAINER:=Florian Fainelli <florian@openwrt.org>
1515
16LINUX_VERSION:=2.6.38.6
16LINUX_VERSION:=2.6.39.1
1717
1818include $(INCLUDE_DIR)/target.mk
1919
target/linux/ep93xx/config-2.6.39
1CONFIG_ALIGNMENT_TRAP=y
2CONFIG_ARCH_EP93XX=y
3# CONFIG_ARCH_EXYNOS4 is not set
4CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
5CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
6CONFIG_ARCH_REQUIRE_GPIOLIB=y
7# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
8# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
9# CONFIG_ARCH_SUPPORTS_MSI is not set
10CONFIG_ARCH_SUSPEND_POSSIBLE=y
11CONFIG_ARCH_USES_GETTIMEOFFSET=y
12# CONFIG_ARCH_VT8500 is not set
13CONFIG_ARM=y
14CONFIG_ARM_AMBA=y
15CONFIG_ARM_L1_CACHE_SHIFT=5
16# CONFIG_ARM_SP805_WATCHDOG is not set
17CONFIG_ARM_THUMB=y
18CONFIG_ARM_VIC=y
19CONFIG_ARM_VIC_NR=2
20# CONFIG_ARPD is not set
21# CONFIG_BLK_DEV_INITRD is not set
22# CONFIG_BSD_PROCESS_ACCT is not set
23CONFIG_CC_OPTIMIZE_FOR_SIZE=y
24CONFIG_CLKDEV_LOOKUP=y
25CONFIG_CMDLINE="console=ttyAM0,57600 init=/etc/preinit"
26CONFIG_CONSOLE_TRANSLATIONS=y
27CONFIG_CPU_32v4T=y
28CONFIG_CPU_ABRT_EV4T=y
29CONFIG_CPU_ARM920T=y
30CONFIG_CPU_CACHE_V4WT=y
31CONFIG_CPU_CACHE_VIVT=y
32CONFIG_CPU_COPY_V4WB=y
33CONFIG_CPU_CP15=y
34CONFIG_CPU_CP15_MMU=y
35# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
36# CONFIG_CPU_ICACHE_DISABLE is not set
37CONFIG_CPU_PABRT_LEGACY=y
38CONFIG_CPU_TLB_V4WBI=y
39CONFIG_CPU_USE_DOMAINS=y
40CONFIG_CRC7=y
41CONFIG_CRC_ITU_T=y
42CONFIG_CRUNCH=y
43CONFIG_CRYPTO_AEAD2=y
44CONFIG_CRYPTO_AES=y
45CONFIG_CRYPTO_ALGAPI=y
46CONFIG_CRYPTO_ALGAPI2=y
47CONFIG_CRYPTO_ARC4=y
48CONFIG_CRYPTO_BLKCIPHER=y
49CONFIG_CRYPTO_BLKCIPHER2=y
50CONFIG_CRYPTO_DES=y
51CONFIG_CRYPTO_ECB=m
52CONFIG_CRYPTO_HASH=y
53CONFIG_CRYPTO_HASH2=y
54CONFIG_CRYPTO_MANAGER=y
55CONFIG_CRYPTO_MANAGER2=y
56CONFIG_CRYPTO_MD5=y
57CONFIG_CRYPTO_MICHAEL_MIC=y
58CONFIG_CRYPTO_PCBC=y
59CONFIG_CRYPTO_PCOMP2=y
60CONFIG_CRYPTO_RNG2=y
61CONFIG_CRYPTO_SHA1=y
62CONFIG_CRYPTO_WORKQUEUE=y
63CONFIG_DEBUG_BUGVERBOSE=y
64CONFIG_DEBUG_USER=y
65CONFIG_DEFAULT_TCP_CONG="cubic"
66CONFIG_DNOTIFY=y
67CONFIG_DUMMY_CONSOLE=y
68CONFIG_ELF_CORE=y
69# CONFIG_ENABLE_WARN_DEPRECATED is not set
70CONFIG_EP93XX_EARLY_UART1=y
71# CONFIG_EP93XX_EARLY_UART2 is not set
72# CONFIG_EP93XX_EARLY_UART3 is not set
73CONFIG_EP93XX_ETH=y
74CONFIG_EP93XX_SDCE0_PHYS_OFFSET=y
75# CONFIG_EP93XX_SDCE1_PHYS_OFFSET is not set
76# CONFIG_EP93XX_SDCE2_PHYS_OFFSET is not set
77# CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET is not set
78# CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET is not set
79CONFIG_EP93XX_WATCHDOG=y
80CONFIG_FB=y
81# CONFIG_FB_ARMCLCD is not set
82CONFIG_FB_CFB_COPYAREA=y
83CONFIG_FB_CFB_FILLRECT=y
84CONFIG_FB_CFB_IMAGEBLIT=y
85CONFIG_FB_EP93XX=y
86# CONFIG_FB_SM7XX is not set
87# CONFIG_FB_WMT_GE_ROPS is not set
88# CONFIG_FIRMWARE_EDID is not set
89CONFIG_FONTS=y
90# CONFIG_FONT_10x18 is not set
91# CONFIG_FONT_6x11 is not set
92# CONFIG_FONT_7x14 is not set
93CONFIG_FONT_8x16=y
94CONFIG_FONT_8x8=y
95# CONFIG_FONT_ACORN_8x8 is not set
96# CONFIG_FONT_MINI_4x6 is not set
97# CONFIG_FONT_PEARL_8x8 is not set
98# CONFIG_FONT_SUN12x22 is not set
99# CONFIG_FONT_SUN8x16 is not set
100CONFIG_FRAMEBUFFER_CONSOLE=y
101# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
102# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
103CONFIG_FRAME_POINTER=y
104# CONFIG_FW_LOADER is not set
105CONFIG_GENERIC_ATOMIC64=y
106CONFIG_GENERIC_FIND_LAST_BIT=y
107CONFIG_GENERIC_GPIO=y
108CONFIG_GENERIC_IRQ_SHOW=y
109CONFIG_GPIOLIB=y
110# CONFIG_GPIO_PL061 is not set
111# CONFIG_HAMRADIO is not set
112CONFIG_HARDIRQS_SW_RESEND=y
113CONFIG_HAS_DMA=y
114CONFIG_HAS_IOMEM=y
115CONFIG_HAS_IOPORT=y
116CONFIG_HAVE_AOUT=y
117CONFIG_HAVE_ARCH_KGDB=y
118CONFIG_HAVE_CLK=y
119CONFIG_HAVE_C_RECORDMCOUNT=y
120CONFIG_HAVE_DMA_API_DEBUG=y
121CONFIG_HAVE_DYNAMIC_FTRACE=y
122CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
123CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
124CONFIG_HAVE_FUNCTION_TRACER=y
125CONFIG_HAVE_GENERIC_DMA_COHERENT=y
126CONFIG_HAVE_GENERIC_HARDIRQS=y
127CONFIG_HAVE_IDE=y
128CONFIG_HAVE_IRQ_WORK=y
129CONFIG_HAVE_KERNEL_GZIP=y
130CONFIG_HAVE_KERNEL_LZMA=y
131CONFIG_HAVE_KERNEL_LZO=y
132CONFIG_HAVE_LATENCYTOP_SUPPORT=y
133CONFIG_HAVE_MEMBLOCK=y
134CONFIG_HAVE_OPROFILE=y
135CONFIG_HAVE_PERF_EVENTS=y
136CONFIG_HAVE_PROC_CPU=y
137CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
138CONFIG_HAVE_SPARSE_IRQ=y
139CONFIG_HW_CONSOLE=y
140CONFIG_I2C=y
141CONFIG_I2C_ALGOBIT=y
142CONFIG_I2C_BOARDINFO=y
143CONFIG_I2C_CHARDEV=y
144# CONFIG_I2C_PXA_PCI is not set
145CONFIG_IKCONFIG=y
146CONFIG_IKCONFIG_PROC=y
147CONFIG_INOTIFY_USER=y
148CONFIG_INPUT=y
149# CONFIG_INPUT_MISC is not set
150CONFIG_INPUT_TOUCHSCREEN=y
151CONFIG_KTIME_SCALAR=y
152# CONFIG_LEDS_GPIO is not set
153CONFIG_LOGO=y
154CONFIG_LOGO_LINUX_CLUT224=y
155CONFIG_LOGO_LINUX_MONO=y
156CONFIG_LOGO_LINUX_VGA16=y
157CONFIG_LOG_BUF_SHIFT=16
158# CONFIG_MACH_EDB9302A is not set
159# CONFIG_MACH_EDB9307A is not set
160# CONFIG_MACH_EDB9315A is not set
161CONFIG_MACH_NO_WESTBRIDGE=y
162CONFIG_MACH_SIM_ONE=y
163# CONFIG_MACH_SNAPPER_CL15 is not set
164# CONFIG_MFD_T7L66XB is not set
165# CONFIG_MISC_DEVICES is not set
166CONFIG_MMC=y
167CONFIG_MMC_BLOCK=y
168CONFIG_MMC_SPI=y
169CONFIG_MODULE_FORCE_UNLOAD=y
170CONFIG_MTD_CFI_ADV_OPTIONS=y
171# CONFIG_MTD_CFI_GEOMETRY is not set
172CONFIG_MTD_CFI_STAA=y
173# CONFIG_MTD_COMPLEX_MAPPINGS is not set
174CONFIG_MTD_PHYSMAP=y
175CONFIG_MTD_RAM=y
176CONFIG_NEED_DMA_MAP_STATE=y
177CONFIG_NEED_PER_CPU_KM=y
178CONFIG_PAGEFLAGS_EXTENDED=y
179CONFIG_PAGE_OFFSET=0xC0000000
180# CONFIG_PCI_SYSCALL is not set
181CONFIG_PERF_USE_VMALLOC=y
182# CONFIG_PREEMPT_RCU is not set
183# CONFIG_QUOTACTL is not set
184# CONFIG_SCSI_DMA is not set
185# CONFIG_SDIO_UART is not set
186# CONFIG_SERIAL_8250 is not set
187CONFIG_SERIAL_AMBA_PL010=y
188CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
189# CONFIG_SERIAL_AMBA_PL011 is not set
190CONFIG_SPI=y
191CONFIG_SPI_BITBANG=y
192CONFIG_SPI_EP93XX=y
193# CONFIG_SPI_GPIO is not set
194CONFIG_SPI_MASTER=y
195# CONFIG_SPI_PL022 is not set
196CONFIG_SPLIT_PTLOCK_CPUS=999999
197CONFIG_SYS_SUPPORTS_APM_EMULATION=y
198# CONFIG_TCP_CONG_ADVANCED is not set
199CONFIG_TCP_CONG_CUBIC=y
200# CONFIG_TOUCHSCREEN_DYNAPRO is not set
201CONFIG_TOUCHSCREEN_EP93XX=y
202# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
203CONFIG_UID16=y
204# CONFIG_USB_ARCH_HAS_EHCI is not set
205CONFIG_USB_SUPPORT=y
206CONFIG_VECTORS_BASE=0xffff0000
207CONFIG_VIDEO_OUTPUT_CONTROL=y
208CONFIG_VM_EVENT_COUNTERS=y
209CONFIG_VT=y
210CONFIG_VT_CONSOLE=y
211# CONFIG_VT_HW_CONSOLE_BINDING is not set
212CONFIG_XZ_DEC=y
213CONFIG_ZBOOT_ROM_BSS=0x0
214CONFIG_ZBOOT_ROM_TEXT=0x0
215CONFIG_ZONE_DMA_FLAG=0
target/linux/ep93xx/patches-2.6.39/001-ep93xx_cpuinfo.patch
1This patch puts the EP93xx chip revision and unique ID into /proc/cpuinfo.
2This is necessary to be able to set a unique MAC address for DHCP purposes
3by adding a line to /etc/network/interfaces:
4
5# Generate a unique locally-assigned MAC address from the CPU serial number
6pre-up ifconfig eth0 hw ether `sed -n 's/^Serial.* 000000/02/p' /proc/cpuinfo`
7
8It uses the chip revision reading code in the ep93xx-chip-revision patch.
9
10Really, this is wrong, since /proc/cpuinfo should report the revision and
11serial number of the ARM920T processor, while these are the rev and serial
12of the EP93xx SoC. In a future kernel (>2.6.34) there may be a new file
13/proc/socinfo for this information.
14
15    -martinwguy 14 May 2010
16
17--- a/arch/arm/kernel/setup.c
18@@ -48,6 +48,12 @@
19 #include <asm/traps.h>
20 #include <asm/unwind.h>
21
22+#if defined(CONFIG_ARCH_EP93XX)
23+#include <mach/io.h>
24+#include <mach/ep93xx-regs.h>
25+#include <mach/platform.h>
26+#endif
27+
28 #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
29 #include "compat.h"
30 #endif
31@@ -1005,9 +1011,16 @@ static int c_show(struct seq_file *m, vo
32     seq_puts(m, "\n");
33
34     seq_printf(m, "Hardware\t: %s\n", machine_name);
35+#if defined(CONFIG_ARCH_EP93XX)
36+ seq_printf(m, "Revision\t: %04x\n",
37+ ep93xx_chip_revision());
38+ seq_printf(m, "Serial\t\t: %016x\n",
39+ *((unsigned int *)EP93XX_SECURITY_UNIQID));
40+#else
41     seq_printf(m, "Revision\t: %04x\n", system_rev);
42     seq_printf(m, "Serial\t\t: %08x%08x\n",
43            system_serial_high, system_serial_low);
44+#endif
45
46     return 0;
47 }
48--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
49@@ -97,6 +97,8 @@
50 #define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
51
52 #define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
53+#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x))
54+#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440)
55
56 #define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
57 #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
target/linux/ep93xx/patches-2.6.39/002-mmc_spi_fix_sdhc.patch
1This patch makes SDHC cards work with the mmc_spi driver.
2
3The problem is that they fail when reading the last block of the card using
4a multi-block read. This is because on SDHC the multiple block read has to be
5stopped with an explicit STOP command, which needs to be sent to the card
6while the incoming transfer is in progress.
7The 2.6.3[45] mmc-spi driver sends it after the last block transfer, so the
8SDHC card continues reading past the end of the card.
9This patch works around this by using single-block reads if we're reading the
10last blocks of the card.
11  -martinwguy, 14 May 2010
12
13Date: Thu, 29 Apr 2010 21:30:36 +0300
14From: Mika Westerberg <mika.westerberg@iki.fi>
15To: Martin Guy <martinwguy@gmail.com>
16
17On Wed, Apr 21, 2010 at 02:10:08AM +0100, Martin Guy wrote:
18>
19> the SDHC cards I have don't work at all, spewing tons of:
20> mmcblk0: error -38 sending status comand
21> mmcblk0: error -38 sending read/write command, response 0x4, card status 0xff04
22> end_request: I/O error, dev mmcblk0, sector 7744509
23
24I bought today a new 4GB SDHC card and with that I get similar
25errors that you are getting. I hacked around quick fix which seems
26to work in my case. I'm wondering whether you could check if it
27helps with your SDHC card as well?
28
29This problem is easy to reproduce, just read last sector of the
30card (I wrote simple C program but running fdisk -l does the same).
31
32Patch is below.
33
34Thanks,
35MW
36
37From: Mika Westerberg <mika.westerberg@iki.fi>
38Date: Thu, 29 Apr 2010 21:14:32 +0300
39Subject: [PATCH] mmc_block: use single block reads for last block on SPI
40
41Some SD-cards fail when doing multiblock read for last block with SPI host. Real
42reason is not known but as workaround we can perform this last read using
43multiple single block reads.
44
45Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi>
46---
47 drivers/mmc/card/block.c | 19 +++++++++++++++++++
48 1 files changed, 19 insertions(+), 0 deletions(-)
49
50--- a/drivers/mmc/card/block.c
51@@ -366,6 +366,22 @@ static int mmc_blk_issue_rw_rq(struct mm
52         if (brq.data.blocks > card->host->max_blk_count)
53             brq.data.blocks = card->host->max_blk_count;
54
55+ if (mmc_host_is_spi(card->host)) {
56+ /*
57+ * Some SD-cards fail when we are reading last block
58+ * with multiblock read. In these cases we automatically
59+ * use single block reads. This only happens on SPI
60+ * hosts.
61+ */
62+ if (rq_data_dir(req) == READ && brq.data.blocks > 1) {
63+ sector_t s = blk_rq_pos(req) + brq.data.blocks;
64+
65+ if (s >= get_capacity(md->disk)) {
66+ disable_multi = 1;
67+ }
68+ }
69+ }
70+
71         /*
72          * After a read error, we redo the request one sector at a time
73          * in order to accurately determine which sectors can be read
target/linux/ep93xx/patches-2.6.39/003-ep93xx_touchscreen.patch
1---
2 arch/arm/mach-ep93xx/include/mach/hardware.h | 1
3 arch/arm/mach-ep93xx/include/mach/regs_touch.h | 95 ++
4 drivers/input/touchscreen/Kconfig | 5
5 drivers/input/touchscreen/Makefile | 1
6 drivers/input/touchscreen/ep93xx_ts.c | 1117 +++++++++++++++++++++++++
7 drivers/input/touchscreen/ep93xx_ts.h | 53 +
8 6 files changed, 1272 insertions(+)
9
10--- a/drivers/input/touchscreen/Kconfig
11@@ -177,6 +177,15 @@ config TOUCHSCREEN_EETI
12       To compile this driver as a module, choose M here: the
13       module will be called eeti_ts.
14
15+config TOUCHSCREEN_EP93XX
16+ tristate "EP93xx Touchscreen"
17+ depends on ARM && INPUT && ARCH_EP93XX
18+ help
19+ Say Y here to enable support for EP93xx touch screen.
20+
21+ To compile this driver as a module, choose M here:
22+ the module will be called ep93xx_ts.
23+
24 config TOUCHSCREEN_FUJITSU
25     tristate "Fujitsu serial touchscreen"
26     select SERIO
27--- a/drivers/input/touchscreen/Makefile
28@@ -23,6 +23,7 @@ obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += h
29 obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
30 obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
31 obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
32+obj-$(CONFIG_TOUCHSCREEN_EP93XX) += ep93xx_ts.o
33 obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
34 obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
35 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
36--- /dev/null
37@@ -0,0 +1,1021 @@
38+/*
39+ * linux/drivers/input/touchscreen/ep93xx_ts.c
40+ *
41+ * Copyright (C) 2003-2004 Cirrus Corp.
42+ *
43+ * This program is free software; you can redistribute it and/or modify
44+ * it under the terms of the GNU General Public License version 2 as
45+ * published by the Free Software Foundation.
46+ */
47+
48+#include <linux/module.h>
49+#include <linux/types.h>
50+#include <linux/delay.h>
51+#include <linux/wait.h>
52+#include <linux/fs.h>
53+#include <linux/sched.h>
54+#include <linux/poll.h>
55+#include <linux/miscdevice.h>
56+#include <linux/init.h>
57+#include <linux/compiler.h>
58+#include <linux/timer.h>
59+#include <linux/interrupt.h>
60+#include <linux/syscalls.h>
61+#include <linux/input.h>
62+#include <linux/semaphore.h>
63+#include <asm/irq.h>
64+#include <mach/hardware.h>
65+#include <asm/io.h>
66+
67+/* This stuff should be in ep93xx-regs.h */
68+#define EP93XX_TOUCHSCREEN_REG(x) (EP93XX_TOUCHSCREEN_BASE + (x))
69+/* R/W touchscreen controller setup control register. */
70+#define EP93XX_TOUCHSCREEN_SETUP EP93XX_TOUCHSCREEN_REG(0x00)
71+/* R/W touchscreen controller max/min register. */
72+#define EP93XX_TOUCHSCREEN_XYMAXMIN EP93XX_TOUCHSCREEN_REG(0x04)
73+/* R touchscreen controller result register. */
74+#define EP93XX_TOUCHSCREEN_XYRESULT EP93XX_TOUCHSCREEN_REG(0x08)
75+/* LOCKED R/W touchscreen Switch Matrix control register. */
76+#define EP93XX_TOUCHSCREEN_DISCHARGE EP93XX_TOUCHSCREEN_REG(0x0C)
77+#define EP93XX_TOUCHSCREEN_XSAMPLE EP93XX_TOUCHSCREEN_REG(0x10)
78+#define EP93XX_TOUCHSCREEN_YSAMPLE EP93XX_TOUCHSCREEN_REG(0x14)
79+#define EP93XX_TOUCHSCREEN_DIRECT EP93XX_TOUCHSCREEN_REG(0x18)
80+#define EP93XX_TOUCHSCREEN_DETECT EP93XX_TOUCHSCREEN_REG(0x1C)
81+/* NA R/W touchscreen software lock register. */
82+#define EP93XX_TOUCHSCREEN_SWLOCK EP93XX_TOUCHSCREEN_REG(0x20)
83+/* R/W touchscreen setup control register #2. */
84+#define EP93XX_TOUCHSCREEN_SETUP2 EP93XX_TOUCHSCREEN_REG(0x24)
85+
86+/* These are duplicated in mach-ep93xx/core.c */
87+#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
88+#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
89+#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
90+#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
91+#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
92+
93+/*
94+ * Register bit definitions
95+ */
96+#define TSSETUP_SDLY_MASK 0x000003FF
97+#define TSSETUP_SDLY_SHIFT 0
98+#define TSSETUP_NSMP_4 0x00000000
99+#define TSSETUP_NSMP_8 0x00000400
100+#define TSSETUP_NSMP_16 0x00000800
101+#define TSSETUP_NSMP_32 0x00000C00
102+#define TSSETUP_NSMP_MASK 0x00000C00
103+#define TSSETUP_DEV_4 0x00000000
104+#define TSSETUP_DEV_8 0x00001000
105+#define TSSETUP_DEV_12 0x00002000
106+#define TSSETUP_DEV_16 0x00003000
107+#define TSSETUP_DEV_24 0x00004000
108+#define TSSETUP_DEV_32 0x00005000
109+#define TSSETUP_DEV_64 0x00006000
110+#define TSSETUP_DEV_128 0x00007000
111+#define TSSETUP_ENABLE 0x00008000
112+#define TSSETUP_DLY_MASK 0x03FF0000
113+#define TSSETUP_DLY_SHIFT 16
114+#define TSSETUP_TDTCT 0x80000000
115+
116+#define TSMAXMIN_XMIN_MASK 0x000000FF
117+#define TSMAXMIN_XMIN_SHIFT 0
118+#define TSMAXMIN_YMIN_MASK 0x0000FF00
119+#define TSMAXMIN_YMIN_SHIFT 8
120+#define TSMAXMIN_XMAX_MASK 0x00FF0000
121+#define TSMAXMIN_XMAX_SHIFT 16
122+#define TSMAXMIN_YMAX_MASK 0xFF000000
123+#define TSMAXMIN_YMAX_SHIFT 24
124+
125+#define TSXYRESULT_X_MASK 0x00000FFF
126+#define TSXYRESULT_X_SHIFT 0
127+#define TSXYRESULT_AD_MASK 0x0000FFFF
128+#define TSXYRESULT_AD_SHIFT 0
129+#define TSXYRESULT_Y_MASK 0x0FFF0000
130+#define TSXYRESULT_Y_SHIFT 16
131+#define TSXYRESULT_SDR 0x80000000
132+
133+#define TSX_SAMPLE_MASK 0x00003FFF
134+#define TSX_SAMPLE_SHIFT 0x00
135+#define TSY_SAMPLE_MASK 0x3FFF0000
136+#define TSY_SAMPLE_SHIFT 0x10
137+
138+#define TSSETUP2_TINT 0x00000001
139+#define TSSETUP2_NICOR 0x00000002
140+#define TSSETUP2_PINT 0x00000004
141+#define TSSETUP2_PENSTS 0x00000008
142+#define TSSETUP2_PINTEN 0x00000010
143+#define TSSETUP2_DEVINT 0x00000020
144+#define TSSETUP2_DINTEN 0x00000040
145+#define TSSETUP2_DTMEN 0x00000080
146+#define TSSETUP2_DISDEV 0x00000100
147+#define TSSETUP2_NSIGND 0x00000200
148+#define TSSETUP2_S28EN 0x00000400
149+#define TSSETUP2_RINTEN 0x00000800
150+
151+#define TSXYRESULT_SDR 0x80000000
152+
153+/*
154+ * These are used as trigger levels to know when we have pen up/down.
155+ * The rules:
156+ * 1. TS_HEAVY_INV_PRESSURE < TS_LIGHT_INV_PRESSURE because these
157+ * are Inverse pressure.
158+ * 2. Any touch lighter than TS_LIGHT_INV_PRESSURE is a pen up.
159+ * 3. Any touch heavier than TS_HEAVY_INV_PRESSURE is a pen down.
160+ */
161+#define TS_HEAVY_INV_PRESSURE 0xFE0 /* C00 */
162+#define TS_LIGHT_INV_PRESSURE 0xFFF /* e00 */
163+
164+/*
165+ * If the x, y, or inverse pressure changes more than these values
166+ * between two succeeding points, the point is not reported.
167+ */
168+#define TS_MAX_VALID_XY_CHANGE 0x300
169+#define TS_MAX_VALID_PRESSURE_CHANGE 0x100
170+
171+/*
172+ * This is the minimum Z1 Value that is valid.
173+ */
174+#define MIN_Z1_VALUE 0x50
175+
176+/*
177+ * Settling delay for taking each ADC measurement. Increase this
178+ * if ts is jittery.
179+ */
180+#define EP93XX_TS_ADC_DELAY_USEC 2000
181+
182+/*
183+ * Delay between TS points.
184+ */
185+#define EP93XX_TS_PER_POINT_DELAY_USEC 10000
186+
187+/*
188+ * A few more macros...
189+ */
190+#define TSSETUP_DEFAULT (TSSETUP_NSMP_32 | TSSETUP_DEV_64 | \
191+ ((128<<TSSETUP_SDLY_SHIFT) & TSSETUP_SDLY_MASK) | \
192+ ((128<<TSSETUP_DLY_SHIFT) & TSSETUP_DLY_MASK))
193+
194+#define TSSETUP2_DEFAULT (TSSETUP2_NSIGND)
195+
196+/*
197+ * For now, we use one of the minor numbers from the local/experimental
198+ * range.
199+ */
200+#define EP93XX_TS_MINOR 240
201+
202+/*
203+ * Static Declarations
204+ */
205+static unsigned int guiLastX, guiLastY;
206+static unsigned int guiLastInvPressure;
207+
208+struct TouchScreenSample
209+{
210+ int currentX;
211+ int currentY;
212+ int currentButton;
213+ int currentPressure;
214+ struct timeval currentTime;
215+};
216+
217+/*
218+ * This must match the structure in tslib.
219+ */
220+struct ts_sample {
221+ int x;
222+ int y;
223+ unsigned int pressure;
224+ struct timeval tv;
225+};
226+
227+static struct TouchScreenSample gSample;
228+static int bFreshTouchData;
229+static int bCurrentPenDown;
230+
231+static DECLARE_WAIT_QUEUE_HEAD(queue);
232+static DEFINE_SEMAPHORE(open_sem);
233+static DEFINE_SPINLOCK(event_buffer_lock);
234+static struct fasync_struct *ep93xx_fasync;
235+
236+/*
237+ * Typedef Declarations
238+ */
239+typedef enum {
240+ TS_MODE_UN_INITIALIZED,
241+ TS_MODE_HARDWARE_SCAN,
242+ TS_MODE_SOFT_SCAN
243+} ts_mode_t;
244+
245+static ts_mode_t gScanningMode;
246+
247+typedef enum{
248+ TS_STATE_STOPPED = 0,
249+ TS_STATE_Z1,
250+ TS_STATE_Z2,
251+ TS_STATE_Y,
252+ TS_STATE_X,
253+ TS_STATE_DONE
254+} ts_states_t;
255+
256+typedef struct
257+{
258+ unsigned int uiX;
259+ unsigned int uiY;
260+ unsigned int uiZ1;
261+ unsigned int uiZ2;
262+ ts_states_t state;
263+} ts_struct_t;
264+
265+static ts_struct_t sTouch;
266+
267+/*
268+ * From the spec, here's how to set up the touch screen's switch registers.
269+ */
270+typedef struct
271+{
272+ unsigned int uiDetect;
273+ unsigned int uiDischarge;
274+ unsigned int uiXSample;
275+ unsigned int uiYSample;
276+ unsigned int uiSwitchZ1;
277+ unsigned int uiSwitchZ2;
278+}SwitchStructType;
279+
280+/*
281+ * Here's the switch settings for a 4-wire touchscreen. See the spec
282+ * for how to handle a 4, 7, or 8-wire.
283+ */
284+const static SwitchStructType sSwitchSettings =
285+/* s28en=0 */
286+/* TSDetect TSDischarge TSXSample TSYSample SwitchZ1 SwitchZ2 */
287+ {0x00403604, 0x0007fe04, 0x00081604, 0x00104601, 0x00101601, 0x00101608};
288+
289+/*
290+ * Function declarations
291+ */
292+static void ep93xx_ts_set_direct(unsigned int uiADCSwitch);
293+static irqreturn_t ep93xx_ts_isr(int irq, void *dev_id);
294+static irqreturn_t ep93xx_timer2_isr(int irq, void *dev_id);
295+static void ee93xx_ts_evt_add(int button, int dX, int dY, int Pressure);
296+static ssize_t ep93xx_ts_read(struct file *filp, char *buf,
297+ size_t count, loff_t *l);
298+static unsigned int ep93xx_ts_poll(struct file *filp, poll_table *wait);
299+static int ep93xx_ts_open(struct inode *inode, struct file *filp);
300+static int ep93xx_ts_fasync(int fd, struct file *filp, int on);
301+static int ep93xx_ts_release(struct inode *inode, struct file *filp);
302+static ssize_t ep93xx_ts_write(struct file *file, const char *buffer,
303+ size_t count, loff_t *ppos);
304+static void ep93xx_ts_setup(void);
305+static void ep93xx_ts_shutdown(void);
306+int __init ep93xx_ts_init(void);
307+void __exit ep93xx_ts_exit(void);
308+static unsigned int CalculateInvPressure(void);
309+static unsigned int ADCGetData(unsigned int uiSamples, unsigned int uiMaxDiff);
310+static void TS_Soft_Scan_Mode(void);
311+static void TS_Hardware_Scan_Mode(void);
312+static void ProcessPointData(void);
313+static void Set_Timer2_uSec(unsigned int Delay_mSec);
314+static void Stop_Timer2(void);
315+
316+/*
317+ * ep93xx_ts_isr
318+ */
319+static irqreturn_t ep93xx_ts_isr(int irq, void *dev_id)
320+{
321+ /*
322+ * Note that we don't clear the interrupt here. The interrupt
323+ * gets cleared in TS_Soft_Scan_Mode when the TS ENABLE
324+ * bit is cleared.
325+ */
326+
327+ /*
328+ * Set the ts to manual polling mode and schedule a callback.
329+ * That way we can return from the isr in a reasonable amount of
330+ * time and process the touch in the callback after a brief delay.
331+ */
332+ TS_Soft_Scan_Mode();
333+
334+ return(IRQ_HANDLED);
335+}
336+
337+/*
338+ * Save the current ts 'event' in an atomic fashion.
339+ */
340+static void ee93xx_ts_evt_add(int buttons, int iX, int iY, int iPressure)
341+{
342+ /*
343+ * Note the event, but use spinlocks to keep it from getting
344+ * halfway read if we get interrupted.
345+ */
346+
347+ spin_lock(&event_buffer_lock);
348+
349+ gSample.currentX = iX;
350+ gSample.currentY = iY;
351+ gSample.currentButton = buttons;
352+ gSample.currentPressure = iPressure;
353+ bFreshTouchData = 1;
354+ do_gettimeofday(&gSample.currentTime);
355+
356+ spin_unlock(&event_buffer_lock);
357+
358+ kill_fasync(&ep93xx_fasync, SIGIO, POLL_IN);
359+ wake_up_interruptible(&queue);
360+}
361+
362+
363+static ssize_t ep93xx_ts_read(struct file *filp, char *buf, size_t count, loff_t *l)
364+{
365+ unsigned short data[3];
366+ struct ts_sample ts_data;
367+ int iReturn = -EFAULT;
368+
369+ if (!bFreshTouchData)
370+ {
371+ iReturn = 0;
372+ }
373+ else if (count == sizeof(data))
374+ {
375+ spin_lock_irq(&event_buffer_lock);
376+ bFreshTouchData = 0;
377+ data[0] = gSample.currentX;
378+ data[1] = gSample.currentY;
379+ data[2] = gSample.currentButton;
380+
381+ spin_unlock_irq(&event_buffer_lock);
382+
383+ if (copy_to_user(buf, data, sizeof data))
384+ return -EFAULT;
385+
386+ count -= sizeof(data);
387+
388+ /* return the # of bytes that got read */
389+ iReturn = sizeof(data) ;
390+ }
391+ else if (count == sizeof(struct ts_sample) )
392+ {
393+ spin_lock_irq(&event_buffer_lock);
394+ bFreshTouchData = 0;
395+ ts_data.x = gSample.currentX;
396+ ts_data.y = gSample.currentY;
397+ ts_data.pressure = gSample.currentPressure;
398+ ts_data.tv = gSample.currentTime;
399+ spin_unlock_irq(&event_buffer_lock);
400+
401+ if (copy_to_user(buf, &ts_data, sizeof(struct ts_sample)))
402+ {
403+ iReturn = -EFAULT;
404+ }
405+ else
406+ {
407+ count -= sizeof(ts_data);
408+ iReturn = sizeof(ts_data);
409+ }
410+ }
411+
412+ return iReturn;
413+}
414+
415+static unsigned int ep93xx_ts_poll(struct file *filp, poll_table *wait)
416+{
417+ poll_wait(filp, &queue, wait);
418+
419+ if (bFreshTouchData)
420+ {
421+ return POLLIN | POLLRDNORM;
422+ }
423+
424+ return 0;
425+}
426+
427+static int ep93xx_ts_open(struct inode *inode, struct file *filp)
428+{
429+ if (down_trylock(&open_sem))
430+ {
431+ return -EBUSY;
432+ }
433+
434+ ep93xx_ts_setup();
435+
436+ return 0;
437+}
438+
439+/*
440+ * Asynchronous I/O support.
441+ */
442+static int ep93xx_ts_fasync(int fd, struct file *filp, int on)
443+{
444+ int retval;
445+
446+ retval = fasync_helper(fd, filp, on, &ep93xx_fasync);
447+ if (retval < 0)
448+ {
449+ return retval;
450+ }
451+
452+ return 0;
453+}
454+
455+static int ep93xx_ts_release(struct inode *inode, struct file *filp)
456+{
457+ Stop_Timer2();
458+
459+ /*
460+ * Call our async I/O support to request that this file
461+ * cease to be used for async I/O.
462+ */
463+ ep93xx_ts_fasync(-1, filp, 0);
464+
465+ ep93xx_ts_shutdown();
466+
467+ up(&open_sem);
468+
469+ return 0;
470+}
471+
472+static ssize_t ep93xx_ts_write(struct file *file, const char *buffer, size_t count,
473+ loff_t *ppos)
474+{
475+ return -EINVAL;
476+}
477+
478+
479+static int ep93xx_ts_ioctl(struct inode *inode, struct file *file, uint command, ulong u)
480+{
481+ static const int version = EV_VERSION;
482+ static const u_int32_t bit =(1 << EV_ABS);
483+ static const u_int32_t absbit = (1 << ABS_X) | (1 << ABS_Y) | (1 << ABS_PRESSURE);
484+ int iReturn ;
485+ int i = 0;
486+
487+ switch(command)
488+ {
489+ case EVIOCGVERSION:
490+ i = copy_to_user((void __user *)u, (void *)version, sizeof(version));
491+ iReturn = i ? -EFAULT : 0;
492+ break;
493+
494+ case EVIOCGBIT(0,sizeof(u_int32_t) * 8) :
495+ i = copy_to_user((void __user *)u, (void *)bit, sizeof(bit));
496+ iReturn = i ? -EFAULT : 0;
497+ break;
498+
499+ case EVIOCGBIT(EV_ABS, sizeof(absbit) * 8):
500+ i = copy_to_user((void __user *)u, (void *)absbit, sizeof(absbit));
501+ iReturn = i ? -EFAULT : 0;
502+ break;
503+ default:
504+ iReturn = -1;
505+ break;
506+ }
507+
508+ return iReturn;
509+}
510+
511+static struct file_operations ep93xx_ts_fops = {
512+ owner: THIS_MODULE,
513+ read: ep93xx_ts_read,
514+ write: ep93xx_ts_write,
515+ poll: ep93xx_ts_poll,
516+ open: ep93xx_ts_open,
517+ unlocked_ioctl: ep93xx_ts_ioctl,
518+ release: ep93xx_ts_release,
519+ fasync: ep93xx_ts_fasync,
520+};
521+
522+static struct miscdevice ep93xx_ts_miscdev =
523+{
524+ EP93XX_TS_MINOR,
525+ "ep93xx_ts",
526+ &ep93xx_ts_fops
527+};
528+
529+void ep93xx_ts_setup(void)
530+{
531+ unsigned int uiKTDIV, uiTSXYMaxMin;
532+
533+ /*
534+ * Set the TSEN bit in KTDIV so that we are enabling the clock
535+ * for the touchscreen.
536+ */
537+ uiKTDIV = __raw_readl(EP93XX_SYSCON_KEYTCHCLKDIV);
538+ uiKTDIV |= EP93XX_SYSCON_KEYTCHCLKDIV_TSEN;
539+ ep93xx_syscon_swlocked_write(uiKTDIV, EP93XX_SYSCON_KEYTCHCLKDIV);
540+
541+ /*
542+ * Program the EP93XX_TOUCHSCREEN_SETUP and TSSetup2 registers.
543+ */
544+ __raw_writel(TSSETUP_DEFAULT, EP93XX_TOUCHSCREEN_SETUP);
545+ __raw_writel(TSSETUP2_DEFAULT, EP93XX_TOUCHSCREEN_SETUP2);
546+
547+ /*
548+ * Set the the touch settings.
549+ */
550+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
551+ __raw_writel(sSwitchSettings.uiDischarge, EP93XX_TOUCHSCREEN_DIRECT);
552+
553+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
554+ __raw_writel(sSwitchSettings.uiDischarge, EP93XX_TOUCHSCREEN_DISCHARGE);
555+
556+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
557+ __raw_writel(sSwitchSettings.uiSwitchZ1, EP93XX_TOUCHSCREEN_XSAMPLE);
558+
559+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
560+ __raw_writel(sSwitchSettings.uiSwitchZ2, EP93XX_TOUCHSCREEN_YSAMPLE);
561+
562+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
563+ __raw_writel(sSwitchSettings.uiDetect, EP93XX_TOUCHSCREEN_DETECT);
564+
565+ /*
566+ * X,YMin set to 0x40 = have to drag that many pixels for a new irq.
567+ * X,YMax set to 0x40 = 1024 pixels is the maximum movement within the
568+ * time scan limit.
569+ */
570+ uiTSXYMaxMin = (50 << TSMAXMIN_XMIN_SHIFT) & TSMAXMIN_XMIN_MASK;
571+ uiTSXYMaxMin |= (50 << TSMAXMIN_YMIN_SHIFT) & TSMAXMIN_YMIN_MASK;
572+ uiTSXYMaxMin |= (0xff << TSMAXMIN_XMAX_SHIFT) & TSMAXMIN_XMAX_MASK;
573+ uiTSXYMaxMin |= (0xff << TSMAXMIN_YMAX_SHIFT) & TSMAXMIN_YMAX_MASK;
574+ __raw_writel(uiTSXYMaxMin, EP93XX_TOUCHSCREEN_XYMAXMIN);
575+
576+ bCurrentPenDown = 0;
577+ bFreshTouchData = 0;
578+ guiLastX = 0;
579+ guiLastY = 0;
580+ guiLastInvPressure = 0xffffff;
581+
582+ /*
583+ * Enable the touch screen scanning engine.
584+ */
585+ TS_Hardware_Scan_Mode();
586+}
587+
588+/*
589+ * ep93xx_ts_shutdown
590+ *
591+ */
592+static void
593+ep93xx_ts_shutdown(void)
594+{
595+ unsigned int uiKTDIV;
596+
597+ sTouch.state = TS_STATE_STOPPED;
598+ Stop_Timer2();
599+
600+ /*
601+ * Disable the scanning engine.
602+ */
603+ __raw_writel(0, EP93XX_TOUCHSCREEN_SETUP);
604+ __raw_writel(0, EP93XX_TOUCHSCREEN_SETUP2);
605+
606+ /*
607+ * Clear the TSEN bit in KTDIV so that we are disabling the clock
608+ * for the touchscreen.
609+ */
610+ uiKTDIV = __raw_readl(EP93XX_SYSCON_KEYTCHCLKDIV);
611+ uiKTDIV &= ~EP93XX_SYSCON_KEYTCHCLKDIV_TSEN;
612+ ep93xx_syscon_swlocked_write(uiKTDIV, EP93XX_SYSCON_KEYTCHCLKDIV);
613+
614+} /* ep93xx_ts_shutdown */
615+
616+static irqreturn_t ep93xx_timer2_isr(int irq, void *dev_id)
617+{
618+ switch(sTouch.state)
619+ {
620+ case TS_STATE_STOPPED:
621+ TS_Hardware_Scan_Mode();
622+ break;
623+
624+ /*
625+ * Get the Z1 value for pressure measurement and set up
626+ * the switch register for getting the Z2 measurement.
627+ */
628+ case TS_STATE_Z1:
629+ Set_Timer2_uSec(EP93XX_TS_ADC_DELAY_USEC);
630+ sTouch.uiZ1 = ADCGetData(2, 200);
631+ ep93xx_ts_set_direct(sSwitchSettings.uiSwitchZ2);
632+ sTouch.state = TS_STATE_Z2;
633+ break;
634+
635+ /*
636+ * Get the Z2 value for pressure measurement and set up
637+ * the switch register for getting the Y measurement.
638+ */
639+ case TS_STATE_Z2:
640+ sTouch.uiZ2 = ADCGetData(2, 200);
641+ ep93xx_ts_set_direct(sSwitchSettings.uiYSample);
642+ sTouch.state = TS_STATE_Y;
643+ break;
644+
645+ /*
646+ * Get the Y value and set up the switch register for
647+ * getting the X measurement.
648+ */
649+ case TS_STATE_Y:
650+ sTouch.uiY = ADCGetData(4, 20);
651+ ep93xx_ts_set_direct(sSwitchSettings.uiXSample);
652+ sTouch.state = TS_STATE_X;
653+ break;
654+
655+ /*
656+ * Read the X value. This is the last of the 4 adc values
657+ * we need so we continue on to process the data.
658+ */
659+ case TS_STATE_X:
660+ Stop_Timer2();
661+
662+ sTouch.uiX = ADCGetData(4, 20);
663+
664+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
665+ __raw_writel(sSwitchSettings.uiDischarge, EP93XX_TOUCHSCREEN_DIRECT);
666+
667+ sTouch.state = TS_STATE_DONE;
668+
669+ /*
670+ * Process this set of ADC readings.
671+ */
672+ ProcessPointData();
673+
674+ break;
675+
676+ /*
677+ * Shouldn't get here. But if we do, we can recover...
678+ */
679+ case TS_STATE_DONE:
680+ TS_Hardware_Scan_Mode();
681+ break;
682+ }
683+
684+ /*
685+ * Clear the timer2 interrupt.
686+ */
687+ __raw_writel(1, EP93XX_TIMER2_CLEAR);
688+ return(IRQ_HANDLED);
689+}
690+
691+/*---------------------------------------------------------------------
692+ * ProcessPointData
693+ *
694+ * This routine processes the ADC data into usable point data and then
695+ * puts the driver into hw or sw scanning mode before returning.
696+ *
697+ * We calculate inverse pressure (lower number = more pressure) then
698+ * do a hystheresis with the two pressure values 'light' and 'heavy'.
699+ *
700+ * If we are above the light, we have pen up.
701+ * If we are below the heavy we have pen down.
702+ * As long as the pressure stays below the light, pen stays down.
703+ * When we get above the light again, pen goes back up.
704+ *
705+ */
706+static void ProcessPointData(void)
707+{
708+ int bValidPoint = 0;
709+ unsigned int uiXDiff, uiYDiff, uiInvPressureDiff;
710+ unsigned int uiInvPressure;
711+
712+ /*
713+ * Calculate the current pressure.
714+ */
715+ uiInvPressure = CalculateInvPressure();
716+
717+ /*
718+ * If pen pressure is so light that it is greater than the 'max' setting
719+ * then we consider this to be a pen up.
720+ */
721+ if (uiInvPressure >= TS_LIGHT_INV_PRESSURE)
722+ {
723+ bCurrentPenDown = 0;
724+ ee93xx_ts_evt_add(0, guiLastX, guiLastY, 0);
725+ TS_Hardware_Scan_Mode();
726+ return;
727+ }
728+
729+ /*
730+ * Hysteresis:
731+ * If the pen pressure is hard enough to be less than the 'min' OR
732+ * the pen is already down and is still less than the 'max'...
733+ */
734+ if ((uiInvPressure < TS_HEAVY_INV_PRESSURE) ||
735+ (bCurrentPenDown && (uiInvPressure < TS_LIGHT_INV_PRESSURE)))
736+ {
737+ if (bCurrentPenDown)
738+ {
739+ /*
740+ * If pen was previously down, check the difference between
741+ * the last sample and this one... if the difference between
742+ * samples is too great, ignore the sample.
743+ */
744+ uiXDiff = abs(guiLastX - sTouch.uiX);
745+ uiYDiff = abs(guiLastY - sTouch.uiY);
746+ uiInvPressureDiff = abs(guiLastInvPressure - uiInvPressure);
747+
748+ if (uiXDiff < TS_MAX_VALID_XY_CHANGE
749+ && uiYDiff < TS_MAX_VALID_XY_CHANGE
750+ && uiInvPressureDiff < TS_MAX_VALID_PRESSURE_CHANGE)
751+ {
752+ bValidPoint = 1;
753+ }
754+ }
755+ else
756+ {
757+ bValidPoint = 1;
758+ }
759+
760+ /*
761+ * If either the pen was put down or dragged make a note of it.
762+ */
763+ if (bValidPoint)
764+ {
765+ guiLastX = sTouch.uiX;
766+ guiLastY = sTouch.uiY;
767+ guiLastInvPressure = uiInvPressure;
768+ bCurrentPenDown = 1;
769+ ee93xx_ts_evt_add(1, sTouch.uiX, sTouch.uiY,
770+ 0x7000000 / uiInvPressure);
771+ }
772+
773+ TS_Soft_Scan_Mode();
774+ return;
775+ }
776+
777+ TS_Hardware_Scan_Mode();
778+}
779+
780+static void ep93xx_ts_set_direct(unsigned int uiADCSwitch)
781+{
782+ unsigned int uiResult;
783+
784+ /*
785+ * Set the switch settings in the direct register.
786+ */
787+ __raw_writel(0xaa, EP93XX_TOUCHSCREEN_SWLOCK);
788+ __raw_writel(uiADCSwitch, EP93XX_TOUCHSCREEN_DIRECT);
789+
790+ /*
791+ * Read and throw away the first sample.
792+ */
793+ do {
794+ uiResult = __raw_readl(EP93XX_TOUCHSCREEN_XYRESULT);
795+ } while (!(uiResult & TSXYRESULT_SDR));
796+
797+}
798+
799+static unsigned int ADCGetData(unsigned int uiSamples, unsigned int uiMaxDiff)
800+{
801+ unsigned int uiResult, uiValue, uiCount, uiLowest, uiHighest, uiSum, uiAve;
802+
803+ do
804+ {
805+ /*
806+ * Initialize our values.
807+ */
808+ uiLowest = 0xfffffff;
809+ uiHighest = 0;
810+ uiSum = 0;
811+
812+ for (uiCount = 0; uiCount < uiSamples; uiCount++)
813+ {
814+ /*
815+ * Read the touch screen four more times and average.
816+ */
817+ do {
818+ uiResult = __raw_readl(EP93XX_TOUCHSCREEN_XYRESULT);
819+ } while (!(uiResult & TSXYRESULT_SDR));
820+
821+ uiValue = (uiResult & TSXYRESULT_AD_MASK) >> TSXYRESULT_AD_SHIFT;
822+ uiValue = ((uiValue >> 4) + ((1 + TSXYRESULT_X_MASK)>>1)) & TSXYRESULT_X_MASK;
823+
824+ /*
825+ * Add up the values.
826+ */
827+ uiSum += uiValue;
828+
829+ /*
830+ * Get the lowest and highest values.
831+ */
832+ if (uiValue < uiLowest)
833+ {
834+ uiLowest = uiValue;
835+ }
836+ if (uiValue > uiHighest)
837+ {
838+ uiHighest = uiValue;
839+ }
840+ }
841+ } while ((uiHighest - uiLowest) > uiMaxDiff);
842+
843+ /*
844+ * Calculate the Average value.
845+ */
846+ uiAve = uiSum / uiSamples;
847+
848+ return uiAve;
849+}
850+
851+/*
852+ * CalculateInvPressure
853+ *
854+ * Is the Touch Valid. Touch is not valid if the X or Y value is not
855+ * in range and the pressure is not enough.
856+ *
857+ * Touch resistance can be measured by the following formula:
858+ *
859+ * Rx * X * Z2
860+ * Rtouch = --------- * (-- - 1)
861+ * 4096 Z1
862+ *
863+ * This is simplified in the ration of Rtouch to Rx. The lower the value, the
864+ * higher the pressure.
865+ *
866+ * Z2
867+ * InvPressure = X * (-- - 1)
868+ * Z1
869+ */
870+static unsigned int CalculateInvPressure(void)
871+{
872+ unsigned int uiInvPressure;
873+
874+ /*
875+ * Check to see if the point is valid.
876+ */
877+ if (sTouch.uiZ1 < MIN_Z1_VALUE)
878+ {
879+ uiInvPressure = 0x10000;
880+ }
881+
882+ /*
883+ * Can omit the pressure calculation if you need to get rid of the division.
884+ */
885+ else
886+ {
887+ uiInvPressure = ((sTouch.uiX * sTouch.uiZ2) / sTouch.uiZ1) - sTouch.uiX;
888+ }
889+
890+ return uiInvPressure;
891+}
892+
893+/*
894+ * TS_Hardware_Scan_Mode
895+ *
896+ * Enables the ep93xx ts scanning engine so that when the pen goes down
897+ * we will get an interrupt.
898+ */
899+static void TS_Hardware_Scan_Mode(void)
900+{
901+ unsigned int uiDevCfg;
902+
903+ /*
904+ * Disable the soft scanning engine.
905+ */
906+ sTouch.state = TS_STATE_STOPPED;
907+ Stop_Timer2();
908+
909+ /*
910+ * Clear the TIN (Touchscreen INactive) bit so we can go to
911+ * automatic scanning mode.
912+ */
913+ uiDevCfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
914+ ep93xx_syscon_swlocked_write(uiDevCfg & ~EP93XX_SYSCON_DEVCFG_TIN,
915+ EP93XX_SYSCON_DEVCFG);
916+
917+ /*
918+ * Enable the touch screen scanning state machine by setting
919+ * the ENABLE bit.
920+ */
921+ __raw_writel(TSSETUP_DEFAULT | TSSETUP_ENABLE, EP93XX_TOUCHSCREEN_SETUP);
922+
923+ /*
924+ * Set the flag to show that we are in interrupt mode.
925+ */
926+ gScanningMode = TS_MODE_HARDWARE_SCAN;
927+
928+ /*
929+ * Initialize EP93XX_TOUCHSCREEN_SETUP2 register.
930+ */
931+ __raw_writel(TSSETUP2_DEFAULT, EP93XX_TOUCHSCREEN_SETUP2);
932+
933+}
934+
935+/*
936+ * TS_Soft_Scan_Mode
937+ *
938+ * Sets the touch screen to manual polling mode.
939+ */
940+static void TS_Soft_Scan_Mode(void)
941+{
942+ unsigned int uiDevCfg;
943+
944+ if (gScanningMode != TS_MODE_SOFT_SCAN)
945+ {
946+ /*
947+ * Disable the touch screen scanning state machine by clearing
948+ * the ENABLE bit.
949+ */
950+ __raw_writel(TSSETUP_DEFAULT, EP93XX_TOUCHSCREEN_SETUP);
951+
952+ /*
953+ * Set the TIN bit so we can do manual touchscreen polling.
954+ */
955+ uiDevCfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
956+ ep93xx_syscon_swlocked_write(uiDevCfg | EP93XX_SYSCON_DEVCFG_TIN,
957+ EP93XX_SYSCON_DEVCFG);
958+ }
959+
960+ /*
961+ * Set the switch register up for the first ADC reading
962+ */
963+ ep93xx_ts_set_direct(sSwitchSettings.uiSwitchZ1);
964+
965+ /*
966+ * Initialize our software state machine to know which ADC
967+ * reading to take
968+ */
969+ sTouch.state = TS_STATE_Z1;
970+
971+ /*
972+ * Set the timer so after a mSec or two settling delay it will
973+ * take the first ADC reading.
974+ */
975+ Set_Timer2_uSec(EP93XX_TS_PER_POINT_DELAY_USEC);
976+
977+ /*
978+ * Note that we are in sw scanning mode not hw scanning mode.
979+ */
980+ gScanningMode = TS_MODE_SOFT_SCAN;
981+
982+}
983+
984+static void Set_Timer2_uSec(unsigned int uiDelay_uSec)
985+{
986+ unsigned int uiClockTicks;
987+
988+ /*
989+ * Stop timer 2
990+ */
991+ __raw_writel(0, EP93XX_TIMER2_CONTROL);
992+
993+ uiClockTicks = ((uiDelay_uSec * 508) + 999) / 1000;
994+ __raw_writel(uiClockTicks, EP93XX_TIMER2_LOAD);
995+ __raw_writel(uiClockTicks, EP93XX_TIMER2_VALUE);
996+
997+ /*
998+ * Set up Timer 2 for 508 kHz clock and periodic mode.
999+ */
1000+ __raw_writel(0xC8, EP93XX_TIMER2_CONTROL);
1001+
1002+}
1003+
1004+static void Stop_Timer2(void)
1005+{
1006+ __raw_writel(0, EP93XX_TIMER2_CONTROL);
1007+}
1008+
1009+/*
1010+ * Initialization and exit routines
1011+ */
1012+int __init ep93xx_ts_init(void)
1013+{
1014+ int retval;
1015+
1016+ retval = request_irq(IRQ_EP93XX_TOUCH, ep93xx_ts_isr,
1017+ IRQF_DISABLED, "ep93xx_ts", 0);
1018+ if (retval)
1019+ {
1020+ printk(KERN_WARNING "ep93xx_ts: failed to get touchscreen IRQ\n");
1021+ return retval;
1022+ }
1023+
1024+ retval = request_irq(IRQ_EP93XX_TIMER2, ep93xx_timer2_isr,
1025+ IRQF_DISABLED, "ep93xx_timer2", 0);
1026+ if (retval)
1027+ {
1028+ printk(KERN_WARNING "ep93xx_ts: failed to get timer2 IRQ\n");
1029+ free_irq(IRQ_EP93XX_TOUCH, 0);
1030+ return retval;
1031+ }
1032+
1033+ misc_register(&ep93xx_ts_miscdev);
1034+
1035+ sTouch.state = TS_STATE_STOPPED;
1036+ gScanningMode = TS_MODE_UN_INITIALIZED;
1037+
1038+ printk(KERN_NOTICE "ep93xx touchscreen driver configured for 4-wire operation\n");
1039+
1040+ return 0;
1041+}
1042+
1043+void __exit ep93xx_ts_exit(void)
1044+{
1045+ Stop_Timer2();
1046+
1047+ free_irq(IRQ_EP93XX_TOUCH, 0);
1048+ free_irq(IRQ_EP93XX_TIMER2, 0);
1049+
1050+ misc_deregister(&ep93xx_ts_miscdev);
1051+}
1052+
1053+module_init(ep93xx_ts_init);
1054+module_exit(ep93xx_ts_exit);
1055+
1056+MODULE_DESCRIPTION("Cirrus EP93xx touchscreen driver");
1057+MODULE_SUPPORTED_DEVICE("touchscreen/ep93xx");
1058+MODULE_LICENSE("GPL");
target/linux/ep93xx/patches-2.6.39/004-simone_add_mmc_spi.patch
1This enables the mmc-over-spi driver for the Sim.One board, based on Mika's
2patch, which used a GPIO for chip select in stead of the default SFRMOUT pin.
3I've modified it to use the usual SFRMOUT; if you've modified your Sim.One
4board to use a GPIO instead, uncomment and modify
5// #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO15
6in the source file.
7   -martinwguy, 14 May 2010
8
9From: Mika Westerberg <mika.westerberg@iki.fi>
10Date: Wed, 28 Apr 2010 08:42:46 +0300
11Subject: [PATCH] ep93xx: simone: added board specific SPI support for MMC/SD cards
12
13This includes setting up EGPIOs 0 and 9 for card detection and chip select
14respectively.
15
16--- a/arch/arm/mach-ep93xx/simone.c
17@@ -18,12 +18,16 @@
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/platform_device.h>
21+#include <linux/mmc/host.h>
22 #include <linux/gpio.h>
23+#include <linux/spi/spi.h>
24+#include <linux/spi/mmc_spi.h>
25 #include <linux/i2c.h>
26 #include <linux/i2c-gpio.h>
27
28 #include <mach/hardware.h>
29 #include <mach/fb.h>
30+#include <mach/ep93xx_spi.h>
31
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34@@ -38,6 +42,135 @@ static struct ep93xxfb_mach_info __initd
35     .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
36 };
37
38+/*
39+ * GPIO lines used for MMC card detection.
40+ */
41+#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0
42+
43+/*
44+ * If you have hacked your Sim.One to use a GPIO as SD card chip select
45+ * (SD pin 1), uncomment the following line.
46+ * The example, EGPIO15, is on TP17 near the CPU.
47+ */
48+// #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO15
49+
50+/*
51+ * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal,
52+ * you can leave these empty and pass NULL as .controller_data.
53+ */
54+
55+#ifdef MMC_CHIP_SELECT_GPIO
56+static int simone_mmc_spi_setup(struct spi_device *spi)
57+{
58+ unsigned int gpio = MMC_CHIP_SELECT_GPIO;
59+ int err;
60+
61+ err = gpio_request(gpio, spi->modalias);
62+ if (err)
63+ return err;
64+
65+ err = gpio_direction_output(gpio, 1);
66+ if (err) {
67+ gpio_free(gpio);
68+ return err;
69+ }
70+
71+ return 0;
72+}
73+
74+static void simone_mmc_spi_cleanup(struct spi_device *spi)
75+{
76+ unsigned int gpio = MMC_CHIP_SELECT_GPIO;
77+
78+ gpio_set_value(gpio, 1);
79+ gpio_direction_input(gpio);
80+ gpio_free(gpio);
81+}
82+
83+static void simone_mmc_spi_cs_control(struct spi_device *spi, int value)
84+{
85+ gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
86+}
87+
88+static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = {
89+ .setup = simone_mmc_spi_setup,
90+ .cleanup = simone_mmc_spi_cleanup,
91+ .cs_control = simone_mmc_spi_cs_control,
92+};
93+#endif
94+
95+/*
96+ * MMC card detection GPIO setup.
97+ */
98+static int simone_mmc_spi_init(struct device *dev,
99+ irqreturn_t (*irq_handler)(int, void *), void *mmc)
100+{
101+ unsigned int gpio = MMC_CARD_DETECT_GPIO;
102+ int irq, err;
103+
104+ err = gpio_request(gpio, dev_name(dev));
105+ if (err)
106+ return err;
107+
108+ err = gpio_direction_input(gpio);
109+ if (err)
110+ goto fail;
111+
112+ irq = gpio_to_irq(gpio);
113+ if (irq < 0)
114+ goto fail;
115+
116+ err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING,
117+ "MMC card detect", mmc);
118+ if (err)
119+ goto fail;
120+
121+ printk(KERN_INFO "%s: using irq %d for MMC card detection\n",
122+ dev_name(dev), irq);
123+
124+ return 0;
125+fail:
126+ gpio_free(gpio);
127+ return err;
128+}
129+
130+static void simone_mmc_spi_exit(struct device *dev, void *mmc)
131+{
132+ unsigned int gpio = MMC_CARD_DETECT_GPIO;
133+
134+ free_irq(gpio_to_irq(gpio), mmc);
135+ gpio_free(gpio);
136+}
137+
138+static struct mmc_spi_platform_data simone_mmc_spi_data = {
139+ .init = simone_mmc_spi_init,
140+ .exit = simone_mmc_spi_exit,
141+ .detect_delay = 500,
142+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
143+};
144+
145+static struct spi_board_info simone_spi_devices[] __initdata = {
146+ {
147+ .modalias = "mmc_spi",
148+#ifdef MMC_CHIP_SELECT_GPIO
149+ .controller_data = &simone_mmc_spi_ops,
150+#endif
151+ .platform_data = &simone_mmc_spi_data,
152+ /*
153+ * We use 10 MHz even though the maximum is 3.7 MHz. The driver
154+ * will limit it automatically to max. frequency.
155+ */
156+ .max_speed_hz = 10 * 1000 * 1000,
157+ .bus_num = 0,
158+ .chip_select = 0,
159+ .mode = SPI_MODE_3,
160+ },
161+};
162+
163+static struct ep93xx_spi_info simone_spi_info __initdata = {
164+ .num_chipselect = ARRAY_SIZE(simone_spi_devices),
165+};
166+
167 static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
168     .sda_pin = EP93XX_GPIO_LINE_EEDAT,
169     .sda_is_open_drain = 0,
170@@ -61,6 +194,8 @@ static void __init simone_init_machine(v
171     ep93xx_register_fb(&simone_fb_info);
172     ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
173                 ARRAY_SIZE(simone_i2c_board_info));
174+ ep93xx_register_spi(&simone_spi_info, simone_spi_devices,
175+ ARRAY_SIZE(simone_spi_devices));
176     ep93xx_register_ac97();
177 }
178

Archive Download the corresponding diff file



interactive