Date:2011-08-22 10:19:14 (3 years 1 month ago)
Author:Xiangfu Liu
Commit:fd6b4ce429fdbe226beebd660535e8088e2dc886
Message:ben nanonote: forward patches to linux-3.0

Files: target/linux/xburst/Makefile (1 diff)
target/linux/xburst/config-3.0 (1 diff)
target/linux/xburst/patches-3.0/0001-JZ4740-cache-quirks.patch (1 diff)
target/linux/xburst/patches-3.0/0002-Add-n516-board-support.patch (1 diff)
target/linux/xburst/patches-3.0/0003-Add-n526-board-support.patch (1 diff)
target/linux/xburst/patches-3.0/0004-MIPS-JZ4740-Add-id800wt-board.patch (1 diff)
target/linux/xburst/patches-3.0/0005-Add-N516-sound-SoC-board-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0006-Add-n516-lpc-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0007-Add-N526-sound-SoC-board-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0008-i2c-Add-i2c-driver-for-JZ47XX-SoCs.patch (1 diff)
target/linux/xburst/patches-3.0/0009-MIPS-JZ4740-Fix-i2c-driver-name.patch (1 diff)
target/linux/xburst/patches-3.0/0010-MFD-jz4740-adc-Add-support-for-the-touchscreen-part-.patch (1 diff)
target/linux/xburst/patches-3.0/0011-input-Add-touchscreen-driver-for-the-JZ4740-SoC.patch (1 diff)
target/linux/xburst/patches-3.0/0012-Add-ili8960-lcd-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0013-Add-jz4740-udc-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0014-Framebuffer-notifier-Call-notifier-callbacks-prior-t.patch (1 diff)
target/linux/xburst/patches-3.0/0015-500-modifier-keys.patch.patch (1 diff)
target/linux/xburst/patches-3.0/0016-850-ks7010-support.patch.patch (1 diff)
target/linux/xburst/patches-3.0/0017-900-add-openwrt-logo.patch (1 diff)
target/linux/xburst/patches-3.0/0018-901-ubi-Read-only-the-vid-header-instead-of-the-whol.patch (1 diff)
target/linux/xburst/patches-3.0/0019-902-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch.patch (1 diff)
target/linux/xburst/patches-3.0/0020-903-NAND-Add-support-for-subpage-reads-for-NAND_ECC_.patch (1 diff)
target/linux/xburst/patches-3.0/0021-904-NAND-Optimize-reading-the-eec-data-for-the-JZ474.patch (1 diff)
target/linux/xburst/patches-3.0/0022-qi_lb60-Don-t-use-3-wire-spi-mode-for-the-display-fo.patch (1 diff)
target/linux/xburst/patches-3.0/0023-qi_lb60-NAND-add-data-partition.patch (1 diff)
target/linux/xburst/patches-3.0/0024-forward-code-to-linux-3.0.patch (1 diff)
target/linux/xburst/patches-3.0/0025-Update-to-new-platform-code.patch (1 diff)
target/linux/xburst/patches-3.0/0026-sound-update-DMA-code.patch (1 diff)
target/linux/xburst/patches-3.0/0027-Add-DEVMEM-support.patch (1 diff)
target/linux/xburst/patches-3.0/0028-Add-cpufreq-support.patch (1 diff)
target/linux/xburst/patches-3.0/0029-Add-new-jz4740_lcd.h.patch (1 diff)
target/linux/xburst/qi_lb60/config-3.0 (1 diff)

Change Details

target/linux/xburst/Makefile
1212FEATURES:=jffs2 targz ubifs audio
1313SUBTARGETS:=qi_lb60 n516 n526 id800wt
1414
15LINUX_VERSION:=2.6.37.6
15LINUX_VERSION:=3.0
1616
1717DEVICE_TYPE=other
1818
target/linux/xburst/config-3.0
1
2CONFIG_32BIT=y
3# CONFIG_64BIT is not set
4# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
5# CONFIG_AR7 is not set
6# CONFIG_ARCH_HAS_ILOG2_U32 is not set
7# CONFIG_ARCH_HAS_ILOG2_U64 is not set
8CONFIG_ARCH_HIBERNATION_POSSIBLE=y
9# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
10CONFIG_ARCH_POPULATES_NODE_MAP=y
11CONFIG_ARCH_REQUIRE_GPIOLIB=y
12# CONFIG_ARCH_SUPPORTS_MSI is not set
13CONFIG_ARCH_SUPPORTS_OPROFILE=y
14CONFIG_ARCH_SUSPEND_POSSIBLE=y
15# CONFIG_ARPD is not set
16# CONFIG_AUTO_IRQ_AFFINITY is not set
17# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
18# CONFIG_BACKLIGHT_GENERIC is not set
19# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
20# CONFIG_BATTERY_BQ20Z75 is not set
21CONFIG_BATTERY_JZ4740=y
22# CONFIG_BCM47XX is not set
23# CONFIG_BCM63XX is not set
24CONFIG_BITREVERSE=y
25# CONFIG_BKL is not set
26# CONFIG_BLK_DEV_INITRD is not set
27# CONFIG_BMP085 is not set
28# CONFIG_BRIDGE is not set
29# CONFIG_BSD_PROCESS_ACCT is not set
30# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
31# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
32CONFIG_CHARGER_GPIO=y
33CONFIG_CONSOLE_TRANSLATIONS=y
34# CONFIG_CPU_BIG_ENDIAN is not set
35# CONFIG_CPU_CAVIUM_OCTEON is not set
36CONFIG_CPU_HAS_PREFETCH=y
37CONFIG_CPU_HAS_SYNC=y
38CONFIG_CPU_LITTLE_ENDIAN=y
39# CONFIG_CPU_LOONGSON2E is not set
40# CONFIG_CPU_LOONGSON2F is not set
41CONFIG_CPU_MIPS32_R1=y
42# CONFIG_CPU_MIPS32_R2 is not set
43CONFIG_CPU_MIPS32=y
44# CONFIG_CPU_MIPS64_R1 is not set
45# CONFIG_CPU_MIPS64_R2 is not set
46CONFIG_CPU_MIPSR1=y
47# CONFIG_CPU_NEVADA is not set
48# CONFIG_CPU_R10000 is not set
49# CONFIG_CPU_R3000 is not set
50# CONFIG_CPU_R4300 is not set
51# CONFIG_CPU_R4X00 is not set
52# CONFIG_CPU_R5000 is not set
53# CONFIG_CPU_R5432 is not set
54# CONFIG_CPU_R5500 is not set
55# CONFIG_CPU_R6000 is not set
56# CONFIG_CPU_R8000 is not set
57# CONFIG_CPU_RM7000 is not set
58# CONFIG_CPU_RM9000 is not set
59# CONFIG_CPU_SB1 is not set
60CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
61CONFIG_CPU_SUPPORTS_HIGHMEM=y
62# CONFIG_CPU_TX39XX is not set
63# CONFIG_CPU_TX49XX is not set
64# CONFIG_CPU_VR41XX is not set
65CONFIG_CRC16=y
66CONFIG_CRYPTO_DEFLATE=y
67CONFIG_CRYPTO_LZO=y
68CONFIG_DEFAULT_AS=y
69CONFIG_DMA_NEED_PCI_MAP_STATE=y
70CONFIG_DMA_NONCOHERENT=y
71CONFIG_DUMMY_CONSOLE=y
72CONFIG_EARLY_PRINTK=y
73CONFIG_ELF_CORE=y
74CONFIG_ENABLE_MUST_CHECK=y
75CONFIG_EXT4_FS=y
76CONFIG_FAT_FS=y
77# CONFIG_FB_JZ4740 is not set
78CONFIG_FB_SYS_COPYAREA=y
79CONFIG_FB_SYS_FILLRECT=y
80CONFIG_FB_SYS_IMAGEBLIT=y
81CONFIG_FB=y
82# CONFIG_FIRMWARE_EDID is not set
83CONFIG_FONTS=y
84# CONFIG_FONT_10x18 is not set
85# CONFIG_FONT_6x11 is not set
86# CONFIG_FONT_7x14 is not set
87# CONFIG_FONT_8x16 is not set
88# CONFIG_FONT_8x8 is not set
89# CONFIG_FONT_ACORN_8x8 is not set
90# CONFIG_FONT_MINI_4x6 is not set
91# CONFIG_FONT_PEARL_8x8 is not set
92# CONFIG_FONT_SUN12x22 is not set
93CONFIG_FONT_SUN8x16=y
94CONFIG_FORCE_MAX_ZONEORDER=12
95# CONFIG_FRAMEBUFFER_CONSOLE is not set
96# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
97# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
98CONFIG_FREEZER=y
99CONFIG_GENERIC_ATOMIC64=y
100CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
101CONFIG_GENERIC_CLOCKEVENTS=y
102CONFIG_GENERIC_CMOS_UPDATE=y
103CONFIG_GENERIC_FIND_LAST_BIT=y
104CONFIG_GENERIC_FIND_NEXT_BIT=y
105CONFIG_GENERIC_GPIO=y
106CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
107# CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED is not set
108# CONFIG_GENERIC_PENDING_IRQ is not set
109CONFIG_GPIOLIB=y
110# CONFIG_GPIO_SX150X is not set
111# CONFIG_HAMRADIO is not set
112# CONFIG_HARDLOCKUP_DETECTOR is not set
113# CONFIG_HARDIRQS_SW_RESEND is not set
114CONFIG_HARDWARE_WATCHPOINTS=y
115CONFIG_HAS_DMA=y
116CONFIG_HAS_IOMEM=y
117CONFIG_HAS_IOPORT=y
118CONFIG_HAVE_ARCH_KGDB=y
119CONFIG_HAVE_C_RECORDMCOUNT=y
120CONFIG_HAVE_DMA_API_DEBUG=y
121CONFIG_HAVE_DMA_ATTRS=y
122CONFIG_HAVE_DYNAMIC_FTRACE=y
123CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
124CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
125CONFIG_HAVE_FUNCTION_TRACER=y
126CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
127CONFIG_HAVE_GENERIC_HARDIRQS=y
128CONFIG_HAVE_GENERIC_DMA_COHERENT=y
129CONFIG_HAVE_IDE=y
130CONFIG_HAVE_KPROBES=y
131CONFIG_HAVE_KRETPROBES=y
132CONFIG_HAVE_OPROFILE=y
133CONFIG_HAVE_PERF_EVENTS=y
134CONFIG_HAVE_PWM=y
135# CONFIG_HAVE_SPARSE_IRQ is not set
136# CONFIG_HIBERNATION is not set
137# CONFIG_HIGH_RES_TIMERS is not set
138CONFIG_HW_CONSOLE=y
139# CONFIG_HW_RANDOM is not set
140# CONFIG_I2C_JZ47XX is not set
141# CONFIG_INLINE_READ_UNLOCK is not set
142# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
143# CONFIG_INLINE_SPIN_UNLOCK is not set
144# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
145# CONFIG_INLINE_WRITE_UNLOCK is not set
146# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
147CONFIG_INOTIFY_USER=y
148CONFIG_INPUT_EVDEV=y
149# CONFIG_INPUT_GPIO_BUTTONS is not set
150CONFIG_INPUT_KEYBOARD=y
151# CONFIG_INPUT_PWM_BEEPER is not set
152CONFIG_INPUT=y
153CONFIG_IRQ_CPU=y
154# CONFIG_IRQ_PER_CPU is not set
155CONFIG_JBD=y
156CONFIG_JBD2=y
157# CONFIG_JZ4740_ADC is not set
158# CONFIG_JZ4740_ID800WT is not set
159# CONFIG_JZ4740_N516 is not set
160# CONFIG_JZ4740_N526 is not set
161# CONFIG_JZ4740_QI_LB60 is not set
162CONFIG_KALLSYMS=y
163# CONFIG_KEYBOARD_ATKBD is not set
164# CONFIG_KEYBOARD_GPIO is not set
165# CONFIG_KEYBOARD_LKKBD is not set
166# CONFIG_KEYBOARD_MATRIX is not set
167# CONFIG_KEYBOARD_MCS is not set
168# CONFIG_KEYBOARD_NEWTON is not set
169# CONFIG_KEYBOARD_STOWAWAY is not set
170# CONFIG_KEYBOARD_SUNKBD is not set
171# CONFIG_KEYBOARD_XTKBD is not set
172# CONFIG_LCD_CLASS_DEVICE is not set
173# CONFIG_LCD_GPM940B0 is not set
174# CONFIG_LCD_ILI9320 is not set
175# CONFIG_LCD_L4F00242T03 is not set
176# CONFIG_LCD_LMS283GF05 is not set
177# CONFIG_LCD_LTV350QV is not set
178# CONFIG_LCD_PLATFORM is not set
179# CONFIG_LCD_TDO24M is not set
180# CONFIG_LCD_VGG2432A4 is not set
181# CONFIG_LEDS_PWM is not set
182CONFIG_LEGACY_PTYS=y
183CONFIG_LEGACY_PTY_COUNT=2
184CONFIG_LOCK_KERNEL=y
185# CONFIG_LOGO is not set
186# CONFIG_LOGO_LINUX_CLUT224 is not set
187# CONFIG_LOGO_LINUX_MONO is not set
188# CONFIG_LOGO_LINUX_VGA16 is not set
189# CONFIG_LOGO_OPENWRT_CLUT224 is not set
190# CONFIG_LOONGSON_MC146818 is not set
191CONFIG_LOONGSON_UART_BASE=y
192CONFIG_LZO_COMPRESS=y
193CONFIG_LZO_DECOMPRESS=y
194# CONFIG_MACH_ALCHEMY is not set
195# CONFIG_MACH_DECSTATION is not set
196# CONFIG_MACH_JAZZ is not set
197CONFIG_MACH_JZ4740=y
198# CONFIG_MACH_LOONGSON is not set
199# CONFIG_MACH_TX39XX is not set
200# CONFIG_MACH_TX49XX is not set
201# CONFIG_MACH_VR41XX is not set
202# CONFIG_MIPS_ALCHEMY is not set
203# CONFIG_MFD_JZ4740_ADC is not set
204# CONFIG_MFD_MAX8998 is not set
205# CONFIG_MFD_STMPE is not set
206# CONFIG_MFD_TPS6586X is not set
207# CONFIG_MIKROTIK_RB532 is not set
208# CONFIG_MINI_FO is not set
209# CONFIG_MIPS_COBALT is not set
210CONFIG_MIPS_L1_CACHE_SHIFT=5
211# CONFIG_MIPS_MACHINE is not set
212# CONFIG_MIPS_MALTA is not set
213CONFIG_MIPS_MT_DISABLED=y
214# CONFIG_MIPS_MT_SMP is not set
215# CONFIG_MIPS_MT_SMTC is not set
216# CONFIG_MIPS_SIM is not set
217CONFIG_MIPS=y
218# CONFIG_MMC_AT91 is not set
219# CONFIG_MMC_ATMELMCI is not set
220# CONFIG_MMC_BLOCK_BOUNCE is not set
221CONFIG_MMC_BLOCK=y
222CONFIG_MMC_JZ4740=y
223CONFIG_MMC_UNSAFE_RESUME=y
224CONFIG_MMC=y
225# CONFIG_MTD_CFI is not set
226# CONFIG_MTD_COMPLEX_MAPPINGS is not set
227CONFIG_MTD_NAND_JZ4740=y
228# CONFIG_MTD_NAND_VERIFY_WRITE is not set
229CONFIG_MTD_NAND=y
230CONFIG_MTD_NAND_ECC=y
231# CONFIG_MTD_SM_COMMON is not set
232CONFIG_MTD_UBI_BEB_RESERVE=1
233# CONFIG_MTD_UBI_DEBUG is not set
234# CONFIG_MTD_UBI_GLUEBI is not set
235CONFIG_MTD_UBI_WL_THRESHOLD=4096
236CONFIG_MTD_UBI=y
237# CONFIG_N516_LPC is not set
238CONFIG_NEED_DMA_MAP_STATE=y
239CONFIG_NEED_PER_CPU_KM=y
240# CONFIG_NETDEV_1000 is not set
241# CONFIG_NETWORK_FILESYSTEMS is not set
242# CONFIG_NET_ETHERNET is not set
243# CONFIG_NET_SCHED is not set
244# CONFIG_NEW_LEDS is not set
245CONFIG_NLS_ASCII=y
246CONFIG_NLS_CODEPAGE_1250=y
247CONFIG_NLS_CODEPAGE_1251=y
248CONFIG_NLS_CODEPAGE_437=y
249CONFIG_NLS_CODEPAGE_737=y
250CONFIG_NLS_CODEPAGE_775=y
251CONFIG_NLS_CODEPAGE_850=y
252CONFIG_NLS_CODEPAGE_852=y
253CONFIG_NLS_CODEPAGE_855=y
254CONFIG_NLS_CODEPAGE_857=y
255CONFIG_NLS_CODEPAGE_860=y
256CONFIG_NLS_CODEPAGE_861=y
257CONFIG_NLS_CODEPAGE_862=y
258CONFIG_NLS_CODEPAGE_863=y
259CONFIG_NLS_CODEPAGE_864=y
260CONFIG_NLS_CODEPAGE_865=y
261CONFIG_NLS_CODEPAGE_866=y
262CONFIG_NLS_CODEPAGE_869=y
263CONFIG_NLS_CODEPAGE_874=y
264CONFIG_NLS_CODEPAGE_932=y
265CONFIG_NLS_CODEPAGE_936=y
266CONFIG_NLS_CODEPAGE_949=y
267CONFIG_NLS_CODEPAGE_950=y
268CONFIG_NLS_ISO8859_13=y
269CONFIG_NLS_ISO8859_14=y
270CONFIG_NLS_ISO8859_15=y
271CONFIG_NLS_ISO8859_1=y
272CONFIG_NLS_ISO8859_2=y
273CONFIG_NLS_ISO8859_3=y
274CONFIG_NLS_ISO8859_4=y
275CONFIG_NLS_ISO8859_5=y
276CONFIG_NLS_ISO8859_6=y
277CONFIG_NLS_ISO8859_7=y
278CONFIG_NLS_ISO8859_8=y
279CONFIG_NLS_ISO8859_9=y
280CONFIG_NLS_KOI8_R=y
281CONFIG_NLS_KOI8_U=y
282CONFIG_NLS_UTF8=y
283CONFIG_NLS=y
284# CONFIG_NO_IOPORT is not set
285# CONFIG_NXP_STB220 is not set
286# CONFIG_NXP_STB225 is not set
287# CONFIG_PACKET_MMAP is not set
288CONFIG_PAGEFLAGS_EXTENDED=y
289# CONFIG_PCI is not set
290# CONFIG_PDA_POWER is not set
291CONFIG_PERF_USE_VMALLOC=y
292# CONFIG_PMC_MSP is not set
293# CONFIG_PMC_YOSEMITE is not set
294# CONFIG_PM_DEBUG is not set
295CONFIG_PM_OPS=y
296# CONFIG_PM_RUNTIME is not set
297CONFIG_PM_SLEEP=y
298CONFIG_PM=y
299# CONFIG_PNX8550_JBS is not set
300# CONFIG_PNX8550_STB810 is not set
301# CONFIG_POWERTV is not set
302# CONFIG_POWER_SUPPLY_DEBUG is not set
303CONFIG_POWER_SUPPLY=y
304# CONFIG_PREEMPT_NONE is not set
305# CONFIG_PREEMPT_RCU is not set
306CONFIG_PREEMPT=y
307CONFIG_PRINTK_TIME=y
308CONFIG_PROC_PAGE_MONITOR=y
309# CONFIG_QUOTACTL is not set
310CONFIG_RTC_CLASS=y
311# CONFIG_RTC_DRV_CMOS is not set
312# CONFIG_RTC_DRV_DS3232 is not set
313# CONFIG_RTC_DRV_ISL12022 is not set
314CONFIG_RTC_DRV_JZ4740=y
315CONFIG_SCHED_OMIT_FRAME_POINTER=y
316# CONFIG_SCSI_DMA is not set
317CONFIG_SCSI_MOD=y
318# CONFIG_SDIO_UART is not set
319# CONFIG_SENSORS_BH1780 is not set
320# CONFIG_SENSORS_EMC2103 is not set
321# CONFIG_SENSORS_JC42 is not set
322# CONFIG_SENSORS_JZ4740 is not set
323# CONFIG_SENSORS_SMM665 is not set
324# CONFIG_SERIAL_8250_EXTENDED is not set
325# CONFIG_SERIAL_MAX3107 is not set
326# CONFIG_SGI_IP22 is not set
327# CONFIG_SGI_IP27 is not set
328# CONFIG_SGI_IP28 is not set
329# CONFIG_SGI_IP32 is not set
330# CONFIG_SIBYTE_BIGSUR is not set
331# CONFIG_SIBYTE_CARMEL is not set
332# CONFIG_SIBYTE_CRHINE is not set
333# CONFIG_SIBYTE_CRHONE is not set
334# CONFIG_SIBYTE_LITTLESUR is not set
335# CONFIG_SIBYTE_RHONE is not set
336# CONFIG_SIBYTE_SENTOSA is not set
337# CONFIG_SIBYTE_SWARM is not set
338# CONFIG_SND_JZ4740_SOC_N516 is not set
339# CONFIG_SND_JZ4740_SOC_N526 is not set
340# CONFIG_SND_JZ4740_SOC_QI_LB60 is not set
341# CONFIG_SND_SOC_ALL_CODECS is not set
342# CONFIG_SND_SOC_JZ4740 is not set
343# CONFIG_SPI_SPIDEV is not set
344# CONFIG_SQUASHFS is not set
345# CONFIG_STAGING is not set
346CONFIG_SUSPEND_FREEZER=y
347CONFIG_SUSPEND_NVS=y
348CONFIG_SUSPEND=y
349# CONFIG_SYN_COOKIES is not set
350CONFIG_SYS_HAS_CPU_MIPS32_R1=y
351CONFIG_SYS_HAS_EARLY_PRINTK=y
352CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
353CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
354CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
355# CONFIG_TEST_POWER is not set
356# CONFIG_TINY_PREEMPT_RCU is not set
357CONFIG_TRAD_SIGNALS=y
358CONFIG_UBIFS_FS_ADVANCED_COMPR=y
359# CONFIG_UBIFS_FS_DEBUG is not set
360CONFIG_UBIFS_FS_LZO=y
361# CONFIG_UBIFS_FS_XATTR is not set
362CONFIG_UBIFS_FS_ZLIB=y
363CONFIG_UBIFS_FS=y
364# CONFIG_USB_ARCH_HAS_EHCI is not set
365CONFIG_USB_ARCH_HAS_HCD=y
366CONFIG_USB_ARCH_HAS_OHCI=y
367# CONFIG_USB_AUDIO is not set
368# CONFIG_USB_CDC_COMPOSITE is not set
369# CONFIG_USB_ETH_EEM is not set
370# CONFIG_USB_ETH_RNDIS is not set
371CONFIG_USB_ETH=y
372# CONFIG_USB_FILE_STORAGE is not set
373# CONFIG_USB_FUNCTIONFS is not set
374# CONFIG_USB_GADGETFS is not set
375# CONFIG_USB_GADGET_AMD5536UDC is not set
376# CONFIG_USB_GADGET_AT91 is not set
377# CONFIG_USB_GADGET_ATMEL_USBA is not set
378# CONFIG_USB_GADGET_CI13XXX is not set
379# CONFIG_USB_GADGET_DEBUG_FILES is not set
380# CONFIG_USB_GADGET_DEBUG_FS is not set
381CONFIG_USB_GADGET_DUALSPEED=y
382# CONFIG_USB_GADGET_DUMMY_HCD is not set
383# CONFIG_USB_GADGET_FSL_QE is not set
384# CONFIG_USB_GADGET_FSL_USB2 is not set
385# CONFIG_USB_GADGET_GOKU is not set
386# CONFIG_USB_GADGET_IMX is not set
387CONFIG_USB_GADGET_JZ4740=y
388# CONFIG_USB_GADGET_LANGWELL is not set
389# CONFIG_USB_GADGET_LH7A40X is not set
390# CONFIG_USB_GADGET_M66592 is not set
391# CONFIG_USB_GADGET_MUSB_HDRC is not set
392# CONFIG_USB_GADGET_NET2280 is not set
393# CONFIG_USB_GADGET_OMAP is not set
394# CONFIG_USB_GADGET_PXA25X is not set
395# CONFIG_USB_GADGET_PXA27X is not set
396# CONFIG_USB_GADGET_R8A66597 is not set
397# CONFIG_USB_GADGET_S3C2410 is not set
398# CONFIG_USB_GADGET_S3C_HSOTG is not set
399CONFIG_USB_GADGET_SELECTED=y
400CONFIG_USB_GADGET_VBUS_DRAW=2
401CONFIG_USB_GADGET=y
402# CONFIG_USB_G_DBGP is not set
403# CONFIG_USB_G_HID is not set
404# CONFIG_USB_G_PRINTER is not set
405# CONFIG_USB_G_SERIAL is not set
406# CONFIG_USB_G_WEBCAM is not set
407CONFIG_USB_JZ4740=y
408# CONFIG_USB_MIDI_GADGET is not set
409CONFIG_USB_SUPPORT=y
410# CONFIG_USB_ZERO is not set
411CONFIG_VFAT_FS=y
412# CONFIG_VGA_CONSOLE is not set
413# CONFIG_VLAN_8021Q is not set
414CONFIG_VT_CONSOLE=y
415CONFIG_VT_HW_CONSOLE_BINDING=y
416CONFIG_VT=y
417# CONFIG_WATCHDOG is not set
418# CONFIG_WLAN_80211 is not set
419CONFIG_ZONE_DMA_FLAG=0
420CONFIG_INPUT_UINPUT=y
421CONFIG_INPUT_MOUSE=y
422CONFIG_INPUT_MOUSEDEV=y
423CONFIG_MOUSE_PS2=y
424# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
425# CONFIG_MOUSE_PS2_ALPS is not set
426# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
427# CONFIG_MOUSE_PS2_SYNAPTICS is not set
428# CONFIG_MOUSE_PS2_TRACKPOINT is not set
429CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
430CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
431# CONFIG_MOUSE_PS2_ELANTECH is not set
432# CONFIG_MOUSE_PS2_TOUCHKIT is not set
433# CONFIG_MOUSE_SERIAL is not set
434# CONFIG_MOUSE_VSXXXAA is not set
435# CONFIG_MOUSE_GPIO is not set
436# CONFIG_MOUSE_BCM5974 is not set
437# CONFIG_SERIO_I8042 is not set
438# CONFIG_SERIO_SERPORT is not set
439# CONFIG_SERIO_RAW is not set
target/linux/xburst/patches-3.0/0001-JZ4740-cache-quirks.patch
1From 2f669aa98831b7248402bab6a07b1b6f722cb6e9 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sat, 24 Apr 2010 17:34:29 +0200
4Subject: [PATCH 01/29] JZ4740 cache quirks
5
6---
7 arch/mips/include/asm/r4kcache.h | 231 ++++++++++++++++++++++++++++++++++++++
8 1 files changed, 231 insertions(+), 0 deletions(-)
9
10diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
11index 54ea47d..3feee5b 100644
12--- a/arch/mips/include/asm/r4kcache.h
13@@ -17,6 +17,58 @@
14 #include <asm/cpu-features.h>
15 #include <asm/mipsmtregs.h>
16
17+#ifdef CONFIG_MACH_JZ4740
18+
19+#define K0_TO_K1() \
20+do { \
21+ unsigned long __k0_addr; \
22+ \
23+ __asm__ __volatile__( \
24+ "la %0, 1f\n\t" \
25+ "or %0, %0, %1\n\t" \
26+ "jr %0\n\t" \
27+ "nop\n\t" \
28+ "1: nop\n" \
29+ : "=&r"(__k0_addr) \
30+ : "r" (0x20000000) ); \
31+} while(0)
32+
33+#define K1_TO_K0() \
34+do { \
35+ unsigned long __k0_addr; \
36+ __asm__ __volatile__( \
37+ "nop;nop;nop;nop;nop;nop;nop\n\t" \
38+ "la %0, 1f\n\t" \
39+ "jr %0\n\t" \
40+ "nop\n\t" \
41+ "1: nop\n" \
42+ : "=&r" (__k0_addr)); \
43+} while (0)
44+
45+#define INVALIDATE_BTB() \
46+do { \
47+ unsigned long tmp; \
48+ __asm__ __volatile__( \
49+ ".set mips32\n\t" \
50+ "mfc0 %0, $16, 7\n\t" \
51+ "nop\n\t" \
52+ "ori %0, 2\n\t" \
53+ "mtc0 %0, $16, 7\n\t" \
54+ "nop\n\t" \
55+ : "=&r" (tmp)); \
56+} while (0)
57+
58+#define SYNC_WB() __asm__ __volatile__ ("sync")
59+
60+#else /* CONFIG_JZRISC */
61+
62+#define K0_TO_K1() do { } while (0)
63+#define K1_TO_K0() do { } while (0)
64+#define INVALIDATE_BTB() do { } while (0)
65+#define SYNC_WB() do { } while (0)
66+
67+#endif /* CONFIG_JZRISC */
68+
69 /*
70  * This macro return a properly sign-extended address suitable as base address
71  * for indexed cache operations. Two issues here:
72@@ -144,6 +196,7 @@ static inline void flush_icache_line_indexed(unsigned long addr)
73 {
74     __iflush_prologue
75     cache_op(Index_Invalidate_I, addr);
76+ INVALIDATE_BTB();
77     __iflush_epilogue
78 }
79
80@@ -151,6 +204,7 @@ static inline void flush_dcache_line_indexed(unsigned long addr)
81 {
82     __dflush_prologue
83     cache_op(Index_Writeback_Inv_D, addr);
84+ SYNC_WB();
85     __dflush_epilogue
86 }
87
88@@ -163,6 +217,7 @@ static inline void flush_icache_line(unsigned long addr)
89 {
90     __iflush_prologue
91     cache_op(Hit_Invalidate_I, addr);
92+ INVALIDATE_BTB();
93     __iflush_epilogue
94 }
95
96@@ -170,6 +225,7 @@ static inline void flush_dcache_line(unsigned long addr)
97 {
98     __dflush_prologue
99     cache_op(Hit_Writeback_Inv_D, addr);
100+ SYNC_WB();
101     __dflush_epilogue
102 }
103
104@@ -177,6 +233,7 @@ static inline void invalidate_dcache_line(unsigned long addr)
105 {
106     __dflush_prologue
107     cache_op(Hit_Invalidate_D, addr);
108+ SYNC_WB();
109     __dflush_epilogue
110 }
111
112@@ -209,6 +266,7 @@ static inline void flush_scache_line(unsigned long addr)
113 static inline void protected_flush_icache_line(unsigned long addr)
114 {
115     protected_cache_op(Hit_Invalidate_I, addr);
116+ INVALIDATE_BTB();
117 }
118
119 /*
120@@ -220,6 +278,7 @@ static inline void protected_flush_icache_line(unsigned long addr)
121 static inline void protected_writeback_dcache_line(unsigned long addr)
122 {
123     protected_cache_op(Hit_Writeback_Inv_D, addr);
124+ SYNC_WB();
125 }
126
127 static inline void protected_writeback_scache_line(unsigned long addr)
128@@ -396,8 +455,10 @@ static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page)
129 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
130 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
131 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
132+#ifndef CONFIG_JZRISC
133 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
134 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
135+#endif
136 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
137 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
138 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
139@@ -405,12 +466,122 @@ __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
140 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
141
142 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16)
143+#ifndef CONFIG_JZRISC
144 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32)
145+#endif
146 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16)
147 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32)
148 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64)
149 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
150
151+#ifdef CONFIG_JZRISC
152+
153+static inline void blast_dcache32(void)
154+{
155+ unsigned long start = INDEX_BASE;
156+ unsigned long end = start + current_cpu_data.dcache.waysize;
157+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
158+ unsigned long ws_end = current_cpu_data.dcache.ways <<
159+ current_cpu_data.dcache.waybit;
160+ unsigned long ws, addr;
161+
162+ for (ws = 0; ws < ws_end; ws += ws_inc)
163+ for (addr = start; addr < end; addr += 0x400)
164+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
165+
166+ SYNC_WB();
167+}
168+
169+static inline void blast_dcache32_page(unsigned long page)
170+{
171+ unsigned long start = page;
172+ unsigned long end = page + PAGE_SIZE;
173+
174+ do {
175+ cache32_unroll32(start,Hit_Writeback_Inv_D);
176+ start += 0x400;
177+ } while (start < end);
178+
179+ SYNC_WB();
180+}
181+
182+static inline void blast_dcache32_page_indexed(unsigned long page)
183+{
184+ unsigned long indexmask = current_cpu_data.dcache.waysize - 1;
185+ unsigned long start = INDEX_BASE + (page & indexmask);
186+ unsigned long end = start + PAGE_SIZE;
187+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
188+ unsigned long ws_end = current_cpu_data.dcache.ways <<
189+ current_cpu_data.dcache.waybit;
190+ unsigned long ws, addr;
191+
192+ for (ws = 0; ws < ws_end; ws += ws_inc)
193+ for (addr = start; addr < end; addr += 0x400)
194+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
195+
196+ SYNC_WB();
197+}
198+
199+static inline void blast_icache32(void)
200+{
201+ unsigned long start = INDEX_BASE;
202+ unsigned long end = start + current_cpu_data.icache.waysize;
203+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
204+ unsigned long ws_end = current_cpu_data.icache.ways <<
205+ current_cpu_data.icache.waybit;
206+ unsigned long ws, addr;
207+
208+ K0_TO_K1();
209+
210+ for (ws = 0; ws < ws_end; ws += ws_inc)
211+ for (addr = start; addr < end; addr += 0x400)
212+ cache32_unroll32(addr|ws,Index_Invalidate_I);
213+
214+ INVALIDATE_BTB();
215+
216+ K1_TO_K0();
217+}
218+
219+static inline void blast_icache32_page(unsigned long page)
220+{
221+ unsigned long start = page;
222+ unsigned long end = page + PAGE_SIZE;
223+
224+ K0_TO_K1();
225+
226+ do {
227+ cache32_unroll32(start,Hit_Invalidate_I);
228+ start += 0x400;
229+ } while (start < end);
230+
231+ INVALIDATE_BTB();
232+
233+ K1_TO_K0();
234+}
235+
236+static inline void blast_icache32_page_indexed(unsigned long page)
237+{
238+ unsigned long indexmask = current_cpu_data.icache.waysize - 1;
239+ unsigned long start = INDEX_BASE + (page & indexmask);
240+ unsigned long end = start + PAGE_SIZE;
241+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
242+ unsigned long ws_end = current_cpu_data.icache.ways <<
243+ current_cpu_data.icache.waybit;
244+ unsigned long ws, addr;
245+
246+ K0_TO_K1();
247+
248+ for (ws = 0; ws < ws_end; ws += ws_inc)
249+ for (addr = start; addr < end; addr += 0x400)
250+ cache32_unroll32(addr|ws,Index_Invalidate_I);
251+
252+ INVALIDATE_BTB();
253+
254+ K1_TO_K0();
255+}
256+
257+#endif /* CONFIG_JZRISC */
258+
259 /* build blast_xxx_range, protected_blast_xxx_range */
260 #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \
261 static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
262@@ -432,13 +603,73 @@ static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
263     __##pfx##flush_epilogue \
264 }
265
266+#ifndef CONFIG_JZRISC
267 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_)
268+#endif
269 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_)
270+#ifndef CONFIG_JZRISC
271 __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_)
272 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, )
273+#endif
274 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )
275 /* blast_inv_dcache_range */
276 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
277 __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
278
279+#ifdef CONFIG_JZRISC
280+
281+static inline void protected_blast_dcache_range(unsigned long start,
282+ unsigned long end)
283+{
284+ unsigned long lsize = cpu_dcache_line_size();
285+ unsigned long addr = start & ~(lsize - 1);
286+ unsigned long aend = (end - 1) & ~(lsize - 1);
287+
288+ while (1) {
289+ protected_cache_op(Hit_Writeback_Inv_D, addr);
290+ if (addr == aend)
291+ break;
292+ addr += lsize;
293+ }
294+ SYNC_WB();
295+}
296+
297+static inline void protected_blast_icache_range(unsigned long start,
298+ unsigned long end)
299+{
300+ unsigned long lsize = cpu_icache_line_size();
301+ unsigned long addr = start & ~(lsize - 1);
302+ unsigned long aend = (end - 1) & ~(lsize - 1);
303+
304+ K0_TO_K1();
305+
306+ while (1) {
307+ protected_cache_op(Hit_Invalidate_I, addr);
308+ if (addr == aend)
309+ break;
310+ addr += lsize;
311+ }
312+ INVALIDATE_BTB();
313+
314+ K1_TO_K0();
315+}
316+
317+static inline void blast_dcache_range(unsigned long start,
318+ unsigned long end)
319+{
320+ unsigned long lsize = cpu_dcache_line_size();
321+ unsigned long addr = start & ~(lsize - 1);
322+ unsigned long aend = (end - 1) & ~(lsize - 1);
323+
324+ while (1) {
325+ cache_op(Hit_Writeback_Inv_D, addr);
326+ if (addr == aend)
327+ break;
328+ addr += lsize;
329+ }
330+ SYNC_WB();
331+}
332+
333+#endif /* CONFIG_JZRISC */
334+
335 #endif /* _ASM_R4KCACHE_H */
336--
3371.7.4.1
338
target/linux/xburst/patches-3.0/0002-Add-n516-board-support.patch
1From 633a1f02f183675e3448c45a5ddd5e942ecbc37c Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sat, 24 Apr 2010 17:25:01 +0200
4Subject: [PATCH 02/29] Add n516 board support
5
6---
7 arch/mips/include/asm/mach-jz4740/board-n516.h | 39 +++
8 arch/mips/jz4740/Kconfig | 4 +
9 arch/mips/jz4740/Makefile | 1 +
10 arch/mips/jz4740/board-n516-display.c | 394 ++++++++++++++++++++++++
11 arch/mips/jz4740/board-n516.c | 182 +++++++++++
12 5 files changed, 620 insertions(+), 0 deletions(-)
13 create mode 100644 arch/mips/include/asm/mach-jz4740/board-n516.h
14 create mode 100644 arch/mips/jz4740/board-n516-display.c
15 create mode 100644 arch/mips/jz4740/board-n516.c
16
17diff --git a/arch/mips/include/asm/mach-jz4740/board-n516.h b/arch/mips/include/asm/mach-jz4740/board-n516.h
18new file mode 100644
19index 0000000..090707e
20--- /dev/null
21@@ -0,0 +1,39 @@
22+/*
23+ * linux/include/asm-mips/mach-jz4740/board-n516.h
24+ *
25+ * JZ4730-based N516 board definition.
26+ *
27+ * Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com>
28+ *
29+ * This program is free software; you can redistribute it and/or modify
30+ * it under the terms of the GNU General Public License as published by
31+ * the Free Software Foundation; either version 2 of the License, or
32+ * (at your option) any later version.
33+ */
34+
35+#ifndef __ASM_JZ4740_N516_H__
36+#define __ASM_JZ4740_N516_H__
37+
38+#include <asm/mach-jz4740/gpio.h>
39+
40+/*
41+ * GPIO
42+ */
43+#define GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(17)
44+#define GPIO_SD_CD_N JZ_GPIO_PORTD(7)
45+#define GPIO_SD_WP JZ_GPIO_PORTD(15)
46+#define GPIO_USB_DETECT JZ_GPIO_PORTD(19)
47+#define GPIO_CHARG_STAT_N JZ_GPIO_PORTD(16)
48+#define GPIO_LED_ENABLE JZ_GPIO_PORTD(28)
49+#define GPIO_LPC_INT JZ_GPIO_PORTD(14)
50+#define GPIO_HPHONE_DETECT JZ_GPIO_PORTD(20)
51+#define GPIO_SPEAKER_ENABLE JZ_GPIO_PORTD(21)
52+
53+/* Display */
54+#define GPIO_DISPLAY_RST_L JZ_GPIO_PORTB(18)
55+#define GPIO_DISPLAY_RDY JZ_GPIO_PORTB(17)
56+#define GPIO_DISPLAY_STBY JZ_GPIO_PORTC(22)
57+#define GPIO_DISPLAY_ERR JZ_GPIO_PORTC(23)
58+#define GPIO_DISPLAY_OFF_N JZ_GPIO_PORTD(1)
59+
60+#endif /* __ASM_JZ4740_N516_H__ */
61diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
62index 3e7141f..85bfbf3 100644
63--- a/arch/mips/jz4740/Kconfig
64@@ -6,6 +6,10 @@ choice
65 config JZ4740_QI_LB60
66     bool "Qi Hardware Ben NanoNote"
67
68+config JZ4740_N516
69+ bool "Hanvon n516 eBook reader"
70+ select SOC_JZ4740
71+
72 endchoice
73
74 config HAVE_PWM
75diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
76index a9dff33..727270a 100644
77--- a/arch/mips/jz4740/Makefile
78@@ -12,6 +12,7 @@ obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
79 # board specific support
80
81 obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
82+obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
83
84 # PM support
85
86diff --git a/arch/mips/jz4740/board-n516-display.c b/arch/mips/jz4740/board-n516-display.c
87new file mode 100644
88index 0000000..0e77a82
89--- /dev/null
90@@ -0,0 +1,394 @@
91+/*
92+ * board-n516-display.c -- Platform device for N516 display
93+ *
94+ * Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com>
95+ *
96+ * This file is subject to the terms and conditions of the GNU General Public
97+ * License. See the file COPYING in the main directory of this archive for
98+ * more details.
99+ */
100+
101+#include <linux/module.h>
102+#include <linux/kernel.h>
103+#include <linux/errno.h>
104+#include <linux/string.h>
105+#include <linux/delay.h>
106+#include <linux/interrupt.h>
107+#include <linux/fb.h>
108+#include <linux/init.h>
109+#include <linux/platform_device.h>
110+#include <linux/irq.h>
111+#include <linux/gpio.h>
112+
113+#include <asm/mach-jz4740/jz4740_fb.h>
114+
115+#include <asm/mach-jz4740/platform.h>
116+#include <asm/mach-jz4740/board-n516.h>
117+
118+#include <video/metronomefb.h>
119+#include <linux/console.h>
120+
121+static struct fb_videomode n516_fb_modes[] = {
122+ [0] = {
123+ .name = "Metronome 800x600",
124+ .refresh = 50,
125+ .xres = 400,
126+ .yres = 624,
127+ .hsync_len = 31,
128+ .vsync_len = 23,
129+ .right_margin = 31,
130+ .left_margin = 5,
131+ .upper_margin = 1,
132+ .lower_margin = 2,
133+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
134+ },
135+};
136+
137+static struct jz4740_fb_platform_data n516_fb_pdata = {
138+ .num_modes = ARRAY_SIZE(n516_fb_modes),
139+ .modes = n516_fb_modes,
140+ .bpp = 16,
141+ .lcd_type = JZ_LCD_TYPE_GENERIC_16_BIT,
142+};
143+
144+struct n516_board_info {
145+ uint8_t *metromem;
146+ size_t wfm_size;
147+ struct fb_info *host_fbinfo; /* the host LCD controller's fbi */
148+ unsigned int fw;
149+ unsigned int fh;
150+};
151+
152+static struct platform_device *n516_device;
153+static struct n516_board_info n516_board_info;
154+
155+static int metronome_gpios[] = {
156+ GPIO_DISPLAY_STBY,
157+ GPIO_DISPLAY_RST_L,
158+ GPIO_DISPLAY_RDY,
159+ GPIO_DISPLAY_ERR,
160+/* GPIO_DISPLAY_OFF_N,*/
161+};
162+
163+static const char *metronome_gpio_names[] = {
164+ "Metronome STDBY",
165+ "Metronome RST",
166+ "Metronome RDY",
167+ "Metronome ERR",
168+/* "Metronone OFF",*/
169+};
170+
171+static int n516_enable_hostfb(bool enable)
172+{
173+ int ret;
174+ int blank = enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
175+
176+ acquire_console_sem();
177+ ret = fb_blank(n516_board_info.host_fbinfo, blank);
178+ release_console_sem();
179+
180+ return ret;
181+}
182+
183+static int n516_init_metronome_gpios(struct metronomefb_par *par)
184+{
185+ int i;
186+ int ret;
187+
188+ for (i = 0; i < ARRAY_SIZE(metronome_gpios); ++i) {
189+ ret = gpio_request(metronome_gpios[i], metronome_gpio_names[i]);
190+ if (ret)
191+ goto err;
192+ }
193+
194+ gpio_direction_output(GPIO_DISPLAY_OFF_N, 0);
195+ gpio_direction_output(GPIO_DISPLAY_RST_L, 0);
196+ gpio_direction_output(GPIO_DISPLAY_STBY, 0);
197+ gpio_direction_input(GPIO_DISPLAY_RDY);
198+ gpio_direction_input(GPIO_DISPLAY_ERR);
199+
200+ return 0;
201+err:
202+ for (--i; i >= 0; --i)
203+ gpio_free(metronome_gpios[i]);
204+
205+ return ret;
206+}
207+
208+static int n516_share_video_mem(struct fb_info *info)
209+{
210+ int ret;
211+
212+ dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
213+ dev_dbg(&n516_device->dev, "%s, info->var.xres = %u, info->var.yres = %u\n", __func__, info->var.xres, info->var.yres);
214+ /* rough check if this is our desired fb and not something else */
215+ if ((info->var.xres != n516_fb_pdata.modes[0].xres)
216+ || (info->var.yres != n516_fb_pdata.modes[0].yres))
217+ return 0;
218+
219+ /* we've now been notified that we have our new fb */
220+ n516_board_info.metromem = info->screen_base;
221+ n516_board_info.host_fbinfo = info;
222+
223+ n516_enable_hostfb(false);
224+ /* try to refcount host drv since we are the consumer after this */
225+ if (!try_module_get(info->fbops->owner))
226+ return -ENODEV;
227+
228+ /* this _add binds metronomefb to n516. metronomefb refcounts n516 */
229+ ret = platform_device_add(n516_device);
230+
231+ if (ret) {
232+ platform_device_put(n516_device);
233+ return ret;
234+ }
235+
236+ /* request our platform independent driver */
237+ request_module("metronomefb");
238+
239+ return 0;
240+}
241+
242+static int n516_unshare_video_mem(struct fb_info *info)
243+{
244+ dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
245+
246+ if (info != n516_board_info.host_fbinfo)
247+ return 0;
248+
249+ module_put(n516_board_info.host_fbinfo->fbops->owner);
250+ return 0;
251+}
252+
253+static int n516_fb_notifier_callback(struct notifier_block *self,
254+ unsigned long event, void *data)
255+{
256+ struct fb_event *evdata = data;
257+ struct fb_info *info = evdata->info;
258+
259+ dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
260+
261+ if (event == FB_EVENT_FB_REGISTERED)
262+ return n516_share_video_mem(info);
263+ else if (event == FB_EVENT_FB_UNREGISTERED)
264+ return n516_unshare_video_mem(info);
265+
266+ return 0;
267+}
268+
269+static struct notifier_block n516_fb_notif = {
270+ .notifier_call = n516_fb_notifier_callback,
271+};
272+
273+/* this gets called as part of our init. these steps must be done now so
274+ * that we can use set_pxa_fb_info */
275+static void __init n516_presetup_fb(void)
276+{
277+ int padding_size;
278+ int totalsize;
279+
280+ /* the frame buffer is divided as follows:
281+ command | CRC | padding
282+ 16kb waveform data | CRC | padding
283+ image data | CRC
284+ */
285+
286+ n516_board_info.fw = 800;
287+ n516_board_info.fh = 624;
288+
289+ /* waveform must be 16k + 2 for checksum */
290+ n516_board_info.wfm_size = roundup(16*1024 + 2, n516_board_info.fw);
291+
292+ padding_size = PAGE_SIZE + (4 * n516_board_info.fw);
293+
294+ /* total is 1 cmd , 1 wfm, padding and image */
295+ totalsize = n516_board_info.fw + n516_board_info.wfm_size;
296+ totalsize += padding_size + (n516_board_info.fw*n516_board_info.fh);
297+
298+ /* save this off because we're manipulating fw after this and
299+ * we'll need it when we're ready to setup the framebuffer */
300+
301+ /* the reason we do this adjustment is because we want to acquire
302+ * more framebuffer memory without imposing custom awareness on the
303+ * underlying driver */
304+ n516_fb_pdata.modes[0].yres = DIV_ROUND_UP(totalsize, n516_board_info.fw);
305+
306+ jz4740_framebuffer_device.dev.platform_data = &n516_fb_pdata;
307+ platform_device_register(&jz4740_framebuffer_device);
308+}
309+
310+/* this gets called by metronomefb as part of its init, in our case, we
311+ * have already completed initial framebuffer init in presetup_fb so we
312+ * can just setup the fb access pointers */
313+static int n516_setup_fb(struct metronomefb_par *par)
314+{
315+ /* metromem was set up by the notifier in share_video_mem so now
316+ * we can use its value to calculate the other entries */
317+ par->metromem_cmd = (struct metromem_cmd *) n516_board_info.metromem;
318+ par->metromem_wfm = n516_board_info.metromem + n516_board_info.fw;
319+ par->metromem_img = par->metromem_wfm + n516_board_info.wfm_size;
320+ par->metromem_img_csum = (u16 *) (par->metromem_img + (n516_board_info.fw * n516_board_info.fh));
321+ par->metromem_dma = n516_board_info.host_fbinfo->fix.smem_start;
322+
323+ return 0;
324+}
325+
326+static int n516_get_panel_type(void)
327+{
328+ return 5;
329+}
330+
331+static irqreturn_t n516_handle_irq(int irq, void *dev_id)
332+{
333+ struct metronomefb_par *par = dev_id;
334+
335+ dev_dbg(&par->pdev->dev, "Metronome IRQ! RDY=%d\n", gpio_get_value(GPIO_DISPLAY_RDY));
336+ wake_up_all(&par->waitq);
337+
338+ return IRQ_HANDLED;
339+}
340+
341+static void n516_power_ctl(struct metronomefb_par *par, int cmd)
342+{
343+ switch (cmd) {
344+ case METRONOME_POWER_OFF:
345+ gpio_set_value(GPIO_DISPLAY_OFF_N, 1);
346+ n516_enable_hostfb(false);
347+ break;
348+ case METRONOME_POWER_ON:
349+ gpio_set_value(GPIO_DISPLAY_OFF_N, 0);
350+ n516_enable_hostfb(true);
351+ break;
352+ }
353+}
354+
355+static int n516_get_rdy(struct metronomefb_par *par)
356+{
357+ return gpio_get_value(GPIO_DISPLAY_RDY);
358+}
359+
360+static int n516_get_err(struct metronomefb_par *par)
361+{
362+ return gpio_get_value(GPIO_DISPLAY_ERR);
363+}
364+
365+static int n516_setup_irq(struct fb_info *info)
366+{
367+ int ret;
368+
369+ dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
370+
371+ ret = request_irq(gpio_to_irq(GPIO_DISPLAY_RDY), n516_handle_irq,
372+ IRQF_TRIGGER_RISING,
373+ "n516", info->par);
374+ if (ret)
375+ dev_err(&n516_device->dev, "request_irq failed: %d\n", ret);
376+
377+ return ret;
378+}
379+
380+static void n516_set_rst(struct metronomefb_par *par, int state)
381+{
382+ dev_dbg(&n516_device->dev, "ENTER %s, RDY=%d\n", __func__, gpio_get_value(GPIO_DISPLAY_RDY));
383+ if (state)
384+ gpio_set_value(GPIO_DISPLAY_RST_L, 1);
385+ else
386+ gpio_set_value(GPIO_DISPLAY_RST_L, 0);
387+}
388+
389+static void n516_set_stdby(struct metronomefb_par *par, int state)
390+{
391+ dev_dbg(&n516_device->dev, "ENTER %s, RDY=%d\n", __func__, gpio_get_value(GPIO_DISPLAY_RDY));
392+ if (state)
393+ gpio_set_value(GPIO_DISPLAY_STBY, 1);
394+ else
395+ gpio_set_value(GPIO_DISPLAY_STBY, 0);
396+}
397+
398+static int n516_wait_event(struct metronomefb_par *par)
399+{
400+ unsigned long timeout = jiffies + HZ / 20;
401+
402+ dev_dbg(&n516_device->dev, "ENTER1 %s, RDY=%d\n",
403+ __func__, gpio_get_value(GPIO_DISPLAY_RDY));
404+ while (n516_get_rdy(par) && time_before(jiffies, timeout))
405+ schedule();
406+
407+ dev_dbg(&n516_device->dev, "ENTER2 %s, RDY=%d\n",
408+ __func__, gpio_get_value(GPIO_DISPLAY_RDY));
409+ return wait_event_timeout(par->waitq,
410+ n516_get_rdy(par), HZ * 2) ? 0 : -EIO;
411+}
412+
413+static int n516_wait_event_intr(struct metronomefb_par *par)
414+{
415+ unsigned long timeout = jiffies + HZ/20;
416+
417+ dev_dbg(&n516_device->dev, "ENTER1 %s, RDY=%d\n",
418+ __func__, gpio_get_value(GPIO_DISPLAY_RDY));
419+ while (n516_get_rdy(par) && time_before(jiffies, timeout))
420+ schedule();
421+
422+ dev_dbg(&n516_device->dev, "ENTER2 %s, RDY=%d\n",
423+ __func__, gpio_get_value(GPIO_DISPLAY_RDY));
424+ return wait_event_interruptible_timeout(par->waitq,
425+ n516_get_rdy(par), HZ * 2) ? 0 : -EIO;
426+}
427+
428+static void n516_cleanup(struct metronomefb_par *par)
429+{
430+ int i;
431+
432+ free_irq(gpio_to_irq(GPIO_DISPLAY_RDY), par);
433+ for (i = 0; i < ARRAY_SIZE(metronome_gpios); ++i)
434+ gpio_free(metronome_gpios[i]);
435+}
436+
437+static struct metronome_board n516_board __initdata = {
438+ .owner = THIS_MODULE,
439+ .power_ctl = n516_power_ctl,
440+ .setup_irq = n516_setup_irq,
441+ .setup_io = n516_init_metronome_gpios,
442+ .setup_fb = n516_setup_fb,
443+ .set_rst = n516_set_rst,
444+ .get_err = n516_get_err,
445+ .get_rdy = n516_get_rdy,
446+ .set_stdby = n516_set_stdby,
447+ .met_wait_event = n516_wait_event,
448+ .met_wait_event_intr = n516_wait_event_intr,
449+ .get_panel_type = n516_get_panel_type,
450+ .cleanup = n516_cleanup,
451+};
452+
453+static int __init n516_init(void)
454+{
455+ int ret;
456+
457+ /* Keep the metronome off, until its driver is loaded */
458+ ret = gpio_request(GPIO_DISPLAY_OFF_N, "Display off");
459+ if (ret)
460+ return ret;
461+
462+ gpio_direction_output(GPIO_DISPLAY_OFF_N, 1);
463+
464+ /* before anything else, we request notification for any fb
465+ * creation events */
466+ fb_register_client(&n516_fb_notif);
467+
468+ n516_device = platform_device_alloc("metronomefb", -1);
469+ if (!n516_device)
470+ return -ENOMEM;
471+
472+ /* the n516_board that will be seen by metronomefb is a copy */
473+ platform_device_add_data(n516_device, &n516_board,
474+ sizeof(n516_board));
475+
476+ n516_presetup_fb();
477+
478+ return 0;
479+}
480+module_init(n516_init);
481+
482+MODULE_DESCRIPTION("board driver for n516 display");
483+MODULE_AUTHOR("Yauhen Kharuzhy");
484+MODULE_LICENSE("GPL");
485diff --git a/arch/mips/jz4740/board-n516.c b/arch/mips/jz4740/board-n516.c
486new file mode 100644
487index 0000000..678885c
488--- /dev/null
489@@ -0,0 +1,182 @@
490+/*
491+ * linux/arch/mips/jz4740/board-516.c
492+ *
493+ * JZ4740 n516 board setup routines.
494+ *
495+ * Copyright (c) 2009, Yauhen Kharuzhy <jekhor@gmail.com>
496+ *
497+ * This program is free software; you can redistribute it and/or modify
498+ * it under the terms of the GNU General Public License as published by
499+ * the Free Software Foundation; either version 2 of the License, or
500+ * (at your option) any later version.
501+ */
502+
503+#include <linux/init.h>
504+#include <linux/sched.h>
505+#include <linux/ioport.h>
506+#include <linux/mm.h>
507+#include <linux/console.h>
508+#include <linux/delay.h>
509+#include <linux/i2c.h>
510+#include <linux/platform_device.h>
511+#include <linux/mtd/mtd.h>
512+#include <linux/leds.h>
513+
514+#include <linux/power_supply.h>
515+#include <linux/power/gpio-charger.h>
516+
517+#include <linux/i2c.h>
518+
519+#include <asm/mach-jz4740/jz4740_mmc.h>
520+#include <asm/mach-jz4740/jz4740_nand.h>
521+
522+#include <asm/mach-jz4740/board-n516.h>
523+#include <asm/mach-jz4740/platform.h>
524+
525+#include "clock.h"
526+
527+static long n516_panic_blink(int state)
528+{
529+ gpio_set_value(GPIO_LED_ENABLE, state ? 1 : 0);
530+ return 0;
531+}
532+
533+static void __init board_gpio_setup(void)
534+{
535+/* jz_gpio_enable_pullup(JZ_GPIO_PORTD(23));
536+ jz_gpio_enable_pullup(JZ_GPIO_PORTD(24));*/
537+}
538+
539+static const struct i2c_board_info n516_i2c_board_info[] = {
540+ {
541+ .type = "LPC524",
542+ .addr = 0x54,
543+ },
544+ {
545+ .type = "lm75a",
546+ .addr = 0x48,
547+ }
548+};
549+
550+static struct jz4740_mmc_platform_data n516_mmc_pdata = {
551+ .gpio_card_detect = GPIO_SD_CD_N,
552+ .card_detect_active_low = 1,
553+ .gpio_read_only = -1,
554+ .gpio_power = GPIO_SD_VCC_EN_N,
555+ .power_active_low = 1,
556+};
557+
558+static struct gpio_led n516_leds[] = {
559+ {
560+ .name = "n516:blue:power",
561+ .gpio = GPIO_LED_ENABLE,
562+ .default_state = LEDS_GPIO_DEFSTATE_ON,
563+ .default_trigger = "nand-disk",
564+ }
565+};
566+
567+static struct gpio_led_platform_data n516_leds_pdata = {
568+ .leds = n516_leds,
569+ .num_leds = ARRAY_SIZE(n516_leds),
570+};
571+
572+static struct platform_device n516_leds_device = {
573+ .name = "leds-gpio",
574+ .id = -1,
575+ .dev = {
576+ .platform_data = &n516_leds_pdata,
577+ },
578+};
579+
580+static struct mtd_partition n516_partitions[] = {
581+ { .name = "NAND BOOT partition",
582+ .offset = 0 * 0x100000,
583+ .size = 4 * 0x100000,
584+ },
585+ { .name = "NAND KERNEL partition",
586+ .offset = 4 * 0x100000,
587+ .size = 4 * 0x100000,
588+ },
589+ { .name = "NAND ROOTFS partition",
590+ .offset = 8 * 0x100000,
591+ .size = 504 * 0x100000,
592+ },
593+};
594+
595+static struct nand_ecclayout n516_ecclayout = {
596+ .eccbytes = 36,
597+ .eccpos = {
598+ 6, 7, 8, 9, 10, 11, 12, 13, 14,
599+ 15, 16, 17, 18, 19, 20, 21, 22, 23,
600+ 24, 25, 26, 27, 28, 29, 30, 31, 32,
601+ 33, 34, 35, 36, 37, 38, 39, 40, 41,
602+ },
603+ .oobfree = {
604+ {
605+ .offset = 2,
606+ .length = 4
607+ },
608+ {
609+ .offset = 42,
610+ .length = 22,
611+ }
612+ }
613+};
614+
615+static struct jz_nand_platform_data n516_nand_pdata = {
616+ .ecc_layout = &n516_ecclayout,
617+ .partitions = n516_partitions,
618+ .num_partitions = ARRAY_SIZE(n516_partitions),
619+ .busy_gpio = 94,
620+};
621+
622+static char *n516_batteries[] = {
623+ "n516_battery",
624+};
625+
626+static struct gpio_charger_platform_data n516_charger_pdata = {
627+ .name = "usb",
628+ .type = POWER_SUPPLY_TYPE_USB,
629+ .gpio = GPIO_USB_DETECT,
630+ .gpio_active_low = 1,
631+ .batteries = n516_batteries,
632+ .num_batteries = ARRAY_SIZE(n516_batteries),
633+};
634+
635+static struct platform_device n516_charger_device = {
636+ .name = "gpio-charger",
637+ .dev = {
638+ .platform_data = &n516_charger_pdata,
639+ },
640+};
641+
642+static struct platform_device *n516_devices[] __initdata = {
643+ &jz4740_nand_device,
644+ &n516_leds_device,
645+ &jz4740_mmc_device,
646+ &jz4740_i2s_device,
647+ &jz4740_codec_device,
648+ &jz4740_rtc_device,
649+ &jz4740_udc_device,
650+ &jz4740_i2c_device,
651+ &n516_charger_device,
652+};
653+
654+struct jz4740_clock_board_data jz4740_clock_bdata = {
655+ .ext_rate = 12000000,
656+ .rtc_rate = 32768,
657+};
658+
659+static int n516_setup_platform(void)
660+{
661+ jz4740_serial_device_register();
662+ board_gpio_setup();
663+
664+ panic_blink = n516_panic_blink;
665+ i2c_register_board_info(0, n516_i2c_board_info, ARRAY_SIZE(n516_i2c_board_info));
666+ jz4740_mmc_device.dev.platform_data = &n516_mmc_pdata;
667+ jz4740_nand_device.dev.platform_data = &n516_nand_pdata;
668+
669+ return platform_add_devices(n516_devices, ARRAY_SIZE(n516_devices));
670+}
671+arch_initcall(n516_setup_platform);
672--
6731.7.4.1
674
target/linux/xburst/patches-3.0/0003-Add-n526-board-support.patch
1From dcc0d9f15146c100a843dfa62ba259e208330f07 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sat, 24 Apr 2010 17:25:23 +0200
4Subject: [PATCH 03/29] Add n526 board support
5
6---
7 arch/mips/jz4740/Kconfig | 4 +
8 arch/mips/jz4740/Makefile | 1 +
9 arch/mips/jz4740/board-n526.c | 320 +++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 325 insertions(+), 0 deletions(-)
11 create mode 100644 arch/mips/jz4740/board-n526.c
12
13diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
14index 85bfbf3..2f366d7 100644
15--- a/arch/mips/jz4740/Kconfig
16@@ -10,6 +10,10 @@ config JZ4740_N516
17     bool "Hanvon n516 eBook reader"
18     select SOC_JZ4740
19
20+config JZ4740_N526
21+ bool "Hanvon n526 eBook reader"
22+ select SOC_JZ4740
23+
24 endchoice
25
26 config HAVE_PWM
27diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
28index 727270a..e8f2904 100644
29--- a/arch/mips/jz4740/Makefile
30@@ -13,6 +13,7 @@ obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
31
32 obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
33 obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
34+obj-$(CONFIG_JZ4740_N526) += board-n526.o
35
36 # PM support
37
38diff --git a/arch/mips/jz4740/board-n526.c b/arch/mips/jz4740/board-n526.c
39new file mode 100644
40index 0000000..494c4cb
41--- /dev/null
42@@ -0,0 +1,320 @@
43+/*
44+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
45+ * N526 eBook reader support
46+ *
47+ * This program is free software; you can redistribute it and/or modify it
48+ * under the terms of the GNU General Public License as published by the
49+ * Free Software Foundation; either version 2 of the License, or (at your
50+ * option) any later version.
51+ *
52+ * You should have received a copy of the GNU General Public License along
53+ * with this program; if not, write to the Free Software Foundation, Inc.,
54+ * 675 Mass Ave, Cambridge, MA 02139, USA.
55+ *
56+ */
57+
58+#include <linux/kernel.h>
59+#include <linux/init.h>
60+#include <linux/gpio.h>
61+
62+#include <linux/mutex.h>
63+#include <linux/wait.h>
64+#include <video/broadsheetfb.h>
65+#include <linux/delay.h>
66+#include <linux/interrupt.h>
67+
68+#include <linux/input.h>
69+#include <linux/gpio_keys.h>
70+
71+#include <linux/leds.h>
72+
73+#include <linux/i2c.h>
74+
75+#include "clock.h"
76+
77+#include <asm/mach-jz4740/jz4740_mmc.h>
78+#include <asm/mach-jz4740/jz4740_nand.h>
79+#include <asm/mach-jz4740/jz4740_fb.h>
80+
81+#include <asm/mach-jz4740/platform.h>
82+
83+/* NAND */
84+static struct nand_ecclayout n526_ecclayout = {
85+ .eccbytes = 36,
86+ .eccpos = {
87+ 6, 7, 8, 9, 10, 11, 12, 13,
88+ 14, 15, 16, 17, 18, 19, 20, 21,
89+ 22, 23, 24, 25, 26, 27, 28, 29,
90+ 30, 31, 32, 33, 34, 35, 36, 37,
91+ 38, 39, 40, 41},
92+ .oobfree = {
93+ {
94+ .offset = 2,
95+ .length = 4,
96+ },
97+ {
98+ .offset = 42,
99+ .length = 22,
100+ },
101+ }
102+};
103+
104+static struct mtd_partition n526_partitions[] = {
105+ { .name = "NAND BOOT partition",
106+ .offset = 0 * 0x100000,
107+ .size = 4 * 0x100000,
108+ },
109+ { .name = "NAND KERNEL partition",
110+ .offset = 4 * 0x100000,
111+ .size = 4 * 0x100000,
112+ },
113+ { .name = "NAND ROOTFS partition",
114+ .offset = 16 * 0x100000,
115+ .size = 498 * 0x100000,
116+ },
117+};
118+
119+static struct jz_nand_platform_data n526_nand_pdata = {
120+ .ecc_layout = &n526_ecclayout,
121+ .partitions = n526_partitions,
122+ .num_partitions = ARRAY_SIZE(n526_partitions),
123+ .busy_gpio = JZ_GPIO_PORTC(30),
124+};
125+
126+static struct jz4740_mmc_platform_data n526_mmc_pdata = {
127+ .gpio_card_detect = JZ_GPIO_PORTD(7),
128+ .card_detect_active_low = 1,
129+ .gpio_read_only = -1,
130+ .gpio_power = JZ_GPIO_PORTD(17),
131+ .power_active_low = 1,
132+};
133+
134+static struct gpio_led n526_leds[] = {
135+ {
136+ .name = "n526:blue:power",
137+ .gpio = JZ_GPIO_PORTD(28),
138+ .default_state = LEDS_GPIO_DEFSTATE_ON,
139+ }
140+};
141+
142+static struct gpio_led_platform_data n526_leds_pdata = {
143+ .leds = n526_leds,
144+ .num_leds = ARRAY_SIZE(n526_leds),
145+};
146+
147+static struct platform_device n526_leds_device = {
148+ .name = "leds-gpio",
149+ .id = -1,
150+ .dev = {
151+ .platform_data = &n526_leds_pdata,
152+ },
153+};
154+
155+static void __init board_gpio_setup(void)
156+{
157+ /* We only need to enable/disable pullup here for pins used in generic
158+ * drivers. Everything else is done by the drivers themselfs. */
159+ jz_gpio_disable_pullup(JZ_GPIO_PORTD(17));
160+ jz_gpio_enable_pullup(JZ_GPIO_PORTD(7));
161+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(19));
162+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(20));
163+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(21));
164+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(23));
165+}
166+
167+
168+static const int n526_eink_ctrl_gpios[] = {
169+ 0,
170+ JZ_GPIO_PORTC(23),
171+ JZ_GPIO_PORTC(19),
172+ JZ_GPIO_PORTC(20),
173+};
174+
175+static void n526_eink_set_ctl(struct broadsheetfb_par * par, unsigned char ctrl, u8
176+value)
177+{
178+ gpio_set_value(n526_eink_ctrl_gpios[ctrl], value);
179+}
180+
181+
182+static int n526_eink_wait(struct broadsheetfb_par *par)
183+{
184+ wait_event(par->waitq, gpio_get_value(JZ_GPIO_PORTB(17)));
185+
186+ return 0;
187+}
188+
189+static u16 n526_eink_get_hdb(struct broadsheetfb_par *par)
190+{
191+ u16 value = 0;
192+ jz_gpio_port_direction_input(JZ_GPIO_PORTC(0), 0xffff);
193+ gpio_set_value(JZ_GPIO_PORTC(21), 0);
194+ mdelay(100);
195+
196+ value = jz_gpio_port_get_value(JZ_GPIO_PORTC(0), 0xffff);
197+
198+ gpio_set_value(JZ_GPIO_PORTC(21), 1);
199+ jz_gpio_port_direction_output(JZ_GPIO_PORTC(0), 0xffff);
200+ return value;
201+}
202+
203+static void n526_eink_set_hdb(struct broadsheetfb_par *par, u16 value)
204+{
205+ jz_gpio_port_set_value(JZ_GPIO_PORTC(0), value, 0xffff);
206+}
207+
208+static int n526_eink_init(struct broadsheetfb_par *par)
209+{
210+ int i;
211+
212+ gpio_request(JZ_GPIO_PORTD(1), "display reset");
213+ gpio_direction_output(JZ_GPIO_PORTD(1), 1);
214+ mdelay(10);
215+ gpio_set_value(JZ_GPIO_PORTD(1), 0);
216+
217+ gpio_request(JZ_GPIO_PORTB(18), "eink enable");
218+ gpio_direction_output(JZ_GPIO_PORTB(18), 0);
219+
220+ gpio_request(JZ_GPIO_PORTB(29), "foobar");
221+ gpio_direction_output(JZ_GPIO_PORTB(29), 1);
222+
223+ for(i = 1; i < ARRAY_SIZE(n526_eink_ctrl_gpios); ++i) {
224+ gpio_request(n526_eink_ctrl_gpios[i], "eink display ctrl");
225+ gpio_direction_output(n526_eink_ctrl_gpios[i], 0);
226+ }
227+
228+ gpio_request(JZ_GPIO_PORTC(22), "foobar");
229+ gpio_direction_input(JZ_GPIO_PORTC(22));
230+ gpio_request(JZ_GPIO_PORTC(21), "eink nRD");
231+ gpio_direction_output(JZ_GPIO_PORTC(21), 1);
232+
233+ for(i = 0; i < 16; ++i) {
234+ gpio_request(JZ_GPIO_PORTC(i), "eink display data");
235+ }
236+ jz_gpio_port_direction_output(JZ_GPIO_PORTC(0), 0xffff);
237+
238+ gpio_set_value(JZ_GPIO_PORTB(18), 1);
239+
240+ return 0;
241+}
242+
243+static irqreturn_t n526_eink_busy_irq(int irq, void *devid)
244+{
245+ struct broadsheetfb_par *par = devid;
246+ wake_up(&par->waitq);
247+
248+ return IRQ_HANDLED;
249+}
250+
251+static int n526_eink_setup_irq(struct fb_info *info)
252+{
253+ int ret;
254+ struct broadsheetfb_par *par = info->par;
255+
256+ gpio_request(JZ_GPIO_PORTB(17), "eink busy");
257+ gpio_direction_input(JZ_GPIO_PORTB(17));
258+
259+ ret = request_irq(gpio_to_irq(JZ_GPIO_PORTB(17)), n526_eink_busy_irq,
260+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
261+ "eink busyline", par);
262+ if (ret)
263+ printk("n526 display: Failed to request busyline irq: %d\n", ret);
264+ return 0;
265+}
266+
267+static void n526_eink_cleanup(struct broadsheetfb_par *par)
268+{
269+}
270+
271+static struct broadsheet_board broadsheet_pdata = {
272+ .owner = THIS_MODULE,
273+ .init = n526_eink_init,
274+ .wait_for_rdy = n526_eink_wait,
275+ .set_ctl = n526_eink_set_ctl,
276+ .set_hdb = n526_eink_set_hdb,
277+ .get_hdb = n526_eink_get_hdb,
278+ .cleanup = n526_eink_cleanup,
279+ .setup_irq = n526_eink_setup_irq,
280+};
281+
282+static struct platform_device n526_broadsheet_device = {
283+ .name = "broadsheetfb",
284+ .id = -1,
285+ .dev = {
286+ .platform_data = &broadsheet_pdata,
287+ },
288+};
289+
290+/* Buttons */
291+static struct gpio_keys_button n526_gpio_keys_buttons[] = {
292+ [0] = {
293+ .code = KEY_ENTER,
294+ .gpio = 0,
295+ .active_low = 1,
296+ .desc = "Power",
297+ },
298+};
299+
300+static struct gpio_keys_platform_data n526_gpio_keys_data = {
301+ .nbuttons = ARRAY_SIZE(n526_gpio_keys_buttons),
302+ .buttons = n526_gpio_keys_buttons,
303+};
304+
305+static struct platform_device n526_gpio_keys_device = {
306+ .name = "gpio-keys",
307+ .id = -1,
308+ .dev = {
309+ .platform_data = &n526_gpio_keys_data,
310+ }
311+};
312+
313+static struct i2c_board_info n526_i2c_board_info = {
314+ .type = "n526-lpc",
315+ .addr = 0x54,
316+};
317+
318+static struct platform_device *n526_platform_devices[] __initdata = {
319+ &jz4740_usb_ohci_device,
320+ &jz4740_udc_device,
321+ &jz4740_mmc_device,
322+ &jz4740_nand_device,
323+ &jz4740_i2s_device,
324+ &jz4740_codec_device,
325+ &jz4740_pcm_device,
326+ &jz4740_rtc_device,
327+ &jz4740_i2c_device,
328+ &n526_leds_device,
329+ &n526_broadsheet_device,
330+ &n526_gpio_keys_device,
331+};
332+
333+static int __init n526_init_platform_devices(void)
334+{
335+ jz4740_nand_device.dev.platform_data = &n526_nand_pdata;
336+ jz4740_mmc_device.dev.platform_data = &n526_mmc_pdata;
337+
338+ jz4740_serial_device_register();
339+
340+ n526_i2c_board_info.irq = gpio_to_irq(JZ_GPIO_PORTD(14)),
341+ i2c_register_board_info(0, &n526_i2c_board_info, 1);
342+
343+ return platform_add_devices(n526_platform_devices,
344+ ARRAY_SIZE(n526_platform_devices));
345+
346+}
347+
348+struct jz4740_clock_board_data jz4740_clock_bdata = {
349+ .ext_rate = 12000000,
350+ .rtc_rate = 32768,
351+};
352+
353+static int __init n526_board_setup(void)
354+{
355+ board_gpio_setup();
356+
357+ if (n526_init_platform_devices())
358+ panic("Failed to initalize platform devices\n");
359+
360+ return 0;
361+}
362+arch_initcall(n526_board_setup);
363--
3641.7.4.1
365
target/linux/xburst/patches-3.0/0004-MIPS-JZ4740-Add-id800wt-board.patch
1From 322d8e1ccf544f576d60622dc304f136cef64a3b Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 5 Sep 2010 20:34:08 +0200
4Subject: [PATCH 04/29] MIPS: JZ4740: Add id800wt board
5
6---
7 arch/mips/jz4740/Kconfig | 4 +
8 arch/mips/jz4740/Makefile | 1 +
9 arch/mips/jz4740/board-id800wt.c | 158 ++++++++++++++++++++++++++++++++++++++
10 3 files changed, 163 insertions(+), 0 deletions(-)
11 create mode 100644 arch/mips/jz4740/board-id800wt.c
12
13diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
14index 2f366d7..680a2bd 100644
15--- a/arch/mips/jz4740/Kconfig
16@@ -14,6 +14,10 @@ config JZ4740_N526
17     bool "Hanvon n526 eBook reader"
18     select SOC_JZ4740
19
20+config JZ4740_ID800WT
21+ bool "Sungale id800wt picture frame"
22+ select SOC_JZ4740
23+
24 endchoice
25
26 config HAVE_PWM
27diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
28index e8f2904..72eb2ad 100644
29--- a/arch/mips/jz4740/Makefile
30@@ -14,6 +14,7 @@ obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
31 obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
32 obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
33 obj-$(CONFIG_JZ4740_N526) += board-n526.o
34+obj-$(CONFIG_JZ4740_ID800WT) += board-id800wt.o
35
36 # PM support
37
38diff --git a/arch/mips/jz4740/board-id800wt.c b/arch/mips/jz4740/board-id800wt.c
39new file mode 100644
40index 0000000..93fc996
41--- /dev/null
42@@ -0,0 +1,158 @@
43+/*
44+ * Copyright (C) 2010 Lars-Peter Clausen <lars@metafoo.de>
45+ *
46+ * This program is free software; you can redistribute it and/or modify
47+ * it under the terms of the GNU General Public License version 2 or later
48+ * as published by the Free Software Foundation.
49+ */
50+
51+#include <linux/kernel.h>
52+#include <linux/init.h>
53+#include <linux/gpio.h>
54+
55+#include <asm/mach-jz4740/platform.h>
56+
57+#include <linux/input.h>
58+#include <linux/power_supply.h>
59+#include <linux/pwm_backlight.h>
60+
61+#include "clock.h"
62+
63+#include <asm/mach-jz4740/jz4740_fb.h>
64+#include <asm/mach-jz4740/jz4740_nand.h>
65+
66+/* NAND */
67+static struct nand_ecclayout id800wt_ecclayout = {
68+ .oobfree = {
69+ {
70+ .offset = 2,
71+ .length = 4,
72+ },
73+ {
74+ .offset = 42,
75+ .length = 22,
76+ },
77+ }
78+};
79+
80+static struct mtd_partition id800wt_partitions[] = {
81+ { .name = "NAND BOOT partition",
82+ .offset = 0 * 0x100000,
83+ .size = 2 * 0x100000,
84+ },
85+ { .name = "NAND KERNEL partition",
86+ .offset = 2 * 0x100000,
87+ .size = 4 * 0x100000,
88+ },
89+ { .name = "NAND ROOTFS partition",
90+ .offset = 6 * 0x100000,
91+ .size = 498 * 0x100000,
92+ },
93+};
94+
95+static struct jz_nand_platform_data id800wt_nand_pdata = {
96+ .ecc_layout = &id800wt_ecclayout,
97+ .partitions = id800wt_partitions,
98+ .num_partitions = ARRAY_SIZE(id800wt_partitions),
99+ .busy_gpio = JZ_GPIO_PORTC(30),
100+};
101+
102+/* Display */
103+static struct fb_videomode id800wt_video_modes[] = {
104+ {
105+ .name = "800x600",
106+ .xres = 800,
107+ .yres = 600,
108+ .refresh = 40,
109+ .left_margin = 0,
110+ .right_margin = 255,
111+ .upper_margin = 0,
112+ .lower_margin = 35,
113+ .hsync_len = 1,
114+ .vsync_len = 1,
115+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
116+ .vmode = FB_VMODE_NONINTERLACED,
117+ },
118+};
119+
120+static struct jz4740_fb_platform_data id800wt_fb_pdata = {
121+ .width = 60,
122+ .height = 45,
123+ .num_modes = ARRAY_SIZE(id800wt_video_modes),
124+ .modes = id800wt_video_modes,
125+ .bpp = 16,
126+ .lcd_type = JZ_LCD_TYPE_SPECIAL_TFT_1,
127+ .pixclk_falling_edge = 1,
128+ .special_tft_config = {
129+ .spl = JZ4740_FB_SPECIAL_TFT_CONFIG(1051, 1053),
130+ .cls = JZ4740_FB_SPECIAL_TFT_CONFIG(631, 744),
131+ .ps = JZ4740_FB_SPECIAL_TFT_CONFIG(0, 45),
132+ .rev = JZ4740_FB_SPECIAL_TFT_CONFIG(0, 0),
133+ },
134+};
135+
136+/* Backlight */
137+static int id800wt_backlight_invert(struct device *dev, int brightness)
138+{
139+ return 255 - brightness;
140+}
141+
142+static struct platform_pwm_backlight_data id800wt_backlight_data = {
143+ .pwm_id = 7,
144+ .max_brightness = 255,
145+ .dft_brightness = 255,
146+ .pwm_period_ns = 8000000,
147+ .notify = id800wt_backlight_invert,
148+};
149+
150+static struct platform_device id800wt_backlight_device = {
151+ .name = "pwm-backlight",
152+ .id = -1,
153+ .dev = {
154+ .platform_data = &id800wt_backlight_data,
155+ .parent = &jz4740_framebuffer_device.dev,
156+ },
157+};
158+
159+static struct platform_device *jz_platform_devices[] __initdata = {
160+ &jz4740_usb_ohci_device,
161+ &jz4740_udc_device,
162+ &jz4740_nand_device,
163+ &jz4740_framebuffer_device,
164+ &jz4740_i2s_device,
165+ &jz4740_codec_device,
166+ &jz4740_pcm_device,
167+ &jz4740_rtc_device,
168+ &jz4740_adc_device,
169+ &id800wt_backlight_device,
170+};
171+
172+static int __init id800wt_init_platform_devices(void)
173+{
174+ jz4740_framebuffer_device.dev.platform_data = &id800wt_fb_pdata;
175+ jz4740_nand_device.dev.platform_data = &id800wt_nand_pdata;
176+
177+ jz4740_serial_device_register();
178+
179+ jz_gpio_enable_pullup(JZ_GPIO_LCD_PS);
180+ jz_gpio_enable_pullup(JZ_GPIO_LCD_REV);
181+
182+ return platform_add_devices(jz_platform_devices,
183+ ARRAY_SIZE(jz_platform_devices));
184+}
185+
186+struct jz4740_clock_board_data jz4740_clock_bdata = {
187+ .ext_rate = 12000000,
188+ .rtc_rate = 32768,
189+};
190+
191+static int __init id800wt_board_setup(void)
192+{
193+ printk("Sungale pictureframe id800wt setup\n");
194+
195+ if (id800wt_init_platform_devices())
196+ panic("Failed to initalize platform devices\n");
197+
198+ return 0;
199+}
200+arch_initcall(id800wt_board_setup);
201--
2021.7.4.1
203
target/linux/xburst/patches-3.0/0005-Add-N516-sound-SoC-board-driver.patch
1From 523f9ca02b5c2c8b79f1d01fff03b1191a6aed6c Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 1 Aug 2010 21:34:54 +0200
4Subject: [PATCH 05/29] Add N516 sound SoC board driver
5
6---
7 sound/soc/jz4740/Kconfig | 8 ++
8 sound/soc/jz4740/Makefile | 2 +
9 sound/soc/jz4740/n516.c | 303 +++++++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 313 insertions(+), 0 deletions(-)
11 create mode 100644 sound/soc/jz4740/n516.c
12
13diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
14index 5351cba..08530ca 100644
15--- a/sound/soc/jz4740/Kconfig
16@@ -21,3 +21,11 @@ config SND_JZ4740_SOC_QI_LB60
17     help
18       Say Y if you want to add support for ASoC audio on the Qi LB60 board
19       a.k.a Qi Ben NanoNote.
20+
21+config SND_JZ4740_SOC_N516
22+ tristate "SoC Audio support for Hanvon N516 eBook reader"
23+ depends on SND_JZ4740_SOC && JZ4740_N516
24+ select SND_JZ4740_SOC_I2S
25+ select SND_SOC_JZCODEC
26+ help
27+ Say Y if you want to enable support for SoC audio on the Hanvon N516.
28diff --git a/sound/soc/jz4740/Makefile b/sound/soc/jz4740/Makefile
29index be873c1..b64d912 100644
30--- a/sound/soc/jz4740/Makefile
31@@ -9,5 +9,7 @@ obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o
32
33 # Jz4740 Machine Support
34 snd-soc-qi-lb60-objs := qi_lb60.o
35+snd-soc-n516-objs := n516.o
36
37 obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
38+obj-$(CONFIG_SND_JZ4740_SOC_N516) += snd-soc-n516.o
39diff --git a/sound/soc/jz4740/n516.c b/sound/soc/jz4740/n516.c
40new file mode 100644
41index 0000000..9cb51c2
42--- /dev/null
43@@ -0,0 +1,303 @@
44+/*
45+ * Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com>
46+ * OpenInkpot project
47+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
48+ *
49+ * This program is free software; you can redistribute it and/or modify
50+ * it under the terms of the GNU General Public License version 2 as
51+ * published by the Free Software Foundation.
52+ *
53+ * You should have received a copy of the GNU General Public License along
54+ * with this program; if not, write to the Free Software Foundation, Inc.,
55+ * 675 Mass Ave, Cambridge, MA 02139, USA.
56+ *
57+ */
58+
59+#include <linux/module.h>
60+#include <linux/interrupt.h>
61+#include <linux/platform_device.h>
62+#include <sound/core.h>
63+#include <sound/pcm.h>
64+#include <sound/soc.h>
65+#include <sound/soc-dapm.h>
66+#include <sound/jack.h>
67+#include <linux/gpio.h>
68+#include <linux/workqueue.h>
69+
70+#include "../codecs/jzcodec.h"
71+#include "jz4740-pcm.h"
72+#include "jz4740-i2s.h"
73+
74+#include <asm/mach-jz4740/board-n516.h>
75+
76+enum {
77+ N516_SPEAKER_AUTO = 0,
78+ N516_SPEAKER_OFF = 1,
79+ N516_SPEAKER_ON = 2,
80+};
81+
82+static int n516_speaker_mode;
83+static struct snd_soc_codec *n516_codec;
84+static struct work_struct n516_headphone_work;
85+
86+static void n516_ext_control(void)
87+{
88+ if (!n516_codec)
89+ return;
90+
91+ switch (n516_speaker_mode) {
92+ case N516_SPEAKER_ON:
93+ snd_soc_dapm_enable_pin(n516_codec, "Speaker");
94+ break;
95+ case N516_SPEAKER_OFF:
96+ snd_soc_dapm_disable_pin(n516_codec, "Speaker");
97+ break;
98+ case N516_SPEAKER_AUTO:
99+ if (snd_soc_dapm_get_pin_status(n516_codec, "Headphone"))
100+ snd_soc_dapm_disable_pin(n516_codec, "Speaker");
101+ else
102+ snd_soc_dapm_enable_pin(n516_codec, "Speaker");
103+ break;
104+ default:
105+ break;
106+ }
107+
108+ /* signal a DAPM event */
109+ snd_soc_dapm_sync(n516_codec);
110+}
111+
112+static int n516_speaker_event(struct snd_soc_dapm_widget *widget,
113+ struct snd_kcontrol *ctrl, int event)
114+{
115+ int on = !SND_SOC_DAPM_EVENT_OFF(event);
116+
117+ gpio_set_value(GPIO_SPEAKER_ENABLE, on);
118+
119+ return 0;
120+}
121+
122+static void n516_headphone_event_work(struct work_struct *work)
123+{
124+ n516_ext_control();
125+}
126+
127+static int n516_headphone_event(struct snd_soc_dapm_widget *widget,
128+ struct snd_kcontrol *ctrl, int event)
129+{
130+ /* We can't call soc_dapm_sync from a event handler */
131+ if (event & (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD))
132+ schedule_work(&n516_headphone_work);
133+ return 0;
134+}
135+
136+static const struct snd_soc_dapm_widget n516_widgets[] = {
137+ SND_SOC_DAPM_SPK("Speaker", n516_speaker_event),
138+ SND_SOC_DAPM_HP("Headphone", n516_headphone_event),
139+ SND_SOC_DAPM_MIC("Mic", NULL),
140+};
141+
142+static const struct snd_soc_dapm_route n516_routes[] = {
143+ {"Mic", NULL, "MIC"},
144+ {"Speaker", NULL, "LOUT"},
145+ {"Speaker", NULL, "ROUT"},
146+ {"Headphone", NULL, "LOUT"},
147+ {"Headphone", NULL, "ROUT"},
148+};
149+
150+static const char *n516_speaker_modes[] = {"Auto", "Off", "On"};
151+static const struct soc_enum n516_speaker_mode_enum =
152+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(n516_speaker_modes), n516_speaker_modes);
153+
154+static int n516_get_speaker_mode(struct snd_kcontrol *kcontrol,
155+ struct snd_ctl_elem_value *ucontrol)
156+{
157+ ucontrol->value.integer.value[0] = n516_speaker_mode;
158+ return 0;
159+}
160+
161+static int n516_set_speaker_mode(struct snd_kcontrol *kcontrol,
162+ struct snd_ctl_elem_value *ucontrol)
163+{
164+ if (n516_speaker_mode == ucontrol->value.integer.value[0])
165+ return 0;
166+
167+ n516_speaker_mode = ucontrol->value.integer.value[0];
168+ n516_ext_control();
169+ return 1;
170+}
171+
172+static const struct snd_kcontrol_new n516_controls[] = {
173+ SOC_ENUM_EXT("Speaker Function", n516_speaker_mode_enum,
174+ n516_get_speaker_mode, n516_set_speaker_mode),
175+};
176+
177+#define N516_DAIFMT (SND_SOC_DAIFMT_I2S | \
178+ SND_SOC_DAIFMT_NB_NF | \
179+ SND_SOC_DAIFMT_CBM_CFM)
180+
181+static int n516_codec_init(struct snd_soc_codec *codec)
182+{
183+ int ret;
184+ struct snd_soc_dai *cpu_dai = codec->socdev->card->dai_link->cpu_dai;
185+ struct snd_soc_dai *codec_dai = codec->socdev->card->dai_link->codec_dai;
186+
187+ n516_codec = codec;
188+
189+ snd_soc_dapm_nc_pin(codec, "LIN");
190+ snd_soc_dapm_nc_pin(codec, "RIN");
191+
192+ ret = snd_soc_dai_set_fmt(codec_dai, N516_DAIFMT);
193+ if (ret < 0) {
194+ dev_err(codec->dev, "Failed to set codec dai format: %d\n", ret);
195+ return ret;
196+ }
197+
198+ ret = snd_soc_dai_set_fmt(cpu_dai, N516_DAIFMT);
199+ if (ret < 0) {
200+ dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret);
201+ return ret;
202+ }
203+
204+ ret = snd_soc_dai_set_sysclk(codec_dai, JZCODEC_SYSCLK, 111,
205+ SND_SOC_CLOCK_IN);
206+ if (ret < 0) {
207+ dev_err(codec->dev, "Failed to set codec dai sysclk: %d\n", ret);
208+ return ret;
209+ }
210+
211+ ret = snd_soc_add_controls(codec, n516_controls,
212+ ARRAY_SIZE(n516_controls));
213+ if (ret) {
214+ dev_err(codec->dev, "Failed to add controls: %d\n", ret);
215+ return ret;
216+ }
217+
218+
219+ ret = snd_soc_dapm_new_controls(codec, n516_widgets,
220+ ARRAY_SIZE(n516_widgets));
221+ if (ret) {
222+ dev_err(codec->dev, "Failed to add dapm controls: %d\n", ret);
223+ return ret;
224+ }
225+
226+ ret = snd_soc_dapm_add_routes(codec, n516_routes, ARRAY_SIZE(n516_routes));
227+ if (ret) {
228+ dev_err(codec->dev, "Failed to add dapm routes: %d\n", ret);
229+ return ret;
230+ }
231+
232+ snd_soc_dapm_sync(codec);
233+
234+ return 0;
235+}
236+
237+static struct snd_soc_dai_link n516_dai = {
238+ .name = "jz-codec",
239+ .stream_name = "JZCODEC",
240+ .cpu_dai = &jz4740_i2s_dai,
241+ .codec_dai = &jz_codec_dai,
242+ .init = n516_codec_init,
243+};
244+
245+static struct snd_soc_card n516_card = {
246+ .name = "N516",
247+ .dai_link = &n516_dai,
248+ .num_links = 1,
249+ .platform = &jz4740_soc_platform,
250+};
251+
252+static struct snd_soc_device n516_snd_devdata = {
253+ .card = &n516_card,
254+ .codec_dev = &soc_codec_dev_jzcodec,
255+};
256+
257+static struct platform_device *n516_snd_device;
258+
259+static struct snd_soc_jack n516_hp_jack;
260+
261+static struct snd_soc_jack_pin n516_hp_pin = {
262+ .pin = "Headphone",
263+ .mask = SND_JACK_HEADPHONE,
264+};
265+
266+static struct snd_soc_jack_gpio n516_hp_gpio = {
267+ .gpio = GPIO_HPHONE_DETECT,
268+ .name = "Headphone detect",
269+ .report = SND_JACK_HEADPHONE,
270+ .debounce_time = 100,
271+};
272+
273+static int __init n516_add_headphone_jack(void)
274+{
275+ int ret;
276+
277+ ret = snd_soc_jack_new(&n516_card, "Headphone jack",
278+ SND_JACK_HEADPHONE, &n516_hp_jack);
279+ if (ret)
280+ return ret;
281+
282+ ret = snd_soc_jack_add_pins(&n516_hp_jack, 1, &n516_hp_pin);
283+ if (ret)
284+ return ret;
285+
286+ ret = snd_soc_jack_add_gpios(&n516_hp_jack, 1, &n516_hp_gpio);
287+
288+ return ret;
289+}
290+
291+static int __init n516_init(void)
292+{
293+ int ret;
294+
295+ n516_snd_device = platform_device_alloc("soc-audio", -1);
296+
297+ if (!n516_snd_device)
298+ return -ENOMEM;
299+
300+ ret = gpio_request(GPIO_SPEAKER_ENABLE, "Speaker enable");
301+ if (ret) {
302+ pr_err("n516 snd: Failed to request SPEAKER_ENABLE GPIO(%d): %d\n",
303+ GPIO_SPEAKER_ENABLE, ret);
304+ goto err_device_put;
305+ }
306+
307+ gpio_direction_output(GPIO_SPEAKER_ENABLE, 0);
308+ INIT_WORK(&n516_headphone_work, n516_headphone_event_work);
309+
310+ platform_set_drvdata(n516_snd_device, &n516_snd_devdata);
311+ n516_snd_devdata.dev = &n516_snd_device->dev;
312+ ret = platform_device_add(n516_snd_device);
313+ if (ret) {
314+ pr_err("n516 snd: Failed to add snd soc device: %d\n", ret);
315+ goto err_unset_pdata;
316+ }
317+
318+ ret = n516_add_headphone_jack();
319+ /* We can live without it, so just print a warning */
320+ if (ret)
321+ pr_warning("n516 snd: Failed to initalise headphone jack: %d\n", ret);
322+
323+ return 0;
324+
325+err_unset_pdata:
326+ platform_set_drvdata(n516_snd_device, NULL);
327+/*err_gpio_free_speaker:*/
328+ gpio_free(GPIO_SPEAKER_ENABLE);
329+err_device_put:
330+ platform_device_put(n516_snd_device);
331+
332+ return ret;
333+}
334+module_init(n516_init);
335+
336+static void __exit n516_exit(void)
337+{
338+ snd_soc_jack_free_gpios(&n516_hp_jack, 1, &n516_hp_gpio);
339+ gpio_free(GPIO_SPEAKER_ENABLE);
340+ platform_device_unregister(n516_snd_device);
341+}
342+module_exit(n516_exit);
343+
344+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
345+MODULE_DESCRIPTION("ALSA SoC N516 Audio support");
346+MODULE_LICENSE("GPL v2");
347--
3481.7.4.1
349
target/linux/xburst/patches-3.0/0006-Add-n516-lpc-driver.patch
1From b02e39f1ba2310fedf212d2a6e5d99c4a14fc297 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Wed, 12 May 2010 14:22:36 +0200
4Subject: [PATCH 06/29] Add n516 lpc driver
5
6---
7 drivers/misc/Kconfig | 8 +
8 drivers/misc/Makefile | 1 +
9 drivers/misc/n516-lpc.c | 471 +++++++++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 480 insertions(+), 0 deletions(-)
11 create mode 100644 drivers/misc/n516-lpc.c
12
13diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
14index 4e349cd..aabc92e 100644
15--- a/drivers/misc/Kconfig
16@@ -490,6 +490,14 @@ config PCH_PHUB
17       To compile this driver as a module, choose M here: the module will
18       be called pch_phub.
19
20+config N516_LPC
21+ tristate "N516 keys & power controller"
22+ depends on I2C
23+ depends on INPUT
24+ depends on POWER_SUPPLY
25+ help
26+ N516 keyboard & power controller driver
27+
28 source "drivers/misc/c2port/Kconfig"
29 source "drivers/misc/eeprom/Kconfig"
30 source "drivers/misc/cb710/Kconfig"
31diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
32index 5f03172..905b807 100644
33--- a/drivers/misc/Makefile
34@@ -46,3 +46,4 @@ obj-y += ti-st/
35 obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
36 obj-y += lis3lv02d/
37 obj-y += carma/
38+obj-$(CONFIG_N516_LPC) += n516-lpc.o
39diff --git a/drivers/misc/n516-lpc.c b/drivers/misc/n516-lpc.c
40new file mode 100644
41index 0000000..2b7a5b3
42--- /dev/null
43@@ -0,0 +1,471 @@
44+#include <linux/module.h>
45+#include <linux/version.h>
46+#include <linux/init.h>
47+#include <linux/fs.h>
48+#include <linux/interrupt.h>
49+#include <linux/irq.h>
50+#include <linux/sched.h>
51+#include <linux/pm.h>
52+#include <linux/sysctl.h>
53+#include <linux/proc_fs.h>
54+#include <linux/delay.h>
55+#include <linux/platform_device.h>
56+#include <linux/input.h>
57+#include <linux/power_supply.h>
58+#include <linux/suspend.h>
59+
60+#include <linux/i2c.h>
61+
62+#include <asm/mach-jz4740/irq.h>
63+#include <asm/mach-jz4740/gpio.h>
64+#include <asm/mach-jz4740/board-n516.h>
65+
66+static int batt_level=0;
67+module_param(batt_level, int, 0);
68+
69+struct n516_lpc_chip {
70+ struct i2c_client *i2c_client;
71+ struct input_dev *input;
72+ unsigned int battery_level;
73+ unsigned int suspending:1, can_sleep:1;
74+};
75+
76+static struct n516_lpc_chip *the_lpc;
77+
78+struct i2c_device_id n516_lpc_i2c_ids[] = {
79+ {"LPC524", 0},
80+ {},
81+};
82+
83+MODULE_DEVICE_TABLE(i2c, n516_lpc_i2c_ids);
84+
85+static const unsigned short normal_i2c[] = I2C_ADDRS(0x54);
86+
87+static const unsigned int n516_lpc_keymap[] = {
88+ [0x01] = KEY_4,
89+ [0x02] = KEY_3,
90+ [0x03] = KEY_2,
91+ [0x04] = KEY_1,
92+ [0x05] = KEY_0,
93+ [0x07] = KEY_9,
94+ [0x08] = KEY_8,
95+ [0x09] = KEY_7,
96+ [0x0a] = KEY_6,
97+ [0x0b] = KEY_5,
98+ [0x0d] = KEY_PLAYPAUSE,
99+ [0x0e] = KEY_MENU,
100+ [0x0f] = KEY_SEARCH,
101+ [0x10] = KEY_DIRECTION,
102+ [0x11] = KEY_SPACE,
103+ [0x13] = KEY_ENTER,
104+ [0x14] = KEY_UP,
105+ [0x15] = KEY_DOWN,
106+ [0x16] = KEY_RIGHT,
107+ [0x17] = KEY_LEFT,
108+ [0x19] = KEY_PAGEDOWN,
109+ [0x1a] = KEY_PAGEUP,
110+ [0x1c] = KEY_POWER,
111+ [0x1d] = KEY_ESC,
112+ [0x1e] = KEY_SLEEP,
113+ [0x1f] = KEY_WAKEUP,
114+};
115+
116+static const unsigned int batt_charge[] = {0, 7, 20, 45, 65, 80, 100};
117+#define MAX_BAT_LEVEL 6
118+
119+static inline int n516_bat_charging(void)
120+{
121+ return !gpio_get_value(GPIO_CHARG_STAT_N);
122+}
123+
124+static int n516_bat_get_status(struct power_supply *b)
125+{
126+ if (power_supply_am_i_supplied(b)) {
127+ if (n516_bat_charging())
128+ return POWER_SUPPLY_STATUS_CHARGING;
129+ else
130+ return POWER_SUPPLY_STATUS_FULL;
131+ } else {
132+ return POWER_SUPPLY_STATUS_DISCHARGING;
133+ }
134+}
135+
136+static int n516_bat_get_charge(struct power_supply *b)
137+{
138+ return batt_charge[the_lpc->battery_level];
139+}
140+
141+static int n516_bat_get_property(struct power_supply *b,
142+ enum power_supply_property psp,
143+ union power_supply_propval *val)
144+{
145+ switch (psp) {
146+ case POWER_SUPPLY_PROP_STATUS:
147+ val->intval = n516_bat_get_status(b);
148+ break;
149+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
150+ val->intval = 100;
151+ break;
152+ case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
153+ val->intval = 0;
154+ break;
155+ case POWER_SUPPLY_PROP_CHARGE_NOW:
156+ val->intval = n516_bat_get_charge(b);
157+ break;
158+ default:
159+ return -EINVAL;
160+ }
161+ return 0;
162+}
163+
164+static void n516_bat_power_changed(struct power_supply *p)
165+{
166+ if (power_supply_am_i_supplied(p) && !n516_bat_charging())
167+ the_lpc->battery_level = MAX_BAT_LEVEL;
168+
169+ power_supply_changed(p);
170+}
171+
172+static enum power_supply_property n516_bat_properties[] = {
173+ POWER_SUPPLY_PROP_STATUS,
174+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
175+ POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
176+ POWER_SUPPLY_PROP_CHARGE_NOW,
177+};
178+
179+static struct power_supply n516_battery = {
180+ .name = "n516-battery",
181+ .get_property = n516_bat_get_property,
182+ .properties = n516_bat_properties,
183+ .num_properties = ARRAY_SIZE(n516_bat_properties),
184+ .external_power_changed = n516_bat_power_changed,
185+};
186+
187+static irqreturn_t n516_bat_charge_irq(int irq, void *dev)
188+{
189+ struct power_supply *psy = dev;
190+
191+ dev_dbg(psy->dev, "Battery charging IRQ\n");
192+
193+ if (power_supply_am_i_supplied(psy) && !n516_bat_charging())
194+ the_lpc->battery_level = MAX_BAT_LEVEL;
195+
196+ power_supply_changed(psy);
197+
198+ return IRQ_HANDLED;
199+}
200+
201+static int n516_lpc_send_message(struct n516_lpc_chip *chip, unsigned char val)
202+{
203+ struct i2c_client *client = chip->i2c_client;
204+ struct i2c_msg msg = {client->addr, client->flags, 1, &val};
205+ int ret = 0;
206+
207+ ret = i2c_transfer(client->adapter, &msg, 1);
208+ return ret > 0 ? 0 : ret;
209+}
210+
211+static void n516_key_event(struct n516_lpc_chip *chip, unsigned char keycode)
212+{
213+ struct i2c_client *client = chip->i2c_client;
214+ bool long_press = false;
215+
216+ if (keycode & 0x40) {
217+ keycode &= ~0x40;
218+ long_press = true;
219+ }
220+
221+ dev_dbg(&client->dev, "keycode: 0x%02x, long_press: 0x%02x\n", keycode, (unsigned int)long_press);
222+
223+ if (keycode >= ARRAY_SIZE(n516_lpc_keymap) || n516_lpc_keymap[keycode] == 0)
224+ return;
225+
226+ if (long_press)
227+ input_report_key(chip->input, KEY_LEFTALT, 1);
228+
229+ input_report_key(chip->input, n516_lpc_keymap[keycode], 1);
230+ input_sync(chip->input);
231+ input_report_key(chip->input, n516_lpc_keymap[keycode], 0);
232+
233+ if (long_press)
234+ input_report_key(chip->input, KEY_LEFTALT, 0);
235+ input_sync(chip->input);
236+}
237+
238+static void n516_battery_event(struct n516_lpc_chip *chip, unsigned char battery_level)
239+{
240+ if (battery_level != chip->battery_level) {
241+ chip->battery_level = battery_level;
242+ power_supply_changed(&n516_battery);
243+ }
244+}
245+
246+static irqreturn_t n516_lpc_irq_thread(int irq, void *devid)
247+{
248+ struct n516_lpc_chip *chip = (struct n516_lpc_chip*)devid;
249+ int ret;
250+ unsigned char raw_msg;
251+ struct i2c_client *client = chip->i2c_client;
252+ struct i2c_msg msg = {client->addr, client->flags | I2C_M_RD, 1, &raw_msg};
253+
254+ if (client->dev.power.status >= DPM_OFF)
255+ return IRQ_HANDLED;
256+
257+ ret = i2c_transfer(client->adapter, &msg, 1);
258+ if (ret != 1) {
259+ dev_dbg(&client->dev, "I2C error: %d\n", ret);
260+ return IRQ_HANDLED;
261+ }
262+
263+ dev_dbg(&client->dev, "msg: 0x%02x\n", raw_msg);
264+
265+ /* Ack wakeup event */
266+ if ((raw_msg & ~0x40) < ARRAY_SIZE(n516_lpc_keymap))
267+ n516_key_event(chip, raw_msg);
268+ else if ((raw_msg >= 0x81) && (raw_msg <= 0x87))
269+ n516_battery_event(chip, raw_msg - 0x81);
270+ else if (raw_msg == 0x7e)
271+ n516_lpc_send_message(chip, 0x00);
272+ else
273+ dev_warn(&client->dev, "Unknown message: %x\n", raw_msg);
274+
275+ if (chip->suspending)
276+ chip->can_sleep = 0;
277+
278+ return IRQ_HANDLED;
279+}
280+
281+static void n516_lpc_power_off(void)
282+{
283+ struct i2c_client *client = the_lpc->i2c_client;
284+ unsigned char val = 0x01;
285+ struct i2c_msg msg = {client->addr, client->flags, 1, &val};
286+
287+ printk("Issue LPC POWEROFF command...\n");
288+ while (1)
289+ i2c_transfer(client->adapter, &msg, 1);
290+}
291+
292+static int n516_lpc_detect(struct i2c_client *client, struct i2c_board_info *info)
293+{
294+ return 0;
295+}
296+
297+static int n516_lpc_suspend_notifier(struct notifier_block *nb,
298+ unsigned long event,
299+ void *dummy)
300+{
301+ switch(event) {
302+ case PM_SUSPEND_PREPARE:
303+ the_lpc->suspending = 1;
304+ the_lpc->can_sleep = 1;
305+ break;
306+ case PM_POST_SUSPEND:
307+ the_lpc->suspending = 0;
308+ the_lpc->can_sleep = 1;
309+ break;
310+ default:
311+ return NOTIFY_DONE;
312+ }
313+ return NOTIFY_OK;
314+}
315+
316+static struct notifier_block n516_lpc_notif_block = {
317+ .notifier_call = n516_lpc_suspend_notifier,
318+};
319+
320+static int __devinit n516_lpc_probe(struct i2c_client *client, const struct i2c_device_id *id)
321+{
322+ struct n516_lpc_chip *chip;
323+ struct input_dev *input;
324+ int ret = 0;
325+ int i;
326+
327+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
328+ if (!chip)
329+ return -ENOMEM;
330+
331+ the_lpc = chip;
332+ chip->i2c_client = client;
333+ if ((batt_level > 0) && (batt_level < ARRAY_SIZE(batt_charge)))
334+ chip->battery_level = batt_level;
335+ else
336+ chip->battery_level = 1;
337+
338+ i2c_set_clientdata(client, chip);
339+
340+ ret = gpio_request(GPIO_LPC_INT, "LPC interrupt request");
341+ if (ret) {
342+ dev_err(&client->dev, "Unable to reguest LPC INT GPIO\n");
343+ goto err_gpio_req_lpcint;
344+ }
345+
346+ ret = gpio_request(GPIO_CHARG_STAT_N, "LPC charging status");
347+ if (ret) {
348+ dev_err(&client->dev, "Unable to reguest CHARG STAT GPIO\n");
349+ goto err_gpio_req_chargstat;
350+ }
351+
352+ /* Enter normal mode */
353+ n516_lpc_send_message(chip, 0x2);
354+
355+ input = input_allocate_device();
356+ if (!input) {
357+ dev_err(&client->dev, "Unable to allocate input device\n");
358+ ret = -ENOMEM;
359+ goto err_input_alloc;
360+ }
361+
362+ chip->input = input;
363+
364+ __set_bit(EV_KEY, input->evbit);
365+
366+ for (i = 0; i < ARRAY_SIZE(n516_lpc_keymap); i++)
367+ __set_bit(n516_lpc_keymap[i], input->keybit);
368+
369+ __set_bit(KEY_LEFTALT, input->keybit);
370+
371+ input->name = "n516-keys";
372+ input->phys = "n516-keys/input0";
373+ input->dev.parent = &client->dev;
374+ input->id.bustype = BUS_I2C;
375+ input->id.vendor = 0x0001;
376+ input->id.product = 0x0001;
377+ input->id.version = 0x0100;
378+
379+ ret = input_register_device(input);
380+ if (ret < 0) {
381+ dev_err(&client->dev, "Unable to register input device\n");
382+ goto err_input_register;
383+ }
384+
385+ ret = power_supply_register(NULL, &n516_battery);
386+ if (ret) {
387+ dev_err(&client->dev, "Unable to register N516 battery\n");
388+ goto err_bat_reg;
389+ }
390+
391+ ret = request_threaded_irq(gpio_to_irq(GPIO_LPC_INT), NULL,
392+ n516_lpc_irq_thread,
393+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
394+ "lpc", chip);
395+ if (ret) {
396+ dev_err(&client->dev, "request_irq failed: %d\n", ret);
397+ goto err_request_lpc_irq;
398+ }
399+
400+ ret = request_irq(gpio_to_irq(GPIO_CHARG_STAT_N), n516_bat_charge_irq,
401+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
402+ "battery charging", &n516_battery);
403+ if (ret) {
404+ dev_err(&client->dev, "Unable to claim battery charging IRQ\n");
405+ goto err_request_chrg_irq;
406+ }
407+
408+ pm_power_off = n516_lpc_power_off;
409+ ret = register_pm_notifier(&n516_lpc_notif_block);
410+ if (ret) {
411+ dev_err(&client->dev, "Unable to register PM notify block\n");
412+ goto err_reg_pm_notifier;
413+ }
414+
415+ device_init_wakeup(&client->dev, 1);
416+
417+ return 0;
418+
419+ unregister_pm_notifier(&n516_lpc_notif_block);
420+err_reg_pm_notifier:
421+ free_irq(gpio_to_irq(GPIO_CHARG_STAT_N), &n516_battery);
422+err_request_chrg_irq:
423+ free_irq(gpio_to_irq(GPIO_LPC_INT), chip);
424+err_request_lpc_irq:
425+ power_supply_unregister(&n516_battery);
426+err_bat_reg:
427+ input_unregister_device(input);
428+err_input_register:
429+ input_free_device(input);
430+err_input_alloc:
431+ gpio_free(GPIO_CHARG_STAT_N);
432+err_gpio_req_chargstat:
433+ gpio_free(GPIO_LPC_INT);
434+err_gpio_req_lpcint:
435+ i2c_set_clientdata(client, NULL);
436+ kfree(chip);
437+
438+ return ret;
439+}
440+
441+static int __devexit n516_lpc_remove(struct i2c_client *client)
442+{
443+ struct n516_lpc_chip *chip = i2c_get_clientdata(client);
444+
445+ unregister_pm_notifier(&n516_lpc_notif_block);
446+ pm_power_off = NULL;
447+ free_irq(gpio_to_irq(GPIO_CHARG_STAT_N), &n516_battery);
448+ free_irq(gpio_to_irq(GPIO_LPC_INT), chip);
449+ power_supply_unregister(&n516_battery);
450+ input_unregister_device(chip->input);
451+ gpio_free(GPIO_CHARG_STAT_N);
452+ gpio_free(GPIO_LPC_INT);
453+ i2c_set_clientdata(client, NULL);
454+ kfree(chip);
455+
456+ return 0;
457+}
458+
459+#if CONFIG_PM
460+static int n516_lpc_suspend(struct i2c_client *client, pm_message_t msg)
461+{
462+ if (!the_lpc->can_sleep)
463+ return -EBUSY;
464+
465+ if (device_may_wakeup(&client->dev))
466+ enable_irq_wake(gpio_to_irq(GPIO_LPC_INT));
467+
468+ return 0;
469+}
470+
471+static int n516_lpc_resume(struct i2c_client *client)
472+{
473+ if (device_may_wakeup(&client->dev))
474+ disable_irq_wake(gpio_to_irq(GPIO_LPC_INT));
475+
476+ return 0;
477+}
478+#else
479+#define n516_lpc_suspend NULL
480+#define n516_lpc_resume NULL
481+#endif
482+
483+
484+static struct i2c_driver n516_lpc_driver = {
485+ .class = I2C_CLASS_HWMON,
486+ .driver = {
487+ .name = "n516-keys",
488+ .owner = THIS_MODULE,
489+ },
490+ .probe = n516_lpc_probe,
491+ .remove = __devexit_p(n516_lpc_remove),
492+ .detect = n516_lpc_detect,
493+ .id_table = n516_lpc_i2c_ids,
494+ .address_list = normal_i2c,
495+ .suspend = n516_lpc_suspend,
496+ .resume = n516_lpc_resume,
497+};
498+
499+static int __init n516_lpc_init(void)
500+{
501+ return i2c_add_driver(&n516_lpc_driver);
502+}
503+module_init(n516_lpc_init);
504+
505+static void __exit n516_lpc_exit(void)
506+{
507+ i2c_del_driver(&n516_lpc_driver);
508+}
509+module_exit(n516_lpc_exit);
510+
511+MODULE_AUTHOR("Yauhen Kharuzhy");
512+MODULE_LICENSE("GPL");
513+MODULE_DESCRIPTION("Keys and power controller driver for N516");
514+MODULE_ALIAS("platform:n516-keys");
515--
5161.7.4.1
517
target/linux/xburst/patches-3.0/0007-Add-N526-sound-SoC-board-driver.patch
1From 19d5c8c334a79951d927a1b6eb25bf6a896c9ab5 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sat, 24 Apr 2010 12:38:41 +0200
4Subject: [PATCH 07/29] Add N526 sound SoC board driver
5
6---
7 sound/soc/jz4740/Kconfig | 8 ++
8 sound/soc/jz4740/Makefile | 2 +
9 sound/soc/jz4740/n526.c | 169 +++++++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 179 insertions(+), 0 deletions(-)
11 create mode 100644 sound/soc/jz4740/n526.c
12
13diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
14index 08530ca..c222dcb 100644
15--- a/sound/soc/jz4740/Kconfig
16@@ -29,3 +29,11 @@ config SND_JZ4740_SOC_N516
17     select SND_SOC_JZCODEC
18     help
19       Say Y if you want to enable support for SoC audio on the Hanvon N516.
20+
21+config SND_JZ4740_SOC_N526
22+ tristate "SoC Audio support for Hanvon N526 eBook reader"
23+ depends on SND_JZ4740_SOC && JZ4740_N526
24+ select SND_JZ4740_SOC_I2S
25+ select SND_SOC_JZCODEC
26+ help
27+ Say Y if you want to enable support for SoC audio on the Hanvon N526.
28diff --git a/sound/soc/jz4740/Makefile b/sound/soc/jz4740/Makefile
29index b64d912..e7952d3 100644
30--- a/sound/soc/jz4740/Makefile
31@@ -10,6 +10,8 @@ obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o
32 # Jz4740 Machine Support
33 snd-soc-qi-lb60-objs := qi_lb60.o
34 snd-soc-n516-objs := n516.o
35+snd-soc-n526-objs := n526.o
36
37 obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
38 obj-$(CONFIG_SND_JZ4740_SOC_N516) += snd-soc-n516.o
39+obj-$(CONFIG_SND_JZ4740_SOC_N526) += snd-soc-n526.o
40diff --git a/sound/soc/jz4740/n526.c b/sound/soc/jz4740/n526.c
41new file mode 100644
42index 0000000..2283904
43--- /dev/null
44@@ -0,0 +1,169 @@
45+/*
46+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
47+ *
48+ * This program is free software; you can redistribute it and/or modify
49+ * it under the terms of the GNU General Public License version 2 as
50+ * published by the Free Software Foundation.
51+ *
52+ * You should have received a copy of the GNU General Public License along
53+ * with this program; if not, write to the Free Software Foundation, Inc.,
54+ * 675 Mass Ave, Cambridge, MA 02139, USA.
55+ *
56+ */
57+
58+#include <linux/module.h>
59+#include <linux/moduleparam.h>
60+#include <linux/timer.h>
61+#include <linux/interrupt.h>
62+#include <linux/platform_device.h>
63+#include <sound/core.h>
64+#include <sound/pcm.h>
65+#include <sound/soc.h>
66+#include <sound/soc-dapm.h>
67+#include <linux/gpio.h>
68+
69+#include "../codecs/jzcodec.h"
70+#include "jz4740-pcm.h"
71+#include "jz4740-i2s.h"
72+
73+#define N526_AMP_EN_GPIO JZ_GPIO_PORTD(4)
74+
75+static int n526_spk_event(struct snd_soc_dapm_widget *widget,
76+ struct snd_kcontrol *ctrl, int event)
77+{
78+ gpio_set_value(N526_AMP_EN_GPIO, !SND_SOC_DAPM_EVENT_OFF(event));
79+ return 0;
80+}
81+
82+static const struct snd_soc_dapm_widget n526_widgets[] = {
83+ SND_SOC_DAPM_SPK("Speaker", n526_spk_event),
84+ SND_SOC_DAPM_HP("Headphone", NULL),
85+ SND_SOC_DAPM_MIC("Mic", NULL),
86+};
87+
88+static const struct snd_soc_dapm_route n526_routes[] = {
89+ {"Mic", NULL, "MIC"},
90+ {"Speaker", NULL, "LOUT"},
91+ {"Speaker", NULL, "ROUT"},
92+ {"Headphone", NULL, "LOUT"},
93+ {"Headphone", NULL, "ROUT"},
94+};
95+
96+static const struct snd_kcontrol_new n526_controls[] = {
97+ SOC_DAPM_PIN_SWITCH("Speaker"),
98+};
99+
100+#define N526_DAIFMT (SND_SOC_DAIFMT_I2S | \
101+ SND_SOC_DAIFMT_NB_NF | \
102+ SND_SOC_DAIFMT_CBM_CFM)
103+
104+static int n526_codec_init(struct snd_soc_codec *codec)
105+{
106+ int ret;
107+ struct snd_soc_dai *cpu_dai = codec->socdev->card->dai_link->cpu_dai;
108+ struct snd_soc_dai *codec_dai = codec->socdev->card->dai_link->codec_dai;
109+
110+ snd_soc_dapm_nc_pin(codec, "LIN");
111+ snd_soc_dapm_nc_pin(codec, "RIN");
112+
113+ ret = snd_soc_dai_set_fmt(codec_dai, N526_DAIFMT);
114+ if (ret < 0) {
115+ dev_err(codec->dev, "Failed to set codec dai format: %d\n", ret);
116+ return ret;
117+ }
118+
119+ ret = snd_soc_dai_set_fmt(cpu_dai, N526_DAIFMT);
120+ if (ret < 0) {
121+ dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret);
122+ return ret;
123+ }
124+
125+ ret = snd_soc_dai_set_sysclk(codec_dai, JZCODEC_SYSCLK, 111,
126+ SND_SOC_CLOCK_IN);
127+ if (ret < 0) {
128+ dev_err(codec->dev, "Failed to set codec dai sysclk: %d\n", ret);
129+ return ret;
130+ }
131+
132+ snd_soc_dapm_new_controls(codec, n526_widgets, ARRAY_SIZE(n526_widgets));
133+
134+ snd_soc_add_controls(codec, n526_controls,
135+ ARRAY_SIZE(n526_controls));
136+
137+ snd_soc_dapm_add_routes(codec, n526_routes, ARRAY_SIZE(n526_routes));
138+
139+ snd_soc_dapm_sync(codec);
140+
141+ return 0;
142+}
143+
144+static struct snd_soc_dai_link n526_dai = {
145+ .name = "jz-codec",
146+ .stream_name = "JZCODEC",
147+ .cpu_dai = &jz4740_i2s_dai,
148+ .codec_dai = &jz_codec_dai,
149+ .init = n526_codec_init,
150+};
151+
152+static struct snd_soc_card n526 = {
153+ .name = "N526",
154+ .dai_link = &n526_dai,
155+ .num_links = 1,
156+ .platform = &jz4740_soc_platform,
157+};
158+
159+static struct snd_soc_device n526_snd_devdata = {
160+ .card = &n526,
161+ .codec_dev = &soc_codec_dev_jzcodec,
162+};
163+
164+static struct platform_device *n526_snd_device;
165+
166+static int __init n526_init(void)
167+{
168+ int ret;
169+
170+ n526_snd_device = platform_device_alloc("soc-audio", -1);
171+
172+ if (!n526_snd_device)
173+ return -ENOMEM;
174+
175+ ret = gpio_request(N526_AMP_EN_GPIO, "AMP");
176+ if (ret) {
177+ pr_err("n526 snd: Failed to request AMP GPIO(%d): %d\n",
178+ N526_AMP_EN_GPIO, ret);
179+ goto err_device_put;
180+ }
181+
182+ gpio_direction_output(JZ_GPIO_PORTD(4), 0);
183+
184+ platform_set_drvdata(n526_snd_device, &n526_snd_devdata);
185+ n526_snd_devdata.dev = &n526_snd_device->dev;
186+ ret = platform_device_add(n526_snd_device);
187+ if (ret) {
188+ pr_err("n526 snd: Failed to add snd soc device: %d\n", ret);
189+ goto err_unset_pdata;
190+ }
191+
192+ return 0;
193+
194+err_unset_pdata:
195+ platform_set_drvdata(n526_snd_device, NULL);
196+ gpio_free(N526_AMP_EN_GPIO);
197+err_device_put:
198+ platform_device_put(n526_snd_device);
199+
200+ return ret;
201+}
202+module_init(n526_init);
203+
204+static void __exit n526_exit(void)
205+{
206+ gpio_free(N526_AMP_EN_GPIO);
207+ platform_device_unregister(n526_snd_device);
208+}
209+module_exit(n526_exit);
210+
211+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
212+MODULE_DESCRIPTION("ALSA SoC N526 audio support");
213+MODULE_LICENSE("GPL v2");
214--
2151.7.4.1
216
target/linux/xburst/patches-3.0/0008-i2c-Add-i2c-driver-for-JZ47XX-SoCs.patch
1From 5e219770079a61b8c8e59abe5510678361c94696 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 5 Sep 2010 03:19:10 +0200
4Subject: [PATCH 08/29] i2c: Add i2c driver for JZ47XX SoCs
5
6This patch adds a driver for the i2c controller found in Ingenic JZ47XX based
7SoCs.
8
9Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
10---
11 drivers/i2c/busses/Kconfig | 10 +
12 drivers/i2c/busses/Makefile | 1 +
13 drivers/i2c/busses/i2c-jz47xx.c | 424 +++++++++++++++++++++++++++++++++++++++
14 3 files changed, 435 insertions(+), 0 deletions(-)
15 create mode 100644 drivers/i2c/busses/i2c-jz47xx.c
16
17diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
18index 646068e..5b76fcf 100644
19--- a/drivers/i2c/busses/Kconfig
20@@ -434,6 +434,16 @@ config I2C_IXP2000
21       This driver is deprecated and will be dropped soon. Use i2c-gpio
22       instead.
23
24+config I2C_JZ47XX
25+ tristate "JZ4740 I2C Interface"
26+ depends on ARCH_JZ4740
27+ help
28+ Say Y here if you want support for the I2C controller found on Ingenic
29+ JZ47XX based SoCs.
30+
31+ This driver can also be built as a module. If so, the module will be
32+ called i2c-jz47xx.
33+
34 config I2C_MPC
35     tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
36     depends on PPC
37diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
38index e6cf294..07be071 100644
39--- a/drivers/i2c/busses/Makefile
40@@ -41,6 +41,7 @@ obj-$(CONFIG_I2C_IMX) += i2c-imx.o
41 obj-$(CONFIG_I2C_INTEL_MID) += i2c-intel-mid.o
42 obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
43 obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
44+obj-$(CONFIG_I2C_JZ47XX) += i2c-jz47xx.o
45 obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
46 obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
47 obj-$(CONFIG_I2C_MXS) += i2c-mxs.o
48diff --git a/drivers/i2c/busses/i2c-jz47xx.c b/drivers/i2c/busses/i2c-jz47xx.c
49new file mode 100644
50index 0000000..492d350
51--- /dev/null
52@@ -0,0 +1,424 @@
53+
54+#include <linux/init.h>
55+#include <linux/kernel.h>
56+#include <linux/module.h>
57+#include <linux/err.h>
58+#include <linux/clk.h>
59+#include <linux/platform_device.h>
60+#include <linux/i2c.h>
61+#include <linux/slab.h>
62+#include <linux/interrupt.h>
63+
64+#include <linux/gpio.h>
65+#include <linux/delay.h>
66+
67+#define JZ47XX_REG_I2C_DATA 0x00
68+#define JZ47XX_REG_I2C_CTRL 0x04
69+#define JZ47XX_REG_I2C_STATUS 0x08
70+#define JZ47XX_REG_I2C_CLOCK 0x0C
71+
72+#define JZ47XX_I2C_STATUS_FIFO_FULL BIT(4)
73+#define JZ47XX_I2C_STATUS_BUSY BIT(3)
74+#define JZ47XX_I2C_STATUS_TEND BIT(2)
75+#define JZ47XX_I2C_STATUS_DATA_VALID BIT(1)
76+#define JZ47XX_I2C_STATUS_NACK BIT(0)
77+
78+#define JZ47XX_I2C_CTRL_IRQ_ENABLE BIT(4)
79+#define JZ47XX_I2C_CTRL_START BIT(3)
80+#define JZ47XX_I2C_CTRL_STOP BIT(2)
81+#define JZ47XX_I2C_CTRL_NACK BIT(1)
82+#define JZ47XX_I2C_CTRL_ENABLE BIT(0)
83+
84+struct jz47xx_i2c {
85+ struct resource *mem;
86+ void __iomem *base;
87+ int irq;
88+ struct clk *clk;
89+
90+ struct i2c_adapter adapter;
91+
92+ wait_queue_head_t wait_queue;
93+};
94+
95+static inline struct jz47xx_i2c *adapter_to_jz47xx_i2c(struct i2c_adapter *adap)
96+{
97+ return container_of(adap, struct jz47xx_i2c, adapter);
98+}
99+
100+static inline void jz47xx_i2c_set_ctrl(struct jz47xx_i2c *jz47xx_i2c,
101+ uint8_t mask, uint8_t value)
102+{
103+ uint8_t ctrl;
104+ ctrl = readb(jz47xx_i2c->base + JZ47XX_REG_I2C_CTRL);
105+ ctrl &= ~mask;
106+ ctrl |= value;
107+ printk("ctrl: %x\n", ctrl);
108+ writeb(ctrl, jz47xx_i2c->base + JZ47XX_REG_I2C_CTRL);
109+}
110+
111+static irqreturn_t jz47xx_i2c_irq_handler(int irq, void *devid)
112+{
113+ struct jz47xx_i2c *jz47xx_i2c = devid;
114+
115+ printk("IRQ\n");
116+
117+ wake_up(&jz47xx_i2c->wait_queue);
118+
119+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_IRQ_ENABLE, 0);
120+
121+ return IRQ_HANDLED;
122+}
123+
124+static inline void jz47xx_i2c_set_data_valid(struct jz47xx_i2c *jz47xx_i2c,
125+ bool valid)
126+{
127+ uint8_t val;
128+ val = readb(jz47xx_i2c->base + JZ47XX_REG_I2C_STATUS);
129+ if (valid)
130+ val |= JZ47XX_I2C_STATUS_DATA_VALID;
131+ else
132+ val &= ~JZ47XX_I2C_STATUS_DATA_VALID;
133+ writeb(val, jz47xx_i2c->base + JZ47XX_REG_I2C_STATUS);
134+}
135+
136+static int jz47xx_i2c_test_event(struct jz47xx_i2c *jz47xx_i2c, uint8_t mask, uint8_t value)
137+{
138+ uint8_t status;
139+
140+ mask |= JZ47XX_I2C_STATUS_NACK;
141+ value |= JZ47XX_I2C_STATUS_NACK;
142+
143+ status = readb(jz47xx_i2c->base + JZ47XX_REG_I2C_STATUS);
144+ printk("status: %x %x %x %x\n", status, mask, value, (status & mask) ^
145+ value);
146+ if (((status & mask) ^ value) == mask) {
147+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_IRQ_ENABLE,
148+ JZ47XX_I2C_CTRL_IRQ_ENABLE);
149+ return 0;
150+ }
151+ return 1;
152+}
153+
154+static int jz47xx_i2c_wait_event_or_nack(struct jz47xx_i2c *jz47xx_i2c, uint8_t
155+mask, uint8_t value)
156+{
157+ int ret;
158+
159+ ret = wait_event_interruptible_timeout(jz47xx_i2c->wait_queue,
160+ jz47xx_i2c_test_event(jz47xx_i2c, mask, value), 30 * HZ);
161+
162+/* while (!jz47xx_i2c_test_event(jz47xx_i2c, mask, value));
163+
164+ ret = 1;*/
165+
166+ printk("wait event or nack: %d %x\n", ret, readb(jz47xx_i2c->base +
167+ JZ47XX_REG_I2C_STATUS));
168+
169+ if (ret == 0)
170+ ret = -ETIMEDOUT;
171+ else if(ret > 0) {
172+ if (readb(jz47xx_i2c->base + JZ47XX_REG_I2C_STATUS) & JZ47XX_I2C_STATUS_NACK)
173+ ret = -EIO;
174+ else
175+ ret = 0;
176+ }
177+
178+ return ret;
179+}
180+
181+static int jz47xx_i2c_wait_event(struct jz47xx_i2c *jz47xx_i2c, uint8_t event)
182+{
183+ int ret;
184+
185+ ret = wait_event_interruptible_timeout(jz47xx_i2c->wait_queue,
186+ jz47xx_i2c_test_event(jz47xx_i2c, event, event), 30 * HZ);
187+
188+ if (ret == 0)
189+ ret = -ETIMEDOUT;
190+ else if(ret > 0)
191+ ret = 0;
192+
193+ return ret;
194+}
195+
196+
197+static int jz47xx_i2c_write_msg(struct jz47xx_i2c *jz47xx_i2c,
198+ struct i2c_msg *msg)
199+{
200+ int ret;
201+ int i;
202+
203+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
204+ for (i = 0; i < msg->len; ++i) {
205+ writeb(msg->buf[i], jz47xx_i2c->base + JZ47XX_REG_I2C_DATA);
206+ jz47xx_i2c_set_data_valid(jz47xx_i2c, true);
207+ ret = jz47xx_i2c_wait_event_or_nack(jz47xx_i2c,
208+ JZ47XX_I2C_STATUS_DATA_VALID, 0);
209+ if (ret)
210+ break;
211+ }
212+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_STOP,
213+ JZ47XX_I2C_CTRL_STOP);
214+
215+ if (!ret)
216+ ret = jz47xx_i2c_wait_event_or_nack(jz47xx_i2c, JZ47XX_I2C_STATUS_TEND,
217+ JZ47XX_I2C_STATUS_TEND);
218+
219+ return ret;
220+}
221+
222+static int jz47xx_i2c_read_msg(struct jz47xx_i2c *jz47xx_i2c,
223+ struct i2c_msg *msg)
224+{
225+ int i;
226+ int ret;
227+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
228+
229+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_NACK,
230+ msg->len == 1 ? JZ47XX_I2C_CTRL_NACK : 0);
231+
232+ for (i = 0; i < msg->len; ++i) {
233+ ret = jz47xx_i2c_wait_event(jz47xx_i2c, JZ47XX_I2C_STATUS_DATA_VALID);
234+ if (ret) {
235+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_NACK,
236+ JZ47XX_I2C_CTRL_NACK);
237+ break;
238+ }
239+
240+ if (i == msg->len - 2) {
241+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_NACK,
242+ JZ47XX_I2C_CTRL_NACK);
243+ }
244+
245+ msg->buf[i] = readb(jz47xx_i2c->base + JZ47XX_REG_I2C_DATA);
246+ printk("read: %x\n", msg->buf[i]);
247+ jz47xx_i2c_set_data_valid(jz47xx_i2c, false);
248+ }
249+
250+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_STOP,
251+ JZ47XX_I2C_CTRL_STOP);
252+
253+ return ret;
254+}
255+
256+static int jz47xx_i2c_xfer_msg(struct jz47xx_i2c *jz47xx_i2c,
257+ struct i2c_msg *msg)
258+{
259+ uint8_t addr;
260+ int ret;
261+
262+ addr = msg->addr << 1;
263+ if (msg->flags & I2C_M_RD)
264+ addr |= 1;
265+
266+ jz47xx_i2c_set_ctrl(jz47xx_i2c, JZ47XX_I2C_CTRL_START,
267+ JZ47XX_I2C_CTRL_START);
268+ writeb(addr, jz47xx_i2c->base + JZ47XX_REG_I2C_DATA);
269+ jz47xx_i2c_set_data_valid(jz47xx_i2c, true);
270+
271+ if (msg->flags & I2C_M_RD) {
272+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
273+ ret = jz47xx_i2c_wait_event_or_nack(jz47xx_i2c,
274+ JZ47XX_I2C_STATUS_TEND, JZ47XX_I2C_STATUS_TEND);
275+ if (!ret)
276+ ret = jz47xx_i2c_read_msg(jz47xx_i2c, msg);
277+ } else {
278+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
279+ ret = jz47xx_i2c_wait_event_or_nack(jz47xx_i2c,
280+ JZ47XX_I2C_STATUS_DATA_VALID, 0);
281+ if (!ret)
282+ ret = jz47xx_i2c_write_msg(jz47xx_i2c, msg);
283+ }
284+
285+ return ret;
286+}
287+
288+static int jz47xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int
289+num)
290+{
291+ struct jz47xx_i2c *jz47xx_i2c = adapter_to_jz47xx_i2c(adap);
292+ int ret = 0;
293+ int i;
294+ int mask = JZ47XX_I2C_CTRL_ENABLE;
295+
296+ printk("xfer: %d %x\n", num, readb(jz47xx_i2c->base +
297+ JZ47XX_REG_I2C_STATUS));
298+
299+ clk_enable(jz47xx_i2c->clk);
300+ jz47xx_i2c_set_ctrl(jz47xx_i2c, mask, mask);
301+
302+ for (i = 0; i < num; ++i) {
303+ ret = jz47xx_i2c_xfer_msg(jz47xx_i2c, &msgs[i]);
304+ if (ret)
305+ break;
306+ }
307+
308+ jz47xx_i2c_set_ctrl(jz47xx_i2c, mask, 0);
309+ clk_disable(jz47xx_i2c->clk);
310+
311+ printk("xfer ret: %d\n", ret);
312+
313+ return ret;
314+}
315+
316+static u32 jz47xx_i2c_functionality(struct i2c_adapter *adap)
317+{
318+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
319+}
320+
321+static const struct i2c_algorithm jz47xx_i2c_algorithm = {
322+ .master_xfer = jz47xx_i2c_xfer,
323+ .functionality = jz47xx_i2c_functionality,
324+};
325+
326+const static struct jz_gpio_bulk_request jz47xx_i2c_pins[] = {
327+ JZ_GPIO_BULK_PIN(I2C_SDA),
328+ JZ_GPIO_BULK_PIN(I2C_SCK),
329+};
330+
331+static int __devinit jz47xx_i2c_probe(struct platform_device *pdev)
332+{
333+ struct jz47xx_i2c *jz47xx_i2c;
334+ struct resource *mem;
335+ void __iomem *base;
336+ struct clk *clk;
337+ int irq;
338+ int ret;
339+
340+ irq = platform_get_irq(pdev, 0);
341+ if (!irq) {
342+ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
343+ return irq;
344+ }
345+
346+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
347+ if (!mem) {
348+ dev_err(&pdev->dev, "Failed to get iomem region\n");
349+ return -ENXIO;
350+ }
351+
352+ mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
353+ if (!mem) {
354+ dev_err(&pdev->dev, "Failed to request iomem region\n");
355+ return -EBUSY;
356+ }
357+
358+ base = ioremap(mem->start, resource_size(mem));
359+ if (!base) {
360+ dev_err(&pdev->dev, "Failed to ioremap iomem\n");
361+ ret = -EBUSY;
362+ goto err_release_mem_region;
363+ }
364+
365+ clk = clk_get(&pdev->dev, "i2c");
366+ if (IS_ERR(clk)) {
367+ ret = PTR_ERR(clk);
368+ goto err_iounmap;
369+ }
370+
371+ jz47xx_i2c = kzalloc(sizeof(*jz47xx_i2c), GFP_KERNEL);
372+ if (!jz47xx_i2c) {
373+ ret = -ENOMEM;
374+ goto err_clk_put;
375+ }
376+
377+ jz47xx_i2c->adapter.owner = THIS_MODULE;
378+ jz47xx_i2c->adapter.algo = &jz47xx_i2c_algorithm;
379+ jz47xx_i2c->adapter.dev.parent = &pdev->dev;
380+ jz47xx_i2c->adapter.nr = pdev->id < 0 ?: 0;
381+ strcpy(jz47xx_i2c->adapter.name, pdev->name);
382+
383+ jz47xx_i2c->mem = mem;
384+ jz47xx_i2c->base = base;
385+ jz47xx_i2c->clk = clk;
386+ jz47xx_i2c->irq = irq;
387+
388+ init_waitqueue_head(&jz47xx_i2c->wait_queue);
389+
390+ ret = request_irq(irq, jz47xx_i2c_irq_handler, 0, pdev->name, jz47xx_i2c);
391+ if (ret) {
392+ dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
393+ goto err_free;
394+ }
395+
396+ ret = jz_gpio_bulk_request(jz47xx_i2c_pins, ARRAY_SIZE(jz47xx_i2c_pins));
397+ if (ret) {
398+ dev_err(&pdev->dev, "Failed to request i2c pins: %d\n", ret);
399+ goto err_free_irq;
400+ }
401+
402+ writew(0x10, jz47xx_i2c->base + JZ47XX_REG_I2C_CLOCK);
403+
404+ ret = i2c_add_numbered_adapter(&jz47xx_i2c->adapter);
405+ if (ret) {
406+ dev_err(&pdev->dev, "Failed to add i2c adapter: %d\n", ret);
407+ goto err_free_gpios;
408+ }
409+
410+ platform_set_drvdata(pdev, jz47xx_i2c);
411+
412+ printk("JZ4740 I2C\n");
413+
414+ return 0;
415+
416+err_free_gpios:
417+ jz_gpio_bulk_free(jz47xx_i2c_pins, ARRAY_SIZE(jz47xx_i2c_pins));
418+err_free_irq:
419+ free_irq(irq, jz47xx_i2c);
420+err_free:
421+ kfree(jz47xx_i2c);
422+err_clk_put:
423+ clk_put(clk);
424+err_iounmap:
425+ iounmap(base);
426+err_release_mem_region:
427+ release_mem_region(mem->start, resource_size(mem));
428+ return ret;
429+}
430+
431+static int __devexit jz47xx_i2c_remove(struct platform_device *pdev)
432+{
433+ struct jz47xx_i2c *jz47xx_i2c = platform_get_drvdata(pdev);
434+
435+ platform_set_drvdata(pdev, NULL);
436+ i2c_del_adapter(&jz47xx_i2c->adapter);
437+
438+ jz_gpio_bulk_free(jz47xx_i2c_pins, ARRAY_SIZE(jz47xx_i2c_pins));
439+
440+ free_irq(jz47xx_i2c->irq, jz47xx_i2c);
441+ clk_put(jz47xx_i2c->clk);
442+
443+ iounmap(jz47xx_i2c->base);
444+ release_mem_region(jz47xx_i2c->mem->start, resource_size(jz47xx_i2c->mem));
445+
446+ kfree(jz47xx_i2c);
447+
448+ return 0;
449+}
450+
451+static struct platform_driver jz47xx_i2c_driver = {
452+ .probe = jz47xx_i2c_probe,
453+ .remove = jz47xx_i2c_remove,
454+ .driver = {
455+ .name = "jz47xx-i2c",
456+ .owner = THIS_MODULE,
457+ },
458+};
459+
460+static int __init jz47xx_i2c_init(void)
461+{
462+ return platform_driver_register(&jz47xx_i2c_driver);
463+}
464+module_init(jz47xx_i2c_init);
465+
466+static void jz47xx_i2c_exit(void)
467+{
468+ platform_driver_unregister(&jz47xx_i2c_driver);
469+}
470+module_exit(jz47xx_i2c_exit);
471+
472+MODULE_LICENSE("GPL");
473+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
474+MODULE_DESCRIPTION("I2C adapter driver for JZ47XX SoCs");
475+MODULE_ALIAS("platform:jz47xx-i2c");
476+
477--
4781.7.4.1
479
target/linux/xburst/patches-3.0/0009-MIPS-JZ4740-Fix-i2c-driver-name.patch
1From 05bc4140f9da08fa48d81131ffa785e3026773a8 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 5 Sep 2010 03:21:51 +0200
4Subject: [PATCH 09/29] MIPS: JZ4740: Fix i2c driver name.
5
6The i2c driver is generic to all JZ47XX based SoCs not only the JZ4740. Reflect
7this in the driver name.
8
9Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
10---
11 arch/mips/jz4740/platform.c | 2 +-
12 1 files changed, 1 insertions(+), 1 deletions(-)
13
14diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
15index 10929e2..cc6de5b 100644
16--- a/arch/mips/jz4740/platform.c
17@@ -142,7 +142,7 @@ static struct resource jz4740_i2c_resources[] = {
18 };
19
20 struct platform_device jz4740_i2c_device = {
21- .name = "jz4740-i2c",
22+ .name = "jz47xx-i2c",
23     .id = 0,
24     .num_resources = ARRAY_SIZE(jz4740_i2c_resources),
25     .resource = jz4740_i2c_resources,
26--
271.7.4.1
28
target/linux/xburst/patches-3.0/0010-MFD-jz4740-adc-Add-support-for-the-touchscreen-part-.patch
1From 659b0bb01c8e567d4593ffbd7acd6b8ceab0edf3 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 5 Sep 2010 20:36:59 +0200
4Subject: [PATCH 10/29] MFD: jz4740-adc: Add support for the touchscreen part of the adc unit
5
6---
7 drivers/mfd/jz4740-adc.c | 27 ++++++++++++++++++++++++---
8 include/linux/jz4740-adc.h | 2 +-
9 2 files changed, 25 insertions(+), 4 deletions(-)
10
11diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
12index a0bd0cf..3be161e 100644
13--- a/drivers/mfd/jz4740-adc.c
14@@ -46,9 +46,9 @@
15 enum {
16     JZ_ADC_IRQ_ADCIN = 0,
17     JZ_ADC_IRQ_BATTERY,
18- JZ_ADC_IRQ_TOUCH,
19- JZ_ADC_IRQ_PENUP,
20- JZ_ADC_IRQ_PENDOWN,
21+ JZ_ADC_IRQ_TS_DATA_READY,
22+ JZ_ADC_IRQ_TS_PENUP,
23+ JZ_ADC_IRQ_TS_PENDOWN,
24 };
25
26 struct jz4740_adc {
27@@ -226,6 +226,27 @@ static struct resource jz4740_battery_resources[] = {
28     },
29 };
30
31+static struct resource jz4740_ts_resources[] = {
32+ {
33+ .start = JZ_ADC_IRQ_TS_DATA_READY,
34+ .flags = IORESOURCE_IRQ,
35+ },
36+ {
37+ .start = JZ_ADC_IRQ_TS_PENUP,
38+ .flags = IORESOURCE_IRQ,
39+ },
40+ {
41+ .start = JZ_ADC_IRQ_TS_PENDOWN,
42+ .flags = IORESOURCE_IRQ,
43+ },
44+ {
45+ .start = JZ_REG_ADC_TOUCHSCREEN_BASE,
46+ .end = JZ_REG_ADC_TOUCHSCREEN_BASE + 0xb,
47+ .flags = IORESOURCE_MEM,
48+ },
49+};
50+
51+
52 const struct mfd_cell jz4740_adc_cells[] = {
53     {
54         .id = 0,
55diff --git a/include/linux/jz4740-adc.h b/include/linux/jz4740-adc.h
56index 9053f95..3f15f66 100644
57--- a/include/linux/jz4740-adc.h
58@@ -25,7 +25,7 @@ int jz4740_adc_set_config(struct device *dev, uint32_t mask, uint32_t val);
59 #define JZ_ADC_CONFIG_BAT_MB BIT(4)
60
61 #define JZ_ADC_CONFIG_DNUM(dnum) ((dnum) << 16)
62-#define JZ_ADC_CONFIG_XYZ_OFFSET(dnum) ((xyz) << 13)
63+#define JZ_ADC_CONFIG_XYZ_OFFSET(xyz) ((xyz) << 13)
64 #define JZ_ADC_CONFIG_SAMPLE_NUM(x) ((x) << 10)
65 #define JZ_ADC_CONFIG_CLKDIV(div) ((div) << 5)
66
67--
681.7.4.1
69
target/linux/xburst/patches-3.0/0011-input-Add-touchscreen-driver-for-the-JZ4740-SoC.patch
1From 71e0648ad022c6f05e1bed1fcca69abc8abde4d9 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 5 Sep 2010 20:45:08 +0200
4Subject: [PATCH 11/29] input: Add touchscreen driver for the JZ4740 SoC
5
6This patch adds a touchscreen driver for the Ingenic JZ4740 SoC.
7The touchscreen controller is part of the ADC unit and thus this driver is a mfd
8cell from the jz4740-adc driver.
9
10Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
11---
12 drivers/input/touchscreen/Kconfig | 12 ++
13 drivers/input/touchscreen/Makefile | 1 +
14 drivers/input/touchscreen/jz4740-ts.c | 330 +++++++++++++++++++++++++++++++++
15 3 files changed, 343 insertions(+), 0 deletions(-)
16 create mode 100644 drivers/input/touchscreen/jz4740-ts.c
17
18diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
19index cabd9e5..10836e5 100644
20--- a/drivers/input/touchscreen/Kconfig
21@@ -726,4 +726,16 @@ config TOUCHSCREEN_TPS6507X
22       To compile this driver as a module, choose M here: the
23       module will be called tps6507x_ts.
24
25+config TOUCHSCREEN_JZ4740
26+ tristate "JZ4740 touchscreen support"
27+ depends on MFD_JZ4740_ADC
28+ help
29+ Say Y here if you want support for the touchscreen controller found on
30+ Ingenic JZ4740 SoCs.
31+
32+ If unsure, say N.
33+
34+ To compile this driver as a module, choose M here: the
35+ module will be called jz4740-ts.
36+
37 endif
38diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
39index 282d6f7..d8cc316 100644
40--- a/drivers/input/touchscreen/Makefile
41@@ -27,6 +27,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
42 obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
43 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
44 obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
45+obj-$(CONFIG_TOUCHSCREEN_JZ4740) += jz4740-ts.o
46 obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o
47 obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o
48 obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
49diff --git a/drivers/input/touchscreen/jz4740-ts.c b/drivers/input/touchscreen/jz4740-ts.c
50new file mode 100644
51index 0000000..dd5de34
52--- /dev/null
53@@ -0,0 +1,330 @@
54+/*
55+ * Touchscreen driver for Ingenic JZ SoCs.
56+ *
57+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
58+ *
59+ * This program is free software; you can redistribute it and/or modify
60+ * it under the terms of the GNU General Public License version 2 as
61+ * published by the Free Software Foundation.
62+ *
63+ */
64+
65+#include <linux/interrupt.h>
66+#include <linux/kernel.h>
67+#include <linux/module.h>
68+#include <linux/platform_device.h>
69+#include <linux/slab.h>
70+
71+#include <linux/delay.h>
72+#include <linux/mfd/core.h>
73+#include <linux/input.h>
74+#include <linux/bitops.h>
75+#include <linux/jz4740-adc.h>
76+
77+struct jz4740_ts {
78+ struct platform_device *pdev;
79+
80+ struct resource *mem;
81+ void __iomem *base;
82+
83+ int irq_penup;
84+ int irq_pendown;
85+ int irq_data_ready;
86+
87+ struct mfd_cell *cell;
88+ struct input_dev *input;
89+
90+ bool is_open;
91+};
92+
93+static irqreturn_t jz4740_ts_data_ready_irq_handler(int irq, void *devid)
94+{
95+ struct jz4740_ts *jz4740_ts = devid;
96+ uint32_t data;
97+ unsigned long x, y, z1, z2, pressure;
98+
99+ data = readl(jz4740_ts->base + 0x08);
100+ x = data & 0xfff;
101+ y = (data >> 16) & 0xfff;
102+
103+ data = readl(jz4740_ts->base + 0x08);
104+ z1 = data & 0xfff;
105+ z2 = (data >> 16) & 0xfff;
106+ if (z1 == 0) {
107+ pressure = 4095UL;
108+ } else if (z1 > z2) {
109+ pressure = 0;
110+ } else {
111+ if (data & 0x8000)
112+ pressure = (((480UL * x * z2) / z1) - 480UL * x) / 4096UL;
113+ else
114+ pressure = (((272UL * y * z2) / z1) - 272UL * y) / 4096UL;
115+ if (pressure >= 4096UL)
116+ pressure = 4095UL;
117+ pressure = 4095UL - pressure;
118+ }
119+
120+ input_report_abs(jz4740_ts->input, ABS_X, y);
121+ input_report_abs(jz4740_ts->input, ABS_Y, 4095 - x);
122+ input_report_abs(jz4740_ts->input, ABS_PRESSURE, pressure);
123+ input_report_key(jz4740_ts->input, BTN_TOUCH, 1);
124+ input_sync(jz4740_ts->input);
125+
126+ return IRQ_HANDLED;
127+}
128+
129+static irqreturn_t jz4740_ts_pen_irq_handler(int irq, void *devid)
130+{
131+ struct jz4740_ts *jz4740_ts = devid;
132+ int is_pressed;
133+
134+ if (irq == jz4740_ts->irq_penup) {
135+ enable_irq(jz4740_ts->irq_pendown);
136+ is_pressed = 0;
137+ } else {
138+ enable_irq(jz4740_ts->irq_penup);
139+ is_pressed = 1;
140+ }
141+ disable_irq_nosync(irq);
142+
143+ printk("pen irq: %d\n", irq);
144+ input_report_key(jz4740_ts->input, BTN_TOUCH, is_pressed);
145+ if (is_pressed == 0)
146+ input_report_abs(jz4740_ts->input, ABS_PRESSURE, 0);
147+ input_sync(jz4740_ts->input);
148+
149+ return IRQ_HANDLED;
150+}
151+
152+static int jz4740_ts_open(struct input_dev *input)
153+{
154+ struct jz4740_ts *jz4740_ts = input_get_drvdata(input);
155+
156+ jz4740_ts->is_open = true;
157+ jz4740_ts->cell->enable(jz4740_ts->pdev);
158+
159+ return 0;
160+}
161+
162+static void jz4740_ts_close(struct input_dev *input)
163+{
164+ struct jz4740_ts *jz4740_ts = input_get_drvdata(input);
165+
166+ jz4740_ts->cell->disable(jz4740_ts->pdev);
167+ jz4740_ts->is_open = false;
168+}
169+
170+static int __devinit jz4740_ts_probe(struct platform_device *pdev)
171+{
172+ int ret = 0;
173+ struct jz4740_ts *jz4740_ts;
174+ struct input_dev *input;
175+
176+ jz4740_ts = kzalloc(sizeof(*jz4740_ts), GFP_KERNEL);
177+ if (!jz4740_ts) {
178+ dev_err(&pdev->dev, "Failed to allocate driver structure\n");
179+ return -ENOMEM;
180+ }
181+
182+ jz4740_ts->pdev = pdev;
183+ jz4740_ts->cell = pdev->dev.platform_data;
184+
185+ jz4740_ts->irq_data_ready = platform_get_irq(pdev, 0);
186+ if (jz4740_ts->irq_data_ready < 0) {
187+ ret = jz4740_ts->irq_data_ready;
188+ dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
189+ goto err_free;
190+ }
191+
192+ jz4740_ts->irq_penup = platform_get_irq(pdev, 1);
193+ if (jz4740_ts->irq_penup < 0) {
194+ ret = jz4740_ts->irq_penup;
195+ dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
196+ goto err_free;
197+ }
198+
199+ jz4740_ts->irq_pendown = platform_get_irq(pdev, 2);
200+ if (jz4740_ts->irq_pendown < 0) {
201+ ret = jz4740_ts->irq_pendown;
202+ dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
203+ goto err_free;
204+ }
205+
206+ jz4740_ts->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
207+ if (!jz4740_ts->mem) {
208+ ret = -ENOENT;
209+ dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
210+ goto err_free;
211+ }
212+
213+ jz4740_ts->mem = request_mem_region(jz4740_ts->mem->start,
214+ resource_size(jz4740_ts->mem), pdev->name);
215+ if (!jz4740_ts->mem) {
216+ ret = -EBUSY;
217+ dev_err(&pdev->dev, "Failed to request mmio memory region\n");
218+ goto err_free;
219+ }
220+
221+ jz4740_ts->base = ioremap_nocache(jz4740_ts->mem->start,
222+ resource_size(jz4740_ts->mem));
223+ if (!jz4740_ts->base) {
224+ ret = -EBUSY;
225+ dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
226+ goto err_release_mem_region;
227+ }
228+
229+ input = input_allocate_device();
230+ if (!input) {
231+ dev_err(&pdev->dev, "Failed to allocate input device\n");
232+ ret = -ENOMEM;
233+ goto err_iounmap;
234+ }
235+
236+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
237+ __set_bit(BTN_TOUCH, input->keybit);
238+
239+ input_set_abs_params(input, ABS_X, 150, 3920, 0, 0);
240+ input_set_abs_params(input, ABS_Y, 270, 3700, 0, 0);
241+ input_set_abs_params(input, ABS_PRESSURE, 0, 4096, 0, 0);
242+
243+ input->name = pdev->name;
244+ input->phys = "jz4740";
245+ input->id.bustype = BUS_HOST;
246+ input->dev.parent = &pdev->dev;
247+
248+ input->open = jz4740_ts_open;
249+ input->close = jz4740_ts_close;
250+
251+ input_set_drvdata(input, jz4740_ts);
252+
253+ ret = input_register_device(input);
254+ if (ret) {
255+ dev_err(&pdev->dev, "Failed to register input device: %d\n", ret);
256+ input_free_device(input);
257+ goto err_iounmap;
258+ }
259+ jz4740_ts->input = input;
260+
261+ ret = request_irq(jz4740_ts->irq_data_ready, jz4740_ts_data_ready_irq_handler, 0, pdev->name,
262+ jz4740_ts);
263+ if (ret) {
264+ dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
265+ goto err_input_unregister_device;
266+ }
267+ ret = request_irq(jz4740_ts->irq_penup, jz4740_ts_pen_irq_handler, 0, pdev->name,
268+ jz4740_ts);
269+ if (ret) {
270+ dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
271+ goto err_free_irq_data_ready;
272+ }
273+ disable_irq(jz4740_ts->irq_penup);
274+ ret = request_irq(jz4740_ts->irq_pendown, jz4740_ts_pen_irq_handler, 0, pdev->name,
275+ jz4740_ts);
276+ if (ret) {
277+ dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
278+ goto err_free_irq_penup;
279+ }
280+ platform_set_drvdata(pdev, jz4740_ts);
281+
282+ jz4740_adc_set_config(pdev->dev.parent,
283+ JZ_ADC_CONFIG_EX_IN | JZ_ADC_CONFIG_XYZ_OFFSET(2) | JZ_ADC_CONFIG_DNUM(7),
284+ JZ_ADC_CONFIG_EX_IN | JZ_ADC_CONFIG_XYZ_MASK | JZ_ADC_CONFIG_DNUM_MASK);
285+
286+
287+ writel(0x15e, jz4740_ts->base);
288+ writel(0x32, jz4740_ts->base + 0x04);
289+
290+ return 0;
291+
292+err_free_irq_penup:
293+ free_irq(jz4740_ts->irq_penup, jz4740_ts);
294+err_free_irq_data_ready:
295+ free_irq(jz4740_ts->irq_data_ready, jz4740_ts);
296+err_input_unregister_device:
297+ input_unregister_device(jz4740_ts->input);
298+err_iounmap:
299+ platform_set_drvdata(pdev, NULL);
300+ iounmap(jz4740_ts->base);
301+err_release_mem_region:
302+ release_mem_region(jz4740_ts->mem->start, resource_size(jz4740_ts->mem));
303+err_free:
304+ kfree(jz4740_ts);
305+ return ret;
306+}
307+
308+static int __devexit jz4740_ts_remove(struct platform_device *pdev)
309+{
310+ struct jz4740_ts *jz4740_ts = platform_get_drvdata(pdev);
311+
312+
313+ free_irq(jz4740_ts->irq_pendown, jz4740_ts);
314+ free_irq(jz4740_ts->irq_penup, jz4740_ts);
315+ free_irq(jz4740_ts->irq_data_ready, jz4740_ts);
316+
317+ input_unregister_device(jz4740_ts->input);
318+
319+ iounmap(jz4740_ts->base);
320+ release_mem_region(jz4740_ts->mem->start, resource_size(jz4740_ts->mem));
321+
322+ kfree(jz4740_ts);
323+
324+ return 0;
325+}
326+
327+#ifdef CONFIG_PM
328+static int jz4740_ts_suspend(struct device *dev)
329+{
330+ struct jz4740_ts *jz4740_ts = dev_get_drvdata(dev);
331+
332+ if (jz4740_ts->is_open);
333+ jz4740_ts->cell->disable(jz4740_ts->pdev);
334+
335+ return 0;
336+}
337+
338+static int jz4740_ts_resume(struct device *dev)
339+{
340+ struct jz4740_ts *jz4740_ts = dev_get_drvdata(dev);
341+
342+ if (jz4740_ts->is_open);
343+ jz4740_ts->cell->enable(jz4740_ts->pdev);
344+
345+ return 0;
346+}
347+
348+static const struct dev_pm_ops jz4740_ts_pm_ops = {
349+ .suspend = jz4740_ts_suspend,
350+ .resume = jz4740_ts_resume,
351+};
352+
353+#define JZ4740_TS_PM_OPS (&jz4740_ts_pm_ops)
354+#else
355+#define JZ4740_TS_PM_OPS NULL
356+#endif
357+
358+static struct platform_driver jz4740_ts_driver = {
359+ .probe = jz4740_ts_probe,
360+ .remove = __devexit_p(jz4740_ts_remove),
361+ .driver = {
362+ .name = "jz4740-ts",
363+ .owner = THIS_MODULE,
364+ .pm = JZ4740_TS_PM_OPS,
365+ },
366+};
367+
368+static int __init jz4740_ts_init(void)
369+{
370+ return platform_driver_register(&jz4740_ts_driver);
371+}
372+module_init(jz4740_ts_init);
373+
374+static void __exit jz4740_ts_exit(void)
375+{
376+ platform_driver_unregister(&jz4740_ts_driver);
377+}
378+module_exit(jz4740_ts_exit);
379+
380+MODULE_ALIAS("platform:jz4740-ts");
381+MODULE_LICENSE("GPL");
382+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
383+MODULE_DESCRIPTION("JZ4740 SoC battery driver");
384--
3851.7.4.1
386
target/linux/xburst/patches-3.0/0012-Add-ili8960-lcd-driver.patch
1From d7a92f8ccdca40672a2a242c756fb52c31b2bdba Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sun, 1 Aug 2010 21:19:40 +0200
4Subject: [PATCH 12/29] Add ili8960 lcd driver
5
6---
7 drivers/video/backlight/Kconfig | 7 +
8 drivers/video/backlight/Makefile | 1 +
9 drivers/video/backlight/ili8960.c | 263 +++++++++++++++++++++++++++++++++++++
10 3 files changed, 271 insertions(+), 0 deletions(-)
11 create mode 100644 drivers/video/backlight/ili8960.c
12
13diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
14index 2d93c8d..2fad528 100644
15--- a/drivers/video/backlight/Kconfig
16@@ -59,6 +59,13 @@ config LCD_LTV350QV
17
18       The LTV350QV panel is present on all ATSTK1000 boards.
19
20+config LCD_ILI8960
21+ tristate "Ilitek ili8960 LCD driver"
22+ depends on LCD_CLASS_DEVICE && SPI
23+ default n
24+ help
25+ Driver for the Ilitek ili8960 LCD controller chip.
26+
27 config LCD_ILI9320
28     tristate
29     help
30diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
31index ee72adb..c7af746 100644
32--- a/drivers/video/backlight/Makefile
33@@ -6,6 +6,7 @@ obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
34 obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
35 obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
36 obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
37+obj-$(CONFIG_LCD_ILI8960) += ili8960.o
38 obj-$(CONFIG_LCD_ILI9320) += ili9320.o
39 obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
40 obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
41diff --git a/drivers/video/backlight/ili8960.c b/drivers/video/backlight/ili8960.c
42new file mode 100644
43index 0000000..1438e92
44--- /dev/null
45@@ -0,0 +1,263 @@
46+/*
47+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
48+ * Driver for Ilitek ili8960 LCD
49+ *
50+ * This program is free software; you can redistribute it and/or modify it
51+ * under the terms of the GNU General Public License as published by the
52+ * Free Software Foundation; either version 2 of the License, or (at your
53+ * option) any later version.
54+ *
55+ * You should have received a copy of the GNU General Public License along
56+ * with this program; if not, write to the Free Software Foundation, Inc.,
57+ * 675 Mass Ave, Cambridge, MA 02139, USA.
58+ *
59+ */
60+
61+#include <linux/module.h>
62+#include <linux/spi/spi.h>
63+#include <linux/lcd.h>
64+#include <linux/backlight.h>
65+#include <linux/delay.h>
66+
67+struct ili8960 {
68+ struct spi_device *spi;
69+ struct lcd_device *lcd;
70+ struct backlight_device *bl;
71+ bool enabled;
72+ unsigned int brightness;
73+};
74+
75+#define ILI8960_REG_BRIGHTNESS 0x03
76+#define ILI8960_REG_POWER 0x05
77+#define ILI8960_REG_CONTRAST 0x0d
78+
79+static int ili8960_write_reg(struct spi_device *spi, uint8_t reg,
80+ uint8_t data)
81+{
82+ uint8_t buf[2];
83+ buf[0] = ((reg & 0x40) << 1) | (reg & 0x3f);
84+ buf[1] = data;
85+
86+ return spi_write(spi, buf, sizeof(buf));
87+}
88+
89+static int ili8960_programm_power(struct spi_device *spi, bool enabled)
90+{
91+ int ret;
92+
93+ if (enabled)
94+ mdelay(20);
95+
96+ ret = ili8960_write_reg(spi, ILI8960_REG_POWER, enabled ? 0xc7 : 0xc6);
97+
98+ if (!enabled)
99+ mdelay(20);
100+
101+ return ret;
102+}
103+
104+static int ili8960_set_power(struct lcd_device *lcd, int power)
105+{
106+ struct ili8960 *ili8960 = lcd_get_data(lcd);
107+
108+ switch (power) {
109+ case FB_BLANK_UNBLANK:
110+ ili8960->enabled = true;
111+ break;
112+ default:
113+ ili8960->enabled = false;
114+ break;
115+ }
116+
117+ return ili8960_programm_power(ili8960->spi, ili8960->enabled);
118+}
119+
120+static int ili8960_get_power(struct lcd_device *lcd)
121+{
122+ struct ili8960 *ili8960 = lcd_get_data(lcd);
123+ return ili8960->enabled ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
124+}
125+
126+static int ili8960_set_contrast(struct lcd_device *lcd, int contrast)
127+{
128+ struct ili8960 *ili8960 = lcd_get_data(lcd);
129+
130+ return ili8960_write_reg(ili8960->spi, ILI8960_REG_CONTRAST, contrast);
131+}
132+
133+static int ili8960_set_mode(struct lcd_device *lcd, struct fb_videomode *mode)
134+{
135+ if (mode->xres != 320 && mode->yres != 240)
136+ return -EINVAL;
137+
138+ return 0;
139+}
140+
141+static int ili8960_set_brightness(struct ili8960 *ili8960, int brightness)
142+{
143+ int ret;
144+
145+ ret = ili8960_write_reg(ili8960->spi, ILI8960_REG_BRIGHTNESS, brightness);
146+
147+ if (ret == 0)
148+ ili8960->brightness = brightness;
149+
150+ return ret;
151+}
152+
153+static ssize_t ili8960_show_brightness(struct device *dev,
154+ struct device_attribute *attr, char *buf)
155+{
156+ struct lcd_device *ld = to_lcd_device(dev);
157+ struct ili8960 *ili8960 = lcd_get_data(ld);
158+
159+ return sprintf(buf, "%u\n", ili8960->brightness);
160+}
161+
162+static ssize_t ili8960_store_brightness(struct device *dev,
163+ struct device_attribute *attr, const char *buf, size_t count)
164+{
165+ struct lcd_device *ld = to_lcd_device(dev);
166+ struct ili8960 *ili8960 = lcd_get_data(ld);
167+ unsigned long brightness;
168+ int ret;
169+
170+ ret = strict_strtoul(buf, 0, &brightness);
171+ if (ret)
172+ return ret;
173+
174+ if (brightness > 255)
175+ return -EINVAL;
176+
177+ ili8960_set_brightness(ili8960, brightness);
178+
179+ return count;
180+}
181+
182+
183+static DEVICE_ATTR(brightness, 0644, ili8960_show_brightness,
184+ ili8960_store_brightness);
185+
186+static struct lcd_ops ili8960_lcd_ops = {
187+ .set_power = ili8960_set_power,
188+ .get_power = ili8960_get_power,
189+ .set_contrast = ili8960_set_contrast,
190+ .set_mode = ili8960_set_mode,
191+};
192+
193+static int __devinit ili8960_probe(struct spi_device *spi)
194+{
195+ int ret;
196+ struct ili8960 *ili8960;
197+
198+ ili8960 = kmalloc(sizeof(*ili8960), GFP_KERNEL);
199+ if (!ili8960)
200+ return -ENOMEM;
201+
202+ spi->bits_per_word = 8;
203+ spi->mode = SPI_MODE_3;
204+
205+ ret = spi_setup(spi);
206+ if (ret) {
207+ dev_err(&spi->dev, "Failed to setup spi\n");
208+ goto err_free_ili8960;
209+ }
210+
211+ ili8960->spi = spi;
212+
213+ ili8960->lcd = lcd_device_register("ili8960-lcd", &spi->dev, ili8960,
214+ &ili8960_lcd_ops);
215+
216+ if (IS_ERR(ili8960->lcd)) {
217+ ret = PTR_ERR(ili8960->lcd);
218+ dev_err(&spi->dev, "Failed to register lcd device: %d\n", ret);
219+ goto err_free_ili8960;
220+ }
221+
222+ ili8960->lcd->props.max_contrast = 255;
223+
224+ ret = device_create_file(&ili8960->lcd->dev, &dev_attr_brightness);
225+ if (ret)
226+ goto err_unregister_lcd;
227+
228+ ili8960_programm_power(ili8960->spi, true);
229+ ili8960->enabled = true;
230+
231+ spi_set_drvdata(spi, ili8960);
232+
233+ ili8960_write_reg(spi, 0x13, 0x01);
234+
235+ return 0;
236+err_unregister_lcd:
237+ lcd_device_unregister(ili8960->lcd);
238+err_free_ili8960:
239+ kfree(ili8960);
240+ return ret;
241+}
242+
243+static int __devexit ili8960_remove(struct spi_device *spi)
244+{
245+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
246+
247+ device_remove_file(&ili8960->lcd->dev, &dev_attr_brightness);
248+ lcd_device_unregister(ili8960->lcd);
249+
250+ spi_set_drvdata(spi, NULL);
251+ kfree(ili8960);
252+ return 0;
253+}
254+
255+#ifdef CONFIG_PM
256+
257+static int ili8960_suspend(struct spi_device *spi, pm_message_t state)
258+{
259+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
260+
261+ if (ili8960->enabled)
262+ ili8960_programm_power(ili8960->spi, false);
263+
264+ return 0;
265+}
266+
267+static int ili8960_resume(struct spi_device *spi)
268+{
269+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
270+
271+ if (ili8960->enabled)
272+ ili8960_programm_power(ili8960->spi, true);
273+
274+ return 0;
275+}
276+
277+#else
278+#define ili8960_suspend NULL
279+#define ili8960_resume NULL
280+#endif
281+
282+static struct spi_driver ili8960_driver = {
283+ .driver = {
284+ .name = "ili8960",
285+ .owner = THIS_MODULE,
286+ },
287+ .probe = ili8960_probe,
288+ .remove = __devexit_p(ili8960_remove),
289+ .suspend = ili8960_suspend,
290+ .resume = ili8960_resume,
291+};
292+
293+static int __init ili8960_init(void)
294+{
295+ return spi_register_driver(&ili8960_driver);
296+}
297+module_init(ili8960_init);
298+
299+static void __exit ili8960_exit(void)
300+{
301+ spi_unregister_driver(&ili8960_driver);
302+}
303+module_exit(ili8960_exit)
304+
305+MODULE_AUTHOR("Lars-Peter Clausen");
306+MODULE_LICENSE("GPL");
307+MODULE_DESCRIPTION("LCD driver for Ilitek ili8960");
308+MODULE_ALIAS("spi:ili8960");
309--
3101.7.4.1
311
target/linux/xburst/patches-3.0/0013-Add-jz4740-udc-driver.patch
1From ecd72bc68f9b9a39cb0f1ec456787c61f03be978 Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
3Date: Tue, 13 Sep 2011 16:07:41 +0800
4Subject: [PATCH 13/29] Add jz4740 udc driver
5
6---
7 drivers/usb/gadget/Kconfig | 13 +
8 drivers/usb/gadget/Makefile | 1 +
9 drivers/usb/gadget/gadget_chips.h | 8 +
10 drivers/usb/gadget/jz4740_udc.c | 2188 +++++++++++++++++++++++++++++++++++++
11 drivers/usb/gadget/jz4740_udc.h | 101 ++
12 5 files changed, 2311 insertions(+), 0 deletions(-)
13 create mode 100644 drivers/usb/gadget/jz4740_udc.c
14 create mode 100644 drivers/usb/gadget/jz4740_udc.h
15
16diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
17index 029e288..750480c 100644
18--- a/drivers/usb/gadget/Kconfig
19@@ -121,6 +121,19 @@ choice
20 #
21 # Integrated controllers
22 #
23+config USB_GADGET_JZ4740
24+ boolean "JZ4740 UDC"
25+ depends on MACH_JZ4740
26+ select USB_GADGET_SELECTED
27+ select USB_GADGET_DUALSPEED
28+ help
29+ Select this to support the Ingenic JZ4740 processor
30+ high speed USB device controller.
31+
32+config USB_JZ4740
33+ tristate
34+ depends on USB_GADGET_JZ4740
35+ default USB_GADGET
36
37 config USB_GADGET_AT91
38     boolean "Atmel AT91 USB Device Port"
39diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
40index 4fe92b1..e0e2dd8 100644
41--- a/drivers/usb/gadget/Makefile
42@@ -29,6 +29,7 @@ obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o
43 mv_udc-y := mv_udc_core.o mv_udc_phy.o
44 obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o
45 obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o
46+obj-$(CONFIG_USB_JZ4740) += jz4740_udc.o
47
48 #
49 # USB gadget drivers
50diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
51index bcdac7c..12f5205 100644
52--- a/drivers/usb/gadget/gadget_chips.h
53@@ -15,6 +15,12 @@
54 #ifndef __GADGET_CHIPS_H
55 #define __GADGET_CHIPS_H
56
57+#ifdef CONFIG_USB_GADGET_JZ4740
58+#define gadget_is_jz4740(g) !strcmp("ingenic_hsusb", (g)->name)
59+#else
60+#define gadget_is_jz4740(g) 0
61+#endif
62+
63 #ifdef CONFIG_USB_GADGET_NET2280
64 #define gadget_is_net2280(g) !strcmp("net2280", (g)->name)
65 #else
66@@ -223,6 +229,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
67         return 0x29;
68     else if (gadget_is_s3c_hsudc(gadget))
69         return 0x30;
70+ else if (gadget_is_jz4740(gadget))
71+ return 0x31;
72
73     return -ENOENT;
74 }
75diff --git a/drivers/usb/gadget/jz4740_udc.c b/drivers/usb/gadget/jz4740_udc.c
76new file mode 100644
77index 0000000..528fd57
78--- /dev/null
79@@ -0,0 +1,2188 @@
80+/*
81+ * linux/drivers/usb/gadget/jz4740_udc.c
82+ *
83+ * Ingenic JZ4740 on-chip high speed USB device controller
84+ *
85+ * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc.
86+ * Author: <jlwei@ingenic.cn>
87+ *
88+ * This program is free software; you can redistribute it and/or modify
89+ * it under the terms of the GNU General Public License as published by
90+ * the Free Software Foundation; either version 2 of the License, or
91+ * (at your option) any later version.
92+ */
93+
94+/*
95+ * This device has ep0, two bulk-in/interrupt-in endpoints, and one bulk-out endpoint.
96+ *
97+ * - Endpoint numbering is fixed: ep0, ep1in-int, ep2in-bulk, ep1out-bulk.
98+ * - DMA works with bulk-in (channel 1) and bulk-out (channel 2) endpoints.
99+ */
100+
101+#include <linux/kernel.h>
102+#include <linux/module.h>
103+#include <linux/platform_device.h>
104+#include <linux/delay.h>
105+#include <linux/ioport.h>
106+#include <linux/slab.h>
107+#include <linux/errno.h>
108+#include <linux/init.h>
109+#include <linux/list.h>
110+#include <linux/interrupt.h>
111+#include <linux/proc_fs.h>
112+#include <linux/usb.h>
113+#include <linux/usb/gadget.h>
114+#include <linux/clk.h>
115+
116+#include <asm/byteorder.h>
117+#include <asm/io.h>
118+#include <asm/irq.h>
119+#include <asm/system.h>
120+#include <asm/mach-jz4740/clock.h>
121+
122+#include "jz4740_udc.h"
123+
124+#define JZ_REG_UDC_FADDR 0x00 /* Function Address 8-bit */
125+#define JZ_REG_UDC_POWER 0x01 /* Power Management 8-bit */
126+#define JZ_REG_UDC_INTRIN 0x02 /* Interrupt IN 16-bit */
127+#define JZ_REG_UDC_INTROUT 0x04 /* Interrupt OUT 16-bit */
128+#define JZ_REG_UDC_INTRINE 0x06 /* Intr IN enable 16-bit */
129+#define JZ_REG_UDC_INTROUTE 0x08 /* Intr OUT enable 16-bit */
130+#define JZ_REG_UDC_INTRUSB 0x0a /* Interrupt USB 8-bit */
131+#define JZ_REG_UDC_INTRUSBE 0x0b /* Interrupt USB Enable 8-bit */
132+#define JZ_REG_UDC_FRAME 0x0c /* Frame number 16-bit */
133+#define JZ_REG_UDC_INDEX 0x0e /* Index register 8-bit */
134+#define JZ_REG_UDC_TESTMODE 0x0f /* USB test mode 8-bit */
135+
136+#define JZ_REG_UDC_CSR0 0x12 /* EP0 CSR 8-bit */
137+#define JZ_REG_UDC_INMAXP 0x10 /* EP1-2 IN Max Pkt Size 16-bit */
138+#define JZ_REG_UDC_INCSR 0x12 /* EP1-2 IN CSR LSB 8/16bit */
139+#define JZ_REG_UDC_INCSRH 0x13 /* EP1-2 IN CSR MSB 8-bit */
140+
141+#define JZ_REG_UDC_OUTMAXP 0x14 /* EP1 OUT Max Pkt Size 16-bit */
142+#define JZ_REG_UDC_OUTCSR 0x16 /* EP1 OUT CSR LSB 8/16bit */
143+#define JZ_REG_UDC_OUTCSRH 0x17 /* EP1 OUT CSR MSB 8-bit */
144+#define JZ_REG_UDC_OUTCOUNT 0x18 /* bytes in EP0/1 OUT FIFO 16-bit */
145+
146+#define JZ_REG_UDC_EP_FIFO(x) (4 * (x) + 0x20)
147+
148+#define JZ_REG_UDC_EPINFO 0x78 /* Endpoint information */
149+#define JZ_REG_UDC_RAMINFO 0x79 /* RAM information */
150+
151+#define JZ_REG_UDC_INTR 0x200 /* DMA pending interrupts */
152+#define JZ_REG_UDC_CNTL1 0x204 /* DMA channel 1 control */
153+#define JZ_REG_UDC_ADDR1 0x208 /* DMA channel 1 AHB memory addr */
154+#define JZ_REG_UDC_COUNT1 0x20c /* DMA channel 1 byte count */
155+#define JZ_REG_UDC_CNTL2 0x214 /* DMA channel 2 control */
156+#define JZ_REG_UDC_ADDR2 0x218 /* DMA channel 2 AHB memory addr */
157+#define JZ_REG_UDC_COUNT2 0x21c /* DMA channel 2 byte count */
158+
159+/* Power register bit masks */
160+#define USB_POWER_SUSPENDM 0x01
161+#define USB_POWER_RESUME 0x04
162+#define USB_POWER_HSMODE 0x10
163+#define USB_POWER_HSENAB 0x20
164+#define USB_POWER_SOFTCONN 0x40
165+
166+/* Interrupt register bit masks */
167+#define USB_INTR_SUSPEND 0x01
168+#define USB_INTR_RESUME 0x02
169+#define USB_INTR_RESET 0x04
170+
171+#define USB_INTR_EP0 0x0001
172+#define USB_INTR_INEP1 0x0002
173+#define USB_INTR_INEP2 0x0004
174+#define USB_INTR_OUTEP1 0x0002
175+
176+/* CSR0 bit masks */
177+#define USB_CSR0_OUTPKTRDY 0x01
178+#define USB_CSR0_INPKTRDY 0x02
179+#define USB_CSR0_SENTSTALL 0x04
180+#define USB_CSR0_DATAEND 0x08
181+#define USB_CSR0_SETUPEND 0x10
182+#define USB_CSR0_SENDSTALL 0x20
183+#define USB_CSR0_SVDOUTPKTRDY 0x40
184+#define USB_CSR0_SVDSETUPEND 0x80
185+
186+/* Endpoint CSR register bits */
187+#define USB_INCSRH_AUTOSET 0x80
188+#define USB_INCSRH_ISO 0x40
189+#define USB_INCSRH_MODE 0x20
190+#define USB_INCSRH_DMAREQENAB 0x10
191+#define USB_INCSRH_DMAREQMODE 0x04
192+#define USB_INCSR_CDT 0x40
193+#define USB_INCSR_SENTSTALL 0x20
194+#define USB_INCSR_SENDSTALL 0x10
195+#define USB_INCSR_FF 0x08
196+#define USB_INCSR_UNDERRUN 0x04
197+#define USB_INCSR_FFNOTEMPT 0x02
198+#define USB_INCSR_INPKTRDY 0x01
199+
200+#define USB_OUTCSRH_AUTOCLR 0x80
201+#define USB_OUTCSRH_ISO 0x40
202+#define USB_OUTCSRH_DMAREQENAB 0x20
203+#define USB_OUTCSRH_DNYT 0x10
204+#define USB_OUTCSRH_DMAREQMODE 0x08
205+#define USB_OUTCSR_CDT 0x80
206+#define USB_OUTCSR_SENTSTALL 0x40
207+#define USB_OUTCSR_SENDSTALL 0x20
208+#define USB_OUTCSR_FF 0x10
209+#define USB_OUTCSR_DATAERR 0x08
210+#define USB_OUTCSR_OVERRUN 0x04
211+#define USB_OUTCSR_FFFULL 0x02
212+#define USB_OUTCSR_OUTPKTRDY 0x01
213+
214+/* DMA control bits */
215+#define USB_CNTL_ENA 0x01
216+#define USB_CNTL_DIR_IN 0x02
217+#define USB_CNTL_MODE_1 0x04
218+#define USB_CNTL_INTR_EN 0x08
219+#define USB_CNTL_EP(n) ((n) << 4)
220+#define USB_CNTL_BURST_0 (0 << 9)
221+#define USB_CNTL_BURST_4 (1 << 9)
222+#define USB_CNTL_BURST_8 (2 << 9)
223+#define USB_CNTL_BURST_16 (3 << 9)
224+
225+
226+#ifndef DEBUG
227+# define DEBUG(fmt,args...) do {} while(0)
228+#endif
229+#ifndef DEBUG_EP0
230+# define NO_STATES
231+# define DEBUG_EP0(fmt,args...) do {} while(0)
232+#endif
233+#ifndef DEBUG_SETUP
234+# define DEBUG_SETUP(fmt,args...) do {} while(0)
235+#endif
236+
237+static struct jz4740_udc jz4740_udc_controller;
238+
239+/*
240+ * Local declarations.
241+ */
242+static void jz4740_ep0_kick(struct jz4740_udc *dev, struct jz4740_ep *ep);
243+static void jz4740_handle_ep0(struct jz4740_udc *dev, uint32_t intr);
244+
245+static void done(struct jz4740_ep *ep, struct jz4740_request *req,
246+ int status);
247+static void pio_irq_enable(struct jz4740_ep *ep);
248+static void pio_irq_disable(struct jz4740_ep *ep);
249+static void stop_activity(struct jz4740_udc *dev,
250+ struct usb_gadget_driver *driver);
251+static void nuke(struct jz4740_ep *ep, int status);
252+static void flush(struct jz4740_ep *ep);
253+static void udc_set_address(struct jz4740_udc *dev, unsigned char address);
254+
255+/*-------------------------------------------------------------------------*/
256+
257+/* inline functions of register read/write/set/clear */
258+
259+static inline uint8_t usb_readb(struct jz4740_udc *udc, size_t reg)
260+{
261+ return readb(udc->base + reg);
262+}
263+
264+static inline uint16_t usb_readw(struct jz4740_udc *udc, size_t reg)
265+{
266+ return readw(udc->base + reg);
267+}
268+
269+static inline uint32_t usb_readl(struct jz4740_udc *udc, size_t reg)
270+{
271+ return readl(udc->base + reg);
272+}
273+
274+static inline void usb_writeb(struct jz4740_udc *udc, size_t reg, uint8_t val)
275+{
276+ writeb(val, udc->base + reg);
277+}
278+
279+static inline void usb_writew(struct jz4740_udc *udc, size_t reg, uint16_t val)
280+{
281+ writew(val, udc->base + reg);
282+}
283+
284+static inline void usb_writel(struct jz4740_udc *udc, size_t reg, uint32_t val)
285+{
286+ writel(val, udc->base + reg);
287+}
288+
289+static inline void usb_setb(struct jz4740_udc *udc, size_t reg, uint8_t mask)
290+{
291+ usb_writeb(udc, reg, usb_readb(udc, reg) | mask);
292+}
293+
294+static inline void usb_setw(struct jz4740_udc *udc, size_t reg, uint16_t mask)
295+{
296+ usb_writew(udc, reg, usb_readw(udc, reg) | mask);
297+}
298+
299+static inline void usb_clearb(struct jz4740_udc *udc, size_t reg, uint8_t mask)
300+{
301+ usb_writeb(udc, reg, usb_readb(udc, reg) & ~mask);
302+}
303+
304+static inline void usb_clearw(struct jz4740_udc *udc, size_t reg, uint16_t mask)
305+{
306+ usb_writew(udc, reg, usb_readw(udc, reg) & ~mask);
307+}
308+
309+/*-------------------------------------------------------------------------*/
310+
311+static inline void jz_udc_set_index(struct jz4740_udc *udc, uint8_t index)
312+{
313+ usb_writeb(udc, JZ_REG_UDC_INDEX, index);
314+}
315+
316+static inline void jz_udc_select_ep(struct jz4740_ep *ep)
317+{
318+ jz_udc_set_index(ep->dev, ep_index(ep));
319+}
320+
321+static inline int write_packet(struct jz4740_ep *ep,
322+ struct jz4740_request *req, unsigned int count)
323+{
324+ uint8_t *buf;
325+ unsigned int length;
326+ void __iomem *fifo = ep->dev->base + ep->fifo;
327+
328+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
329+
330+ buf = req->req.buf + req->req.actual;
331+
332+ length = req->req.length - req->req.actual;
333+ if (length > count)
334+ length = count;
335+ req->req.actual += length;
336+
337+ DEBUG("Write %d (count %d), fifo %x\n", length, count, ep->fifo);
338+
339+ writesl(fifo, buf, length >> 2);
340+ writesb(fifo, &buf[length - (length & 3)], length & 3);
341+
342+ return length;
343+}
344+
345+static int read_packet(struct jz4740_ep *ep,
346+ struct jz4740_request *req, unsigned int count)
347+{
348+ uint8_t *buf;
349+ unsigned int length;
350+ void __iomem *fifo = ep->dev->base + ep->fifo;
351+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
352+
353+ buf = req->req.buf + req->req.actual;
354+
355+ length = req->req.length - req->req.actual;
356+ if (length > count)
357+ length = count;
358+ req->req.actual += length;
359+
360+ DEBUG("Read %d, fifo %x\n", length, ep->fifo);
361+
362+ readsl(fifo, buf, length >> 2);
363+ readsb(fifo, &buf[length - (length & 3)], length & 3);
364+
365+ return length;
366+}
367+
368+/*-------------------------------------------------------------------------*/
369+
370+/*
371+ * udc_disable - disable USB device controller
372+ */
373+static void udc_disable(struct jz4740_udc *dev)
374+{
375+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
376+
377+ udc_set_address(dev, 0);
378+
379+ /* Disable interrupts */
380+ usb_writew(dev, JZ_REG_UDC_INTRINE, 0);
381+ usb_writew(dev, JZ_REG_UDC_INTROUTE, 0);
382+ usb_writeb(dev, JZ_REG_UDC_INTRUSBE, 0);
383+
384+ /* Disable DMA */
385+ usb_writel(dev, JZ_REG_UDC_CNTL1, 0);
386+ usb_writel(dev, JZ_REG_UDC_CNTL2, 0);
387+
388+ /* Disconnect from usb */
389+ usb_clearb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN);
390+
391+ /* Disable the USB PHY */
392+ clk_disable(dev->clk);
393+
394+ dev->ep0state = WAIT_FOR_SETUP;
395+ dev->gadget.speed = USB_SPEED_UNKNOWN;
396+
397+ return;
398+}
399+
400+/*
401+ * udc_reinit - initialize software state
402+ */
403+static void udc_reinit(struct jz4740_udc *dev)
404+{
405+ int i;
406+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
407+
408+ /* device/ep0 records init */
409+ INIT_LIST_HEAD(&dev->gadget.ep_list);
410+ INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
411+ dev->ep0state = WAIT_FOR_SETUP;
412+
413+ for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
414+ struct jz4740_ep *ep = &dev->ep[i];
415+
416+ if (i != 0)
417+ list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
418+
419+ INIT_LIST_HEAD(&ep->queue);
420+ ep->desc = 0;
421+ ep->stopped = 0;
422+ }
423+}
424+
425+/* until it's enabled, this UDC should be completely invisible
426+ * to any USB host.
427+ */
428+static void udc_enable(struct jz4740_udc *dev)
429+{
430+ int i;
431+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
432+
433+ /* UDC state is incorrect - Added by River */
434+ if (dev->state != UDC_STATE_ENABLE) {
435+ return;
436+ }
437+
438+ dev->gadget.speed = USB_SPEED_UNKNOWN;
439+
440+ /* Flush FIFO for each */
441+ for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
442+ struct jz4740_ep *ep = &dev->ep[i];
443+
444+ jz_udc_select_ep(ep);
445+ flush(ep);
446+ }
447+
448+ /* Set this bit to allow the UDC entering low-power mode when
449+ * there are no actions on the USB bus.
450+ * UDC still works during this bit was set.
451+ */
452+ jz4740_clock_udc_enable_auto_suspend();
453+
454+ /* Enable the USB PHY */
455+ clk_enable(dev->clk);
456+
457+ /* Disable interrupts */
458+/* usb_writew(dev, JZ_REG_UDC_INTRINE, 0);
459+ usb_writew(dev, JZ_REG_UDC_INTROUTE, 0);
460+ usb_writeb(dev, JZ_REG_UDC_INTRUSBE, 0);*/
461+
462+ /* Enable interrupts */
463+ usb_setw(dev, JZ_REG_UDC_INTRINE, USB_INTR_EP0);
464+ usb_setb(dev, JZ_REG_UDC_INTRUSBE, USB_INTR_RESET);
465+ /* Don't enable rest of the interrupts */
466+ /* usb_setw(dev, JZ_REG_UDC_INTRINE, USB_INTR_INEP1 | USB_INTR_INEP2);
467+ usb_setw(dev, JZ_REG_UDC_INTROUTE, USB_INTR_OUTEP1); */
468+
469+ /* Enable SUSPEND */
470+ /* usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_SUSPENDM); */
471+
472+ /* Enable HS Mode */
473+ usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_HSENAB);
474+
475+ /* Let host detect UDC:
476+ * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this
477+ * transistor on and pull the USBDP pin HIGH.
478+ */
479+ usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN);
480+
481+ return;
482+}
483+
484+/*-------------------------------------------------------------------------*/
485+
486+/* keeping it simple:
487+ * - one bus driver, initted first;
488+ * - one function driver, initted second
489+ */
490+
491+/*
492+ * Register entry point for the peripheral controller driver.
493+ */
494+
495+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
496+ int (*bind)(struct usb_gadget *))
497+{
498+ struct jz4740_udc *dev = &jz4740_udc_controller;
499+ int retval;
500+
501+ if (!driver || !bind)
502+ return -EINVAL;
503+
504+ if (!dev)
505+ return -ENODEV;
506+
507+ if (dev->driver)
508+ return -EBUSY;
509+
510+ /* hook up the driver */
511+ dev->driver = driver;
512+ dev->gadget.dev.driver = &driver->driver;
513+
514+ retval = bind(&dev->gadget);
515+ if (retval) {
516+ DEBUG("%s: bind to driver %s --> error %d\n", dev->gadget.name,
517+ driver->driver.name, retval);
518+ dev->driver = 0;
519+ return retval;
520+ }
521+
522+ /* then enable host detection and ep0; and we're ready
523+ * for set_configuration as well as eventual disconnect.
524+ */
525+ udc_enable(dev);
526+
527+ DEBUG("%s: registered gadget driver '%s'\n", dev->gadget.name,
528+ driver->driver.name);
529+
530+ return 0;
531+}
532+EXPORT_SYMBOL(usb_gadget_probe_driver);
533+
534+static void stop_activity(struct jz4740_udc *dev,
535+ struct usb_gadget_driver *driver)
536+{
537+ int i;
538+
539+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
540+
541+ /* don't disconnect drivers more than once */
542+ if (dev->gadget.speed == USB_SPEED_UNKNOWN)
543+ driver = 0;
544+ dev->gadget.speed = USB_SPEED_UNKNOWN;
545+
546+ /* prevent new request submissions, kill any outstanding requests */
547+ for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
548+ struct jz4740_ep *ep = &dev->ep[i];
549+
550+ ep->stopped = 1;
551+
552+ jz_udc_select_ep(ep);
553+ nuke(ep, -ESHUTDOWN);
554+ }
555+
556+ /* report disconnect; the driver is already quiesced */
557+ if (driver) {
558+ spin_unlock(&dev->lock);
559+ driver->disconnect(&dev->gadget);
560+ spin_lock(&dev->lock);
561+ }
562+
563+ /* re-init driver-visible data structures */
564+ udc_reinit(dev);
565+}
566+
567+
568+/*
569+ * Unregister entry point for the peripheral controller driver.
570+ */
571+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
572+{
573+ struct jz4740_udc *dev = &jz4740_udc_controller;
574+ unsigned long flags;
575+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
576+
577+ if (!dev)
578+ return -ENODEV;
579+ if (!driver || driver != dev->driver)
580+ return -EINVAL;
581+ if (!driver->unbind)
582+ return -EBUSY;
583+
584+ spin_lock_irqsave(&dev->lock, flags);
585+ dev->driver = 0;
586+ stop_activity(dev, driver);
587+ spin_unlock_irqrestore(&dev->lock, flags);
588+
589+ driver->unbind(&dev->gadget);
590+
591+ udc_disable(dev);
592+
593+ DEBUG("unregistered driver '%s'\n", driver->driver.name);
594+
595+ return 0;
596+}
597+
598+EXPORT_SYMBOL(usb_gadget_unregister_driver);
599+
600+/*-------------------------------------------------------------------------*/
601+
602+/** Write request to FIFO (max write == maxp size)
603+ * Return: 0 = still running, 1 = completed, negative = errno
604+ * NOTE: INDEX register must be set for EP
605+ */
606+static int write_fifo(struct jz4740_ep *ep, struct jz4740_request *req)
607+{
608+ struct jz4740_udc *dev = ep->dev;
609+ uint32_t max, csr;
610+
611+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
612+ max = le16_to_cpu(ep->desc->wMaxPacketSize);
613+
614+ csr = usb_readb(dev, ep->csr);
615+
616+ if (!(csr & USB_INCSR_FFNOTEMPT)) {
617+ unsigned count;
618+ int is_last, is_short;
619+
620+ count = write_packet(ep, req, max);
621+ usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY);
622+
623+ /* last packet is usually short (or a zlp) */
624+ if (unlikely(count != max))
625+ is_last = is_short = 1;
626+ else {
627+ if (likely(req->req.length != req->req.actual)
628+ || req->req.zero)
629+ is_last = 0;
630+ else
631+ is_last = 1;
632+ /* interrupt/iso maxpacket may not fill the fifo */
633+ is_short = unlikely(max < ep_maxpacket(ep));
634+ }
635+
636+ DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__,
637+ ep->ep.name, count,
638+ is_last ? "/L" : "", is_short ? "/S" : "",
639+ req->req.length - req->req.actual, req);
640+
641+ /* requests complete when all IN data is in the FIFO */
642+ if (is_last) {
643+ done(ep, req, 0);
644+ if (list_empty(&ep->queue)) {
645+ pio_irq_disable(ep);
646+ }
647+ return 1;
648+ }
649+ } else {
650+ DEBUG("Hmm.. %d ep FIFO is not empty!\n", ep_index(ep));
651+ }
652+
653+ return 0;
654+}
655+
656+/** Read to request from FIFO (max read == bytes in fifo)
657+ * Return: 0 = still running, 1 = completed, negative = errno
658+ * NOTE: INDEX register must be set for EP
659+ */
660+static int read_fifo(struct jz4740_ep *ep, struct jz4740_request *req)
661+{
662+ struct jz4740_udc *dev = ep->dev;
663+ uint32_t csr;
664+ unsigned count, is_short;
665+
666+ /* make sure there's a packet in the FIFO. */
667+ csr = usb_readb(dev, ep->csr);
668+ if (!(csr & USB_OUTCSR_OUTPKTRDY)) {
669+ DEBUG("%s: Packet NOT ready!\n", __FUNCTION__);
670+ return -EINVAL;
671+ }
672+
673+ /* read all bytes from this packet */
674+ count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT);
675+
676+ is_short = (count < ep->ep.maxpacket);
677+
678+ count = read_packet(ep, req, count);
679+
680+ DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n",
681+ ep->ep.name, csr, count,
682+ is_short ? "/S" : "", req, req->req.actual, req->req.length);
683+
684+ /* Clear OutPktRdy */
685+ usb_clearb(dev, ep->csr, USB_OUTCSR_OUTPKTRDY);
686+
687+ /* completion */
688+ if (is_short || req->req.actual == req->req.length) {
689+ done(ep, req, 0);
690+
691+ if (list_empty(&ep->queue))
692+ pio_irq_disable(ep);
693+ return 1;
694+ }
695+
696+ /* finished that packet. the next one may be waiting... */
697+ return 0;
698+}
699+
700+/*
701+ * done - retire a request; caller blocked irqs
702+ * INDEX register is preserved to keep same
703+ */
704+static void done(struct jz4740_ep *ep, struct jz4740_request *req, int status)
705+{
706+ unsigned int stopped = ep->stopped;
707+ uint32_t index;
708+
709+ DEBUG("%s, %p\n", __FUNCTION__, ep);
710+ list_del_init(&req->queue);
711+
712+ if (likely(req->req.status == -EINPROGRESS))
713+ req->req.status = status;
714+ else
715+ status = req->req.status;
716+
717+ if (status && status != -ESHUTDOWN)
718+ DEBUG("complete %s req %p stat %d len %u/%u\n",
719+ ep->ep.name, &req->req, status,
720+ req->req.actual, req->req.length);
721+
722+ /* don't modify queue heads during completion callback */
723+ ep->stopped = 1;
724+ /* Read current index (completion may modify it) */
725+ index = usb_readb(ep->dev, JZ_REG_UDC_INDEX);
726+ spin_unlock_irqrestore(&ep->dev->lock, ep->dev->lock_flags);
727+
728+ req->req.complete(&ep->ep, &req->req);
729+
730+ spin_lock_irqsave(&ep->dev->lock, ep->dev->lock_flags);
731+ /* Restore index */
732+ jz_udc_set_index(ep->dev, index);
733+ ep->stopped = stopped;
734+}
735+
736+static inline unsigned int jz4740_udc_ep_irq_enable_reg(struct jz4740_ep *ep)
737+{
738+ if (ep_is_in(ep))
739+ return JZ_REG_UDC_INTRINE;
740+ else
741+ return JZ_REG_UDC_INTROUTE;
742+}
743+
744+/** Enable EP interrupt */
745+static void pio_irq_enable(struct jz4740_ep *ep)
746+{
747+ DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT");
748+
749+ usb_setw(ep->dev, jz4740_udc_ep_irq_enable_reg(ep), BIT(ep_index(ep)));
750+}
751+
752+/** Disable EP interrupt */
753+static void pio_irq_disable(struct jz4740_ep *ep)
754+{
755+ DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT");
756+
757+ usb_clearw(ep->dev, jz4740_udc_ep_irq_enable_reg(ep), BIT(ep_index(ep)));
758+}
759+
760+/*
761+ * nuke - dequeue ALL requests
762+ */
763+static void nuke(struct jz4740_ep *ep, int status)
764+{
765+ struct jz4740_request *req;
766+
767+ DEBUG("%s, %p\n", __FUNCTION__, ep);
768+
769+ /* Flush FIFO */
770+ flush(ep);
771+
772+ /* called with irqs blocked */
773+ while (!list_empty(&ep->queue)) {
774+ req = list_entry(ep->queue.next, struct jz4740_request, queue);
775+ done(ep, req, status);
776+ }
777+
778+ /* Disable IRQ if EP is enabled (has descriptor) */
779+ if (ep->desc)
780+ pio_irq_disable(ep);
781+}
782+
783+/** Flush EP FIFO
784+ * NOTE: INDEX register must be set before this call
785+ */
786+static void flush(struct jz4740_ep *ep)
787+{
788+ DEBUG("%s: %s\n", __FUNCTION__, ep->ep.name);
789+
790+ switch (ep->type) {
791+ case ep_bulk_in:
792+ case ep_interrupt:
793+ usb_setb(ep->dev, ep->csr, USB_INCSR_FF);
794+ break;
795+ case ep_bulk_out:
796+ usb_setb(ep->dev, ep->csr, USB_OUTCSR_FF);
797+ break;
798+ case ep_control:
799+ break;
800+ }
801+}
802+
803+/**
804+ * jz4740_in_epn - handle IN interrupt
805+ */
806+static void jz4740_in_epn(struct jz4740_udc *dev, uint32_t ep_idx, uint32_t intr)
807+{
808+ uint32_t csr;
809+ struct jz4740_ep *ep = &dev->ep[ep_idx + 1];
810+ struct jz4740_request *req;
811+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
812+
813+ jz_udc_select_ep(ep);
814+
815+ csr = usb_readb(dev, ep->csr);
816+ DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr);
817+
818+ if (csr & USB_INCSR_SENTSTALL) {
819+ DEBUG("USB_INCSR_SENTSTALL\n");
820+ usb_clearb(dev, ep->csr, USB_INCSR_SENTSTALL);
821+ return;
822+ }
823+
824+ if (!ep->desc) {
825+ DEBUG("%s: NO EP DESC\n", __FUNCTION__);
826+ return;
827+ }
828+
829+ if (!list_empty(&ep->queue)) {
830+ req = list_first_entry(&ep->queue, struct jz4740_request, queue);
831+ write_fifo(ep, req);
832+ }
833+}
834+
835+/*
836+ * Bulk OUT (recv)
837+ */
838+static void jz4740_out_epn(struct jz4740_udc *dev, uint32_t ep_idx, uint32_t intr)
839+{
840+ struct jz4740_ep *ep = &dev->ep[ep_idx];
841+ struct jz4740_request *req;
842+
843+ DEBUG("%s: %d\n", __FUNCTION__, ep_idx);
844+
845+ jz_udc_select_ep(ep);
846+ if (ep->desc) {
847+ uint32_t csr;
848+
849+ while ((csr = usb_readb(dev, ep->csr)) &
850+ (USB_OUTCSR_OUTPKTRDY | USB_OUTCSR_SENTSTALL)) {
851+ DEBUG("%s: %x\n", __FUNCTION__, csr);
852+
853+ if (csr & USB_OUTCSR_SENTSTALL) {
854+ DEBUG("%s: stall sent, flush fifo\n",
855+ __FUNCTION__);
856+ /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */
857+ flush(ep);
858+ } else if (csr & USB_OUTCSR_OUTPKTRDY) {
859+ if (list_empty(&ep->queue))
860+ req = 0;
861+ else
862+ req =
863+ list_entry(ep->queue.next,
864+ struct jz4740_request,
865+ queue);
866+
867+ if (!req) {
868+ DEBUG("%s: NULL REQ %d\n",
869+ __FUNCTION__, ep_idx);
870+ break;
871+ } else {
872+ read_fifo(ep, req);
873+ }
874+ }
875+ }
876+ } else {
877+ /* Throw packet away.. */
878+ DEBUG("%s: ep %p ep_indx %d No descriptor?!?\n", __FUNCTION__, ep, ep_idx);
879+ flush(ep);
880+ }
881+}
882+
883+/** Halt specific EP
884+ * Return 0 if success
885+ * NOTE: Sets INDEX register to EP !
886+ */
887+static int jz4740_set_halt(struct usb_ep *_ep, int value)
888+{
889+ struct jz4740_udc *dev;
890+ struct jz4740_ep *ep;
891+ unsigned long flags;
892+
893+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
894+
895+ ep = container_of(_ep, struct jz4740_ep, ep);
896+ if (unlikely(!_ep || (!ep->desc && ep->type != ep_control))) {
897+ DEBUG("%s, bad ep\n", __FUNCTION__);
898+ return -EINVAL;
899+ }
900+
901+ dev = ep->dev;
902+
903+ spin_lock_irqsave(&dev->lock, flags);
904+
905+ jz_udc_select_ep(ep);
906+
907+ DEBUG("%s, ep %d, val %d\n", __FUNCTION__, ep_index(ep), value);
908+
909+ if (ep_index(ep) == 0) {
910+ /* EP0 */
911+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SENDSTALL);
912+ } else if (ep_is_in(ep)) {
913+ uint32_t csr = usb_readb(dev, ep->csr);
914+ if (value && ((csr & USB_INCSR_FFNOTEMPT)
915+ || !list_empty(&ep->queue))) {
916+ /*
917+ * Attempts to halt IN endpoints will fail (returning -EAGAIN)
918+ * if any transfer requests are still queued, or if the controller
919+ * FIFO still holds bytes that the host hasn’t collected.
920+ */
921+ spin_unlock_irqrestore(&dev->lock, flags);
922+ DEBUG
923+ ("Attempt to halt IN endpoint failed (returning -EAGAIN) %d %d\n",
924+ (csr & USB_INCSR_FFNOTEMPT),
925+ !list_empty(&ep->queue));
926+ return -EAGAIN;
927+ }
928+ flush(ep);
929+ if (value) {
930+ usb_setb(dev, ep->csr, USB_INCSR_SENDSTALL);
931+ } else {
932+ usb_clearb(dev, ep->csr, USB_INCSR_SENDSTALL);
933+ usb_setb(dev, ep->csr, USB_INCSR_CDT);
934+ }
935+ } else {
936+
937+ flush(ep);
938+ if (value) {
939+ usb_setb(dev, ep->csr, USB_OUTCSR_SENDSTALL);
940+ } else {
941+ usb_clearb(dev, ep->csr, USB_OUTCSR_SENDSTALL);
942+ usb_setb(dev, ep->csr, USB_OUTCSR_CDT);
943+ }
944+ }
945+
946+ ep->stopped = value;
947+
948+ spin_unlock_irqrestore(&dev->lock, flags);
949+
950+ DEBUG("%s %s halted\n", _ep->name, value == 0 ? "NOT" : "IS");
951+
952+ return 0;
953+}
954+
955+
956+static int jz4740_ep_enable(struct usb_ep *_ep,
957+ const struct usb_endpoint_descriptor *desc)
958+{
959+ struct jz4740_ep *ep;
960+ struct jz4740_udc *dev;
961+ unsigned long flags;
962+ uint32_t max, csrh = 0;
963+
964+ DEBUG("%s: trying to enable %s\n", __FUNCTION__, _ep->name);
965+
966+ if (!_ep || !desc)
967+ return -EINVAL;
968+
969+ ep = container_of(_ep, struct jz4740_ep, ep);
970+ if (ep->desc || ep->type == ep_control
971+ || desc->bDescriptorType != USB_DT_ENDPOINT
972+ || ep->bEndpointAddress != desc->bEndpointAddress) {
973+ DEBUG("%s, bad ep or descriptor\n", __FUNCTION__);
974+ return -EINVAL;
975+ }
976+
977+ /* xfer types must match, except that interrupt ~= bulk */
978+ if (ep->bmAttributes != desc->bmAttributes
979+ && ep->bmAttributes != USB_ENDPOINT_XFER_BULK
980+ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
981+ DEBUG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
982+ return -EINVAL;
983+ }
984+
985+ dev = ep->dev;
986+ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
987+ DEBUG("%s, bogus device state\n", __FUNCTION__);
988+ return -ESHUTDOWN;
989+ }
990+
991+ max = le16_to_cpu(desc->wMaxPacketSize);
992+
993+ spin_lock_irqsave(&ep->dev->lock, flags);
994+
995+ /* Configure the endpoint */
996+ jz_udc_select_ep(ep);
997+ if (ep_is_in(ep)) {
998+ usb_writew(dev, JZ_REG_UDC_INMAXP, max);
999+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
1000+ case USB_ENDPOINT_XFER_BULK:
1001+ case USB_ENDPOINT_XFER_INT:
1002+ csrh &= ~USB_INCSRH_ISO;
1003+ break;
1004+ case USB_ENDPOINT_XFER_ISOC:
1005+ csrh |= USB_INCSRH_ISO;
1006+ break;
1007+ }
1008+ usb_writeb(dev, JZ_REG_UDC_INCSRH, csrh);
1009+ }
1010+ else {
1011+ usb_writew(dev, JZ_REG_UDC_OUTMAXP, max);
1012+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
1013+ case USB_ENDPOINT_XFER_BULK:
1014+ csrh &= ~USB_OUTCSRH_ISO;
1015+ break;
1016+ case USB_ENDPOINT_XFER_INT:
1017+ csrh &= ~USB_OUTCSRH_ISO;
1018+ csrh |= USB_OUTCSRH_DNYT;
1019+ break;
1020+ case USB_ENDPOINT_XFER_ISOC:
1021+ csrh |= USB_OUTCSRH_ISO;
1022+ break;
1023+ }
1024+ usb_writeb(dev, JZ_REG_UDC_OUTCSRH, csrh);
1025+ }
1026+
1027+
1028+ ep->stopped = 0;
1029+ ep->desc = desc;
1030+ ep->ep.maxpacket = max;
1031+
1032+ spin_unlock_irqrestore(&ep->dev->lock, flags);
1033+
1034+ /* Reset halt state (does flush) */
1035+ jz4740_set_halt(_ep, 0);
1036+
1037+ DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name);
1038+
1039+ return 0;
1040+}
1041+
1042+/** Disable EP
1043+ * NOTE: Sets INDEX register
1044+ */
1045+static int jz4740_ep_disable(struct usb_ep *_ep)
1046+{
1047+ struct jz4740_ep *ep;
1048+ unsigned long flags;
1049+
1050+ DEBUG("%s, %p\n", __FUNCTION__, _ep);
1051+
1052+ ep = container_of(_ep, struct jz4740_ep, ep);
1053+ if (!_ep || !ep->desc) {
1054+ DEBUG("%s, %s not enabled\n", __FUNCTION__,
1055+ _ep ? ep->ep.name : NULL);
1056+ return -EINVAL;
1057+ }
1058+
1059+ spin_lock_irqsave(&ep->dev->lock, flags);
1060+
1061+ jz_udc_select_ep(ep);
1062+
1063+ /* Nuke all pending requests (does flush) */
1064+ nuke(ep, -ESHUTDOWN);
1065+
1066+ /* Disable ep IRQ */
1067+ pio_irq_disable(ep);
1068+
1069+ ep->desc = 0;
1070+ ep->stopped = 1;
1071+
1072+ spin_unlock_irqrestore(&ep->dev->lock, flags);
1073+
1074+ DEBUG("%s: disabled %s\n", __FUNCTION__, _ep->name);
1075+ return 0;
1076+}
1077+
1078+static struct usb_request *jz4740_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
1079+{
1080+ struct jz4740_request *req;
1081+
1082+ req = kzalloc(sizeof(*req), gfp_flags);
1083+ if (!req)
1084+ return NULL;
1085+
1086+ INIT_LIST_HEAD(&req->queue);
1087+
1088+ return &req->req;
1089+}
1090+
1091+static void jz4740_free_request(struct usb_ep *ep, struct usb_request *_req)
1092+{
1093+ struct jz4740_request *req;
1094+
1095+ req = container_of(_req, struct jz4740_request, req);
1096+ WARN_ON(!list_empty(&req->queue));
1097+
1098+ kfree(req);
1099+}
1100+
1101+/*--------------------------------------------------------------------*/
1102+
1103+/** Queue one request
1104+ * Kickstart transfer if needed
1105+ * NOTE: Sets INDEX register
1106+ */
1107+static int jz4740_queue(struct usb_ep *_ep, struct usb_request *_req,
1108+ gfp_t gfp_flags)
1109+{
1110+ struct jz4740_request *req;
1111+ struct jz4740_ep *ep;
1112+ struct jz4740_udc *dev;
1113+
1114+ DEBUG("%s, %p\n", __FUNCTION__, _ep);
1115+
1116+ req = container_of(_req, struct jz4740_request, req);
1117+ if (unlikely
1118+ (!_req || !_req->complete || !_req->buf
1119+ || !list_empty(&req->queue))) {
1120+ DEBUG("%s, bad params\n", __FUNCTION__);
1121+ return -EINVAL;
1122+ }
1123+
1124+ ep = container_of(_ep, struct jz4740_ep, ep);
1125+ if (unlikely(!_ep || (!ep->desc && ep->type != ep_control))) {
1126+ DEBUG("%s, bad ep\n", __FUNCTION__);
1127+ return -EINVAL;
1128+ }
1129+
1130+ dev = ep->dev;
1131+ if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
1132+ DEBUG("%s, bogus device state %p\n", __FUNCTION__, dev->driver);
1133+ return -ESHUTDOWN;
1134+ }
1135+
1136+ DEBUG("%s queue req %p, len %d buf %p\n", _ep->name, _req, _req->length,
1137+ _req->buf);
1138+
1139+ spin_lock_irqsave(&dev->lock, dev->lock_flags);
1140+
1141+ _req->status = -EINPROGRESS;
1142+ _req->actual = 0;
1143+
1144+ /* kickstart this i/o queue? */
1145+ DEBUG("Add to %d Q %d %d\n", ep_index(ep), list_empty(&ep->queue),
1146+ ep->stopped);
1147+ if (list_empty(&ep->queue) && likely(!ep->stopped)) {
1148+ uint32_t csr;
1149+
1150+ if (unlikely(ep_index(ep) == 0)) {
1151+ /* EP0 */
1152+ list_add_tail(&req->queue, &ep->queue);
1153+ jz4740_ep0_kick(dev, ep);
1154+ req = 0;
1155+ }
1156+ else if (ep_is_in(ep)) {
1157+ /* EP1 & EP2 */
1158+ jz_udc_select_ep(ep);
1159+ csr = usb_readb(dev, ep->csr);
1160+ pio_irq_enable(ep);
1161+ if (!(csr & USB_INCSR_FFNOTEMPT)) {
1162+ if (write_fifo(ep, req) == 1)
1163+ req = 0;
1164+ }
1165+ } else {
1166+ /* EP1 */
1167+ jz_udc_select_ep(ep);
1168+ csr = usb_readb(dev, ep->csr);
1169+ pio_irq_enable(ep);
1170+ if (csr & USB_OUTCSR_OUTPKTRDY) {
1171+ if (read_fifo(ep, req) == 1)
1172+ req = 0;
1173+ }
1174+ }
1175+ }
1176+
1177+ /* pio or dma irq handler advances the queue. */
1178+ if (likely(req != 0))
1179+ list_add_tail(&req->queue, &ep->queue);
1180+
1181+ spin_unlock_irqrestore(&dev->lock, dev->lock_flags);
1182+
1183+ return 0;
1184+}
1185+
1186+/* dequeue JUST ONE request */
1187+static int jz4740_dequeue(struct usb_ep *_ep, struct usb_request *_req)
1188+{
1189+ struct jz4740_ep *ep;
1190+ struct jz4740_request *req;
1191+ unsigned long flags;
1192+
1193+ DEBUG("%s, %p\n", __FUNCTION__, _ep);
1194+
1195+ ep = container_of(_ep, struct jz4740_ep, ep);
1196+ if (!_ep || ep->type == ep_control)
1197+ return -EINVAL;
1198+
1199+ spin_lock_irqsave(&ep->dev->lock, flags);
1200+
1201+ /* make sure it's actually queued on this endpoint */
1202+ list_for_each_entry(req, &ep->queue, queue) {
1203+ if (&req->req == _req)
1204+ break;
1205+ }
1206+ if (&req->req != _req) {
1207+ spin_unlock_irqrestore(&ep->dev->lock, flags);
1208+ return -EINVAL;
1209+ }
1210+ done(ep, req, -ECONNRESET);
1211+
1212+ spin_unlock_irqrestore(&ep->dev->lock, flags);
1213+ return 0;
1214+}
1215+
1216+/** Return bytes in EP FIFO
1217+ * NOTE: Sets INDEX register to EP
1218+ */
1219+static int jz4740_fifo_status(struct usb_ep *_ep)
1220+{
1221+ uint32_t csr;
1222+ int count = 0;
1223+ struct jz4740_ep *ep;
1224+ unsigned long flags;
1225+
1226+ ep = container_of(_ep, struct jz4740_ep, ep);
1227+ if (!_ep) {
1228+ DEBUG("%s, bad ep\n", __FUNCTION__);
1229+ return -ENODEV;
1230+ }
1231+
1232+ DEBUG("%s, %d\n", __FUNCTION__, ep_index(ep));
1233+
1234+ /* LPD can't report unclaimed bytes from IN fifos */
1235+ if (ep_is_in(ep))
1236+ return -EOPNOTSUPP;
1237+
1238+ spin_lock_irqsave(&ep->dev->lock, flags);
1239+ jz_udc_select_ep(ep);
1240+
1241+ csr = usb_readb(ep->dev, ep->csr);
1242+ if (ep->dev->gadget.speed != USB_SPEED_UNKNOWN ||
1243+ csr & 0x1) {
1244+ count = usb_readw(ep->dev, JZ_REG_UDC_OUTCOUNT);
1245+ }
1246+
1247+ spin_unlock_irqrestore(&ep->dev->lock, flags);
1248+
1249+ return count;
1250+}
1251+
1252+/** Flush EP FIFO
1253+ * NOTE: Sets INDEX register to EP
1254+ */
1255+static void jz4740_fifo_flush(struct usb_ep *_ep)
1256+{
1257+ struct jz4740_ep *ep;
1258+ unsigned long flags;
1259+
1260+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1261+
1262+ ep = container_of(_ep, struct jz4740_ep, ep);
1263+ if (unlikely(!_ep || (!ep->desc && ep->type == ep_control))) {
1264+ DEBUG("%s, bad ep\n", __FUNCTION__);
1265+ return;
1266+ }
1267+
1268+ spin_lock_irqsave(&ep->dev->lock, flags);
1269+
1270+ jz_udc_select_ep(ep);
1271+ flush(ep);
1272+
1273+ spin_unlock_irqrestore(&ep->dev->lock, flags);
1274+}
1275+
1276+/****************************************************************/
1277+/* End Point 0 related functions */
1278+/****************************************************************/
1279+
1280+/* return: 0 = still running, 1 = completed, negative = errno */
1281+static int write_fifo_ep0(struct jz4740_ep *ep, struct jz4740_request *req)
1282+{
1283+ uint32_t max;
1284+ unsigned count;
1285+ int is_last;
1286+
1287+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1288+ max = ep_maxpacket(ep);
1289+
1290+ count = write_packet(ep, req, max);
1291+
1292+ /* last packet is usually short (or a zlp) */
1293+ if (unlikely(count != max))
1294+ is_last = 1;
1295+ else {
1296+ if (likely(req->req.length != req->req.actual) || req->req.zero)
1297+ is_last = 0;
1298+ else
1299+ is_last = 1;
1300+ }
1301+
1302+ DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __FUNCTION__,
1303+ ep->ep.name, count,
1304+ is_last ? "/L" : "", req->req.length - req->req.actual, req);
1305+
1306+ /* requests complete when all IN data is in the FIFO */
1307+ if (is_last) {
1308+ done(ep, req, 0);
1309+ return 1;
1310+ }
1311+
1312+ return 0;
1313+}
1314+
1315+static inline int jz4740_fifo_read(struct jz4740_ep *ep,
1316+ unsigned char *cp, int max)
1317+{
1318+ int bytes;
1319+ int count = usb_readw(ep->dev, JZ_REG_UDC_OUTCOUNT);
1320+
1321+ if (count > max)
1322+ count = max;
1323+ bytes = count;
1324+ while (count--)
1325+ *cp++ = usb_readb(ep->dev, ep->fifo);
1326+
1327+ return bytes;
1328+}
1329+
1330+static inline void jz4740_fifo_write(struct jz4740_ep *ep,
1331+ unsigned char *cp, int count)
1332+{
1333+ DEBUG("fifo_write: %d %d\n", ep_index(ep), count);
1334+ while (count--)
1335+ usb_writeb(ep->dev, ep->fifo, *cp++);
1336+}
1337+
1338+static int read_fifo_ep0(struct jz4740_ep *ep, struct jz4740_request *req)
1339+{
1340+ struct jz4740_udc *dev = ep->dev;
1341+ uint32_t csr;
1342+ uint8_t *buf;
1343+ unsigned bufferspace, count, is_short;
1344+
1345+ DEBUG_EP0("%s\n", __FUNCTION__);
1346+
1347+ csr = usb_readb(dev, JZ_REG_UDC_CSR0);
1348+ if (!(csr & USB_CSR0_OUTPKTRDY))
1349+ return 0;
1350+
1351+ buf = req->req.buf + req->req.actual;
1352+ prefetchw(buf);
1353+ bufferspace = req->req.length - req->req.actual;
1354+
1355+ /* read all bytes from this packet */
1356+ if (likely(csr & USB_CSR0_OUTPKTRDY)) {
1357+ count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT);
1358+ req->req.actual += min(count, bufferspace);
1359+ } else /* zlp */
1360+ count = 0;
1361+
1362+ is_short = (count < ep->ep.maxpacket);
1363+ DEBUG_EP0("read %s %02x, %d bytes%s req %p %d/%d\n",
1364+ ep->ep.name, csr, count,
1365+ is_short ? "/S" : "", req, req->req.actual, req->req.length);
1366+
1367+ while (likely(count-- != 0)) {
1368+ uint8_t byte = (uint8_t)usb_readl(dev, ep->fifo);
1369+
1370+ if (unlikely(bufferspace == 0)) {
1371+ /* this happens when the driver's buffer
1372+ * is smaller than what the host sent.
1373+ * discard the extra data.
1374+ */
1375+ if (req->req.status != -EOVERFLOW)
1376+ DEBUG_EP0("%s overflow %d\n", ep->ep.name,
1377+ count);
1378+ req->req.status = -EOVERFLOW;
1379+ } else {
1380+ *buf++ = byte;
1381+ bufferspace--;
1382+ }
1383+ }
1384+
1385+ /* completion */
1386+ if (is_short || req->req.actual == req->req.length) {
1387+ done(ep, req, 0);
1388+ return 1;
1389+ }
1390+
1391+ /* finished that packet. the next one may be waiting... */
1392+ return 0;
1393+}
1394+
1395+/**
1396+ * udc_set_address - set the USB address for this device
1397+ * @address:
1398+ *
1399+ * Called from control endpoint function after it decodes a set address setup packet.
1400+ */
1401+static void udc_set_address(struct jz4740_udc *dev, unsigned char address)
1402+{
1403+ DEBUG_EP0("%s: %d\n", __FUNCTION__, address);
1404+
1405+ usb_writeb(dev, JZ_REG_UDC_FADDR, address);
1406+}
1407+
1408+/*
1409+ * DATA_STATE_RECV (USB_CSR0_OUTPKTRDY)
1410+ * - if error
1411+ * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL bits
1412+ * - else
1413+ * set USB_CSR0_SVDOUTPKTRDY bit
1414+ if last set USB_CSR0_DATAEND bit
1415+ */
1416+static void jz4740_ep0_out(struct jz4740_udc *dev, uint32_t csr, int kickstart)
1417+{
1418+ struct jz4740_request *req;
1419+ struct jz4740_ep *ep = &dev->ep[0];
1420+ int ret;
1421+
1422+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
1423+
1424+ if (list_empty(&ep->queue))
1425+ req = 0;
1426+ else
1427+ req = list_entry(ep->queue.next, struct jz4740_request, queue);
1428+
1429+ if (req) {
1430+ if (req->req.length == 0) {
1431+ DEBUG_EP0("ZERO LENGTH OUT!\n");
1432+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));
1433+ dev->ep0state = WAIT_FOR_SETUP;
1434+ return;
1435+ } else if (kickstart) {
1436+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY));
1437+ return;
1438+ }
1439+ ret = read_fifo_ep0(ep, req);
1440+ if (ret) {
1441+ /* Done! */
1442+ DEBUG_EP0("%s: finished, waiting for status\n",
1443+ __FUNCTION__);
1444+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));
1445+ dev->ep0state = WAIT_FOR_SETUP;
1446+ } else {
1447+ /* Not done yet.. */
1448+ DEBUG_EP0("%s: not finished\n", __FUNCTION__);
1449+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY);
1450+ }
1451+ } else {
1452+ DEBUG_EP0("NO REQ??!\n");
1453+ }
1454+}
1455+
1456+/*
1457+ * DATA_STATE_XMIT
1458+ */
1459+static int jz4740_ep0_in(struct jz4740_udc *dev, uint32_t csr)
1460+{
1461+ struct jz4740_request *req;
1462+ struct jz4740_ep *ep = &dev->ep[0];
1463+ int ret, need_zlp = 0;
1464+
1465+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
1466+
1467+ if (list_empty(&ep->queue))
1468+ req = 0;
1469+ else
1470+ req = list_entry(ep->queue.next, struct jz4740_request, queue);
1471+
1472+ if (!req) {
1473+ DEBUG_EP0("%s: NULL REQ\n", __FUNCTION__);
1474+ return 0;
1475+ }
1476+
1477+ if (req->req.length == 0) {
1478+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND));
1479+ dev->ep0state = WAIT_FOR_SETUP;
1480+ return 1;
1481+ }
1482+
1483+ if (req->req.length - req->req.actual == EP0_MAXPACKETSIZE) {
1484+ /* Next write will end with the packet size, */
1485+ /* so we need zero-length-packet */
1486+ need_zlp = 1;
1487+ }
1488+
1489+ ret = write_fifo_ep0(ep, req);
1490+
1491+ if (ret == 1 && !need_zlp) {
1492+ /* Last packet */
1493+ DEBUG_EP0("%s: finished, waiting for status\n", __FUNCTION__);
1494+
1495+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND));
1496+ dev->ep0state = WAIT_FOR_SETUP;
1497+ } else {
1498+ DEBUG_EP0("%s: not finished\n", __FUNCTION__);
1499+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_INPKTRDY);
1500+ }
1501+
1502+ if (need_zlp) {
1503+ DEBUG_EP0("%s: Need ZLP!\n", __FUNCTION__);
1504+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_INPKTRDY);
1505+ dev->ep0state = DATA_STATE_NEED_ZLP;
1506+ }
1507+
1508+ return 1;
1509+}
1510+
1511+static int jz4740_handle_get_status(struct jz4740_udc *dev,
1512+ struct usb_ctrlrequest *ctrl)
1513+{
1514+ struct jz4740_ep *ep0 = &dev->ep[0];
1515+ struct jz4740_ep *qep;
1516+ int reqtype = (ctrl->bRequestType & USB_RECIP_MASK);
1517+ uint16_t val = 0;
1518+
1519+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1520+
1521+ if (reqtype == USB_RECIP_INTERFACE) {
1522+ /* This is not supported.
1523+ * And according to the USB spec, this one does nothing..
1524+ * Just return 0
1525+ */
1526+ DEBUG_SETUP("GET_STATUS: USB_RECIP_INTERFACE\n");
1527+ } else if (reqtype == USB_RECIP_DEVICE) {
1528+ DEBUG_SETUP("GET_STATUS: USB_RECIP_DEVICE\n");
1529+ val |= (1 << 0); /* Self powered */
1530+ /*val |= (1<<1); *//* Remote wakeup */
1531+ } else if (reqtype == USB_RECIP_ENDPOINT) {
1532+ int ep_num = (ctrl->wIndex & ~USB_DIR_IN);
1533+
1534+ DEBUG_SETUP
1535+ ("GET_STATUS: USB_RECIP_ENDPOINT (%d), ctrl->wLength = %d\n",
1536+ ep_num, ctrl->wLength);
1537+
1538+ if (ctrl->wLength > 2 || ep_num > 3)
1539+ return -EOPNOTSUPP;
1540+
1541+ qep = &dev->ep[ep_num];
1542+ if (ep_is_in(qep) != ((ctrl->wIndex & USB_DIR_IN) ? 1 : 0)
1543+ && ep_index(qep) != 0) {
1544+ return -EOPNOTSUPP;
1545+ }
1546+
1547+ jz_udc_select_ep(qep);
1548+
1549+ /* Return status on next IN token */
1550+ switch (qep->type) {
1551+ case ep_control:
1552+ val =
1553+ (usb_readb(dev, qep->csr) & USB_CSR0_SENDSTALL) ==
1554+ USB_CSR0_SENDSTALL;
1555+ break;
1556+ case ep_bulk_in:
1557+ case ep_interrupt:
1558+ val =
1559+ (usb_readb(dev, qep->csr) & USB_INCSR_SENDSTALL) ==
1560+ USB_INCSR_SENDSTALL;
1561+ break;
1562+ case ep_bulk_out:
1563+ val =
1564+ (usb_readb(dev, qep->csr) & USB_OUTCSR_SENDSTALL) ==
1565+ USB_OUTCSR_SENDSTALL;
1566+ break;
1567+ }
1568+
1569+ /* Back to EP0 index */
1570+ jz_udc_set_index(dev, 0);
1571+
1572+ DEBUG_SETUP("GET_STATUS, ep: %d (%x), val = %d\n", ep_num,
1573+ ctrl->wIndex, val);
1574+ } else {
1575+ DEBUG_SETUP("Unknown REQ TYPE: %d\n", reqtype);
1576+ return -EOPNOTSUPP;
1577+ }
1578+
1579+ /* Clear "out packet ready" */
1580+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY);
1581+ /* Put status to FIFO */
1582+ jz4740_fifo_write(ep0, (uint8_t *)&val, sizeof(val));
1583+ /* Issue "In packet ready" */
1584+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND));
1585+
1586+ return 0;
1587+}
1588+
1589+/*
1590+ * WAIT_FOR_SETUP (OUTPKTRDY)
1591+ * - read data packet from EP0 FIFO
1592+ * - decode command
1593+ * - if error
1594+ * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL bits
1595+ * - else
1596+ * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND bits
1597+ */
1598+static void jz4740_ep0_setup(struct jz4740_udc *dev, uint32_t csr)
1599+{
1600+ struct jz4740_ep *ep = &dev->ep[0];
1601+ struct usb_ctrlrequest ctrl;
1602+ int i;
1603+
1604+ DEBUG_SETUP("%s: %x\n", __FUNCTION__, csr);
1605+
1606+ /* Nuke all previous transfers */
1607+ nuke(ep, -EPROTO);
1608+
1609+ /* read control req from fifo (8 bytes) */
1610+ jz4740_fifo_read(ep, (unsigned char *)&ctrl, 8);
1611+
1612+ DEBUG_SETUP("SETUP %02x.%02x v%04x i%04x l%04x\n",
1613+ ctrl.bRequestType, ctrl.bRequest,
1614+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1615+
1616+ /* Set direction of EP0 */
1617+ if (likely(ctrl.bRequestType & USB_DIR_IN)) {
1618+ ep->bEndpointAddress |= USB_DIR_IN;
1619+ } else {
1620+ ep->bEndpointAddress &= ~USB_DIR_IN;
1621+ }
1622+
1623+ /* Handle some SETUP packets ourselves */
1624+ switch (ctrl.bRequest) {
1625+ case USB_REQ_SET_ADDRESS:
1626+ if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
1627+ break;
1628+
1629+ DEBUG_SETUP("USB_REQ_SET_ADDRESS (%d)\n", ctrl.wValue);
1630+ udc_set_address(dev, ctrl.wValue);
1631+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));
1632+ return;
1633+
1634+ case USB_REQ_SET_CONFIGURATION:
1635+ if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
1636+ break;
1637+
1638+ DEBUG_SETUP("USB_REQ_SET_CONFIGURATION (%d)\n", ctrl.wValue);
1639+/* usb_setb(JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));*/
1640+
1641+ /* Enable RESUME and SUSPEND interrupts */
1642+ usb_setb(dev, JZ_REG_UDC_INTRUSBE, (USB_INTR_RESUME | USB_INTR_SUSPEND));
1643+ break;
1644+
1645+ case USB_REQ_SET_INTERFACE:
1646+ if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
1647+ break;
1648+
1649+ DEBUG_SETUP("USB_REQ_SET_INTERFACE (%d)\n", ctrl.wValue);
1650+/* usb_setb(JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));*/
1651+ break;
1652+
1653+ case USB_REQ_GET_STATUS:
1654+ if (jz4740_handle_get_status(dev, &ctrl) == 0)
1655+ return;
1656+
1657+ case USB_REQ_CLEAR_FEATURE:
1658+ case USB_REQ_SET_FEATURE:
1659+ if (ctrl.bRequestType == USB_RECIP_ENDPOINT) {
1660+ struct jz4740_ep *qep;
1661+ int ep_num = (ctrl.wIndex & 0x0f);
1662+
1663+ /* Support only HALT feature */
1664+ if (ctrl.wValue != 0 || ctrl.wLength != 0
1665+ || ep_num > 3 || ep_num < 1)
1666+ break;
1667+
1668+ qep = &dev->ep[ep_num];
1669+ spin_unlock(&dev->lock);
1670+ if (ctrl.bRequest == USB_REQ_SET_FEATURE) {
1671+ DEBUG_SETUP("SET_FEATURE (%d)\n",
1672+ ep_num);
1673+ jz4740_set_halt(&qep->ep, 1);
1674+ } else {
1675+ DEBUG_SETUP("CLR_FEATURE (%d)\n",
1676+ ep_num);
1677+ jz4740_set_halt(&qep->ep, 0);
1678+ }
1679+ spin_lock(&dev->lock);
1680+
1681+ jz_udc_set_index(dev, 0);
1682+
1683+ /* Reply with a ZLP on next IN token */
1684+ usb_setb(dev, JZ_REG_UDC_CSR0,
1685+ (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));
1686+ return;
1687+ }
1688+ break;
1689+
1690+ default:
1691+ break;
1692+ }
1693+
1694+ /* gadget drivers see class/vendor specific requests,
1695+ * {SET,GET}_{INTERFACE,DESCRIPTOR,CONFIGURATION},
1696+ * and more.
1697+ */
1698+ if (dev->driver) {
1699+ /* device-2-host (IN) or no data setup command, process immediately */
1700+ spin_unlock(&dev->lock);
1701+
1702+ i = dev->driver->setup(&dev->gadget, &ctrl);
1703+ spin_lock(&dev->lock);
1704+
1705+ if (unlikely(i < 0)) {
1706+ /* setup processing failed, force stall */
1707+ DEBUG_SETUP
1708+ (" --> ERROR: gadget setup FAILED (stalling), setup returned %d\n",
1709+ i);
1710+ jz_udc_set_index(dev, 0);
1711+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL));
1712+
1713+ /* ep->stopped = 1; */
1714+ dev->ep0state = WAIT_FOR_SETUP;
1715+ }
1716+ else {
1717+ DEBUG_SETUP("gadget driver setup ok (%d)\n", ctrl.wLength);
1718+/* if (!ctrl.wLength) {
1719+ usb_setb(JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY);
1720+ }*/
1721+ }
1722+ }
1723+}
1724+
1725+/*
1726+ * DATA_STATE_NEED_ZLP
1727+ */
1728+static void jz4740_ep0_in_zlp(struct jz4740_udc *dev, uint32_t csr)
1729+{
1730+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
1731+
1732+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND));
1733+ dev->ep0state = WAIT_FOR_SETUP;
1734+}
1735+
1736+/*
1737+ * handle ep0 interrupt
1738+ */
1739+static void jz4740_handle_ep0(struct jz4740_udc *dev, uint32_t intr)
1740+{
1741+ struct jz4740_ep *ep = &dev->ep[0];
1742+ uint32_t csr;
1743+
1744+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1745+ /* Set index 0 */
1746+ jz_udc_set_index(dev, 0);
1747+ csr = usb_readb(dev, JZ_REG_UDC_CSR0);
1748+
1749+ DEBUG_EP0("%s: csr = %x state = \n", __FUNCTION__, csr);//, state_names[dev->ep0state]);
1750+
1751+ /*
1752+ * if SENT_STALL is set
1753+ * - clear the SENT_STALL bit
1754+ */
1755+ if (csr & USB_CSR0_SENTSTALL) {
1756+ DEBUG_EP0("%s: USB_CSR0_SENTSTALL is set: %x\n", __FUNCTION__, csr);
1757+ usb_clearb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SENDSTALL | USB_CSR0_SENTSTALL);
1758+ nuke(ep, -ECONNABORTED);
1759+ dev->ep0state = WAIT_FOR_SETUP;
1760+ return;
1761+ }
1762+
1763+ /*
1764+ * if a transfer is in progress && INPKTRDY and OUTPKTRDY are clear
1765+ * - fill EP0 FIFO
1766+ * - if last packet
1767+ * - set IN_PKT_RDY | DATA_END
1768+ * - else
1769+ * set IN_PKT_RDY
1770+ */
1771+ if (!(csr & (USB_CSR0_INPKTRDY | USB_CSR0_OUTPKTRDY))) {
1772+ DEBUG_EP0("%s: INPKTRDY and OUTPKTRDY are clear\n",
1773+ __FUNCTION__);
1774+
1775+ switch (dev->ep0state) {
1776+ case DATA_STATE_XMIT:
1777+ DEBUG_EP0("continue with DATA_STATE_XMIT\n");
1778+ jz4740_ep0_in(dev, csr);
1779+ return;
1780+ case DATA_STATE_NEED_ZLP:
1781+ DEBUG_EP0("continue with DATA_STATE_NEED_ZLP\n");
1782+ jz4740_ep0_in_zlp(dev, csr);
1783+ return;
1784+ default:
1785+ /* Stall? */
1786+// DEBUG_EP0("Odd state!! state = %s\n",
1787+// state_names[dev->ep0state]);
1788+ dev->ep0state = WAIT_FOR_SETUP;
1789+ /* nuke(ep, 0); */
1790+ /* usb_setb(ep->csr, USB_CSR0_SENDSTALL); */
1791+// break;
1792+ return;
1793+ }
1794+ }
1795+
1796+ /*
1797+ * if SETUPEND is set
1798+ * - abort the last transfer
1799+ * - set SERVICED_SETUP_END_BIT
1800+ */
1801+ if (csr & USB_CSR0_SETUPEND) {
1802+ DEBUG_EP0("%s: USB_CSR0_SETUPEND is set: %x\n", __FUNCTION__, csr);
1803+
1804+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDSETUPEND);
1805+ nuke(ep, 0);
1806+ dev->ep0state = WAIT_FOR_SETUP;
1807+ }
1808+
1809+ /*
1810+ * if USB_CSR0_OUTPKTRDY is set
1811+ * - read data packet from EP0 FIFO
1812+ * - decode command
1813+ * - if error
1814+ * set SVDOUTPKTRDY | DATAEND | SENDSTALL bits
1815+ * - else
1816+ * set SVDOUTPKTRDY | DATAEND bits
1817+ */
1818+ if (csr & USB_CSR0_OUTPKTRDY) {
1819+
1820+ DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __FUNCTION__,
1821+ csr);
1822+
1823+ switch (dev->ep0state) {
1824+ case WAIT_FOR_SETUP:
1825+ DEBUG_EP0("WAIT_FOR_SETUP\n");
1826+ jz4740_ep0_setup(dev, csr);
1827+ break;
1828+
1829+ case DATA_STATE_RECV:
1830+ DEBUG_EP0("DATA_STATE_RECV\n");
1831+ jz4740_ep0_out(dev, csr, 0);
1832+ break;
1833+
1834+ default:
1835+ /* send stall? */
1836+ DEBUG_EP0("strange state!! 2. send stall? state = %d\n",
1837+ dev->ep0state);
1838+ break;
1839+ }
1840+ }
1841+}
1842+
1843+static void jz4740_ep0_kick(struct jz4740_udc *dev, struct jz4740_ep *ep)
1844+{
1845+ uint32_t csr;
1846+
1847+ jz_udc_set_index(dev, 0);
1848+
1849+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
1850+
1851+ /* Clear "out packet ready" */
1852+
1853+ if (ep_is_in(ep)) {
1854+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY);
1855+ csr = usb_readb(dev, JZ_REG_UDC_CSR0);
1856+ dev->ep0state = DATA_STATE_XMIT;
1857+ jz4740_ep0_in(dev, csr);
1858+ } else {
1859+ csr = usb_readb(dev, JZ_REG_UDC_CSR0);
1860+ dev->ep0state = DATA_STATE_RECV;
1861+ jz4740_ep0_out(dev, csr, 1);
1862+ }
1863+}
1864+
1865+/** Handle USB RESET interrupt
1866+ */
1867+static void jz4740_reset_irq(struct jz4740_udc *dev)
1868+{
1869+ dev->gadget.speed = (usb_readb(dev, JZ_REG_UDC_POWER) & USB_POWER_HSMODE) ?
1870+ USB_SPEED_HIGH : USB_SPEED_FULL;
1871+
1872+ DEBUG_SETUP("%s: address = %d, speed = %s\n", __FUNCTION__, 0,
1873+ (dev->gadget.speed == USB_SPEED_HIGH) ? "HIGH":"FULL" );
1874+}
1875+
1876+/*
1877+ * jz4740 usb device interrupt handler.
1878+ */
1879+static irqreturn_t jz4740_udc_irq(int irq, void *devid)
1880+{
1881+ struct jz4740_udc *jz4740_udc = devid;
1882+ uint8_t index;
1883+
1884+ uint32_t intr_usb = usb_readb(jz4740_udc, JZ_REG_UDC_INTRUSB) & 0x7; /* mask SOF */
1885+ uint32_t intr_in = usb_readw(jz4740_udc, JZ_REG_UDC_INTRIN);
1886+ uint32_t intr_out = usb_readw(jz4740_udc, JZ_REG_UDC_INTROUT);
1887+ uint32_t intr_dma = usb_readb(jz4740_udc, JZ_REG_UDC_INTR);
1888+
1889+ if (!intr_usb && !intr_in && !intr_out && !intr_dma)
1890+ return IRQ_HANDLED;
1891+
1892+
1893+ DEBUG("intr_out=%x intr_in=%x intr_usb=%x\n",
1894+ intr_out, intr_in, intr_usb);
1895+
1896+ spin_lock(&jz4740_udc->lock);
1897+ index = usb_readb(jz4740_udc, JZ_REG_UDC_INDEX);
1898+
1899+ /* Check for resume from suspend mode */
1900+ if ((intr_usb & USB_INTR_RESUME) &&
1901+ (usb_readb(jz4740_udc, JZ_REG_UDC_INTRUSBE) & USB_INTR_RESUME)) {
1902+ DEBUG("USB resume\n");
1903+ jz4740_udc->driver->resume(&jz4740_udc->gadget); /* We have suspend(), so we must have resume() too. */
1904+ }
1905+
1906+ /* Check for system interrupts */
1907+ if (intr_usb & USB_INTR_RESET) {
1908+ DEBUG("USB reset\n");
1909+ jz4740_reset_irq(jz4740_udc);
1910+ }
1911+
1912+ /* Check for endpoint 0 interrupt */
1913+ if (intr_in & USB_INTR_EP0) {
1914+ DEBUG("USB_INTR_EP0 (control)\n");
1915+ jz4740_handle_ep0(jz4740_udc, intr_in);
1916+ }
1917+
1918+ /* Check for Bulk-IN DMA interrupt */
1919+ if (intr_dma & 0x1) {
1920+ int ep_num;
1921+ struct jz4740_ep *ep;
1922+ ep_num = (usb_readl(jz4740_udc, JZ_REG_UDC_CNTL1) >> 4) & 0xf;
1923+ ep = &jz4740_udc->ep[ep_num + 1];
1924+ jz_udc_select_ep(ep);
1925+ usb_setb(jz4740_udc, ep->csr, USB_INCSR_INPKTRDY);
1926+/* jz4740_in_epn(jz4740_udc, ep_num, intr_in);*/
1927+ }
1928+
1929+ /* Check for Bulk-OUT DMA interrupt */
1930+ if (intr_dma & 0x2) {
1931+ int ep_num;
1932+ ep_num = (usb_readl(jz4740_udc, JZ_REG_UDC_CNTL2) >> 4) & 0xf;
1933+ jz4740_out_epn(jz4740_udc, ep_num, intr_out);
1934+ }
1935+
1936+ /* Check for each configured endpoint interrupt */
1937+ if (intr_in & USB_INTR_INEP1) {
1938+ DEBUG("USB_INTR_INEP1\n");
1939+ jz4740_in_epn(jz4740_udc, 1, intr_in);
1940+ }
1941+
1942+ if (intr_in & USB_INTR_INEP2) {
1943+ DEBUG("USB_INTR_INEP2\n");
1944+ jz4740_in_epn(jz4740_udc, 2, intr_in);
1945+ }
1946+
1947+ if (intr_out & USB_INTR_OUTEP1) {
1948+ DEBUG("USB_INTR_OUTEP1\n");
1949+ jz4740_out_epn(jz4740_udc, 1, intr_out);
1950+ }
1951+
1952+ /* Check for suspend mode */
1953+ if ((intr_usb & USB_INTR_SUSPEND) &&
1954+ (usb_readb(jz4740_udc, JZ_REG_UDC_INTRUSBE) & USB_INTR_SUSPEND)) {
1955+ DEBUG("USB suspend\n");
1956+ jz4740_udc->driver->suspend(&jz4740_udc->gadget);
1957+ /* Host unloaded from us, can do something, such as flushing
1958+ the NAND block cache etc. */
1959+ }
1960+
1961+ jz_udc_set_index(jz4740_udc, index);
1962+
1963+ spin_unlock(&jz4740_udc->lock);
1964+
1965+ return IRQ_HANDLED;
1966+}
1967+
1968+
1969+
1970+/*-------------------------------------------------------------------------*/
1971+
1972+
1973+static inline struct jz4740_udc *gadget_to_udc(struct usb_gadget *gadget)
1974+{
1975+ return container_of(gadget, struct jz4740_udc, gadget);
1976+}
1977+
1978+static int jz4740_udc_get_frame(struct usb_gadget *_gadget)
1979+{
1980+ DEBUG("%s, %p\n", __FUNCTION__, _gadget);
1981+ return usb_readw(gadget_to_udc(_gadget), JZ_REG_UDC_FRAME);
1982+}
1983+
1984+static int jz4740_udc_wakeup(struct usb_gadget *_gadget)
1985+{
1986+ /* host may not have enabled remote wakeup */
1987+ /*if ((UDCCS0 & UDCCS0_DRWF) == 0)
1988+ return -EHOSTUNREACH;
1989+ udc_set_mask_UDCCR(UDCCR_RSM); */
1990+ return -ENOTSUPP;
1991+}
1992+
1993+static int jz4740_udc_pullup(struct usb_gadget *_gadget, int on)
1994+{
1995+ struct jz4740_udc *udc = gadget_to_udc(_gadget);
1996+ unsigned long flags;
1997+
1998+ local_irq_save(flags);
1999+
2000+ if (on) {
2001+ udc->state = UDC_STATE_ENABLE;
2002+ udc_enable(udc);
2003+ } else {
2004+ udc->state = UDC_STATE_DISABLE;
2005+ udc_disable(udc);
2006+ }
2007+
2008+ local_irq_restore(flags);
2009+
2010+ return 0;
2011+}
2012+
2013+
2014+static const struct usb_gadget_ops jz4740_udc_ops = {
2015+ .get_frame = jz4740_udc_get_frame,
2016+ .wakeup = jz4740_udc_wakeup,
2017+ .pullup = jz4740_udc_pullup,
2018+};
2019+
2020+static struct usb_ep_ops jz4740_ep_ops = {
2021+ .enable = jz4740_ep_enable,
2022+ .disable = jz4740_ep_disable,
2023+
2024+ .alloc_request = jz4740_alloc_request,
2025+ .free_request = jz4740_free_request,
2026+
2027+ .queue = jz4740_queue,
2028+ .dequeue = jz4740_dequeue,
2029+
2030+ .set_halt = jz4740_set_halt,
2031+ .fifo_status = jz4740_fifo_status,
2032+ .fifo_flush = jz4740_fifo_flush,
2033+};
2034+
2035+
2036+/*-------------------------------------------------------------------------*/
2037+
2038+static struct jz4740_udc jz4740_udc_controller = {
2039+ .gadget = {
2040+ .ops = &jz4740_udc_ops,
2041+ .ep0 = &jz4740_udc_controller.ep[0].ep,
2042+ .name = "jz4740-udc",
2043+ .dev = {
2044+ .init_name = "gadget",
2045+ },
2046+ },
2047+
2048+ /* control endpoint */
2049+ .ep[0] = {
2050+ .ep = {
2051+ .name = "ep0",
2052+ .ops = &jz4740_ep_ops,
2053+ .maxpacket = EP0_MAXPACKETSIZE,
2054+ },
2055+ .dev = &jz4740_udc_controller,
2056+
2057+ .bEndpointAddress = 0,
2058+ .bmAttributes = 0,
2059+
2060+ .type = ep_control,
2061+ .fifo = JZ_REG_UDC_EP_FIFO(0),
2062+ .csr = JZ_REG_UDC_CSR0,
2063+ },
2064+
2065+ /* bulk out endpoint */
2066+ .ep[1] = {
2067+ .ep = {
2068+ .name = "ep1out-bulk",
2069+ .ops = &jz4740_ep_ops,
2070+ .maxpacket = EPBULK_MAXPACKETSIZE,
2071+ },
2072+ .dev = &jz4740_udc_controller,
2073+
2074+ .bEndpointAddress = 1,
2075+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
2076+
2077+ .type = ep_bulk_out,
2078+ .fifo = JZ_REG_UDC_EP_FIFO(1),
2079+ .csr = JZ_REG_UDC_OUTCSR,
2080+ },
2081+
2082+ /* bulk in endpoint */
2083+ .ep[2] = {
2084+ .ep = {
2085+ .name = "ep1in-bulk",
2086+ .ops = &jz4740_ep_ops,
2087+ .maxpacket = EPBULK_MAXPACKETSIZE,
2088+ },
2089+ .dev = &jz4740_udc_controller,
2090+
2091+ .bEndpointAddress = 1 | USB_DIR_IN,
2092+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
2093+
2094+ .type = ep_bulk_in,
2095+ .fifo = JZ_REG_UDC_EP_FIFO(1),
2096+ .csr = JZ_REG_UDC_INCSR,
2097+ },
2098+
2099+ /* interrupt in endpoint */
2100+ .ep[3] = {
2101+ .ep = {
2102+ .name = "ep2in-int",
2103+ .ops = &jz4740_ep_ops,
2104+ .maxpacket = EPINTR_MAXPACKETSIZE,
2105+ },
2106+ .dev = &jz4740_udc_controller,
2107+
2108+ .bEndpointAddress = 2 | USB_DIR_IN,
2109+ .bmAttributes = USB_ENDPOINT_XFER_INT,
2110+
2111+ .type = ep_interrupt,
2112+ .fifo = JZ_REG_UDC_EP_FIFO(2),
2113+ .csr = JZ_REG_UDC_INCSR,
2114+ },
2115+};
2116+
2117+static int __devinit jz4740_udc_probe(struct platform_device *pdev)
2118+{
2119+ struct jz4740_udc *jz4740_udc = &jz4740_udc_controller;
2120+ int ret;
2121+
2122+ spin_lock_init(&jz4740_udc->lock);
2123+
2124+ jz4740_udc->dev = &pdev->dev;
2125+ jz4740_udc->gadget.dev.parent = &pdev->dev;
2126+ jz4740_udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
2127+
2128+ ret = device_register(&jz4740_udc->gadget.dev);
2129+ if (ret)
2130+ return ret;
2131+
2132+ jz4740_udc->clk = clk_get(&pdev->dev, "udc");
2133+ if (IS_ERR(jz4740_udc->clk)) {
2134+ ret = PTR_ERR(jz4740_udc->clk);
2135+ dev_err(&pdev->dev, "Failed to get udc clock: %d\n", ret);
2136+ goto err_device_unregister;
2137+ }
2138+
2139+ platform_set_drvdata(pdev, jz4740_udc);
2140+
2141+ jz4740_udc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2142+
2143+ if (!jz4740_udc->mem) {
2144+ ret = -ENOENT;
2145+ dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
2146+ goto err_clk_put;
2147+ }
2148+
2149+ jz4740_udc->mem = request_mem_region(jz4740_udc->mem->start,
2150+ resource_size(jz4740_udc->mem), pdev->name);
2151+
2152+ if (!jz4740_udc->mem) {
2153+ ret = -EBUSY;
2154+ dev_err(&pdev->dev, "Failed to request mmio memory region\n");
2155+ goto err_device_unregister;
2156+ }
2157+
2158+ jz4740_udc->base = ioremap(jz4740_udc->mem->start, resource_size(jz4740_udc->mem));
2159+
2160+ if (!jz4740_udc->base) {
2161+ ret = -EBUSY;
2162+ dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
2163+ goto err_release_mem_region;
2164+ }
2165+
2166+ jz4740_udc->irq = platform_get_irq(pdev, 0);
2167+ ret = request_irq(jz4740_udc->irq, jz4740_udc_irq, 0, pdev->name,
2168+ jz4740_udc);
2169+ if (ret) {
2170+ dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
2171+ goto err_iounmap;
2172+ }
2173+
2174+ udc_disable(jz4740_udc);
2175+ udc_reinit(jz4740_udc);
2176+
2177+ return 0;
2178+
2179+err_iounmap:
2180+ iounmap(jz4740_udc->base);
2181+err_release_mem_region:
2182+ release_mem_region(jz4740_udc->mem->start, resource_size(jz4740_udc->mem));
2183+err_clk_put:
2184+ clk_put(jz4740_udc->clk);
2185+err_device_unregister:
2186+ device_unregister(&jz4740_udc->gadget.dev);
2187+ platform_set_drvdata(pdev, NULL);
2188+
2189+ return ret;
2190+}
2191+
2192+static int __devexit jz4740_udc_remove(struct platform_device *pdev)
2193+{
2194+ struct jz4740_udc *dev = platform_get_drvdata(pdev);
2195+
2196+ if (dev->driver)
2197+ return -EBUSY;
2198+
2199+ udc_disable(dev);
2200+
2201+ free_irq(dev->irq, dev);
2202+ iounmap(dev->base);
2203+ release_mem_region(dev->mem->start, resource_size(dev->mem));
2204+ clk_put(dev->clk);
2205+
2206+ platform_set_drvdata(pdev, NULL);
2207+ device_unregister(&dev->gadget.dev);
2208+
2209+ return 0;
2210+}
2211+
2212+#ifdef CONFIG_PM
2213+
2214+static int jz4740_udc_suspend(struct device *dev)
2215+{
2216+ struct jz4740_udc *jz4740_udc = dev_get_drvdata(dev);
2217+
2218+ if (jz4740_udc->state == UDC_STATE_ENABLE)
2219+ udc_disable(jz4740_udc);
2220+
2221+ return 0;
2222+}
2223+
2224+static int jz4740_udc_resume(struct device *dev)
2225+{
2226+ struct jz4740_udc *jz4740_udc = dev_get_drvdata(dev);
2227+
2228+ if (jz4740_udc->state == UDC_STATE_ENABLE)
2229+ udc_enable(jz4740_udc);
2230+
2231+ return 0;
2232+}
2233+
2234+static SIMPLE_DEV_PM_OPS(jz4740_udc_pm_ops, jz4740_udc_suspend, jz4740_udc_resume);
2235+#define JZ4740_UDC_PM_OPS (&jz4740_udc_pm_ops)
2236+
2237+#else
2238+#define JZ4740_UDC_PM_OPS NULL
2239+#endif
2240+
2241+static struct platform_driver udc_driver = {
2242+ .probe = jz4740_udc_probe,
2243+ .remove = __devexit_p(jz4740_udc_remove),
2244+ .driver = {
2245+ .name = "jz-udc",
2246+ .owner = THIS_MODULE,
2247+ .pm = JZ4740_UDC_PM_OPS,
2248+ },
2249+};
2250+
2251+/*-------------------------------------------------------------------------*/
2252+
2253+static int __init udc_init (void)
2254+{
2255+ return platform_driver_register(&udc_driver);
2256+}
2257+module_init(udc_init);
2258+
2259+static void __exit udc_exit (void)
2260+{
2261+ platform_driver_unregister(&udc_driver);
2262+}
2263+module_exit(udc_exit);
2264+
2265+MODULE_DESCRIPTION("JZ4740 USB Device Controller");
2266+MODULE_AUTHOR("Wei Jianli <jlwei@ingenic.cn>");
2267+MODULE_LICENSE("GPL");
2268diff --git a/drivers/usb/gadget/jz4740_udc.h b/drivers/usb/gadget/jz4740_udc.h
2269new file mode 100644
2270index 0000000..53fd1da
2271--- /dev/null
2272@@ -0,0 +1,101 @@
2273+/*
2274+ * linux/drivers/usb/gadget/jz4740_udc.h
2275+ *
2276+ * Ingenic JZ4740 on-chip high speed USB device controller
2277+ *
2278+ * Copyright (C) 2006 Ingenic Semiconductor Inc.
2279+ * Author: <jlwei@ingenic.cn>
2280+ *
2281+ * This program is free software; you can redistribute it and/or modify
2282+ * it under the terms of the GNU General Public License as published by
2283+ * the Free Software Foundation; either version 2 of the License, or
2284+ * (at your option) any later version.
2285+ */
2286+
2287+#ifndef __USB_GADGET_JZ4740_H__
2288+#define __USB_GADGET_JZ4740_H__
2289+
2290+/*-------------------------------------------------------------------------*/
2291+
2292+// Max packet size
2293+#define EP0_MAXPACKETSIZE 64
2294+#define EPBULK_MAXPACKETSIZE 512
2295+#define EPINTR_MAXPACKETSIZE 64
2296+
2297+#define UDC_MAX_ENDPOINTS 4
2298+
2299+/*-------------------------------------------------------------------------*/
2300+
2301+enum ep_type {
2302+ ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt
2303+};
2304+
2305+struct jz4740_ep {
2306+ struct usb_ep ep;
2307+ struct jz4740_udc *dev;
2308+
2309+ const struct usb_endpoint_descriptor *desc;
2310+
2311+ uint8_t stopped;
2312+ uint8_t bEndpointAddress;
2313+ uint8_t bmAttributes;
2314+
2315+ enum ep_type type;
2316+ size_t fifo;
2317+ uint32_t csr;
2318+
2319+ uint32_t reg_addr;
2320+ struct list_head queue;
2321+};
2322+
2323+struct jz4740_request {
2324+ struct usb_request req;
2325+ struct list_head queue;
2326+};
2327+
2328+enum ep0state {
2329+ WAIT_FOR_SETUP, /* between STATUS ack and SETUP report */
2330+ DATA_STATE_XMIT, /* data tx stage */
2331+ DATA_STATE_NEED_ZLP, /* data tx zlp stage */
2332+ WAIT_FOR_OUT_STATUS, /* status stages */
2333+ DATA_STATE_RECV, /* data rx stage */
2334+};
2335+
2336+/* For function binding with UDC Disable - Added by River */
2337+typedef enum {
2338+ UDC_STATE_ENABLE = 0,
2339+ UDC_STATE_DISABLE,
2340+}udc_state_t;
2341+
2342+struct jz4740_udc {
2343+ struct usb_gadget gadget;
2344+ struct usb_gadget_driver *driver;
2345+ struct device *dev;
2346+ spinlock_t lock;
2347+ unsigned long lock_flags;
2348+
2349+ enum ep0state ep0state;
2350+ struct jz4740_ep ep[UDC_MAX_ENDPOINTS];
2351+
2352+ udc_state_t state;
2353+
2354+ struct resource *mem;
2355+ void __iomem *base;
2356+ int irq;
2357+
2358+ struct clk *clk;
2359+};
2360+
2361+#define ep_maxpacket(EP) ((EP)->ep.maxpacket)
2362+
2363+static inline bool ep_is_in(const struct jz4740_ep *ep)
2364+{
2365+ return (ep->bEndpointAddress & USB_DIR_IN) == USB_DIR_IN;
2366+}
2367+
2368+static inline uint8_t ep_index(const struct jz4740_ep *ep)
2369+{
2370+ return ep->bEndpointAddress & 0xf;
2371+}
2372+
2373+#endif /* __USB_GADGET_JZ4740_H__ */
2374--
23751.7.4.1
2376
target/linux/xburst/patches-3.0/0014-Framebuffer-notifier-Call-notifier-callbacks-prior-t.patch
1From c7700fa672bf0a171ceb9f4b092de33e3b306243 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sat, 24 Apr 2010 12:23:28 +0200
4Subject: [PATCH 14/29] Framebuffer notifier: Call notifier callbacks prior to blanking the screen
5
6---
7 drivers/video/fbmem.c | 8 ++++++--
8 1 files changed, 6 insertions(+), 2 deletions(-)
9
10diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
11index 5aac00e..b1beaa7 100644
12--- a/drivers/video/fbmem.c
13@@ -1032,12 +1032,12 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
14 int
15 fb_blank(struct fb_info *info, int blank)
16 {
17- int ret = -EINVAL;
18+ int ret = 0;
19
20      if (blank > FB_BLANK_POWERDOWN)
21          blank = FB_BLANK_POWERDOWN;
22
23- if (info->fbops->fb_blank)
24+ if (info->fbops->fb_blank && blank == FB_BLANK_UNBLANK)
25          ret = info->fbops->fb_blank(blank, info);
26
27      if (!ret) {
28@@ -1048,6 +1048,10 @@ fb_blank(struct fb_info *info, int blank)
29         fb_notifier_call_chain(FB_EVENT_BLANK, &event);
30     }
31
32+ if (info->fbops->fb_blank && blank != FB_BLANK_UNBLANK)
33+ ret = info->fbops->fb_blank(blank, info);
34+
35+
36      return ret;
37 }
38
39--
401.7.4.1
41
target/linux/xburst/patches-3.0/0015-500-modifier-keys.patch.patch
1From 15bd698ca3f4104f3e3c28dcc7619dcef21f40ad Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@macbook.(none)>
3Date: Fri, 19 Aug 2011 15:40:08 +0800
4Subject: [PATCH 15/29] 500-modifier-keys.patch
5
6---
7 drivers/tty/vt/defkeymap.c_shipped | 326 +++++++++++++++++++++++++++---------
8 drivers/tty/vt/defkeymap.map | 88 +++++++---
9 2 files changed, 305 insertions(+), 109 deletions(-)
10
11diff --git a/drivers/tty/vt/defkeymap.c_shipped b/drivers/tty/vt/defkeymap.c_shipped
12index d2208dfe..41ea840 100644
13--- a/drivers/tty/vt/defkeymap.c_shipped
14@@ -9,10 +9,10 @@ u_short plain_map[NR_KEYS] = {
15     0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
16     0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
17     0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
18- 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
19+ 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf706, 0xfb61, 0xfb73,
20     0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
21     0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
22- 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
23+ 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf701, 0xf30c,
24     0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
25     0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
26     0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
27@@ -20,56 +20,104 @@ u_short plain_map[NR_KEYS] = {
28     0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
29     0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
30     0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
31- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
32+ 0xf11a, 0xf10c, 0xf10b, 0xf10a, 0xf11c, 0xf110, 0xf311, 0xf11d,
33+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
34+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
35+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
36+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
37+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
38+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
39+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
40+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
41+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
42+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
43+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
44+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
45+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
46+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
47+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
48+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
49     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
50 };
51
52-u_short shift_map[NR_KEYS] = {
53+static u_short shift_map[NR_KEYS] = {
54     0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
55     0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
56     0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
57- 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
58+ 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf706, 0xfb41, 0xfb53,
59     0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
60     0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
61- 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
62+ 0xfb42, 0xfb4e, 0xfb4d, 0xf03b, 0xf03a, 0xf03f, 0xf701, 0xf30c,
63     0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
64     0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
65     0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
66- 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
67- 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
68- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
69+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf20b,
70+ 0xf20a, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
71+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
72     0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
73- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
74+ 0xf11a, 0xf10c, 0xf20a, 0xf20b, 0xf11c, 0xf110, 0xf311, 0xf11d,
75+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
76+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
77+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
78+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
79+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
80+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
81+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
82+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
83+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
84+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
85+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
86+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
87+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
88+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
89+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
90+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
91     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
92 };
93
94-u_short altgr_map[NR_KEYS] = {
95+static u_short altgr_map[NR_KEYS] = {
96     0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
97- 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
98- 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
99- 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
100- 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
101- 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
102- 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
103- 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
104- 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
105+ 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf07e, 0xf116, 0xf200,
106+ 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a,
107+ 0xf028, 0xf029, 0xf200, 0xf07e, 0xf201, 0xf706, 0xf0b0, 0xf0a8,
108+ 0xf0a4, 0xf02d, 0xf05f, 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf200,
109+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf039, 0xf030, 0xf916, 0xfb76,
110+ 0xf915, 0xf03c, 0xf03e, 0xf027, 0xf022, 0xf200, 0xf701, 0xf30c,
111+ 0xf703, 0xf200, 0xf207, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035,
112+ 0xf036, 0xf037, 0xf038, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
113     0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
114     0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
115     0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
116- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
117+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
118     0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
119- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
120+ 0xf11a, 0xf10c, 0xf517, 0xf516, 0xf11c, 0xf110, 0xf311, 0xf11d,
121+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
122+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
123+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
124+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
125+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
126+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
127+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
128+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
129+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
130+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
131+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
132+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
133+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
134+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
135+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
136+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
137     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
138 };
139
140-u_short ctrl_map[NR_KEYS] = {
141+static u_short ctrl_map[NR_KEYS] = {
142     0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
143- 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
144+ 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
145     0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
146- 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
147+ 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf706, 0xf001, 0xf013,
148     0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
149     0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
150- 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
151+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf701, 0xf30c,
152     0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
153     0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
154     0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
155@@ -77,37 +125,69 @@ u_short ctrl_map[NR_KEYS] = {
156     0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
157     0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
158     0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
159- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
160+ 0xf11a, 0xf10c, 0xf10b, 0xf10a, 0xf11c, 0xf110, 0xf311, 0xf11d,
161+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
162+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
163+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
164+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
165+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
166+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
167+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
168+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
169+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
170+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
171+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
172+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
173+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
174+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
175+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
176+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
177     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
178 };
179
180-u_short shift_ctrl_map[NR_KEYS] = {
181+static u_short shift_ctrl_map[NR_KEYS] = {
182     0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
183     0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
184     0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
185- 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
186+ 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf706, 0xf001, 0xf013,
187     0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
188     0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
189- 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
190+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf701, 0xf30c,
191     0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
192     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
193     0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
194     0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
195     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
196- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
197+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
198     0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
199- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
200+ 0xf11a, 0xf10c, 0xf200, 0xf200, 0xf11c, 0xf110, 0xf311, 0xf11d,
201+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
202+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
203+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
204+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
205+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
206+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
207+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
208+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
209+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
210+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
211+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
212+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
213+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
214+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
215+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
216+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
217     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
218 };
219
220-u_short alt_map[NR_KEYS] = {
221+static u_short alt_map[NR_KEYS] = {
222     0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
223     0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
224     0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
225- 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
226+ 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf706, 0xf861, 0xf873,
227     0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
228     0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
229- 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
230+ 0xf862, 0xf86e, 0xf86d, 0xf200, 0xf200, 0xf82f, 0xf701, 0xf30c,
231     0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
232     0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
233     0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
234@@ -115,37 +195,117 @@ u_short alt_map[NR_KEYS] = {
235     0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
236     0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
237     0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
238- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
239+ 0xf11a, 0xf10c, 0xf50b, 0xf50a, 0xf11c, 0xf110, 0xf311, 0xf11d,
240+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
241+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
242+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
243+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
244+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
245+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
246+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
247+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
248+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
249+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
250+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
251+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
252+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
253+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
254+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
255+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
256     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
257 };
258
259-u_short ctrl_alt_map[NR_KEYS] = {
260+static u_short ctrl_alt_map[NR_KEYS] = {
261     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
262     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
263     0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
264- 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
265+ 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf706, 0xf801, 0xf813,
266     0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
267     0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
268- 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
269+ 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf701, 0xf30c,
270     0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
271     0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
272     0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
273     0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
274     0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
275- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
276+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
277     0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
278- 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
279+ 0xf11a, 0xf10c, 0xf50b, 0xf50a, 0xf11c, 0xf110, 0xf311, 0xf11d,
280+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
281+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
282+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
283+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
284+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
285+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
286+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
287+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
288+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
289+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
290+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
291+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
292+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
293+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
294+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
295+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
296+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
297+};
298+
299+static u_short ctl_map[NR_KEYS] = {
300+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
301+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf033, 0xf200, 0xf200,
302+ 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xf037, 0xf038,
303+ 0xf039, 0xfb70, 0xf200, 0xf200, 0xf201, 0xf706, 0xfb61, 0xfb73,
304+ 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xf034, 0xf035, 0xf036, 0xf200,
305+ 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
306+ 0xfb62, 0xf031, 0xf032, 0xf200, 0xf200, 0xf030, 0xf701, 0xf30c,
307+ 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
308+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
309+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
310+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
311+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
312+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
313+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
314+ 0xf11a, 0xf10c, 0xf200, 0xf200, 0xf11c, 0xf110, 0xf311, 0xf11d,
315+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
316+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
317+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
318+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
319+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
320+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
321+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
322+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
323+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
324+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
325+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
326+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
327+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
328+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
329+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
330+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
331     0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
332 };
333
334 ushort *key_maps[MAX_NR_KEYMAPS] = {
335- plain_map, shift_map, altgr_map, NULL,
336- ctrl_map, shift_ctrl_map, NULL, NULL,
337- alt_map, NULL, NULL, NULL,
338- ctrl_alt_map, NULL
339+ plain_map, shift_map, altgr_map, 0,
340+ ctrl_map, shift_ctrl_map, 0, 0,
341+ alt_map, 0, 0, 0,
342+ ctrl_alt_map, 0, 0, 0,
343+ 0, 0, 0, 0,
344+ 0, 0, 0, 0,
345+ 0, 0, 0, 0,
346+ 0, 0, 0, 0,
347+ 0, 0, 0, 0,
348+ 0, 0, 0, 0,
349+ 0, 0, 0, 0,
350+ 0, 0, 0, 0,
351+ 0, 0, 0, 0,
352+ 0, 0, 0, 0,
353+ 0, 0, 0, 0,
354+ 0, 0, 0, 0,
355+ ctl_map, 0
356 };
357
358-unsigned int keymap_count = 7;
359+unsigned int keymap_count = 8;
360
361 /*
362  * Philosophy: most people do not define more strings, but they who do
363@@ -216,47 +376,47 @@ char *func_table[MAX_NR_FUNC] = {
364     func_buf + 135,
365     func_buf + 140,
366     func_buf + 145,
367- NULL,
368- NULL,
369+ 0,
370+ 0,
371     func_buf + 149,
372- NULL,
373+ 0,
374 };
375
376-struct kbdiacruc accent_table[MAX_DIACR] = {
377- {'`', 'A', 0300}, {'`', 'a', 0340},
378- {'\'', 'A', 0301}, {'\'', 'a', 0341},
379- {'^', 'A', 0302}, {'^', 'a', 0342},
380- {'~', 'A', 0303}, {'~', 'a', 0343},
381- {'"', 'A', 0304}, {'"', 'a', 0344},
382- {'O', 'A', 0305}, {'o', 'a', 0345},
383- {'0', 'A', 0305}, {'0', 'a', 0345},
384- {'A', 'A', 0305}, {'a', 'a', 0345},
385- {'A', 'E', 0306}, {'a', 'e', 0346},
386- {',', 'C', 0307}, {',', 'c', 0347},
387- {'`', 'E', 0310}, {'`', 'e', 0350},
388- {'\'', 'E', 0311}, {'\'', 'e', 0351},
389- {'^', 'E', 0312}, {'^', 'e', 0352},
390- {'"', 'E', 0313}, {'"', 'e', 0353},
391- {'`', 'I', 0314}, {'`', 'i', 0354},
392- {'\'', 'I', 0315}, {'\'', 'i', 0355},
393- {'^', 'I', 0316}, {'^', 'i', 0356},
394- {'"', 'I', 0317}, {'"', 'i', 0357},
395- {'-', 'D', 0320}, {'-', 'd', 0360},
396- {'~', 'N', 0321}, {'~', 'n', 0361},
397- {'`', 'O', 0322}, {'`', 'o', 0362},
398- {'\'', 'O', 0323}, {'\'', 'o', 0363},
399- {'^', 'O', 0324}, {'^', 'o', 0364},
400- {'~', 'O', 0325}, {'~', 'o', 0365},
401- {'"', 'O', 0326}, {'"', 'o', 0366},
402- {'/', 'O', 0330}, {'/', 'o', 0370},
403- {'`', 'U', 0331}, {'`', 'u', 0371},
404- {'\'', 'U', 0332}, {'\'', 'u', 0372},
405- {'^', 'U', 0333}, {'^', 'u', 0373},
406- {'"', 'U', 0334}, {'"', 'u', 0374},
407- {'\'', 'Y', 0335}, {'\'', 'y', 0375},
408- {'T', 'H', 0336}, {'t', 'h', 0376},
409- {'s', 's', 0337}, {'"', 'y', 0377},
410- {'s', 'z', 0337}, {'i', 'j', 0377},
411+struct kbdiacr accent_table[MAX_DIACR] = {
412+ {'`', 'A', '\300'}, {'`', 'a', '\340'},
413+ {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
414+ {'^', 'A', '\302'}, {'^', 'a', '\342'},
415+ {'~', 'A', '\303'}, {'~', 'a', '\343'},
416+ {'"', 'A', '\304'}, {'"', 'a', '\344'},
417+ {'O', 'A', '\305'}, {'o', 'a', '\345'},
418+ {'0', 'A', '\305'}, {'0', 'a', '\345'},
419+ {'A', 'A', '\305'}, {'a', 'a', '\345'},
420+ {'A', 'E', '\306'}, {'a', 'e', '\346'},
421+ {',', 'C', '\307'}, {',', 'c', '\347'},
422+ {'`', 'E', '\310'}, {'`', 'e', '\350'},
423+ {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
424+ {'^', 'E', '\312'}, {'^', 'e', '\352'},
425+ {'"', 'E', '\313'}, {'"', 'e', '\353'},
426+ {'`', 'I', '\314'}, {'`', 'i', '\354'},
427+ {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
428+ {'^', 'I', '\316'}, {'^', 'i', '\356'},
429+ {'"', 'I', '\317'}, {'"', 'i', '\357'},
430+ {'-', 'D', '\320'}, {'-', 'd', '\360'},
431+ {'~', 'N', '\321'}, {'~', 'n', '\361'},
432+ {'`', 'O', '\322'}, {'`', 'o', '\362'},
433+ {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
434+ {'^', 'O', '\324'}, {'^', 'o', '\364'},
435+ {'~', 'O', '\325'}, {'~', 'o', '\365'},
436+ {'"', 'O', '\326'}, {'"', 'o', '\366'},
437+ {'/', 'O', '\330'}, {'/', 'o', '\370'},
438+ {'`', 'U', '\331'}, {'`', 'u', '\371'},
439+ {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
440+ {'^', 'U', '\333'}, {'^', 'u', '\373'},
441+ {'"', 'U', '\334'}, {'"', 'u', '\374'},
442+ {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
443+ {'T', 'H', '\336'}, {'t', 'h', '\376'},
444+ {'s', 's', '\337'}, {'"', 'y', '\377'},
445+ {'s', 'z', '\337'}, {'i', 'j', '\377'},
446 };
447
448 unsigned int accent_table_size = 68;
449diff --git a/drivers/tty/vt/defkeymap.map b/drivers/tty/vt/defkeymap.map
450index 50b30ca..732f395 100644
451--- a/drivers/tty/vt/defkeymap.map
452@@ -1,5 +1,5 @@
453 # Default kernel keymap. This uses 7 modifier combinations.
454-keymaps 0-2,4-5,8,12
455+keymaps 0-2,4-5,8,12,64
456 # Change the above line into
457 # keymaps 0-2,4-6,8,12
458 # in case you want the entries
459@@ -45,24 +45,38 @@ keycode 12 = minus underscore backslash
460     control keycode 12 = Control_underscore
461     shift control keycode 12 = Control_underscore
462     alt keycode 12 = Meta_minus