summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-rp-2.6.23
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.23')
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/arm_pxa_20070923.patch5877
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/binutils-buildid-arm.patch16
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-prevent-oops-HACK.patch17
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-remove-ide-HACK.patch12
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-akita1737
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-bootcdx861579
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-c7x01741
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-collie1790
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-htcuniversal1313
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-hx20001231
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-poodle1741
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemuarm1397
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemux861756
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-spitz1741
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-tosa1665
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-zylonite1527
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/hostap-monitor-mode.patch209
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/hrw-add-wcf11-to-hostap.patch31
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni-acx.patch33526
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni.patch8044
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/mtd-module.patch13
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/pxa-serial-hack.patch90
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/pxa_fb_overlay.patch26
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch155
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/sharpsl-rc-r1.patch519
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/squashfs3.0-2.6.15.patch4189
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch2590
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/versatile-armv6.patch19
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/wm8750-treble.patch11
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-reset-loop-r2.patch44
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-suspend-cold-res-r2.patch16
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0-fix-r0.patch128
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch2899
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite-boot.patch45
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_keypad-r0.patch1187
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch4093
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_touch-r0.patch1548
37 files changed, 84522 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/arm_pxa_20070923.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/arm_pxa_20070923.patch
new file mode 100644
index 0000000000..ad4ce996df
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/arm_pxa_20070923.patch
@@ -0,0 +1,5877 @@
1# Base git commit: da8f153e51290e7438ba7da66234a864e5d3e1c1
2# (Revert "x86_64: Quicklist support for x86_64")
3#
4# Author: eric miao (Wed Sep 12 03:13:17 BST 2007)
5# Committer: Russell King (Sun Sep 23 14:18:19 BST 2007)
6#
7# [ARM] pxa: PXA3xx base support
8#
9# Signed-off-by: eric miao
10# Signed-off-by: Russell King
11#
12# arch/arm/Kconfig | 6
13# arch/arm/boot/compressed/head-xscale.S | 4
14# arch/arm/mach-pxa/Kconfig | 30 +
15# arch/arm/mach-pxa/Makefile | 9
16# arch/arm/mach-pxa/clock.c | 79 ++--
17# arch/arm/mach-pxa/clock.h | 43 ++
18# arch/arm/mach-pxa/devices.h | 3
19# arch/arm/mach-pxa/generic.c | 146 ++++---
20# arch/arm/mach-pxa/generic.h | 26 +
21# arch/arm/mach-pxa/irq.c | 80 ----
22# arch/arm/mach-pxa/mfp.c | 235 ++++++++++++
23# arch/arm/mach-pxa/pxa25x.c | 90 ++++
24# arch/arm/mach-pxa/pxa27x.c | 127 ++++++
25# arch/arm/mach-pxa/pxa300.c | 93 +++++
26# arch/arm/mach-pxa/pxa320.c | 88 ++++
27# arch/arm/mach-pxa/pxa3xx.c | 216 +++++++++++
28# arch/arm/mach-pxa/time.c | 53 ++
29# arch/arm/mach-pxa/zylonite.c | 184 +++++++++
30# arch/arm/mach-pxa/zylonite_pxa300.c | 188 ++++++++++
31# arch/arm/mach-pxa/zylonite_pxa320.c | 173 +++++++++
32# arch/arm/mm/Kconfig | 4
33# drivers/i2c/busses/i2c-pxa.c | 45 +-
34# drivers/input/keyboard/pxa27x_keyboard.c | 25 +
35# drivers/mmc/host/pxamci.c | 43 +-
36# drivers/mmc/host/pxamci.h | 14
37# drivers/mtd/maps/lubbock-flash.c | 9
38# drivers/mtd/maps/mainstone-flash.c | 5
39# drivers/net/irda/pxaficp_ir.c | 51 ++
40# drivers/net/smc91x.c | 62 ---
41# drivers/net/smc91x.h | 71 +++
42# drivers/serial/pxa.c | 163 ++++----
43# drivers/serial/serial_core.c | 18
44# drivers/usb/gadget/pxa2xx_udc.c | 68 ++-
45# drivers/usb/gadget/pxa2xx_udc.h | 1
46# drivers/video/pxafb.c | 36 +
47# drivers/video/pxafb.h | 1
48# include/asm-arm/arch-pxa/hardware.h | 72 +++
49# include/asm-arm/arch-pxa/irqs.h | 6
50# include/asm-arm/arch-pxa/mfp-pxa300.h | 574 ++++++++++++++++++++++++++++++
51# include/asm-arm/arch-pxa/mfp-pxa320.h | 446 ++++++++++++++++++++++++
52# include/asm-arm/arch-pxa/mfp.h | 576 +++++++++++++++++++++++++++++++
53# include/asm-arm/arch-pxa/pxa-regs.h | 2
54# include/asm-arm/arch-pxa/pxa3xx-regs.h | 75 ++++
55# include/asm-arm/arch-pxa/timex.h | 2
56# include/asm-arm/arch-pxa/zylonite.h | 35 +
57# 45 files changed, 3825 insertions(+), 452 deletions(-)
58# create mode 100644 arch/arm/mach-pxa/mfp.c
59# create mode 100644 arch/arm/mach-pxa/pxa300.c
60# create mode 100644 arch/arm/mach-pxa/pxa320.c
61# create mode 100644 arch/arm/mach-pxa/pxa3xx.c
62# create mode 100644 arch/arm/mach-pxa/zylonite.c
63# create mode 100644 arch/arm/mach-pxa/zylonite_pxa300.c
64# create mode 100644 arch/arm/mach-pxa/zylonite_pxa320.c
65# create mode 100644 include/asm-arm/arch-pxa/mfp-pxa300.h
66# create mode 100644 include/asm-arm/arch-pxa/mfp-pxa320.h
67# create mode 100644 include/asm-arm/arch-pxa/mfp.h
68# create mode 100644 include/asm-arm/arch-pxa/pxa3xx-regs.h
69# create mode 100644 include/asm-arm/arch-pxa/zylonite.h
70#
71# Author: Russell King (Sat Sep 1 21:27:18 BST 2007)
72# Committer: Russell King (Sun Sep 23 14:18:17 BST 2007)
73#
74# [NET] smc91x: fix PXA DMA support code
75#
76# The PXA DMA support code for smc91x doesn't pass a struct device to
77# the dma_*map_single() functions, which leads to an oops in the dma
78# bounce code. We have a struct device which was used to probe the
79# SMC chip. Use it.
80#
81# (This patch is slightly larger because it requires struct smc_local
82# to move into the header file.)
83#
84# Signed-off-by: Russell King
85#
86#
87# Author: Russell King (Sat Sep 1 21:25:09 BST 2007)
88# Committer: Russell King (Sun Sep 23 14:18:12 BST 2007)
89#
90# [SERIAL] Fix console initialisation ordering
91#
92# Ensure pm callback is called upon initialisation to place port in
93# correct power saving state. Ensure console is initialised prior
94# to deciding whether to power down the port.
95#
96# Signed-off-by: Russell King
97#
98#
99# Author: Russell King (Wed Sep 19 09:21:51 BST 2007)
100# Committer: Russell King (Sun Sep 23 14:18:07 BST 2007)
101#
102# [ARM] pxa: tidy up arch/arm/mach-pxa/Makefile
103#
104# Signed-off-by: Russell King
105#
106#
107# Author: Russell King (Sat Sep 1 21:28:55 BST 2007)
108# Committer: Russell King (Sun Sep 23 14:18:03 BST 2007)
109#
110# [ARM] lubbock, mainstone: only initialise if running on that platform
111#
112# Signed-off-by: Russell King
113#
114#
115# Author: eric miao (Wed Aug 29 10:22:17 BST 2007)
116# Committer: Russell King (Sun Sep 23 14:18:01 BST 2007)
117#
118# [ARM] 4560/1: pxa: move processor specific set_wake logic out of irq.c
119#
120# a function pxa_init_irq_set_wake() was introduced, so that
121# processor specific code could install their own version
122#
123# code setting PFER and PRER registers within pxa_gpio_irq_type
124# are removed, and the edge configuration is postponed to the
125# (*set_wake) and copies the GRER and GFER register, which will
126# always be set up correctly by pxa_gpio_irq_type()
127#
128# Signed-off-by: eric miao
129# Signed-off-by: Russell King
130#
131#
132# Author: eric miao (Wed Aug 29 10:18:47 BST 2007)
133# Committer: Russell King (Sun Sep 23 14:17:59 BST 2007)
134#
135# [ARM] 4559/1: pxa: make PXA_LAST_GPIO a run-time variable
136#
137# This definition produces processor specific code in generic function
138# pxa_gpio_mode(), thus creating inconsistencies for support of pxa25x
139# and pxa27x in a single zImage.
140#
141# As David Brownell suggests, make it a run-time variable and initialize
142# at run-time according to the number of GPIOs on the processor. For now
143# the initialization happens in pxa_init_irq_gpio(), since there is
144# already a parameter for that, besides, this is and MUST be earlier
145# than any subsequent calls to pxa_gpio_mode().
146#
147# Signed-off-by: eric miao
148# Signed-off-by: Russell King
149#
150#
151# Author: eric miao (Wed Aug 29 10:15:41 BST 2007)
152# Committer: Russell King (Sun Sep 23 14:17:57 BST 2007)
153#
154# [ARM] 4558/1: pxa: remove MACH_TYPE_LUBBOCK assignment and leave it to boot loader
155#
156# since both u-boot and blob support passing MACH_TYPE_LUBBOCK to the
157# kernel, it should be quite safe to remove this
158#
159# Signed-off-by: eric miao
160# Acked-by: Nicolas Pitre
161# Signed-off-by: Russell King
162#
163#
164# Author: eric miao (Wed Sep 12 03:13:17 BST 2007)
165# Committer: Russell King (Sun Sep 23 14:17:55 BST 2007)
166#
167# [ARM] pxa: add PXA3 cpu_is_xxx() macros
168#
169# Extracted from patch by Eric Miao, this adds the cpu_is_xxx() macros
170# for identifying PXA3 SoCs.
171#
172# Signed-off-by: eric miao
173# Signed-off-by: Russell King
174#
175#
176# Author: Russell King (Wed Sep 19 09:38:32 BST 2007)
177# Committer: Russell King (Sun Sep 23 14:17:51 BST 2007)
178#
179# [ARM] pxa: Make CPU_XSCALE depend on PXA25x or PXA27x
180#
181# PXA3 SoCs are supported by the Xscale3 CPU code rather than the
182# Xscale CPU code.
183#
184# Signed-off-by: Russell King
185#
186#
187# Author: Russell King (Wed Sep 19 09:33:55 BST 2007)
188# Committer: Russell King (Sun Sep 23 14:17:48 BST 2007)
189#
190# [ARM] pxa: mark pxa_set_cken deprecated
191#
192# Allow the generic clock support code to fiddle with the CKEN register
193# and mark pxa_set_cken() deprecated.
194#
195# Signed-off-by: Russell King
196#
197#
198# Author: Russell King (Mon Aug 20 10:34:37 BST 2007)
199# Committer: Russell King (Sun Sep 23 14:17:43 BST 2007)
200#
201# [ARM] pxa: remove get_lcdclk_frequency_10khz()
202#
203# get_lcdclk_frequency_10khz() is now redundant, remove it. Hide
204# pxa27x_get_lcdclk_frequency_10khz() from public view.
205#
206# Signed-off-by: Russell King
207#
208#
209# Author: Russell King (Sun Sep 2 17:09:23 BST 2007)
210# Committer: Russell King (Sun Sep 23 14:17:39 BST 2007)
211#
212# [ARM] pxa: update pxa irda driver to use clk support
213#
214# Signed-off-by: Russell King
215#
216#
217# Author: Russell King (Sun Sep 2 17:08:42 BST 2007)
218# Committer: Russell King (Sun Sep 23 14:17:36 BST 2007)
219#
220# [ARM] pxa: Make STUART and FICP clocks available
221#
222# Signed-off-by: Russell King
223#
224#
225# Author: Russell King (Mon Aug 20 10:33:35 BST 2007)
226# Committer: Russell King (Sun Sep 23 14:17:34 BST 2007)
227#
228# [ARM] pxa: update PXA UDC driver to use clk support
229#
230# Note: this produces a WARN() dump.
231#
232# Signed-off-by: Russell King
233#
234#
235# Author: Russell King (Mon Aug 20 10:28:15 BST 2007)
236# Committer: Russell King (Sun Sep 23 14:17:31 BST 2007)
237#
238# [ARM] pxa: update pxa serial driver to use clk support
239#
240# Signed-off-by: Russell King
241#
242#
243# Author: Russell King (Mon Aug 20 10:20:03 BST 2007)
244# Committer: Russell King (Sun Sep 23 14:17:27 BST 2007)
245#
246# [ARM] pxa: update PXA MMC interface driver to use clk support
247#
248# Signed-off-by: Russell King
249#
250#
251# Author: Russell King (Mon Aug 20 10:19:39 BST 2007)
252# Committer: Russell King (Sun Sep 23 14:17:23 BST 2007)
253#
254# [ARM] pxa: update pxa27x keypad driver to use clk support
255#
256# Signed-off-by: Russell King
257#
258#
259# Author: Russell King (Mon Aug 20 10:19:10 BST 2007)
260# Committer: Russell King (Sun Sep 23 14:17:19 BST 2007)
261#
262# [ARM] pxa: update pxa i2c driver to use clk support
263#
264# Signed-off-by: Russell King
265#
266#
267# Author: Russell King (Mon Aug 20 10:18:42 BST 2007)
268# Committer: Russell King (Sun Sep 23 14:16:50 BST 2007)
269#
270# [ARM] pxa: update pxafb to use clk support
271#
272# Signed-off-by: Russell King
273#
274#
275# Author: Russell King (Mon Aug 20 10:18:02 BST 2007)
276# Committer: Russell King (Sat Sep 22 20:48:09 BST 2007)
277#
278# [ARM] pxa: introduce clk support for PXA SoC clocks
279#
280# Signed-off-by: Russell King
281#
282# create mode 100644 arch/arm/mach-pxa/clock.h
283#
284# Author: Russell King (Mon Aug 20 10:09:18 BST 2007)
285# Committer: Russell King (Sat Sep 22 20:48:09 BST 2007)
286#
287# [ARM] pxa: make pxa27x devices globally visible
288#
289# Signed-off-by: Russell King
290#
291#
292# Author: Russell King (Mon Aug 20 10:07:44 BST 2007)
293# Committer: Russell King (Sat Sep 22 20:48:08 BST 2007)
294#
295# [ARM] pxa: fix naming of memory/lcd/core clock functions
296#
297# Rename pxa25x and pxa27x memory/lcd/core clock functions, and
298# select the correct version at run time.
299#
300# Signed-off-by: Russell King
301#
302#
303# Author: Russell King (Mon Aug 20 09:47:41 BST 2007)
304# Committer: Russell King (Sat Sep 22 20:48:08 BST 2007)
305#
306# [ARM] pxa: convert PXA serial drivers to use platform resources
307#
308# Signed-off-by: Russell King
309#
310#
311# Author: Russell King (Sat Sep 1 21:12:50 BST 2007)
312# Committer: Russell King (Sat Sep 22 20:48:07 BST 2007)
313#
314# [ARM] pxa: make pxa timer initialisation select clock rate at runtime
315#
316# Rather than using the compile-time constant CLOCK_TICK_RATE, select
317# the clock tick rate at run time. We organise the selection so that
318# PXA3 automatically falls out with the right tick rate.
319#
320# Signed-off-by: Russell King
321#
322#
323# Author: Nicolas Pitre (Fri Aug 17 16:55:22 BST 2007)
324# Committer: Russell King (Sat Sep 22 20:48:05 BST 2007)
325#
326# [ARM] 4550/1: sched_clock on PXA should cope with run time clock rate selection
327#
328# The previous implementation was relying on compile time optimizations
329# based on a constant clock rate. However, support for different PXA
330# flavors in the same kernel binary requires that the clock be selected at
331# run time, so here it is.
332#
333# Let's move this code to a more appropriate location while at it.
334#
335# Signed-off-by: Nicolas Pitre
336# Signed-off-by: Russell King
337#
338#
339--- linux-2.6.23.orig/arch/arm/Kconfig
340+++ linux-2.6.23/arch/arm/Kconfig
341@@ -336,14 +336,14 @@
342 This enables support for Philips PNX4008 mobile platform.
343
344 config ARCH_PXA
345- bool "PXA2xx-based"
346+ bool "PXA2xx/PXA3xx-based"
347 depends on MMU
348 select ARCH_MTD_XIP
349 select GENERIC_GPIO
350 select GENERIC_TIME
351 select GENERIC_CLOCKEVENTS
352 help
353- Support for Intel's PXA2XX processor line.
354+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
355
356 config ARCH_RPC
357 bool "RiscPC"
358@@ -486,7 +486,7 @@
359 config IWMMXT
360 bool "Enable iWMMXt support"
361 depends on CPU_XSCALE || CPU_XSC3
362- default y if PXA27x
363+ default y if PXA27x || PXA3xx
364 help
365 Enable support for iWMMXt context switching at run time if
366 running on a CPU that supports it.
367--- linux-2.6.23.orig/arch/arm/boot/compressed/head-xscale.S
368+++ linux-2.6.23/arch/arm/boot/compressed/head-xscale.S
369@@ -33,10 +33,6 @@
370 bic r0, r0, #0x1000 @ clear Icache
371 mcr p15, 0, r0, c1, c0, 0
372
373-#ifdef CONFIG_ARCH_LUBBOCK
374- mov r7, #MACH_TYPE_LUBBOCK
375-#endif
376-
377 #ifdef CONFIG_ARCH_COTULLA_IDP
378 mov r7, #MACH_TYPE_COTULLA_IDP
379 #endif
380--- linux-2.6.23.orig/arch/arm/mach-pxa/Kconfig
381+++ linux-2.6.23/arch/arm/mach-pxa/Kconfig
382@@ -1,6 +1,24 @@
383 if ARCH_PXA
384
385-menu "Intel PXA2xx Implementations"
386+menu "Intel PXA2xx/PXA3xx Implementations"
387+
388+if PXA3xx
389+
390+menu "Supported PXA3xx Processor Variants"
391+
392+config CPU_PXA300
393+ bool "PXA300 (codename Monahans-L)"
394+
395+config CPU_PXA310
396+ bool "PXA310 (codename Monahans-LV)"
397+ select CPU_PXA300
398+
399+config CPU_PXA320
400+ bool "PXA320 (codename Monahans-P)"
401+
402+endmenu
403+
404+endif
405
406 choice
407 prompt "Select target board"
408@@ -41,6 +59,11 @@
409 bool "CompuLab EM-x270 platform"
410 select PXA27x
411
412+
413+config MACH_ZYLONITE
414+ bool "PXA3xx Development Platform"
415+ select PXA3xx
416+
417 config MACH_HX2750
418 bool "HP iPAQ hx2750"
419 select PXA27x
420@@ -228,6 +251,11 @@
421 help
422 Select code specific to PXA27x variants
423
424+config PXA3xx
425+ bool
426+ help
427+ Select code specific to PXA3xx variants
428+
429 config PXA_SHARP_C7xx
430 bool
431 select PXA_SSP
432--- linux-2.6.23.orig/arch/arm/mach-pxa/Makefile
433+++ linux-2.6.23/arch/arm/mach-pxa/Makefile
434@@ -6,6 +6,9 @@
435 obj-y += clock.o generic.o irq.o dma.o time.o
436 obj-$(CONFIG_PXA25x) += pxa25x.o
437 obj-$(CONFIG_PXA27x) += pxa27x.o
438+obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
439+obj-$(CONFIG_CPU_PXA300) += pxa300.o
440+obj-$(CONFIG_CPU_PXA320) += pxa320.o
441
442 # Specific board support
443 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
444@@ -19,6 +22,12 @@
445 obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o sharpsl_pm.o poodle_pm.o
446 obj-$(CONFIG_MACH_TOSA) += tosa.o
447 obj-$(CONFIG_MACH_EM_X270) += em-x270.o
448+ifeq ($(CONFIG_MACH_ZYLONITE),y)
449+ obj-y += zylonite.o
450+ obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o
451+ obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
452+endif
453+
454 obj-$(CONFIG_MACH_HX2750) += hx2750.o hx2750_test.o
455 obj-$(CONFIG_MACH_HTCUNIVERSAL) += htcuniversal/
456
457--- linux-2.6.23.orig/arch/arm/mach-pxa/clock.c
458+++ linux-2.6.23/arch/arm/mach-pxa/clock.c
459@@ -9,19 +9,15 @@
460 #include <linux/string.h>
461 #include <linux/clk.h>
462 #include <linux/spinlock.h>
463+#include <linux/platform_device.h>
464+#include <linux/delay.h>
465
466 #include <asm/arch/pxa-regs.h>
467 #include <asm/hardware.h>
468
469-struct clk {
470- struct list_head node;
471- unsigned long rate;
472- struct module *owner;
473- const char *name;
474- unsigned int enabled;
475- void (*enable)(void);
476- void (*disable)(void);
477-};
478+#include "devices.h"
479+#include "generic.h"
480+#include "clock.h"
481
482 static LIST_HEAD(clocks);
483 static DEFINE_MUTEX(clocks_mutex);
484@@ -33,7 +29,8 @@
485
486 mutex_lock(&clocks_mutex);
487 list_for_each_entry(p, &clocks, node) {
488- if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
489+ if (strcmp(id, p->name) == 0 &&
490+ (p->dev == NULL || p->dev == dev)) {
491 clk = p;
492 break;
493 }
494@@ -46,7 +43,6 @@
495
496 void clk_put(struct clk *clk)
497 {
498- module_put(clk->owner);
499 }
500 EXPORT_SYMBOL(clk_put);
501
502@@ -56,8 +52,12 @@
503
504 spin_lock_irqsave(&clocks_lock, flags);
505 if (clk->enabled++ == 0)
506- clk->enable();
507+ clk->ops->enable(clk);
508 spin_unlock_irqrestore(&clocks_lock, flags);
509+
510+ if (clk->delay)
511+ udelay(clk->delay);
512+
513 return 0;
514 }
515 EXPORT_SYMBOL(clk_enable);
516@@ -70,54 +70,75 @@
517
518 spin_lock_irqsave(&clocks_lock, flags);
519 if (--clk->enabled == 0)
520- clk->disable();
521+ clk->ops->disable(clk);
522 spin_unlock_irqrestore(&clocks_lock, flags);
523 }
524 EXPORT_SYMBOL(clk_disable);
525
526 unsigned long clk_get_rate(struct clk *clk)
527 {
528- return clk->rate;
529+ unsigned long rate;
530+
531+ rate = clk->rate;
532+ if (clk->ops->getrate)
533+ rate = clk->ops->getrate(clk);
534+
535+ return rate;
536 }
537 EXPORT_SYMBOL(clk_get_rate);
538
539
540-static void clk_gpio27_enable(void)
541+static void clk_gpio27_enable(struct clk *clk)
542 {
543 pxa_gpio_mode(GPIO11_3_6MHz_MD);
544 }
545
546-static void clk_gpio27_disable(void)
547+static void clk_gpio27_disable(struct clk *clk)
548 {
549 }
550
551-static struct clk clk_gpio27 = {
552- .name = "GPIO27_CLK",
553- .rate = 3686400,
554+static const struct clkops clk_gpio27_ops = {
555 .enable = clk_gpio27_enable,
556 .disable = clk_gpio27_disable,
557 };
558
559-int clk_register(struct clk *clk)
560+
561+void clk_cken_enable(struct clk *clk)
562 {
563- mutex_lock(&clocks_mutex);
564- list_add(&clk->node, &clocks);
565- mutex_unlock(&clocks_mutex);
566- return 0;
567+ CKEN |= 1 << clk->cken;
568 }
569-EXPORT_SYMBOL(clk_register);
570
571-void clk_unregister(struct clk *clk)
572+void clk_cken_disable(struct clk *clk)
573 {
574+ CKEN &= ~(1 << clk->cken);
575+}
576+
577+const struct clkops clk_cken_ops = {
578+ .enable = clk_cken_enable,
579+ .disable = clk_cken_disable,
580+};
581+
582+static struct clk common_clks[] = {
583+ {
584+ .name = "GPIO27_CLK",
585+ .ops = &clk_gpio27_ops,
586+ .rate = 3686400,
587+ },
588+};
589+
590+void clks_register(struct clk *clks, size_t num)
591+{
592+ int i;
593+
594 mutex_lock(&clocks_mutex);
595- list_del(&clk->node);
596+ for (i = 0; i < num; i++)
597+ list_add(&clks[i].node, &clocks);
598 mutex_unlock(&clocks_mutex);
599 }
600-EXPORT_SYMBOL(clk_unregister);
601
602 static int __init clk_init(void)
603 {
604- clk_register(&clk_gpio27);
605+ clks_register(common_clks, ARRAY_SIZE(common_clks));
606 return 0;
607 }
608 arch_initcall(clk_init);
609--- /dev/null
610+++ linux-2.6.23/arch/arm/mach-pxa/clock.h
611@@ -0,0 +1,43 @@
612+struct clk;
613+
614+struct clkops {
615+ void (*enable)(struct clk *);
616+ void (*disable)(struct clk *);
617+ unsigned long (*getrate)(struct clk *);
618+};
619+
620+struct clk {
621+ struct list_head node;
622+ const char *name;
623+ struct device *dev;
624+ const struct clkops *ops;
625+ unsigned long rate;
626+ unsigned int cken;
627+ unsigned int delay;
628+ unsigned int enabled;
629+};
630+
631+#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \
632+ { \
633+ .name = _name, \
634+ .dev = _dev, \
635+ .ops = &clk_cken_ops, \
636+ .rate = _rate, \
637+ .cken = CKEN_##_cken, \
638+ .delay = _delay, \
639+ }
640+
641+#define INIT_CK(_name, _cken, _ops, _dev) \
642+ { \
643+ .name = _name, \
644+ .dev = _dev, \
645+ .ops = _ops, \
646+ .cken = CKEN_##_cken, \
647+ }
648+
649+extern const struct clkops clk_cken_ops;
650+
651+void clk_cken_enable(struct clk *clk);
652+void clk_cken_disable(struct clk *clk);
653+
654+void clks_register(struct clk *clks, size_t num);
655--- linux-2.6.23.orig/arch/arm/mach-pxa/devices.h
656+++ linux-2.6.23/arch/arm/mach-pxa/devices.h
657@@ -9,3 +9,6 @@
658 extern struct platform_device pxa_device_i2s;
659 extern struct platform_device pxa_device_ficp;
660 extern struct platform_device pxa_device_rtc;
661+
662+extern struct platform_device pxa27x_device_i2c_power;
663+extern struct platform_device pxa27x_device_ohci;
664--- linux-2.6.23.orig/arch/arm/mach-pxa/generic.c
665+++ linux-2.6.23/arch/arm/mach-pxa/generic.c
666@@ -25,10 +25,6 @@
667 #include <linux/pm.h>
668 #include <linux/string.h>
669
670-#include <linux/sched.h>
671-#include <asm/cnt32_to_63.h>
672-#include <asm/div64.h>
673-
674 #include <asm/hardware.h>
675 #include <asm/irq.h>
676 #include <asm/system.h>
677@@ -48,66 +44,39 @@
678 #include "generic.h"
679
680 /*
681- * This is the PXA2xx sched_clock implementation. This has a resolution
682- * of at least 308ns and a maximum value that depends on the value of
683- * CLOCK_TICK_RATE.
684- *
685- * The return value is guaranteed to be monotonic in that range as
686- * long as there is always less than 582 seconds between successive
687- * calls to this function.
688+ * Get the clock frequency as reflected by CCCR and the turbo flag.
689+ * We assume these values have been applied via a fcs.
690+ * If info is not 0 we also display the current settings.
691 */
692-unsigned long long sched_clock(void)
693+unsigned int get_clk_frequency_khz(int info)
694 {
695- unsigned long long v = cnt32_to_63(OSCR);
696- /* Note: top bit ov v needs cleared unless multiplier is even. */
697-
698-#if CLOCK_TICK_RATE == 3686400
699- /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */
700- /* The <<1 is used to get rid of tick.hi top bit */
701- v *= 78125<<1;
702- do_div(v, 288<<1);
703-#elif CLOCK_TICK_RATE == 3250000
704- /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */
705- v *= 4000;
706- do_div(v, 13);
707-#elif CLOCK_TICK_RATE == 3249600
708- /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */
709- v *= 625000;
710- do_div(v, 2031);
711-#else
712-#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE"
713- /*
714- * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for
715- * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand
716- * years range and truncation to unsigned long long limits it to
717- * sched_clock's max range of ~584 years. This is nice but with
718- * higher computation cost.
719- */
720- {
721- union {
722- unsigned long long val;
723- struct { unsigned long lo, hi; };
724- } x;
725- unsigned long long y;
726-
727- x.val = v;
728- x.hi &= 0x7fffffff;
729- y = (unsigned long long)x.lo * NSEC_PER_SEC;
730- x.lo = y;
731- y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC;
732- x.hi = do_div(y, CLOCK_TICK_RATE);
733- do_div(x.val, CLOCK_TICK_RATE);
734- x.hi += y;
735- v = x.val;
736- }
737-#endif
738+ if (cpu_is_pxa21x() || cpu_is_pxa25x())
739+ return pxa25x_get_clk_frequency_khz(info);
740+ else if (cpu_is_pxa27x())
741+ return pxa27x_get_clk_frequency_khz(info);
742+ else
743+ return pxa3xx_get_clk_frequency_khz(info);
744+}
745+EXPORT_SYMBOL(get_clk_frequency_khz);
746
747- return v;
748+/*
749+ * Return the current memory clock frequency in units of 10kHz
750+ */
751+unsigned int get_memclk_frequency_10khz(void)
752+{
753+ if (cpu_is_pxa21x() || cpu_is_pxa25x())
754+ return pxa25x_get_memclk_frequency_10khz();
755+ else if (cpu_is_pxa27x())
756+ return pxa27x_get_memclk_frequency_10khz();
757+ else
758+ return pxa3xx_get_memclk_frequency_10khz();
759 }
760+EXPORT_SYMBOL(get_memclk_frequency_10khz);
761
762 /*
763 * Handy function to set GPIO alternate functions
764 */
765+int pxa_last_gpio;
766
767 int pxa_gpio_mode(int gpio_mode)
768 {
769@@ -116,7 +85,7 @@
770 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
771 int gafr;
772
773- if (gpio > PXA_LAST_GPIO)
774+ if (gpio > pxa_last_gpio)
775 return -EINVAL;
776
777 local_irq_save(flags);
778@@ -160,7 +129,7 @@
779 /*
780 * Routine to safely enable or disable a clock in the CKEN
781 */
782-void pxa_set_cken(int clock, int enable)
783+void __pxa_set_cken(int clock, int enable)
784 {
785 unsigned long flags;
786 local_irq_save(flags);
787@@ -173,7 +142,7 @@
788 local_irq_restore(flags);
789 }
790
791-EXPORT_SYMBOL(pxa_set_cken);
792+EXPORT_SYMBOL(__pxa_set_cken);
793
794 /*
795 * Intel PXA2xx internal register mapping.
796@@ -330,21 +299,80 @@
797 pxa_device_fb.dev.parent = parent_dev;
798 }
799
800+static struct resource pxa_resource_ffuart[] = {
801+ {
802+ .start = __PREG(FFUART),
803+ .end = __PREG(FFUART) + 35,
804+ .flags = IORESOURCE_MEM,
805+ }, {
806+ .start = IRQ_FFUART,
807+ .end = IRQ_FFUART,
808+ .flags = IORESOURCE_IRQ,
809+ }
810+};
811+
812 struct platform_device pxa_device_ffuart= {
813 .name = "pxa2xx-uart",
814 .id = 0,
815+ .resource = pxa_resource_ffuart,
816+ .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
817+};
818+
819+static struct resource pxa_resource_btuart[] = {
820+ {
821+ .start = __PREG(BTUART),
822+ .end = __PREG(BTUART) + 35,
823+ .flags = IORESOURCE_MEM,
824+ }, {
825+ .start = IRQ_BTUART,
826+ .end = IRQ_BTUART,
827+ .flags = IORESOURCE_IRQ,
828+ }
829 };
830+
831 struct platform_device pxa_device_btuart = {
832 .name = "pxa2xx-uart",
833 .id = 1,
834+ .resource = pxa_resource_btuart,
835+ .num_resources = ARRAY_SIZE(pxa_resource_btuart),
836 };
837+
838+static struct resource pxa_resource_stuart[] = {
839+ {
840+ .start = __PREG(STUART),
841+ .end = __PREG(STUART) + 35,
842+ .flags = IORESOURCE_MEM,
843+ }, {
844+ .start = IRQ_STUART,
845+ .end = IRQ_STUART,
846+ .flags = IORESOURCE_IRQ,
847+ }
848+};
849+
850 struct platform_device pxa_device_stuart = {
851 .name = "pxa2xx-uart",
852 .id = 2,
853+ .resource = pxa_resource_stuart,
854+ .num_resources = ARRAY_SIZE(pxa_resource_stuart),
855+};
856+
857+static struct resource pxa_resource_hwuart[] = {
858+ {
859+ .start = __PREG(HWUART),
860+ .end = __PREG(HWUART) + 47,
861+ .flags = IORESOURCE_MEM,
862+ }, {
863+ .start = IRQ_HWUART,
864+ .end = IRQ_HWUART,
865+ .flags = IORESOURCE_IRQ,
866+ }
867 };
868+
869 struct platform_device pxa_device_hwuart = {
870 .name = "pxa2xx-uart",
871 .id = 3,
872+ .resource = pxa_resource_hwuart,
873+ .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
874 };
875
876 void __init pxa_set_ffuart_info(struct platform_pxa_serial_funcs *info)
877--- linux-2.6.23.orig/arch/arm/mach-pxa/generic.h
878+++ linux-2.6.23/arch/arm/mach-pxa/generic.h
879@@ -15,14 +15,40 @@
880 extern void __init pxa_init_irq_low(void);
881 extern void __init pxa_init_irq_high(void);
882 extern void __init pxa_init_irq_gpio(int gpio_nr);
883+extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
884 extern void __init pxa25x_init_irq(void);
885 extern void __init pxa27x_init_irq(void);
886+extern void __init pxa3xx_init_irq(void);
887 extern void __init pxa_map_io(void);
888
889 extern unsigned int get_clk_frequency_khz(int info);
890+extern int pxa_last_gpio;
891
892 #define SET_BANK(__nr,__start,__size) \
893 mi->bank[__nr].start = (__start), \
894 mi->bank[__nr].size = (__size), \
895 mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
896
897+#ifdef CONFIG_PXA25x
898+extern unsigned pxa25x_get_clk_frequency_khz(int);
899+extern unsigned pxa25x_get_memclk_frequency_10khz(void);
900+#else
901+#define pxa25x_get_clk_frequency_khz(x) (0)
902+#define pxa25x_get_memclk_frequency_10khz() (0)
903+#endif
904+
905+#ifdef CONFIG_PXA27x
906+extern unsigned pxa27x_get_clk_frequency_khz(int);
907+extern unsigned pxa27x_get_memclk_frequency_10khz(void);
908+#else
909+#define pxa27x_get_clk_frequency_khz(x) (0)
910+#define pxa27x_get_memclk_frequency_10khz() (0)
911+#endif
912+
913+#ifdef CONFIG_PXA3xx
914+extern unsigned pxa3xx_get_clk_frequency_khz(int);
915+extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
916+#else
917+#define pxa3xx_get_clk_frequency_khz(x) (0)
918+#define pxa3xx_get_memclk_frequency_10khz() (0)
919+#endif
920--- linux-2.6.23.orig/arch/arm/mach-pxa/irq.c
921+++ linux-2.6.23/arch/arm/mach-pxa/irq.c
922@@ -38,33 +38,11 @@
923 ICMR |= (1 << irq);
924 }
925
926-static int pxa_set_wake(unsigned int irq, unsigned int on)
927-{
928- u32 mask;
929-
930- switch (irq) {
931- case IRQ_RTCAlrm:
932- mask = PWER_RTC;
933- break;
934-#ifdef CONFIG_PXA27x
935- /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
936-#endif
937- default:
938- return -EINVAL;
939- }
940- if (on)
941- PWER |= mask;
942- else
943- PWER &= ~mask;
944- return 0;
945-}
946-
947 static struct irq_chip pxa_internal_chip_low = {
948 .name = "SC",
949 .ack = pxa_mask_low_irq,
950 .mask = pxa_mask_low_irq,
951 .unmask = pxa_unmask_low_irq,
952- .set_wake = pxa_set_wake,
953 };
954
955 void __init pxa_init_irq_low(void)
956@@ -87,7 +65,7 @@
957 }
958 }
959
960-#ifdef CONFIG_PXA27x
961+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
962
963 /*
964 * This is for the second set of internal IRQs as found on the PXA27x.
965@@ -125,26 +103,6 @@
966 }
967 #endif
968
969-/* Note that if an input/irq line ever gets changed to an output during
970- * suspend, the relevant PWER, PRER, and PFER bits should be cleared.
971- */
972-#ifdef CONFIG_PXA27x
973-
974-/* PXA27x: Various gpios can issue wakeup events. This logic only
975- * handles the simple cases, not the WEMUX2 and WEMUX3 options
976- */
977-#define PXA27x_GPIO_NOWAKE_MASK \
978- ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
979-#define WAKEMASK(gpio) \
980- (((gpio) <= 15) \
981- ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
982- : ((gpio == 35) ? (1 << 24) : 0))
983-#else
984-
985-/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */
986-#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
987-#endif
988-
989 /*
990 * PXA GPIO edge detection for IRQs:
991 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
992@@ -158,11 +116,9 @@
993 static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
994 {
995 int gpio, idx;
996- u32 mask;
997
998 gpio = IRQ_TO_GPIO(irq);
999 idx = gpio >> 5;
1000- mask = WAKEMASK(gpio);
1001
1002 if (type == IRQT_PROBE) {
1003 /* Don't mess with enabled GPIOs using preconfigured edges or
1004@@ -182,19 +138,15 @@
1005 if (type & __IRQT_RISEDGE) {
1006 /* printk("rising "); */
1007 __set_bit (gpio, GPIO_IRQ_rising_edge);
1008- PRER |= mask;
1009 } else {
1010 __clear_bit (gpio, GPIO_IRQ_rising_edge);
1011- PRER &= ~mask;
1012 }
1013
1014 if (type & __IRQT_FALEDGE) {
1015 /* printk("falling "); */
1016 __set_bit (gpio, GPIO_IRQ_falling_edge);
1017- PFER |= mask;
1018 } else {
1019 __clear_bit (gpio, GPIO_IRQ_falling_edge);
1020- PFER &= ~mask;
1021 }
1022
1023 /* printk("edges\n"); */
1024@@ -213,29 +165,12 @@
1025 GEDR0 = (1 << (irq - IRQ_GPIO0));
1026 }
1027
1028-static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
1029-{
1030- int gpio = IRQ_TO_GPIO(irq);
1031- u32 mask = WAKEMASK(gpio);
1032-
1033- if (!mask)
1034- return -EINVAL;
1035-
1036- if (on)
1037- PWER |= mask;
1038- else
1039- PWER &= ~mask;
1040- return 0;
1041-}
1042-
1043-
1044 static struct irq_chip pxa_low_gpio_chip = {
1045 .name = "GPIO-l",
1046 .ack = pxa_ack_low_gpio,
1047 .mask = pxa_mask_low_irq,
1048 .unmask = pxa_unmask_low_irq,
1049 .set_type = pxa_gpio_irq_type,
1050- .set_wake = pxa_set_gpio_wake,
1051 };
1052
1053 /*
1054@@ -342,13 +277,14 @@
1055 .mask = pxa_mask_muxed_gpio,
1056 .unmask = pxa_unmask_muxed_gpio,
1057 .set_type = pxa_gpio_irq_type,
1058- .set_wake = pxa_set_gpio_wake,
1059 };
1060
1061 void __init pxa_init_irq_gpio(int gpio_nr)
1062 {
1063 int irq, i;
1064
1065+ pxa_last_gpio = gpio_nr - 1;
1066+
1067 /* clear all GPIO edge detects */
1068 for (i = 0; i < gpio_nr; i += 32) {
1069 GFER(i) = 0;
1070@@ -375,3 +311,13 @@
1071 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
1072 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
1073 }
1074+
1075+void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
1076+{
1077+ pxa_internal_chip_low.set_wake = set_wake;
1078+#ifdef CONFIG_PXA27x
1079+ pxa_internal_chip_high.set_wake = set_wake;
1080+#endif
1081+ pxa_low_gpio_chip.set_wake = set_wake;
1082+ pxa_muxed_gpio_chip.set_wake = set_wake;
1083+}
1084--- /dev/null
1085+++ linux-2.6.23/arch/arm/mach-pxa/mfp.c
1086@@ -0,0 +1,235 @@
1087+/*
1088+ * linux/arch/arm/mach-pxa/mfp.c
1089+ *
1090+ * PXA3xx Multi-Function Pin Support
1091+ *
1092+ * Copyright (C) 2007 Marvell Internation Ltd.
1093+ *
1094+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
1095+ * initial version
1096+ *
1097+ * This program is free software; you can redistribute it and/or modify
1098+ * it under the terms of the GNU General Public License version 2 as
1099+ * published by the Free Software Foundation.
1100+ */
1101+
1102+#include <linux/module.h>
1103+#include <linux/kernel.h>
1104+#include <linux/init.h>
1105+#include <linux/io.h>
1106+
1107+#include <asm/hardware.h>
1108+#include <asm/arch/mfp.h>
1109+
1110+/* mfp_spin_lock is used to ensure that MFP register configuration
1111+ * (most likely a read-modify-write operation) is atomic, and that
1112+ * mfp_table[] is consistent
1113+ */
1114+static DEFINE_SPINLOCK(mfp_spin_lock);
1115+
1116+static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
1117+static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
1118+
1119+#define mfpr_readl(off) \
1120+ __raw_readl(mfpr_mmio_base + (off))
1121+
1122+#define mfpr_writel(off, val) \
1123+ __raw_writel(val, mfpr_mmio_base + (off))
1124+
1125+/*
1126+ * perform a read-back of any MFPR register to make sure the
1127+ * previous writings are finished
1128+ */
1129+#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
1130+
1131+static inline void __mfp_config(int pin, unsigned long val)
1132+{
1133+ unsigned long off = mfp_table[pin].mfpr_off;
1134+
1135+ mfp_table[pin].mfpr_val = val;
1136+ mfpr_writel(off, val);
1137+}
1138+
1139+void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num)
1140+{
1141+ int i, pin;
1142+ unsigned long val, flags;
1143+ mfp_cfg_t *mfp_cfg = mfp_cfgs;
1144+
1145+ spin_lock_irqsave(&mfp_spin_lock, flags);
1146+
1147+ for (i = 0; i < num; i++, mfp_cfg++) {
1148+ pin = MFP_CFG_PIN(*mfp_cfg);
1149+ val = MFP_CFG_VAL(*mfp_cfg);
1150+
1151+ BUG_ON(pin >= MFP_PIN_MAX);
1152+
1153+ __mfp_config(pin, val);
1154+ }
1155+
1156+ mfpr_sync();
1157+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1158+}
1159+
1160+unsigned long pxa3xx_mfp_read(int mfp)
1161+{
1162+ unsigned long val, flags;
1163+
1164+ BUG_ON(mfp >= MFP_PIN_MAX);
1165+
1166+ spin_lock_irqsave(&mfp_spin_lock, flags);
1167+ val = mfpr_readl(mfp_table[mfp].mfpr_off);
1168+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1169+
1170+ return val;
1171+}
1172+
1173+void pxa3xx_mfp_write(int mfp, unsigned long val)
1174+{
1175+ unsigned long flags;
1176+
1177+ BUG_ON(mfp >= MFP_PIN_MAX);
1178+
1179+ spin_lock_irqsave(&mfp_spin_lock, flags);
1180+ mfpr_writel(mfp_table[mfp].mfpr_off, val);
1181+ mfpr_sync();
1182+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1183+}
1184+
1185+void pxa3xx_mfp_set_afds(int mfp, int af, int ds)
1186+{
1187+ uint32_t mfpr_off, mfpr_val;
1188+ unsigned long flags;
1189+
1190+ BUG_ON(mfp >= MFP_PIN_MAX);
1191+
1192+ spin_lock_irqsave(&mfp_spin_lock, flags);
1193+ mfpr_off = mfp_table[mfp].mfpr_off;
1194+
1195+ mfpr_val = mfpr_readl(mfpr_off);
1196+ mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
1197+ mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
1198+ ((ds & 0x7) << MFPR_DRV_OFFSET));
1199+
1200+ mfpr_writel(mfpr_off, mfpr_val);
1201+ mfpr_sync();
1202+
1203+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1204+}
1205+
1206+void pxa3xx_mfp_set_rdh(int mfp, int rdh)
1207+{
1208+ uint32_t mfpr_off, mfpr_val;
1209+ unsigned long flags;
1210+
1211+ BUG_ON(mfp >= MFP_PIN_MAX);
1212+
1213+ spin_lock_irqsave(&mfp_spin_lock, flags);
1214+
1215+ mfpr_off = mfp_table[mfp].mfpr_off;
1216+
1217+ mfpr_val = mfpr_readl(mfpr_off);
1218+ mfpr_val &= ~MFPR_RDH_MASK;
1219+
1220+ if (likely(rdh))
1221+ mfpr_val |= (1u << MFPR_SS_OFFSET);
1222+
1223+ mfpr_writel(mfpr_off, mfpr_val);
1224+ mfpr_sync();
1225+
1226+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1227+}
1228+
1229+void pxa3xx_mfp_set_lpm(int mfp, int lpm)
1230+{
1231+ uint32_t mfpr_off, mfpr_val;
1232+ unsigned long flags;
1233+
1234+ BUG_ON(mfp >= MFP_PIN_MAX);
1235+
1236+ spin_lock_irqsave(&mfp_spin_lock, flags);
1237+
1238+ mfpr_off = mfp_table[mfp].mfpr_off;
1239+ mfpr_val = mfpr_readl(mfpr_off);
1240+ mfpr_val &= ~MFPR_LPM_MASK;
1241+
1242+ if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
1243+ if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
1244+ if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
1245+ if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
1246+ if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;
1247+
1248+ mfpr_writel(mfpr_off, mfpr_val);
1249+ mfpr_sync();
1250+
1251+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1252+}
1253+
1254+void pxa3xx_mfp_set_pull(int mfp, int pull)
1255+{
1256+ uint32_t mfpr_off, mfpr_val;
1257+ unsigned long flags;
1258+
1259+ BUG_ON(mfp >= MFP_PIN_MAX);
1260+
1261+ spin_lock_irqsave(&mfp_spin_lock, flags);
1262+
1263+ mfpr_off = mfp_table[mfp].mfpr_off;
1264+ mfpr_val = mfpr_readl(mfpr_off);
1265+ mfpr_val &= ~MFPR_PULL_MASK;
1266+ mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET);
1267+
1268+ mfpr_writel(mfpr_off, mfpr_val);
1269+ mfpr_sync();
1270+
1271+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1272+}
1273+
1274+void pxa3xx_mfp_set_edge(int mfp, int edge)
1275+{
1276+ uint32_t mfpr_off, mfpr_val;
1277+ unsigned long flags;
1278+
1279+ BUG_ON(mfp >= MFP_PIN_MAX);
1280+
1281+ spin_lock_irqsave(&mfp_spin_lock, flags);
1282+
1283+ mfpr_off = mfp_table[mfp].mfpr_off;
1284+ mfpr_val = mfpr_readl(mfpr_off);
1285+
1286+ mfpr_val &= ~MFPR_EDGE_MASK;
1287+ mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
1288+ mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;
1289+
1290+ mfpr_writel(mfpr_off, mfpr_val);
1291+ mfpr_sync();
1292+
1293+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1294+}
1295+
1296+void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
1297+{
1298+ struct pxa3xx_mfp_addr_map *p;
1299+ unsigned long offset, flags;
1300+ int i;
1301+
1302+ spin_lock_irqsave(&mfp_spin_lock, flags);
1303+
1304+ for (p = map; p->start != MFP_PIN_INVALID; p++) {
1305+ offset = p->offset;
1306+ i = p->start;
1307+
1308+ do {
1309+ mfp_table[i].mfpr_off = offset;
1310+ mfp_table[i].mfpr_val = 0;
1311+ offset += 4; i++;
1312+ } while ((i <= p->end) && (p->end != -1));
1313+ }
1314+
1315+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
1316+}
1317+
1318+void __init pxa3xx_init_mfp(void)
1319+{
1320+ memset(mfp_table, 0, sizeof(mfp_table));
1321+}
1322--- linux-2.6.23.orig/arch/arm/mach-pxa/pxa25x.c
1323+++ linux-2.6.23/arch/arm/mach-pxa/pxa25x.c
1324@@ -30,6 +30,7 @@
1325
1326 #include "generic.h"
1327 #include "devices.h"
1328+#include "clock.h"
1329
1330 /*
1331 * Various clock factors driven by the CCCR register.
1332@@ -53,7 +54,7 @@
1333 * We assume these values have been applied via a fcs.
1334 * If info is not 0 we also display the current settings.
1335 */
1336-unsigned int get_clk_frequency_khz(int info)
1337+unsigned int pxa25x_get_clk_frequency_khz(int info)
1338 {
1339 unsigned long cccr, turbo;
1340 unsigned int l, L, m, M, n2, N;
1341@@ -86,27 +87,48 @@
1342 return (turbo & 1) ? (N/1000) : (M/1000);
1343 }
1344
1345-EXPORT_SYMBOL(get_clk_frequency_khz);
1346-
1347 /*
1348 * Return the current memory clock frequency in units of 10kHz
1349 */
1350-unsigned int get_memclk_frequency_10khz(void)
1351+unsigned int pxa25x_get_memclk_frequency_10khz(void)
1352 {
1353 return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
1354 }
1355
1356-EXPORT_SYMBOL(get_memclk_frequency_10khz);
1357-
1358-/*
1359- * Return the current LCD clock frequency in units of 10kHz
1360- */
1361-unsigned int get_lcdclk_frequency_10khz(void)
1362+static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk)
1363 {
1364- return get_memclk_frequency_10khz();
1365+ return pxa25x_get_memclk_frequency_10khz() * 10000;
1366 }
1367
1368-EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
1369+static const struct clkops clk_pxa25x_lcd_ops = {
1370+ .enable = clk_cken_enable,
1371+ .disable = clk_cken_disable,
1372+ .getrate = clk_pxa25x_lcd_getrate,
1373+};
1374+
1375+/*
1376+ * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
1377+ * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
1378+ * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
1379+ */
1380+static struct clk pxa25x_clks[] = {
1381+ INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
1382+ INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev),
1383+ INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
1384+ INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
1385+ INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
1386+ INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
1387+ INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
1388+ INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
1389+ /*
1390+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
1391+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
1392+ INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL),
1393+ INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL),
1394+ INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL),
1395+ */
1396+ INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
1397+};
1398
1399 #ifdef CONFIG_PM
1400
1401@@ -207,10 +229,52 @@
1402 }
1403 #endif
1404
1405+/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
1406+ */
1407+
1408+static int pxa25x_set_wake(unsigned int irq, unsigned int on)
1409+{
1410+ int gpio = IRQ_TO_GPIO(irq);
1411+ uint32_t gpio_bit, mask = 0;
1412+
1413+ if (gpio >= 0 && gpio <= 15) {
1414+ gpio_bit = GPIO_bit(gpio);
1415+ mask = gpio_bit;
1416+ if (on) {
1417+ if (GRER(gpio) | gpio_bit)
1418+ PRER |= gpio_bit;
1419+ else
1420+ PRER &= ~gpio_bit;
1421+
1422+ if (GFER(gpio) | gpio_bit)
1423+ PFER |= gpio_bit;
1424+ else
1425+ PFER &= ~gpio_bit;
1426+ }
1427+ goto set_pwer;
1428+ }
1429+
1430+ if (irq == IRQ_RTCAlrm) {
1431+ mask = PWER_RTC;
1432+ goto set_pwer;
1433+ }
1434+
1435+ return -EINVAL;
1436+
1437+set_pwer:
1438+ if (on)
1439+ PWER |= mask;
1440+ else
1441+ PWER &=~mask;
1442+
1443+ return 0;
1444+}
1445+
1446 void __init pxa25x_init_irq(void)
1447 {
1448 pxa_init_irq_low();
1449 pxa_init_irq_gpio(85);
1450+ pxa_init_irq_set_wake(pxa25x_set_wake);
1451 }
1452
1453 static struct platform_device *pxa25x_devices[] __initdata = {
1454@@ -231,6 +295,8 @@
1455 int ret = 0;
1456
1457 if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
1458+ clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks));
1459+
1460 if ((ret = pxa_init_dma(16)))
1461 return ret;
1462 #ifdef CONFIG_PM
1463--- linux-2.6.23.orig/arch/arm/mach-pxa/pxa27x.c
1464+++ linux-2.6.23/arch/arm/mach-pxa/pxa27x.c
1465@@ -27,6 +27,7 @@
1466
1467 #include "generic.h"
1468 #include "devices.h"
1469+#include "clock.h"
1470
1471 /* Crystal clock: 13MHz */
1472 #define BASE_CLK 13000000
1473@@ -36,7 +37,7 @@
1474 * We assume these values have been applied via a fcs.
1475 * If info is not 0 we also display the current settings.
1476 */
1477-unsigned int get_clk_frequency_khz( int info)
1478+unsigned int pxa27x_get_clk_frequency_khz(int info)
1479 {
1480 unsigned long ccsr, clkcfg;
1481 unsigned int l, L, m, M, n2, N, S;
1482@@ -79,7 +80,7 @@
1483 * Return the current mem clock frequency in units of 10kHz as
1484 * reflected by CCCR[A], B, and L
1485 */
1486-unsigned int get_memclk_frequency_10khz(void)
1487+unsigned int pxa27x_get_memclk_frequency_10khz(void)
1488 {
1489 unsigned long ccsr, clkcfg;
1490 unsigned int l, L, m, M;
1491@@ -104,7 +105,7 @@
1492 /*
1493 * Return the current LCD clock frequency in units of 10kHz as
1494 */
1495-unsigned int get_lcdclk_frequency_10khz(void)
1496+static unsigned int pxa27x_get_lcdclk_frequency_10khz(void)
1497 {
1498 unsigned long ccsr;
1499 unsigned int l, L, k, K;
1500@@ -120,9 +121,47 @@
1501 return (K / 10000);
1502 }
1503
1504-EXPORT_SYMBOL(get_clk_frequency_khz);
1505-EXPORT_SYMBOL(get_memclk_frequency_10khz);
1506-EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
1507+static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
1508+{
1509+ return pxa27x_get_lcdclk_frequency_10khz() * 10000;
1510+}
1511+
1512+static const struct clkops clk_pxa27x_lcd_ops = {
1513+ .enable = clk_cken_enable,
1514+ .disable = clk_cken_disable,
1515+ .getrate = clk_pxa27x_lcd_getrate,
1516+};
1517+
1518+static struct clk pxa27x_clks[] = {
1519+ INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev),
1520+ INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL),
1521+
1522+ INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
1523+ INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
1524+ INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
1525+
1526+ INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev),
1527+ INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
1528+ INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev),
1529+ INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev),
1530+ INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev),
1531+
1532+ INIT_CKEN("USBCLK", USB, 48000000, 0, &pxa27x_device_ohci.dev),
1533+ INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
1534+ INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
1535+
1536+ /*
1537+ INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
1538+ INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL),
1539+ INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL),
1540+ INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL),
1541+ INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
1542+ INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
1543+ INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
1544+ INIT_CKEN("IMCLK", IM, 0, 0, NULL),
1545+ INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL),
1546+ */
1547+};
1548
1549 #ifdef CONFIG_PM
1550
1551@@ -269,6 +308,69 @@
1552 }
1553 #endif
1554
1555+/* PXA27x: Various gpios can issue wakeup events. This logic only
1556+ * handles the simple cases, not the WEMUX2 and WEMUX3 options
1557+ */
1558+#define PXA27x_GPIO_NOWAKE_MASK \
1559+ ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
1560+#define WAKEMASK(gpio) \
1561+ (((gpio) <= 15) \
1562+ ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
1563+ : ((gpio == 35) ? (1 << 24) : 0))
1564+
1565+static int pxa27x_set_wake(unsigned int irq, unsigned int on)
1566+{
1567+ int gpio = IRQ_TO_GPIO(irq);
1568+ uint32_t mask;
1569+
1570+ if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) {
1571+ if (WAKEMASK(gpio) == 0)
1572+ return -EINVAL;
1573+
1574+ mask = WAKEMASK(gpio);
1575+
1576+ if (on) {
1577+ if (GRER(gpio) | GPIO_bit(gpio))
1578+ PRER |= mask;
1579+ else
1580+ PRER &= ~mask;
1581+
1582+ if (GFER(gpio) | GPIO_bit(gpio))
1583+ PFER |= mask;
1584+ else
1585+ PFER &= ~mask;
1586+ }
1587+ goto set_pwer;
1588+ }
1589+
1590+ switch (irq) {
1591+ case IRQ_RTCAlrm:
1592+ mask = PWER_RTC;
1593+ break;
1594+ case IRQ_USB:
1595+ mask = 1u << 26;
1596+ break;
1597+ default:
1598+ return -EINVAL;
1599+ }
1600+
1601+set_pwer:
1602+ if (on)
1603+ PWER |= mask;
1604+ else
1605+ PWER &=~mask;
1606+
1607+ return 0;
1608+}
1609+
1610+void __init pxa27x_init_irq(void)
1611+{
1612+ pxa_init_irq_low();
1613+ pxa_init_irq_high();
1614+ pxa_init_irq_gpio(128);
1615+ pxa_init_irq_set_wake(pxa27x_set_wake);
1616+}
1617+
1618 /*
1619 * device registration specific to PXA27x.
1620 */
1621@@ -288,7 +390,7 @@
1622 },
1623 };
1624
1625-static struct platform_device pxa27x_device_ohci = {
1626+struct platform_device pxa27x_device_ohci = {
1627 .name = "pxa27x-ohci",
1628 .id = -1,
1629 .dev = {
1630@@ -316,7 +418,7 @@
1631 },
1632 };
1633
1634-static struct platform_device pxa27x_device_i2c_power = {
1635+struct platform_device pxa27x_device_i2c_power = {
1636 .name = "pxa2xx-i2c",
1637 .id = 1,
1638 .resource = i2c_power_resources,
1639@@ -338,17 +440,12 @@
1640 &pxa27x_device_ohci,
1641 };
1642
1643-void __init pxa27x_init_irq(void)
1644-{
1645- pxa_init_irq_low();
1646- pxa_init_irq_high();
1647- pxa_init_irq_gpio(128);
1648-}
1649-
1650 static int __init pxa27x_init(void)
1651 {
1652 int ret = 0;
1653 if (cpu_is_pxa27x()) {
1654+ clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks));
1655+
1656 if ((ret = pxa_init_dma(32)))
1657 return ret;
1658 #ifdef CONFIG_PM
1659--- /dev/null
1660+++ linux-2.6.23/arch/arm/mach-pxa/pxa300.c
1661@@ -0,0 +1,93 @@
1662+/*
1663+ * linux/arch/arm/mach-pxa/pxa300.c
1664+ *
1665+ * Code specific to PXA300/PXA310
1666+ *
1667+ * Copyright (C) 2007 Marvell Internation Ltd.
1668+ *
1669+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
1670+ * initial version
1671+ *
1672+ * This program is free software; you can redistribute it and/or modify
1673+ * it under the terms of the GNU General Public License version 2 as
1674+ * published by the Free Software Foundation.
1675+ */
1676+
1677+#include <linux/module.h>
1678+#include <linux/kernel.h>
1679+
1680+#include <asm/hardware.h>
1681+#include <asm/arch/mfp-pxa300.h>
1682+
1683+static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
1684+
1685+ MFP_ADDR_X(GPIO0, GPIO2, 0x00b4),
1686+ MFP_ADDR_X(GPIO3, GPIO26, 0x027c),
1687+ MFP_ADDR_X(GPIO27, GPIO127, 0x0400),
1688+ MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec),
1689+
1690+ MFP_ADDR(nBE0, 0x0204),
1691+ MFP_ADDR(nBE1, 0x0208),
1692+
1693+ MFP_ADDR(nLUA, 0x0244),
1694+ MFP_ADDR(nLLA, 0x0254),
1695+
1696+ MFP_ADDR(DF_CLE_nOE, 0x0240),
1697+ MFP_ADDR(DF_nRE_nOE, 0x0200),
1698+ MFP_ADDR(DF_ALE_nWE, 0x020C),
1699+ MFP_ADDR(DF_INT_RnB, 0x00C8),
1700+ MFP_ADDR(DF_nCS0, 0x0248),
1701+ MFP_ADDR(DF_nCS1, 0x0278),
1702+ MFP_ADDR(DF_nWE, 0x00CC),
1703+
1704+ MFP_ADDR(DF_ADDR0, 0x0210),
1705+ MFP_ADDR(DF_ADDR1, 0x0214),
1706+ MFP_ADDR(DF_ADDR2, 0x0218),
1707+ MFP_ADDR(DF_ADDR3, 0x021C),
1708+
1709+ MFP_ADDR(DF_IO0, 0x0220),
1710+ MFP_ADDR(DF_IO1, 0x0228),
1711+ MFP_ADDR(DF_IO2, 0x0230),
1712+ MFP_ADDR(DF_IO3, 0x0238),
1713+ MFP_ADDR(DF_IO4, 0x0258),
1714+ MFP_ADDR(DF_IO5, 0x0260),
1715+ MFP_ADDR(DF_IO6, 0x0268),
1716+ MFP_ADDR(DF_IO7, 0x0270),
1717+ MFP_ADDR(DF_IO8, 0x0224),
1718+ MFP_ADDR(DF_IO9, 0x022C),
1719+ MFP_ADDR(DF_IO10, 0x0234),
1720+ MFP_ADDR(DF_IO11, 0x023C),
1721+ MFP_ADDR(DF_IO12, 0x025C),
1722+ MFP_ADDR(DF_IO13, 0x0264),
1723+ MFP_ADDR(DF_IO14, 0x026C),
1724+ MFP_ADDR(DF_IO15, 0x0274),
1725+
1726+ MFP_ADDR_END,
1727+};
1728+
1729+/* override pxa300 MFP register addresses */
1730+static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
1731+ MFP_ADDR_X(GPIO30, GPIO98, 0x0418),
1732+ MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C),
1733+
1734+ MFP_ADDR(ULPI_STP, 0x040C),
1735+ MFP_ADDR(ULPI_NXT, 0x0410),
1736+ MFP_ADDR(ULPI_DIR, 0x0414),
1737+
1738+ MFP_ADDR_END,
1739+};
1740+
1741+static int __init pxa300_init(void)
1742+{
1743+ if (cpu_is_pxa300() || cpu_is_pxa310()) {
1744+ pxa3xx_init_mfp();
1745+ pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
1746+ }
1747+
1748+ if (cpu_is_pxa310())
1749+ pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
1750+
1751+ return 0;
1752+}
1753+
1754+core_initcall(pxa300_init);
1755--- /dev/null
1756+++ linux-2.6.23/arch/arm/mach-pxa/pxa320.c
1757@@ -0,0 +1,88 @@
1758+/*
1759+ * linux/arch/arm/mach-pxa/pxa320.c
1760+ *
1761+ * Code specific to PXA320
1762+ *
1763+ * Copyright (C) 2007 Marvell Internation Ltd.
1764+ *
1765+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
1766+ * initial version
1767+ *
1768+ * This program is free software; you can redistribute it and/or modify
1769+ * it under the terms of the GNU General Public License version 2 as
1770+ * published by the Free Software Foundation.
1771+ */
1772+
1773+#include <linux/module.h>
1774+#include <linux/kernel.h>
1775+
1776+#include <asm/hardware.h>
1777+#include <asm/arch/mfp.h>
1778+#include <asm/arch/mfp-pxa320.h>
1779+
1780+static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
1781+
1782+ MFP_ADDR_X(GPIO0, GPIO4, 0x0124),
1783+ MFP_ADDR_X(GPIO5, GPIO26, 0x028C),
1784+ MFP_ADDR_X(GPIO27, GPIO62, 0x0400),
1785+ MFP_ADDR_X(GPIO63, GPIO73, 0x04B4),
1786+ MFP_ADDR_X(GPIO74, GPIO98, 0x04F0),
1787+ MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
1788+ MFP_ADDR_X(GPIO0_2, GPIO5_2, 0x0674),
1789+ MFP_ADDR_X(GPIO6_2, GPIO13_2, 0x0494),
1790+ MFP_ADDR_X(GPIO14_2, GPIO17_2, 0x04E0),
1791+
1792+ MFP_ADDR(nXCVREN, 0x0138),
1793+ MFP_ADDR(DF_CLE_nOE, 0x0204),
1794+ MFP_ADDR(DF_nADV1_ALE, 0x0208),
1795+ MFP_ADDR(DF_SCLK_S, 0x020C),
1796+ MFP_ADDR(DF_SCLK_E, 0x0210),
1797+ MFP_ADDR(nBE0, 0x0214),
1798+ MFP_ADDR(nBE1, 0x0218),
1799+ MFP_ADDR(DF_nADV2_ALE, 0x021C),
1800+ MFP_ADDR(DF_INT_RnB, 0x0220),
1801+ MFP_ADDR(DF_nCS0, 0x0224),
1802+ MFP_ADDR(DF_nCS1, 0x0228),
1803+ MFP_ADDR(DF_nWE, 0x022C),
1804+ MFP_ADDR(DF_nRE_nOE, 0x0230),
1805+ MFP_ADDR(nLUA, 0x0234),
1806+ MFP_ADDR(nLLA, 0x0238),
1807+ MFP_ADDR(DF_ADDR0, 0x023C),
1808+ MFP_ADDR(DF_ADDR1, 0x0240),
1809+ MFP_ADDR(DF_ADDR2, 0x0244),
1810+ MFP_ADDR(DF_ADDR3, 0x0248),
1811+ MFP_ADDR(DF_IO0, 0x024C),
1812+ MFP_ADDR(DF_IO8, 0x0250),
1813+ MFP_ADDR(DF_IO1, 0x0254),
1814+ MFP_ADDR(DF_IO9, 0x0258),
1815+ MFP_ADDR(DF_IO2, 0x025C),
1816+ MFP_ADDR(DF_IO10, 0x0260),
1817+ MFP_ADDR(DF_IO3, 0x0264),
1818+ MFP_ADDR(DF_IO11, 0x0268),
1819+ MFP_ADDR(DF_IO4, 0x026C),
1820+ MFP_ADDR(DF_IO12, 0x0270),
1821+ MFP_ADDR(DF_IO5, 0x0274),
1822+ MFP_ADDR(DF_IO13, 0x0278),
1823+ MFP_ADDR(DF_IO6, 0x027C),
1824+ MFP_ADDR(DF_IO14, 0x0280),
1825+ MFP_ADDR(DF_IO7, 0x0284),
1826+ MFP_ADDR(DF_IO15, 0x0288),
1827+
1828+ MFP_ADDR_END,
1829+};
1830+
1831+static void __init pxa320_init_mfp(void)
1832+{
1833+ pxa3xx_init_mfp();
1834+ pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
1835+}
1836+
1837+static int __init pxa320_init(void)
1838+{
1839+ if (cpu_is_pxa320())
1840+ pxa320_init_mfp();
1841+
1842+ return 0;
1843+}
1844+
1845+core_initcall(pxa320_init);
1846--- /dev/null
1847+++ linux-2.6.23/arch/arm/mach-pxa/pxa3xx.c
1848@@ -0,0 +1,216 @@
1849+/*
1850+ * linux/arch/arm/mach-pxa/pxa3xx.c
1851+ *
1852+ * code specific to pxa3xx aka Monahans
1853+ *
1854+ * Copyright (C) 2006 Marvell International Ltd.
1855+ *
1856+ * 2007-09-02: eric miao <eric.y.miao@gmail.com>
1857+ * initial version
1858+ *
1859+ * This program is free software; you can redistribute it and/or modify
1860+ * it under the terms of the GNU General Public License version 2 as
1861+ * published by the Free Software Foundation.
1862+ */
1863+
1864+#include <linux/module.h>
1865+#include <linux/kernel.h>
1866+#include <linux/init.h>
1867+#include <linux/pm.h>
1868+#include <linux/platform_device.h>
1869+#include <linux/irq.h>
1870+
1871+#include <asm/hardware.h>
1872+#include <asm/arch/pxa3xx-regs.h>
1873+#include <asm/arch/ohci.h>
1874+#include <asm/arch/pm.h>
1875+#include <asm/arch/dma.h>
1876+#include <asm/arch/ssp.h>
1877+
1878+#include "generic.h"
1879+#include "devices.h"
1880+#include "clock.h"
1881+
1882+/* Crystal clock: 13MHz */
1883+#define BASE_CLK 13000000
1884+
1885+/* Ring Oscillator Clock: 60MHz */
1886+#define RO_CLK 60000000
1887+
1888+#define ACCR_D0CS (1 << 26)
1889+
1890+/* crystal frequency to static memory controller multiplier (SMCFS) */
1891+static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
1892+
1893+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
1894+static unsigned char hss_mult[4] = { 8, 12, 16, 0 };
1895+
1896+/*
1897+ * Get the clock frequency as reflected by CCSR and the turbo flag.
1898+ * We assume these values have been applied via a fcs.
1899+ * If info is not 0 we also display the current settings.
1900+ */
1901+unsigned int pxa3xx_get_clk_frequency_khz(int info)
1902+{
1903+ unsigned long acsr, xclkcfg;
1904+ unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
1905+
1906+ /* Read XCLKCFG register turbo bit */
1907+ __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
1908+ t = xclkcfg & 0x1;
1909+
1910+ acsr = ACSR;
1911+
1912+ xl = acsr & 0x1f;
1913+ xn = (acsr >> 8) & 0x7;
1914+ hss = (acsr >> 14) & 0x3;
1915+
1916+ XL = xl * BASE_CLK;
1917+ XN = xn * XL;
1918+
1919+ ro = acsr & ACCR_D0CS;
1920+
1921+ CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
1922+ HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
1923+
1924+ if (info) {
1925+ pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
1926+ RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
1927+ (ro) ? "" : "in");
1928+ pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
1929+ XL / 1000000, (XL % 1000000) / 10000, xl);
1930+ pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
1931+ XN / 1000000, (XN % 1000000) / 10000, xn,
1932+ (t) ? "" : "in");
1933+ pr_info("HSIO bus clock: %d.%02dMHz\n",
1934+ HSS / 1000000, (HSS % 1000000) / 10000);
1935+ }
1936+
1937+ return CLK;
1938+}
1939+
1940+/*
1941+ * Return the current static memory controller clock frequency
1942+ * in units of 10kHz
1943+ */
1944+unsigned int pxa3xx_get_memclk_frequency_10khz(void)
1945+{
1946+ unsigned long acsr;
1947+ unsigned int smcfs, clk = 0;
1948+
1949+ acsr = ACSR;
1950+
1951+ smcfs = (acsr >> 23) & 0x7;
1952+ clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK;
1953+
1954+ return (clk / 10000);
1955+}
1956+
1957+/*
1958+ * Return the current HSIO bus clock frequency
1959+ */
1960+static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
1961+{
1962+ unsigned long acsr;
1963+ unsigned int hss, hsio_clk;
1964+
1965+ acsr = ACSR;
1966+
1967+ hss = (acsr >> 14) & 0x3;
1968+ hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
1969+
1970+ return hsio_clk;
1971+}
1972+
1973+static void clk_pxa3xx_cken_enable(struct clk *clk)
1974+{
1975+ unsigned long mask = 1ul << (clk->cken & 0x1f);
1976+
1977+ local_irq_disable();
1978+
1979+ if (clk->cken < 32)
1980+ CKENA |= mask;
1981+ else
1982+ CKENB |= mask;
1983+
1984+ local_irq_enable();
1985+}
1986+
1987+static void clk_pxa3xx_cken_disable(struct clk *clk)
1988+{
1989+ unsigned long mask = 1ul << (clk->cken & 0x1f);
1990+
1991+ local_irq_disable();
1992+
1993+ if (clk->cken < 32)
1994+ CKENA &= ~mask;
1995+ else
1996+ CKENB &= ~mask;
1997+
1998+ local_irq_enable();
1999+}
2000+
2001+static const struct clkops clk_pxa3xx_hsio_ops = {
2002+ .enable = clk_pxa3xx_cken_enable,
2003+ .disable = clk_pxa3xx_cken_disable,
2004+ .getrate = clk_pxa3xx_hsio_getrate,
2005+};
2006+
2007+static struct clk pxa3xx_clks[] = {
2008+ INIT_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
2009+ INIT_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
2010+
2011+ INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
2012+ INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
2013+ INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
2014+
2015+ INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
2016+ INIT_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
2017+};
2018+
2019+void __init pxa3xx_init_irq(void)
2020+{
2021+ /* enable CP6 access */
2022+ u32 value;
2023+ __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
2024+ value |= (1 << 6);
2025+ __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
2026+
2027+ pxa_init_irq_low();
2028+ pxa_init_irq_high();
2029+ pxa_init_irq_gpio(128);
2030+}
2031+
2032+/*
2033+ * device registration specific to PXA3xx.
2034+ */
2035+
2036+static struct platform_device *devices[] __initdata = {
2037+ &pxa_device_mci,
2038+ &pxa_device_udc,
2039+ &pxa_device_fb,
2040+ &pxa_device_ffuart,
2041+ &pxa_device_btuart,
2042+ &pxa_device_stuart,
2043+ &pxa_device_i2c,
2044+ &pxa_device_i2s,
2045+ &pxa_device_ficp,
2046+ &pxa_device_rtc,
2047+};
2048+
2049+static int __init pxa3xx_init(void)
2050+{
2051+ int ret = 0;
2052+
2053+ if (cpu_is_pxa3xx()) {
2054+ clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks));
2055+
2056+ if ((ret = pxa_init_dma(32)))
2057+ return ret;
2058+
2059+ return platform_add_devices(devices, ARRAY_SIZE(devices));
2060+ }
2061+ return 0;
2062+}
2063+
2064+subsys_initcall(pxa3xx_init);
2065--- linux-2.6.23.orig/arch/arm/mach-pxa/time.c
2066+++ linux-2.6.23/arch/arm/mach-pxa/time.c
2067@@ -16,10 +16,48 @@
2068 #include <linux/init.h>
2069 #include <linux/interrupt.h>
2070 #include <linux/clockchips.h>
2071+#include <linux/sched.h>
2072
2073+#include <asm/div64.h>
2074+#include <asm/cnt32_to_63.h>
2075 #include <asm/mach/irq.h>
2076 #include <asm/mach/time.h>
2077 #include <asm/arch/pxa-regs.h>
2078+#include <asm/mach-types.h>
2079+
2080+/*
2081+ * This is PXA's sched_clock implementation. This has a resolution
2082+ * of at least 308 ns and a maximum value of 208 days.
2083+ *
2084+ * The return value is guaranteed to be monotonic in that range as
2085+ * long as there is always less than 582 seconds between successive
2086+ * calls to sched_clock() which should always be the case in practice.
2087+ */
2088+
2089+#define OSCR2NS_SCALE_FACTOR 10
2090+
2091+static unsigned long oscr2ns_scale;
2092+
2093+static void __init set_oscr2ns_scale(unsigned long oscr_rate)
2094+{
2095+ unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR;
2096+ do_div(v, oscr_rate);
2097+ oscr2ns_scale = v;
2098+ /*
2099+ * We want an even value to automatically clear the top bit
2100+ * returned by cnt32_to_63() without an additional run time
2101+ * instruction. So if the LSB is 1 then round it up.
2102+ */
2103+ if (oscr2ns_scale & 1)
2104+ oscr2ns_scale++;
2105+}
2106+
2107+unsigned long long sched_clock(void)
2108+{
2109+ unsigned long long v = cnt32_to_63(OSCR);
2110+ return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
2111+}
2112+
2113
2114 static irqreturn_t
2115 pxa_ost0_interrupt(int irq, void *dev_id)
2116@@ -149,18 +187,29 @@
2117
2118 static void __init pxa_timer_init(void)
2119 {
2120+ unsigned long clock_tick_rate;
2121+
2122 OIER = 0;
2123 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
2124
2125+ if (cpu_is_pxa21x() || cpu_is_pxa25x())
2126+ clock_tick_rate = 3686400;
2127+ else if (machine_is_mainstone())
2128+ clock_tick_rate = 3249600;
2129+ else
2130+ clock_tick_rate = 3250000;
2131+
2132+ set_oscr2ns_scale(clock_tick_rate);
2133+
2134 ckevt_pxa_osmr0.mult =
2135- div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
2136+ div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
2137 ckevt_pxa_osmr0.max_delta_ns =
2138 clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
2139 ckevt_pxa_osmr0.min_delta_ns =
2140 clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1;
2141
2142 cksrc_pxa_oscr0.mult =
2143- clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift);
2144+ clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
2145
2146 setup_irq(IRQ_OST0, &pxa_ost0_irq);
2147
2148--- /dev/null
2149+++ linux-2.6.23/arch/arm/mach-pxa/zylonite.c
2150@@ -0,0 +1,184 @@
2151+/*
2152+ * linux/arch/arm/mach-pxa/zylonite.c
2153+ *
2154+ * Support for the PXA3xx Development Platform (aka Zylonite)
2155+ *
2156+ * Copyright (C) 2006 Marvell International Ltd.
2157+ *
2158+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
2159+ * rewrite to align with latest kernel
2160+ *
2161+ * This program is free software; you can redistribute it and/or modify
2162+ * it under the terms of the GNU General Public License version 2 as
2163+ * published by the Free Software Foundation.
2164+ */
2165+
2166+#include <linux/module.h>
2167+#include <linux/kernel.h>
2168+#include <linux/interrupt.h>
2169+#include <linux/init.h>
2170+#include <linux/platform_device.h>
2171+
2172+#include <asm/mach-types.h>
2173+#include <asm/mach/arch.h>
2174+#include <asm/hardware.h>
2175+#include <asm/arch/gpio.h>
2176+#include <asm/arch/pxafb.h>
2177+#include <asm/arch/zylonite.h>
2178+
2179+#include "generic.h"
2180+
2181+int gpio_backlight;
2182+int gpio_eth_irq;
2183+
2184+int lcd_id;
2185+int lcd_orientation;
2186+
2187+static struct resource smc91x_resources[] = {
2188+ [0] = {
2189+ .start = ZYLONITE_ETH_PHYS + 0x300,
2190+ .end = ZYLONITE_ETH_PHYS + 0xfffff,
2191+ .flags = IORESOURCE_MEM,
2192+ },
2193+ [1] = {
2194+ .start = -1, /* for run-time assignment */
2195+ .end = -1,
2196+ .flags = IORESOURCE_IRQ,
2197+ }
2198+};
2199+
2200+static struct platform_device smc91x_device = {
2201+ .name = "smc91x",
2202+ .id = 0,
2203+ .num_resources = ARRAY_SIZE(smc91x_resources),
2204+ .resource = smc91x_resources,
2205+};
2206+
2207+#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
2208+static void zylonite_backlight_power(int on)
2209+{
2210+ gpio_set_value(gpio_backlight, on);
2211+}
2212+
2213+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
2214+ .pixclock = 110000,
2215+ .xres = 240,
2216+ .yres = 320,
2217+ .bpp = 16,
2218+ .hsync_len = 4,
2219+ .left_margin = 6,
2220+ .right_margin = 4,
2221+ .vsync_len = 2,
2222+ .upper_margin = 2,
2223+ .lower_margin = 3,
2224+ .sync = FB_SYNC_VERT_HIGH_ACT,
2225+};
2226+
2227+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
2228+ .pixclock = 50000,
2229+ .xres = 640,
2230+ .yres = 480,
2231+ .bpp = 16,
2232+ .hsync_len = 1,
2233+ .left_margin = 0x9f,
2234+ .right_margin = 1,
2235+ .vsync_len = 44,
2236+ .upper_margin = 0,
2237+ .lower_margin = 0,
2238+ .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
2239+};
2240+
2241+static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
2242+ .num_modes = 1,
2243+ .lccr0 = LCCR0_Act,
2244+ .lccr3 = LCCR3_PCP,
2245+ .pxafb_backlight_power = zylonite_backlight_power,
2246+};
2247+
2248+static struct pxafb_mode_info sharp_ls037_modes[] = {
2249+ [0] = {
2250+ .pixclock = 158000,
2251+ .xres = 240,
2252+ .yres = 320,
2253+ .bpp = 16,
2254+ .hsync_len = 4,
2255+ .left_margin = 39,
2256+ .right_margin = 39,
2257+ .vsync_len = 1,
2258+ .upper_margin = 2,
2259+ .lower_margin = 3,
2260+ .sync = 0,
2261+ },
2262+ [1] = {
2263+ .pixclock = 39700,
2264+ .xres = 480,
2265+ .yres = 640,
2266+ .bpp = 16,
2267+ .hsync_len = 8,
2268+ .left_margin = 81,
2269+ .right_margin = 81,
2270+ .vsync_len = 1,
2271+ .upper_margin = 2,
2272+ .lower_margin = 7,
2273+ .sync = 0,
2274+ },
2275+};
2276+
2277+static struct pxafb_mach_info zylonite_sharp_lcd_info = {
2278+ .modes = sharp_ls037_modes,
2279+ .num_modes = 2,
2280+ .lccr0 = LCCR0_Act,
2281+ .lccr3 = LCCR3_PCP | LCCR3_HSP | LCCR3_VSP,
2282+ .pxafb_backlight_power = zylonite_backlight_power,
2283+};
2284+
2285+static void __init zylonite_init_lcd(void)
2286+{
2287+ /* backlight GPIO: output, default on */
2288+ gpio_direction_output(gpio_backlight, 1);
2289+
2290+ if (lcd_id & 0x20) {
2291+ set_pxa_fb_info(&zylonite_sharp_lcd_info);
2292+ return;
2293+ }
2294+
2295+ /* legacy LCD panels, it would be handy here if LCD panel type can
2296+ * be decided at run-time
2297+ */
2298+ if (1)
2299+ zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
2300+ else
2301+ zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
2302+
2303+ set_pxa_fb_info(&zylonite_toshiba_lcd_info);
2304+}
2305+#else
2306+static inline void zylonite_init_lcd(void) {}
2307+#endif
2308+
2309+static void __init zylonite_init(void)
2310+{
2311+ /* board-processor specific initialization */
2312+ zylonite_pxa300_init();
2313+ zylonite_pxa320_init();
2314+
2315+ /*
2316+ * Note: We depend that the bootloader set
2317+ * the correct value to MSC register for SMC91x.
2318+ */
2319+ smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
2320+ smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
2321+ platform_device_register(&smc91x_device);
2322+
2323+ zylonite_init_lcd();
2324+}
2325+
2326+MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
2327+ .phys_io = 0x40000000,
2328+ .boot_params = 0xa0000100,
2329+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
2330+ .map_io = pxa_map_io,
2331+ .init_irq = pxa3xx_init_irq,
2332+ .timer = &pxa_timer,
2333+ .init_machine = zylonite_init,
2334+MACHINE_END
2335--- /dev/null
2336+++ linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c
2337@@ -0,0 +1,188 @@
2338+/*
2339+ * linux/arch/arm/mach-pxa/zylonite_pxa300.c
2340+ *
2341+ * PXA300/PXA310 specific support code for the
2342+ * PXA3xx Development Platform (aka Zylonite)
2343+ *
2344+ * Copyright (C) 2007 Marvell Internation Ltd.
2345+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
2346+ * initial version
2347+ *
2348+ * This program is free software; you can redistribute it and/or modify
2349+ * it under the terms of the GNU General Public License version 2 as
2350+ * published by the Free Software Foundation.
2351+ */
2352+
2353+#include <linux/module.h>
2354+#include <linux/kernel.h>
2355+#include <linux/init.h>
2356+
2357+#include <asm/gpio.h>
2358+#include <asm/arch/mfp-pxa300.h>
2359+#include <asm/arch/zylonite.h>
2360+
2361+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
2362+
2363+/* PXA300/PXA310 common configurations */
2364+static mfp_cfg_t common_mfp_cfg[] __initdata = {
2365+ /* LCD */
2366+ GPIO54_LCD_LDD_0,
2367+ GPIO55_LCD_LDD_1,
2368+ GPIO56_LCD_LDD_2,
2369+ GPIO57_LCD_LDD_3,
2370+ GPIO58_LCD_LDD_4,
2371+ GPIO59_LCD_LDD_5,
2372+ GPIO60_LCD_LDD_6,
2373+ GPIO61_LCD_LDD_7,
2374+ GPIO62_LCD_LDD_8,
2375+ GPIO63_LCD_LDD_9,
2376+ GPIO64_LCD_LDD_10,
2377+ GPIO65_LCD_LDD_11,
2378+ GPIO66_LCD_LDD_12,
2379+ GPIO67_LCD_LDD_13,
2380+ GPIO68_LCD_LDD_14,
2381+ GPIO69_LCD_LDD_15,
2382+ GPIO70_LCD_LDD_16,
2383+ GPIO71_LCD_LDD_17,
2384+ GPIO72_LCD_FCLK,
2385+ GPIO73_LCD_LCLK,
2386+ GPIO74_LCD_PCLK,
2387+ GPIO75_LCD_BIAS,
2388+ GPIO76_LCD_VSYNC,
2389+ GPIO127_LCD_CS_N,
2390+
2391+ /* BTUART */
2392+ GPIO111_UART2_RTS,
2393+ GPIO112_UART2_RXD,
2394+ GPIO113_UART2_TXD,
2395+ GPIO114_UART2_CTS,
2396+
2397+ /* STUART */
2398+ GPIO109_UART3_TXD,
2399+ GPIO110_UART3_RXD,
2400+
2401+ /* AC97 */
2402+ GPIO23_AC97_nACRESET,
2403+ GPIO24_AC97_SYSCLK,
2404+ GPIO29_AC97_BITCLK,
2405+ GPIO25_AC97_SDATA_IN_0,
2406+ GPIO27_AC97_SDATA_OUT,
2407+ GPIO28_AC97_SYNC,
2408+
2409+ /* Keypad */
2410+ GPIO107_KP_DKIN_0,
2411+ GPIO108_KP_DKIN_1,
2412+ GPIO115_KP_MKIN_0,
2413+ GPIO116_KP_MKIN_1,
2414+ GPIO117_KP_MKIN_2,
2415+ GPIO118_KP_MKIN_3,
2416+ GPIO119_KP_MKIN_4,
2417+ GPIO120_KP_MKIN_5,
2418+ GPIO2_2_KP_MKIN_6,
2419+ GPIO3_2_KP_MKIN_7,
2420+ GPIO121_KP_MKOUT_0,
2421+ GPIO122_KP_MKOUT_1,
2422+ GPIO123_KP_MKOUT_2,
2423+ GPIO124_KP_MKOUT_3,
2424+ GPIO125_KP_MKOUT_4,
2425+ GPIO4_2_KP_MKOUT_5,
2426+ GPIO5_2_KP_MKOUT_6,
2427+ GPIO6_2_KP_MKOUT_7,
2428+};
2429+
2430+static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
2431+ /* FFUART */
2432+ GPIO30_UART1_RXD,
2433+ GPIO31_UART1_TXD,
2434+ GPIO32_UART1_CTS,
2435+ GPIO37_UART1_RTS,
2436+ GPIO33_UART1_DCD,
2437+ GPIO34_UART1_DSR,
2438+ GPIO35_UART1_RI,
2439+ GPIO36_UART1_DTR,
2440+
2441+ /* Ethernet */
2442+ GPIO2_nCS3,
2443+ GPIO99_GPIO,
2444+};
2445+
2446+static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
2447+ /* FFUART */
2448+ GPIO99_UART1_RXD,
2449+ GPIO100_UART1_TXD,
2450+ GPIO101_UART1_CTS,
2451+ GPIO106_UART1_RTS,
2452+
2453+ /* Ethernet */
2454+ GPIO2_nCS3,
2455+ GPIO102_GPIO,
2456+};
2457+
2458+#define NUM_LCD_DETECT_PINS 7
2459+
2460+static int lcd_detect_pins[] __initdata = {
2461+ MFP_PIN_GPIO71, /* LCD_LDD_17 - ORIENT */
2462+ MFP_PIN_GPIO70, /* LCD_LDD_16 - LCDID[5] */
2463+ MFP_PIN_GPIO75, /* LCD_BIAS - LCDID[4] */
2464+ MFP_PIN_GPIO73, /* LCD_LCLK - LCDID[3] */
2465+ MFP_PIN_GPIO72, /* LCD_FCLK - LCDID[2] */
2466+ MFP_PIN_GPIO127,/* LCD_CS_N - LCDID[1] */
2467+ MFP_PIN_GPIO76, /* LCD_VSYNC - LCDID[0] */
2468+};
2469+
2470+static void __init zylonite_detect_lcd_panel(void)
2471+{
2472+ unsigned long mfpr_save[NUM_LCD_DETECT_PINS];
2473+ int i, gpio, id = 0;
2474+
2475+ /* save the original MFP settings of these pins and configure
2476+ * them as GPIO Input, DS01X, Pull Neither, Edge Clear
2477+ */
2478+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
2479+ mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
2480+ pxa3xx_mfp_write(lcd_detect_pins[i], 0x8440);
2481+ }
2482+
2483+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
2484+ id = id << 1;
2485+ gpio = mfp_to_gpio(lcd_detect_pins[i]);
2486+ gpio_direction_input(gpio);
2487+
2488+ if (gpio_get_value(gpio))
2489+ id = id | 0x1;
2490+ }
2491+
2492+ /* lcd id, flush out bit 1 */
2493+ lcd_id = id & 0x3d;
2494+
2495+ /* lcd orientation, portrait or landscape */
2496+ lcd_orientation = (id >> 6) & 0x1;
2497+
2498+ /* restore the original MFP settings */
2499+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++)
2500+ pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
2501+}
2502+
2503+void __init zylonite_pxa300_init(void)
2504+{
2505+ if (cpu_is_pxa300() || cpu_is_pxa310()) {
2506+ /* initialize MFP */
2507+ pxa3xx_mfp_config(ARRAY_AND_SIZE(common_mfp_cfg));
2508+
2509+ /* detect LCD panel */
2510+ zylonite_detect_lcd_panel();
2511+
2512+ /* GPIO pin assignment */
2513+ gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
2514+ }
2515+
2516+ if (cpu_is_pxa300()) {
2517+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_mfp_cfg));
2518+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO99);
2519+ }
2520+
2521+ if (cpu_is_pxa310()) {
2522+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
2523+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
2524+ }
2525+}
2526--- /dev/null
2527+++ linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa320.c
2528@@ -0,0 +1,173 @@
2529+/*
2530+ * linux/arch/arm/mach-pxa/zylonite_pxa320.c
2531+ *
2532+ * PXA320 specific support code for the
2533+ * PXA3xx Development Platform (aka Zylonite)
2534+ *
2535+ * Copyright (C) 2007 Marvell Internation Ltd.
2536+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
2537+ * initial version
2538+ *
2539+ * This program is free software; you can redistribute it and/or modify
2540+ * it under the terms of the GNU General Public License version 2 as
2541+ * published by the Free Software Foundation.
2542+ */
2543+
2544+#include <linux/module.h>
2545+#include <linux/kernel.h>
2546+#include <linux/init.h>
2547+
2548+#include <asm/arch/gpio.h>
2549+#include <asm/arch/mfp-pxa320.h>
2550+#include <asm/arch/zylonite.h>
2551+
2552+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
2553+
2554+static mfp_cfg_t mfp_cfg[] __initdata = {
2555+ /* LCD */
2556+ GPIO6_2_LCD_LDD_0,
2557+ GPIO7_2_LCD_LDD_1,
2558+ GPIO8_2_LCD_LDD_2,
2559+ GPIO9_2_LCD_LDD_3,
2560+ GPIO10_2_LCD_LDD_4,
2561+ GPIO11_2_LCD_LDD_5,
2562+ GPIO12_2_LCD_LDD_6,
2563+ GPIO13_2_LCD_LDD_7,
2564+ GPIO63_LCD_LDD_8,
2565+ GPIO64_LCD_LDD_9,
2566+ GPIO65_LCD_LDD_10,
2567+ GPIO66_LCD_LDD_11,
2568+ GPIO67_LCD_LDD_12,
2569+ GPIO68_LCD_LDD_13,
2570+ GPIO69_LCD_LDD_14,
2571+ GPIO70_LCD_LDD_15,
2572+ GPIO71_LCD_LDD_16,
2573+ GPIO72_LCD_LDD_17,
2574+ GPIO73_LCD_CS_N,
2575+ GPIO74_LCD_VSYNC,
2576+ GPIO14_2_LCD_FCLK,
2577+ GPIO15_2_LCD_LCLK,
2578+ GPIO16_2_LCD_PCLK,
2579+ GPIO17_2_LCD_BIAS,
2580+
2581+ /* FFUART */
2582+ GPIO41_UART1_RXD,
2583+ GPIO42_UART1_TXD,
2584+ GPIO43_UART1_CTS,
2585+ GPIO44_UART1_DCD,
2586+ GPIO45_UART1_DSR,
2587+ GPIO46_UART1_RI,
2588+ GPIO47_UART1_DTR,
2589+ GPIO48_UART1_RTS,
2590+
2591+ /* AC97 */
2592+ GPIO34_AC97_SYSCLK,
2593+ GPIO35_AC97_SDATA_IN_0,
2594+ GPIO37_AC97_SDATA_OUT,
2595+ GPIO38_AC97_SYNC,
2596+ GPIO39_AC97_BITCLK,
2597+ GPIO40_AC97_nACRESET,
2598+
2599+ /* I2C */
2600+ GPIO32_I2C_SCL,
2601+ GPIO33_I2C_SDA,
2602+
2603+ /* Keypad */
2604+ GPIO105_KP_DKIN_0,
2605+ GPIO106_KP_DKIN_1,
2606+ GPIO113_KP_MKIN_0,
2607+ GPIO114_KP_MKIN_1,
2608+ GPIO115_KP_MKIN_2,
2609+ GPIO116_KP_MKIN_3,
2610+ GPIO117_KP_MKIN_4,
2611+ GPIO118_KP_MKIN_5,
2612+ GPIO119_KP_MKIN_6,
2613+ GPIO120_KP_MKIN_7,
2614+ GPIO121_KP_MKOUT_0,
2615+ GPIO122_KP_MKOUT_1,
2616+ GPIO123_KP_MKOUT_2,
2617+ GPIO124_KP_MKOUT_3,
2618+ GPIO125_KP_MKOUT_4,
2619+ GPIO126_KP_MKOUT_5,
2620+ GPIO127_KP_MKOUT_6,
2621+ GPIO5_2_KP_MKOUT_7,
2622+
2623+ /* Ethernet */
2624+ GPIO4_nCS3,
2625+ GPIO90_GPIO,
2626+};
2627+
2628+#define NUM_LCD_DETECT_PINS 7
2629+
2630+static int lcd_detect_pins[] __initdata = {
2631+ MFP_PIN_GPIO72, /* LCD_LDD_17 - ORIENT */
2632+ MFP_PIN_GPIO71, /* LCD_LDD_16 - LCDID[5] */
2633+ MFP_PIN_GPIO17_2, /* LCD_BIAS - LCDID[4] */
2634+ MFP_PIN_GPIO15_2, /* LCD_LCLK - LCDID[3] */
2635+ MFP_PIN_GPIO14_2, /* LCD_FCLK - LCDID[2] */
2636+ MFP_PIN_GPIO73, /* LCD_CS_N - LCDID[1] */
2637+ MFP_PIN_GPIO74, /* LCD_VSYNC - LCDID[0] */
2638+ /*
2639+ * set the MFP_PIN_GPIO 14/15/17 to alternate function other than
2640+ * GPIO to avoid input level confliction with 14_2, 15_2, 17_2
2641+ */
2642+ MFP_PIN_GPIO14,
2643+ MFP_PIN_GPIO15,
2644+ MFP_PIN_GPIO17,
2645+};
2646+
2647+static int lcd_detect_mfpr[] __initdata = {
2648+ /* AF0, DS 1X, Pull Neither, Edge Clear */
2649+ 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440,
2650+ 0xc442, /* Backlight, Pull-Up, AF2 */
2651+ 0x8445, /* AF5 */
2652+ 0x8445, /* AF5 */
2653+};
2654+
2655+static void __init zylonite_detect_lcd_panel(void)
2656+{
2657+ unsigned long mfpr_save[ARRAY_SIZE(lcd_detect_pins)];
2658+ int i, gpio, id = 0;
2659+
2660+ /* save the original MFP settings of these pins and configure them
2661+ * as GPIO Input, DS01X, Pull Neither, Edge Clear
2662+ */
2663+ for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) {
2664+ mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
2665+ pxa3xx_mfp_write(lcd_detect_pins[i], lcd_detect_mfpr[i]);
2666+ }
2667+
2668+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
2669+ id = id << 1;
2670+ gpio = mfp_to_gpio(lcd_detect_pins[i]);
2671+ gpio_direction_input(gpio);
2672+
2673+ if (gpio_get_value(gpio))
2674+ id = id | 0x1;
2675+ }
2676+
2677+ /* lcd id, flush out bit 1 */
2678+ lcd_id = id & 0x3d;
2679+
2680+ /* lcd orientation, portrait or landscape */
2681+ lcd_orientation = (id >> 6) & 0x1;
2682+
2683+ /* restore the original MFP settings */
2684+ for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++)
2685+ pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
2686+}
2687+
2688+void __init zylonite_pxa320_init(void)
2689+{
2690+ if (cpu_is_pxa320()) {
2691+ /* initialize MFP */
2692+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
2693+
2694+ /* detect LCD panel */
2695+ zylonite_detect_lcd_panel();
2696+
2697+ /* GPIO pin assignment */
2698+ gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14);
2699+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
2700+ }
2701+}
2702--- linux-2.6.23.orig/arch/arm/mm/Kconfig
2703+++ linux-2.6.23/arch/arm/mm/Kconfig
2704@@ -322,7 +322,7 @@
2705 # XScale
2706 config CPU_XSCALE
2707 bool
2708- depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000
2709+ depends on ARCH_IOP32X || ARCH_IOP33X || PXA25x || PXA27x || ARCH_IXP4XX || ARCH_IXP2000
2710 default y
2711 select CPU_32v5
2712 select CPU_ABRT_EV5T
2713@@ -333,7 +333,7 @@
2714 # XScale Core Version 3
2715 config CPU_XSC3
2716 bool
2717- depends on ARCH_IXP23XX || ARCH_IOP13XX
2718+ depends on ARCH_IXP23XX || ARCH_IOP13XX || PXA3xx
2719 default y
2720 select CPU_32v5
2721 select CPU_ABRT_EV5T
2722--- linux-2.6.23.orig/drivers/i2c/busses/i2c-pxa.c
2723+++ linux-2.6.23/drivers/i2c/busses/i2c-pxa.c
2724@@ -31,6 +31,8 @@
2725 #include <linux/interrupt.h>
2726 #include <linux/i2c-pxa.h>
2727 #include <linux/platform_device.h>
2728+#include <linux/err.h>
2729+#include <linux/clk.h>
2730
2731 #include <asm/hardware.h>
2732 #include <asm/irq.h>
2733@@ -48,6 +50,7 @@
2734 unsigned int slave_addr;
2735
2736 struct i2c_adapter adap;
2737+ struct clk *clk;
2738 #ifdef CONFIG_I2C_PXA_SLAVE
2739 struct i2c_slave_client *slave;
2740 #endif
2741@@ -869,6 +872,12 @@
2742
2743 sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id);
2744
2745+ i2c->clk = clk_get(&dev->dev, "I2CCLK");
2746+ if (IS_ERR(i2c->clk)) {
2747+ ret = PTR_ERR(i2c->clk);
2748+ goto eclk;
2749+ }
2750+
2751 i2c->reg_base = ioremap(res->start, res_len(res));
2752 if (!i2c->reg_base) {
2753 ret = -EIO;
2754@@ -889,22 +898,19 @@
2755 }
2756 #endif
2757
2758+ clk_enable(i2c->clk);
2759+#ifdef CONFIG_PXA27x
2760 switch (dev->id) {
2761 case 0:
2762-#ifdef CONFIG_PXA27x
2763 pxa_gpio_mode(GPIO117_I2CSCL_MD);
2764 pxa_gpio_mode(GPIO118_I2CSDA_MD);
2765-#endif
2766- pxa_set_cken(CKEN_I2C, 1);
2767 break;
2768-#ifdef CONFIG_PXA27x
2769 case 1:
2770 local_irq_disable();
2771 PCFR |= PCFR_PI2CEN;
2772 local_irq_enable();
2773- pxa_set_cken(CKEN_PWRI2C, 1);
2774-#endif
2775 }
2776+#endif
2777
2778 ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
2779 i2c->adap.name, i2c);
2780@@ -948,19 +954,18 @@
2781 eadapt:
2782 free_irq(irq, i2c);
2783 ereqirq:
2784- switch (dev->id) {
2785- case 0:
2786- pxa_set_cken(CKEN_I2C, 0);
2787- break;
2788+ clk_disable(i2c->clk);
2789+
2790 #ifdef CONFIG_PXA27x
2791- case 1:
2792- pxa_set_cken(CKEN_PWRI2C, 0);
2793+ if (dev->id == 1) {
2794 local_irq_disable();
2795 PCFR &= ~PCFR_PI2CEN;
2796 local_irq_enable();
2797-#endif
2798 }
2799+#endif
2800 eremap:
2801+ clk_put(i2c->clk);
2802+eclk:
2803 kfree(i2c);
2804 emalloc:
2805 release_mem_region(res->start, res_len(res));
2806@@ -975,18 +980,18 @@
2807
2808 i2c_del_adapter(&i2c->adap);
2809 free_irq(i2c->irq, i2c);
2810- switch (dev->id) {
2811- case 0:
2812- pxa_set_cken(CKEN_I2C, 0);
2813- break;
2814+
2815+ clk_disable(i2c->clk);
2816+ clk_put(i2c->clk);
2817+
2818 #ifdef CONFIG_PXA27x
2819- case 1:
2820- pxa_set_cken(CKEN_PWRI2C, 0);
2821+ if (dev->id == 1) {
2822 local_irq_disable();
2823 PCFR &= ~PCFR_PI2CEN;
2824 local_irq_enable();
2825-#endif
2826 }
2827+#endif
2828+
2829 release_mem_region(i2c->iobase, i2c->iosize);
2830 kfree(i2c);
2831
2832--- linux-2.6.23.orig/drivers/input/keyboard/pxa27x_keyboard.c
2833+++ linux-2.6.23/drivers/input/keyboard/pxa27x_keyboard.c
2834@@ -23,6 +23,8 @@
2835 #include <linux/input.h>
2836 #include <linux/device.h>
2837 #include <linux/platform_device.h>
2838+#include <linux/clk.h>
2839+#include <linux/err.h>
2840
2841 #include <asm/mach-types.h>
2842 #include <asm/mach/arch.h>
2843@@ -40,6 +42,8 @@
2844 col/2 == 2 ? KPASMKP2 : KPASMKP3)
2845 #define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2)))
2846
2847+static struct clk *pxakbd_clk;
2848+
2849 static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id)
2850 {
2851 struct platform_device *pdev = dev_id;
2852@@ -104,7 +108,7 @@
2853 KPREC = 0x7F;
2854
2855 /* Enable unit clock */
2856- pxa_set_cken(CKEN_KEYPAD, 1);
2857+ clk_enable(pxakbd_clk);
2858
2859 return 0;
2860 }
2861@@ -112,7 +116,7 @@
2862 static void pxakbd_close(struct input_dev *dev)
2863 {
2864 /* Disable clock unit */
2865- pxa_set_cken(CKEN_KEYPAD, 0);
2866+ clk_disable(pxakbd_clk);
2867 }
2868
2869 #ifdef CONFIG_PM
2870@@ -140,7 +144,8 @@
2871 KPREC = pdata->reg_kprec;
2872
2873 /* Enable unit clock */
2874- pxa_set_cken(CKEN_KEYPAD, 1);
2875+ clk_disable(pxakbd_clk);
2876+ clk_enable(pxakbd_clk);
2877 }
2878
2879 mutex_unlock(&input_dev->mutex);
2880@@ -158,11 +163,18 @@
2881 struct input_dev *input_dev;
2882 int i, row, col, error;
2883
2884+ pxakbd_clk = clk_get(&pdev->dev, "KBDCLK");
2885+ if (IS_ERR(pxakbd_clk)) {
2886+ error = PTR_ERR(pxakbd_clk);
2887+ goto err_clk;
2888+ }
2889+
2890 /* Create and register the input driver. */
2891 input_dev = input_allocate_device();
2892 if (!input_dev) {
2893 printk(KERN_ERR "Cannot request keypad device\n");
2894- return -ENOMEM;
2895+ error = -ENOMEM;
2896+ goto err_alloc;
2897 }
2898
2899 input_dev->name = DRIVER_NAME;
2900@@ -185,7 +197,6 @@
2901 DRIVER_NAME, pdev);
2902 if (error) {
2903 printk(KERN_ERR "Cannot request keypad IRQ\n");
2904- pxa_set_cken(CKEN_KEYPAD, 0);
2905 goto err_free_dev;
2906 }
2907
2908@@ -217,6 +228,9 @@
2909 free_irq(IRQ_KEYPAD, pdev);
2910 err_free_dev:
2911 input_free_device(input_dev);
2912+ err_alloc:
2913+ clk_put(pxakbd_clk);
2914+ err_clk:
2915 return error;
2916 }
2917
2918@@ -226,6 +240,7 @@
2919
2920 input_unregister_device(input_dev);
2921 free_irq(IRQ_KEYPAD, pdev);
2922+ clk_put(pxakbd_clk);
2923 platform_set_drvdata(pdev, NULL);
2924
2925 return 0;
2926--- linux-2.6.23.orig/drivers/mmc/host/pxamci.c
2927+++ linux-2.6.23/drivers/mmc/host/pxamci.c
2928@@ -23,6 +23,8 @@
2929 #include <linux/delay.h>
2930 #include <linux/interrupt.h>
2931 #include <linux/dma-mapping.h>
2932+#include <linux/clk.h>
2933+#include <linux/err.h>
2934 #include <linux/mmc/host.h>
2935
2936 #include <asm/dma.h>
2937@@ -44,6 +46,8 @@
2938 spinlock_t lock;
2939 struct resource *res;
2940 void __iomem *base;
2941+ struct clk *clk;
2942+ unsigned long clkrate;
2943 int irq;
2944 int dma;
2945 unsigned int clkrt;
2946@@ -119,7 +123,7 @@
2947 writel(nob, host->base + MMC_NOB);
2948 writel(data->blksz, host->base + MMC_BLKLEN);
2949
2950- clks = (unsigned long long)data->timeout_ns * CLOCKRATE;
2951+ clks = (unsigned long long)data->timeout_ns * host->clkrate;
2952 do_div(clks, 1000000000UL);
2953 timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt);
2954 writel((timeout + 255) / 256, host->base + MMC_RDTO);
2955@@ -358,18 +362,25 @@
2956 struct pxamci_host *host = mmc_priv(mmc);
2957
2958 if (ios->clock) {
2959- unsigned int clk = CLOCKRATE / ios->clock;
2960- if (CLOCKRATE / clk > ios->clock)
2961+ unsigned long rate = host->clkrate;
2962+ unsigned int clk = rate / ios->clock;
2963+
2964+ /*
2965+ * clk might result in a lower divisor than we
2966+ * desire. check for that condition and adjust
2967+ * as appropriate.
2968+ */
2969+ if (rate / clk > ios->clock)
2970 clk <<= 1;
2971 host->clkrt = fls(clk) - 1;
2972- pxa_set_cken(CKEN_MMC, 1);
2973+ clk_enable(host->clk);
2974
2975 /*
2976 * we write clkrt on the next command
2977 */
2978 } else {
2979 pxamci_stop_clock(host);
2980- pxa_set_cken(CKEN_MMC, 0);
2981+ clk_disable(host->clk);
2982 }
2983
2984 if (host->power_mode != ios->power_mode) {
2985@@ -429,8 +440,6 @@
2986 }
2987
2988 mmc->ops = &pxamci_ops;
2989- mmc->f_min = CLOCKRATE_MIN;
2990- mmc->f_max = CLOCKRATE_MAX;
2991
2992 /*
2993 * We can do SG-DMA, but we don't because we never know how much
2994@@ -457,6 +466,22 @@
2995 host->mmc = mmc;
2996 host->dma = -1;
2997 host->pdata = pdev->dev.platform_data;
2998+
2999+ host->clk = clk_get(&pdev->dev, "MMCCLK");
3000+ if (IS_ERR(host->clk)) {
3001+ ret = PTR_ERR(host->clk);
3002+ host->clk = NULL;
3003+ goto out;
3004+ }
3005+
3006+ host->clkrate = clk_get_rate(host->clk);
3007+
3008+ /*
3009+ * Calculate minimum clock rate, rounding up.
3010+ */
3011+ mmc->f_min = (host->clkrate + 63) / 64;
3012+ mmc->f_max = host->clkrate;
3013+
3014 mmc->ocr_avail = host->pdata ?
3015 host->pdata->ocr_mask :
3016 MMC_VDD_32_33|MMC_VDD_33_34;
3017@@ -515,6 +540,8 @@
3018 iounmap(host->base);
3019 if (host->sg_cpu)
3020 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
3021+ if (host->clk)
3022+ clk_put(host->clk);
3023 }
3024 if (mmc)
3025 mmc_free_host(mmc);
3026@@ -549,6 +576,8 @@
3027 iounmap(host->base);
3028 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
3029
3030+ clk_put(host->clk);
3031+
3032 release_resource(host->res);
3033
3034 mmc_free_host(mmc);
3035--- linux-2.6.23.orig/drivers/mmc/host/pxamci.h
3036+++ linux-2.6.23/drivers/mmc/host/pxamci.h
3037@@ -86,17 +86,3 @@
3038 #define MMC_RXFIFO 0x0040 /* 8 bit */
3039
3040 #define MMC_TXFIFO 0x0044 /* 8 bit */
3041-
3042-/*
3043- * The base MMC clock rate
3044- */
3045-#ifdef CONFIG_PXA27x
3046-#define CLOCKRATE_MIN 304688
3047-#define CLOCKRATE_MAX 19500000
3048-#else
3049-#define CLOCKRATE_MIN 312500
3050-#define CLOCKRATE_MAX 20000000
3051-#endif
3052-
3053-#define CLOCKRATE CLOCKRATE_MAX
3054-
3055--- linux-2.6.23.orig/drivers/mtd/maps/lubbock-flash.c
3056+++ linux-2.6.23/drivers/mtd/maps/lubbock-flash.c
3057@@ -22,6 +22,7 @@
3058
3059 #include <asm/io.h>
3060 #include <asm/hardware.h>
3061+#include <asm/mach-types.h>
3062 #include <asm/arch/pxa-regs.h>
3063 #include <asm/arch/lubbock.h>
3064 #include <asm/cacheflush.h>
3065@@ -71,9 +72,14 @@
3066
3067 static int __init init_lubbock(void)
3068 {
3069- int flashboot = (LUB_CONF_SWITCHES & 1);
3070+ int flashboot;
3071 int ret = 0, i;
3072
3073+ if (!machine_is_lubbock())
3074+ return -ENODEV;
3075+
3076+ flashboot = (LUB_CONF_SWITCHES & 1);
3077+
3078 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
3079 (BOOT_DEF & 1) ? 2 : 4;
3080
3081--- linux-2.6.23.orig/drivers/mtd/maps/mainstone-flash.c
3082+++ linux-2.6.23/drivers/mtd/maps/mainstone-flash.c
3083@@ -22,6 +22,7 @@
3084
3085 #include <asm/io.h>
3086 #include <asm/hardware.h>
3087+#include <asm/mach-types.h>
3088 #include <asm/arch/pxa-regs.h>
3089 #include <asm/arch/mainstone.h>
3090 #include <asm/cacheflush.h>
3091@@ -76,6 +77,9 @@
3092 int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
3093 int ret = 0, i;
3094
3095+ if (!machine_is_mainstone())
3096+ return -ENODEV;
3097+
3098 mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4;
3099 mainstone_maps[1].bankwidth = 4;
3100
3101--- linux-2.6.23.orig/drivers/net/irda/pxaficp_ir.c
3102+++ linux-2.6.23/drivers/net/irda/pxaficp_ir.c
3103@@ -23,6 +23,7 @@
3104 #include <linux/dma-mapping.h>
3105 #include <linux/platform_device.h>
3106 #include <linux/pm.h>
3107+#include <linux/clk.h>
3108
3109 #include <net/irda/irda.h>
3110 #include <net/irda/irmod.h>
3111@@ -87,8 +88,30 @@
3112
3113 struct device *dev;
3114 struct pxaficp_platform_data *pdata;
3115+ struct clk *fir_clk;
3116+ struct clk *sir_clk;
3117+ struct clk *cur_clk;
3118 };
3119
3120+static inline void pxa_irda_disable_clk(struct pxa_irda *si)
3121+{
3122+ if (si->cur_clk)
3123+ clk_disable(si->cur_clk);
3124+ si->cur_clk = NULL;
3125+}
3126+
3127+static inline void pxa_irda_enable_firclk(struct pxa_irda *si)
3128+{
3129+ si->cur_clk = si->fir_clk;
3130+ clk_enable(si->fir_clk);
3131+}
3132+
3133+static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
3134+{
3135+ si->cur_clk = si->sir_clk;
3136+ clk_enable(si->sir_clk);
3137+}
3138+
3139
3140 #define IS_FIR(si) ((si)->speed >= 4000000)
3141 #define IRDA_FRAME_SIZE_LIMIT 2047
3142@@ -134,7 +157,7 @@
3143 DCSR(si->rxdma) &= ~DCSR_RUN;
3144 /* disable FICP */
3145 ICCR0 = 0;
3146- pxa_set_cken(CKEN_FICP, 0);
3147+ pxa_irda_disable_clk(si);
3148
3149 /* set board transceiver to SIR mode */
3150 si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
3151@@ -144,7 +167,7 @@
3152 pxa_gpio_mode(GPIO47_STTXD_MD);
3153
3154 /* enable the STUART clock */
3155- pxa_set_cken(CKEN_STUART, 1);
3156+ pxa_irda_enable_sirclk(si);
3157 }
3158
3159 /* disable STUART first */
3160@@ -169,7 +192,7 @@
3161 /* disable STUART */
3162 STIER = 0;
3163 STISR = 0;
3164- pxa_set_cken(CKEN_STUART, 0);
3165+ pxa_irda_disable_clk(si);
3166
3167 /* disable FICP first */
3168 ICCR0 = 0;
3169@@ -182,7 +205,7 @@
3170 pxa_gpio_mode(GPIO47_ICPTXD_MD);
3171
3172 /* enable the FICP clock */
3173- pxa_set_cken(CKEN_FICP, 1);
3174+ pxa_irda_enable_firclk(si);
3175
3176 si->speed = speed;
3177 pxa_irda_fir_dma_rx_start(si);
3178@@ -592,16 +615,15 @@
3179 STIER = 0;
3180 /* disable STUART SIR mode */
3181 STISR = 0;
3182- /* disable the STUART clock */
3183- pxa_set_cken(CKEN_STUART, 0);
3184
3185 /* disable DMA */
3186 DCSR(si->txdma) &= ~DCSR_RUN;
3187 DCSR(si->rxdma) &= ~DCSR_RUN;
3188 /* disable FICP */
3189 ICCR0 = 0;
3190- /* disable the FICP clock */
3191- pxa_set_cken(CKEN_FICP, 0);
3192+
3193+ /* disable the STUART or FICP clocks */
3194+ pxa_irda_disable_clk(si);
3195
3196 DRCMR17 = 0;
3197 DRCMR18 = 0;
3198@@ -792,6 +814,13 @@
3199 si->dev = &pdev->dev;
3200 si->pdata = pdev->dev.platform_data;
3201
3202+ si->sir_clk = clk_get(&pdev->dev, "UARTCLK");
3203+ si->fir_clk = clk_get(&pdev->dev, "FICPCLK");
3204+ if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) {
3205+ err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk);
3206+ goto err_mem_4;
3207+ }
3208+
3209 /*
3210 * Initialise the SIR buffers
3211 */
3212@@ -831,6 +860,10 @@
3213 err_mem_5:
3214 kfree(si->rx_buff.head);
3215 err_mem_4:
3216+ if (si->sir_clk && !IS_ERR(si->sir_clk))
3217+ clk_put(si->sir_clk);
3218+ if (si->fir_clk && !IS_ERR(si->fir_clk))
3219+ clk_put(si->fir_clk);
3220 free_netdev(dev);
3221 err_mem_3:
3222 release_mem_region(__PREG(FICP), 0x1c);
3223@@ -850,6 +883,8 @@
3224 unregister_netdev(dev);
3225 kfree(si->tx_buff.head);
3226 kfree(si->rx_buff.head);
3227+ clk_put(si->fir_clk);
3228+ clk_put(si->sir_clk);
3229 free_netdev(dev);
3230 }
3231
3232--- linux-2.6.23.orig/drivers/net/smc91x.c
3233+++ linux-2.6.23/drivers/net/smc91x.c
3234@@ -173,56 +173,6 @@
3235 */
3236 #define MII_DELAY 1
3237
3238-/* store this information for the driver.. */
3239-struct smc_local {
3240- /*
3241- * If I have to wait until memory is available to send a
3242- * packet, I will store the skbuff here, until I get the
3243- * desired memory. Then, I'll send it out and free it.
3244- */
3245- struct sk_buff *pending_tx_skb;
3246- struct tasklet_struct tx_task;
3247-
3248- /*
3249- * these are things that the kernel wants me to keep, so users
3250- * can find out semi-useless statistics of how well the card is
3251- * performing
3252- */
3253- struct net_device_stats stats;
3254-
3255- /* version/revision of the SMC91x chip */
3256- int version;
3257-
3258- /* Contains the current active transmission mode */
3259- int tcr_cur_mode;
3260-
3261- /* Contains the current active receive mode */
3262- int rcr_cur_mode;
3263-
3264- /* Contains the current active receive/phy mode */
3265- int rpc_cur_mode;
3266- int ctl_rfduplx;
3267- int ctl_rspeed;
3268-
3269- u32 msg_enable;
3270- u32 phy_type;
3271- struct mii_if_info mii;
3272-
3273- /* work queue */
3274- struct work_struct phy_configure;
3275- struct net_device *dev;
3276- int work_pending;
3277-
3278- spinlock_t lock;
3279-
3280-#ifdef SMC_USE_PXA_DMA
3281- /* DMA needs the physical address of the chip */
3282- u_long physaddr;
3283-#endif
3284- void __iomem *base;
3285- void __iomem *datacs;
3286-};
3287-
3288 #if SMC_DEBUG > 0
3289 #define DBG(n, args...) \
3290 do { \
3291@@ -2238,17 +2188,19 @@
3292 goto out_release_attrib;
3293 }
3294
3295- platform_set_drvdata(pdev, ndev);
3296- ret = smc_probe(ndev, addr);
3297- if (ret != 0)
3298- goto out_iounmap;
3299 #ifdef SMC_USE_PXA_DMA
3300- else {
3301+ {
3302 struct smc_local *lp = netdev_priv(ndev);
3303+ lp->device = &pdev->dev;
3304 lp->physaddr = res->start;
3305 }
3306 #endif
3307
3308+ platform_set_drvdata(pdev, ndev);
3309+ ret = smc_probe(ndev, addr);
3310+ if (ret != 0)
3311+ goto out_iounmap;
3312+
3313 smc_request_datacs(pdev, ndev);
3314
3315 return 0;
3316--- linux-2.6.23.orig/drivers/net/smc91x.h
3317+++ linux-2.6.23/drivers/net/smc91x.h
3318@@ -461,6 +461,59 @@
3319
3320 #endif
3321
3322+
3323+/* store this information for the driver.. */
3324+struct smc_local {
3325+ /*
3326+ * If I have to wait until memory is available to send a
3327+ * packet, I will store the skbuff here, until I get the
3328+ * desired memory. Then, I'll send it out and free it.
3329+ */
3330+ struct sk_buff *pending_tx_skb;
3331+ struct tasklet_struct tx_task;
3332+
3333+ /*
3334+ * these are things that the kernel wants me to keep, so users
3335+ * can find out semi-useless statistics of how well the card is
3336+ * performing
3337+ */
3338+ struct net_device_stats stats;
3339+
3340+ /* version/revision of the SMC91x chip */
3341+ int version;
3342+
3343+ /* Contains the current active transmission mode */
3344+ int tcr_cur_mode;
3345+
3346+ /* Contains the current active receive mode */
3347+ int rcr_cur_mode;
3348+
3349+ /* Contains the current active receive/phy mode */
3350+ int rpc_cur_mode;
3351+ int ctl_rfduplx;
3352+ int ctl_rspeed;
3353+
3354+ u32 msg_enable;
3355+ u32 phy_type;
3356+ struct mii_if_info mii;
3357+
3358+ /* work queue */
3359+ struct work_struct phy_configure;
3360+ struct net_device *dev;
3361+ int work_pending;
3362+
3363+ spinlock_t lock;
3364+
3365+#ifdef SMC_USE_PXA_DMA
3366+ /* DMA needs the physical address of the chip */
3367+ u_long physaddr;
3368+ struct device *device;
3369+#endif
3370+ void __iomem *base;
3371+ void __iomem *datacs;
3372+};
3373+
3374+
3375 #ifdef SMC_USE_PXA_DMA
3376 /*
3377 * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
3378@@ -475,11 +528,12 @@
3379 #ifdef SMC_insl
3380 #undef SMC_insl
3381 #define SMC_insl(a, r, p, l) \
3382- smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
3383+ smc_pxa_dma_insl(a, lp, r, dev->dma, p, l)
3384 static inline void
3385-smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
3386+smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
3387 u_char *buf, int len)
3388 {
3389+ u_long physaddr = lp->physaddr;
3390 dma_addr_t dmabuf;
3391
3392 /* fallback if no DMA available */
3393@@ -496,7 +550,7 @@
3394 }
3395
3396 len *= 4;
3397- dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
3398+ dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
3399 DCSR(dma) = DCSR_NODESC;
3400 DTADR(dma) = dmabuf;
3401 DSADR(dma) = physaddr + reg;
3402@@ -506,18 +560,19 @@
3403 while (!(DCSR(dma) & DCSR_STOPSTATE))
3404 cpu_relax();
3405 DCSR(dma) = 0;
3406- dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
3407+ dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
3408 }
3409 #endif
3410
3411 #ifdef SMC_insw
3412 #undef SMC_insw
3413 #define SMC_insw(a, r, p, l) \
3414- smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
3415+ smc_pxa_dma_insw(a, lp, r, dev->dma, p, l)
3416 static inline void
3417-smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
3418+smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
3419 u_char *buf, int len)
3420 {
3421+ u_long physaddr = lp->physaddr;
3422 dma_addr_t dmabuf;
3423
3424 /* fallback if no DMA available */
3425@@ -534,7 +589,7 @@
3426 }
3427
3428 len *= 2;
3429- dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
3430+ dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
3431 DCSR(dma) = DCSR_NODESC;
3432 DTADR(dma) = dmabuf;
3433 DSADR(dma) = physaddr + reg;
3434@@ -544,7 +599,7 @@
3435 while (!(DCSR(dma) & DCSR_STOPSTATE))
3436 cpu_relax();
3437 DCSR(dma) = 0;
3438- dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
3439+ dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
3440 }
3441 #endif
3442
3443--- linux-2.6.23.orig/drivers/serial/pxa.c
3444+++ linux-2.6.23/drivers/serial/pxa.c
3445@@ -42,6 +42,7 @@
3446 #include <linux/tty.h>
3447 #include <linux/tty_flip.h>
3448 #include <linux/serial_core.h>
3449+#include <linux/clk.h>
3450
3451 #include <asm/io.h>
3452 #include <asm/hardware.h>
3453@@ -56,7 +57,7 @@
3454 unsigned char lcr;
3455 unsigned char mcr;
3456 unsigned int lsr_break_flag;
3457- unsigned int cken;
3458+ struct clk *clk;
3459 char *name;
3460 };
3461
3462@@ -363,6 +364,8 @@
3463 else
3464 up->mcr = 0;
3465
3466+ up->port.uartclk = clk_get_rate(up->clk);
3467+
3468 /*
3469 * Allocate the IRQ
3470 */
3471@@ -568,9 +571,11 @@
3472 unsigned int oldstate)
3473 {
3474 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
3475- pxa_set_cken(up->cken, !state);
3476+
3477 if (!state)
3478- udelay(1);
3479+ clk_enable(up->clk);
3480+ else
3481+ clk_disable(up->clk);
3482 }
3483
3484 static void serial_pxa_release_port(struct uart_port *port)
3485@@ -604,7 +609,7 @@
3486
3487 #ifdef CONFIG_SERIAL_PXA_CONSOLE
3488
3489-static struct uart_pxa_port serial_pxa_ports[];
3490+static struct uart_pxa_port *serial_pxa_ports[4];
3491 static struct uart_driver serial_pxa_reg;
3492
3493 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
3494@@ -654,9 +659,11 @@
3495 static void
3496 serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
3497 {
3498- struct uart_pxa_port *up = &serial_pxa_ports[co->index];
3499+ struct uart_pxa_port *up = serial_pxa_ports[co->index];
3500 unsigned int ier;
3501
3502+ clk_enable(up->clk);
3503+
3504 /*
3505 * First save the IER then disable the interrupts
3506 */
3507@@ -671,6 +678,8 @@
3508 */
3509 wait_for_xmitr(up);
3510 serial_out(up, UART_IER, ier);
3511+
3512+ clk_disable(up->clk);
3513 }
3514
3515 static int __init
3516@@ -684,7 +693,9 @@
3517
3518 if (co->index == -1 || co->index >= serial_pxa_reg.nr)
3519 co->index = 0;
3520- up = &serial_pxa_ports[co->index];
3521+ up = serial_pxa_ports[co->index];
3522+ if (!up)
3523+ return -ENODEV;
3524
3525 if (options)
3526 uart_parse_options(options, &baud, &parity, &bits, &flow);
3527@@ -702,15 +713,6 @@
3528 .data = &serial_pxa_reg,
3529 };
3530
3531-static int __init
3532-serial_pxa_console_init(void)
3533-{
3534- register_console(&serial_pxa_console);
3535- return 0;
3536-}
3537-
3538-console_initcall(serial_pxa_console_init);
3539-
3540 #define PXA_CONSOLE &serial_pxa_console
3541 #else
3542 #define PXA_CONSOLE NULL
3543@@ -736,73 +738,13 @@
3544 .verify_port = serial_pxa_verify_port,
3545 };
3546
3547-static struct uart_pxa_port serial_pxa_ports[] = {
3548- { /* FFUART */
3549- .name = "FFUART",
3550- .cken = CKEN_FFUART,
3551- .port = {
3552- .type = PORT_PXA,
3553- .iotype = UPIO_MEM,
3554- .membase = (void *)&FFUART,
3555- .mapbase = __PREG(FFUART),
3556- .irq = IRQ_FFUART,
3557- .uartclk = 921600 * 16,
3558- .fifosize = 64,
3559- .ops = &serial_pxa_pops,
3560- .line = 0,
3561- },
3562- }, { /* BTUART */
3563- .name = "BTUART",
3564- .cken = CKEN_BTUART,
3565- .port = {
3566- .type = PORT_PXA,
3567- .iotype = UPIO_MEM,
3568- .membase = (void *)&BTUART,
3569- .mapbase = __PREG(BTUART),
3570- .irq = IRQ_BTUART,
3571- .uartclk = 921600 * 16,
3572- .fifosize = 64,
3573- .ops = &serial_pxa_pops,
3574- .line = 1,
3575- },
3576- }, { /* STUART */
3577- .name = "STUART",
3578- .cken = CKEN_STUART,
3579- .port = {
3580- .type = PORT_PXA,
3581- .iotype = UPIO_MEM,
3582- .membase = (void *)&STUART,
3583- .mapbase = __PREG(STUART),
3584- .irq = IRQ_STUART,
3585- .uartclk = 921600 * 16,
3586- .fifosize = 64,
3587- .ops = &serial_pxa_pops,
3588- .line = 2,
3589- },
3590- }, { /* HWUART */
3591- .name = "HWUART",
3592- .cken = CKEN_HWUART,
3593- .port = {
3594- .type = PORT_PXA,
3595- .iotype = UPIO_MEM,
3596- .membase = (void *)&HWUART,
3597- .mapbase = __PREG(HWUART),
3598- .irq = IRQ_HWUART,
3599- .uartclk = 921600 * 16,
3600- .fifosize = 64,
3601- .ops = &serial_pxa_pops,
3602- .line = 3,
3603- },
3604- }
3605-};
3606-
3607 static struct uart_driver serial_pxa_reg = {
3608 .owner = THIS_MODULE,
3609 .driver_name = "PXA serial",
3610 .dev_name = "ttyS",
3611 .major = TTY_MAJOR,
3612 .minor = 64,
3613- .nr = ARRAY_SIZE(serial_pxa_ports),
3614+ .nr = 4,
3615 .cons = PXA_CONSOLE,
3616 };
3617
3618@@ -828,10 +770,68 @@
3619
3620 static int serial_pxa_probe(struct platform_device *dev)
3621 {
3622- serial_pxa_ports[dev->id].port.dev = &dev->dev;
3623- uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port);
3624- platform_set_drvdata(dev, &serial_pxa_ports[dev->id]);
3625+ struct uart_pxa_port *sport;
3626+ struct resource *mmres, *irqres;
3627+ int ret;
3628+
3629+ mmres = platform_get_resource(dev, IORESOURCE_MEM, 0);
3630+ irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0);
3631+ if (!mmres || !irqres)
3632+ return -ENODEV;
3633+
3634+ sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL);
3635+ if (!sport)
3636+ return -ENOMEM;
3637+
3638+ sport->clk = clk_get(&dev->dev, "UARTCLK");
3639+ if (IS_ERR(sport->clk)) {
3640+ ret = PTR_ERR(sport->clk);
3641+ goto err_free;
3642+ }
3643+
3644+ sport->port.type = PORT_PXA;
3645+ sport->port.iotype = UPIO_MEM;
3646+ sport->port.mapbase = mmres->start;
3647+ sport->port.irq = irqres->start;
3648+ sport->port.fifosize = 64;
3649+ sport->port.ops = &serial_pxa_pops;
3650+ sport->port.line = dev->id;
3651+ sport->port.dev = &dev->dev;
3652+ sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
3653+ sport->port.uartclk = clk_get_rate(sport->clk);
3654+
3655+ /*
3656+ * Is it worth keeping this?
3657+ */
3658+ if (mmres->start == __PREG(FFUART))
3659+ sport->name = "FFUART";
3660+ else if (mmres->start == __PREG(BTUART))
3661+ sport->name = "BTUART";
3662+ else if (mmres->start == __PREG(STUART))
3663+ sport->name = "STUART";
3664+ else if (mmres->start == __PREG(HWUART))
3665+ sport->name = "HWUART";
3666+ else
3667+ sport->name = "???";
3668+
3669+ sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1);
3670+ if (!sport->port.membase) {
3671+ ret = -ENOMEM;
3672+ goto err_clk;
3673+ }
3674+
3675+ serial_pxa_ports[dev->id] = sport;
3676+
3677+ uart_add_one_port(&serial_pxa_reg, &sport->port);
3678+ platform_set_drvdata(dev, sport);
3679+
3680 return 0;
3681+
3682+ err_clk:
3683+ clk_put(sport->clk);
3684+ err_free:
3685+ kfree(sport);
3686+ return ret;
3687 }
3688
3689 static int serial_pxa_remove(struct platform_device *dev)
3690@@ -840,8 +840,9 @@
3691
3692 platform_set_drvdata(dev, NULL);
3693
3694- if (sport)
3695- uart_remove_one_port(&serial_pxa_reg, &sport->port);
3696+ uart_remove_one_port(&serial_pxa_reg, &sport->port);
3697+ clk_put(sport->clk);
3698+ kfree(sport);
3699
3700 return 0;
3701 }
3702--- linux-2.6.23.orig/drivers/serial/serial_core.c
3703+++ linux-2.6.23/drivers/serial/serial_core.c
3704@@ -2128,6 +2128,14 @@
3705 spin_unlock_irqrestore(&port->lock, flags);
3706
3707 /*
3708+ * If this driver supports console, and it hasn't been
3709+ * successfully registered yet, try to re-register it.
3710+ * It may be that the port was not available.
3711+ */
3712+ if (port->cons && !(port->cons->flags & CON_ENABLED))
3713+ register_console(port->cons);
3714+
3715+ /*
3716 * Power down all ports by default, except the
3717 * console if we have one.
3718 */
3719@@ -2288,6 +2296,7 @@
3720 }
3721
3722 state->port = port;
3723+ state->pm_state = -1;
3724
3725 port->cons = drv->cons;
3726 port->info = state->info;
3727@@ -2310,15 +2319,6 @@
3728 tty_register_device(drv->tty_driver, port->line, port->dev);
3729
3730 /*
3731- * If this driver supports console, and it hasn't been
3732- * successfully registered yet, try to re-register it.
3733- * It may be that the port was not available.
3734- */
3735- if (port->type != PORT_UNKNOWN &&
3736- port->cons && !(port->cons->flags & CON_ENABLED))
3737- register_console(port->cons);
3738-
3739- /*
3740 * Ensure UPF_DEAD is not set.
3741 */
3742 port->flags &= ~UPF_DEAD;
3743--- linux-2.6.23.orig/drivers/usb/gadget/pxa2xx_udc.c
3744+++ linux-2.6.23/drivers/usb/gadget/pxa2xx_udc.c
3745@@ -43,6 +43,8 @@
3746 #include <linux/platform_device.h>
3747 #include <linux/dma-mapping.h>
3748 #include <linux/irq.h>
3749+#include <linux/clk.h>
3750+#include <linux/err.h>
3751
3752 #include <asm/byteorder.h>
3753 #include <asm/dma.h>
3754@@ -1157,7 +1159,7 @@
3755
3756 #ifdef CONFIG_ARCH_PXA
3757 /* Disable clock for USB device */
3758- pxa_set_cken(CKEN_USB, 0);
3759+ clk_disable(dev->clk);
3760 #endif
3761
3762 ep0_idle (dev);
3763@@ -1202,8 +1204,7 @@
3764
3765 #ifdef CONFIG_ARCH_PXA
3766 /* Enable clock for USB device */
3767- pxa_set_cken(CKEN_USB, 1);
3768- udelay(5);
3769+ clk_enable(dev->clk);
3770 #endif
3771
3772 /* try to clear these bits before we enable the udc */
3773@@ -2137,6 +2138,14 @@
3774 if (irq < 0)
3775 return -ENODEV;
3776
3777+#ifdef CONFIG_ARCH_PXA
3778+ dev->clk = clk_get(&pdev->dev, "UDCCLK");
3779+ if (IS_ERR(dev->clk)) {
3780+ retval = PTR_ERR(dev->clk);
3781+ goto err_clk;
3782+ }
3783+#endif
3784+
3785 pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
3786 dev->has_cfr ? "" : " (!cfr)",
3787 SIZE_STR "(pio)"
3788@@ -2152,11 +2161,10 @@
3789 dev_dbg(&pdev->dev,
3790 "can't get vbus gpio %d, err: %d\n",
3791 dev->mach->gpio_vbus, retval);
3792- return -EBUSY;
3793+ goto err_gpio_vbus;
3794 }
3795 gpio_direction_input(dev->mach->gpio_vbus);
3796 vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
3797- set_irq_type(vbus_irq, IRQT_BOTHEDGE);
3798 } else
3799 vbus_irq = 0;
3800
3801@@ -2166,9 +2174,7 @@
3802 dev_dbg(&pdev->dev,
3803 "can't get pullup gpio %d, err: %d\n",
3804 dev->mach->gpio_pullup, retval);
3805- if (dev->mach->gpio_vbus)
3806- gpio_free(dev->mach->gpio_vbus);
3807- return -EBUSY;
3808+ goto err_gpio_pullup;
3809 }
3810 gpio_direction_output(dev->mach->gpio_pullup, 0);
3811 }
3812@@ -2195,11 +2201,7 @@
3813 if (retval != 0) {
3814 printk(KERN_ERR "%s: can't get irq %d, err %d\n",
3815 driver_name, irq, retval);
3816- if (dev->mach->gpio_pullup)
3817- gpio_free(dev->mach->gpio_pullup);
3818- if (dev->mach->gpio_vbus)
3819- gpio_free(dev->mach->gpio_vbus);
3820- return -EBUSY;
3821+ goto err_irq1;
3822 }
3823 dev->got_irq = 1;
3824
3825@@ -2213,12 +2215,7 @@
3826 printk(KERN_ERR "%s: can't get irq %i, err %d\n",
3827 driver_name, LUBBOCK_USB_DISC_IRQ, retval);
3828 lubbock_fail0:
3829- free_irq(irq, dev);
3830- if (dev->mach->gpio_pullup)
3831- gpio_free(dev->mach->gpio_pullup);
3832- if (dev->mach->gpio_vbus)
3833- gpio_free(dev->mach->gpio_vbus);
3834- return -EBUSY;
3835+ goto err_irq_lub;
3836 }
3837 retval = request_irq(LUBBOCK_USB_IRQ,
3838 lubbock_vbus_irq,
3839@@ -2234,22 +2231,37 @@
3840 #endif
3841 if (vbus_irq) {
3842 retval = request_irq(vbus_irq, udc_vbus_irq,
3843- IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
3844+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
3845+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
3846 driver_name, dev);
3847 if (retval != 0) {
3848 printk(KERN_ERR "%s: can't get irq %i, err %d\n",
3849 driver_name, vbus_irq, retval);
3850- free_irq(irq, dev);
3851- if (dev->mach->gpio_pullup)
3852- gpio_free(dev->mach->gpio_pullup);
3853- if (dev->mach->gpio_vbus)
3854- gpio_free(dev->mach->gpio_vbus);
3855- return -EBUSY;
3856+ goto err_vbus_irq;
3857 }
3858 }
3859 create_proc_files();
3860
3861 return 0;
3862+
3863+ err_vbus_irq:
3864+#ifdef CONFIG_ARCH_LUBBOCK
3865+ free_irq(LUBBOCK_USB_DISC_IRQ, dev);
3866+ err_irq_lub:
3867+#endif
3868+ free_irq(irq, dev);
3869+ err_irq1:
3870+ if (dev->mach->gpio_pullup)
3871+ gpio_free(dev->mach->gpio_pullup);
3872+ err_gpio_pullup:
3873+ if (dev->mach->gpio_vbus)
3874+ gpio_free(dev->mach->gpio_vbus);
3875+ err_gpio_vbus:
3876+#ifdef CONFIG_ARCH_PXA
3877+ clk_put(dev->clk);
3878+ err_clk:
3879+#endif
3880+ return retval;
3881 }
3882
3883 static void pxa2xx_udc_shutdown(struct platform_device *_dev)
3884@@ -2284,6 +2296,10 @@
3885 if (dev->mach->gpio_pullup)
3886 gpio_free(dev->mach->gpio_pullup);
3887
3888+#ifdef CONFIG_ARCH_PXA
3889+ clk_put(dev->clk);
3890+#endif
3891+
3892 platform_set_drvdata(pdev, NULL);
3893 the_controller = NULL;
3894 return 0;
3895--- linux-2.6.23.orig/drivers/usb/gadget/pxa2xx_udc.h
3896+++ linux-2.6.23/drivers/usb/gadget/pxa2xx_udc.h
3897@@ -125,6 +125,7 @@
3898 struct timer_list timer;
3899
3900 struct device *dev;
3901+ struct clk *clk;
3902 struct pxa2xx_udc_mach_info *mach;
3903 u64 dma_mask;
3904 struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS];
3905--- linux-2.6.23.orig/drivers/video/pxafb.c
3906+++ linux-2.6.23/drivers/video/pxafb.c
3907@@ -37,6 +37,8 @@
3908 #include <linux/cpufreq.h>
3909 #include <linux/platform_device.h>
3910 #include <linux/dma-mapping.h>
3911+#include <linux/clk.h>
3912+#include <linux/err.h>
3913
3914 #include <asm/hardware.h>
3915 #include <asm/io.h>
3916@@ -574,15 +576,15 @@
3917 *
3918 * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
3919 */
3920-static inline unsigned int get_pcd(unsigned int pixclock)
3921+static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock)
3922 {
3923 unsigned long long pcd;
3924
3925 /* FIXME: Need to take into account Double Pixel Clock mode
3926- * (DPC) bit? or perhaps set it based on the various clock
3927- * speeds */
3928-
3929- pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
3930+ * (DPC) bit? or perhaps set it based on the various clock
3931+ * speeds */
3932+ pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000);
3933+ pcd *= pixclock;
3934 do_div(pcd, 100000000 * 2);
3935 /* no need for this, since we should subtract 1 anyway. they cancel */
3936 /* pcd += 1; */ /* make up for integer math truncations */
3937@@ -591,19 +593,21 @@
3938
3939 /*
3940 * Some touchscreens need hsync information from the video driver to
3941- * function correctly. We export it here.
3942+ * function correctly. We export it here. Note that 'hsync_time' and
3943+ * the value returned from pxafb_get_hsync_time() is the *reciprocal*
3944+ * of the hsync period in seconds.
3945 */
3946 static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
3947 {
3948- unsigned long long htime;
3949+ unsigned long htime;
3950
3951 if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
3952 fbi->hsync_time=0;
3953 return;
3954 }
3955
3956- htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000;
3957- do_div(htime, pcd * fbi->fb.var.hsync_len);
3958+ htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len);
3959+
3960 fbi->hsync_time = htime;
3961 }
3962
3963@@ -628,7 +632,7 @@
3964 {
3965 struct pxafb_lcd_reg new_regs;
3966 u_long flags;
3967- u_int lines_per_panel, pcd = get_pcd(var->pixclock);
3968+ u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
3969
3970 pr_debug("pxafb: Configuring PXA LCD\n");
3971
3972@@ -908,7 +912,7 @@
3973 pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
3974
3975 /* enable LCD controller clock */
3976- pxa_set_cken(CKEN_LCD, 1);
3977+ clk_enable(fbi->clk);
3978
3979 down(&fcs_lcd_sem);
3980 /* Sequence from 11.7.10 */
3981@@ -950,7 +954,7 @@
3982 up(&fcs_lcd_sem);
3983
3984 /* disable LCD controller clock */
3985- pxa_set_cken(CKEN_LCD, 0);
3986+ clk_disable(fbi->clk);
3987 }
3988
3989 /*
3990@@ -1161,7 +1165,7 @@
3991 if ((clkinfo->old == 13000))
3992 break;
3993
3994- pcd = get_pcd(fbi->fb.var.pixclock);
3995+ pcd = get_pcd(fbi, fbi->fb.var.pixclock);
3996 lccr3 = fbi->reg_lccr3;
3997 set_hsync_time(fbi, pcd);
3998 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
3999@@ -1293,6 +1297,12 @@
4000 memset(fbi, 0, sizeof(struct pxafb_info));
4001 fbi->dev = dev;
4002
4003+ fbi->clk = clk_get(dev, "LCDCLK");
4004+ if (IS_ERR(fbi->clk)) {
4005+ kfree(fbi);
4006+ return NULL;
4007+ }
4008+
4009 strcpy(fbi->fb.fix.id, PXA_NAME);
4010
4011 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
4012--- linux-2.6.23.orig/drivers/video/pxafb.h
4013+++ linux-2.6.23/drivers/video/pxafb.h
4014@@ -94,6 +94,7 @@
4015 struct pxafb_info {
4016 struct fb_info fb;
4017 struct device *dev;
4018+ struct clk *clk;
4019
4020 /*
4021 * These are the addresses we mapped
4022--- linux-2.6.23.orig/include/asm-arm/arch-pxa/hardware.h
4023+++ linux-2.6.23/include/asm-arm/arch-pxa/hardware.h
4024@@ -80,6 +80,24 @@
4025 _id == 0x411; \
4026 })
4027
4028+#define __cpu_is_pxa300(id) \
4029+ ({ \
4030+ unsigned int _id = (id) >> 4 & 0xfff; \
4031+ _id == 0x688; \
4032+ })
4033+
4034+#define __cpu_is_pxa310(id) \
4035+ ({ \
4036+ unsigned int _id = (id) >> 4 & 0xfff; \
4037+ _id == 0x689; \
4038+ })
4039+
4040+#define __cpu_is_pxa320(id) \
4041+ ({ \
4042+ unsigned int _id = (id) >> 4 & 0xfff; \
4043+ _id == 0x603 || _id == 0x682; \
4044+ })
4045+
4046 #define cpu_is_pxa21x() \
4047 ({ \
4048 unsigned int id = read_cpuid(CPUID_ID); \
4049@@ -98,6 +116,53 @@
4050 __cpu_is_pxa27x(id); \
4051 })
4052
4053+#define cpu_is_pxa300() \
4054+ ({ \
4055+ unsigned int id = read_cpuid(CPUID_ID); \
4056+ __cpu_is_pxa300(id); \
4057+ })
4058+
4059+#define cpu_is_pxa310() \
4060+ ({ \
4061+ unsigned int id = read_cpuid(CPUID_ID); \
4062+ __cpu_is_pxa310(id); \
4063+ })
4064+
4065+#define cpu_is_pxa320() \
4066+ ({ \
4067+ unsigned int id = read_cpuid(CPUID_ID); \
4068+ __cpu_is_pxa320(id); \
4069+ })
4070+
4071+/*
4072+ * CPUID Core Generation Bit
4073+ * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
4074+ * == 0x3 for pxa300/pxa310/pxa320
4075+ */
4076+#define __cpu_is_pxa2xx(id) \
4077+ ({ \
4078+ unsigned int _id = (id) >> 13 & 0x7; \
4079+ _id <= 0x2; \
4080+ })
4081+
4082+#define __cpu_is_pxa3xx(id) \
4083+ ({ \
4084+ unsigned int _id = (id) >> 13 & 0x7; \
4085+ _id == 0x3; \
4086+ })
4087+
4088+#define cpu_is_pxa2xx() \
4089+ ({ \
4090+ unsigned int id = read_cpuid(CPUID_ID); \
4091+ __cpu_is_pxa2xx(id); \
4092+ })
4093+
4094+#define cpu_is_pxa3xx() \
4095+ ({ \
4096+ unsigned int id = read_cpuid(CPUID_ID); \
4097+ __cpu_is_pxa3xx(id); \
4098+ })
4099+
4100 /*
4101 * Handy routine to set GPIO alternate functions
4102 */
4103@@ -116,13 +181,16 @@
4104 /*
4105 * Routine to enable or disable CKEN
4106 */
4107-extern void pxa_set_cken(int clock, int enable);
4108+static inline void __deprecated pxa_set_cken(int clock, int enable)
4109+{
4110+ extern void __pxa_set_cken(int clock, int enable);
4111+ __pxa_set_cken(clock, enable);
4112+}
4113
4114 /*
4115 * return current memory and LCD clock frequency in units of 10kHz
4116 */
4117 extern unsigned int get_memclk_frequency_10khz(void);
4118-extern unsigned int get_lcdclk_frequency_10khz(void);
4119
4120 #endif
4121
4122--- linux-2.6.23.orig/include/asm-arm/arch-pxa/irqs.h
4123+++ linux-2.6.23/include/asm-arm/arch-pxa/irqs.h
4124@@ -66,12 +66,6 @@
4125 #define IRQ_TO_GPIO_2_x(i) ((i) - PXA_GPIO_IRQ_BASE)
4126 #define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
4127
4128-#if defined(CONFIG_PXA25x)
4129-#define PXA_LAST_GPIO 84
4130-#elif defined(CONFIG_PXA27x)
4131-#define PXA_LAST_GPIO 127
4132-#endif
4133-
4134 /*
4135 * The next 16 interrupts are for board specific purposes. Since
4136 * the kernel can only run on one machine at a time, we can re-use
4137--- /dev/null
4138+++ linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h
4139@@ -0,0 +1,574 @@
4140+/*
4141+ * linux/include/asm-arm/arch-pxa/mfp-pxa300.h
4142+ *
4143+ * PXA300/PXA310 specific MFP configuration definitions
4144+ *
4145+ * Copyright (C) 2007 Marvell International Ltd.
4146+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
4147+ * initial version
4148+ *
4149+ * This program is free software; you can redistribute it and/or modify
4150+ * it under the terms of the GNU General Public License version 2 as
4151+ * published by the Free Software Foundation.
4152+ */
4153+
4154+#ifndef __ASM_ARCH_MFP_PXA300_H
4155+#define __ASM_ARCH_MFP_PXA300_H
4156+
4157+#include <asm/arch/mfp.h>
4158+
4159+/* GPIO */
4160+#define GPIO46_GPIO MFP_CFG(GPIO46, AF1)
4161+#define GPIO49_GPIO MFP_CFG(GPIO49, AF3)
4162+#define GPIO50_GPIO MFP_CFG(GPIO50, AF2)
4163+#define GPIO51_GPIO MFP_CFG(GPIO51, AF3)
4164+#define GPIO52_GPIO MFP_CFG(GPIO52, AF3)
4165+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
4166+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
4167+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
4168+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
4169+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
4170+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
4171+
4172+#ifdef CONFIG_CPU_PXA310
4173+#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0)
4174+#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0)
4175+#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0)
4176+#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0)
4177+#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0)
4178+#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0)
4179+#endif
4180+
4181+/* Chip Select */
4182+#define GPIO2_nCS3 MFP_CFG(GPIO2, AF1)
4183+
4184+/* AC97 */
4185+#define GPIO23_AC97_nACRESET MFP_CFG(GPIO23, AF1)
4186+#define GPIO24_AC97_SYSCLK MFP_CFG(GPIO24, AF1)
4187+#define GPIO29_AC97_BITCLK MFP_CFG(GPIO29, AF1)
4188+#define GPIO25_AC97_SDATA_IN_0 MFP_CFG(GPIO25, AF1)
4189+#define GPIO26_AC97_SDATA_IN_1 MFP_CFG(GPIO26, AF1)
4190+#define GPIO17_AC97_SDATA_IN_2 MFP_CFG(GPIO17, AF3)
4191+#define GPIO21_AC97_SDATA_IN_2 MFP_CFG(GPIO21, AF2)
4192+#define GPIO18_AC97_SDATA_IN_3 MFP_CFG(GPIO18, AF3)
4193+#define GPIO22_AC97_SDATA_IN_3 MFP_CFG(GPIO22, AF2)
4194+#define GPIO27_AC97_SDATA_OUT MFP_CFG(GPIO27, AF1)
4195+#define GPIO28_AC97_SYNC MFP_CFG(GPIO28, AF1)
4196+
4197+/* I2C */
4198+#define GPIO21_I2C_SCL MFP_CFG_LPM(GPIO21, AF1, PULL_HIGH)
4199+#define GPIO22_I2C_SDA MFP_CFG_LPM(GPIO22, AF1, PULL_HIGH)
4200+
4201+/* QCI */
4202+#define GPIO39_CI_DD_0 MFP_CFG_DRV(GPIO39, AF1, DS04X)
4203+#define GPIO40_CI_DD_1 MFP_CFG_DRV(GPIO40, AF1, DS04X)
4204+#define GPIO41_CI_DD_2 MFP_CFG_DRV(GPIO41, AF1, DS04X)
4205+#define GPIO42_CI_DD_3 MFP_CFG_DRV(GPIO42, AF1, DS04X)
4206+#define GPIO43_CI_DD_4 MFP_CFG_DRV(GPIO43, AF1, DS04X)
4207+#define GPIO44_CI_DD_5 MFP_CFG_DRV(GPIO44, AF1, DS04X)
4208+#define GPIO45_CI_DD_6 MFP_CFG_DRV(GPIO45, AF1, DS04X)
4209+#define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X)
4210+#define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X)
4211+#define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X)
4212+#define GPIO52_CI_HSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X)
4213+#define GPIO51_CI_VSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X)
4214+#define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X)
4215+#define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X)
4216+
4217+/* KEYPAD */
4218+#define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT)
4219+#define GPIO4_KP_DKIN_7 MFP_CFG_LPM(GPIO4, AF2, FLOAT)
4220+#define GPIO16_KP_DKIN_6 MFP_CFG_LPM(GPIO16, AF6, FLOAT)
4221+#define GPIO83_KP_DKIN_2 MFP_CFG_LPM(GPIO83, AF5, FLOAT)
4222+#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF5, FLOAT)
4223+#define GPIO85_KP_DKIN_0 MFP_CFG_LPM(GPIO85, AF3, FLOAT)
4224+#define GPIO86_KP_DKIN_1 MFP_CFG_LPM(GPIO86, AF3, FLOAT)
4225+#define GPIO87_KP_DKIN_2 MFP_CFG_LPM(GPIO87, AF3, FLOAT)
4226+#define GPIO88_KP_DKIN_3 MFP_CFG_LPM(GPIO88, AF3, FLOAT)
4227+#define GPIO89_KP_DKIN_3 MFP_CFG_LPM(GPIO89, AF3, FLOAT)
4228+#define GPIO107_KP_DKIN_0 MFP_CFG_LPM(GPIO107, AF2, FLOAT)
4229+#define GPIO108_KP_DKIN_1 MFP_CFG_LPM(GPIO108, AF2, FLOAT)
4230+#define GPIO109_KP_DKIN_2 MFP_CFG_LPM(GPIO109, AF2, FLOAT)
4231+#define GPIO110_KP_DKIN_3 MFP_CFG_LPM(GPIO110, AF2, FLOAT)
4232+#define GPIO111_KP_DKIN_4 MFP_CFG_LPM(GPIO111, AF2, FLOAT)
4233+#define GPIO112_KP_DKIN_5 MFP_CFG_LPM(GPIO112, AF2, FLOAT)
4234+#define GPIO113_KP_DKIN_6 MFP_CFG_LPM(GPIO113, AF2, FLOAT)
4235+#define GPIO114_KP_DKIN_7 MFP_CFG_LPM(GPIO114, AF2, FLOAT)
4236+#define GPIO115_KP_DKIN_0 MFP_CFG_LPM(GPIO115, AF2, FLOAT)
4237+#define GPIO116_KP_DKIN_1 MFP_CFG_LPM(GPIO116, AF2, FLOAT)
4238+#define GPIO117_KP_DKIN_2 MFP_CFG_LPM(GPIO117, AF2, FLOAT)
4239+#define GPIO118_KP_DKIN_3 MFP_CFG_LPM(GPIO118, AF2, FLOAT)
4240+#define GPIO119_KP_DKIN_4 MFP_CFG_LPM(GPIO119, AF2, FLOAT)
4241+#define GPIO120_KP_DKIN_5 MFP_CFG_LPM(GPIO120, AF2, FLOAT)
4242+#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT)
4243+#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT)
4244+#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT)
4245+#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT)
4246+#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF5, FLOAT)
4247+#define GPIO0_2_KP_DKIN_0 MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
4248+#define GPIO1_2_KP_DKIN_1 MFP_CFG_LPM(GPIO1_2, AF2, FLOAT)
4249+#define GPIO2_2_KP_DKIN_6 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
4250+#define GPIO3_2_KP_DKIN_7 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
4251+#define GPIO4_2_KP_DKIN_1 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
4252+#define GPIO5_2_KP_DKIN_0 MFP_CFG_LPM(GPIO5_2, AF2, FLOAT)
4253+
4254+#define GPIO5_KP_MKIN_0 MFP_CFG_LPM(GPIO5, AF2, FLOAT)
4255+#define GPIO6_KP_MKIN_1 MFP_CFG_LPM(GPIO6, AF2, FLOAT)
4256+#define GPIO9_KP_MKIN_6 MFP_CFG_LPM(GPIO9, AF3, FLOAT)
4257+#define GPIO10_KP_MKIN_7 MFP_CFG_LPM(GPIO10, AF3, FLOAT)
4258+#define GPIO70_KP_MKIN_6 MFP_CFG_LPM(GPIO70, AF3, FLOAT)
4259+#define GPIO71_KP_MKIN_7 MFP_CFG_LPM(GPIO71, AF3, FLOAT)
4260+#define GPIO100_KP_MKIN_6 MFP_CFG_LPM(GPIO100, AF7, FLOAT)
4261+#define GPIO101_KP_MKIN_7 MFP_CFG_LPM(GPIO101, AF7, FLOAT)
4262+#define GPIO112_KP_MKIN_6 MFP_CFG_LPM(GPIO112, AF4, FLOAT)
4263+#define GPIO113_KP_MKIN_7 MFP_CFG_LPM(GPIO113, AF4, FLOAT)
4264+#define GPIO115_KP_MKIN_0 MFP_CFG_LPM(GPIO115, AF1, FLOAT)
4265+#define GPIO116_KP_MKIN_1 MFP_CFG_LPM(GPIO116, AF1, FLOAT)
4266+#define GPIO117_KP_MKIN_2 MFP_CFG_LPM(GPIO117, AF1, FLOAT)
4267+#define GPIO118_KP_MKIN_3 MFP_CFG_LPM(GPIO118, AF1, FLOAT)
4268+#define GPIO119_KP_MKIN_4 MFP_CFG_LPM(GPIO119, AF1, FLOAT)
4269+#define GPIO120_KP_MKIN_5 MFP_CFG_LPM(GPIO120, AF1, FLOAT)
4270+#define GPIO125_KP_MKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT)
4271+#define GPIO2_2_KP_MKIN_6 MFP_CFG_LPM(GPIO2_2, AF1, FLOAT)
4272+#define GPIO3_2_KP_MKIN_7 MFP_CFG_LPM(GPIO3_2, AF1, FLOAT)
4273+
4274+#define GPIO7_KP_MKOUT_5 MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
4275+#define GPIO11_KP_MKOUT_5 MFP_CFG_LPM(GPIO11, AF3, DRIVE_HIGH)
4276+#define GPIO12_KP_MKOUT_6 MFP_CFG_LPM(GPIO12, AF3, DRIVE_HIGH)
4277+#define GPIO13_KP_MKOUT_7 MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
4278+#define GPIO19_KP_MKOUT_4 MFP_CFG_LPM(GPIO19, AF3, DRIVE_HIGH)
4279+#define GPIO20_KP_MKOUT_5 MFP_CFG_LPM(GPIO20, AF3, DRIVE_HIGH)
4280+#define GPIO38_KP_MKOUT_5 MFP_CFG_LPM(GPIO38, AF5, DRIVE_HIGH)
4281+#define GPIO53_KP_MKOUT_6 MFP_CFG_LPM(GPIO53, AF5, DRIVE_HIGH)
4282+#define GPIO78_KP_MKOUT_7 MFP_CFG_LPM(GPIO78, AF5, DRIVE_HIGH)
4283+#define GPIO85_KP_MKOUT_0 MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
4284+#define GPIO86_KP_MKOUT_1 MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
4285+#define GPIO87_KP_MKOUT_2 MFP_CFG_LPM(GPIO87, AF2, DRIVE_HIGH)
4286+#define GPIO88_KP_MKOUT_3 MFP_CFG_LPM(GPIO88, AF2, DRIVE_HIGH)
4287+#define GPIO104_KP_MKOUT_6 MFP_CFG_LPM(GPIO104, AF5, DRIVE_HIGH)
4288+#define GPIO105_KP_MKOUT_7 MFP_CFG_LPM(GPIO105, AF5, DRIVE_HIGH)
4289+#define GPIO121_KP_MKOUT_0 MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
4290+#define GPIO122_KP_MKOUT_1 MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
4291+#define GPIO123_KP_MKOUT_2 MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
4292+#define GPIO124_KP_MKOUT_3 MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
4293+#define GPIO125_KP_MKOUT_4 MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
4294+#define GPIO126_KP_MKOUT_7 MFP_CFG_LPM(GPIO126, AF4, DRIVE_HIGH)
4295+#define GPIO5_2_KP_MKOUT_6 MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
4296+#define GPIO4_2_KP_MKOUT_5 MFP_CFG_LPM(GPIO4_2, AF1, DRIVE_HIGH)
4297+#define GPIO6_2_KP_MKOUT_7 MFP_CFG_LPM(GPIO6_2, AF1, DRIVE_HIGH)
4298+
4299+/* LCD */
4300+#define GPIO54_LCD_LDD_0 MFP_CFG_DRV(GPIO54, AF1, DS01X)
4301+#define GPIO55_LCD_LDD_1 MFP_CFG_DRV(GPIO55, AF1, DS01X)
4302+#define GPIO56_LCD_LDD_2 MFP_CFG_DRV(GPIO56, AF1, DS01X)
4303+#define GPIO57_LCD_LDD_3 MFP_CFG_DRV(GPIO57, AF1, DS01X)
4304+#define GPIO58_LCD_LDD_4 MFP_CFG_DRV(GPIO58, AF1, DS01X)
4305+#define GPIO59_LCD_LDD_5 MFP_CFG_DRV(GPIO59, AF1, DS01X)
4306+#define GPIO60_LCD_LDD_6 MFP_CFG_DRV(GPIO60, AF1, DS01X)
4307+#define GPIO61_LCD_LDD_7 MFP_CFG_DRV(GPIO61, AF1, DS01X)
4308+#define GPIO62_LCD_LDD_8 MFP_CFG_DRV(GPIO62, AF1, DS01X)
4309+#define GPIO63_LCD_LDD_9 MFP_CFG_DRV(GPIO63, AF1, DS01X)
4310+#define GPIO64_LCD_LDD_10 MFP_CFG_DRV(GPIO64, AF1, DS01X)
4311+#define GPIO65_LCD_LDD_11 MFP_CFG_DRV(GPIO65, AF1, DS01X)
4312+#define GPIO66_LCD_LDD_12 MFP_CFG_DRV(GPIO66, AF1, DS01X)
4313+#define GPIO67_LCD_LDD_13 MFP_CFG_DRV(GPIO67, AF1, DS01X)
4314+#define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X)
4315+#define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X)
4316+#define GPIO70_LCD_LDD_16 MFP_CFG_DRV(GPIO70, AF1, DS01X)
4317+#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF1, DS01X)
4318+#define GPIO62_LCD_CS_N MFP_CFG_DRV(GPIO62, AF2, DS01X)
4319+#define GPIO72_LCD_FCLK MFP_CFG_DRV(GPIO72, AF1, DS01X)
4320+#define GPIO73_LCD_LCLK MFP_CFG_DRV(GPIO73, AF1, DS01X)
4321+#define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS01X)
4322+#define GPIO75_LCD_BIAS MFP_CFG_DRV(GPIO75, AF1, DS01X)
4323+#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF2, DS01X)
4324+
4325+#define GPIO15_LCD_CS_N MFP_CFG_DRV(GPIO15, AF2, DS01X)
4326+#define GPIO127_LCD_CS_N MFP_CFG_DRV(GPIO127, AF1, DS01X)
4327+#define GPIO63_LCD_VSYNC MFP_CFG_DRV(GPIO63, AF2, DS01X)
4328+
4329+/* Mini-LCD */
4330+#define GPIO72_MLCD_FCLK MFP_CFG_DRV(GPIO72, AF7, DS08X)
4331+#define GPIO73_MLCD_LCLK MFP_CFG_DRV(GPIO73, AF7, DS08X)
4332+#define GPIO54_MLCD_LDD_0 MFP_CFG_DRV(GPIO54, AF7, DS08X)
4333+#define GPIO55_MLCD_LDD_1 MFP_CFG_DRV(GPIO55, AF7, DS08X)
4334+#define GPIO56_MLCD_LDD_2 MFP_CFG_DRV(GPIO56, AF7, DS08X)
4335+#define GPIO57_MLCD_LDD_3 MFP_CFG_DRV(GPIO57, AF7, DS08X)
4336+#define GPIO58_MLCD_LDD_4 MFP_CFG_DRV(GPIO58, AF7, DS08X)
4337+#define GPIO59_MLCD_LDD_5 MFP_CFG_DRV(GPIO59, AF7, DS08X)
4338+#define GPIO60_MLCD_LDD_6 MFP_CFG_DRV(GPIO60, AF7, DS08X)
4339+#define GPIO61_MLCD_LDD_7 MFP_CFG_DRV(GPIO61, AF7, DS08X)
4340+#define GPIO62_MLCD_LDD_8 MFP_CFG_DRV(GPIO62, AF7, DS08X)
4341+#define GPIO63_MLCD_LDD_9 MFP_CFG_DRV(GPIO63, AF7, DS08X)
4342+#define GPIO64_MLCD_LDD_10 MFP_CFG_DRV(GPIO64, AF7, DS08X)
4343+#define GPIO65_MLCD_LDD_11 MFP_CFG_DRV(GPIO65, AF7, DS08X)
4344+#define GPIO66_MLCD_LDD_12 MFP_CFG_DRV(GPIO66, AF7, DS08X)
4345+#define GPIO67_MLCD_LDD_13 MFP_CFG_DRV(GPIO67, AF7, DS08X)
4346+#define GPIO68_MLCD_LDD_14 MFP_CFG_DRV(GPIO68, AF7, DS08X)
4347+#define GPIO69_MLCD_LDD_15 MFP_CFG_DRV(GPIO69, AF7, DS08X)
4348+#define GPIO74_MLCD_PCLK MFP_CFG_DRV(GPIO74, AF7, DS08X)
4349+#define GPIO75_MLCD_BIAS MFP_CFG_DRV(GPIO75, AF2, DS08X)
4350+
4351+/* MMC1 */
4352+#define GPIO7_MMC1_CLK MFP_CFG_LPM(GPIO7, AF4, DRIVE_HIGH)
4353+#define GPIO8_MMC1_CMD MFP_CFG_LPM(GPIO8, AF4, DRIVE_HIGH)
4354+#define GPIO14_MMC1_CMD MFP_CFG_LPM(GPIO14, AF5, DRIVE_HIGH)
4355+#define GPIO15_MMC1_CMD MFP_CFG_LPM(GPIO15, AF5, DRIVE_HIGH)
4356+#define GPIO3_MMC1_DAT0 MFP_CFG_LPM(GPIO3, AF4, DRIVE_HIGH)
4357+#define GPIO4_MMC1_DAT1 MFP_CFG_LPM(GPIO4, AF4, DRIVE_HIGH)
4358+#define GPIO5_MMC1_DAT2 MFP_CFG_LPM(GPIO5, AF4, DRIVE_HIGH)
4359+#define GPIO6_MMC1_DAT3 MFP_CFG_LPM(GPIO6, AF4, DRIVE_HIGH)
4360+
4361+/* MMC2 */
4362+#define GPIO9_MMC2_DAT0 MFP_CFG_LPM(GPIO9, AF4, PULL_HIGH)
4363+#define GPIO10_MMC2_DAT1 MFP_CFG_LPM(GPIO10, AF4, PULL_HIGH)
4364+#define GPIO11_MMC2_DAT2 MFP_CFG_LPM(GPIO11, AF4, PULL_HIGH)
4365+#define GPIO12_MMC2_DAT3 MFP_CFG_LPM(GPIO12, AF4, PULL_HIGH)
4366+#define GPIO13_MMC2_CLK MFP_CFG_LPM(GPIO13, AF4, PULL_HIGH)
4367+#define GPIO14_MMC2_CMD MFP_CFG_LPM(GPIO14, AF4, PULL_HIGH)
4368+#define GPIO77_MMC2_DAT0 MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
4369+#define GPIO78_MMC2_DAT1 MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
4370+#define GPIO79_MMC2_DAT2 MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
4371+#define GPIO80_MMC2_DAT3 MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
4372+#define GPIO81_MMC2_CLK MFP_CFG_LPM(GPIO81, AF4, PULL_HIGH)
4373+#define GPIO82_MMC2_CMD MFP_CFG_LPM(GPIO82, AF4, PULL_HIGH)
4374+
4375+/* SSP1 */
4376+#define GPIO89_SSP1_EXTCLK MFP_CFG(GPIO89, AF1)
4377+#define GPIO90_SSP1_SYSCLK MFP_CFG(GPIO90, AF1)
4378+#define GPIO15_SSP1_SCLK MFP_CFG(GPIO15, AF6)
4379+#define GPIO16_SSP1_FRM MFP_CFG(GPIO16, AF2)
4380+#define GPIO33_SSP1_SCLK MFP_CFG(GPIO33, AF5)
4381+#define GPIO34_SSP1_FRM MFP_CFG(GPIO34, AF5)
4382+#define GPIO85_SSP1_SCLK MFP_CFG(GPIO85, AF1)
4383+#define GPIO86_SSP1_FRM MFP_CFG(GPIO86, AF1)
4384+#define GPIO18_SSP1_TXD MFP_CFG(GPIO18, AF7)
4385+#define GPIO18_SSP1_RXD MFP_CFG(GPIO18, AF2)
4386+#define GPIO20_SSP1_TXD MFP_CFG(GPIO20, AF2)
4387+#define GPIO20_SSP1_RXD MFP_CFG(GPIO20, AF7)
4388+#define GPIO35_SSP1_TXD MFP_CFG(GPIO35, AF5)
4389+#define GPIO35_SSP1_RXD MFP_CFG(GPIO35, AF4)
4390+#define GPIO36_SSP1_TXD MFP_CFG(GPIO36, AF5)
4391+#define GPIO36_SSP1_RXD MFP_CFG(GPIO36, AF6)
4392+#define GPIO87_SSP1_TXD MFP_CFG(GPIO87, AF1)
4393+#define GPIO87_SSP1_RXD MFP_CFG(GPIO87, AF6)
4394+#define GPIO88_SSP1_TXD MFP_CFG(GPIO88, AF6)
4395+#define GPIO88_SSP1_RXD MFP_CFG(GPIO88, AF1)
4396+
4397+/* SSP2 */
4398+#define GPIO29_SSP2_EXTCLK MFP_CFG(GPIO29, AF2)
4399+#define GPIO23_SSP2_SCLK MFP_CFG(GPIO23, AF2)
4400+#define GPIO17_SSP2_FRM MFP_CFG(GPIO17, AF2)
4401+#define GPIO25_SSP2_SCLK MFP_CFG(GPIO25, AF2)
4402+#define GPIO26_SSP2_FRM MFP_CFG(GPIO26, AF2)
4403+#define GPIO33_SSP2_SCLK MFP_CFG(GPIO33, AF6)
4404+#define GPIO34_SSP2_FRM MFP_CFG(GPIO34, AF6)
4405+#define GPIO64_SSP2_SCLK MFP_CFG(GPIO64, AF2)
4406+#define GPIO65_SSP2_FRM MFP_CFG(GPIO65, AF2)
4407+#define GPIO19_SSP2_TXD MFP_CFG(GPIO19, AF2)
4408+#define GPIO19_SSP2_RXD MFP_CFG(GPIO19, AF7)
4409+#define GPIO24_SSP2_TXD MFP_CFG(GPIO24, AF5)
4410+#define GPIO24_SSP2_RXD MFP_CFG(GPIO24, AF4)
4411+#define GPIO27_SSP2_TXD MFP_CFG(GPIO27, AF2)
4412+#define GPIO27_SSP2_RXD MFP_CFG(GPIO27, AF5)
4413+#define GPIO28_SSP2_TXD MFP_CFG(GPIO28, AF5)
4414+#define GPIO28_SSP2_RXD MFP_CFG(GPIO28, AF2)
4415+#define GPIO35_SSP2_TXD MFP_CFG(GPIO35, AF7)
4416+#define GPIO35_SSP2_RXD MFP_CFG(GPIO35, AF6)
4417+#define GPIO66_SSP2_TXD MFP_CFG(GPIO66, AF4)
4418+#define GPIO66_SSP2_RXD MFP_CFG(GPIO66, AF2)
4419+#define GPIO67_SSP2_TXD MFP_CFG(GPIO67, AF2)
4420+#define GPIO67_SSP2_RXD MFP_CFG(GPIO67, AF4)
4421+#define GPIO36_SSP2_TXD MFP_CFG(GPIO36, AF7)
4422+
4423+/* SSP3 */
4424+#define GPIO69_SSP3_FRM MFP_CFG_X(GPIO69, AF2, DS08X, DRIVE_LOW)
4425+#define GPIO68_SSP3_SCLK MFP_CFG_X(GPIO68, AF2, DS08X, FLOAT)
4426+#define GPIO92_SSP3_FRM MFP_CFG_X(GPIO92, AF1, DS08X, DRIVE_LOW)
4427+#define GPIO91_SSP3_SCLK MFP_CFG_X(GPIO91, AF1, DS08X, FLOAT)
4428+#define GPIO70_SSP3_TXD MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
4429+#define GPIO70_SSP3_RXD MFP_CFG_X(GPIO70, AF5, DS08X, FLOAT)
4430+#define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF5, DS08X, DRIVE_LOW)
4431+#define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF2, DS08X, FLOAT)
4432+#define GPIO93_SSP3_TXD MFP_CFG_X(GPIO93, AF1, DS08X, DRIVE_LOW)
4433+#define GPIO93_SSP3_RXD MFP_CFG_X(GPIO93, AF5, DS08X, FLOAT)
4434+#define GPIO94_SSP3_TXD MFP_CFG_X(GPIO94, AF5, DS08X, DRIVE_LOW)
4435+#define GPIO94_SSP3_RXD MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)
4436+
4437+/* SSP4 */
4438+#define GPIO95_SSP4_SCLK MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
4439+#define GPIO96_SSP4_FRM MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
4440+#define GPIO97_SSP4_TXD MFP_CFG_LPM(GPIO97, AF1, PULL_HIGH)
4441+#define GPIO97_SSP4_RXD MFP_CFG_LPM(GPIO97, AF5, PULL_HIGH)
4442+#define GPIO98_SSP4_TXD MFP_CFG_LPM(GPIO98, AF5, PULL_HIGH)
4443+#define GPIO98_SSP4_RXD MFP_CFG_LPM(GPIO98, AF1, PULL_HIGH)
4444+
4445+/* UART1 */
4446+#define GPIO32_UART1_CTS MFP_CFG_LPM(GPIO32, AF2, FLOAT)
4447+#define GPIO37_UART1_CTS MFP_CFG_LPM(GPIO37, AF4, FLOAT)
4448+#define GPIO79_UART1_CTS MFP_CFG_LPM(GPIO79, AF1, FLOAT)
4449+#define GPIO84_UART1_CTS MFP_CFG_LPM(GPIO84, AF3, FLOAT)
4450+#define GPIO101_UART1_CTS MFP_CFG_LPM(GPIO101, AF1, FLOAT)
4451+#define GPIO106_UART1_CTS MFP_CFG_LPM(GPIO106, AF6, FLOAT)
4452+
4453+#define GPIO32_UART1_RTS MFP_CFG_LPM(GPIO32, AF4, FLOAT)
4454+#define GPIO37_UART1_RTS MFP_CFG_LPM(GPIO37, AF2, FLOAT)
4455+#define GPIO79_UART1_RTS MFP_CFG_LPM(GPIO79, AF3, FLOAT)
4456+#define GPIO84_UART1_RTS MFP_CFG_LPM(GPIO84, AF1, FLOAT)
4457+#define GPIO101_UART1_RTS MFP_CFG_LPM(GPIO101, AF6, FLOAT)
4458+#define GPIO106_UART1_RTS MFP_CFG_LPM(GPIO106, AF1, FLOAT)
4459+
4460+#define GPIO34_UART1_DSR MFP_CFG_LPM(GPIO34, AF2, FLOAT)
4461+#define GPIO36_UART1_DSR MFP_CFG_LPM(GPIO36, AF4, FLOAT)
4462+#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF1, FLOAT)
4463+#define GPIO83_UART1_DSR MFP_CFG_LPM(GPIO83, AF3, FLOAT)
4464+#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
4465+#define GPIO105_UART1_DSR MFP_CFG_LPM(GPIO105, AF6, FLOAT)
4466+
4467+#define GPIO34_UART1_DTR MFP_CFG_LPM(GPIO34, AF4, FLOAT)
4468+#define GPIO36_UART1_DTR MFP_CFG_LPM(GPIO36, AF2, FLOAT)
4469+#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF3, FLOAT)
4470+#define GPIO83_UART1_DTR MFP_CFG_LPM(GPIO83, AF1, FLOAT)
4471+#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
4472+#define GPIO105_UART1_DTR MFP_CFG_LPM(GPIO105, AF1, FLOAT)
4473+
4474+#define GPIO35_UART1_RI MFP_CFG_LPM(GPIO35, AF2, FLOAT)
4475+#define GPIO82_UART1_RI MFP_CFG_LPM(GPIO82, AF1, FLOAT)
4476+#define GPIO104_UART1_RI MFP_CFG_LPM(GPIO104, AF1, FLOAT)
4477+
4478+#define GPIO33_UART1_DCD MFP_CFG_LPM(GPIO33, AF2, FLOAT)
4479+#define GPIO80_UART1_DCD MFP_CFG_LPM(GPIO80, AF1, FLOAT)
4480+#define GPIO102_UART1_DCD MFP_CFG_LPM(GPIO102, AF1, FLOAT)
4481+
4482+#define GPIO30_UART1_RXD MFP_CFG_LPM(GPIO30, AF2, FLOAT)
4483+#define GPIO31_UART1_RXD MFP_CFG_LPM(GPIO31, AF4, FLOAT)
4484+#define GPIO77_UART1_RXD MFP_CFG_LPM(GPIO77, AF1, FLOAT)
4485+#define GPIO78_UART1_RXD MFP_CFG_LPM(GPIO78, AF3, FLOAT)
4486+#define GPIO99_UART1_RXD MFP_CFG_LPM(GPIO99, AF1, FLOAT)
4487+#define GPIO100_UART1_RXD MFP_CFG_LPM(GPIO100, AF6, FLOAT)
4488+#define GPIO102_UART1_RXD MFP_CFG_LPM(GPIO102, AF6, FLOAT)
4489+#define GPIO104_UART1_RXD MFP_CFG_LPM(GPIO104, AF4, FLOAT)
4490+
4491+#define GPIO30_UART1_TXD MFP_CFG_LPM(GPIO30, AF4, FLOAT)
4492+#define GPIO31_UART1_TXD MFP_CFG_LPM(GPIO31, AF2, FLOAT)
4493+#define GPIO77_UART1_TXD MFP_CFG_LPM(GPIO77, AF3, FLOAT)
4494+#define GPIO78_UART1_TXD MFP_CFG_LPM(GPIO78, AF1, FLOAT)
4495+#define GPIO99_UART1_TXD MFP_CFG_LPM(GPIO99, AF6, FLOAT)
4496+#define GPIO100_UART1_TXD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
4497+#define GPIO102_UART1_TXD MFP_CFG_LPM(GPIO102, AF4, FLOAT)
4498+
4499+/* UART2 */
4500+#define GPIO15_UART2_CTS MFP_CFG_LPM(GPIO15, AF3, FLOAT)
4501+#define GPIO16_UART2_CTS MFP_CFG_LPM(GPIO16, AF5, FLOAT)
4502+#define GPIO111_UART2_CTS MFP_CFG_LPM(GPIO111, AF3, FLOAT)
4503+#define GPIO114_UART2_CTS MFP_CFG_LPM(GPIO114, AF1, FLOAT)
4504+
4505+#define GPIO15_UART2_RTS MFP_CFG_LPM(GPIO15, AF4, FLOAT)
4506+#define GPIO16_UART2_RTS MFP_CFG_LPM(GPIO16, AF4, FLOAT)
4507+#define GPIO114_UART2_RTS MFP_CFG_LPM(GPIO114, AF3, FLOAT)
4508+#define GPIO111_UART2_RTS MFP_CFG_LPM(GPIO111, AF1, FLOAT)
4509+
4510+#define GPIO18_UART2_RXD MFP_CFG_LPM(GPIO18, AF5, FLOAT)
4511+#define GPIO19_UART2_RXD MFP_CFG_LPM(GPIO19, AF4, FLOAT)
4512+#define GPIO112_UART2_RXD MFP_CFG_LPM(GPIO112, AF1, FLOAT)
4513+#define GPIO113_UART2_RXD MFP_CFG_LPM(GPIO113, AF3, FLOAT)
4514+
4515+#define GPIO18_UART2_TXD MFP_CFG_LPM(GPIO18, AF4, FLOAT)
4516+#define GPIO19_UART2_TXD MFP_CFG_LPM(GPIO19, AF5, FLOAT)
4517+#define GPIO112_UART2_TXD MFP_CFG_LPM(GPIO112, AF3, FLOAT)
4518+#define GPIO113_UART2_TXD MFP_CFG_LPM(GPIO113, AF1, FLOAT)
4519+
4520+/* UART3 */
4521+#define GPIO91_UART3_CTS MFP_CFG_LPM(GPIO91, AF2, FLOAT)
4522+#define GPIO92_UART3_CTS MFP_CFG_LPM(GPIO92, AF4, FLOAT)
4523+#define GPIO107_UART3_CTS MFP_CFG_LPM(GPIO107, AF1, FLOAT)
4524+#define GPIO108_UART3_CTS MFP_CFG_LPM(GPIO108, AF3, FLOAT)
4525+
4526+#define GPIO91_UART3_RTS MFP_CFG_LPM(GPIO91, AF4, FLOAT)
4527+#define GPIO92_UART3_RTS MFP_CFG_LPM(GPIO92, AF2, FLOAT)
4528+#define GPIO107_UART3_RTS MFP_CFG_LPM(GPIO107, AF3, FLOAT)
4529+#define GPIO108_UART3_RTS MFP_CFG_LPM(GPIO108, AF1, FLOAT)
4530+
4531+#define GPIO7_UART3_RXD MFP_CFG_LPM(GPIO7, AF2, FLOAT)
4532+#define GPIO8_UART3_RXD MFP_CFG_LPM(GPIO8, AF6, FLOAT)
4533+#define GPIO93_UART3_RXD MFP_CFG_LPM(GPIO93, AF4, FLOAT)
4534+#define GPIO94_UART3_RXD MFP_CFG_LPM(GPIO94, AF2, FLOAT)
4535+#define GPIO109_UART3_RXD MFP_CFG_LPM(GPIO109, AF3, FLOAT)
4536+#define GPIO110_UART3_RXD MFP_CFG_LPM(GPIO110, AF1, FLOAT)
4537+
4538+#define GPIO7_UART3_TXD MFP_CFG_LPM(GPIO7, AF6, FLOAT)
4539+#define GPIO8_UART3_TXD MFP_CFG_LPM(GPIO8, AF2, FLOAT)
4540+#define GPIO93_UART3_TXD MFP_CFG_LPM(GPIO93, AF2, FLOAT)
4541+#define GPIO94_UART3_TXD MFP_CFG_LPM(GPIO94, AF4, FLOAT)
4542+#define GPIO109_UART3_TXD MFP_CFG_LPM(GPIO109, AF1, FLOAT)
4543+#define GPIO110_UART3_TXD MFP_CFG_LPM(GPIO110, AF3, FLOAT)
4544+
4545+/* USB Host */
4546+#define GPIO0_2_USBH_PEN MFP_CFG(GPIO0_2, AF1)
4547+#define GPIO1_2_USBH_PWR MFP_CFG(GPIO1_2, AF1)
4548+
4549+/* USB P3 */
4550+#define GPIO77_USB_P3_1 MFP_CFG(GPIO77, AF2)
4551+#define GPIO78_USB_P3_2 MFP_CFG(GPIO78, AF2)
4552+#define GPIO79_USB_P3_3 MFP_CFG(GPIO79, AF2)
4553+#define GPIO80_USB_P3_4 MFP_CFG(GPIO80, AF2)
4554+#define GPIO81_USB_P3_5 MFP_CFG(GPIO81, AF2)
4555+#define GPIO82_USB_P3_6 MFP_CFG(GPIO82, AF2)
4556+
4557+/* PWM */
4558+#define GPIO17_PWM0_OUT MFP_CFG(GPIO17, AF1)
4559+#define GPIO18_PWM1_OUT MFP_CFG(GPIO18, AF1)
4560+#define GPIO19_PWM2_OUT MFP_CFG(GPIO19, AF1)
4561+#define GPIO20_PWM3_OUT MFP_CFG(GPIO20, AF1)
4562+
4563+/* CIR */
4564+#define GPIO8_CIR_OUT MFP_CFG(GPIO8, AF5)
4565+#define GPIO16_CIR_OUT MFP_CFG(GPIO16, AF3)
4566+
4567+#define GPIO20_OW_DQ_IN MFP_CFG(GPIO20, AF5)
4568+#define GPIO126_OW_DQ MFP_CFG(GPIO126, AF2)
4569+
4570+#define GPIO0_DF_RDY MFP_CFG(GPIO0, AF1)
4571+#define GPIO7_CLK_BYPASS_XSC MFP_CFG(GPIO7, AF7)
4572+#define GPIO17_EXT_SYNC_MVT_0 MFP_CFG(GPIO17, AF6)
4573+#define GPIO18_EXT_SYNC_MVT_1 MFP_CFG(GPIO18, AF6)
4574+#define GPIO19_OST_CHOUT_MVT_0 MFP_CFG(GPIO19, AF6)
4575+#define GPIO20_OST_CHOUT_MVT_1 MFP_CFG(GPIO20, AF6)
4576+#define GPIO49_48M_CLK MFP_CFG(GPIO49, AF2)
4577+#define GPIO126_EXT_CLK MFP_CFG(GPIO126, AF3)
4578+#define GPIO127_CLK_BYPASS_GB MFP_CFG(GPIO127, AF7)
4579+#define GPIO71_EXT_MATCH_MVT MFP_CFG(GPIO71, AF6)
4580+
4581+#define GPIO3_uIO_IN MFP_CFG(GPIO3, AF1)
4582+
4583+#define GPIO4_uSIM_CARD_STATE MFP_CFG(GPIO4, AF1)
4584+#define GPIO5_uSIM_uCLK MFP_CFG(GPIO5, AF1)
4585+#define GPIO6_uSIM_uRST MFP_CFG(GPIO6, AF1)
4586+#define GPIO16_uSIM_UVS_0 MFP_CFG(GPIO16, AF1)
4587+
4588+#define GPIO9_SCIO MFP_CFG(GPIO9, AF1)
4589+#define GPIO20_RTC_MVT MFP_CFG(GPIO20, AF4)
4590+#define GPIO126_RTC_MVT MFP_CFG(GPIO126, AF1)
4591+
4592+/*
4593+ * PXA300 specific MFP configurations
4594+ */
4595+#ifdef CONFIG_CPU_PXA300
4596+#define GPIO99_USB_P2_2 MFP_CFG(GPIO99, AF2)
4597+#define GPIO99_USB_P2_5 MFP_CFG(GPIO99, AF3)
4598+#define GPIO99_USB_P2_6 MFP_CFG(GPIO99, AF4)
4599+#define GPIO100_USB_P2_2 MFP_CFG(GPIO100, AF4)
4600+#define GPIO100_USB_P2_5 MFP_CFG(GPIO100, AF5)
4601+#define GPIO101_USB_P2_1 MFP_CFG(GPIO101, AF2)
4602+#define GPIO102_USB_P2_4 MFP_CFG(GPIO102, AF2)
4603+#define GPIO104_USB_P2_3 MFP_CFG(GPIO104, AF2)
4604+#define GPIO105_USB_P2_5 MFP_CFG(GPIO105, AF2)
4605+#define GPIO100_USB_P2_6 MFP_CFG(GPIO100, AF2)
4606+#define GPIO106_USB_P2_7 MFP_CFG(GPIO106, AF2)
4607+#define GPIO103_USB_P2_8 MFP_CFG(GPIO103, AF2)
4608+
4609+/* U2D UTMI */
4610+#define GPIO38_UTM_CLK MFP_CFG(GPIO38, AF1)
4611+#define GPIO26_U2D_RXERROR MFP_CFG(GPIO26, AF3)
4612+#define GPIO50_U2D_RXERROR MFP_CFG(GPIO50, AF1)
4613+#define GPIO89_U2D_RXERROR MFP_CFG(GPIO89, AF5)
4614+#define GPIO24_UTM_RXVALID MFP_CFG(GPIO24, AF3)
4615+#define GPIO48_UTM_RXVALID MFP_CFG(GPIO48, AF2)
4616+#define GPIO87_UTM_RXVALID MFP_CFG(GPIO87, AF5)
4617+#define GPIO25_UTM_RXACTIVE MFP_CFG(GPIO25, AF3)
4618+#define GPIO47_UTM_RXACTIVE MFP_CFG(GPIO47, AF2)
4619+#define GPIO49_UTM_RXACTIVE MFP_CFG(GPIO49, AF1)
4620+#define GPIO88_UTM_RXACTIVE MFP_CFG(GPIO88, AF5)
4621+#define GPIO53_UTM_TXREADY MFP_CFG(GPIO53, AF1)
4622+#define GPIO67_UTM_LINESTATE_0 MFP_CFG(GPIO67, AF3)
4623+#define GPIO92_UTM_LINESTATE_0 MFP_CFG(GPIO92, AF3)
4624+#define GPIO104_UTM_LINESTATE_0 MFP_CFG(GPIO104, AF3)
4625+#define GPIO109_UTM_LINESTATE_0 MFP_CFG(GPIO109, AF4)
4626+#define GPIO68_UTM_LINESTATE_1 MFP_CFG(GPIO68, AF3)
4627+#define GPIO93_UTM_LINESTATE_1 MFP_CFG(GPIO93, AF3)
4628+#define GPIO105_UTM_LINESTATE_1 MFP_CFG(GPIO105, AF3)
4629+#define GPIO27_U2D_OPMODE_0 MFP_CFG(GPIO27, AF4)
4630+#define GPIO51_U2D_OPMODE_0 MFP_CFG(GPIO51, AF2)
4631+#define GPIO90_U2D_OPMODE_0 MFP_CFG(GPIO90, AF7)
4632+#define GPIO28_U2D_OPMODE_1 MFP_CFG(GPIO28, AF4)
4633+#define GPIO52_U2D_OPMODE_1 MFP_CFG(GPIO52, AF2)
4634+#define GPIO106_U2D_OPMODE_1 MFP_CFG(GPIO106, AF3)
4635+#define GPIO110_U2D_OPMODE_1 MFP_CFG(GPIO110, AF5)
4636+#define GPIO76_U2D_RESET MFP_CFG(GPIO76, AF1)
4637+#define GPIO95_U2D_RESET MFP_CFG(GPIO95, AF2)
4638+#define GPIO100_U2D_RESET MFP_CFG(GPIO100, AF3)
4639+#define GPIO66_U2D_SUSPEND MFP_CFG(GPIO66, AF3)
4640+#define GPIO98_U2D_SUSPEND MFP_CFG(GPIO98, AF2)
4641+#define GPIO103_U2D_SUSPEND MFP_CFG(GPIO103, AF3)
4642+#define GPIO65_U2D_TERM_SEL MFP_CFG(GPIO65, AF5)
4643+#define GPIO97_U2D_TERM_SEL MFP_CFG(GPIO97, AF3)
4644+#define GPIO102_U2D_TERM_SEL MFP_CFG(GPIO102, AF5)
4645+#define GPIO29_U2D_TXVALID MFP_CFG(GPIO29, AF3)
4646+#define GPIO52_U2D_TXVALID MFP_CFG(GPIO52, AF4)
4647+#define GPIO69_U2D_TXVALID MFP_CFG(GPIO69, AF3)
4648+#define GPIO85_U2D_TXVALID MFP_CFG(GPIO85, AF7)
4649+#define GPIO64_U2D_XCVR_SEL MFP_CFG(GPIO64, AF5)
4650+#define GPIO96_U2D_XCVR_SEL MFP_CFG(GPIO96, AF3)
4651+#define GPIO101_U2D_XCVR_SEL MFP_CFG(GPIO101, AF5)
4652+#define GPIO30_UTM_PHYDATA_0 MFP_CFG(GPIO30, AF3)
4653+#define GPIO31_UTM_PHYDATA_1 MFP_CFG(GPIO31, AF3)
4654+#define GPIO32_UTM_PHYDATA_2 MFP_CFG(GPIO32, AF3)
4655+#define GPIO33_UTM_PHYDATA_3 MFP_CFG(GPIO33, AF3)
4656+#define GPIO34_UTM_PHYDATA_4 MFP_CFG(GPIO34, AF3)
4657+#define GPIO35_UTM_PHYDATA_5 MFP_CFG(GPIO35, AF3)
4658+#define GPIO36_UTM_PHYDATA_6 MFP_CFG(GPIO36, AF3)
4659+#define GPIO37_UTM_PHYDATA_7 MFP_CFG(GPIO37, AF3)
4660+#define GPIO39_UTM_PHYDATA_0 MFP_CFG(GPIO39, AF3)
4661+#define GPIO40_UTM_PHYDATA_1 MFP_CFG(GPIO40, AF3)
4662+#define GPIO41_UTM_PHYDATA_2 MFP_CFG(GPIO41, AF3)
4663+#define GPIO42_UTM_PHYDATA_3 MFP_CFG(GPIO42, AF3)
4664+#define GPIO43_UTM_PHYDATA_4 MFP_CFG(GPIO43, AF3)
4665+#define GPIO44_UTM_PHYDATA_5 MFP_CFG(GPIO44, AF3)
4666+#define GPIO45_UTM_PHYDATA_6 MFP_CFG(GPIO45, AF3)
4667+#define GPIO46_UTM_PHYDATA_7 MFP_CFG(GPIO46, AF3)
4668+#endif /* CONFIG_CPU_PXA300 */
4669+
4670+/*
4671+ * PXA310 specific MFP configurations
4672+ */
4673+#ifdef CONFIG_CPU_PXA310
4674+/* USB P2 */
4675+#define GPIO36_USB_P2_1 MFP_CFG(GPIO36, AF1)
4676+#define GPIO30_USB_P2_2 MFP_CFG(GPIO30, AF1)
4677+#define GPIO35_USB_P2_3 MFP_CFG(GPIO35, AF1)
4678+#define GPIO32_USB_P2_4 MFP_CFG(GPIO32, AF1)
4679+#define GPIO34_USB_P2_5 MFP_CFG(GPIO34, AF1)
4680+#define GPIO31_USB_P2_6 MFP_CFG(GPIO31, AF1)
4681+
4682+/* MMC1 */
4683+#define GPIO24_MMC1_CMD MFP_CFG(GPIO24, AF3)
4684+#define GPIO29_MMC1_DAT0 MFP_CFG(GPIO29, AF3)
4685+
4686+/* MMC3 */
4687+#define GPIO103_MMC3_CLK MFP_CFG(GPIO103, AF2)
4688+#define GPIO105_MMC3_CMD MFP_CFG(GPIO105, AF2)
4689+#define GPIO11_2_MMC3_CLK MFP_CFG(GPIO11_2, AF1)
4690+#define GPIO12_2_MMC3_CMD MFP_CFG(GPIO12_2, AF1)
4691+#define GPIO7_2_MMC3_DAT0 MFP_CFG(GPIO7_2, AF1)
4692+#define GPIO8_2_MMC3_DAT1 MFP_CFG(GPIO8_2, AF1)
4693+#define GPIO9_2_MMC3_DAT2 MFP_CFG(GPIO9_2, AF1)
4694+#define GPIO10_2_MMC3_DAT3 MFP_CFG(GPIO10_2, AF1)
4695+
4696+/* ULPI */
4697+#define GPIO38_ULPI_CLK MFP_CFG(GPIO38, AF1)
4698+#define GPIO30_ULPI_DATA_OUT_0 MFP_CFG(GPIO30, AF3)
4699+#define GPIO31_ULPI_DATA_OUT_1 MFP_CFG(GPIO31, AF3)
4700+#define GPIO32_ULPI_DATA_OUT_2 MFP_CFG(GPIO32, AF3)
4701+#define GPIO33_ULPI_DATA_OUT_3 MFP_CFG(GPIO33, AF3)
4702+#define GPIO34_ULPI_DATA_OUT_4 MFP_CFG(GPIO34, AF3)
4703+#define GPIO35_ULPI_DATA_OUT_5 MFP_CFG(GPIO35, AF3)
4704+#define GPIO36_ULPI_DATA_OUT_6 MFP_CFG(GPIO36, AF3)
4705+#define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3)
4706+#define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1)
4707+
4708+#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, MFP_AF0, MFP_DS01X)
4709+#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, MFP_AF0, MFP_DS01X)
4710+#define ULPI_STP MFP_CFG_DRV(ULPI_STP, MFP_AF0, MFP_DS01X)
4711+#endif /* CONFIG_CPU_PXA310 */
4712+
4713+#endif /* __ASM_ARCH_MFP_PXA300_H */
4714--- /dev/null
4715+++ linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa320.h
4716@@ -0,0 +1,446 @@
4717+/*
4718+ * linux/include/asm-arm/arch-pxa/mfp-pxa320.h
4719+ *
4720+ * PXA320 specific MFP configuration definitions
4721+ *
4722+ * Copyright (C) 2007 Marvell International Ltd.
4723+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
4724+ * initial version
4725+ *
4726+ * This program is free software; you can redistribute it and/or modify
4727+ * it under the terms of the GNU General Public License version 2 as
4728+ * published by the Free Software Foundation.
4729+ */
4730+
4731+#ifndef __ASM_ARCH_MFP_PXA320_H
4732+#define __ASM_ARCH_MFP_PXA320_H
4733+
4734+#include <asm/arch/mfp.h>
4735+
4736+/* GPIO */
4737+#define GPIO46_GPIO MFP_CFG(GPIO6, AF0)
4738+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
4739+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
4740+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
4741+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
4742+
4743+#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0)
4744+#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0)
4745+#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0)
4746+#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0)
4747+#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0)
4748+#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0)
4749+#define GPIO13_2_GPIO MFP_CFG(GPIO13_2, AF0)
4750+#define GPIO14_2_GPIO MFP_CFG(GPIO14_2, AF0)
4751+#define GPIO15_2_GPIO MFP_CFG(GPIO15_2, AF0)
4752+#define GPIO16_2_GPIO MFP_CFG(GPIO16_2, AF0)
4753+#define GPIO17_2_GPIO MFP_CFG(GPIO17_2, AF0)
4754+
4755+/* Chip Select */
4756+#define GPIO4_nCS3 MFP_CFG(GPIO4, AF1)
4757+
4758+/* AC97 */
4759+#define GPIO34_AC97_SYSCLK MFP_CFG(GPIO34, AF1)
4760+#define GPIO39_AC97_BITCLK MFP_CFG(GPIO39, AF1)
4761+#define GPIO40_AC97_nACRESET MFP_CFG(GPIO40, AF1)
4762+#define GPIO35_AC97_SDATA_IN_0 MFP_CFG(GPIO35, AF1)
4763+#define GPIO36_AC97_SDATA_IN_1 MFP_CFG(GPIO36, AF1)
4764+#define GPIO32_AC97_SDATA_IN_2 MFP_CFG(GPIO32, AF2)
4765+#define GPIO33_AC97_SDATA_IN_3 MFP_CFG(GPIO33, AF2)
4766+#define GPIO11_AC97_SDATA_IN_2 MFP_CFG(GPIO11, AF3)
4767+#define GPIO12_AC97_SDATA_IN_3 MFP_CFG(GPIO12, AF3)
4768+#define GPIO37_AC97_SDATA_OUT MFP_CFG(GPIO37, AF1)
4769+#define GPIO38_AC97_SYNC MFP_CFG(GPIO38, AF1)
4770+
4771+/* I2C */
4772+#define GPIO32_I2C_SCL MFP_CFG_LPM(GPIO32, AF1, PULL_HIGH)
4773+#define GPIO33_I2C_SDA MFP_CFG_LPM(GPIO33, AF1, PULL_HIGH)
4774+
4775+/* QCI */
4776+#define GPIO49_CI_DD_0 MFP_CFG_DRV(GPIO49, AF1, DS04X)
4777+#define GPIO50_CI_DD_1 MFP_CFG_DRV(GPIO50, AF1, DS04X)
4778+#define GPIO51_CI_DD_2 MFP_CFG_DRV(GPIO51, AF1, DS04X)
4779+#define GPIO52_CI_DD_3 MFP_CFG_DRV(GPIO52, AF1, DS04X)
4780+#define GPIO53_CI_DD_4 MFP_CFG_DRV(GPIO53, AF1, DS04X)
4781+#define GPIO54_CI_DD_5 MFP_CFG_DRV(GPIO54, AF1, DS04X)
4782+#define GPIO55_CI_DD_6 MFP_CFG_DRV(GPIO55, AF1, DS04X)
4783+#define GPIO56_CI_DD_7 MFP_CFG_DRV(GPIO56, AF0, DS04X)
4784+#define GPIO57_CI_DD_8 MFP_CFG_DRV(GPIO57, AF1, DS04X)
4785+#define GPIO58_CI_DD_9 MFP_CFG_DRV(GPIO58, AF1, DS04X)
4786+#define GPIO59_CI_MCLK MFP_CFG_DRV(GPIO59, AF0, DS04X)
4787+#define GPIO60_CI_PCLK MFP_CFG_DRV(GPIO60, AF0, DS04X)
4788+#define GPIO61_CI_HSYNC MFP_CFG_DRV(GPIO61, AF0, DS04X)
4789+#define GPIO62_CI_VSYNC MFP_CFG_DRV(GPIO62, AF0, DS04X)
4790+
4791+#define GPIO31_CIR_OUT MFP_CFG(GPIO31, AF5)
4792+
4793+#define GPIO0_2_CLK_EXT MFP_CFG(GPIO0_2, AF3)
4794+#define GPIO0_DRQ MFP_CFG(GPIO0, AF2)
4795+#define GPIO11_EXT_SYNC0 MFP_CFG(GPIO11, AF5)
4796+#define GPIO12_EXT_SYNC1 MFP_CFG(GPIO12, AF6)
4797+#define GPIO0_2_HZ_CLK MFP_CFG(GPIO0_2, AF1)
4798+#define GPIO14_HZ_CLK MFP_CFG(GPIO14, AF4)
4799+#define GPIO30_ICP_RXD MFP_CFG(GPIO30, AF1)
4800+#define GPIO31_ICP_TXD MFP_CFG(GPIO31, AF1)
4801+
4802+#define GPIO83_KP_DKIN_0 MFP_CFG_LPM(GPIO83, AF3, FLOAT)
4803+#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF3, FLOAT)
4804+#define GPIO85_KP_DKIN_2 MFP_CFG_LPM(GPIO85, AF3, FLOAT)
4805+#define GPIO86_KP_DKIN_3 MFP_CFG_LPM(GPIO86, AF3, FLOAT)
4806+
4807+#define GPIO105_KP_DKIN_0 MFP_CFG_LPM(GPIO105, AF2, FLOAT)
4808+#define GPIO106_KP_DKIN_1 MFP_CFG_LPM(GPIO106, AF2, FLOAT)
4809+#define GPIO107_KP_DKIN_2 MFP_CFG_LPM(GPIO107, AF2, FLOAT)
4810+#define GPIO108_KP_DKIN_3 MFP_CFG_LPM(GPIO108, AF2, FLOAT)
4811+#define GPIO109_KP_DKIN_4 MFP_CFG_LPM(GPIO109, AF2, FLOAT)
4812+#define GPIO110_KP_DKIN_5 MFP_CFG_LPM(GPIO110, AF2, FLOAT)
4813+#define GPIO111_KP_DKIN_6 MFP_CFG_LPM(GPIO111, AF2, FLOAT)
4814+#define GPIO112_KP_DKIN_7 MFP_CFG_LPM(GPIO112, AF2, FLOAT)
4815+
4816+#define GPIO113_KP_DKIN_0 MFP_CFG_LPM(GPIO113, AF2, FLOAT)
4817+#define GPIO114_KP_DKIN_1 MFP_CFG_LPM(GPIO114, AF2, FLOAT)
4818+#define GPIO115_KP_DKIN_2 MFP_CFG_LPM(GPIO115, AF2, FLOAT)
4819+#define GPIO116_KP_DKIN_3 MFP_CFG_LPM(GPIO116, AF2, FLOAT)
4820+#define GPIO117_KP_DKIN_4 MFP_CFG_LPM(GPIO117, AF2, FLOAT)
4821+#define GPIO118_KP_DKIN_5 MFP_CFG_LPM(GPIO118, AF2, FLOAT)
4822+#define GPIO119_KP_DKIN_6 MFP_CFG_LPM(GPIO119, AF2, FLOAT)
4823+#define GPIO120_KP_DKIN_7 MFP_CFG_LPM(GPIO120, AF2, FLOAT)
4824+
4825+#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF2, FLOAT)
4826+#define GPIO126_KP_DKIN_1 MFP_CFG_LPM(GPIO126, AF2, FLOAT)
4827+
4828+#define GPIO2_2_KP_DKIN_0 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
4829+#define GPIO3_2_KP_DKIN_1 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
4830+#define GPIO125_KP_DKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT)
4831+#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT)
4832+#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT)
4833+#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT)
4834+#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT)
4835+#define GPIO4_2_KP_DKIN_7 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
4836+
4837+#define GPIO113_KP_MKIN_0 MFP_CFG_LPM(GPIO113, AF1, FLOAT)
4838+#define GPIO114_KP_MKIN_1 MFP_CFG_LPM(GPIO114, AF1, FLOAT)
4839+#define GPIO115_KP_MKIN_2 MFP_CFG_LPM(GPIO115, AF1, FLOAT)
4840+#define GPIO116_KP_MKIN_3 MFP_CFG_LPM(GPIO116, AF1, FLOAT)
4841+#define GPIO117_KP_MKIN_4 MFP_CFG_LPM(GPIO117, AF1, FLOAT)
4842+#define GPIO118_KP_MKIN_5 MFP_CFG_LPM(GPIO118, AF1, FLOAT)
4843+#define GPIO119_KP_MKIN_6 MFP_CFG_LPM(GPIO119, AF1, FLOAT)
4844+#define GPIO120_KP_MKIN_7 MFP_CFG_LPM(GPIO120, AF1, FLOAT)
4845+
4846+#define GPIO83_KP_MKOUT_0 MFP_CFG_LPM(GPIO83, AF2, DRIVE_HIGH)
4847+#define GPIO84_KP_MKOUT_1 MFP_CFG_LPM(GPIO84, AF2, DRIVE_HIGH)
4848+#define GPIO85_KP_MKOUT_2 MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
4849+#define GPIO86_KP_MKOUT_3 MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
4850+#define GPIO13_KP_MKOUT_4 MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
4851+#define GPIO14_KP_MKOUT_5 MFP_CFG_LPM(GPIO14, AF3, DRIVE_HIGH)
4852+
4853+#define GPIO121_KP_MKOUT_0 MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
4854+#define GPIO122_KP_MKOUT_1 MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
4855+#define GPIO123_KP_MKOUT_2 MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
4856+#define GPIO124_KP_MKOUT_3 MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
4857+#define GPIO125_KP_MKOUT_4 MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
4858+#define GPIO126_KP_MKOUT_5 MFP_CFG_LPM(GPIO126, AF1, DRIVE_HIGH)
4859+#define GPIO127_KP_MKOUT_6 MFP_CFG_LPM(GPIO127, AF1, DRIVE_HIGH)
4860+#define GPIO5_2_KP_MKOUT_7 MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
4861+
4862+/* LCD */
4863+#define GPIO6_2_LCD_LDD_0 MFP_CFG_DRV(GPIO6_2, AF1, DS01X)
4864+#define GPIO7_2_LCD_LDD_1 MFP_CFG_DRV(GPIO7_2, AF1, DS01X)
4865+#define GPIO8_2_LCD_LDD_2 MFP_CFG_DRV(GPIO8_2, AF1, DS01X)
4866+#define GPIO9_2_LCD_LDD_3 MFP_CFG_DRV(GPIO9_2, AF1, DS01X)
4867+#define GPIO10_2_LCD_LDD_4 MFP_CFG_DRV(GPIO10_2, AF1, DS01X)
4868+#define GPIO11_2_LCD_LDD_5 MFP_CFG_DRV(GPIO11_2, AF1, DS01X)
4869+#define GPIO12_2_LCD_LDD_6 MFP_CFG_DRV(GPIO12_2, AF1, DS01X)
4870+#define GPIO13_2_LCD_LDD_7 MFP_CFG_DRV(GPIO13_2, AF1, DS01X)
4871+#define GPIO63_LCD_LDD_8 MFP_CFG_DRV(GPIO63, AF1, DS01X)
4872+#define GPIO64_LCD_LDD_9 MFP_CFG_DRV(GPIO64, AF1, DS01X)
4873+#define GPIO65_LCD_LDD_10 MFP_CFG_DRV(GPIO65, AF1, DS01X)
4874+#define GPIO66_LCD_LDD_11 MFP_CFG_DRV(GPIO66, AF1, DS01X)
4875+#define GPIO67_LCD_LDD_12 MFP_CFG_DRV(GPIO67, AF1, DS01X)
4876+#define GPIO68_LCD_LDD_13 MFP_CFG_DRV(GPIO68, AF1, DS01X)
4877+#define GPIO69_LCD_LDD_14 MFP_CFG_DRV(GPIO69, AF1, DS01X)
4878+#define GPIO70_LCD_LDD_15 MFP_CFG_DRV(GPIO70, AF1, DS01X)
4879+#define GPIO71_LCD_LDD_16 MFP_CFG_DRV(GPIO71, AF1, DS01X)
4880+#define GPIO72_LCD_LDD_17 MFP_CFG_DRV(GPIO72, AF1, DS01X)
4881+#define GPIO73_LCD_CS_N MFP_CFG_DRV(GPIO73, AF2, DS01X)
4882+#define GPIO74_LCD_VSYNC MFP_CFG_DRV(GPIO74, AF2, DS01X)
4883+#define GPIO14_2_LCD_FCLK MFP_CFG_DRV(GPIO14_2, AF1, DS01X)
4884+#define GPIO15_2_LCD_LCLK MFP_CFG_DRV(GPIO15_2, AF1, DS01X)
4885+#define GPIO16_2_LCD_PCLK MFP_CFG_DRV(GPIO16_2, AF1, DS01X)
4886+#define GPIO17_2_LCD_BIAS MFP_CFG_DRV(GPIO17_2, AF1, DS01X)
4887+#define GPIO64_LCD_VSYNC MFP_CFG_DRV(GPIO64, AF2, DS01X)
4888+#define GPIO63_LCD_CS_N MFP_CFG_DRV(GPIO63, AF2, DS01X)
4889+
4890+#define GPIO6_2_MLCD_DD_0 MFP_CFG_DRV(GPIO6_2, AF7, DS08X)
4891+#define GPIO7_2_MLCD_DD_1 MFP_CFG_DRV(GPIO7_2, AF7, DS08X)
4892+#define GPIO8_2_MLCD_DD_2 MFP_CFG_DRV(GPIO8_2, AF7, DS08X)
4893+#define GPIO9_2_MLCD_DD_3 MFP_CFG_DRV(GPIO9_2, AF7, DS08X)
4894+#define GPIO10_2_MLCD_DD_4 MFP_CFG_DRV(GPIO10_2, AF7, DS08X)
4895+#define GPIO11_2_MLCD_DD_5 MFP_CFG_DRV(GPIO11_2, AF7, DS08X)
4896+#define GPIO12_2_MLCD_DD_6 MFP_CFG_DRV(GPIO12_2, AF7, DS08X)
4897+#define GPIO13_2_MLCD_DD_7 MFP_CFG_DRV(GPIO13_2, AF7, DS08X)
4898+#define GPIO63_MLCD_DD_8 MFP_CFG_DRV(GPIO63, AF7, DS08X)
4899+#define GPIO64_MLCD_DD_9 MFP_CFG_DRV(GPIO64, AF7, DS08X)
4900+#define GPIO65_MLCD_DD_10 MFP_CFG_DRV(GPIO65, AF7, DS08X)
4901+#define GPIO66_MLCD_DD_11 MFP_CFG_DRV(GPIO66, AF7, DS08X)
4902+#define GPIO67_MLCD_DD_12 MFP_CFG_DRV(GPIO67, AF7, DS08X)
4903+#define GPIO68_MLCD_DD_13 MFP_CFG_DRV(GPIO68, AF7, DS08X)
4904+#define GPIO69_MLCD_DD_14 MFP_CFG_DRV(GPIO69, AF7, DS08X)
4905+#define GPIO70_MLCD_DD_15 MFP_CFG_DRV(GPIO70, AF7, DS08X)
4906+#define GPIO71_MLCD_DD_16 MFP_CFG_DRV(GPIO71, AF7, DS08X)
4907+#define GPIO72_MLCD_DD_17 MFP_CFG_DRV(GPIO72, AF7, DS08X)
4908+#define GPIO73_MLCD_CS MFP_CFG_DRV(GPIO73, AF7, DS08X)
4909+#define GPIO74_MLCD_VSYNC MFP_CFG_DRV(GPIO74, AF7, DS08X)
4910+#define GPIO14_2_MLCD_FCLK MFP_CFG_DRV(GPIO14_2, AF7, DS08X)
4911+#define GPIO15_2_MLCD_LCLK MFP_CFG_DRV(GPIO15_2, AF7, DS08X)
4912+#define GPIO16_2_MLCD_PCLK MFP_CFG_DRV(GPIO16_2, AF7, DS08X)
4913+#define GPIO17_2_MLCD_BIAS MFP_CFG_DRV(GPIO17_2, AF7, DS08X)
4914+
4915+/* MMC1 */
4916+#define GPIO9_MMC1_CMD MFP_CFG_LPM(GPIO9, AF4, DRIVE_HIGH)
4917+#define GPIO22_MMC1_CLK MFP_CFG_LPM(GPIO22, AF4, DRIVE_HIGH)
4918+#define GPIO23_MMC1_CMD MFP_CFG_LPM(GPIO23, AF4, DRIVE_HIGH)
4919+#define GPIO30_MMC1_CLK MFP_CFG_LPM(GPIO30, AF4, DRIVE_HIGH)
4920+#define GPIO31_MMC1_CMD MFP_CFG_LPM(GPIO31, AF4, DRIVE_HIGH)
4921+#define GPIO5_MMC1_DAT0 MFP_CFG_LPM(GPIO5, AF4, DRIVE_HIGH)
4922+#define GPIO6_MMC1_DAT1 MFP_CFG_LPM(GPIO6, AF4, DRIVE_HIGH)
4923+#define GPIO7_MMC1_DAT2 MFP_CFG_LPM(GPIO7, AF4, DRIVE_HIGH)
4924+#define GPIO8_MMC1_DAT3 MFP_CFG_LPM(GPIO8, AF4, DRIVE_HIGH)
4925+#define GPIO18_MMC1_DAT0 MFP_CFG_LPM(GPIO18, AF4, DRIVE_HIGH)
4926+#define GPIO19_MMC1_DAT1 MFP_CFG_LPM(GPIO19, AF4, DRIVE_HIGH)
4927+#define GPIO20_MMC1_DAT2 MFP_CFG_LPM(GPIO20, AF4, DRIVE_HIGH)
4928+#define GPIO21_MMC1_DAT3 MFP_CFG_LPM(GPIO21, AF4, DRIVE_HIGH)
4929+
4930+#define GPIO28_MMC2_CLK MFP_CFG_LPM(GPIO28, AF4, PULL_HIGH)
4931+#define GPIO29_MMC2_CMD MFP_CFG_LPM(GPIO29, AF4, PULL_HIGH)
4932+#define GPIO30_MMC2_CLK MFP_CFG_LPM(GPIO30, AF3, PULL_HIGH)
4933+#define GPIO31_MMC2_CMD MFP_CFG_LPM(GPIO31, AF3, PULL_HIGH)
4934+#define GPIO79_MMC2_CLK MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
4935+#define GPIO80_MMC2_CMD MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
4936+
4937+#define GPIO5_MMC2_DAT0 MFP_CFG_LPM(GPIO5, AF2, PULL_HIGH)
4938+#define GPIO6_MMC2_DAT1 MFP_CFG_LPM(GPIO6, AF2, PULL_HIGH)
4939+#define GPIO7_MMC2_DAT2 MFP_CFG_LPM(GPIO7, AF2, PULL_HIGH)
4940+#define GPIO8_MMC2_DAT3 MFP_CFG_LPM(GPIO8, AF2, PULL_HIGH)
4941+#define GPIO24_MMC2_DAT0 MFP_CFG_LPM(GPIO24, AF4, PULL_HIGH)
4942+#define GPIO75_MMC2_DAT0 MFP_CFG_LPM(GPIO75, AF4, PULL_HIGH)
4943+#define GPIO25_MMC2_DAT1 MFP_CFG_LPM(GPIO25, AF4, PULL_HIGH)
4944+#define GPIO76_MMC2_DAT1 MFP_CFG_LPM(GPIO76, AF4, PULL_HIGH)
4945+#define GPIO26_MMC2_DAT2 MFP_CFG_LPM(GPIO26, AF4, PULL_HIGH)
4946+#define GPIO77_MMC2_DAT2 MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
4947+#define GPIO27_MMC2_DAT3 MFP_CFG_LPM(GPIO27, AF4, PULL_HIGH)
4948+#define GPIO78_MMC2_DAT3 MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
4949+
4950+/* 1-Wire */
4951+#define GPIO14_ONE_WIRE MFP_CFG_LPM(GPIO14, AF5, FLOAT)
4952+#define GPIO0_2_ONE_WIRE MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
4953+
4954+/* SSP1 */
4955+#define GPIO87_SSP1_EXTCLK MFP_CFG(GPIO87, AF1)
4956+#define GPIO88_SSP1_SYSCLK MFP_CFG(GPIO88, AF1)
4957+#define GPIO83_SSP1_SCLK MFP_CFG(GPIO83, AF1)
4958+#define GPIO84_SSP1_SFRM MFP_CFG(GPIO84, AF1)
4959+#define GPIO85_SSP1_RXD MFP_CFG(GPIO85, AF6)
4960+#define GPIO85_SSP1_TXD MFP_CFG(GPIO85, AF1)
4961+#define GPIO86_SSP1_RXD MFP_CFG(GPIO86, AF1)
4962+#define GPIO86_SSP1_TXD MFP_CFG(GPIO86, AF6)
4963+
4964+/* SSP2 */
4965+#define GPIO39_SSP2_EXTCLK MFP_CFG(GPIO39, AF2)
4966+#define GPIO40_SSP2_SYSCLK MFP_CFG(GPIO40, AF2)
4967+#define GPIO12_SSP2_SCLK MFP_CFG(GPIO12, AF2)
4968+#define GPIO35_SSP2_SCLK MFP_CFG(GPIO35, AF2)
4969+#define GPIO36_SSP2_SFRM MFP_CFG(GPIO36, AF2)
4970+#define GPIO37_SSP2_RXD MFP_CFG(GPIO37, AF5)
4971+#define GPIO37_SSP2_TXD MFP_CFG(GPIO37, AF2)
4972+#define GPIO38_SSP2_RXD MFP_CFG(GPIO38, AF2)
4973+#define GPIO38_SSP2_TXD MFP_CFG(GPIO38, AF5)
4974+
4975+#define GPIO69_SSP3_SCLK MFP_CFG(GPIO69, AF2, DS08X, FLOAT)
4976+#define GPIO70_SSP3_FRM MFP_CFG(GPIO70, AF2, DS08X, DRIVE_LOW)
4977+#define GPIO89_SSP3_SCLK MFP_CFG(GPIO89, AF1, DS08X, FLOAT)
4978+#define GPIO90_SSP3_FRM MFP_CFG(GPIO90, AF1, DS08X, DRIVE_LOW)
4979+#define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT)
4980+#define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW)
4981+#define GPIO72_SSP3_RXD MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT)
4982+#define GPIO72_SSP3_TXD MFP_CFG_X(GPIO72, AF5, DS08X, DRIVE_LOW)
4983+#define GPIO91_SSP3_RXD MFP_CFG_X(GPIO91, AF5, DS08X, FLOAT)
4984+#define GPIO91_SSP3_TXD MFP_CFG_X(GPIO91, AF1, DS08X, DRIVE_LOW)
4985+#define GPIO92_SSP3_RXD MFP_CFG_X(GPIO92, AF1, DS08X, FLOAT)
4986+#define GPIO92_SSP3_TXD MFP_CFG_X(GPIO92, AF5, DS08X, DRIVE_LOW)
4987+
4988+#define GPIO93_SSP4_SCLK MFP_CFG_LPM(GPIO93, AF1, PULL_HIGH)
4989+#define GPIO94_SSP4_FRM MFP_CFG_LPM(GPIO94, AF1, PULL_HIGH)
4990+#define GPIO94_SSP4_RXD MFP_CFG_LPM(GPIO94, AF5, PULL_HIGH)
4991+#define GPIO95_SSP4_RXD MFP_CFG_LPM(GPIO95, AF5, PULL_HIGH)
4992+#define GPIO95_SSP4_TXD MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
4993+#define GPIO96_SSP4_RXD MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
4994+#define GPIO96_SSP4_TXD MFP_CFG_LPM(GPIO96, AF5, PULL_HIGH)
4995+
4996+/* UART1 */
4997+#define GPIO41_UART1_RXD MFP_CFG_LPM(GPIO41, AF2, FLOAT)
4998+#define GPIO41_UART1_TXD MFP_CFG_LPM(GPIO41, AF4, FLOAT)
4999+#define GPIO42_UART1_RXD MFP_CFG_LPM(GPIO42, AF4, FLOAT)
5000+#define GPIO42_UART1_TXD MFP_CFG_LPM(GPIO42, AF2, FLOAT)
5001+#define GPIO97_UART1_RXD MFP_CFG_LPM(GPIO97, AF1, FLOAT)
5002+#define GPIO97_UART1_TXD MFP_CFG_LPM(GPIO97, AF6, FLOAT)
5003+#define GPIO98_UART1_RXD MFP_CFG_LPM(GPIO98, AF6, FLOAT)
5004+#define GPIO98_UART1_TXD MFP_CFG_LPM(GPIO98, AF1, FLOAT)
5005+#define GPIO43_UART1_CTS MFP_CFG_LPM(GPIO43, AF2, FLOAT)
5006+#define GPIO43_UART1_RTS MFP_CFG_LPM(GPIO43, AF4, FLOAT)
5007+#define GPIO48_UART1_CTS MFP_CFG_LPM(GPIO48, AF4, FLOAT)
5008+#define GPIO48_UART1_RTS MFP_CFG_LPM(GPIO48, AF2, FLOAT)
5009+#define GPIO99_UART1_CTS MFP_CFG_LPM(GPIO99, AF1, FLOAT)
5010+#define GPIO99_UART1_RTS MFP_CFG_LPM(GPIO99, AF6, FLOAT)
5011+#define GPIO104_UART1_CTS MFP_CFG_LPM(GPIO104, AF6, FLOAT)
5012+#define GPIO104_UART1_RTS MFP_CFG_LPM(GPIO104, AF1, FLOAT)
5013+#define GPIO45_UART1_DTR MFP_CFG_LPM(GPIO45, AF4, FLOAT)
5014+#define GPIO45_UART1_DSR MFP_CFG_LPM(GPIO45, AF2, FLOAT)
5015+#define GPIO47_UART1_DTR MFP_CFG_LPM(GPIO47, AF2, FLOAT)
5016+#define GPIO47_UART1_DSR MFP_CFG_LPM(GPIO47, AF4, FLOAT)
5017+#define GPIO101_UART1_DTR MFP_CFG_LPM(GPIO101, AF6, FLOAT)
5018+#define GPIO101_UART1_DSR MFP_CFG_LPM(GPIO101, AF1, FLOAT)
5019+#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
5020+#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
5021+#define GPIO44_UART1_DCD MFP_CFG_LPM(GPIO44, AF2, FLOAT)
5022+#define GPIO100_UART1_DCD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
5023+#define GPIO46_UART1_RI MFP_CFG_LPM(GPIO46, AF2, FLOAT)
5024+#define GPIO102_UART1_RI MFP_CFG_LPM(GPIO102, AF1, FLOAT)
5025+
5026+/* UART2 */
5027+#define GPIO109_UART2_CTS MFP_CFG_LPM(GPIO109, AF3, FLOAT)
5028+#define GPIO109_UART2_RTS MFP_CFG_LPM(GPIO109, AF1, FLOAT)
5029+#define GPIO112_UART2_CTS MFP_CFG_LPM(GPIO112, AF1, FLOAT)
5030+#define GPIO112_UART2_RTS MFP_CFG_LPM(GPIO112, AF3, FLOAT)
5031+#define GPIO110_UART2_RXD MFP_CFG_LPM(GPIO110, AF1, FLOAT)
5032+#define GPIO110_UART2_TXD MFP_CFG_LPM(GPIO110, AF3, FLOAT)
5033+#define GPIO111_UART2_RXD MFP_CFG_LPM(GPIO111, AF3, FLOAT)
5034+#define GPIO111_UART2_TXD MFP_CFG_LPM(GPIO111, AF1, FLOAT)
5035+
5036+/* UART3 */
5037+#define GPIO89_UART3_CTS MFP_CFG_LPM(GPIO89, AF2, FLOAT)
5038+#define GPIO89_UART3_RTS MFP_CFG_LPM(GPIO89, AF4, FLOAT)
5039+#define GPIO90_UART3_CTS MFP_CFG_LPM(GPIO90, AF4, FLOAT)
5040+#define GPIO90_UART3_RTS MFP_CFG_LPM(GPIO90, AF2, FLOAT)
5041+#define GPIO105_UART3_CTS MFP_CFG_LPM(GPIO105, AF1, FLOAT)
5042+#define GPIO105_UART3_RTS MFP_CFG_LPM(GPIO105, AF3, FLOAT)
5043+#define GPIO106_UART3_CTS MFP_CFG_LPM(GPIO106, AF3, FLOAT)
5044+#define GPIO106_UART3_RTS MFP_CFG_LPM(GPIO106, AF1, FLOAT)
5045+#define GPIO30_UART3_RXD MFP_CFG_LPM(GPIO30, AF2, FLOAT)
5046+#define GPIO30_UART3_TXD MFP_CFG_LPM(GPIO30, AF6, FLOAT)
5047+#define GPIO31_UART3_RXD MFP_CFG_LPM(GPIO31, AF6, FLOAT)
5048+#define GPIO31_UART3_TXD MFP_CFG_LPM(GPIO31, AF2, FLOAT)
5049+#define GPIO91_UART3_RXD MFP_CFG_LPM(GPIO91, AF4, FLOAT)
5050+#define GPIO91_UART3_TXD MFP_CFG_LPM(GPIO91, AF2, FLOAT)
5051+#define GPIO92_UART3_RXD MFP_CFG_LPM(GPIO92, AF2, FLOAT)
5052+#define GPIO92_UART3_TXD MFP_CFG_LPM(GPIO92, AF4, FLOAT)
5053+#define GPIO107_UART3_RXD MFP_CFG_LPM(GPIO107, AF3, FLOAT)
5054+#define GPIO107_UART3_TXD MFP_CFG_LPM(GPIO107, AF1, FLOAT)
5055+#define GPIO108_UART3_RXD MFP_CFG_LPM(GPIO108, AF1, FLOAT)
5056+#define GPIO108_UART3_TXD MFP_CFG_LPM(GPIO108, AF3, FLOAT)
5057+
5058+
5059+/* USB 2.0 UTMI */
5060+#define GPIO10_UTM_CLK MFP_CFG(GPIO10, AF1)
5061+#define GPIO36_U2D_RXERROR MFP_CFG(GPIO36, AF3)
5062+#define GPIO60_U2D_RXERROR MFP_CFG(GPIO60, AF1)
5063+#define GPIO87_U2D_RXERROR MFP_CFG(GPIO87, AF5)
5064+#define GPIO34_UTM_RXVALID MFP_CFG(GPIO34, AF3)
5065+#define GPIO58_UTM_RXVALID MFP_CFG(GPIO58, AF2)
5066+#define GPIO85_UTM_RXVALID MFP_CFG(GPIO85, AF5)
5067+#define GPIO35_UTM_RXACTIVE MFP_CFG(GPIO35, AF3)
5068+#define GPIO59_UTM_RXACTIVE MFP_CFG(GPIO59, AF1)
5069+#define GPIO86_UTM_RXACTIVE MFP_CFG(GPIO86, AF5)
5070+#define GPIO73_UTM_TXREADY MFP_CFG(GPIO73, AF1)
5071+#define GPIO68_UTM_LINESTATE_0 MFP_CFG(GPIO68, AF3)
5072+#define GPIO90_UTM_LINESTATE_0 MFP_CFG(GPIO90, AF3)
5073+#define GPIO102_UTM_LINESTATE_0 MFP_CFG(GPIO102, AF3)
5074+#define GPIO107_UTM_LINESTATE_0 MFP_CFG(GPIO107, AF4)
5075+#define GPIO69_UTM_LINESTATE_1 MFP_CFG(GPIO69, AF3)
5076+#define GPIO91_UTM_LINESTATE_1 MFP_CFG(GPIO91, AF3)
5077+#define GPIO103_UTM_LINESTATE_1 MFP_CFG(GPIO103, AF3)
5078+
5079+#define GPIO41_U2D_PHYDATA_0 MFP_CFG(GPIO41, AF3)
5080+#define GPIO42_U2D_PHYDATA_1 MFP_CFG(GPIO42, AF3)
5081+#define GPIO43_U2D_PHYDATA_2 MFP_CFG(GPIO43, AF3)
5082+#define GPIO44_U2D_PHYDATA_3 MFP_CFG(GPIO44, AF3)
5083+#define GPIO45_U2D_PHYDATA_4 MFP_CFG(GPIO45, AF3)
5084+#define GPIO46_U2D_PHYDATA_5 MFP_CFG(GPIO46, AF3)
5085+#define GPIO47_U2D_PHYDATA_6 MFP_CFG(GPIO47, AF3)
5086+#define GPIO48_U2D_PHYDATA_7 MFP_CFG(GPIO48, AF3)
5087+
5088+#define GPIO49_U2D_PHYDATA_0 MFP_CFG(GPIO49, AF3)
5089+#define GPIO50_U2D_PHYDATA_1 MFP_CFG(GPIO50, AF3)
5090+#define GPIO51_U2D_PHYDATA_2 MFP_CFG(GPIO51, AF3)
5091+#define GPIO52_U2D_PHYDATA_3 MFP_CFG(GPIO52, AF3)
5092+#define GPIO53_U2D_PHYDATA_4 MFP_CFG(GPIO53, AF3)
5093+#define GPIO54_U2D_PHYDATA_5 MFP_CFG(GPIO54, AF3)
5094+#define GPIO55_U2D_PHYDATA_6 MFP_CFG(GPIO55, AF3)
5095+#define GPIO56_U2D_PHYDATA_7 MFP_CFG(GPIO56, AF3)
5096+
5097+#define GPIO37_U2D_OPMODE0 MFP_CFG(GPIO37, AF4)
5098+#define GPIO61_U2D_OPMODE0 MFP_CFG(GPIO61, AF2)
5099+#define GPIO88_U2D_OPMODE0 MFP_CFG(GPIO88, AF7)
5100+
5101+#define GPIO38_U2D_OPMODE1 MFP_CFG(GPIO38, AF4)
5102+#define GPIO62_U2D_OPMODE1 MFP_CFG(GPIO62, AF2)
5103+#define GPIO104_U2D_OPMODE1 MFP_CFG(GPIO104, AF4)
5104+#define GPIO108_U2D_OPMODE1 MFP_CFG(GPIO108, AF5)
5105+
5106+#define GPIO74_U2D_RESET MFP_CFG(GPIO74, AF1)
5107+#define GPIO93_U2D_RESET MFP_CFG(GPIO93, AF2)
5108+#define GPIO98_U2D_RESET MFP_CFG(GPIO98, AF3)
5109+
5110+#define GPIO67_U2D_SUSPEND MFP_CFG(GPIO67, AF3)
5111+#define GPIO96_U2D_SUSPEND MFP_CFG(GPIO96, AF2)
5112+#define GPIO101_U2D_SUSPEND MFP_CFG(GPIO101, AF3)
5113+
5114+#define GPIO66_U2D_TERM_SEL MFP_CFG(GPIO66, AF5)
5115+#define GPIO95_U2D_TERM_SEL MFP_CFG(GPIO95, AF3)
5116+#define GPIO97_U2D_TERM_SEL MFP_CFG(GPIO97, AF7)
5117+#define GPIO100_U2D_TERM_SEL MFP_CFG(GPIO100, AF5)
5118+
5119+#define GPIO39_U2D_TXVALID MFP_CFG(GPIO39, AF4)
5120+#define GPIO70_U2D_TXVALID MFP_CFG(GPIO70, AF5)
5121+#define GPIO83_U2D_TXVALID MFP_CFG(GPIO83, AF7)
5122+
5123+#define GPIO65_U2D_XCVR_SEL MFP_CFG(GPIO65, AF5)
5124+#define GPIO94_U2D_XCVR_SEL MFP_CFG(GPIO94, AF3)
5125+#define GPIO99_U2D_XCVR_SEL MFP_CFG(GPIO99, AF5)
5126+
5127+/* USB Host 1.1 */
5128+#define GPIO2_2_USBH_PEN MFP_CFG(GPIO2_2, AF1)
5129+#define GPIO3_2_USBH_PWR MFP_CFG(GPIO3_2, AF1)
5130+
5131+/* USB P2 */
5132+#define GPIO97_USB_P2_2 MFP_CFG(GPIO97, AF2)
5133+#define GPIO97_USB_P2_6 MFP_CFG(GPIO97, AF4)
5134+#define GPIO98_USB_P2_2 MFP_CFG(GPIO98, AF4)
5135+#define GPIO98_USB_P2_6 MFP_CFG(GPIO98, AF2)
5136+#define GPIO99_USB_P2_1 MFP_CFG(GPIO99, AF2)
5137+#define GPIO100_USB_P2_4 MFP_CFG(GPIO100, AF2)
5138+#define GPIO101_USB_P2_8 MFP_CFG(GPIO101, AF2)
5139+#define GPIO102_USB_P2_3 MFP_CFG(GPIO102, AF2)
5140+#define GPIO103_USB_P2_5 MFP_CFG(GPIO103, AF2)
5141+#define GPIO104_USB_P2_7 MFP_CFG(GPIO104, AF2)
5142+
5143+/* USB P3 */
5144+#define GPIO75_USB_P3_1 MFP_CFG(GPIO75, AF2)
5145+#define GPIO76_USB_P3_2 MFP_CFG(GPIO76, AF2)
5146+#define GPIO77_USB_P3_3 MFP_CFG(GPIO77, AF2)
5147+#define GPIO78_USB_P3_4 MFP_CFG(GPIO78, AF2)
5148+#define GPIO79_USB_P3_5 MFP_CFG(GPIO79, AF2)
5149+#define GPIO80_USB_P3_6 MFP_CFG(GPIO80, AF2)
5150+
5151+#define GPIO13_CHOUT0 MFP_CFG(GPIO13, AF6)
5152+#define GPIO14_CHOUT1 MFP_CFG(GPIO14, AF6)
5153+
5154+#define GPIO2_RDY MFP_CFG(GPIO2, AF1)
5155+#define GPIO5_NPIOR MFP_CFG(GPIO5, AF3)
5156+
5157+#define GPIO11_PWM0_OUT MFP_CFG(GPIO11, AF1)
5158+#define GPIO12_PWM1_OUT MFP_CFG(GPIO12, AF1)
5159+#define GPIO13_PWM2_OUT MFP_CFG(GPIO13, AF1)
5160+#define GPIO14_PWM3_OUT MFP_CFG(GPIO14, AF1)
5161+
5162+#endif /* __ASM_ARCH_MFP_PXA320_H */
5163--- /dev/null
5164+++ linux-2.6.23/include/asm-arm/arch-pxa/mfp.h
5165@@ -0,0 +1,576 @@
5166+/*
5167+ * linux/include/asm-arm/arch-pxa/mfp.h
5168+ *
5169+ * Multi-Function Pin Definitions
5170+ *
5171+ * Copyright (C) 2007 Marvell International Ltd.
5172+ *
5173+ * 2007-8-21: eric miao <eric.y.miao@gmail.com>
5174+ * initial version
5175+ *
5176+ * This program is free software; you can redistribute it and/or modify
5177+ * it under the terms of the GNU General Public License version 2 as
5178+ * published by the Free Software Foundation.
5179+ */
5180+
5181+#ifndef __ASM_ARCH_MFP_H
5182+#define __ASM_ARCH_MFP_H
5183+
5184+#define MFPR_BASE (0x40e10000)
5185+#define MFPR_SIZE (PAGE_SIZE)
5186+
5187+#define mfp_to_gpio(m) ((m) % 128)
5188+
5189+/* list of all the configurable MFP pins */
5190+enum {
5191+ MFP_PIN_INVALID = -1,
5192+
5193+ MFP_PIN_GPIO0 = 0,
5194+ MFP_PIN_GPIO1,
5195+ MFP_PIN_GPIO2,
5196+ MFP_PIN_GPIO3,
5197+ MFP_PIN_GPIO4,
5198+ MFP_PIN_GPIO5,
5199+ MFP_PIN_GPIO6,
5200+ MFP_PIN_GPIO7,
5201+ MFP_PIN_GPIO8,
5202+ MFP_PIN_GPIO9,
5203+ MFP_PIN_GPIO10,
5204+ MFP_PIN_GPIO11,
5205+ MFP_PIN_GPIO12,
5206+ MFP_PIN_GPIO13,
5207+ MFP_PIN_GPIO14,
5208+ MFP_PIN_GPIO15,
5209+ MFP_PIN_GPIO16,
5210+ MFP_PIN_GPIO17,
5211+ MFP_PIN_GPIO18,
5212+ MFP_PIN_GPIO19,
5213+ MFP_PIN_GPIO20,
5214+ MFP_PIN_GPIO21,
5215+ MFP_PIN_GPIO22,
5216+ MFP_PIN_GPIO23,
5217+ MFP_PIN_GPIO24,
5218+ MFP_PIN_GPIO25,
5219+ MFP_PIN_GPIO26,
5220+ MFP_PIN_GPIO27,
5221+ MFP_PIN_GPIO28,
5222+ MFP_PIN_GPIO29,
5223+ MFP_PIN_GPIO30,
5224+ MFP_PIN_GPIO31,
5225+ MFP_PIN_GPIO32,
5226+ MFP_PIN_GPIO33,
5227+ MFP_PIN_GPIO34,
5228+ MFP_PIN_GPIO35,
5229+ MFP_PIN_GPIO36,
5230+ MFP_PIN_GPIO37,
5231+ MFP_PIN_GPIO38,
5232+ MFP_PIN_GPIO39,
5233+ MFP_PIN_GPIO40,
5234+ MFP_PIN_GPIO41,
5235+ MFP_PIN_GPIO42,
5236+ MFP_PIN_GPIO43,
5237+ MFP_PIN_GPIO44,
5238+ MFP_PIN_GPIO45,
5239+ MFP_PIN_GPIO46,
5240+ MFP_PIN_GPIO47,
5241+ MFP_PIN_GPIO48,
5242+ MFP_PIN_GPIO49,
5243+ MFP_PIN_GPIO50,
5244+ MFP_PIN_GPIO51,
5245+ MFP_PIN_GPIO52,
5246+ MFP_PIN_GPIO53,
5247+ MFP_PIN_GPIO54,
5248+ MFP_PIN_GPIO55,
5249+ MFP_PIN_GPIO56,
5250+ MFP_PIN_GPIO57,
5251+ MFP_PIN_GPIO58,
5252+ MFP_PIN_GPIO59,
5253+ MFP_PIN_GPIO60,
5254+ MFP_PIN_GPIO61,
5255+ MFP_PIN_GPIO62,
5256+ MFP_PIN_GPIO63,
5257+ MFP_PIN_GPIO64,
5258+ MFP_PIN_GPIO65,
5259+ MFP_PIN_GPIO66,
5260+ MFP_PIN_GPIO67,
5261+ MFP_PIN_GPIO68,
5262+ MFP_PIN_GPIO69,
5263+ MFP_PIN_GPIO70,
5264+ MFP_PIN_GPIO71,
5265+ MFP_PIN_GPIO72,
5266+ MFP_PIN_GPIO73,
5267+ MFP_PIN_GPIO74,
5268+ MFP_PIN_GPIO75,
5269+ MFP_PIN_GPIO76,
5270+ MFP_PIN_GPIO77,
5271+ MFP_PIN_GPIO78,
5272+ MFP_PIN_GPIO79,
5273+ MFP_PIN_GPIO80,
5274+ MFP_PIN_GPIO81,
5275+ MFP_PIN_GPIO82,
5276+ MFP_PIN_GPIO83,
5277+ MFP_PIN_GPIO84,
5278+ MFP_PIN_GPIO85,
5279+ MFP_PIN_GPIO86,
5280+ MFP_PIN_GPIO87,
5281+ MFP_PIN_GPIO88,
5282+ MFP_PIN_GPIO89,
5283+ MFP_PIN_GPIO90,
5284+ MFP_PIN_GPIO91,
5285+ MFP_PIN_GPIO92,
5286+ MFP_PIN_GPIO93,
5287+ MFP_PIN_GPIO94,
5288+ MFP_PIN_GPIO95,
5289+ MFP_PIN_GPIO96,
5290+ MFP_PIN_GPIO97,
5291+ MFP_PIN_GPIO98,
5292+ MFP_PIN_GPIO99,
5293+ MFP_PIN_GPIO100,
5294+ MFP_PIN_GPIO101,
5295+ MFP_PIN_GPIO102,
5296+ MFP_PIN_GPIO103,
5297+ MFP_PIN_GPIO104,
5298+ MFP_PIN_GPIO105,
5299+ MFP_PIN_GPIO106,
5300+ MFP_PIN_GPIO107,
5301+ MFP_PIN_GPIO108,
5302+ MFP_PIN_GPIO109,
5303+ MFP_PIN_GPIO110,
5304+ MFP_PIN_GPIO111,
5305+ MFP_PIN_GPIO112,
5306+ MFP_PIN_GPIO113,
5307+ MFP_PIN_GPIO114,
5308+ MFP_PIN_GPIO115,
5309+ MFP_PIN_GPIO116,
5310+ MFP_PIN_GPIO117,
5311+ MFP_PIN_GPIO118,
5312+ MFP_PIN_GPIO119,
5313+ MFP_PIN_GPIO120,
5314+ MFP_PIN_GPIO121,
5315+ MFP_PIN_GPIO122,
5316+ MFP_PIN_GPIO123,
5317+ MFP_PIN_GPIO124,
5318+ MFP_PIN_GPIO125,
5319+ MFP_PIN_GPIO126,
5320+ MFP_PIN_GPIO127,
5321+ MFP_PIN_GPIO0_2,
5322+ MFP_PIN_GPIO1_2,
5323+ MFP_PIN_GPIO2_2,
5324+ MFP_PIN_GPIO3_2,
5325+ MFP_PIN_GPIO4_2,
5326+ MFP_PIN_GPIO5_2,
5327+ MFP_PIN_GPIO6_2,
5328+ MFP_PIN_GPIO7_2,
5329+ MFP_PIN_GPIO8_2,
5330+ MFP_PIN_GPIO9_2,
5331+ MFP_PIN_GPIO10_2,
5332+ MFP_PIN_GPIO11_2,
5333+ MFP_PIN_GPIO12_2,
5334+ MFP_PIN_GPIO13_2,
5335+ MFP_PIN_GPIO14_2,
5336+ MFP_PIN_GPIO15_2,
5337+ MFP_PIN_GPIO16_2,
5338+ MFP_PIN_GPIO17_2,
5339+
5340+ MFP_PIN_ULPI_STP,
5341+ MFP_PIN_ULPI_NXT,
5342+ MFP_PIN_ULPI_DIR,
5343+
5344+ MFP_PIN_nXCVREN,
5345+ MFP_PIN_DF_CLE_nOE,
5346+ MFP_PIN_DF_nADV1_ALE,
5347+ MFP_PIN_DF_SCLK_E,
5348+ MFP_PIN_DF_SCLK_S,
5349+ MFP_PIN_nBE0,
5350+ MFP_PIN_nBE1,
5351+ MFP_PIN_DF_nADV2_ALE,
5352+ MFP_PIN_DF_INT_RnB,
5353+ MFP_PIN_DF_nCS0,
5354+ MFP_PIN_DF_nCS1,
5355+ MFP_PIN_nLUA,
5356+ MFP_PIN_nLLA,
5357+ MFP_PIN_DF_nWE,
5358+ MFP_PIN_DF_ALE_nWE,
5359+ MFP_PIN_DF_nRE_nOE,
5360+ MFP_PIN_DF_ADDR0,
5361+ MFP_PIN_DF_ADDR1,
5362+ MFP_PIN_DF_ADDR2,
5363+ MFP_PIN_DF_ADDR3,
5364+ MFP_PIN_DF_IO0,
5365+ MFP_PIN_DF_IO1,
5366+ MFP_PIN_DF_IO2,
5367+ MFP_PIN_DF_IO3,
5368+ MFP_PIN_DF_IO4,
5369+ MFP_PIN_DF_IO5,
5370+ MFP_PIN_DF_IO6,
5371+ MFP_PIN_DF_IO7,
5372+ MFP_PIN_DF_IO8,
5373+ MFP_PIN_DF_IO9,
5374+ MFP_PIN_DF_IO10,
5375+ MFP_PIN_DF_IO11,
5376+ MFP_PIN_DF_IO12,
5377+ MFP_PIN_DF_IO13,
5378+ MFP_PIN_DF_IO14,
5379+ MFP_PIN_DF_IO15,
5380+
5381+ MFP_PIN_MAX,
5382+};
5383+
5384+/*
5385+ * Table that determines the low power modes outputs, with actual settings
5386+ * used in parentheses for don't-care values. Except for the float output,
5387+ * the configured driven and pulled levels match, so if there is a need for
5388+ * non-LPM pulled output, the same configuration could probably be used.
5389+ *
5390+ * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
5391+ * (bit 7) (bit 8) (bit 14d) (bit 13d)
5392+ *
5393+ * Drive 0 0 0 0 X (1) 0
5394+ * Drive 1 0 1 X (1) 0 0
5395+ * Pull hi (1) 1 X(1) 1 0 0
5396+ * Pull lo (0) 1 X(0) 0 1 0
5397+ * Z (float) 1 X(0) 0 0 0
5398+ */
5399+#define MFP_LPM_DRIVE_LOW 0x8
5400+#define MFP_LPM_DRIVE_HIGH 0x6
5401+#define MFP_LPM_PULL_HIGH 0x7
5402+#define MFP_LPM_PULL_LOW 0x9
5403+#define MFP_LPM_FLOAT 0x1
5404+#define MFP_LPM_PULL_NEITHER 0x0
5405+
5406+/*
5407+ * The pullup and pulldown state of the MFP pin is by default determined by
5408+ * selected alternate function. In case some buggy devices need to override
5409+ * this default behavior, pxa3xx_mfp_set_pull() can be invoked with one of
5410+ * the following definition as the parameter.
5411+ *
5412+ * Definition pull_sel pullup_en pulldown_en
5413+ * MFP_PULL_HIGH 1 1 0
5414+ * MFP_PULL_LOW 1 0 1
5415+ * MFP_PULL_BOTH 1 1 1
5416+ * MFP_PULL_NONE 1 0 0
5417+ * MFP_PULL_DEFAULT 0 X X
5418+ *
5419+ * NOTE: pxa3xx_mfp_set_pull() will modify the PULLUP_EN and PULLDOWN_EN
5420+ * bits, which will cause potential conflicts with the low power mode
5421+ * setting, device drivers should take care of this
5422+ */
5423+#define MFP_PULL_BOTH (0x7u)
5424+#define MFP_PULL_HIGH (0x6u)
5425+#define MFP_PULL_LOW (0x5u)
5426+#define MFP_PULL_NONE (0x4u)
5427+#define MFP_PULL_DEFAULT (0x0u)
5428+
5429+#define MFP_AF0 (0)
5430+#define MFP_AF1 (1)
5431+#define MFP_AF2 (2)
5432+#define MFP_AF3 (3)
5433+#define MFP_AF4 (4)
5434+#define MFP_AF5 (5)
5435+#define MFP_AF6 (6)
5436+#define MFP_AF7 (7)
5437+
5438+#define MFP_DS01X (0)
5439+#define MFP_DS02X (1)
5440+#define MFP_DS03X (2)
5441+#define MFP_DS04X (3)
5442+#define MFP_DS06X (4)
5443+#define MFP_DS08X (5)
5444+#define MFP_DS10X (6)
5445+#define MFP_DS12X (7)
5446+
5447+#define MFP_EDGE_BOTH 0x3
5448+#define MFP_EDGE_RISE 0x2
5449+#define MFP_EDGE_FALL 0x1
5450+#define MFP_EDGE_NONE 0x0
5451+
5452+#define MFPR_AF_MASK 0x0007
5453+#define MFPR_DRV_MASK 0x1c00
5454+#define MFPR_RDH_MASK 0x0200
5455+#define MFPR_LPM_MASK 0xe180
5456+#define MFPR_PULL_MASK 0xe000
5457+#define MFPR_EDGE_MASK 0x0070
5458+
5459+#define MFPR_ALT_OFFSET 0
5460+#define MFPR_ERE_OFFSET 4
5461+#define MFPR_EFE_OFFSET 5
5462+#define MFPR_EC_OFFSET 6
5463+#define MFPR_SON_OFFSET 7
5464+#define MFPR_SD_OFFSET 8
5465+#define MFPR_SS_OFFSET 9
5466+#define MFPR_DRV_OFFSET 10
5467+#define MFPR_PD_OFFSET 13
5468+#define MFPR_PU_OFFSET 14
5469+#define MFPR_PS_OFFSET 15
5470+
5471+#define MFPR(af, drv, rdh, lpm, edge) \
5472+ (((af) & 0x7) | (((drv) & 0x7) << 10) |\
5473+ (((rdh) & 0x1) << 9) |\
5474+ (((lpm) & 0x3) << 7) |\
5475+ (((lpm) & 0x4) << 12)|\
5476+ (((lpm) & 0x8) << 10)|\
5477+ ((!(edge)) << 6) |\
5478+ (((edge) & 0x1) << 5) |\
5479+ (((edge) & 0x2) << 3))
5480+
5481+/*
5482+ * a possible MFP configuration is represented by a 32-bit integer
5483+ * bit 0..15 - MFPR value (16-bit)
5484+ * bit 16..31 - mfp pin index (used to obtain the MFPR offset)
5485+ *
5486+ * to facilitate the definition, the following macros are provided
5487+ *
5488+ * MFPR_DEFAULT - default MFPR value, with
5489+ * alternate function = 0,
5490+ * drive strength = fast 1mA (MFP_DS01X)
5491+ * low power mode = default
5492+ * release dalay hold = false (RDH bit)
5493+ * edge detection = none
5494+ *
5495+ * MFP_CFG - default MFPR value with alternate function
5496+ * MFP_CFG_DRV - default MFPR value with alternate function and
5497+ * pin drive strength
5498+ * MFP_CFG_LPM - default MFPR value with alternate function and
5499+ * low power mode
5500+ * MFP_CFG_X - default MFPR value with alternate function,
5501+ * pin drive strength and low power mode
5502+ *
5503+ * use
5504+ *
5505+ * MFP_CFG_PIN - to get the MFP pin index
5506+ * MFP_CFG_VAL - to get the corresponding MFPR value
5507+ */
5508+
5509+typedef uint32_t mfp_cfg_t;
5510+
5511+#define MFP_CFG_PIN(mfp_cfg) (((mfp_cfg) >> 16) & 0xffff)
5512+#define MFP_CFG_VAL(mfp_cfg) ((mfp_cfg) & 0xffff)
5513+
5514+#define MFPR_DEFAULT (0x0000)
5515+
5516+#define MFP_CFG(pin, af) \
5517+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af))
5518+
5519+#define MFP_CFG_DRV(pin, af, drv) \
5520+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
5521+ ((MFP_##drv) << 10) | (MFP_##af))
5522+
5523+#define MFP_CFG_LPM(pin, af, lpm) \
5524+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af) |\
5525+ (((MFP_LPM_##lpm) & 0x3) << 7) |\
5526+ (((MFP_LPM_##lpm) & 0x4) << 12) |\
5527+ (((MFP_LPM_##lpm) & 0x8) << 10))
5528+
5529+#define MFP_CFG_X(pin, af, drv, lpm) \
5530+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
5531+ ((MFP_##drv) << 10) | (MFP_##af) |\
5532+ (((MFP_LPM_##lpm) & 0x3) << 7) |\
5533+ (((MFP_LPM_##lpm) & 0x4) << 12) |\
5534+ (((MFP_LPM_##lpm) & 0x8) << 10))
5535+
5536+/* common MFP configurations - processor specific ones defined
5537+ * in mfp-pxa3xx.h
5538+ */
5539+#define GPIO0_GPIO MFP_CFG(GPIO0, AF0)
5540+#define GPIO1_GPIO MFP_CFG(GPIO1, AF0)
5541+#define GPIO2_GPIO MFP_CFG(GPIO2, AF0)
5542+#define GPIO3_GPIO MFP_CFG(GPIO3, AF0)
5543+#define GPIO4_GPIO MFP_CFG(GPIO4, AF0)
5544+#define GPIO5_GPIO MFP_CFG(GPIO5, AF0)
5545+#define GPIO6_GPIO MFP_CFG(GPIO6, AF0)
5546+#define GPIO7_GPIO MFP_CFG(GPIO7, AF0)
5547+#define GPIO8_GPIO MFP_CFG(GPIO8, AF0)
5548+#define GPIO9_GPIO MFP_CFG(GPIO9, AF0)
5549+#define GPIO10_GPIO MFP_CFG(GPIO10, AF0)
5550+#define GPIO11_GPIO MFP_CFG(GPIO11, AF0)
5551+#define GPIO12_GPIO MFP_CFG(GPIO12, AF0)
5552+#define GPIO13_GPIO MFP_CFG(GPIO13, AF0)
5553+#define GPIO14_GPIO MFP_CFG(GPIO14, AF0)
5554+#define GPIO15_GPIO MFP_CFG(GPIO15, AF0)
5555+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
5556+#define GPIO17_GPIO MFP_CFG(GPIO17, AF0)
5557+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
5558+#define GPIO19_GPIO MFP_CFG(GPIO19, AF0)
5559+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
5560+#define GPIO21_GPIO MFP_CFG(GPIO21, AF0)
5561+#define GPIO22_GPIO MFP_CFG(GPIO22, AF0)
5562+#define GPIO23_GPIO MFP_CFG(GPIO23, AF0)
5563+#define GPIO24_GPIO MFP_CFG(GPIO24, AF0)
5564+#define GPIO25_GPIO MFP_CFG(GPIO25, AF0)
5565+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
5566+#define GPIO27_GPIO MFP_CFG(GPIO27, AF0)
5567+#define GPIO28_GPIO MFP_CFG(GPIO28, AF0)
5568+#define GPIO29_GPIO MFP_CFG(GPIO29, AF0)
5569+#define GPIO30_GPIO MFP_CFG(GPIO30, AF0)
5570+#define GPIO31_GPIO MFP_CFG(GPIO31, AF0)
5571+#define GPIO32_GPIO MFP_CFG(GPIO32, AF0)
5572+#define GPIO33_GPIO MFP_CFG(GPIO33, AF0)
5573+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
5574+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
5575+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
5576+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
5577+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
5578+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
5579+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
5580+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
5581+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
5582+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
5583+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
5584+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
5585+
5586+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
5587+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
5588+
5589+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
5590+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
5591+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
5592+
5593+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
5594+
5595+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
5596+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
5597+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
5598+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
5599+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
5600+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
5601+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
5602+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
5603+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
5604+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
5605+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
5606+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
5607+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
5608+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
5609+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
5610+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
5611+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
5612+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
5613+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
5614+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
5615+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
5616+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
5617+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
5618+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
5619+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
5620+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
5621+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
5622+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
5623+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
5624+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
5625+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
5626+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
5627+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
5628+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
5629+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
5630+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
5631+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
5632+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
5633+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
5634+#define GPIO102_GPIO MFP_CFG(GPIO102, AF0)
5635+#define GPIO103_GPIO MFP_CFG(GPIO103, AF0)
5636+#define GPIO104_GPIO MFP_CFG(GPIO104, AF0)
5637+#define GPIO105_GPIO MFP_CFG(GPIO105, AF0)
5638+#define GPIO106_GPIO MFP_CFG(GPIO106, AF0)
5639+#define GPIO107_GPIO MFP_CFG(GPIO107, AF0)
5640+#define GPIO108_GPIO MFP_CFG(GPIO108, AF0)
5641+#define GPIO109_GPIO MFP_CFG(GPIO109, AF0)
5642+#define GPIO110_GPIO MFP_CFG(GPIO110, AF0)
5643+#define GPIO111_GPIO MFP_CFG(GPIO111, AF0)
5644+#define GPIO112_GPIO MFP_CFG(GPIO112, AF0)
5645+#define GPIO113_GPIO MFP_CFG(GPIO113, AF0)
5646+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
5647+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
5648+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
5649+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
5650+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
5651+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
5652+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
5653+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
5654+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
5655+#define GPIO123_GPIO MFP_CFG(GPIO123, AF0)
5656+#define GPIO124_GPIO MFP_CFG(GPIO124, AF0)
5657+#define GPIO125_GPIO MFP_CFG(GPIO125, AF0)
5658+#define GPIO126_GPIO MFP_CFG(GPIO126, AF0)
5659+#define GPIO127_GPIO MFP_CFG(GPIO127, AF0)
5660+
5661+#define GPIO0_2_GPIO MFP_CFG(GPIO0_2, AF0)
5662+#define GPIO1_2_GPIO MFP_CFG(GPIO1_2, AF0)
5663+#define GPIO2_2_GPIO MFP_CFG(GPIO2_2, AF0)
5664+#define GPIO3_2_GPIO MFP_CFG(GPIO3_2, AF0)
5665+#define GPIO4_2_GPIO MFP_CFG(GPIO4_2, AF0)
5666+#define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0)
5667+#define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0)
5668+
5669+/*
5670+ * each MFP pin will have a MFPR register, since the offset of the
5671+ * register varies between processors, the processor specific code
5672+ * should initialize the pin offsets by pxa3xx_mfp_init_addr()
5673+ *
5674+ * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
5675+ * structure, which represents a range of MFP pins from "start" to
5676+ * "end", with the offset begining at "offset", to define a single
5677+ * pin, let "end" = -1
5678+ *
5679+ * use
5680+ *
5681+ * MFP_ADDR_X() to define a range of pins
5682+ * MFP_ADDR() to define a single pin
5683+ * MFP_ADDR_END to signal the end of pin offset definitions
5684+ */
5685+struct pxa3xx_mfp_addr_map {
5686+ unsigned int start;
5687+ unsigned int end;
5688+ unsigned long offset;
5689+};
5690+
5691+#define MFP_ADDR_X(start, end, offset) \
5692+ { MFP_PIN_##start, MFP_PIN_##end, offset }
5693+
5694+#define MFP_ADDR(pin, offset) \
5695+ { MFP_PIN_##pin, -1, offset }
5696+
5697+#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
5698+
5699+struct pxa3xx_mfp_pin {
5700+ unsigned long mfpr_off; /* MFPRxx register offset */
5701+ unsigned long mfpr_val; /* MFPRxx register value */
5702+};
5703+
5704+/*
5705+ * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
5706+ * to the MFPR register
5707+ */
5708+unsigned long pxa3xx_mfp_read(int mfp);
5709+void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
5710+
5711+/*
5712+ * pxa3xx_mfp_set_afds - set MFP alternate function and drive strength
5713+ * pxa3xx_mfp_set_rdh - set MFP release delay hold on/off
5714+ * pxa3xx_mfp_set_lpm - set MFP low power mode state
5715+ * pxa3xx_mfp_set_edge - set MFP edge detection in low power mode
5716+ *
5717+ * use these functions to override/change the default configuration
5718+ * done by pxa3xx_mfp_set_config(s)
5719+ */
5720+void pxa3xx_mfp_set_afds(int mfp, int af, int ds);
5721+void pxa3xx_mfp_set_rdh(int mfp, int rdh);
5722+void pxa3xx_mfp_set_lpm(int mfp, int lpm);
5723+void pxa3xx_mfp_set_edge(int mfp, int edge);
5724+
5725+/*
5726+ * pxa3xx_mfp_config - configure the MFPR registers
5727+ *
5728+ * used by board specific initialization code
5729+ */
5730+void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num);
5731+
5732+/*
5733+ * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
5734+ * index and MFPR register offset
5735+ *
5736+ * used by processor specific code
5737+ */
5738+void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
5739+void __init pxa3xx_init_mfp(void);
5740+
5741+#endif /* __ASM_ARCH_MFP_H */
5742--- linux-2.6.23.orig/include/asm-arm/arch-pxa/pxa-regs.h
5743+++ linux-2.6.23/include/asm-arm/arch-pxa/pxa-regs.h
5744@@ -1184,7 +1184,7 @@
5745
5746 #define GPIO_bit(x) (1 << ((x) & 0x1f))
5747
5748-#ifdef CONFIG_PXA27x
5749+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
5750
5751 /* Interrupt Controller */
5752
5753--- /dev/null
5754+++ linux-2.6.23/include/asm-arm/arch-pxa/pxa3xx-regs.h
5755@@ -0,0 +1,75 @@
5756+/*
5757+ * linux/include/asm-arm/arch-pxa/pxa3xx-regs.h
5758+ *
5759+ * PXA3xx specific register definitions
5760+ *
5761+ * Copyright (C) 2007 Marvell International Ltd.
5762+ *
5763+ * This program is free software; you can redistribute it and/or modify
5764+ * it under the terms of the GNU General Public License version 2 as
5765+ * published by the Free Software Foundation.
5766+ */
5767+
5768+#ifndef __ASM_ARCH_PXA3XX_REGS_H
5769+#define __ASM_ARCH_PXA3XX_REGS_H
5770+
5771+/*
5772+ * Application Subsystem Clock
5773+ */
5774+#define ACCR __REG(0x41340000) /* Application Subsystem Clock Configuration Register */
5775+#define ACSR __REG(0x41340004) /* Application Subsystem Clock Status Register */
5776+#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */
5777+#define CKENA __REG(0x4134000C) /* A Clock Enable Register */
5778+#define CKENB __REG(0x41340010) /* B Clock Enable Register */
5779+#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */
5780+
5781+/*
5782+ * Clock Enable Bit
5783+ */
5784+#define CKEN_LCD 1 /* < LCD Clock Enable */
5785+#define CKEN_USBH 2 /* < USB host clock enable */
5786+#define CKEN_CAMERA 3 /* < Camera interface clock enable */
5787+#define CKEN_NAND 4 /* < NAND Flash Controller Clock Enable */
5788+#define CKEN_USB2 6 /* < USB 2.0 client clock enable. */
5789+#define CKEN_DMC 8 /* < Dynamic Memory Controller clock enable */
5790+#define CKEN_SMC 9 /* < Static Memory Controller clock enable */
5791+#define CKEN_ISC 10 /* < Internal SRAM Controller clock enable */
5792+#define CKEN_BOOT 11 /* < Boot rom clock enable */
5793+#define CKEN_MMC1 12 /* < MMC1 Clock enable */
5794+#define CKEN_MMC2 13 /* < MMC2 clock enable */
5795+#define CKEN_KEYPAD 14 /* < Keypand Controller Clock Enable */
5796+#define CKEN_CIR 15 /* < Consumer IR Clock Enable */
5797+#define CKEN_USIM0 17 /* < USIM[0] Clock Enable */
5798+#define CKEN_USIM1 18 /* < USIM[1] Clock Enable */
5799+#define CKEN_TPM 19 /* < TPM clock enable */
5800+#define CKEN_UDC 20 /* < UDC clock enable */
5801+#define CKEN_BTUART 21 /* < BTUART clock enable */
5802+#define CKEN_FFUART 22 /* < FFUART clock enable */
5803+#define CKEN_STUART 23 /* < STUART clock enable */
5804+#define CKEN_AC97 24 /* < AC97 clock enable */
5805+#define CKEN_TOUCH 25 /* < Touch screen Interface Clock Enable */
5806+#define CKEN_SSP1 26 /* < SSP1 clock enable */
5807+#define CKEN_SSP2 27 /* < SSP2 clock enable */
5808+#define CKEN_SSP3 28 /* < SSP3 clock enable */
5809+#define CKEN_SSP4 29 /* < SSP4 clock enable */
5810+#define CKEN_MSL0 30 /* < MSL0 clock enable */
5811+#define CKEN_PWM0 32 /* < PWM[0] clock enable */
5812+#define CKEN_PWM1 33 /* < PWM[1] clock enable */
5813+#define CKEN_I2C 36 /* < I2C clock enable */
5814+#define CKEN_INTC 38 /* < Interrupt controller clock enable */
5815+#define CKEN_GPIO 39 /* < GPIO clock enable */
5816+#define CKEN_1WIRE 40 /* < 1-wire clock enable */
5817+#define CKEN_HSIO2 41 /* < HSIO2 clock enable */
5818+#define CKEN_MINI_IM 48 /* < Mini-IM */
5819+#define CKEN_MINI_LCD 49 /* < Mini LCD */
5820+
5821+#if defined(CONFIG_CPU_PXA310)
5822+#define CKEN_MMC3 5 /* < MMC3 Clock Enable */
5823+#define CKEN_MVED 43 /* < MVED clock enable */
5824+#endif
5825+
5826+/* Note: GCU clock enable bit differs on PXA300/PXA310 and PXA320 */
5827+#define PXA300_CKEN_GRAPHICS 42 /* Graphics controller clock enable */
5828+#define PXA320_CKEN_GRAPHICS 7 /* Graphics controller clock enable */
5829+
5830+#endif /* __ASM_ARCH_PXA3XX_REGS_H */
5831--- linux-2.6.23.orig/include/asm-arm/arch-pxa/timex.h
5832+++ linux-2.6.23/include/asm-arm/arch-pxa/timex.h
5833@@ -21,4 +21,6 @@
5834 #else
5835 #define CLOCK_TICK_RATE 3250000
5836 #endif
5837+#else
5838+#define CLOCK_TICK_RATE 3250000
5839 #endif
5840--- /dev/null
5841+++ linux-2.6.23/include/asm-arm/arch-pxa/zylonite.h
5842@@ -0,0 +1,35 @@
5843+#ifndef __ASM_ARCH_ZYLONITE_H
5844+#define __ASM_ARCH_ZYLONITE_H
5845+
5846+#define ZYLONITE_ETH_PHYS 0x14000000
5847+
5848+/* the following variables are processor specific and initialized
5849+ * by the corresponding zylonite_pxa3xx_init()
5850+ */
5851+extern int gpio_backlight;
5852+extern int gpio_eth_irq;
5853+
5854+extern int lcd_id;
5855+extern int lcd_orientation;
5856+
5857+#ifdef CONFIG_CPU_PXA300
5858+extern void zylonite_pxa300_init(void);
5859+#else
5860+static inline void zylonite_pxa300_init(void)
5861+{
5862+ if (cpu_is_pxa300() || cpu_is_pxa310())
5863+ panic("%s: PXA300/PXA310 not supported\n", __FUNCTION__);
5864+}
5865+#endif
5866+
5867+#ifdef CONFIG_CPU_PXA320
5868+extern void zylonite_pxa320_init(void);
5869+#else
5870+static inline void zylonite_pxa320_init(void)
5871+{
5872+ if (cpu_is_pxa320())
5873+ panic("%s: PXA320 not supported\n", __FUNCTION__);
5874+}
5875+#endif
5876+
5877+#endif /* __ASM_ARCH_ZYLONITE_H */
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/binutils-buildid-arm.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/binutils-buildid-arm.patch
new file mode 100644
index 0000000000..68e35e89e1
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/binutils-buildid-arm.patch
@@ -0,0 +1,16 @@
1---
2 arch/arm/kernel/vmlinux.lds.S | 1 +
3 1 file changed, 1 insertion(+)
4
5Index: linux-2.6.22/arch/arm/kernel/vmlinux.lds.S
6===================================================================
7--- linux-2.6.22.orig/arch/arm/kernel/vmlinux.lds.S 2007-09-11 18:32:29.000000000 +0200
8+++ linux-2.6.22/arch/arm/kernel/vmlinux.lds.S 2007-09-11 18:33:42.000000000 +0200
9@@ -94,6 +94,7 @@
10 TEXT_TEXT
11 SCHED_TEXT
12 LOCK_TEXT
13+ *(.note.*)
14 #ifdef CONFIG_MMU
15 *(.fixup)
16 #endif
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-prevent-oops-HACK.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-prevent-oops-HACK.patch
new file mode 100644
index 0000000000..b5439c62e7
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-prevent-oops-HACK.patch
@@ -0,0 +1,17 @@
1Index: linux-2.6.21/drivers/net/wireless/hostap/hostap_hw.c
2===================================================================
3--- linux-2.6.21.orig/drivers/net/wireless/hostap/hostap_hw.c 2007-07-07 12:45:39.000000000 +0100
4+++ linux-2.6.21/drivers/net/wireless/hostap/hostap_hw.c 2007-07-07 12:47:30.000000000 +0100
5@@ -2666,6 +2666,12 @@
6 iface = netdev_priv(dev);
7 local = iface->local;
8
9+ if(dev->base_addr == 0)
10+ {
11+ printk(KERN_DEBUG "%s: IRQ before base_addr set\n", dev->name);
12+ return IRQ_HANDLED;
13+ }
14+
15 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
16
17 if (local->func->card_present && !local->func->card_present(local)) {
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-remove-ide-HACK.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-remove-ide-HACK.patch
new file mode 100644
index 0000000000..4414b21191
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/connectplus-remove-ide-HACK.patch
@@ -0,0 +1,12 @@
1Index: linux-2.6.13/drivers/ide/legacy/ide-cs.c
2===================================================================
3--- linux-2.6.13.orig/drivers/ide/legacy/ide-cs.c 2005-09-01 22:43:46.000000000 +0100
4+++ linux-2.6.13/drivers/ide/legacy/ide-cs.c 2005-09-01 22:45:46.000000000 +0100
5@@ -488,7 +488,6 @@
6 PCMCIA_DEVICE_PROD_ID123("KODAK Picture Card ", "KODAK ", "V100K", 0x94a0d8f3, 0xe4fc3ea0, 0xe5e7eed4),
7 PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
8 PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
9- PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
10 PCMCIA_DEVICE_NULL,
11 };
12 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-akita b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-akita
new file mode 100644
index 0000000000..ddc7ba01b1
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-akita
@@ -0,0 +1,1737 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Mon May 19 22:50:30 2008
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37# CONFIG_LOCALVERSION_AUTO is not set
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41# CONFIG_POSIX_MQUEUE is not set
42CONFIG_BSD_PROCESS_ACCT=y
43CONFIG_BSD_PROCESS_ACCT_V3=y
44# CONFIG_TASKSTATS is not set
45# CONFIG_USER_NS is not set
46# CONFIG_AUDIT is not set
47# CONFIG_IKCONFIG is not set
48CONFIG_LOG_BUF_SHIFT=14
49CONFIG_SYSFS_DEPRECATED=y
50# CONFIG_RELAY is not set
51# CONFIG_BLK_DEV_INITRD is not set
52CONFIG_CC_OPTIMIZE_FOR_SIZE=y
53CONFIG_SYSCTL=y
54CONFIG_EMBEDDED=y
55CONFIG_UID16=y
56CONFIG_SYSCTL_SYSCALL=y
57CONFIG_KALLSYMS=y
58# CONFIG_KALLSYMS_ALL is not set
59# CONFIG_KALLSYMS_EXTRA_PASS is not set
60CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y
62CONFIG_BUG=y
63CONFIG_ELF_CORE=y
64CONFIG_BASE_FULL=y
65CONFIG_FUTEX=y
66CONFIG_ANON_INODES=y
67CONFIG_EPOLL=y
68CONFIG_SIGNALFD=y
69CONFIG_EVENTFD=y
70CONFIG_SHMEM=y
71CONFIG_VM_EVENT_COUNTERS=y
72CONFIG_SLAB=y
73# CONFIG_SLUB is not set
74# CONFIG_SLOB is not set
75CONFIG_RT_MUTEXES=y
76# CONFIG_TINY_SHMEM is not set
77CONFIG_BASE_SMALL=0
78CONFIG_MODULES=y
79CONFIG_MODULE_UNLOAD=y
80CONFIG_MODULE_FORCE_UNLOAD=y
81# CONFIG_MODVERSIONS is not set
82# CONFIG_MODULE_SRCVERSION_ALL is not set
83CONFIG_KMOD=y
84CONFIG_BLOCK=y
85# CONFIG_LBD is not set
86# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set
88# CONFIG_BLK_DEV_BSG is not set
89
90#
91# IO Schedulers
92#
93CONFIG_IOSCHED_NOOP=y
94CONFIG_IOSCHED_AS=y
95CONFIG_IOSCHED_DEADLINE=m
96CONFIG_IOSCHED_CFQ=m
97CONFIG_DEFAULT_AS=y
98# CONFIG_DEFAULT_DEADLINE is not set
99# CONFIG_DEFAULT_CFQ is not set
100# CONFIG_DEFAULT_NOOP is not set
101CONFIG_DEFAULT_IOSCHED="anticipatory"
102
103#
104# System Type
105#
106# CONFIG_ARCH_AAEC2000 is not set
107# CONFIG_ARCH_INTEGRATOR is not set
108# CONFIG_ARCH_REALVIEW is not set
109# CONFIG_ARCH_VERSATILE is not set
110# CONFIG_ARCH_AT91 is not set
111# CONFIG_ARCH_CLPS7500 is not set
112# CONFIG_ARCH_CLPS711X is not set
113# CONFIG_ARCH_CO285 is not set
114# CONFIG_ARCH_EBSA110 is not set
115# CONFIG_ARCH_EP93XX is not set
116# CONFIG_ARCH_FOOTBRIDGE is not set
117# CONFIG_ARCH_NETX is not set
118# CONFIG_ARCH_H720X is not set
119# CONFIG_ARCH_IMX is not set
120# CONFIG_ARCH_IOP13XX is not set
121# CONFIG_ARCH_IOP32X is not set
122# CONFIG_ARCH_IOP33X is not set
123# CONFIG_ARCH_IXP23XX is not set
124# CONFIG_ARCH_IXP2000 is not set
125# CONFIG_ARCH_IXP4XX is not set
126# CONFIG_ARCH_L7200 is not set
127# CONFIG_ARCH_KS8695 is not set
128# CONFIG_ARCH_NS9XXX is not set
129# CONFIG_ARCH_MXC is not set
130# CONFIG_ARCH_PNX4008 is not set
131CONFIG_ARCH_PXA=y
132# CONFIG_ARCH_RPC is not set
133# CONFIG_ARCH_SA1100 is not set
134# CONFIG_ARCH_S3C2410 is not set
135# CONFIG_ARCH_SHARK is not set
136# CONFIG_ARCH_LH7A40X is not set
137# CONFIG_ARCH_DAVINCI is not set
138# CONFIG_ARCH_OMAP is not set
139
140#
141# Intel PXA2xx Implementations
142#
143# CONFIG_ARCH_LUBBOCK is not set
144# CONFIG_MACH_LOGICPD_PXA270 is not set
145# CONFIG_MACH_MAINSTONE is not set
146# CONFIG_ARCH_PXA_IDP is not set
147CONFIG_PXA_SHARPSL=y
148# CONFIG_MACH_TRIZEPS4 is not set
149# CONFIG_MACH_EM_X270 is not set
150# CONFIG_MACH_HX2750 is not set
151# CONFIG_MACH_HTCUNIVERSAL is not set
152# CONFIG_PXA_SHARPSL_25x is not set
153CONFIG_PXA_SHARPSL_27x=y
154CONFIG_MACH_AKITA=y
155CONFIG_MACH_SPITZ=y
156CONFIG_MACH_BORZOI=y
157CONFIG_PXA27x=y
158CONFIG_PXA_SHARP_Cxx00=y
159CONFIG_PXA_SSP=y
160# CONFIG_PXA_KEYS is not set
161
162#
163# Boot options
164#
165
166#
167# Power management
168#
169
170#
171# Processor Type
172#
173CONFIG_CPU_32=y
174CONFIG_CPU_XSCALE=y
175CONFIG_CPU_32v5=y
176CONFIG_CPU_ABRT_EV5T=y
177CONFIG_CPU_CACHE_VIVT=y
178CONFIG_CPU_TLB_V4WBI=y
179CONFIG_CPU_CP15=y
180CONFIG_CPU_CP15_MMU=y
181
182#
183# Processor Features
184#
185CONFIG_ARM_THUMB=y
186# CONFIG_CPU_DCACHE_DISABLE is not set
187# CONFIG_OUTER_CACHE is not set
188CONFIG_IWMMXT=y
189CONFIG_XSCALE_PMU=y
190CONFIG_SHARP_PARAM=y
191CONFIG_SHARPSL_PM=y
192CONFIG_SHARP_SCOOP=y
193
194#
195# Bus support
196#
197# CONFIG_PCI_SYSCALL is not set
198# CONFIG_ARCH_SUPPORTS_MSI is not set
199
200#
201# PCCARD (PCMCIA/CardBus) support
202#
203CONFIG_PCCARD=m
204# CONFIG_PCMCIA_DEBUG is not set
205CONFIG_PCMCIA=m
206CONFIG_PCMCIA_LOAD_CIS=y
207CONFIG_PCMCIA_IOCTL=y
208
209#
210# PC-card bridges
211#
212CONFIG_PCMCIA_PXA2XX=m
213
214#
215# Kernel Features
216#
217# CONFIG_TICK_ONESHOT is not set
218# CONFIG_NO_HZ is not set
219# CONFIG_HIGH_RES_TIMERS is not set
220CONFIG_PREEMPT=y
221CONFIG_HZ=100
222CONFIG_AEABI=y
223CONFIG_OABI_COMPAT=y
224# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
225CONFIG_SELECT_MEMORY_MODEL=y
226CONFIG_FLATMEM_MANUAL=y
227# CONFIG_DISCONTIGMEM_MANUAL is not set
228# CONFIG_SPARSEMEM_MANUAL is not set
229CONFIG_FLATMEM=y
230CONFIG_FLAT_NODE_MEM_MAP=y
231# CONFIG_SPARSEMEM_STATIC is not set
232CONFIG_SPLIT_PTLOCK_CPUS=4096
233# CONFIG_RESOURCES_64BIT is not set
234CONFIG_ZONE_DMA_FLAG=1
235CONFIG_BOUNCE=y
236CONFIG_VIRT_TO_BUS=y
237CONFIG_ALIGNMENT_TRAP=y
238
239#
240# Boot options
241#
242CONFIG_ZBOOT_ROM_TEXT=0x0
243CONFIG_ZBOOT_ROM_BSS=0x0
244CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1 dyntick=enable debug"
245# CONFIG_XIP_KERNEL is not set
246CONFIG_KEXEC=y
247CONFIG_ATAGS_PROC=y
248
249#
250# CPU Frequency scaling
251#
252# CONFIG_CPU_FREQ is not set
253
254#
255# Floating point emulation
256#
257
258#
259# At least one emulation must be selected
260#
261CONFIG_FPE_NWFPE=y
262# CONFIG_FPE_NWFPE_XP is not set
263# CONFIG_FPE_FASTFPE is not set
264
265#
266# Userspace binary formats
267#
268CONFIG_BINFMT_ELF=y
269CONFIG_BINFMT_AOUT=m
270CONFIG_BINFMT_MISC=m
271
272#
273# Power management options
274#
275CONFIG_PM=y
276# CONFIG_PM_LEGACY is not set
277# CONFIG_PM_DEBUG is not set
278CONFIG_PM_SLEEP=y
279CONFIG_SUSPEND_UP_POSSIBLE=y
280CONFIG_SUSPEND=y
281CONFIG_APM_EMULATION=y
282
283#
284# Networking
285#
286CONFIG_NET=y
287
288#
289# Networking options
290#
291CONFIG_PACKET=m
292CONFIG_PACKET_MMAP=y
293CONFIG_UNIX=y
294CONFIG_XFRM=y
295# CONFIG_XFRM_USER is not set
296# CONFIG_XFRM_SUB_POLICY is not set
297# CONFIG_XFRM_MIGRATE is not set
298# CONFIG_NET_KEY is not set
299CONFIG_INET=y
300# CONFIG_IP_MULTICAST is not set
301# CONFIG_IP_ADVANCED_ROUTER is not set
302CONFIG_IP_FIB_HASH=y
303# CONFIG_IP_PNP is not set
304# CONFIG_NET_IPIP is not set
305# CONFIG_NET_IPGRE is not set
306# CONFIG_ARPD is not set
307CONFIG_SYN_COOKIES=y
308# CONFIG_INET_AH is not set
309# CONFIG_INET_ESP is not set
310# CONFIG_INET_IPCOMP is not set
311# CONFIG_INET_XFRM_TUNNEL is not set
312CONFIG_INET_TUNNEL=m
313CONFIG_INET_XFRM_MODE_TRANSPORT=m
314CONFIG_INET_XFRM_MODE_TUNNEL=m
315CONFIG_INET_XFRM_MODE_BEET=m
316CONFIG_INET_DIAG=m
317CONFIG_INET_TCP_DIAG=m
318# CONFIG_TCP_CONG_ADVANCED is not set
319CONFIG_TCP_CONG_CUBIC=y
320CONFIG_DEFAULT_TCP_CONG="cubic"
321# CONFIG_TCP_MD5SIG is not set
322# CONFIG_IP_VS is not set
323CONFIG_IPV6=m
324# CONFIG_IPV6_PRIVACY is not set
325# CONFIG_IPV6_ROUTER_PREF is not set
326# CONFIG_IPV6_OPTIMISTIC_DAD is not set
327CONFIG_INET6_AH=m
328CONFIG_INET6_ESP=m
329CONFIG_INET6_IPCOMP=m
330# CONFIG_IPV6_MIP6 is not set
331CONFIG_INET6_XFRM_TUNNEL=m
332CONFIG_INET6_TUNNEL=m
333CONFIG_INET6_XFRM_MODE_TRANSPORT=m
334CONFIG_INET6_XFRM_MODE_TUNNEL=m
335CONFIG_INET6_XFRM_MODE_BEET=m
336# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
337CONFIG_IPV6_SIT=m
338CONFIG_IPV6_TUNNEL=m
339# CONFIG_IPV6_MULTIPLE_TABLES is not set
340# CONFIG_NETWORK_SECMARK is not set
341CONFIG_NETFILTER=y
342# CONFIG_NETFILTER_DEBUG is not set
343
344#
345# Core Netfilter Configuration
346#
347# CONFIG_NETFILTER_NETLINK is not set
348# CONFIG_NF_CONNTRACK_ENABLED is not set
349# CONFIG_NF_CONNTRACK is not set
350CONFIG_NETFILTER_XTABLES=m
351# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
352# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
353# CONFIG_NETFILTER_XT_TARGET_MARK is not set
354# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
355# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
356# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
357# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
358# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
359# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
360# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
361# CONFIG_NETFILTER_XT_MATCH_ESP is not set
362# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
363# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
364# CONFIG_NETFILTER_XT_MATCH_MAC is not set
365# CONFIG_NETFILTER_XT_MATCH_MARK is not set
366# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
367# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
368# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
369# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
370# CONFIG_NETFILTER_XT_MATCH_REALM is not set
371# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
372# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
373# CONFIG_NETFILTER_XT_MATCH_STRING is not set
374# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
375# CONFIG_NETFILTER_XT_MATCH_U32 is not set
376# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
377
378#
379# IP: Netfilter Configuration
380#
381CONFIG_IP_NF_QUEUE=m
382CONFIG_IP_NF_IPTABLES=m
383CONFIG_IP_NF_MATCH_IPRANGE=m
384CONFIG_IP_NF_MATCH_TOS=m
385CONFIG_IP_NF_MATCH_RECENT=m
386CONFIG_IP_NF_MATCH_ECN=m
387CONFIG_IP_NF_MATCH_AH=m
388CONFIG_IP_NF_MATCH_TTL=m
389CONFIG_IP_NF_MATCH_OWNER=m
390CONFIG_IP_NF_MATCH_ADDRTYPE=m
391CONFIG_IP_NF_FILTER=m
392CONFIG_IP_NF_TARGET_REJECT=m
393CONFIG_IP_NF_TARGET_LOG=m
394CONFIG_IP_NF_TARGET_ULOG=m
395CONFIG_IP_NF_MANGLE=m
396CONFIG_IP_NF_TARGET_TOS=m
397CONFIG_IP_NF_TARGET_ECN=m
398CONFIG_IP_NF_TARGET_TTL=m
399CONFIG_IP_NF_RAW=m
400CONFIG_IP_NF_ARPTABLES=m
401CONFIG_IP_NF_ARPFILTER=m
402CONFIG_IP_NF_ARP_MANGLE=m
403
404#
405# IPv6: Netfilter Configuration (EXPERIMENTAL)
406#
407# CONFIG_IP6_NF_QUEUE is not set
408# CONFIG_IP6_NF_IPTABLES is not set
409# CONFIG_IP_DCCP is not set
410# CONFIG_IP_SCTP is not set
411# CONFIG_TIPC is not set
412# CONFIG_ATM is not set
413# CONFIG_BRIDGE is not set
414# CONFIG_VLAN_8021Q is not set
415# CONFIG_DECNET is not set
416# CONFIG_LLC2 is not set
417# CONFIG_IPX is not set
418# CONFIG_ATALK is not set
419# CONFIG_X25 is not set
420# CONFIG_LAPB is not set
421# CONFIG_ECONET is not set
422# CONFIG_WAN_ROUTER is not set
423
424#
425# QoS and/or fair queueing
426#
427# CONFIG_NET_SCHED is not set
428
429#
430# Network testing
431#
432# CONFIG_NET_PKTGEN is not set
433# CONFIG_HAMRADIO is not set
434CONFIG_IRDA=m
435
436#
437# IrDA protocols
438#
439CONFIG_IRLAN=m
440CONFIG_IRNET=m
441CONFIG_IRCOMM=m
442# CONFIG_IRDA_ULTRA is not set
443
444#
445# IrDA options
446#
447# CONFIG_IRDA_CACHE_LAST_LSAP is not set
448# CONFIG_IRDA_FAST_RR is not set
449# CONFIG_IRDA_DEBUG is not set
450
451#
452# Infrared-port device drivers
453#
454
455#
456# SIR device drivers
457#
458# CONFIG_IRTTY_SIR is not set
459
460#
461# Dongle support
462#
463# CONFIG_KINGSUN_DONGLE is not set
464
465#
466# Old SIR device drivers
467#
468# CONFIG_IRPORT_SIR is not set
469
470#
471# Old Serial dongle support
472#
473
474#
475# FIR device drivers
476#
477# CONFIG_USB_IRDA is not set
478# CONFIG_SIGMATEL_FIR is not set
479CONFIG_PXA_FICP=m
480# CONFIG_MCS_FIR is not set
481CONFIG_BT=m
482CONFIG_BT_L2CAP=m
483CONFIG_BT_SCO=m
484CONFIG_BT_RFCOMM=m
485CONFIG_BT_RFCOMM_TTY=y
486CONFIG_BT_BNEP=m
487CONFIG_BT_BNEP_MC_FILTER=y
488CONFIG_BT_BNEP_PROTO_FILTER=y
489CONFIG_BT_HIDP=m
490
491#
492# Bluetooth device drivers
493#
494CONFIG_BT_HCIUSB=m
495# CONFIG_BT_HCIUSB_SCO is not set
496CONFIG_BT_HCIUART=m
497CONFIG_BT_HCIUART_H4=y
498CONFIG_BT_HCIUART_BCSP=y
499CONFIG_BT_HCIBCM203X=m
500CONFIG_BT_HCIBPA10X=m
501CONFIG_BT_HCIBFUSB=m
502CONFIG_BT_HCIDTL1=m
503CONFIG_BT_HCIBT3C=m
504CONFIG_BT_HCIBLUECARD=m
505CONFIG_BT_HCIBTUART=m
506CONFIG_BT_HCIVHCI=m
507# CONFIG_AF_RXRPC is not set
508
509#
510# Wireless
511#
512# CONFIG_CFG80211 is not set
513CONFIG_WIRELESS_EXT=y
514# CONFIG_MAC80211 is not set
515CONFIG_IEEE80211=m
516# CONFIG_IEEE80211_DEBUG is not set
517CONFIG_IEEE80211_CRYPT_WEP=m
518CONFIG_IEEE80211_CRYPT_CCMP=m
519CONFIG_IEEE80211_CRYPT_TKIP=m
520# CONFIG_IEEE80211_SOFTMAC is not set
521# CONFIG_RFKILL is not set
522# CONFIG_NET_9P is not set
523
524#
525# Device Drivers
526#
527
528#
529# Generic Driver Options
530#
531CONFIG_STANDALONE=y
532CONFIG_PREVENT_FIRMWARE_BUILD=y
533CONFIG_FW_LOADER=y
534# CONFIG_DEBUG_DRIVER is not set
535# CONFIG_DEBUG_DEVRES is not set
536# CONFIG_SYS_HYPERVISOR is not set
537# CONFIG_CONNECTOR is not set
538CONFIG_MTD=y
539# CONFIG_MTD_DEBUG is not set
540# CONFIG_MTD_CONCAT is not set
541CONFIG_MTD_PARTITIONS=y
542# CONFIG_MTD_REDBOOT_PARTS is not set
543CONFIG_MTD_CMDLINE_PARTS=y
544# CONFIG_MTD_AFS_PARTS is not set
545
546#
547# User Modules And Translation Layers
548#
549CONFIG_MTD_CHAR=y
550CONFIG_MTD_BLKDEVS=y
551CONFIG_MTD_BLOCK=y
552# CONFIG_FTL is not set
553# CONFIG_NFTL is not set
554# CONFIG_INFTL is not set
555# CONFIG_RFD_FTL is not set
556# CONFIG_SSFDC is not set
557
558#
559# RAM/ROM/Flash chip drivers
560#
561# CONFIG_MTD_CFI is not set
562# CONFIG_MTD_JEDECPROBE is not set
563CONFIG_MTD_MAP_BANK_WIDTH_1=y
564CONFIG_MTD_MAP_BANK_WIDTH_2=y
565CONFIG_MTD_MAP_BANK_WIDTH_4=y
566# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
567# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
568# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
569CONFIG_MTD_CFI_I1=y
570CONFIG_MTD_CFI_I2=y
571# CONFIG_MTD_CFI_I4 is not set
572# CONFIG_MTD_CFI_I8 is not set
573# CONFIG_MTD_RAM is not set
574CONFIG_MTD_ROM=y
575# CONFIG_MTD_ABSENT is not set
576
577#
578# Mapping drivers for chip access
579#
580CONFIG_MTD_COMPLEX_MAPPINGS=y
581# CONFIG_MTD_PHYSMAP is not set
582CONFIG_MTD_SHARP_SL=y
583# CONFIG_MTD_PLATRAM is not set
584
585#
586# Self-contained MTD device drivers
587#
588# CONFIG_MTD_SLRAM is not set
589# CONFIG_MTD_PHRAM is not set
590# CONFIG_MTD_MTDRAM is not set
591# CONFIG_MTD_BLOCK2MTD is not set
592
593#
594# Disk-On-Chip Device Drivers
595#
596# CONFIG_MTD_DOC2000 is not set
597# CONFIG_MTD_DOC2001 is not set
598# CONFIG_MTD_DOC2001PLUS is not set
599CONFIG_MTD_NAND=y
600CONFIG_MTD_NAND_VERIFY_WRITE=y
601# CONFIG_MTD_NAND_ECC_SMC is not set
602# CONFIG_MTD_NAND_MUSEUM_IDS is not set
603# CONFIG_MTD_NAND_H1900 is not set
604CONFIG_MTD_NAND_IDS=y
605# CONFIG_MTD_NAND_DISKONCHIP is not set
606CONFIG_MTD_NAND_SHARPSL=y
607# CONFIG_MTD_NAND_NANDSIM is not set
608# CONFIG_MTD_NAND_PLATFORM is not set
609# CONFIG_MTD_ONENAND is not set
610
611#
612# UBI - Unsorted block images
613#
614# CONFIG_MTD_UBI is not set
615# CONFIG_PARPORT is not set
616CONFIG_BLK_DEV=y
617# CONFIG_BLK_DEV_COW_COMMON is not set
618CONFIG_BLK_DEV_LOOP=y
619# CONFIG_BLK_DEV_CRYPTOLOOP is not set
620# CONFIG_BLK_DEV_NBD is not set
621# CONFIG_BLK_DEV_UB is not set
622# CONFIG_BLK_DEV_RAM is not set
623# CONFIG_CDROM_PKTCDVD is not set
624# CONFIG_ATA_OVER_ETH is not set
625CONFIG_IDE=y
626CONFIG_IDE_MAX_HWIFS=4
627CONFIG_BLK_DEV_IDE=y
628
629#
630# Please see Documentation/ide.txt for help/info on IDE drives
631#
632# CONFIG_BLK_DEV_IDE_SATA is not set
633CONFIG_BLK_DEV_IDEDISK=y
634# CONFIG_IDEDISK_MULTI_MODE is not set
635CONFIG_BLK_DEV_IDECS=m
636# CONFIG_BLK_DEV_IDECD is not set
637# CONFIG_BLK_DEV_IDETAPE is not set
638# CONFIG_BLK_DEV_IDEFLOPPY is not set
639# CONFIG_BLK_DEV_IDESCSI is not set
640# CONFIG_IDE_TASK_IOCTL is not set
641CONFIG_IDE_PROC_FS=y
642
643#
644# IDE chipset support/bugfixes
645#
646CONFIG_IDE_GENERIC=y
647# CONFIG_IDEPCI_PCIBUS_ORDER is not set
648# CONFIG_IDE_ARM is not set
649# CONFIG_BLK_DEV_IDEDMA is not set
650# CONFIG_BLK_DEV_HD is not set
651
652#
653# SCSI device support
654#
655# CONFIG_RAID_ATTRS is not set
656CONFIG_SCSI=m
657CONFIG_SCSI_DMA=y
658# CONFIG_SCSI_TGT is not set
659# CONFIG_SCSI_NETLINK is not set
660CONFIG_SCSI_PROC_FS=y
661
662#
663# SCSI support type (disk, tape, CD-ROM)
664#
665CONFIG_BLK_DEV_SD=m
666CONFIG_CHR_DEV_ST=m
667CONFIG_CHR_DEV_OSST=m
668CONFIG_BLK_DEV_SR=m
669# CONFIG_BLK_DEV_SR_VENDOR is not set
670CONFIG_CHR_DEV_SG=m
671# CONFIG_CHR_DEV_SCH is not set
672
673#
674# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
675#
676CONFIG_SCSI_MULTI_LUN=y
677# CONFIG_SCSI_CONSTANTS is not set
678# CONFIG_SCSI_LOGGING is not set
679# CONFIG_SCSI_SCAN_ASYNC is not set
680CONFIG_SCSI_WAIT_SCAN=m
681
682#
683# SCSI Transports
684#
685# CONFIG_SCSI_SPI_ATTRS is not set
686# CONFIG_SCSI_FC_ATTRS is not set
687# CONFIG_SCSI_ISCSI_ATTRS is not set
688# CONFIG_SCSI_SAS_LIBSAS is not set
689CONFIG_SCSI_LOWLEVEL=y
690# CONFIG_ISCSI_TCP is not set
691# CONFIG_SCSI_DEBUG is not set
692# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
693# CONFIG_ATA is not set
694CONFIG_MD=y
695# CONFIG_BLK_DEV_MD is not set
696CONFIG_BLK_DEV_DM=m
697# CONFIG_DM_DEBUG is not set
698CONFIG_DM_CRYPT=m
699CONFIG_DM_SNAPSHOT=m
700CONFIG_DM_MIRROR=m
701CONFIG_DM_ZERO=m
702CONFIG_DM_MULTIPATH=m
703CONFIG_DM_MULTIPATH_EMC=m
704# CONFIG_DM_MULTIPATH_RDAC is not set
705# CONFIG_DM_DELAY is not set
706CONFIG_NETDEVICES=y
707# CONFIG_NETDEVICES_MULTIQUEUE is not set
708# CONFIG_DUMMY is not set
709# CONFIG_BONDING is not set
710# CONFIG_MACVLAN is not set
711# CONFIG_EQUALIZER is not set
712CONFIG_TUN=m
713# CONFIG_PHYLIB is not set
714CONFIG_NET_ETHERNET=y
715CONFIG_MII=m
716# CONFIG_AX88796 is not set
717# CONFIG_SMC91X is not set
718# CONFIG_DM9000 is not set
719# CONFIG_SMC911X is not set
720# CONFIG_NETDEV_1000 is not set
721# CONFIG_NETDEV_10000 is not set
722
723#
724# Wireless LAN
725#
726CONFIG_WLAN_PRE80211=y
727# CONFIG_STRIP is not set
728# CONFIG_PCMCIA_WAVELAN is not set
729# CONFIG_PCMCIA_NETWAVE is not set
730CONFIG_WLAN_80211=y
731# CONFIG_PCMCIA_RAYCS is not set
732# CONFIG_LIBERTAS is not set
733CONFIG_HERMES=m
734# CONFIG_ATMEL is not set
735CONFIG_PCMCIA_HERMES=m
736CONFIG_PCMCIA_SPECTRUM=m
737CONFIG_AIRO_CS=m
738# CONFIG_PCMCIA_WL3501 is not set
739# CONFIG_USB_ZD1201 is not set
740CONFIG_HOSTAP=m
741CONFIG_HOSTAP_FIRMWARE=y
742# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
743CONFIG_HOSTAP_CS=m
744
745#
746# USB Network Adapters
747#
748CONFIG_USB_CATC=m
749CONFIG_USB_KAWETH=m
750CONFIG_USB_PEGASUS=m
751CONFIG_USB_RTL8150=m
752CONFIG_USB_USBNET_MII=m
753CONFIG_USB_USBNET=m
754CONFIG_USB_NET_AX8817X=m
755CONFIG_USB_NET_CDCETHER=m
756# CONFIG_USB_NET_DM9601 is not set
757# CONFIG_USB_NET_GL620A is not set
758CONFIG_USB_NET_NET1080=m
759# CONFIG_USB_NET_PLUSB is not set
760# CONFIG_USB_NET_MCS7830 is not set
761# CONFIG_USB_NET_RNDIS_HOST is not set
762# CONFIG_USB_NET_CDC_SUBSET is not set
763CONFIG_USB_NET_ZAURUS=m
764CONFIG_NET_PCMCIA=y
765# CONFIG_PCMCIA_3C589 is not set
766# CONFIG_PCMCIA_3C574 is not set
767# CONFIG_PCMCIA_FMVJ18X is not set
768CONFIG_PCMCIA_PCNET=m
769# CONFIG_PCMCIA_NMCLAN is not set
770# CONFIG_PCMCIA_SMC91C92 is not set
771# CONFIG_PCMCIA_XIRC2PS is not set
772# CONFIG_PCMCIA_AXNET is not set
773# CONFIG_WAN is not set
774CONFIG_PPP=m
775# CONFIG_PPP_MULTILINK is not set
776# CONFIG_PPP_FILTER is not set
777CONFIG_PPP_ASYNC=m
778# CONFIG_PPP_SYNC_TTY is not set
779CONFIG_PPP_DEFLATE=m
780CONFIG_PPP_BSDCOMP=m
781# CONFIG_PPP_MPPE is not set
782# CONFIG_PPPOE is not set
783# CONFIG_PPPOL2TP is not set
784# CONFIG_SLIP is not set
785CONFIG_SLHC=m
786# CONFIG_SHAPER is not set
787# CONFIG_NETCONSOLE is not set
788# CONFIG_NETPOLL is not set
789# CONFIG_NET_POLL_CONTROLLER is not set
790# CONFIG_ISDN is not set
791
792#
793# Input device support
794#
795CONFIG_INPUT=y
796# CONFIG_INPUT_FF_MEMLESS is not set
797# CONFIG_INPUT_POLLDEV is not set
798
799#
800# Userland interfaces
801#
802CONFIG_INPUT_MOUSEDEV=m
803# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
804CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
805CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
806# CONFIG_INPUT_JOYDEV is not set
807# CONFIG_INPUT_TSDEV is not set
808CONFIG_INPUT_EVDEV=y
809# CONFIG_INPUT_EVBUG is not set
810CONFIG_INPUT_POWER=y
811
812#
813# Input Device Drivers
814#
815CONFIG_INPUT_KEYBOARD=y
816# CONFIG_KEYBOARD_ATKBD is not set
817# CONFIG_KEYBOARD_SUNKBD is not set
818# CONFIG_KEYBOARD_LKKBD is not set
819# CONFIG_KEYBOARD_XTKBD is not set
820# CONFIG_KEYBOARD_NEWTON is not set
821# CONFIG_KEYBOARD_STOWAWAY is not set
822# CONFIG_KEYBOARD_CORGI is not set
823CONFIG_KEYBOARD_SPITZ=y
824# CONFIG_KEYBOARD_PXA27x is not set
825# CONFIG_KEYBOARD_GPIO is not set
826# CONFIG_INPUT_MOUSE is not set
827# CONFIG_INPUT_JOYSTICK is not set
828# CONFIG_INPUT_TABLET is not set
829CONFIG_INPUT_TOUCHSCREEN=y
830CONFIG_TOUCHSCREEN_CORGI=y
831# CONFIG_TOUCHSCREEN_FUJITSU is not set
832# CONFIG_TOUCHSCREEN_GUNZE is not set
833# CONFIG_TOUCHSCREEN_ELO is not set
834# CONFIG_TOUCHSCREEN_MTOUCH is not set
835# CONFIG_TOUCHSCREEN_MK712 is not set
836# CONFIG_TOUCHSCREEN_PENMOUNT is not set
837# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
838# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
839# CONFIG_TOUCHSCREEN_UCB1400 is not set
840# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
841CONFIG_INPUT_MISC=y
842# CONFIG_INPUT_ATI_REMOTE is not set
843# CONFIG_INPUT_ATI_REMOTE2 is not set
844# CONFIG_INPUT_KEYSPAN_REMOTE is not set
845# CONFIG_INPUT_POWERMATE is not set
846# CONFIG_INPUT_YEALINK is not set
847CONFIG_INPUT_UINPUT=m
848
849#
850# Hardware I/O ports
851#
852# CONFIG_SERIO is not set
853# CONFIG_GAMEPORT is not set
854
855#
856# Character devices
857#
858CONFIG_VT=y
859CONFIG_VT_CONSOLE=y
860CONFIG_HW_CONSOLE=y
861# CONFIG_VT_HW_CONSOLE_BINDING is not set
862# CONFIG_SERIAL_NONSTANDARD is not set
863
864#
865# Serial drivers
866#
867CONFIG_SERIAL_8250=m
868CONFIG_SERIAL_8250_CS=m
869CONFIG_SERIAL_8250_NR_UARTS=4
870CONFIG_SERIAL_8250_RUNTIME_UARTS=4
871# CONFIG_SERIAL_8250_EXTENDED is not set
872
873#
874# Non-8250 serial port support
875#
876CONFIG_SERIAL_PXA=y
877CONFIG_SERIAL_PXA_CONSOLE=y
878CONFIG_SERIAL_CORE=y
879CONFIG_SERIAL_CORE_CONSOLE=y
880CONFIG_UNIX98_PTYS=y
881# CONFIG_LEGACY_PTYS is not set
882# CONFIG_IPMI_HANDLER is not set
883# CONFIG_WATCHDOG is not set
884CONFIG_HW_RANDOM=m
885# CONFIG_NVRAM is not set
886# CONFIG_R3964 is not set
887
888#
889# PCMCIA character devices
890#
891# CONFIG_SYNCLINK_CS is not set
892# CONFIG_CARDMAN_4000 is not set
893# CONFIG_CARDMAN_4040 is not set
894# CONFIG_RAW_DRIVER is not set
895# CONFIG_TCG_TPM is not set
896CONFIG_I2C=y
897CONFIG_I2C_BOARDINFO=y
898# CONFIG_I2C_CHARDEV is not set
899
900#
901# I2C Algorithms
902#
903# CONFIG_I2C_ALGOBIT is not set
904# CONFIG_I2C_ALGOPCF is not set
905# CONFIG_I2C_ALGOPCA is not set
906
907#
908# I2C Hardware Bus support
909#
910# CONFIG_I2C_GPIO is not set
911CONFIG_I2C_PXA=y
912# CONFIG_I2C_PXA_SLAVE is not set
913# CONFIG_I2C_OCORES is not set
914# CONFIG_I2C_PARPORT_LIGHT is not set
915# CONFIG_I2C_SIMTEC is not set
916# CONFIG_I2C_TAOS_EVM is not set
917# CONFIG_I2C_STUB is not set
918# CONFIG_I2C_TINY_USB is not set
919
920#
921# Miscellaneous I2C Chip support
922#
923# CONFIG_SENSORS_DS1337 is not set
924# CONFIG_SENSORS_DS1374 is not set
925# CONFIG_DS1682 is not set
926# CONFIG_SENSORS_EEPROM is not set
927# CONFIG_SENSORS_PCF8574 is not set
928# CONFIG_SENSORS_PCA9539 is not set
929# CONFIG_SENSORS_PCF8591 is not set
930# CONFIG_SENSORS_MAX6875 is not set
931# CONFIG_SENSORS_TSL2550 is not set
932# CONFIG_I2C_DEBUG_CORE is not set
933# CONFIG_I2C_DEBUG_ALGO is not set
934# CONFIG_I2C_DEBUG_BUS is not set
935# CONFIG_I2C_DEBUG_CHIP is not set
936
937#
938# SPI support
939#
940# CONFIG_SPI is not set
941# CONFIG_SPI_MASTER is not set
942# CONFIG_W1 is not set
943# CONFIG_POWER_SUPPLY is not set
944# CONFIG_HWMON is not set
945CONFIG_MISC_DEVICES=y
946# CONFIG_EEPROM_93CX6 is not set
947
948#
949# Multifunction device drivers
950#
951# CONFIG_MFD_SM501 is not set
952# CONFIG_HTC_ASIC3 is not set
953# CONFIG_HTC_ASIC3_DS1WM is not set
954
955#
956# Multi-Function Devices
957#
958CONFIG_NEW_LEDS=y
959CONFIG_LEDS_CLASS=y
960
961#
962# LED drivers
963#
964CONFIG_LEDS_SPITZ=y
965# CONFIG_LEDS_TOSA is not set
966# CONFIG_LEDS_GPIO is not set
967
968#
969# LED Triggers
970#
971CONFIG_LEDS_TRIGGERS=y
972CONFIG_LEDS_TRIGGER_TIMER=y
973CONFIG_LEDS_TRIGGER_IDE_DISK=y
974# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
975
976#
977# Multimedia devices
978#
979CONFIG_VIDEO_DEV=m
980CONFIG_VIDEO_V4L1=y
981CONFIG_VIDEO_V4L1_COMPAT=y
982CONFIG_VIDEO_V4L2=y
983CONFIG_VIDEO_CAPTURE_DRIVERS=y
984# CONFIG_VIDEO_ADV_DEBUG is not set
985CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
986# CONFIG_VIDEO_CPIA is not set
987# CONFIG_VIDEO_CPIA2 is not set
988# CONFIG_VIDEO_SAA5246A is not set
989# CONFIG_VIDEO_SAA5249 is not set
990# CONFIG_TUNER_3036 is not set
991# CONFIG_TUNER_TEA5761 is not set
992CONFIG_V4L_USB_DRIVERS=y
993# CONFIG_VIDEO_PVRUSB2 is not set
994# CONFIG_VIDEO_EM28XX is not set
995# CONFIG_VIDEO_USBVISION is not set
996# CONFIG_USB_VICAM is not set
997# CONFIG_USB_IBMCAM is not set
998# CONFIG_USB_KONICAWC is not set
999# CONFIG_USB_QUICKCAM_MESSENGER is not set
1000# CONFIG_USB_ET61X251 is not set
1001# CONFIG_VIDEO_OVCAMCHIP is not set
1002# CONFIG_USB_W9968CF is not set
1003# CONFIG_USB_OV511 is not set
1004# CONFIG_USB_SE401 is not set
1005# CONFIG_USB_SN9C102 is not set
1006# CONFIG_USB_STV680 is not set
1007# CONFIG_USB_ZC0301 is not set
1008# CONFIG_USB_PWC is not set
1009# CONFIG_USB_ZR364XX is not set
1010CONFIG_RADIO_ADAPTERS=y
1011# CONFIG_USB_DSBR is not set
1012# CONFIG_DVB_CORE is not set
1013CONFIG_DAB=y
1014CONFIG_USB_DABUSB=m
1015
1016#
1017# Graphics support
1018#
1019CONFIG_BACKLIGHT_LCD_SUPPORT=y
1020CONFIG_LCD_CLASS_DEVICE=y
1021CONFIG_BACKLIGHT_CLASS_DEVICE=y
1022CONFIG_BACKLIGHT_CORGI=y
1023
1024#
1025# Display device support
1026#
1027# CONFIG_DISPLAY_SUPPORT is not set
1028# CONFIG_VGASTATE is not set
1029CONFIG_VIDEO_OUTPUT_CONTROL=m
1030CONFIG_FB=y
1031CONFIG_FIRMWARE_EDID=y
1032# CONFIG_FB_DDC is not set
1033CONFIG_FB_CFB_FILLRECT=y
1034CONFIG_FB_CFB_COPYAREA=y
1035CONFIG_FB_CFB_IMAGEBLIT=y
1036# CONFIG_FB_SYS_FILLRECT is not set
1037# CONFIG_FB_SYS_COPYAREA is not set
1038# CONFIG_FB_SYS_IMAGEBLIT is not set
1039# CONFIG_FB_SYS_FOPS is not set
1040CONFIG_FB_DEFERRED_IO=y
1041# CONFIG_FB_SVGALIB is not set
1042# CONFIG_FB_MACMODES is not set
1043# CONFIG_FB_BACKLIGHT is not set
1044# CONFIG_FB_MODE_HELPERS is not set
1045# CONFIG_FB_TILEBLITTING is not set
1046
1047#
1048# Frame buffer hardware drivers
1049#
1050# CONFIG_FB_S1D13XXX is not set
1051CONFIG_FB_PXA=y
1052CONFIG_FB_PXA_LCD_QVGA=y
1053# CONFIG_FB_PXA_LCD_VGA is not set
1054CONFIG_FB_PXA_OVERLAY=y
1055# CONFIG_FB_PXA_PARAMETERS is not set
1056# CONFIG_FB_MBX is not set
1057# CONFIG_FB_W100 is not set
1058# CONFIG_FB_VIRTUAL is not set
1059
1060#
1061# Console display driver support
1062#
1063# CONFIG_VGA_CONSOLE is not set
1064CONFIG_DUMMY_CONSOLE=y
1065CONFIG_FRAMEBUFFER_CONSOLE=y
1066# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1067CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
1068CONFIG_FONTS=y
1069# CONFIG_FONT_8x8 is not set
1070CONFIG_FONT_8x16=y
1071# CONFIG_FONT_6x11 is not set
1072# CONFIG_FONT_7x14 is not set
1073# CONFIG_FONT_PEARL_8x8 is not set
1074# CONFIG_FONT_ACORN_8x8 is not set
1075# CONFIG_FONT_MINI_4x6 is not set
1076# CONFIG_FONT_SUN8x16 is not set
1077# CONFIG_FONT_SUN12x22 is not set
1078# CONFIG_FONT_10x18 is not set
1079CONFIG_LOGO=y
1080CONFIG_LOGO_LINUX_MONO=y
1081CONFIG_LOGO_LINUX_VGA16=y
1082# CONFIG_LOGO_LINUX_CLUT224 is not set
1083CONFIG_LOGO_OHAND_CLUT224=y
1084
1085#
1086# Sound
1087#
1088CONFIG_SOUND=m
1089
1090#
1091# Advanced Linux Sound Architecture
1092#
1093CONFIG_SND=m
1094CONFIG_SND_TIMER=m
1095CONFIG_SND_PCM=m
1096CONFIG_SND_HWDEP=m
1097CONFIG_SND_RAWMIDI=m
1098CONFIG_SND_SEQUENCER=m
1099# CONFIG_SND_SEQ_DUMMY is not set
1100CONFIG_SND_OSSEMUL=y
1101CONFIG_SND_MIXER_OSS=m
1102CONFIG_SND_PCM_OSS=m
1103CONFIG_SND_PCM_OSS_PLUGINS=y
1104# CONFIG_SND_SEQUENCER_OSS is not set
1105# CONFIG_SND_DYNAMIC_MINORS is not set
1106CONFIG_SND_SUPPORT_OLD_API=y
1107CONFIG_SND_VERBOSE_PROCFS=y
1108CONFIG_SND_VERBOSE_PRINTK=y
1109CONFIG_SND_DEBUG=y
1110# CONFIG_SND_DEBUG_DETECT is not set
1111# CONFIG_SND_PCM_XRUN_DEBUG is not set
1112
1113#
1114# Generic devices
1115#
1116CONFIG_SND_AC97_CODEC=m
1117# CONFIG_SND_DUMMY is not set
1118# CONFIG_SND_VIRMIDI is not set
1119# CONFIG_SND_MTPAV is not set
1120# CONFIG_SND_SERIAL_U16550 is not set
1121# CONFIG_SND_MPU401 is not set
1122
1123#
1124# ALSA ARM devices
1125#
1126CONFIG_SND_PXA2XX_PCM=m
1127CONFIG_SND_PXA2XX_AC97=m
1128
1129#
1130# USB devices
1131#
1132CONFIG_SND_USB_AUDIO=m
1133# CONFIG_SND_USB_CAIAQ is not set
1134
1135#
1136# PCMCIA devices
1137#
1138# CONFIG_SND_VXPOCKET is not set
1139# CONFIG_SND_PDAUDIOCF is not set
1140
1141#
1142# System on Chip audio support
1143#
1144CONFIG_SND_SOC=m
1145CONFIG_SND_PXA2XX_SOC=m
1146CONFIG_SND_PXA2XX_SOC_I2S=m
1147CONFIG_SND_PXA2XX_SOC_SPITZ=m
1148
1149#
1150# SoC Audio support for SuperH
1151#
1152CONFIG_SND_SOC_WM8750=m
1153
1154#
1155# Open Sound System
1156#
1157# CONFIG_SOUND_PRIME is not set
1158CONFIG_AC97_BUS=m
1159CONFIG_HID_SUPPORT=y
1160CONFIG_HID=m
1161# CONFIG_HID_DEBUG is not set
1162
1163#
1164# USB Input Devices
1165#
1166CONFIG_USB_HID=m
1167# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1168# CONFIG_HID_FF is not set
1169# CONFIG_USB_HIDDEV is not set
1170
1171#
1172# USB HID Boot Protocol drivers
1173#
1174CONFIG_USB_KBD=m
1175CONFIG_USB_MOUSE=m
1176CONFIG_USB_SUPPORT=y
1177CONFIG_USB_ARCH_HAS_HCD=y
1178CONFIG_USB_ARCH_HAS_OHCI=y
1179# CONFIG_USB_ARCH_HAS_EHCI is not set
1180CONFIG_USB=m
1181# CONFIG_USB_DEBUG is not set
1182
1183#
1184# Miscellaneous USB options
1185#
1186CONFIG_USB_DEVICEFS=y
1187CONFIG_USB_DEVICE_CLASS=y
1188# CONFIG_USB_DYNAMIC_MINORS is not set
1189# CONFIG_USB_SUSPEND is not set
1190# CONFIG_USB_PERSIST is not set
1191# CONFIG_USB_OTG is not set
1192
1193#
1194# USB Host Controller Drivers
1195#
1196# CONFIG_USB_ISP116X_HCD is not set
1197CONFIG_USB_OHCI_HCD=m
1198# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1199# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1200CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1201CONFIG_USB_SL811_HCD=m
1202CONFIG_USB_SL811_CS=m
1203# CONFIG_USB_R8A66597_HCD is not set
1204
1205#
1206# USB Device Class drivers
1207#
1208CONFIG_USB_ACM=m
1209CONFIG_USB_PRINTER=m
1210
1211#
1212# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1213#
1214
1215#
1216# may also be needed; see USB_STORAGE Help for more information
1217#
1218CONFIG_USB_STORAGE=m
1219# CONFIG_USB_STORAGE_DEBUG is not set
1220# CONFIG_USB_STORAGE_DATAFAB is not set
1221# CONFIG_USB_STORAGE_FREECOM is not set
1222# CONFIG_USB_STORAGE_ISD200 is not set
1223# CONFIG_USB_STORAGE_DPCM is not set
1224# CONFIG_USB_STORAGE_USBAT is not set
1225# CONFIG_USB_STORAGE_SDDR09 is not set
1226# CONFIG_USB_STORAGE_SDDR55 is not set
1227# CONFIG_USB_STORAGE_JUMPSHOT is not set
1228# CONFIG_USB_STORAGE_ALAUDA is not set
1229# CONFIG_USB_STORAGE_KARMA is not set
1230# CONFIG_USB_LIBUSUAL is not set
1231
1232#
1233# USB Imaging devices
1234#
1235CONFIG_USB_MDC800=m
1236CONFIG_USB_MICROTEK=m
1237CONFIG_USB_MON=y
1238
1239#
1240# USB port drivers
1241#
1242
1243#
1244# USB Serial Converter support
1245#
1246CONFIG_USB_SERIAL=m
1247CONFIG_USB_SERIAL_GENERIC=y
1248# CONFIG_USB_SERIAL_AIRCABLE is not set
1249# CONFIG_USB_SERIAL_AIRPRIME is not set
1250# CONFIG_USB_SERIAL_ARK3116 is not set
1251CONFIG_USB_SERIAL_BELKIN=m
1252# CONFIG_USB_SERIAL_WHITEHEAT is not set
1253CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1254# CONFIG_USB_SERIAL_CP2101 is not set
1255CONFIG_USB_SERIAL_CYPRESS_M8=m
1256CONFIG_USB_SERIAL_EMPEG=m
1257CONFIG_USB_SERIAL_FTDI_SIO=m
1258# CONFIG_USB_SERIAL_FUNSOFT is not set
1259CONFIG_USB_SERIAL_VISOR=m
1260CONFIG_USB_SERIAL_IPAQ=m
1261CONFIG_USB_SERIAL_IR=m
1262CONFIG_USB_SERIAL_EDGEPORT=m
1263CONFIG_USB_SERIAL_EDGEPORT_TI=m
1264CONFIG_USB_SERIAL_GARMIN=m
1265CONFIG_USB_SERIAL_IPW=m
1266CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1267CONFIG_USB_SERIAL_KEYSPAN=m
1268# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1269# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1270# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1271# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1272# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1273# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1274# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1275# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1276# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1277# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1278# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1279# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1280CONFIG_USB_SERIAL_KLSI=m
1281CONFIG_USB_SERIAL_KOBIL_SCT=m
1282CONFIG_USB_SERIAL_MCT_U232=m
1283# CONFIG_USB_SERIAL_MOS7720 is not set
1284# CONFIG_USB_SERIAL_MOS7840 is not set
1285# CONFIG_USB_SERIAL_NAVMAN is not set
1286CONFIG_USB_SERIAL_PL2303=m
1287# CONFIG_USB_SERIAL_OTI6858 is not set
1288# CONFIG_USB_SERIAL_HP4X is not set
1289CONFIG_USB_SERIAL_SAFE=m
1290# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1291# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1292CONFIG_USB_SERIAL_TI=m
1293CONFIG_USB_SERIAL_CYBERJACK=m
1294CONFIG_USB_SERIAL_XIRCOM=m
1295# CONFIG_USB_SERIAL_OPTION is not set
1296CONFIG_USB_SERIAL_OMNINET=m
1297# CONFIG_USB_SERIAL_DEBUG is not set
1298CONFIG_USB_EZUSB=y
1299
1300#
1301# USB Miscellaneous drivers
1302#
1303CONFIG_USB_EMI62=m
1304CONFIG_USB_EMI26=m
1305# CONFIG_USB_ADUTUX is not set
1306CONFIG_USB_AUERSWALD=m
1307CONFIG_USB_RIO500=m
1308CONFIG_USB_LEGOTOWER=m
1309CONFIG_USB_LCD=m
1310# CONFIG_USB_BERRY_CHARGE is not set
1311CONFIG_USB_LED=m
1312# CONFIG_USB_CYPRESS_CY7C63 is not set
1313CONFIG_USB_CYTHERM=m
1314# CONFIG_USB_PHIDGET is not set
1315CONFIG_USB_IDMOUSE=m
1316# CONFIG_USB_FTDI_ELAN is not set
1317# CONFIG_USB_APPLEDISPLAY is not set
1318# CONFIG_USB_LD is not set
1319# CONFIG_USB_TRANCEVIBRATOR is not set
1320# CONFIG_USB_IOWARRIOR is not set
1321# CONFIG_USB_TEST is not set
1322
1323#
1324# USB DSL modem support
1325#
1326
1327#
1328# USB Gadget Support
1329#
1330CONFIG_USB_GADGET=m
1331# CONFIG_USB_GADGET_DEBUG is not set
1332# CONFIG_USB_GADGET_DEBUG_FILES is not set
1333CONFIG_USB_GADGET_SELECTED=y
1334# CONFIG_USB_GADGET_AMD5536UDC is not set
1335# CONFIG_USB_GADGET_FSL_USB2 is not set
1336# CONFIG_USB_GADGET_NET2280 is not set
1337# CONFIG_USB_GADGET_PXA2XX is not set
1338# CONFIG_USB_GADGET_M66592 is not set
1339CONFIG_USB_GADGET_PXA27X=y
1340CONFIG_USB_PXA27X=m
1341# CONFIG_USB_GADGET_GOKU is not set
1342# CONFIG_USB_GADGET_LH7A40X is not set
1343# CONFIG_USB_GADGET_OMAP is not set
1344# CONFIG_USB_GADGET_S3C2410 is not set
1345# CONFIG_USB_GADGET_AT91 is not set
1346# CONFIG_USB_GADGET_DUMMY_HCD is not set
1347# CONFIG_USB_GADGET_DUALSPEED is not set
1348CONFIG_USB_ZERO=m
1349CONFIG_USB_ETH=m
1350CONFIG_USB_ETH_RNDIS=y
1351CONFIG_USB_GADGETFS=m
1352CONFIG_USB_FILE_STORAGE=m
1353# CONFIG_USB_FILE_STORAGE_TEST is not set
1354CONFIG_USB_G_SERIAL=m
1355# CONFIG_USB_MIDI_GADGET is not set
1356CONFIG_MMC=y
1357# CONFIG_MMC_DEBUG is not set
1358CONFIG_MMC_UNSAFE_RESUME=y
1359
1360#
1361# MMC/SD Card Drivers
1362#
1363CONFIG_MMC_BLOCK=y
1364CONFIG_MMC_BLOCK_BOUNCE=y
1365
1366#
1367# MMC/SD Host Controller Drivers
1368#
1369CONFIG_MMC_PXA=y
1370CONFIG_RTC_LIB=y
1371CONFIG_RTC_CLASS=y
1372CONFIG_RTC_HCTOSYS=y
1373CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1374# CONFIG_RTC_DEBUG is not set
1375
1376#
1377# RTC interfaces
1378#
1379CONFIG_RTC_INTF_SYSFS=y
1380CONFIG_RTC_INTF_PROC=y
1381CONFIG_RTC_INTF_DEV=y
1382# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1383# CONFIG_RTC_DRV_TEST is not set
1384
1385#
1386# I2C RTC drivers
1387#
1388# CONFIG_RTC_DRV_DS1307 is not set
1389# CONFIG_RTC_DRV_DS1672 is not set
1390# CONFIG_RTC_DRV_MAX6900 is not set
1391# CONFIG_RTC_DRV_RS5C372 is not set
1392# CONFIG_RTC_DRV_ISL1208 is not set
1393# CONFIG_RTC_DRV_X1205 is not set
1394# CONFIG_RTC_DRV_PCF8563 is not set
1395# CONFIG_RTC_DRV_PCF8583 is not set
1396# CONFIG_RTC_DRV_M41T80 is not set
1397
1398#
1399# SPI RTC drivers
1400#
1401
1402#
1403# Platform RTC drivers
1404#
1405# CONFIG_RTC_DRV_CMOS is not set
1406# CONFIG_RTC_DRV_DS1553 is not set
1407# CONFIG_RTC_DRV_STK17TA8 is not set
1408# CONFIG_RTC_DRV_DS1742 is not set
1409# CONFIG_RTC_DRV_M48T86 is not set
1410# CONFIG_RTC_DRV_M48T59 is not set
1411# CONFIG_RTC_DRV_V3020 is not set
1412
1413#
1414# on-CPU RTC drivers
1415#
1416CONFIG_RTC_DRV_SA1100=y
1417
1418#
1419# DMA Engine support
1420#
1421# CONFIG_DMA_ENGINE is not set
1422
1423#
1424# DMA Clients
1425#
1426
1427#
1428# DMA Devices
1429#
1430
1431#
1432# File systems
1433#
1434CONFIG_EXT2_FS=y
1435# CONFIG_EXT2_FS_XATTR is not set
1436# CONFIG_EXT2_FS_XIP is not set
1437CONFIG_EXT3_FS=m
1438# CONFIG_EXT3_FS_XATTR is not set
1439# CONFIG_EXT4DEV_FS is not set
1440CONFIG_JBD=m
1441# CONFIG_JBD_DEBUG is not set
1442# CONFIG_REISERFS_FS is not set
1443# CONFIG_JFS_FS is not set
1444CONFIG_FS_POSIX_ACL=y
1445# CONFIG_XFS_FS is not set
1446# CONFIG_GFS2_FS is not set
1447# CONFIG_OCFS2_FS is not set
1448# CONFIG_MINIX_FS is not set
1449# CONFIG_ROMFS_FS is not set
1450CONFIG_INOTIFY=y
1451CONFIG_INOTIFY_USER=y
1452# CONFIG_QUOTA is not set
1453CONFIG_DNOTIFY=y
1454# CONFIG_AUTOFS_FS is not set
1455# CONFIG_AUTOFS4_FS is not set
1456# CONFIG_FUSE_FS is not set
1457
1458#
1459# CD-ROM/DVD Filesystems
1460#
1461# CONFIG_ISO9660_FS is not set
1462# CONFIG_UDF_FS is not set
1463
1464#
1465# DOS/FAT/NT Filesystems
1466#
1467CONFIG_FAT_FS=y
1468# CONFIG_MSDOS_FS is not set
1469CONFIG_VFAT_FS=y
1470CONFIG_FAT_DEFAULT_CODEPAGE=437
1471CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1472# CONFIG_NTFS_FS is not set
1473
1474#
1475# Pseudo filesystems
1476#
1477CONFIG_PROC_FS=y
1478CONFIG_PROC_SYSCTL=y
1479CONFIG_SYSFS=y
1480CONFIG_TMPFS=y
1481# CONFIG_TMPFS_POSIX_ACL is not set
1482# CONFIG_HUGETLB_PAGE is not set
1483CONFIG_RAMFS=y
1484# CONFIG_CONFIGFS_FS is not set
1485
1486#
1487# Miscellaneous filesystems
1488#
1489# CONFIG_ADFS_FS is not set
1490# CONFIG_AFFS_FS is not set
1491# CONFIG_HFS_FS is not set
1492# CONFIG_HFSPLUS_FS is not set
1493# CONFIG_BEFS_FS is not set
1494# CONFIG_BFS_FS is not set
1495# CONFIG_EFS_FS is not set
1496CONFIG_JFFS2_FS=y
1497CONFIG_JFFS2_FS_DEBUG=0
1498CONFIG_JFFS2_FS_WRITEBUFFER=y
1499CONFIG_JFFS2_SUMMARY=y
1500# CONFIG_JFFS2_FS_XATTR is not set
1501# CONFIG_JFFS2_SYSFS is not set
1502CONFIG_JFFS2_COMPRESSION_OPTIONS=y
1503CONFIG_JFFS2_ZLIB=y
1504CONFIG_JFFS2_LZO=y
1505CONFIG_JFFS2_RTIME=y
1506CONFIG_JFFS2_RUBIN=y
1507# CONFIG_JFFS2_CMODE_NONE is not set
1508CONFIG_JFFS2_CMODE_PRIORITY=y
1509# CONFIG_JFFS2_CMODE_SIZE is not set
1510# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
1511CONFIG_CRAMFS=m
1512CONFIG_SQUASHFS=m
1513# CONFIG_SQUASHFS_EMBEDDED is not set
1514CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1515# CONFIG_SQUASHFS_VMALLOC is not set
1516# CONFIG_VXFS_FS is not set
1517# CONFIG_HPFS_FS is not set
1518# CONFIG_QNX4FS_FS is not set
1519# CONFIG_SYSV_FS is not set
1520# CONFIG_UFS_FS is not set
1521
1522#
1523# Network File Systems
1524#
1525CONFIG_NFS_FS=m
1526CONFIG_NFS_V3=y
1527# CONFIG_NFS_V3_ACL is not set
1528CONFIG_NFS_V4=y
1529# CONFIG_NFS_DIRECTIO is not set
1530CONFIG_NFSD=m
1531CONFIG_NFSD_V3=y
1532# CONFIG_NFSD_V3_ACL is not set
1533CONFIG_NFSD_V4=y
1534CONFIG_NFSD_TCP=y
1535CONFIG_LOCKD=m
1536CONFIG_LOCKD_V4=y
1537CONFIG_EXPORTFS=m
1538CONFIG_NFS_COMMON=y
1539CONFIG_SUNRPC=m
1540CONFIG_SUNRPC_GSS=m
1541# CONFIG_SUNRPC_BIND34 is not set
1542CONFIG_RPCSEC_GSS_KRB5=m
1543# CONFIG_RPCSEC_GSS_SPKM3 is not set
1544CONFIG_SMB_FS=m
1545CONFIG_SMB_NLS_DEFAULT=y
1546CONFIG_SMB_NLS_REMOTE="cp437"
1547CONFIG_CIFS=m
1548# CONFIG_CIFS_STATS is not set
1549# CONFIG_CIFS_WEAK_PW_HASH is not set
1550# CONFIG_CIFS_XATTR is not set
1551# CONFIG_CIFS_DEBUG2 is not set
1552# CONFIG_CIFS_EXPERIMENTAL is not set
1553# CONFIG_NCP_FS is not set
1554# CONFIG_CODA_FS is not set
1555# CONFIG_AFS_FS is not set
1556
1557#
1558# Partition Types
1559#
1560CONFIG_PARTITION_ADVANCED=y
1561# CONFIG_ACORN_PARTITION is not set
1562# CONFIG_OSF_PARTITION is not set
1563# CONFIG_AMIGA_PARTITION is not set
1564# CONFIG_ATARI_PARTITION is not set
1565# CONFIG_MAC_PARTITION is not set
1566CONFIG_MSDOS_PARTITION=y
1567# CONFIG_BSD_DISKLABEL is not set
1568# CONFIG_MINIX_SUBPARTITION is not set
1569# CONFIG_SOLARIS_X86_PARTITION is not set
1570# CONFIG_UNIXWARE_DISKLABEL is not set
1571# CONFIG_LDM_PARTITION is not set
1572# CONFIG_SGI_PARTITION is not set
1573# CONFIG_ULTRIX_PARTITION is not set
1574# CONFIG_SUN_PARTITION is not set
1575# CONFIG_KARMA_PARTITION is not set
1576# CONFIG_EFI_PARTITION is not set
1577# CONFIG_SYSV68_PARTITION is not set
1578
1579#
1580# Native Language Support
1581#
1582CONFIG_NLS=y
1583CONFIG_NLS_DEFAULT="cp437"
1584CONFIG_NLS_CODEPAGE_437=y
1585CONFIG_NLS_CODEPAGE_737=m
1586CONFIG_NLS_CODEPAGE_775=m
1587CONFIG_NLS_CODEPAGE_850=m
1588CONFIG_NLS_CODEPAGE_852=m
1589CONFIG_NLS_CODEPAGE_855=m
1590CONFIG_NLS_CODEPAGE_857=m
1591CONFIG_NLS_CODEPAGE_860=m
1592CONFIG_NLS_CODEPAGE_861=m
1593CONFIG_NLS_CODEPAGE_862=m
1594CONFIG_NLS_CODEPAGE_863=m
1595CONFIG_NLS_CODEPAGE_864=m
1596CONFIG_NLS_CODEPAGE_865=m
1597CONFIG_NLS_CODEPAGE_866=m
1598CONFIG_NLS_CODEPAGE_869=m
1599CONFIG_NLS_CODEPAGE_936=m
1600CONFIG_NLS_CODEPAGE_950=m
1601CONFIG_NLS_CODEPAGE_932=m
1602CONFIG_NLS_CODEPAGE_949=m
1603CONFIG_NLS_CODEPAGE_874=m
1604CONFIG_NLS_ISO8859_8=m
1605CONFIG_NLS_CODEPAGE_1250=m
1606CONFIG_NLS_CODEPAGE_1251=m
1607CONFIG_NLS_ASCII=m
1608CONFIG_NLS_ISO8859_1=y
1609CONFIG_NLS_ISO8859_2=m
1610CONFIG_NLS_ISO8859_3=m
1611CONFIG_NLS_ISO8859_4=m
1612CONFIG_NLS_ISO8859_5=m
1613CONFIG_NLS_ISO8859_6=m
1614CONFIG_NLS_ISO8859_7=m
1615CONFIG_NLS_ISO8859_9=m
1616CONFIG_NLS_ISO8859_13=m
1617CONFIG_NLS_ISO8859_14=m
1618CONFIG_NLS_ISO8859_15=m
1619CONFIG_NLS_KOI8_R=m
1620CONFIG_NLS_KOI8_U=m
1621CONFIG_NLS_UTF8=y
1622
1623#
1624# Distributed Lock Manager
1625#
1626# CONFIG_DLM is not set
1627
1628#
1629# Profiling support
1630#
1631CONFIG_PROFILING=y
1632CONFIG_OPROFILE=m
1633
1634#
1635# Kernel hacking
1636#
1637# CONFIG_PRINTK_TIME is not set
1638CONFIG_ENABLE_MUST_CHECK=y
1639CONFIG_MAGIC_SYSRQ=y
1640# CONFIG_UNUSED_SYMBOLS is not set
1641# CONFIG_DEBUG_FS is not set
1642# CONFIG_HEADERS_CHECK is not set
1643CONFIG_DEBUG_KERNEL=y
1644# CONFIG_DEBUG_SHIRQ is not set
1645# CONFIG_DETECT_SOFTLOCKUP is not set
1646CONFIG_SCHED_DEBUG=y
1647# CONFIG_SCHEDSTATS is not set
1648CONFIG_TIMER_STATS=y
1649# CONFIG_DEBUG_SLAB is not set
1650# CONFIG_DEBUG_PREEMPT is not set
1651# CONFIG_DEBUG_RT_MUTEXES is not set
1652# CONFIG_RT_MUTEX_TESTER is not set
1653# CONFIG_DEBUG_SPINLOCK is not set
1654# CONFIG_DEBUG_MUTEXES is not set
1655# CONFIG_DEBUG_LOCK_ALLOC is not set
1656# CONFIG_PROVE_LOCKING is not set
1657# CONFIG_LOCK_STAT is not set
1658# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1659# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1660# CONFIG_DEBUG_KOBJECT is not set
1661CONFIG_DEBUG_BUGVERBOSE=y
1662# CONFIG_DEBUG_INFO is not set
1663# CONFIG_DEBUG_VM is not set
1664# CONFIG_DEBUG_LIST is not set
1665CONFIG_FRAME_POINTER=y
1666# CONFIG_FORCED_INLINING is not set
1667# CONFIG_RCU_TORTURE_TEST is not set
1668# CONFIG_FAULT_INJECTION is not set
1669# CONFIG_DEBUG_USER is not set
1670CONFIG_DEBUG_ERRORS=y
1671# CONFIG_DEBUG_LL is not set
1672
1673#
1674# Security options
1675#
1676# CONFIG_KEYS is not set
1677# CONFIG_SECURITY is not set
1678CONFIG_CRYPTO=y
1679CONFIG_CRYPTO_ALGAPI=y
1680CONFIG_CRYPTO_BLKCIPHER=m
1681CONFIG_CRYPTO_HASH=y
1682CONFIG_CRYPTO_MANAGER=y
1683CONFIG_CRYPTO_HMAC=y
1684# CONFIG_CRYPTO_XCBC is not set
1685CONFIG_CRYPTO_NULL=m
1686CONFIG_CRYPTO_MD4=m
1687CONFIG_CRYPTO_MD5=m
1688CONFIG_CRYPTO_SHA1=m
1689CONFIG_CRYPTO_SHA256=m
1690CONFIG_CRYPTO_SHA512=m
1691CONFIG_CRYPTO_WP512=m
1692# CONFIG_CRYPTO_TGR192 is not set
1693# CONFIG_CRYPTO_GF128MUL is not set
1694CONFIG_CRYPTO_ECB=m
1695CONFIG_CRYPTO_CBC=m
1696CONFIG_CRYPTO_PCBC=m
1697# CONFIG_CRYPTO_LRW is not set
1698# CONFIG_CRYPTO_CRYPTD is not set
1699CONFIG_CRYPTO_DES=m
1700# CONFIG_CRYPTO_FCRYPT is not set
1701CONFIG_CRYPTO_BLOWFISH=m
1702CONFIG_CRYPTO_TWOFISH=m
1703CONFIG_CRYPTO_TWOFISH_COMMON=m
1704CONFIG_CRYPTO_SERPENT=m
1705CONFIG_CRYPTO_AES=m
1706CONFIG_CRYPTO_CAST5=m
1707CONFIG_CRYPTO_CAST6=m
1708CONFIG_CRYPTO_TEA=m
1709CONFIG_CRYPTO_ARC4=m
1710CONFIG_CRYPTO_KHAZAD=m
1711CONFIG_CRYPTO_ANUBIS=m
1712CONFIG_CRYPTO_DEFLATE=m
1713# CONFIG_CRYPTO_LZO is not set
1714CONFIG_CRYPTO_MICHAEL_MIC=m
1715CONFIG_CRYPTO_CRC32C=m
1716# CONFIG_CRYPTO_CAMELLIA is not set
1717CONFIG_CRYPTO_TEST=m
1718CONFIG_CRYPTO_HW=y
1719
1720#
1721# Library routines
1722#
1723CONFIG_BITREVERSE=y
1724CONFIG_CRC_CCITT=y
1725# CONFIG_CRC16 is not set
1726# CONFIG_CRC_ITU_T is not set
1727CONFIG_CRC32=y
1728# CONFIG_CRC7 is not set
1729CONFIG_LIBCRC32C=m
1730CONFIG_ZLIB_INFLATE=y
1731CONFIG_ZLIB_DEFLATE=y
1732CONFIG_LZO_COMPRESS=y
1733CONFIG_LZO_DECOMPRESS=y
1734CONFIG_PLIST=y
1735CONFIG_HAS_IOMEM=y
1736CONFIG_HAS_IOPORT=y
1737CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-bootcdx86 b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-bootcdx86
new file mode 100644
index 0000000000..244df733ac
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-bootcdx86
@@ -0,0 +1,1579 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Wed Feb 6 18:24:38 2008
5#
6CONFIG_X86_32=y
7CONFIG_GENERIC_TIME=y
8CONFIG_GENERIC_CMOS_UPDATE=y
9CONFIG_CLOCKSOURCE_WATCHDOG=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
12CONFIG_LOCKDEP_SUPPORT=y
13CONFIG_STACKTRACE_SUPPORT=y
14CONFIG_SEMAPHORE_SLEEPERS=y
15CONFIG_X86=y
16CONFIG_MMU=y
17CONFIG_ZONE_DMA=y
18CONFIG_QUICKLIST=y
19CONFIG_GENERIC_ISA_DMA=y
20CONFIG_GENERIC_IOMAP=y
21CONFIG_GENERIC_BUG=y
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_ARCH_MAY_HAVE_PC_FDC=y
24CONFIG_DMI=y
25CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
26
27#
28# General setup
29#
30CONFIG_EXPERIMENTAL=y
31CONFIG_LOCK_KERNEL=y
32CONFIG_INIT_ENV_ARG_LIMIT=32
33CONFIG_LOCALVERSION=""
34# CONFIG_LOCALVERSION_AUTO is not set
35CONFIG_SWAP=y
36CONFIG_SYSVIPC=y
37CONFIG_SYSVIPC_SYSCTL=y
38CONFIG_POSIX_MQUEUE=y
39# CONFIG_BSD_PROCESS_ACCT is not set
40# CONFIG_TASKSTATS is not set
41# CONFIG_USER_NS is not set
42CONFIG_AUDIT=y
43CONFIG_AUDITSYSCALL=y
44# CONFIG_IKCONFIG is not set
45CONFIG_LOG_BUF_SHIFT=15
46# CONFIG_CPUSETS is not set
47# CONFIG_SYSFS_DEPRECATED is not set
48# CONFIG_RELAY is not set
49CONFIG_BLK_DEV_INITRD=y
50CONFIG_INITRAMFS_SOURCE=""
51# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
52CONFIG_SYSCTL=y
53CONFIG_EMBEDDED=y
54CONFIG_UID16=y
55CONFIG_SYSCTL_SYSCALL=y
56CONFIG_KALLSYMS=y
57# CONFIG_KALLSYMS_EXTRA_PASS is not set
58CONFIG_HOTPLUG=y
59CONFIG_PRINTK=y
60CONFIG_BUG=y
61CONFIG_ELF_CORE=y
62CONFIG_BASE_FULL=y
63CONFIG_FUTEX=y
64CONFIG_ANON_INODES=y
65CONFIG_EPOLL=y
66CONFIG_SIGNALFD=y
67CONFIG_EVENTFD=y
68CONFIG_SHMEM=y
69CONFIG_VM_EVENT_COUNTERS=y
70CONFIG_SLAB=y
71# CONFIG_SLUB is not set
72# CONFIG_SLOB is not set
73CONFIG_RT_MUTEXES=y
74# CONFIG_TINY_SHMEM is not set
75CONFIG_BASE_SMALL=0
76CONFIG_MODULES=y
77# CONFIG_MODULE_UNLOAD is not set
78# CONFIG_MODVERSIONS is not set
79# CONFIG_MODULE_SRCVERSION_ALL is not set
80CONFIG_KMOD=y
81CONFIG_STOP_MACHINE=y
82CONFIG_BLOCK=y
83# CONFIG_LBD is not set
84# CONFIG_BLK_DEV_IO_TRACE is not set
85# CONFIG_LSF is not set
86# CONFIG_BLK_DEV_BSG is not set
87
88#
89# IO Schedulers
90#
91CONFIG_IOSCHED_NOOP=y
92# CONFIG_IOSCHED_AS is not set
93# CONFIG_IOSCHED_DEADLINE is not set
94CONFIG_IOSCHED_CFQ=y
95# CONFIG_DEFAULT_AS is not set
96# CONFIG_DEFAULT_DEADLINE is not set
97CONFIG_DEFAULT_CFQ=y
98# CONFIG_DEFAULT_NOOP is not set
99CONFIG_DEFAULT_IOSCHED="cfq"
100
101#
102# Processor type and features
103#
104CONFIG_TICK_ONESHOT=y
105CONFIG_NO_HZ=y
106CONFIG_HIGH_RES_TIMERS=y
107CONFIG_SMP=y
108CONFIG_X86_PC=y
109# CONFIG_X86_ELAN is not set
110# CONFIG_X86_VOYAGER is not set
111# CONFIG_X86_NUMAQ is not set
112# CONFIG_X86_SUMMIT is not set
113# CONFIG_X86_BIGSMP is not set
114# CONFIG_X86_VISWS is not set
115# CONFIG_X86_GENERICARCH is not set
116# CONFIG_X86_ES7000 is not set
117# CONFIG_PARAVIRT is not set
118# CONFIG_M386 is not set
119# CONFIG_M486 is not set
120# CONFIG_M586 is not set
121# CONFIG_M586TSC is not set
122# CONFIG_M586MMX is not set
123# CONFIG_M686 is not set
124CONFIG_MPENTIUMII=y
125# CONFIG_MPENTIUMIII is not set
126# CONFIG_MPENTIUMM is not set
127# CONFIG_MCORE2 is not set
128# CONFIG_MPENTIUM4 is not set
129# CONFIG_MK6 is not set
130# CONFIG_MK7 is not set
131# CONFIG_MK8 is not set
132# CONFIG_MCRUSOE is not set
133# CONFIG_MEFFICEON is not set
134# CONFIG_MWINCHIPC6 is not set
135# CONFIG_MWINCHIP2 is not set
136# CONFIG_MWINCHIP3D is not set
137# CONFIG_MGEODEGX1 is not set
138# CONFIG_MGEODE_LX is not set
139# CONFIG_MCYRIXIII is not set
140# CONFIG_MVIAC3_2 is not set
141# CONFIG_MVIAC7 is not set
142CONFIG_X86_GENERIC=y
143CONFIG_X86_CMPXCHG=y
144CONFIG_X86_L1_CACHE_SHIFT=7
145CONFIG_X86_XADD=y
146CONFIG_RWSEM_XCHGADD_ALGORITHM=y
147# CONFIG_ARCH_HAS_ILOG2_U32 is not set
148# CONFIG_ARCH_HAS_ILOG2_U64 is not set
149CONFIG_GENERIC_CALIBRATE_DELAY=y
150CONFIG_X86_WP_WORKS_OK=y
151CONFIG_X86_INVLPG=y
152CONFIG_X86_BSWAP=y
153CONFIG_X86_POPAD_OK=y
154CONFIG_X86_GOOD_APIC=y
155CONFIG_X86_INTEL_USERCOPY=y
156CONFIG_X86_USE_PPRO_CHECKSUM=y
157CONFIG_X86_TSC=y
158CONFIG_X86_CMOV=y
159CONFIG_X86_MINIMUM_CPU_FAMILY=4
160CONFIG_HPET_TIMER=y
161CONFIG_NR_CPUS=8
162CONFIG_SCHED_SMT=y
163CONFIG_SCHED_MC=y
164CONFIG_PREEMPT_NONE=y
165# CONFIG_PREEMPT_VOLUNTARY is not set
166# CONFIG_PREEMPT is not set
167CONFIG_PREEMPT_BKL=y
168CONFIG_X86_LOCAL_APIC=y
169CONFIG_X86_IO_APIC=y
170CONFIG_X86_MCE=y
171CONFIG_X86_MCE_NONFATAL=y
172CONFIG_X86_MCE_P4THERMAL=y
173CONFIG_VM86=y
174# CONFIG_TOSHIBA is not set
175# CONFIG_I8K is not set
176# CONFIG_X86_REBOOTFIXUPS is not set
177# CONFIG_MICROCODE is not set
178# CONFIG_X86_MSR is not set
179# CONFIG_X86_CPUID is not set
180
181#
182# Firmware Drivers
183#
184# CONFIG_EDD is not set
185# CONFIG_DELL_RBU is not set
186# CONFIG_DCDBAS is not set
187CONFIG_DMIID=y
188CONFIG_NOHIGHMEM=y
189# CONFIG_HIGHMEM4G is not set
190# CONFIG_HIGHMEM64G is not set
191CONFIG_VMSPLIT_3G=y
192# CONFIG_VMSPLIT_3G_OPT is not set
193# CONFIG_VMSPLIT_2G is not set
194# CONFIG_VMSPLIT_2G_OPT is not set
195# CONFIG_VMSPLIT_1G is not set
196CONFIG_PAGE_OFFSET=0xC0000000
197# CONFIG_X86_PAE is not set
198CONFIG_ARCH_FLATMEM_ENABLE=y
199CONFIG_ARCH_SPARSEMEM_ENABLE=y
200CONFIG_ARCH_SELECT_MEMORY_MODEL=y
201CONFIG_ARCH_POPULATES_NODE_MAP=y
202CONFIG_SELECT_MEMORY_MODEL=y
203CONFIG_FLATMEM_MANUAL=y
204# CONFIG_DISCONTIGMEM_MANUAL is not set
205# CONFIG_SPARSEMEM_MANUAL is not set
206CONFIG_FLATMEM=y
207CONFIG_FLAT_NODE_MEM_MAP=y
208CONFIG_SPARSEMEM_STATIC=y
209CONFIG_SPLIT_PTLOCK_CPUS=4
210# CONFIG_RESOURCES_64BIT is not set
211CONFIG_ZONE_DMA_FLAG=1
212CONFIG_BOUNCE=y
213CONFIG_NR_QUICK=1
214CONFIG_VIRT_TO_BUS=y
215# CONFIG_MATH_EMULATION is not set
216CONFIG_MTRR=y
217# CONFIG_EFI is not set
218CONFIG_IRQBALANCE=y
219CONFIG_SECCOMP=y
220# CONFIG_HZ_100 is not set
221CONFIG_HZ_250=y
222# CONFIG_HZ_300 is not set
223# CONFIG_HZ_1000 is not set
224CONFIG_HZ=250
225CONFIG_KEXEC=y
226CONFIG_PHYSICAL_START=0x100000
227# CONFIG_RELOCATABLE is not set
228CONFIG_PHYSICAL_ALIGN=0x100000
229CONFIG_HOTPLUG_CPU=y
230# CONFIG_COMPAT_VDSO is not set
231
232#
233# Power management options (ACPI, APM)
234#
235CONFIG_PM=y
236CONFIG_PM_LEGACY=y
237# CONFIG_PM_DEBUG is not set
238CONFIG_PM_SLEEP_SMP=y
239CONFIG_PM_SLEEP=y
240CONFIG_SUSPEND_SMP_POSSIBLE=y
241CONFIG_SUSPEND=y
242CONFIG_HIBERNATION_SMP_POSSIBLE=y
243# CONFIG_HIBERNATION is not set
244CONFIG_ACPI=y
245CONFIG_ACPI_SLEEP=y
246CONFIG_ACPI_PROCFS=y
247CONFIG_ACPI_PROC_EVENT=y
248CONFIG_ACPI_AC=y
249CONFIG_ACPI_BATTERY=y
250CONFIG_ACPI_BUTTON=y
251CONFIG_ACPI_FAN=y
252# CONFIG_ACPI_DOCK is not set
253CONFIG_ACPI_PROCESSOR=y
254CONFIG_ACPI_HOTPLUG_CPU=y
255CONFIG_ACPI_THERMAL=y
256# CONFIG_ACPI_ASUS is not set
257# CONFIG_ACPI_TOSHIBA is not set
258CONFIG_ACPI_BLACKLIST_YEAR=0
259# CONFIG_ACPI_DEBUG is not set
260CONFIG_ACPI_EC=y
261CONFIG_ACPI_POWER=y
262CONFIG_ACPI_SYSTEM=y
263CONFIG_X86_PM_TIMER=y
264CONFIG_ACPI_CONTAINER=y
265# CONFIG_ACPI_SBS is not set
266# CONFIG_APM is not set
267
268#
269# CPU Frequency scaling
270#
271# CONFIG_CPU_FREQ is not set
272
273#
274# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
275#
276CONFIG_PCI=y
277# CONFIG_PCI_GOBIOS is not set
278# CONFIG_PCI_GOMMCONFIG is not set
279# CONFIG_PCI_GODIRECT is not set
280CONFIG_PCI_GOANY=y
281CONFIG_PCI_BIOS=y
282CONFIG_PCI_DIRECT=y
283CONFIG_PCI_MMCONFIG=y
284CONFIG_PCIEPORTBUS=y
285CONFIG_PCIEAER=y
286CONFIG_ARCH_SUPPORTS_MSI=y
287CONFIG_PCI_MSI=y
288CONFIG_HT_IRQ=y
289CONFIG_ISA_DMA_API=y
290CONFIG_ISA=y
291# CONFIG_EISA is not set
292# CONFIG_MCA is not set
293# CONFIG_SCx200 is not set
294CONFIG_K8_NB=y
295
296#
297# PCCARD (PCMCIA/CardBus) support
298#
299# CONFIG_PCCARD is not set
300# CONFIG_HOTPLUG_PCI is not set
301
302#
303# Executable file formats
304#
305CONFIG_BINFMT_ELF=y
306# CONFIG_BINFMT_AOUT is not set
307# CONFIG_BINFMT_MISC is not set
308
309#
310# Networking
311#
312CONFIG_NET=y
313
314#
315# Networking options
316#
317CONFIG_PACKET=m
318# CONFIG_PACKET_MMAP is not set
319CONFIG_UNIX=y
320# CONFIG_NET_KEY is not set
321CONFIG_INET=y
322CONFIG_IP_MULTICAST=y
323# CONFIG_IP_ADVANCED_ROUTER is not set
324CONFIG_IP_FIB_HASH=y
325CONFIG_IP_PNP=y
326CONFIG_IP_PNP_DHCP=y
327CONFIG_IP_PNP_BOOTP=y
328# CONFIG_IP_PNP_RARP is not set
329# CONFIG_NET_IPIP is not set
330# CONFIG_NET_IPGRE is not set
331# CONFIG_IP_MROUTE is not set
332# CONFIG_ARPD is not set
333# CONFIG_SYN_COOKIES is not set
334# CONFIG_INET_AH is not set
335# CONFIG_INET_ESP is not set
336# CONFIG_INET_IPCOMP is not set
337# CONFIG_INET_XFRM_TUNNEL is not set
338# CONFIG_INET_TUNNEL is not set
339# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
340# CONFIG_INET_XFRM_MODE_TUNNEL is not set
341# CONFIG_INET_XFRM_MODE_BEET is not set
342CONFIG_INET_DIAG=y
343CONFIG_INET_TCP_DIAG=y
344# CONFIG_TCP_CONG_ADVANCED is not set
345CONFIG_TCP_CONG_CUBIC=y
346CONFIG_DEFAULT_TCP_CONG="cubic"
347# CONFIG_TCP_MD5SIG is not set
348# CONFIG_IP_VS is not set
349# CONFIG_IPV6 is not set
350# CONFIG_INET6_XFRM_TUNNEL is not set
351# CONFIG_INET6_TUNNEL is not set
352# CONFIG_NETWORK_SECMARK is not set
353CONFIG_NETFILTER=y
354# CONFIG_NETFILTER_DEBUG is not set
355
356#
357# Core Netfilter Configuration
358#
359# CONFIG_NETFILTER_NETLINK is not set
360# CONFIG_NF_CONNTRACK_ENABLED is not set
361# CONFIG_NF_CONNTRACK is not set
362CONFIG_NETFILTER_XTABLES=m
363# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
364# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
365# CONFIG_NETFILTER_XT_TARGET_MARK is not set
366# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
367# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
368# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
369# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
370# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
371# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
372# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
373# CONFIG_NETFILTER_XT_MATCH_ESP is not set
374# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
375# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
376# CONFIG_NETFILTER_XT_MATCH_MAC is not set
377# CONFIG_NETFILTER_XT_MATCH_MARK is not set
378# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
379# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
380# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
381# CONFIG_NETFILTER_XT_MATCH_REALM is not set
382# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
383# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
384# CONFIG_NETFILTER_XT_MATCH_STRING is not set
385# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
386# CONFIG_NETFILTER_XT_MATCH_U32 is not set
387# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
388
389#
390# IP: Netfilter Configuration
391#
392CONFIG_IP_NF_QUEUE=m
393CONFIG_IP_NF_IPTABLES=m
394CONFIG_IP_NF_MATCH_IPRANGE=m
395CONFIG_IP_NF_MATCH_TOS=m
396CONFIG_IP_NF_MATCH_RECENT=m
397CONFIG_IP_NF_MATCH_ECN=m
398CONFIG_IP_NF_MATCH_AH=m
399CONFIG_IP_NF_MATCH_TTL=m
400CONFIG_IP_NF_MATCH_OWNER=m
401CONFIG_IP_NF_MATCH_ADDRTYPE=m
402CONFIG_IP_NF_FILTER=m
403CONFIG_IP_NF_TARGET_REJECT=m
404CONFIG_IP_NF_TARGET_LOG=m
405CONFIG_IP_NF_TARGET_ULOG=m
406CONFIG_IP_NF_MANGLE=m
407CONFIG_IP_NF_TARGET_TOS=m
408CONFIG_IP_NF_TARGET_ECN=m
409CONFIG_IP_NF_TARGET_TTL=m
410CONFIG_IP_NF_RAW=m
411CONFIG_IP_NF_ARPTABLES=m
412CONFIG_IP_NF_ARPFILTER=m
413CONFIG_IP_NF_ARP_MANGLE=m
414# CONFIG_IP_DCCP is not set
415# CONFIG_IP_SCTP is not set
416# CONFIG_TIPC is not set
417# CONFIG_ATM is not set
418# CONFIG_BRIDGE is not set
419# CONFIG_VLAN_8021Q is not set
420# CONFIG_DECNET is not set
421# CONFIG_LLC2 is not set
422# CONFIG_IPX is not set
423# CONFIG_ATALK is not set
424# CONFIG_X25 is not set
425# CONFIG_LAPB is not set
426# CONFIG_ECONET is not set
427# CONFIG_WAN_ROUTER is not set
428
429#
430# QoS and/or fair queueing
431#
432# CONFIG_NET_SCHED is not set
433
434#
435# Network testing
436#
437# CONFIG_NET_PKTGEN is not set
438# CONFIG_HAMRADIO is not set
439# CONFIG_IRDA is not set
440# CONFIG_BT is not set
441# CONFIG_AF_RXRPC is not set
442
443#
444# Wireless
445#
446# CONFIG_CFG80211 is not set
447# CONFIG_WIRELESS_EXT is not set
448# CONFIG_MAC80211 is not set
449# CONFIG_IEEE80211 is not set
450# CONFIG_RFKILL is not set
451# CONFIG_NET_9P is not set
452
453#
454# Device Drivers
455#
456
457#
458# Generic Driver Options
459#
460CONFIG_STANDALONE=y
461CONFIG_PREVENT_FIRMWARE_BUILD=y
462CONFIG_FW_LOADER=m
463# CONFIG_SYS_HYPERVISOR is not set
464CONFIG_CONNECTOR=y
465CONFIG_PROC_EVENTS=y
466# CONFIG_MTD is not set
467# CONFIG_PARPORT is not set
468CONFIG_PNP=y
469# CONFIG_PNP_DEBUG is not set
470
471#
472# Protocols
473#
474# CONFIG_ISAPNP is not set
475# CONFIG_PNPBIOS is not set
476CONFIG_PNPACPI=y
477CONFIG_BLK_DEV=y
478# CONFIG_BLK_DEV_FD is not set
479# CONFIG_BLK_DEV_XD is not set
480# CONFIG_BLK_CPQ_DA is not set
481# CONFIG_BLK_CPQ_CISS_DA is not set
482# CONFIG_BLK_DEV_DAC960 is not set
483# CONFIG_BLK_DEV_UMEM is not set
484# CONFIG_BLK_DEV_COW_COMMON is not set
485# CONFIG_BLK_DEV_LOOP is not set
486# CONFIG_BLK_DEV_NBD is not set
487# CONFIG_BLK_DEV_SX8 is not set
488# CONFIG_BLK_DEV_UB is not set
489CONFIG_BLK_DEV_RAM=y
490CONFIG_BLK_DEV_RAM_COUNT=1
491CONFIG_BLK_DEV_RAM_SIZE=81920
492CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
493# CONFIG_CDROM_PKTCDVD is not set
494# CONFIG_ATA_OVER_ETH is not set
495CONFIG_MISC_DEVICES=y
496# CONFIG_IBM_ASM is not set
497# CONFIG_PHANTOM is not set
498# CONFIG_EEPROM_93CX6 is not set
499# CONFIG_SGI_IOC4 is not set
500# CONFIG_TIFM_CORE is not set
501# CONFIG_SONY_LAPTOP is not set
502# CONFIG_THINKPAD_ACPI is not set
503# CONFIG_IDE is not set
504
505#
506# SCSI device support
507#
508# CONFIG_RAID_ATTRS is not set
509CONFIG_SCSI=y
510CONFIG_SCSI_DMA=y
511# CONFIG_SCSI_TGT is not set
512# CONFIG_SCSI_NETLINK is not set
513CONFIG_SCSI_PROC_FS=y
514
515#
516# SCSI support type (disk, tape, CD-ROM)
517#
518CONFIG_BLK_DEV_SD=y
519# CONFIG_CHR_DEV_ST is not set
520# CONFIG_CHR_DEV_OSST is not set
521# CONFIG_BLK_DEV_SR is not set
522CONFIG_CHR_DEV_SG=y
523# CONFIG_CHR_DEV_SCH is not set
524
525#
526# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
527#
528CONFIG_SCSI_MULTI_LUN=y
529# CONFIG_SCSI_CONSTANTS is not set
530# CONFIG_SCSI_LOGGING is not set
531# CONFIG_SCSI_SCAN_ASYNC is not set
532CONFIG_SCSI_WAIT_SCAN=m
533
534#
535# SCSI Transports
536#
537# CONFIG_SCSI_SPI_ATTRS is not set
538# CONFIG_SCSI_FC_ATTRS is not set
539# CONFIG_SCSI_ISCSI_ATTRS is not set
540# CONFIG_SCSI_SAS_LIBSAS is not set
541CONFIG_SCSI_LOWLEVEL=y
542# CONFIG_ISCSI_TCP is not set
543# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
544# CONFIG_SCSI_3W_9XXX is not set
545# CONFIG_SCSI_7000FASST is not set
546# CONFIG_SCSI_ACARD is not set
547# CONFIG_SCSI_AHA152X is not set
548# CONFIG_SCSI_AHA1542 is not set
549# CONFIG_SCSI_AACRAID is not set
550# CONFIG_SCSI_AIC7XXX is not set
551# CONFIG_SCSI_AIC7XXX_OLD is not set
552# CONFIG_SCSI_AIC79XX is not set
553# CONFIG_SCSI_AIC94XX is not set
554# CONFIG_SCSI_DPT_I2O is not set
555# CONFIG_SCSI_ADVANSYS is not set
556# CONFIG_SCSI_IN2000 is not set
557# CONFIG_SCSI_ARCMSR is not set
558# CONFIG_MEGARAID_NEWGEN is not set
559# CONFIG_MEGARAID_LEGACY is not set
560# CONFIG_MEGARAID_SAS is not set
561# CONFIG_SCSI_HPTIOP is not set
562# CONFIG_SCSI_BUSLOGIC is not set
563# CONFIG_SCSI_DMX3191D is not set
564# CONFIG_SCSI_DTC3280 is not set
565# CONFIG_SCSI_EATA is not set
566# CONFIG_SCSI_FUTURE_DOMAIN is not set
567# CONFIG_SCSI_GDTH is not set
568# CONFIG_SCSI_GENERIC_NCR5380 is not set
569# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
570# CONFIG_SCSI_IPS is not set
571# CONFIG_SCSI_INITIO is not set
572# CONFIG_SCSI_INIA100 is not set
573# CONFIG_SCSI_NCR53C406A is not set
574# CONFIG_SCSI_STEX is not set
575# CONFIG_SCSI_SYM53C8XX_2 is not set
576# CONFIG_SCSI_PAS16 is not set
577# CONFIG_SCSI_PSI240I is not set
578# CONFIG_SCSI_QLOGIC_FAS is not set
579# CONFIG_SCSI_QLOGIC_1280 is not set
580# CONFIG_SCSI_QLA_FC is not set
581# CONFIG_SCSI_QLA_ISCSI is not set
582# CONFIG_SCSI_LPFC is not set
583# CONFIG_SCSI_SEAGATE is not set
584# CONFIG_SCSI_SYM53C416 is not set
585# CONFIG_SCSI_DC395x is not set
586# CONFIG_SCSI_DC390T is not set
587# CONFIG_SCSI_T128 is not set
588# CONFIG_SCSI_U14_34F is not set
589# CONFIG_SCSI_ULTRASTOR is not set
590# CONFIG_SCSI_NSP32 is not set
591# CONFIG_SCSI_DEBUG is not set
592# CONFIG_SCSI_SRP is not set
593# CONFIG_ATA is not set
594# CONFIG_MD is not set
595
596#
597# Fusion MPT device support
598#
599# CONFIG_FUSION is not set
600# CONFIG_FUSION_SPI is not set
601# CONFIG_FUSION_FC is not set
602# CONFIG_FUSION_SAS is not set
603
604#
605# IEEE 1394 (FireWire) support
606#
607# CONFIG_FIREWIRE is not set
608# CONFIG_IEEE1394 is not set
609# CONFIG_I2O is not set
610# CONFIG_MACINTOSH_DRIVERS is not set
611CONFIG_NETDEVICES=y
612# CONFIG_NETDEVICES_MULTIQUEUE is not set
613# CONFIG_DUMMY is not set
614# CONFIG_BONDING is not set
615# CONFIG_MACVLAN is not set
616# CONFIG_EQUALIZER is not set
617# CONFIG_TUN is not set
618# CONFIG_NET_SB1000 is not set
619# CONFIG_ARCNET is not set
620# CONFIG_PHYLIB is not set
621CONFIG_NET_ETHERNET=y
622CONFIG_MII=y
623# CONFIG_HAPPYMEAL is not set
624# CONFIG_SUNGEM is not set
625# CONFIG_CASSINI is not set
626CONFIG_NET_VENDOR_3COM=y
627# CONFIG_EL1 is not set
628# CONFIG_EL2 is not set
629# CONFIG_ELPLUS is not set
630# CONFIG_EL16 is not set
631# CONFIG_EL3 is not set
632# CONFIG_3C515 is not set
633CONFIG_VORTEX=m
634CONFIG_TYPHOON=m
635CONFIG_LANCE=m
636CONFIG_NET_VENDOR_SMC=y
637CONFIG_WD80x3=m
638CONFIG_ULTRA=m
639CONFIG_SMC9194=m
640# CONFIG_NET_VENDOR_RACAL is not set
641CONFIG_NET_TULIP=y
642# CONFIG_DE2104X is not set
643CONFIG_TULIP=m
644CONFIG_TULIP_MWI=y
645CONFIG_TULIP_MMIO=y
646CONFIG_TULIP_NAPI=y
647CONFIG_TULIP_NAPI_HW_MITIGATION=y
648CONFIG_DE4X5=m
649CONFIG_WINBOND_840=m
650CONFIG_DM9102=m
651CONFIG_ULI526X=m
652CONFIG_AT1700=m
653CONFIG_DEPCA=m
654CONFIG_HP100=m
655CONFIG_NET_ISA=y
656# CONFIG_E2100 is not set
657# CONFIG_EWRK3 is not set
658# CONFIG_EEXPRESS is not set
659# CONFIG_EEXPRESS_PRO is not set
660# CONFIG_HPLAN_PLUS is not set
661# CONFIG_HPLAN is not set
662# CONFIG_LP486E is not set
663# CONFIG_ETH16I is not set
664CONFIG_NE2000=y
665# CONFIG_ZNET is not set
666# CONFIG_SEEQ8005 is not set
667CONFIG_NET_PCI=y
668CONFIG_PCNET32=m
669CONFIG_PCNET32_NAPI=y
670CONFIG_AMD8111_ETH=m
671CONFIG_AMD8111E_NAPI=y
672CONFIG_ADAPTEC_STARFIRE=m
673CONFIG_ADAPTEC_STARFIRE_NAPI=y
674CONFIG_AC3200=m
675CONFIG_APRICOT=m
676CONFIG_B44=m
677CONFIG_FORCEDETH=m
678CONFIG_FORCEDETH_NAPI=y
679CONFIG_CS89x0=m
680CONFIG_DGRS=m
681CONFIG_EEPRO100=m
682CONFIG_E100=m
683CONFIG_FEALNX=m
684CONFIG_NATSEMI=m
685CONFIG_NE2K_PCI=y
686CONFIG_8139CP=m
687CONFIG_8139TOO=m
688CONFIG_8139TOO_PIO=y
689CONFIG_8139TOO_TUNE_TWISTER=y
690CONFIG_8139TOO_8129=y
691# CONFIG_8139_OLD_RX_RESET is not set
692CONFIG_SIS900=m
693CONFIG_EPIC100=m
694CONFIG_SUNDANCE=m
695CONFIG_SUNDANCE_MMIO=y
696CONFIG_TLAN=m
697CONFIG_VIA_RHINE=m
698CONFIG_VIA_RHINE_MMIO=y
699CONFIG_VIA_RHINE_NAPI=y
700CONFIG_SC92031=m
701CONFIG_NETDEV_1000=y
702CONFIG_ACENIC=m
703CONFIG_ACENIC_OMIT_TIGON_I=y
704CONFIG_DL2K=m
705CONFIG_E1000=m
706CONFIG_E1000_NAPI=y
707# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
708CONFIG_NS83820=m
709CONFIG_HAMACHI=m
710CONFIG_YELLOWFIN=m
711CONFIG_R8169=m
712CONFIG_R8169_NAPI=y
713CONFIG_SIS190=m
714CONFIG_SKGE=m
715CONFIG_SKY2=m
716CONFIG_SK98LIN=m
717CONFIG_VIA_VELOCITY=m
718CONFIG_TIGON3=m
719CONFIG_BNX2=m
720CONFIG_QLA3XXX=m
721CONFIG_ATL1=m
722CONFIG_NETDEV_10000=y
723# CONFIG_CHELSIO_T1 is not set
724# CONFIG_CHELSIO_T3 is not set
725# CONFIG_IXGB is not set
726# CONFIG_S2IO is not set
727# CONFIG_MYRI10GE is not set
728# CONFIG_NETXEN_NIC is not set
729# CONFIG_MLX4_CORE is not set
730# CONFIG_TR is not set
731
732#
733# Wireless LAN
734#
735# CONFIG_WLAN_PRE80211 is not set
736# CONFIG_WLAN_80211 is not set
737
738#
739# USB Network Adapters
740#
741# CONFIG_USB_CATC is not set
742# CONFIG_USB_KAWETH is not set
743# CONFIG_USB_PEGASUS is not set
744# CONFIG_USB_RTL8150 is not set
745# CONFIG_USB_USBNET_MII is not set
746# CONFIG_USB_USBNET is not set
747# CONFIG_WAN is not set
748# CONFIG_FDDI is not set
749# CONFIG_HIPPI is not set
750# CONFIG_PPP is not set
751# CONFIG_SLIP is not set
752# CONFIG_NET_FC is not set
753# CONFIG_SHAPER is not set
754# CONFIG_NETCONSOLE is not set
755# CONFIG_NETPOLL is not set
756# CONFIG_NET_POLL_CONTROLLER is not set
757# CONFIG_ISDN is not set
758# CONFIG_PHONE is not set
759
760#
761# Input device support
762#
763CONFIG_INPUT=y
764# CONFIG_INPUT_FF_MEMLESS is not set
765# CONFIG_INPUT_POLLDEV is not set
766
767#
768# Userland interfaces
769#
770CONFIG_INPUT_MOUSEDEV=m
771# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
772CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
773CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
774# CONFIG_INPUT_JOYDEV is not set
775# CONFIG_INPUT_TSDEV is not set
776CONFIG_INPUT_EVDEV=y
777# CONFIG_INPUT_EVBUG is not set
778# CONFIG_INPUT_POWER is not set
779
780#
781# Input Device Drivers
782#
783CONFIG_INPUT_KEYBOARD=y
784CONFIG_KEYBOARD_ATKBD=y
785# CONFIG_KEYBOARD_SUNKBD is not set
786# CONFIG_KEYBOARD_LKKBD is not set
787# CONFIG_KEYBOARD_XTKBD is not set
788# CONFIG_KEYBOARD_NEWTON is not set
789# CONFIG_KEYBOARD_STOWAWAY is not set
790CONFIG_INPUT_MOUSE=y
791CONFIG_MOUSE_PS2=y
792CONFIG_MOUSE_PS2_ALPS=y
793CONFIG_MOUSE_PS2_LOGIPS2PP=y
794CONFIG_MOUSE_PS2_SYNAPTICS=y
795CONFIG_MOUSE_PS2_LIFEBOOK=y
796CONFIG_MOUSE_PS2_TRACKPOINT=y
797# CONFIG_MOUSE_PS2_TOUCHKIT is not set
798# CONFIG_MOUSE_SERIAL is not set
799# CONFIG_MOUSE_APPLETOUCH is not set
800# CONFIG_MOUSE_INPORT is not set
801# CONFIG_MOUSE_LOGIBM is not set
802# CONFIG_MOUSE_PC110PAD is not set
803# CONFIG_MOUSE_VSXXXAA is not set
804# CONFIG_INPUT_JOYSTICK is not set
805# CONFIG_INPUT_TABLET is not set
806# CONFIG_INPUT_TOUCHSCREEN is not set
807# CONFIG_INPUT_MISC is not set
808
809#
810# Hardware I/O ports
811#
812CONFIG_SERIO=y
813CONFIG_SERIO_I8042=y
814# CONFIG_SERIO_SERPORT is not set
815# CONFIG_SERIO_CT82C710 is not set
816# CONFIG_SERIO_PCIPS2 is not set
817CONFIG_SERIO_LIBPS2=y
818# CONFIG_SERIO_RAW is not set
819# CONFIG_GAMEPORT is not set
820
821#
822# Character devices
823#
824CONFIG_VT=y
825CONFIG_VT_CONSOLE=y
826CONFIG_HW_CONSOLE=y
827# CONFIG_VT_HW_CONSOLE_BINDING is not set
828# CONFIG_SERIAL_NONSTANDARD is not set
829
830#
831# Serial drivers
832#
833CONFIG_SERIAL_8250=y
834# CONFIG_SERIAL_8250_CONSOLE is not set
835CONFIG_FIX_EARLYCON_MEM=y
836CONFIG_SERIAL_8250_PCI=y
837CONFIG_SERIAL_8250_PNP=y
838CONFIG_SERIAL_8250_NR_UARTS=4
839CONFIG_SERIAL_8250_RUNTIME_UARTS=4
840# CONFIG_SERIAL_8250_EXTENDED is not set
841
842#
843# Non-8250 serial port support
844#
845CONFIG_SERIAL_CORE=y
846# CONFIG_SERIAL_JSM is not set
847CONFIG_UNIX98_PTYS=y
848# CONFIG_LEGACY_PTYS is not set
849# CONFIG_IPMI_HANDLER is not set
850# CONFIG_WATCHDOG is not set
851# CONFIG_HW_RANDOM is not set
852# CONFIG_NVRAM is not set
853# CONFIG_RTC is not set
854# CONFIG_GEN_RTC is not set
855# CONFIG_DTLK is not set
856# CONFIG_R3964 is not set
857# CONFIG_APPLICOM is not set
858# CONFIG_SONYPI is not set
859CONFIG_AGP=m
860CONFIG_AGP_ALI=m
861CONFIG_AGP_ATI=m
862CONFIG_AGP_AMD=m
863CONFIG_AGP_AMD64=m
864CONFIG_AGP_INTEL=m
865CONFIG_AGP_NVIDIA=m
866CONFIG_AGP_SIS=m
867CONFIG_AGP_SWORKS=m
868CONFIG_AGP_VIA=m
869CONFIG_AGP_EFFICEON=m
870# CONFIG_DRM is not set
871# CONFIG_MWAVE is not set
872# CONFIG_PC8736x_GPIO is not set
873# CONFIG_NSC_GPIO is not set
874# CONFIG_CS5535_GPIO is not set
875# CONFIG_RAW_DRIVER is not set
876# CONFIG_HPET is not set
877# CONFIG_HANGCHECK_TIMER is not set
878# CONFIG_TCG_TPM is not set
879# CONFIG_TELCLOCK is not set
880CONFIG_DEVPORT=y
881# CONFIG_I2C is not set
882
883#
884# SPI support
885#
886# CONFIG_SPI is not set
887# CONFIG_SPI_MASTER is not set
888# CONFIG_W1 is not set
889# CONFIG_POWER_SUPPLY is not set
890# CONFIG_HWMON is not set
891
892#
893# Multifunction device drivers
894#
895# CONFIG_MFD_SM501 is not set
896# CONFIG_HTC_ASIC3 is not set
897# CONFIG_HTC_ASIC3_DS1WM is not set
898
899#
900# Multi-Function Devices
901#
902
903#
904# Multimedia devices
905#
906CONFIG_VIDEO_DEV=m
907CONFIG_VIDEO_V4L1=y
908CONFIG_VIDEO_V4L1_COMPAT=y
909CONFIG_VIDEO_V4L2=y
910CONFIG_VIDEO_CAPTURE_DRIVERS=y
911# CONFIG_VIDEO_ADV_DEBUG is not set
912CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
913# CONFIG_VIDEO_VIVI is not set
914# CONFIG_VIDEO_PMS is not set
915# CONFIG_VIDEO_CPIA is not set
916# CONFIG_VIDEO_CPIA2 is not set
917# CONFIG_VIDEO_STRADIS is not set
918CONFIG_V4L_USB_DRIVERS=y
919# CONFIG_USB_VICAM is not set
920# CONFIG_USB_IBMCAM is not set
921# CONFIG_USB_KONICAWC is not set
922# CONFIG_USB_QUICKCAM_MESSENGER is not set
923# CONFIG_USB_ET61X251 is not set
924# CONFIG_USB_OV511 is not set
925# CONFIG_USB_SE401 is not set
926# CONFIG_USB_SN9C102 is not set
927# CONFIG_USB_STV680 is not set
928# CONFIG_USB_ZC0301 is not set
929# CONFIG_USB_PWC is not set
930# CONFIG_USB_ZR364XX is not set
931CONFIG_RADIO_ADAPTERS=y
932# CONFIG_RADIO_CADET is not set
933# CONFIG_RADIO_RTRACK is not set
934# CONFIG_RADIO_RTRACK2 is not set
935# CONFIG_RADIO_AZTECH is not set
936# CONFIG_RADIO_GEMTEK is not set
937# CONFIG_RADIO_GEMTEK_PCI is not set
938# CONFIG_RADIO_MAXIRADIO is not set
939# CONFIG_RADIO_MAESTRO is not set
940# CONFIG_RADIO_SF16FMI is not set
941# CONFIG_RADIO_SF16FMR2 is not set
942# CONFIG_RADIO_TERRATEC is not set
943# CONFIG_RADIO_TRUST is not set
944# CONFIG_RADIO_TYPHOON is not set
945# CONFIG_RADIO_ZOLTRIX is not set
946# CONFIG_USB_DSBR is not set
947# CONFIG_DVB_CORE is not set
948CONFIG_DAB=y
949# CONFIG_USB_DABUSB is not set
950
951#
952# Graphics support
953#
954# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
955
956#
957# Display device support
958#
959# CONFIG_DISPLAY_SUPPORT is not set
960CONFIG_VGASTATE=y
961CONFIG_VIDEO_OUTPUT_CONTROL=m
962CONFIG_FB=y
963CONFIG_FIRMWARE_EDID=y
964# CONFIG_FB_DDC is not set
965CONFIG_FB_CFB_FILLRECT=y
966CONFIG_FB_CFB_COPYAREA=y
967CONFIG_FB_CFB_IMAGEBLIT=y
968# CONFIG_FB_SYS_FILLRECT is not set
969# CONFIG_FB_SYS_COPYAREA is not set
970# CONFIG_FB_SYS_IMAGEBLIT is not set
971# CONFIG_FB_SYS_FOPS is not set
972CONFIG_FB_DEFERRED_IO=y
973# CONFIG_FB_SVGALIB is not set
974# CONFIG_FB_MACMODES is not set
975# CONFIG_FB_BACKLIGHT is not set
976CONFIG_FB_MODE_HELPERS=y
977CONFIG_FB_TILEBLITTING=y
978
979#
980# Frame buffer hardware drivers
981#
982# CONFIG_FB_CIRRUS is not set
983# CONFIG_FB_PM2 is not set
984# CONFIG_FB_CYBER2000 is not set
985# CONFIG_FB_ARC is not set
986# CONFIG_FB_ASILIANT is not set
987# CONFIG_FB_IMSTT is not set
988# CONFIG_FB_VGA16 is not set
989CONFIG_FB_UVESA=m
990# CONFIG_FB_VESA is not set
991# CONFIG_FB_HECUBA is not set
992# CONFIG_FB_HGA is not set
993# CONFIG_FB_S1D13XXX is not set
994# CONFIG_FB_NVIDIA is not set
995# CONFIG_FB_RIVA is not set
996# CONFIG_FB_I810 is not set
997# CONFIG_FB_LE80578 is not set
998# CONFIG_FB_INTEL is not set
999# CONFIG_FB_MATROX is not set
1000# CONFIG_FB_RADEON is not set
1001# CONFIG_FB_ATY128 is not set
1002# CONFIG_FB_ATY is not set
1003# CONFIG_FB_S3 is not set
1004# CONFIG_FB_SAVAGE is not set
1005# CONFIG_FB_SIS is not set
1006# CONFIG_FB_NEOMAGIC is not set
1007# CONFIG_FB_KYRO is not set
1008# CONFIG_FB_3DFX is not set
1009# CONFIG_FB_VOODOO1 is not set
1010# CONFIG_FB_VT8623 is not set
1011# CONFIG_FB_CYBLA is not set
1012# CONFIG_FB_TRIDENT is not set
1013# CONFIG_FB_ARK is not set
1014# CONFIG_FB_PM3 is not set
1015# CONFIG_FB_GEODE is not set
1016# CONFIG_FB_VIRTUAL is not set
1017
1018#
1019# Console display driver support
1020#
1021CONFIG_VGA_CONSOLE=y
1022# CONFIG_VGACON_SOFT_SCROLLBACK is not set
1023CONFIG_VIDEO_SELECT=y
1024# CONFIG_MDA_CONSOLE is not set
1025CONFIG_DUMMY_CONSOLE=y
1026CONFIG_FRAMEBUFFER_CONSOLE=y
1027# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1028# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1029CONFIG_FONTS=y
1030CONFIG_FONT_8x8=y
1031CONFIG_FONT_8x16=y
1032# CONFIG_FONT_6x11 is not set
1033# CONFIG_FONT_7x14 is not set
1034# CONFIG_FONT_PEARL_8x8 is not set
1035# CONFIG_FONT_ACORN_8x8 is not set
1036# CONFIG_FONT_MINI_4x6 is not set
1037# CONFIG_FONT_SUN8x16 is not set
1038# CONFIG_FONT_SUN12x22 is not set
1039# CONFIG_FONT_10x18 is not set
1040CONFIG_LOGO=y
1041# CONFIG_LOGO_LINUX_MONO is not set
1042# CONFIG_LOGO_LINUX_VGA16 is not set
1043# CONFIG_LOGO_LINUX_CLUT224 is not set
1044CONFIG_LOGO_OHAND_CLUT224=y
1045
1046#
1047# Sound
1048#
1049CONFIG_SOUND=y
1050
1051#
1052# Advanced Linux Sound Architecture
1053#
1054CONFIG_SND=y
1055CONFIG_SND_TIMER=y
1056CONFIG_SND_PCM=y
1057CONFIG_SND_SEQUENCER=y
1058# CONFIG_SND_SEQ_DUMMY is not set
1059CONFIG_SND_OSSEMUL=y
1060CONFIG_SND_MIXER_OSS=y
1061CONFIG_SND_PCM_OSS=y
1062CONFIG_SND_PCM_OSS_PLUGINS=y
1063CONFIG_SND_SEQUENCER_OSS=y
1064# CONFIG_SND_DYNAMIC_MINORS is not set
1065CONFIG_SND_SUPPORT_OLD_API=y
1066CONFIG_SND_VERBOSE_PROCFS=y
1067# CONFIG_SND_VERBOSE_PRINTK is not set
1068# CONFIG_SND_DEBUG is not set
1069
1070#
1071# Generic devices
1072#
1073CONFIG_SND_AC97_CODEC=y
1074# CONFIG_SND_DUMMY is not set
1075# CONFIG_SND_VIRMIDI is not set
1076# CONFIG_SND_MTPAV is not set
1077# CONFIG_SND_SERIAL_U16550 is not set
1078# CONFIG_SND_MPU401 is not set
1079
1080#
1081# ISA devices
1082#
1083# CONFIG_SND_ADLIB is not set
1084# CONFIG_SND_AD1816A is not set
1085# CONFIG_SND_AD1848 is not set
1086# CONFIG_SND_ALS100 is not set
1087# CONFIG_SND_AZT2320 is not set
1088# CONFIG_SND_CMI8330 is not set
1089# CONFIG_SND_CS4231 is not set
1090# CONFIG_SND_CS4232 is not set
1091# CONFIG_SND_CS4236 is not set
1092# CONFIG_SND_DT019X is not set
1093# CONFIG_SND_ES968 is not set
1094# CONFIG_SND_ES1688 is not set
1095# CONFIG_SND_ES18XX is not set
1096# CONFIG_SND_GUSCLASSIC is not set
1097# CONFIG_SND_GUSEXTREME is not set
1098# CONFIG_SND_GUSMAX is not set
1099# CONFIG_SND_INTERWAVE is not set
1100# CONFIG_SND_INTERWAVE_STB is not set
1101# CONFIG_SND_OPL3SA2 is not set
1102# CONFIG_SND_OPTI92X_AD1848 is not set
1103# CONFIG_SND_OPTI92X_CS4231 is not set
1104# CONFIG_SND_OPTI93X is not set
1105# CONFIG_SND_MIRO is not set
1106# CONFIG_SND_SB8 is not set
1107# CONFIG_SND_SB16 is not set
1108# CONFIG_SND_SBAWE is not set
1109# CONFIG_SND_SGALAXY is not set
1110# CONFIG_SND_SSCAPE is not set
1111# CONFIG_SND_WAVEFRONT is not set
1112
1113#
1114# PCI devices
1115#
1116# CONFIG_SND_AD1889 is not set
1117# CONFIG_SND_ALS300 is not set
1118# CONFIG_SND_ALS4000 is not set
1119# CONFIG_SND_ALI5451 is not set
1120# CONFIG_SND_ATIIXP is not set
1121# CONFIG_SND_ATIIXP_MODEM is not set
1122# CONFIG_SND_AU8810 is not set
1123# CONFIG_SND_AU8820 is not set
1124# CONFIG_SND_AU8830 is not set
1125# CONFIG_SND_AZT3328 is not set
1126# CONFIG_SND_BT87X is not set
1127# CONFIG_SND_CA0106 is not set
1128# CONFIG_SND_CMIPCI is not set
1129# CONFIG_SND_CS4281 is not set
1130# CONFIG_SND_CS46XX is not set
1131# CONFIG_SND_CS5530 is not set
1132# CONFIG_SND_CS5535AUDIO is not set
1133# CONFIG_SND_DARLA20 is not set
1134# CONFIG_SND_GINA20 is not set
1135# CONFIG_SND_LAYLA20 is not set
1136# CONFIG_SND_DARLA24 is not set
1137# CONFIG_SND_GINA24 is not set
1138# CONFIG_SND_LAYLA24 is not set
1139# CONFIG_SND_MONA is not set
1140# CONFIG_SND_MIA is not set
1141# CONFIG_SND_ECHO3G is not set
1142# CONFIG_SND_INDIGO is not set
1143# CONFIG_SND_INDIGOIO is not set
1144# CONFIG_SND_INDIGODJ is not set
1145# CONFIG_SND_EMU10K1 is not set
1146# CONFIG_SND_EMU10K1X is not set
1147# CONFIG_SND_ENS1370 is not set
1148# CONFIG_SND_ENS1371 is not set
1149# CONFIG_SND_ES1938 is not set
1150# CONFIG_SND_ES1968 is not set
1151# CONFIG_SND_FM801 is not set
1152# CONFIG_SND_HDA_INTEL is not set
1153# CONFIG_SND_HDSP is not set
1154# CONFIG_SND_HDSPM is not set
1155# CONFIG_SND_ICE1712 is not set
1156# CONFIG_SND_ICE1724 is not set
1157CONFIG_SND_INTEL8X0=y
1158# CONFIG_SND_INTEL8X0M is not set
1159# CONFIG_SND_KORG1212 is not set
1160# CONFIG_SND_MAESTRO3 is not set
1161# CONFIG_SND_MIXART is not set
1162# CONFIG_SND_NM256 is not set
1163# CONFIG_SND_PCXHR is not set
1164# CONFIG_SND_RIPTIDE is not set
1165# CONFIG_SND_RME32 is not set
1166# CONFIG_SND_RME96 is not set
1167# CONFIG_SND_RME9652 is not set
1168# CONFIG_SND_SONICVIBES is not set
1169# CONFIG_SND_TRIDENT is not set
1170# CONFIG_SND_VIA82XX is not set
1171# CONFIG_SND_VIA82XX_MODEM is not set
1172# CONFIG_SND_VX222 is not set
1173# CONFIG_SND_YMFPCI is not set
1174CONFIG_SND_AC97_POWER_SAVE=y
1175
1176#
1177# USB devices
1178#
1179# CONFIG_SND_USB_AUDIO is not set
1180# CONFIG_SND_USB_USX2Y is not set
1181# CONFIG_SND_USB_CAIAQ is not set
1182
1183#
1184# System on Chip audio support
1185#
1186# CONFIG_SND_SOC is not set
1187
1188#
1189# SoC Audio support for SuperH
1190#
1191
1192#
1193# Open Sound System
1194#
1195# CONFIG_SOUND_PRIME is not set
1196CONFIG_AC97_BUS=y
1197CONFIG_HID_SUPPORT=y
1198CONFIG_HID=y
1199# CONFIG_HID_DEBUG is not set
1200
1201#
1202# USB Input Devices
1203#
1204CONFIG_USB_HID=y
1205# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1206# CONFIG_HID_FF is not set
1207# CONFIG_USB_HIDDEV is not set
1208CONFIG_USB_SUPPORT=y
1209CONFIG_USB_ARCH_HAS_HCD=y
1210CONFIG_USB_ARCH_HAS_OHCI=y
1211CONFIG_USB_ARCH_HAS_EHCI=y
1212CONFIG_USB=y
1213# CONFIG_USB_DEBUG is not set
1214
1215#
1216# Miscellaneous USB options
1217#
1218CONFIG_USB_DEVICEFS=y
1219CONFIG_USB_DEVICE_CLASS=y
1220# CONFIG_USB_DYNAMIC_MINORS is not set
1221CONFIG_USB_SUSPEND=y
1222# CONFIG_USB_PERSIST is not set
1223# CONFIG_USB_OTG is not set
1224
1225#
1226# USB Host Controller Drivers
1227#
1228CONFIG_USB_EHCI_HCD=y
1229CONFIG_USB_EHCI_SPLIT_ISO=y
1230# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1231# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1232# CONFIG_USB_ISP116X_HCD is not set
1233CONFIG_USB_OHCI_HCD=y
1234# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1235# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1236CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1237CONFIG_USB_UHCI_HCD=y
1238# CONFIG_USB_SL811_HCD is not set
1239# CONFIG_USB_R8A66597_HCD is not set
1240
1241#
1242# USB Device Class drivers
1243#
1244# CONFIG_USB_ACM is not set
1245# CONFIG_USB_PRINTER is not set
1246
1247#
1248# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1249#
1250
1251#
1252# may also be needed; see USB_STORAGE Help for more information
1253#
1254# CONFIG_USB_STORAGE is not set
1255# CONFIG_USB_LIBUSUAL is not set
1256
1257#
1258# USB Imaging devices
1259#
1260# CONFIG_USB_MDC800 is not set
1261# CONFIG_USB_MICROTEK is not set
1262# CONFIG_USB_MON is not set
1263
1264#
1265# USB port drivers
1266#
1267
1268#
1269# USB Serial Converter support
1270#
1271# CONFIG_USB_SERIAL is not set
1272
1273#
1274# USB Miscellaneous drivers
1275#
1276# CONFIG_USB_EMI62 is not set
1277# CONFIG_USB_EMI26 is not set
1278# CONFIG_USB_ADUTUX is not set
1279# CONFIG_USB_AUERSWALD is not set
1280# CONFIG_USB_RIO500 is not set
1281# CONFIG_USB_LEGOTOWER is not set
1282# CONFIG_USB_LCD is not set
1283# CONFIG_USB_BERRY_CHARGE is not set
1284# CONFIG_USB_LED is not set
1285# CONFIG_USB_CYPRESS_CY7C63 is not set
1286# CONFIG_USB_CYTHERM is not set
1287# CONFIG_USB_PHIDGET is not set
1288# CONFIG_USB_IDMOUSE is not set
1289# CONFIG_USB_FTDI_ELAN is not set
1290# CONFIG_USB_APPLEDISPLAY is not set
1291# CONFIG_USB_SISUSBVGA is not set
1292# CONFIG_USB_LD is not set
1293# CONFIG_USB_TRANCEVIBRATOR is not set
1294# CONFIG_USB_IOWARRIOR is not set
1295# CONFIG_USB_TEST is not set
1296
1297#
1298# USB DSL modem support
1299#
1300
1301#
1302# USB Gadget Support
1303#
1304# CONFIG_USB_GADGET is not set
1305# CONFIG_MMC is not set
1306# CONFIG_NEW_LEDS is not set
1307# CONFIG_INFINIBAND is not set
1308# CONFIG_EDAC is not set
1309# CONFIG_RTC_CLASS is not set
1310
1311#
1312# DMA Engine support
1313#
1314# CONFIG_DMA_ENGINE is not set
1315
1316#
1317# DMA Clients
1318#
1319
1320#
1321# DMA Devices
1322#
1323CONFIG_VIRTUALIZATION=y
1324# CONFIG_KVM is not set
1325
1326#
1327# Userspace I/O
1328#
1329# CONFIG_UIO is not set
1330
1331#
1332# File systems
1333#
1334CONFIG_EXT2_FS=y
1335# CONFIG_EXT2_FS_XATTR is not set
1336# CONFIG_EXT2_FS_XIP is not set
1337CONFIG_EXT3_FS=m
1338CONFIG_EXT3_FS_XATTR=y
1339# CONFIG_EXT3_FS_POSIX_ACL is not set
1340# CONFIG_EXT3_FS_SECURITY is not set
1341# CONFIG_EXT4DEV_FS is not set
1342CONFIG_JBD=m
1343# CONFIG_JBD_DEBUG is not set
1344CONFIG_FS_MBCACHE=y
1345# CONFIG_REISERFS_FS is not set
1346# CONFIG_JFS_FS is not set
1347# CONFIG_FS_POSIX_ACL is not set
1348# CONFIG_XFS_FS is not set
1349# CONFIG_GFS2_FS is not set
1350# CONFIG_OCFS2_FS is not set
1351# CONFIG_MINIX_FS is not set
1352# CONFIG_ROMFS_FS is not set
1353CONFIG_INOTIFY=y
1354CONFIG_INOTIFY_USER=y
1355# CONFIG_QUOTA is not set
1356CONFIG_DNOTIFY=y
1357# CONFIG_AUTOFS_FS is not set
1358# CONFIG_AUTOFS4_FS is not set
1359# CONFIG_FUSE_FS is not set
1360
1361#
1362# CD-ROM/DVD Filesystems
1363#
1364CONFIG_ISO9660_FS=y
1365CONFIG_JOLIET=y
1366# CONFIG_ZISOFS is not set
1367# CONFIG_UDF_FS is not set
1368
1369#
1370# DOS/FAT/NT Filesystems
1371#
1372# CONFIG_MSDOS_FS is not set
1373# CONFIG_VFAT_FS is not set
1374# CONFIG_NTFS_FS is not set
1375
1376#
1377# Pseudo filesystems
1378#
1379CONFIG_PROC_FS=y
1380CONFIG_PROC_KCORE=y
1381CONFIG_PROC_SYSCTL=y
1382CONFIG_SYSFS=y
1383CONFIG_TMPFS=y
1384# CONFIG_TMPFS_POSIX_ACL is not set
1385# CONFIG_HUGETLBFS is not set
1386# CONFIG_HUGETLB_PAGE is not set
1387CONFIG_RAMFS=y
1388# CONFIG_CONFIGFS_FS is not set
1389
1390#
1391# Miscellaneous filesystems
1392#
1393# CONFIG_ADFS_FS is not set
1394# CONFIG_AFFS_FS is not set
1395# CONFIG_HFS_FS is not set
1396# CONFIG_HFSPLUS_FS is not set
1397# CONFIG_BEFS_FS is not set
1398# CONFIG_BFS_FS is not set
1399# CONFIG_EFS_FS is not set
1400# CONFIG_CRAMFS is not set
1401# CONFIG_SQUASHFS is not set
1402# CONFIG_VXFS_FS is not set
1403# CONFIG_HPFS_FS is not set
1404# CONFIG_QNX4FS_FS is not set
1405# CONFIG_SYSV_FS is not set
1406# CONFIG_UFS_FS is not set
1407
1408#
1409# Network File Systems
1410#
1411CONFIG_NFS_FS=y
1412# CONFIG_NFS_V3 is not set
1413# CONFIG_NFS_V4 is not set
1414# CONFIG_NFS_DIRECTIO is not set
1415# CONFIG_NFSD is not set
1416# CONFIG_ROOT_NFS is not set
1417CONFIG_LOCKD=y
1418CONFIG_NFS_COMMON=y
1419CONFIG_SUNRPC=y
1420# CONFIG_SUNRPC_BIND34 is not set
1421# CONFIG_RPCSEC_GSS_KRB5 is not set
1422# CONFIG_RPCSEC_GSS_SPKM3 is not set
1423# CONFIG_SMB_FS is not set
1424# CONFIG_CIFS is not set
1425# CONFIG_NCP_FS is not set
1426# CONFIG_CODA_FS is not set
1427# CONFIG_AFS_FS is not set
1428
1429#
1430# Partition Types
1431#
1432# CONFIG_PARTITION_ADVANCED is not set
1433CONFIG_MSDOS_PARTITION=y
1434
1435#
1436# Native Language Support
1437#
1438CONFIG_NLS=y
1439CONFIG_NLS_DEFAULT="utf-8"
1440CONFIG_NLS_CODEPAGE_437=y
1441# CONFIG_NLS_CODEPAGE_737 is not set
1442# CONFIG_NLS_CODEPAGE_775 is not set
1443# CONFIG_NLS_CODEPAGE_850 is not set
1444# CONFIG_NLS_CODEPAGE_852 is not set
1445# CONFIG_NLS_CODEPAGE_855 is not set
1446# CONFIG_NLS_CODEPAGE_857 is not set
1447# CONFIG_NLS_CODEPAGE_860 is not set
1448# CONFIG_NLS_CODEPAGE_861 is not set
1449# CONFIG_NLS_CODEPAGE_862 is not set
1450# CONFIG_NLS_CODEPAGE_863 is not set
1451# CONFIG_NLS_CODEPAGE_864 is not set
1452# CONFIG_NLS_CODEPAGE_865 is not set
1453# CONFIG_NLS_CODEPAGE_866 is not set
1454# CONFIG_NLS_CODEPAGE_869 is not set
1455# CONFIG_NLS_CODEPAGE_936 is not set
1456# CONFIG_NLS_CODEPAGE_950 is not set
1457# CONFIG_NLS_CODEPAGE_932 is not set
1458# CONFIG_NLS_CODEPAGE_949 is not set
1459# CONFIG_NLS_CODEPAGE_874 is not set
1460# CONFIG_NLS_ISO8859_8 is not set
1461# CONFIG_NLS_CODEPAGE_1250 is not set
1462# CONFIG_NLS_CODEPAGE_1251 is not set
1463# CONFIG_NLS_ASCII is not set
1464CONFIG_NLS_ISO8859_1=y
1465# CONFIG_NLS_ISO8859_2 is not set
1466# CONFIG_NLS_ISO8859_3 is not set
1467# CONFIG_NLS_ISO8859_4 is not set
1468# CONFIG_NLS_ISO8859_5 is not set
1469# CONFIG_NLS_ISO8859_6 is not set
1470# CONFIG_NLS_ISO8859_7 is not set
1471# CONFIG_NLS_ISO8859_9 is not set
1472# CONFIG_NLS_ISO8859_13 is not set
1473# CONFIG_NLS_ISO8859_14 is not set
1474# CONFIG_NLS_ISO8859_15 is not set
1475# CONFIG_NLS_KOI8_R is not set
1476# CONFIG_NLS_KOI8_U is not set
1477CONFIG_NLS_UTF8=y
1478
1479#
1480# Distributed Lock Manager
1481#
1482# CONFIG_DLM is not set
1483CONFIG_INSTRUMENTATION=y
1484CONFIG_PROFILING=y
1485CONFIG_OPROFILE=y
1486# CONFIG_KPROBES is not set
1487
1488#
1489# Kernel hacking
1490#
1491CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1492# CONFIG_PRINTK_TIME is not set
1493CONFIG_ENABLE_MUST_CHECK=y
1494CONFIG_MAGIC_SYSRQ=y
1495# CONFIG_UNUSED_SYMBOLS is not set
1496# CONFIG_DEBUG_FS is not set
1497# CONFIG_HEADERS_CHECK is not set
1498# CONFIG_DEBUG_KERNEL is not set
1499# CONFIG_DEBUG_BUGVERBOSE is not set
1500CONFIG_EARLY_PRINTK=y
1501CONFIG_X86_FIND_SMP_CONFIG=y
1502CONFIG_X86_MPPARSE=y
1503CONFIG_DOUBLEFAULT=y
1504
1505#
1506# Security options
1507#
1508# CONFIG_KEYS is not set
1509# CONFIG_SECURITY is not set
1510CONFIG_CRYPTO=y
1511CONFIG_CRYPTO_ALGAPI=m
1512CONFIG_CRYPTO_BLKCIPHER=m
1513CONFIG_CRYPTO_MANAGER=m
1514# CONFIG_CRYPTO_HMAC is not set
1515# CONFIG_CRYPTO_XCBC is not set
1516# CONFIG_CRYPTO_NULL is not set
1517# CONFIG_CRYPTO_MD4 is not set
1518# CONFIG_CRYPTO_MD5 is not set
1519CONFIG_CRYPTO_SHA1=m
1520CONFIG_CRYPTO_SHA256=m
1521# CONFIG_CRYPTO_SHA512 is not set
1522# CONFIG_CRYPTO_WP512 is not set
1523# CONFIG_CRYPTO_TGR192 is not set
1524# CONFIG_CRYPTO_GF128MUL is not set
1525CONFIG_CRYPTO_ECB=m
1526CONFIG_CRYPTO_CBC=m
1527CONFIG_CRYPTO_PCBC=m
1528# CONFIG_CRYPTO_LRW is not set
1529# CONFIG_CRYPTO_CRYPTD is not set
1530# CONFIG_CRYPTO_DES is not set
1531# CONFIG_CRYPTO_FCRYPT is not set
1532# CONFIG_CRYPTO_BLOWFISH is not set
1533# CONFIG_CRYPTO_TWOFISH is not set
1534# CONFIG_CRYPTO_TWOFISH_586 is not set
1535# CONFIG_CRYPTO_SERPENT is not set
1536# CONFIG_CRYPTO_AES is not set
1537# CONFIG_CRYPTO_AES_586 is not set
1538# CONFIG_CRYPTO_CAST5 is not set
1539# CONFIG_CRYPTO_CAST6 is not set
1540# CONFIG_CRYPTO_TEA is not set
1541# CONFIG_CRYPTO_ARC4 is not set
1542# CONFIG_CRYPTO_KHAZAD is not set
1543# CONFIG_CRYPTO_ANUBIS is not set
1544# CONFIG_CRYPTO_DEFLATE is not set
1545# CONFIG_CRYPTO_LZO is not set
1546# CONFIG_CRYPTO_MICHAEL_MIC is not set
1547# CONFIG_CRYPTO_CRC32C is not set
1548# CONFIG_CRYPTO_CAMELLIA is not set
1549# CONFIG_CRYPTO_TEST is not set
1550CONFIG_CRYPTO_HW=y
1551CONFIG_CRYPTO_DEV_PADLOCK=m
1552CONFIG_CRYPTO_DEV_PADLOCK_AES=m
1553CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
1554CONFIG_CRYPTO_DEV_GEODE=m
1555
1556#
1557# Library routines
1558#
1559CONFIG_BITREVERSE=y
1560CONFIG_CRC_CCITT=m
1561# CONFIG_CRC16 is not set
1562# CONFIG_CRC_ITU_T is not set
1563CONFIG_CRC32=y
1564# CONFIG_CRC7 is not set
1565CONFIG_LIBCRC32C=m
1566CONFIG_AUDIT_GENERIC=y
1567CONFIG_ZLIB_INFLATE=m
1568CONFIG_PLIST=y
1569CONFIG_HAS_IOMEM=y
1570CONFIG_HAS_IOPORT=y
1571CONFIG_HAS_DMA=y
1572CONFIG_GENERIC_HARDIRQS=y
1573CONFIG_GENERIC_IRQ_PROBE=y
1574CONFIG_GENERIC_PENDING_IRQ=y
1575CONFIG_X86_SMP=y
1576CONFIG_X86_HT=y
1577CONFIG_X86_BIOS_REBOOT=y
1578CONFIG_X86_TRAMPOLINE=y
1579CONFIG_KTIME_SCALAR=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-c7x0 b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-c7x0
new file mode 100644
index 0000000000..f1d0295fb0
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-c7x0
@@ -0,0 +1,1741 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Tue Oct 16 12:02:32 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37# CONFIG_LOCALVERSION_AUTO is not set
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41# CONFIG_POSIX_MQUEUE is not set
42CONFIG_BSD_PROCESS_ACCT=y
43CONFIG_BSD_PROCESS_ACCT_V3=y
44# CONFIG_TASKSTATS is not set
45# CONFIG_USER_NS is not set
46# CONFIG_AUDIT is not set
47# CONFIG_IKCONFIG is not set
48CONFIG_LOG_BUF_SHIFT=14
49CONFIG_SYSFS_DEPRECATED=y
50# CONFIG_RELAY is not set
51# CONFIG_BLK_DEV_INITRD is not set
52CONFIG_CC_OPTIMIZE_FOR_SIZE=y
53CONFIG_SYSCTL=y
54CONFIG_EMBEDDED=y
55CONFIG_UID16=y
56CONFIG_SYSCTL_SYSCALL=y
57CONFIG_KALLSYMS=y
58# CONFIG_KALLSYMS_ALL is not set
59# CONFIG_KALLSYMS_EXTRA_PASS is not set
60CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y
62CONFIG_BUG=y
63CONFIG_ELF_CORE=y
64CONFIG_BASE_FULL=y
65CONFIG_FUTEX=y
66CONFIG_ANON_INODES=y
67CONFIG_EPOLL=y
68CONFIG_SIGNALFD=y
69CONFIG_EVENTFD=y
70CONFIG_SHMEM=y
71CONFIG_VM_EVENT_COUNTERS=y
72CONFIG_SLAB=y
73# CONFIG_SLUB is not set
74# CONFIG_SLOB is not set
75CONFIG_RT_MUTEXES=y
76# CONFIG_TINY_SHMEM is not set
77CONFIG_BASE_SMALL=0
78CONFIG_MODULES=y
79CONFIG_MODULE_UNLOAD=y
80CONFIG_MODULE_FORCE_UNLOAD=y
81# CONFIG_MODVERSIONS is not set
82# CONFIG_MODULE_SRCVERSION_ALL is not set
83CONFIG_KMOD=y
84CONFIG_BLOCK=y
85# CONFIG_LBD is not set
86# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set
88# CONFIG_BLK_DEV_BSG is not set
89
90#
91# IO Schedulers
92#
93CONFIG_IOSCHED_NOOP=y
94CONFIG_IOSCHED_AS=y
95CONFIG_IOSCHED_DEADLINE=m
96CONFIG_IOSCHED_CFQ=m
97CONFIG_DEFAULT_AS=y
98# CONFIG_DEFAULT_DEADLINE is not set
99# CONFIG_DEFAULT_CFQ is not set
100# CONFIG_DEFAULT_NOOP is not set
101CONFIG_DEFAULT_IOSCHED="anticipatory"
102
103#
104# System Type
105#
106# CONFIG_ARCH_AAEC2000 is not set
107# CONFIG_ARCH_INTEGRATOR is not set
108# CONFIG_ARCH_REALVIEW is not set
109# CONFIG_ARCH_VERSATILE is not set
110# CONFIG_ARCH_AT91 is not set
111# CONFIG_ARCH_CLPS7500 is not set
112# CONFIG_ARCH_CLPS711X is not set
113# CONFIG_ARCH_CO285 is not set
114# CONFIG_ARCH_EBSA110 is not set
115# CONFIG_ARCH_EP93XX is not set
116# CONFIG_ARCH_FOOTBRIDGE is not set
117# CONFIG_ARCH_NETX is not set
118# CONFIG_ARCH_H720X is not set
119# CONFIG_ARCH_IMX is not set
120# CONFIG_ARCH_IOP13XX is not set
121# CONFIG_ARCH_IOP32X is not set
122# CONFIG_ARCH_IOP33X is not set
123# CONFIG_ARCH_IXP23XX is not set
124# CONFIG_ARCH_IXP2000 is not set
125# CONFIG_ARCH_IXP4XX is not set
126# CONFIG_ARCH_L7200 is not set
127# CONFIG_ARCH_KS8695 is not set
128# CONFIG_ARCH_NS9XXX is not set
129# CONFIG_ARCH_MXC is not set
130# CONFIG_ARCH_PNX4008 is not set
131CONFIG_ARCH_PXA=y
132# CONFIG_ARCH_RPC is not set
133# CONFIG_ARCH_SA1100 is not set
134# CONFIG_ARCH_S3C2410 is not set
135# CONFIG_ARCH_SHARK is not set
136# CONFIG_ARCH_LH7A40X is not set
137# CONFIG_ARCH_DAVINCI is not set
138# CONFIG_ARCH_OMAP is not set
139
140#
141# Intel PXA2xx Implementations
142#
143# CONFIG_ARCH_LUBBOCK is not set
144# CONFIG_MACH_LOGICPD_PXA270 is not set
145# CONFIG_MACH_MAINSTONE is not set
146# CONFIG_ARCH_PXA_IDP is not set
147CONFIG_PXA_SHARPSL=y
148# CONFIG_MACH_TRIZEPS4 is not set
149# CONFIG_MACH_EM_X270 is not set
150# CONFIG_MACH_HX2750 is not set
151# CONFIG_MACH_HTCUNIVERSAL is not set
152CONFIG_PXA_SHARPSL_25x=y
153# CONFIG_PXA_SHARPSL_27x is not set
154# CONFIG_MACH_POODLE is not set
155CONFIG_MACH_CORGI=y
156CONFIG_MACH_SHEPHERD=y
157CONFIG_MACH_HUSKY=y
158# CONFIG_MACH_TOSA is not set
159CONFIG_PXA25x=y
160CONFIG_PXA_SHARP_C7xx=y
161CONFIG_PXA_SSP=y
162# CONFIG_PXA_KEYS is not set
163
164#
165# Boot options
166#
167
168#
169# Power management
170#
171
172#
173# Processor Type
174#
175CONFIG_CPU_32=y
176CONFIG_CPU_XSCALE=y
177CONFIG_CPU_32v5=y
178CONFIG_CPU_ABRT_EV5T=y
179CONFIG_CPU_CACHE_VIVT=y
180CONFIG_CPU_TLB_V4WBI=y
181CONFIG_CPU_CP15=y
182CONFIG_CPU_CP15_MMU=y
183
184#
185# Processor Features
186#
187CONFIG_ARM_THUMB=y
188# CONFIG_CPU_DCACHE_DISABLE is not set
189# CONFIG_OUTER_CACHE is not set
190# CONFIG_IWMMXT is not set
191CONFIG_XSCALE_PMU=y
192CONFIG_SHARP_PARAM=y
193CONFIG_SHARPSL_PM=y
194CONFIG_SHARP_SCOOP=y
195
196#
197# Bus support
198#
199# CONFIG_PCI_SYSCALL is not set
200# CONFIG_ARCH_SUPPORTS_MSI is not set
201
202#
203# PCCARD (PCMCIA/CardBus) support
204#
205CONFIG_PCCARD=m
206# CONFIG_PCMCIA_DEBUG is not set
207CONFIG_PCMCIA=m
208CONFIG_PCMCIA_LOAD_CIS=y
209CONFIG_PCMCIA_IOCTL=y
210
211#
212# PC-card bridges
213#
214CONFIG_PCMCIA_PXA2XX=m
215
216#
217# Kernel Features
218#
219CONFIG_TICK_ONESHOT=y
220CONFIG_NO_HZ=y
221CONFIG_HIGH_RES_TIMERS=y
222CONFIG_PREEMPT=y
223CONFIG_HZ=100
224CONFIG_AEABI=y
225CONFIG_OABI_COMPAT=y
226# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
227CONFIG_SELECT_MEMORY_MODEL=y
228CONFIG_FLATMEM_MANUAL=y
229# CONFIG_DISCONTIGMEM_MANUAL is not set
230# CONFIG_SPARSEMEM_MANUAL is not set
231CONFIG_FLATMEM=y
232CONFIG_FLAT_NODE_MEM_MAP=y
233# CONFIG_SPARSEMEM_STATIC is not set
234CONFIG_SPLIT_PTLOCK_CPUS=4096
235# CONFIG_RESOURCES_64BIT is not set
236CONFIG_ZONE_DMA_FLAG=1
237CONFIG_BOUNCE=y
238CONFIG_VIRT_TO_BUS=y
239CONFIG_ALIGNMENT_TRAP=y
240
241#
242# Boot options
243#
244CONFIG_ZBOOT_ROM_TEXT=0x0
245CONFIG_ZBOOT_ROM_BSS=0x0
246CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 dyntick=enable quiet"
247# CONFIG_XIP_KERNEL is not set
248CONFIG_KEXEC=y
249CONFIG_ATAGS_PROC=y
250CONFIG_CPU_FREQ_PXA25x=y
251
252#
253# CPU Frequency scaling
254#
255CONFIG_CPU_FREQ=y
256CONFIG_CPU_FREQ_TABLE=y
257CONFIG_CPU_FREQ_DEBUG=y
258CONFIG_CPU_FREQ_STAT=y
259# CONFIG_CPU_FREQ_STAT_DETAILS is not set
260CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
261# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
262CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
263CONFIG_CPU_FREQ_GOV_POWERSAVE=y
264CONFIG_CPU_FREQ_GOV_USERSPACE=y
265CONFIG_CPU_FREQ_GOV_ONDEMAND=y
266CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
267
268#
269# Floating point emulation
270#
271
272#
273# At least one emulation must be selected
274#
275CONFIG_FPE_NWFPE=y
276# CONFIG_FPE_NWFPE_XP is not set
277# CONFIG_FPE_FASTFPE is not set
278
279#
280# Userspace binary formats
281#
282CONFIG_BINFMT_ELF=y
283CONFIG_BINFMT_AOUT=m
284CONFIG_BINFMT_MISC=m
285
286#
287# Power management options
288#
289CONFIG_PM=y
290# CONFIG_PM_LEGACY is not set
291# CONFIG_PM_DEBUG is not set
292CONFIG_PM_SLEEP=y
293CONFIG_SUSPEND_UP_POSSIBLE=y
294CONFIG_SUSPEND=y
295CONFIG_APM_EMULATION=y
296
297#
298# Networking
299#
300CONFIG_NET=y
301
302#
303# Networking options
304#
305CONFIG_PACKET=m
306CONFIG_PACKET_MMAP=y
307CONFIG_UNIX=y
308CONFIG_XFRM=y
309CONFIG_XFRM_USER=m
310# CONFIG_XFRM_SUB_POLICY is not set
311# CONFIG_XFRM_MIGRATE is not set
312# CONFIG_NET_KEY is not set
313CONFIG_INET=y
314# CONFIG_IP_MULTICAST is not set
315# CONFIG_IP_ADVANCED_ROUTER is not set
316CONFIG_IP_FIB_HASH=y
317# CONFIG_IP_PNP is not set
318# CONFIG_NET_IPIP is not set
319# CONFIG_NET_IPGRE is not set
320# CONFIG_ARPD is not set
321CONFIG_SYN_COOKIES=y
322# CONFIG_INET_AH is not set
323# CONFIG_INET_ESP is not set
324# CONFIG_INET_IPCOMP is not set
325# CONFIG_INET_XFRM_TUNNEL is not set
326CONFIG_INET_TUNNEL=m
327CONFIG_INET_XFRM_MODE_TRANSPORT=m
328CONFIG_INET_XFRM_MODE_TUNNEL=m
329CONFIG_INET_XFRM_MODE_BEET=m
330CONFIG_INET_DIAG=m
331CONFIG_INET_TCP_DIAG=m
332# CONFIG_TCP_CONG_ADVANCED is not set
333CONFIG_TCP_CONG_CUBIC=y
334CONFIG_DEFAULT_TCP_CONG="cubic"
335# CONFIG_TCP_MD5SIG is not set
336# CONFIG_IP_VS is not set
337CONFIG_IPV6=m
338# CONFIG_IPV6_PRIVACY is not set
339# CONFIG_IPV6_ROUTER_PREF is not set
340# CONFIG_IPV6_OPTIMISTIC_DAD is not set
341CONFIG_INET6_AH=m
342CONFIG_INET6_ESP=m
343CONFIG_INET6_IPCOMP=m
344# CONFIG_IPV6_MIP6 is not set
345CONFIG_INET6_XFRM_TUNNEL=m
346CONFIG_INET6_TUNNEL=m
347CONFIG_INET6_XFRM_MODE_TRANSPORT=m
348CONFIG_INET6_XFRM_MODE_TUNNEL=m
349CONFIG_INET6_XFRM_MODE_BEET=m
350# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
351CONFIG_IPV6_SIT=m
352CONFIG_IPV6_TUNNEL=m
353# CONFIG_IPV6_MULTIPLE_TABLES is not set
354# CONFIG_NETWORK_SECMARK is not set
355CONFIG_NETFILTER=y
356# CONFIG_NETFILTER_DEBUG is not set
357
358#
359# Core Netfilter Configuration
360#
361# CONFIG_NETFILTER_NETLINK is not set
362# CONFIG_NF_CONNTRACK_ENABLED is not set
363# CONFIG_NF_CONNTRACK is not set
364CONFIG_NETFILTER_XTABLES=m
365# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
366# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
367# CONFIG_NETFILTER_XT_TARGET_MARK is not set
368# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
369# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
370# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
371# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
372# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
373# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
374# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
375# CONFIG_NETFILTER_XT_MATCH_ESP is not set
376# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
377# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
378# CONFIG_NETFILTER_XT_MATCH_MAC is not set
379# CONFIG_NETFILTER_XT_MATCH_MARK is not set
380# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
381# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
382# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
383# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
384# CONFIG_NETFILTER_XT_MATCH_REALM is not set
385# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
386# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
387# CONFIG_NETFILTER_XT_MATCH_STRING is not set
388# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
389# CONFIG_NETFILTER_XT_MATCH_U32 is not set
390# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
391
392#
393# IP: Netfilter Configuration
394#
395CONFIG_IP_NF_QUEUE=m
396CONFIG_IP_NF_IPTABLES=m
397CONFIG_IP_NF_MATCH_IPRANGE=m
398CONFIG_IP_NF_MATCH_TOS=m
399CONFIG_IP_NF_MATCH_RECENT=m
400CONFIG_IP_NF_MATCH_ECN=m
401CONFIG_IP_NF_MATCH_AH=m
402CONFIG_IP_NF_MATCH_TTL=m
403CONFIG_IP_NF_MATCH_OWNER=m
404CONFIG_IP_NF_MATCH_ADDRTYPE=m
405CONFIG_IP_NF_FILTER=m
406CONFIG_IP_NF_TARGET_REJECT=m
407CONFIG_IP_NF_TARGET_LOG=m
408CONFIG_IP_NF_TARGET_ULOG=m
409CONFIG_IP_NF_MANGLE=m
410CONFIG_IP_NF_TARGET_TOS=m
411CONFIG_IP_NF_TARGET_ECN=m
412CONFIG_IP_NF_TARGET_TTL=m
413CONFIG_IP_NF_RAW=m
414CONFIG_IP_NF_ARPTABLES=m
415CONFIG_IP_NF_ARPFILTER=m
416CONFIG_IP_NF_ARP_MANGLE=m
417
418#
419# IPv6: Netfilter Configuration (EXPERIMENTAL)
420#
421# CONFIG_IP6_NF_QUEUE is not set
422# CONFIG_IP6_NF_IPTABLES is not set
423# CONFIG_IP_DCCP is not set
424# CONFIG_IP_SCTP is not set
425# CONFIG_TIPC is not set
426# CONFIG_ATM is not set
427# CONFIG_BRIDGE is not set
428# CONFIG_VLAN_8021Q is not set
429# CONFIG_DECNET is not set
430# CONFIG_LLC2 is not set
431# CONFIG_IPX is not set
432# CONFIG_ATALK is not set
433# CONFIG_X25 is not set
434# CONFIG_LAPB is not set
435# CONFIG_ECONET is not set
436# CONFIG_WAN_ROUTER is not set
437
438#
439# QoS and/or fair queueing
440#
441# CONFIG_NET_SCHED is not set
442
443#
444# Network testing
445#
446# CONFIG_NET_PKTGEN is not set
447# CONFIG_HAMRADIO is not set
448CONFIG_IRDA=m
449
450#
451# IrDA protocols
452#
453CONFIG_IRLAN=m
454CONFIG_IRNET=m
455CONFIG_IRCOMM=m
456# CONFIG_IRDA_ULTRA is not set
457
458#
459# IrDA options
460#
461# CONFIG_IRDA_CACHE_LAST_LSAP is not set
462# CONFIG_IRDA_FAST_RR is not set
463# CONFIG_IRDA_DEBUG is not set
464
465#
466# Infrared-port device drivers
467#
468
469#
470# SIR device drivers
471#
472# CONFIG_IRTTY_SIR is not set
473
474#
475# Dongle support
476#
477# CONFIG_KINGSUN_DONGLE is not set
478
479#
480# Old SIR device drivers
481#
482# CONFIG_IRPORT_SIR is not set
483
484#
485# Old Serial dongle support
486#
487
488#
489# FIR device drivers
490#
491# CONFIG_USB_IRDA is not set
492# CONFIG_SIGMATEL_FIR is not set
493CONFIG_PXA_FICP=m
494# CONFIG_MCS_FIR is not set
495CONFIG_BT=m
496CONFIG_BT_L2CAP=m
497CONFIG_BT_SCO=m
498CONFIG_BT_RFCOMM=m
499CONFIG_BT_RFCOMM_TTY=y
500CONFIG_BT_BNEP=m
501CONFIG_BT_BNEP_MC_FILTER=y
502CONFIG_BT_BNEP_PROTO_FILTER=y
503CONFIG_BT_HIDP=m
504
505#
506# Bluetooth device drivers
507#
508CONFIG_BT_HCIUSB=m
509# CONFIG_BT_HCIUSB_SCO is not set
510CONFIG_BT_HCIUART=m
511CONFIG_BT_HCIUART_H4=y
512CONFIG_BT_HCIUART_BCSP=y
513CONFIG_BT_HCIBCM203X=m
514CONFIG_BT_HCIBPA10X=m
515CONFIG_BT_HCIBFUSB=m
516CONFIG_BT_HCIDTL1=m
517CONFIG_BT_HCIBT3C=m
518CONFIG_BT_HCIBLUECARD=m
519CONFIG_BT_HCIBTUART=m
520CONFIG_BT_HCIVHCI=m
521# CONFIG_AF_RXRPC is not set
522
523#
524# Wireless
525#
526# CONFIG_CFG80211 is not set
527CONFIG_WIRELESS_EXT=y
528# CONFIG_MAC80211 is not set
529CONFIG_IEEE80211=m
530# CONFIG_IEEE80211_DEBUG is not set
531CONFIG_IEEE80211_CRYPT_WEP=m
532CONFIG_IEEE80211_CRYPT_CCMP=m
533CONFIG_IEEE80211_CRYPT_TKIP=m
534# CONFIG_IEEE80211_SOFTMAC is not set
535# CONFIG_RFKILL is not set
536# CONFIG_NET_9P is not set
537
538#
539# Device Drivers
540#
541
542#
543# Generic Driver Options
544#
545CONFIG_STANDALONE=y
546CONFIG_PREVENT_FIRMWARE_BUILD=y
547CONFIG_FW_LOADER=y
548# CONFIG_DEBUG_DRIVER is not set
549# CONFIG_DEBUG_DEVRES is not set
550# CONFIG_SYS_HYPERVISOR is not set
551# CONFIG_CONNECTOR is not set
552CONFIG_MTD=y
553# CONFIG_MTD_DEBUG is not set
554# CONFIG_MTD_CONCAT is not set
555CONFIG_MTD_PARTITIONS=y
556# CONFIG_MTD_REDBOOT_PARTS is not set
557CONFIG_MTD_CMDLINE_PARTS=y
558# CONFIG_MTD_AFS_PARTS is not set
559
560#
561# User Modules And Translation Layers
562#
563CONFIG_MTD_CHAR=y
564CONFIG_MTD_BLKDEVS=y
565CONFIG_MTD_BLOCK=y
566# CONFIG_FTL is not set
567# CONFIG_NFTL is not set
568# CONFIG_INFTL is not set
569# CONFIG_RFD_FTL is not set
570# CONFIG_SSFDC is not set
571
572#
573# RAM/ROM/Flash chip drivers
574#
575# CONFIG_MTD_CFI is not set
576# CONFIG_MTD_JEDECPROBE is not set
577CONFIG_MTD_MAP_BANK_WIDTH_1=y
578CONFIG_MTD_MAP_BANK_WIDTH_2=y
579CONFIG_MTD_MAP_BANK_WIDTH_4=y
580# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
581# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
582# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
583CONFIG_MTD_CFI_I1=y
584CONFIG_MTD_CFI_I2=y
585# CONFIG_MTD_CFI_I4 is not set
586# CONFIG_MTD_CFI_I8 is not set
587# CONFIG_MTD_RAM is not set
588CONFIG_MTD_ROM=y
589# CONFIG_MTD_ABSENT is not set
590
591#
592# Mapping drivers for chip access
593#
594CONFIG_MTD_COMPLEX_MAPPINGS=y
595# CONFIG_MTD_PHYSMAP is not set
596CONFIG_MTD_SHARP_SL=y
597# CONFIG_MTD_PLATRAM is not set
598
599#
600# Self-contained MTD device drivers
601#
602# CONFIG_MTD_SLRAM is not set
603# CONFIG_MTD_PHRAM is not set
604# CONFIG_MTD_MTDRAM is not set
605# CONFIG_MTD_BLOCK2MTD is not set
606
607#
608# Disk-On-Chip Device Drivers
609#
610# CONFIG_MTD_DOC2000 is not set
611# CONFIG_MTD_DOC2001 is not set
612# CONFIG_MTD_DOC2001PLUS is not set
613CONFIG_MTD_NAND=y
614CONFIG_MTD_NAND_VERIFY_WRITE=y
615# CONFIG_MTD_NAND_ECC_SMC is not set
616# CONFIG_MTD_NAND_MUSEUM_IDS is not set
617# CONFIG_MTD_NAND_H1900 is not set
618CONFIG_MTD_NAND_IDS=y
619# CONFIG_MTD_NAND_DISKONCHIP is not set
620CONFIG_MTD_NAND_SHARPSL=y
621# CONFIG_MTD_NAND_NANDSIM is not set
622# CONFIG_MTD_NAND_PLATFORM is not set
623# CONFIG_MTD_ONENAND is not set
624
625#
626# UBI - Unsorted block images
627#
628# CONFIG_MTD_UBI is not set
629# CONFIG_PARPORT is not set
630CONFIG_BLK_DEV=y
631# CONFIG_BLK_DEV_COW_COMMON is not set
632CONFIG_BLK_DEV_LOOP=y
633# CONFIG_BLK_DEV_CRYPTOLOOP is not set
634# CONFIG_BLK_DEV_NBD is not set
635# CONFIG_BLK_DEV_UB is not set
636# CONFIG_BLK_DEV_RAM is not set
637# CONFIG_CDROM_PKTCDVD is not set
638# CONFIG_ATA_OVER_ETH is not set
639CONFIG_IDE=y
640CONFIG_IDE_MAX_HWIFS=4
641CONFIG_BLK_DEV_IDE=y
642
643#
644# Please see Documentation/ide.txt for help/info on IDE drives
645#
646# CONFIG_BLK_DEV_IDE_SATA is not set
647CONFIG_BLK_DEV_IDEDISK=y
648# CONFIG_IDEDISK_MULTI_MODE is not set
649CONFIG_BLK_DEV_IDECS=m
650# CONFIG_BLK_DEV_IDECD is not set
651# CONFIG_BLK_DEV_IDETAPE is not set
652# CONFIG_BLK_DEV_IDEFLOPPY is not set
653# CONFIG_BLK_DEV_IDESCSI is not set
654# CONFIG_IDE_TASK_IOCTL is not set
655CONFIG_IDE_PROC_FS=y
656
657#
658# IDE chipset support/bugfixes
659#
660CONFIG_IDE_GENERIC=y
661# CONFIG_IDEPCI_PCIBUS_ORDER is not set
662# CONFIG_IDE_ARM is not set
663# CONFIG_BLK_DEV_IDEDMA is not set
664# CONFIG_BLK_DEV_HD is not set
665
666#
667# SCSI device support
668#
669# CONFIG_RAID_ATTRS is not set
670CONFIG_SCSI=m
671CONFIG_SCSI_DMA=y
672# CONFIG_SCSI_TGT is not set
673# CONFIG_SCSI_NETLINK is not set
674CONFIG_SCSI_PROC_FS=y
675
676#
677# SCSI support type (disk, tape, CD-ROM)
678#
679CONFIG_BLK_DEV_SD=m
680CONFIG_CHR_DEV_ST=m
681CONFIG_CHR_DEV_OSST=m
682CONFIG_BLK_DEV_SR=m
683# CONFIG_BLK_DEV_SR_VENDOR is not set
684CONFIG_CHR_DEV_SG=m
685# CONFIG_CHR_DEV_SCH is not set
686
687#
688# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
689#
690CONFIG_SCSI_MULTI_LUN=y
691# CONFIG_SCSI_CONSTANTS is not set
692# CONFIG_SCSI_LOGGING is not set
693# CONFIG_SCSI_SCAN_ASYNC is not set
694CONFIG_SCSI_WAIT_SCAN=m
695
696#
697# SCSI Transports
698#
699# CONFIG_SCSI_SPI_ATTRS is not set
700# CONFIG_SCSI_FC_ATTRS is not set
701# CONFIG_SCSI_ISCSI_ATTRS is not set
702# CONFIG_SCSI_SAS_LIBSAS is not set
703CONFIG_SCSI_LOWLEVEL=y
704# CONFIG_ISCSI_TCP is not set
705# CONFIG_SCSI_DEBUG is not set
706# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
707# CONFIG_ATA is not set
708CONFIG_MD=y
709# CONFIG_BLK_DEV_MD is not set
710CONFIG_BLK_DEV_DM=m
711# CONFIG_DM_DEBUG is not set
712CONFIG_DM_CRYPT=m
713CONFIG_DM_SNAPSHOT=m
714CONFIG_DM_MIRROR=m
715CONFIG_DM_ZERO=m
716CONFIG_DM_MULTIPATH=m
717CONFIG_DM_MULTIPATH_EMC=m
718# CONFIG_DM_MULTIPATH_RDAC is not set
719# CONFIG_DM_DELAY is not set
720CONFIG_NETDEVICES=y
721# CONFIG_NETDEVICES_MULTIQUEUE is not set
722# CONFIG_DUMMY is not set
723# CONFIG_BONDING is not set
724# CONFIG_MACVLAN is not set
725# CONFIG_EQUALIZER is not set
726CONFIG_TUN=m
727# CONFIG_PHYLIB is not set
728CONFIG_NET_ETHERNET=y
729CONFIG_MII=m
730# CONFIG_AX88796 is not set
731# CONFIG_SMC91X is not set
732# CONFIG_DM9000 is not set
733# CONFIG_SMC911X is not set
734# CONFIG_NETDEV_1000 is not set
735# CONFIG_NETDEV_10000 is not set
736
737#
738# Wireless LAN
739#
740# CONFIG_WLAN_PRE80211 is not set
741CONFIG_WLAN_80211=y
742# CONFIG_PCMCIA_RAYCS is not set
743# CONFIG_LIBERTAS is not set
744CONFIG_HERMES=m
745# CONFIG_ATMEL is not set
746CONFIG_PCMCIA_HERMES=m
747CONFIG_PCMCIA_SPECTRUM=m
748# CONFIG_AIRO_CS is not set
749# CONFIG_PCMCIA_WL3501 is not set
750# CONFIG_USB_ZD1201 is not set
751CONFIG_HOSTAP=m
752CONFIG_HOSTAP_FIRMWARE=y
753# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
754CONFIG_HOSTAP_CS=m
755
756#
757# USB Network Adapters
758#
759CONFIG_USB_CATC=m
760CONFIG_USB_KAWETH=m
761CONFIG_USB_PEGASUS=m
762CONFIG_USB_RTL8150=m
763CONFIG_USB_USBNET_MII=m
764CONFIG_USB_USBNET=m
765CONFIG_USB_NET_AX8817X=m
766CONFIG_USB_NET_CDCETHER=m
767# CONFIG_USB_NET_DM9601 is not set
768# CONFIG_USB_NET_GL620A is not set
769CONFIG_USB_NET_NET1080=m
770# CONFIG_USB_NET_PLUSB is not set
771# CONFIG_USB_NET_MCS7830 is not set
772# CONFIG_USB_NET_RNDIS_HOST is not set
773# CONFIG_USB_NET_CDC_SUBSET is not set
774CONFIG_USB_NET_ZAURUS=m
775CONFIG_NET_PCMCIA=y
776# CONFIG_PCMCIA_3C589 is not set
777# CONFIG_PCMCIA_3C574 is not set
778# CONFIG_PCMCIA_FMVJ18X is not set
779CONFIG_PCMCIA_PCNET=m
780# CONFIG_PCMCIA_NMCLAN is not set
781# CONFIG_PCMCIA_SMC91C92 is not set
782# CONFIG_PCMCIA_XIRC2PS is not set
783# CONFIG_PCMCIA_AXNET is not set
784# CONFIG_WAN is not set
785CONFIG_PPP=m
786# CONFIG_PPP_MULTILINK is not set
787# CONFIG_PPP_FILTER is not set
788CONFIG_PPP_ASYNC=m
789# CONFIG_PPP_SYNC_TTY is not set
790CONFIG_PPP_DEFLATE=m
791CONFIG_PPP_BSDCOMP=m
792# CONFIG_PPP_MPPE is not set
793# CONFIG_PPPOE is not set
794# CONFIG_PPPOL2TP is not set
795# CONFIG_SLIP is not set
796CONFIG_SLHC=m
797# CONFIG_SHAPER is not set
798# CONFIG_NETCONSOLE is not set
799# CONFIG_NETPOLL is not set
800# CONFIG_NET_POLL_CONTROLLER is not set
801# CONFIG_ISDN is not set
802
803#
804# Input device support
805#
806CONFIG_INPUT=y
807# CONFIG_INPUT_FF_MEMLESS is not set
808# CONFIG_INPUT_POLLDEV is not set
809
810#
811# Userland interfaces
812#
813CONFIG_INPUT_MOUSEDEV=m
814# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
815CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
816CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
817# CONFIG_INPUT_JOYDEV is not set
818# CONFIG_INPUT_TSDEV is not set
819CONFIG_INPUT_EVDEV=y
820# CONFIG_INPUT_EVBUG is not set
821CONFIG_INPUT_POWER=y
822
823#
824# Input Device Drivers
825#
826CONFIG_INPUT_KEYBOARD=y
827# CONFIG_KEYBOARD_ATKBD is not set
828# CONFIG_KEYBOARD_SUNKBD is not set
829# CONFIG_KEYBOARD_LKKBD is not set
830# CONFIG_KEYBOARD_XTKBD is not set
831# CONFIG_KEYBOARD_NEWTON is not set
832# CONFIG_KEYBOARD_STOWAWAY is not set
833CONFIG_KEYBOARD_CORGI=y
834# CONFIG_KEYBOARD_SPITZ is not set
835# CONFIG_KEYBOARD_GPIO is not set
836# CONFIG_INPUT_MOUSE is not set
837# CONFIG_INPUT_JOYSTICK is not set
838# CONFIG_INPUT_TABLET is not set
839CONFIG_INPUT_TOUCHSCREEN=y
840CONFIG_TOUCHSCREEN_CORGI=y
841# CONFIG_TOUCHSCREEN_FUJITSU is not set
842# CONFIG_TOUCHSCREEN_GUNZE is not set
843# CONFIG_TOUCHSCREEN_ELO is not set
844# CONFIG_TOUCHSCREEN_MTOUCH is not set
845# CONFIG_TOUCHSCREEN_MK712 is not set
846# CONFIG_TOUCHSCREEN_PENMOUNT is not set
847# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
848# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
849# CONFIG_TOUCHSCREEN_UCB1400 is not set
850# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
851CONFIG_INPUT_MISC=y
852# CONFIG_INPUT_ATI_REMOTE is not set
853# CONFIG_INPUT_ATI_REMOTE2 is not set
854# CONFIG_INPUT_KEYSPAN_REMOTE is not set
855# CONFIG_INPUT_POWERMATE is not set
856# CONFIG_INPUT_YEALINK is not set
857CONFIG_INPUT_UINPUT=m
858
859#
860# Hardware I/O ports
861#
862# CONFIG_SERIO is not set
863# CONFIG_GAMEPORT is not set
864
865#
866# Character devices
867#
868CONFIG_VT=y
869CONFIG_VT_CONSOLE=y
870CONFIG_HW_CONSOLE=y
871# CONFIG_VT_HW_CONSOLE_BINDING is not set
872# CONFIG_SERIAL_NONSTANDARD is not set
873
874#
875# Serial drivers
876#
877CONFIG_SERIAL_8250=m
878CONFIG_SERIAL_8250_CS=m
879CONFIG_SERIAL_8250_NR_UARTS=4
880CONFIG_SERIAL_8250_RUNTIME_UARTS=4
881# CONFIG_SERIAL_8250_EXTENDED is not set
882
883#
884# Non-8250 serial port support
885#
886CONFIG_SERIAL_PXA=y
887CONFIG_SERIAL_PXA_CONSOLE=y
888CONFIG_SERIAL_CORE=y
889CONFIG_SERIAL_CORE_CONSOLE=y
890CONFIG_UNIX98_PTYS=y
891# CONFIG_LEGACY_PTYS is not set
892# CONFIG_IPMI_HANDLER is not set
893# CONFIG_WATCHDOG is not set
894CONFIG_HW_RANDOM=m
895# CONFIG_NVRAM is not set
896# CONFIG_R3964 is not set
897
898#
899# PCMCIA character devices
900#
901# CONFIG_SYNCLINK_CS is not set
902# CONFIG_CARDMAN_4000 is not set
903# CONFIG_CARDMAN_4040 is not set
904# CONFIG_RAW_DRIVER is not set
905# CONFIG_TCG_TPM is not set
906CONFIG_I2C=y
907CONFIG_I2C_BOARDINFO=y
908# CONFIG_I2C_CHARDEV is not set
909
910#
911# I2C Algorithms
912#
913CONFIG_I2C_ALGOBIT=y
914# CONFIG_I2C_ALGOPCF is not set
915# CONFIG_I2C_ALGOPCA is not set
916
917#
918# I2C Hardware Bus support
919#
920# CONFIG_I2C_GPIO is not set
921CONFIG_I2C_PXA=y
922# CONFIG_I2C_PXA_SLAVE is not set
923# CONFIG_I2C_OCORES is not set
924# CONFIG_I2C_PARPORT_LIGHT is not set
925# CONFIG_I2C_SIMTEC is not set
926# CONFIG_I2C_TAOS_EVM is not set
927# CONFIG_I2C_STUB is not set
928# CONFIG_I2C_TINY_USB is not set
929
930#
931# Miscellaneous I2C Chip support
932#
933# CONFIG_SENSORS_DS1337 is not set
934# CONFIG_SENSORS_DS1374 is not set
935# CONFIG_DS1682 is not set
936# CONFIG_SENSORS_EEPROM is not set
937# CONFIG_SENSORS_PCF8574 is not set
938# CONFIG_SENSORS_PCA9539 is not set
939# CONFIG_SENSORS_PCF8591 is not set
940# CONFIG_SENSORS_MAX6875 is not set
941# CONFIG_SENSORS_TSL2550 is not set
942# CONFIG_I2C_DEBUG_CORE is not set
943# CONFIG_I2C_DEBUG_ALGO is not set
944# CONFIG_I2C_DEBUG_BUS is not set
945# CONFIG_I2C_DEBUG_CHIP is not set
946
947#
948# SPI support
949#
950# CONFIG_SPI is not set
951# CONFIG_SPI_MASTER is not set
952# CONFIG_W1 is not set
953# CONFIG_POWER_SUPPLY is not set
954# CONFIG_HWMON is not set
955CONFIG_MISC_DEVICES=y
956# CONFIG_EEPROM_93CX6 is not set
957
958#
959# Multifunction device drivers
960#
961# CONFIG_MFD_SM501 is not set
962# CONFIG_HTC_ASIC3 is not set
963# CONFIG_HTC_ASIC3_DS1WM is not set
964
965#
966# Multi-Function Devices
967#
968CONFIG_NEW_LEDS=y
969CONFIG_LEDS_CLASS=y
970
971#
972# LED drivers
973#
974CONFIG_LEDS_CORGI=y
975# CONFIG_LEDS_TOSA is not set
976# CONFIG_LEDS_GPIO is not set
977
978#
979# LED Triggers
980#
981CONFIG_LEDS_TRIGGERS=y
982CONFIG_LEDS_TRIGGER_TIMER=y
983CONFIG_LEDS_TRIGGER_IDE_DISK=y
984# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
985
986#
987# Multimedia devices
988#
989CONFIG_VIDEO_DEV=m
990CONFIG_VIDEO_V4L1=y
991CONFIG_VIDEO_V4L1_COMPAT=y
992CONFIG_VIDEO_V4L2=y
993CONFIG_VIDEO_CAPTURE_DRIVERS=y
994# CONFIG_VIDEO_ADV_DEBUG is not set
995CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
996# CONFIG_VIDEO_CPIA is not set
997# CONFIG_VIDEO_CPIA2 is not set
998# CONFIG_VIDEO_SAA5246A is not set
999# CONFIG_VIDEO_SAA5249 is not set
1000# CONFIG_TUNER_3036 is not set
1001# CONFIG_TUNER_TEA5761 is not set
1002CONFIG_V4L_USB_DRIVERS=y
1003# CONFIG_VIDEO_PVRUSB2 is not set
1004# CONFIG_VIDEO_EM28XX is not set
1005# CONFIG_VIDEO_USBVISION is not set
1006CONFIG_VIDEO_USBVIDEO=m
1007CONFIG_USB_VICAM=m
1008CONFIG_USB_IBMCAM=m
1009CONFIG_USB_KONICAWC=m
1010# CONFIG_USB_QUICKCAM_MESSENGER is not set
1011# CONFIG_USB_ET61X251 is not set
1012# CONFIG_VIDEO_OVCAMCHIP is not set
1013# CONFIG_USB_W9968CF is not set
1014CONFIG_USB_OV511=m
1015CONFIG_USB_SE401=m
1016CONFIG_USB_SN9C102=m
1017CONFIG_USB_STV680=m
1018# CONFIG_USB_ZC0301 is not set
1019# CONFIG_USB_PWC is not set
1020# CONFIG_USB_ZR364XX is not set
1021CONFIG_RADIO_ADAPTERS=y
1022CONFIG_USB_DSBR=m
1023# CONFIG_DVB_CORE is not set
1024CONFIG_DAB=y
1025CONFIG_USB_DABUSB=m
1026
1027#
1028# Graphics support
1029#
1030CONFIG_BACKLIGHT_LCD_SUPPORT=y
1031# CONFIG_LCD_CLASS_DEVICE is not set
1032CONFIG_BACKLIGHT_CLASS_DEVICE=y
1033CONFIG_BACKLIGHT_CORGI=y
1034
1035#
1036# Display device support
1037#
1038# CONFIG_DISPLAY_SUPPORT is not set
1039# CONFIG_VGASTATE is not set
1040CONFIG_VIDEO_OUTPUT_CONTROL=m
1041CONFIG_FB=y
1042CONFIG_FIRMWARE_EDID=y
1043# CONFIG_FB_DDC is not set
1044CONFIG_FB_CFB_FILLRECT=y
1045CONFIG_FB_CFB_COPYAREA=y
1046CONFIG_FB_CFB_IMAGEBLIT=y
1047# CONFIG_FB_SYS_FILLRECT is not set
1048# CONFIG_FB_SYS_COPYAREA is not set
1049# CONFIG_FB_SYS_IMAGEBLIT is not set
1050# CONFIG_FB_SYS_FOPS is not set
1051CONFIG_FB_DEFERRED_IO=y
1052# CONFIG_FB_SVGALIB is not set
1053# CONFIG_FB_MACMODES is not set
1054# CONFIG_FB_BACKLIGHT is not set
1055# CONFIG_FB_MODE_HELPERS is not set
1056# CONFIG_FB_TILEBLITTING is not set
1057
1058#
1059# Frame buffer hardware drivers
1060#
1061# CONFIG_FB_S1D13XXX is not set
1062# CONFIG_FB_PXA is not set
1063# CONFIG_FB_MBX is not set
1064CONFIG_FB_W100=y
1065# CONFIG_FB_VIRTUAL is not set
1066
1067#
1068# Console display driver support
1069#
1070# CONFIG_VGA_CONSOLE is not set
1071CONFIG_DUMMY_CONSOLE=y
1072CONFIG_FRAMEBUFFER_CONSOLE=y
1073# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1074# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1075CONFIG_FONTS=y
1076# CONFIG_FONT_8x8 is not set
1077CONFIG_FONT_8x16=y
1078# CONFIG_FONT_6x11 is not set
1079# CONFIG_FONT_7x14 is not set
1080# CONFIG_FONT_PEARL_8x8 is not set
1081# CONFIG_FONT_ACORN_8x8 is not set
1082# CONFIG_FONT_MINI_4x6 is not set
1083# CONFIG_FONT_SUN8x16 is not set
1084# CONFIG_FONT_SUN12x22 is not set
1085# CONFIG_FONT_10x18 is not set
1086CONFIG_LOGO=y
1087# CONFIG_LOGO_LINUX_MONO is not set
1088# CONFIG_LOGO_LINUX_VGA16 is not set
1089# CONFIG_LOGO_LINUX_CLUT224 is not set
1090CONFIG_LOGO_OHAND_CLUT224=y
1091# CONFIG_LOGO_OZ240_CLUT224 is not set
1092# CONFIG_LOGO_OZ480_CLUT224 is not set
1093# CONFIG_LOGO_OZ640_CLUT224 is not set
1094
1095#
1096# Sound
1097#
1098CONFIG_SOUND=m
1099
1100#
1101# Advanced Linux Sound Architecture
1102#
1103CONFIG_SND=m
1104CONFIG_SND_TIMER=m
1105CONFIG_SND_PCM=m
1106CONFIG_SND_HWDEP=m
1107CONFIG_SND_RAWMIDI=m
1108CONFIG_SND_SEQUENCER=m
1109# CONFIG_SND_SEQ_DUMMY is not set
1110CONFIG_SND_OSSEMUL=y
1111CONFIG_SND_MIXER_OSS=m
1112CONFIG_SND_PCM_OSS=m
1113CONFIG_SND_PCM_OSS_PLUGINS=y
1114# CONFIG_SND_SEQUENCER_OSS is not set
1115# CONFIG_SND_DYNAMIC_MINORS is not set
1116CONFIG_SND_SUPPORT_OLD_API=y
1117CONFIG_SND_VERBOSE_PROCFS=y
1118CONFIG_SND_VERBOSE_PRINTK=y
1119CONFIG_SND_DEBUG=y
1120# CONFIG_SND_DEBUG_DETECT is not set
1121# CONFIG_SND_PCM_XRUN_DEBUG is not set
1122
1123#
1124# Generic devices
1125#
1126CONFIG_SND_AC97_CODEC=m
1127# CONFIG_SND_DUMMY is not set
1128# CONFIG_SND_VIRMIDI is not set
1129# CONFIG_SND_MTPAV is not set
1130# CONFIG_SND_SERIAL_U16550 is not set
1131# CONFIG_SND_MPU401 is not set
1132
1133#
1134# ALSA ARM devices
1135#
1136CONFIG_SND_PXA2XX_PCM=m
1137CONFIG_SND_PXA2XX_AC97=m
1138
1139#
1140# USB devices
1141#
1142CONFIG_SND_USB_AUDIO=m
1143# CONFIG_SND_USB_CAIAQ is not set
1144
1145#
1146# PCMCIA devices
1147#
1148# CONFIG_SND_VXPOCKET is not set
1149# CONFIG_SND_PDAUDIOCF is not set
1150
1151#
1152# System on Chip audio support
1153#
1154CONFIG_SND_SOC=m
1155CONFIG_SND_PXA2XX_SOC=m
1156CONFIG_SND_PXA2XX_SOC_I2S=m
1157CONFIG_SND_PXA2XX_SOC_CORGI=m
1158
1159#
1160# SoC Audio support for SuperH
1161#
1162CONFIG_SND_SOC_WM8731=m
1163
1164#
1165# Open Sound System
1166#
1167# CONFIG_SOUND_PRIME is not set
1168CONFIG_AC97_BUS=m
1169CONFIG_HID_SUPPORT=y
1170CONFIG_HID=m
1171# CONFIG_HID_DEBUG is not set
1172
1173#
1174# USB Input Devices
1175#
1176CONFIG_USB_HID=m
1177# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1178# CONFIG_HID_FF is not set
1179# CONFIG_USB_HIDDEV is not set
1180
1181#
1182# USB HID Boot Protocol drivers
1183#
1184CONFIG_USB_KBD=m
1185CONFIG_USB_MOUSE=m
1186CONFIG_USB_SUPPORT=y
1187CONFIG_USB_ARCH_HAS_HCD=y
1188# CONFIG_USB_ARCH_HAS_OHCI is not set
1189# CONFIG_USB_ARCH_HAS_EHCI is not set
1190CONFIG_USB=m
1191# CONFIG_USB_DEBUG is not set
1192
1193#
1194# Miscellaneous USB options
1195#
1196CONFIG_USB_DEVICEFS=y
1197CONFIG_USB_DEVICE_CLASS=y
1198# CONFIG_USB_DYNAMIC_MINORS is not set
1199# CONFIG_USB_SUSPEND is not set
1200# CONFIG_USB_PERSIST is not set
1201# CONFIG_USB_OTG is not set
1202
1203#
1204# USB Host Controller Drivers
1205#
1206# CONFIG_USB_ISP116X_HCD is not set
1207CONFIG_USB_SL811_HCD=m
1208CONFIG_USB_SL811_CS=m
1209# CONFIG_USB_R8A66597_HCD is not set
1210
1211#
1212# USB Device Class drivers
1213#
1214CONFIG_USB_ACM=m
1215CONFIG_USB_PRINTER=m
1216
1217#
1218# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1219#
1220
1221#
1222# may also be needed; see USB_STORAGE Help for more information
1223#
1224CONFIG_USB_STORAGE=m
1225# CONFIG_USB_STORAGE_DEBUG is not set
1226# CONFIG_USB_STORAGE_DATAFAB is not set
1227# CONFIG_USB_STORAGE_FREECOM is not set
1228# CONFIG_USB_STORAGE_ISD200 is not set
1229# CONFIG_USB_STORAGE_DPCM is not set
1230# CONFIG_USB_STORAGE_USBAT is not set
1231# CONFIG_USB_STORAGE_SDDR09 is not set
1232# CONFIG_USB_STORAGE_SDDR55 is not set
1233# CONFIG_USB_STORAGE_JUMPSHOT is not set
1234# CONFIG_USB_STORAGE_ALAUDA is not set
1235# CONFIG_USB_STORAGE_KARMA is not set
1236# CONFIG_USB_LIBUSUAL is not set
1237
1238#
1239# USB Imaging devices
1240#
1241CONFIG_USB_MDC800=m
1242CONFIG_USB_MICROTEK=m
1243CONFIG_USB_MON=y
1244
1245#
1246# USB port drivers
1247#
1248
1249#
1250# USB Serial Converter support
1251#
1252CONFIG_USB_SERIAL=m
1253CONFIG_USB_SERIAL_GENERIC=y
1254# CONFIG_USB_SERIAL_AIRCABLE is not set
1255# CONFIG_USB_SERIAL_AIRPRIME is not set
1256# CONFIG_USB_SERIAL_ARK3116 is not set
1257CONFIG_USB_SERIAL_BELKIN=m
1258# CONFIG_USB_SERIAL_WHITEHEAT is not set
1259CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1260# CONFIG_USB_SERIAL_CP2101 is not set
1261CONFIG_USB_SERIAL_CYPRESS_M8=m
1262CONFIG_USB_SERIAL_EMPEG=m
1263CONFIG_USB_SERIAL_FTDI_SIO=m
1264# CONFIG_USB_SERIAL_FUNSOFT is not set
1265CONFIG_USB_SERIAL_VISOR=m
1266CONFIG_USB_SERIAL_IPAQ=m
1267CONFIG_USB_SERIAL_IR=m
1268CONFIG_USB_SERIAL_EDGEPORT=m
1269CONFIG_USB_SERIAL_EDGEPORT_TI=m
1270CONFIG_USB_SERIAL_GARMIN=m
1271CONFIG_USB_SERIAL_IPW=m
1272CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1273CONFIG_USB_SERIAL_KEYSPAN=m
1274# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1275# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1276# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1277# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1278# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1279# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1280# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1281# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1282# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1283# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1284# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1285# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1286CONFIG_USB_SERIAL_KLSI=m
1287CONFIG_USB_SERIAL_KOBIL_SCT=m
1288CONFIG_USB_SERIAL_MCT_U232=m
1289# CONFIG_USB_SERIAL_MOS7720 is not set
1290# CONFIG_USB_SERIAL_MOS7840 is not set
1291# CONFIG_USB_SERIAL_NAVMAN is not set
1292CONFIG_USB_SERIAL_PL2303=m
1293# CONFIG_USB_SERIAL_OTI6858 is not set
1294# CONFIG_USB_SERIAL_HP4X is not set
1295CONFIG_USB_SERIAL_SAFE=m
1296# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1297# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1298CONFIG_USB_SERIAL_TI=m
1299CONFIG_USB_SERIAL_CYBERJACK=m
1300CONFIG_USB_SERIAL_XIRCOM=m
1301# CONFIG_USB_SERIAL_OPTION is not set
1302CONFIG_USB_SERIAL_OMNINET=m
1303# CONFIG_USB_SERIAL_DEBUG is not set
1304CONFIG_USB_EZUSB=y
1305
1306#
1307# USB Miscellaneous drivers
1308#
1309CONFIG_USB_EMI62=m
1310CONFIG_USB_EMI26=m
1311# CONFIG_USB_ADUTUX is not set
1312CONFIG_USB_AUERSWALD=m
1313CONFIG_USB_RIO500=m
1314CONFIG_USB_LEGOTOWER=m
1315CONFIG_USB_LCD=m
1316# CONFIG_USB_BERRY_CHARGE is not set
1317CONFIG_USB_LED=m
1318# CONFIG_USB_CYPRESS_CY7C63 is not set
1319CONFIG_USB_CYTHERM=m
1320# CONFIG_USB_PHIDGET is not set
1321CONFIG_USB_IDMOUSE=m
1322# CONFIG_USB_FTDI_ELAN is not set
1323# CONFIG_USB_APPLEDISPLAY is not set
1324# CONFIG_USB_LD is not set
1325# CONFIG_USB_TRANCEVIBRATOR is not set
1326# CONFIG_USB_IOWARRIOR is not set
1327# CONFIG_USB_TEST is not set
1328
1329#
1330# USB DSL modem support
1331#
1332
1333#
1334# USB Gadget Support
1335#
1336CONFIG_USB_GADGET=y
1337# CONFIG_USB_GADGET_DEBUG is not set
1338# CONFIG_USB_GADGET_DEBUG_FILES is not set
1339CONFIG_USB_GADGET_SELECTED=y
1340# CONFIG_USB_GADGET_AMD5536UDC is not set
1341# CONFIG_USB_GADGET_FSL_USB2 is not set
1342# CONFIG_USB_GADGET_NET2280 is not set
1343CONFIG_USB_GADGET_PXA2XX=y
1344CONFIG_USB_PXA2XX=y
1345# CONFIG_USB_PXA2XX_SMALL is not set
1346# CONFIG_USB_GADGET_M66592 is not set
1347# CONFIG_USB_GADGET_PXA27X is not set
1348# CONFIG_USB_GADGET_GOKU is not set
1349# CONFIG_USB_GADGET_LH7A40X is not set
1350# CONFIG_USB_GADGET_OMAP is not set
1351# CONFIG_USB_GADGET_S3C2410 is not set
1352# CONFIG_USB_GADGET_AT91 is not set
1353# CONFIG_USB_GADGET_DUMMY_HCD is not set
1354# CONFIG_USB_GADGET_DUALSPEED is not set
1355CONFIG_USB_ZERO=m
1356CONFIG_USB_ETH=m
1357CONFIG_USB_ETH_RNDIS=y
1358CONFIG_USB_GADGETFS=m
1359CONFIG_USB_FILE_STORAGE=m
1360# CONFIG_USB_FILE_STORAGE_TEST is not set
1361CONFIG_USB_G_SERIAL=m
1362# CONFIG_USB_MIDI_GADGET is not set
1363CONFIG_MMC=y
1364# CONFIG_MMC_DEBUG is not set
1365CONFIG_MMC_UNSAFE_RESUME=y
1366
1367#
1368# MMC/SD Card Drivers
1369#
1370CONFIG_MMC_BLOCK=y
1371CONFIG_MMC_BLOCK_BOUNCE=y
1372
1373#
1374# MMC/SD Host Controller Drivers
1375#
1376CONFIG_MMC_PXA=y
1377CONFIG_RTC_LIB=y
1378CONFIG_RTC_CLASS=y
1379CONFIG_RTC_HCTOSYS=y
1380CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1381# CONFIG_RTC_DEBUG is not set
1382
1383#
1384# RTC interfaces
1385#
1386CONFIG_RTC_INTF_SYSFS=y
1387CONFIG_RTC_INTF_PROC=y
1388CONFIG_RTC_INTF_DEV=y
1389# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1390# CONFIG_RTC_DRV_TEST is not set
1391
1392#
1393# I2C RTC drivers
1394#
1395# CONFIG_RTC_DRV_DS1307 is not set
1396# CONFIG_RTC_DRV_DS1672 is not set
1397# CONFIG_RTC_DRV_MAX6900 is not set
1398# CONFIG_RTC_DRV_RS5C372 is not set
1399# CONFIG_RTC_DRV_ISL1208 is not set
1400# CONFIG_RTC_DRV_X1205 is not set
1401# CONFIG_RTC_DRV_PCF8563 is not set
1402# CONFIG_RTC_DRV_PCF8583 is not set
1403# CONFIG_RTC_DRV_M41T80 is not set
1404
1405#
1406# SPI RTC drivers
1407#
1408
1409#
1410# Platform RTC drivers
1411#
1412# CONFIG_RTC_DRV_CMOS is not set
1413# CONFIG_RTC_DRV_DS1553 is not set
1414# CONFIG_RTC_DRV_STK17TA8 is not set
1415# CONFIG_RTC_DRV_DS1742 is not set
1416# CONFIG_RTC_DRV_M48T86 is not set
1417# CONFIG_RTC_DRV_M48T59 is not set
1418# CONFIG_RTC_DRV_V3020 is not set
1419
1420#
1421# on-CPU RTC drivers
1422#
1423CONFIG_RTC_DRV_SA1100=y
1424
1425#
1426# DMA Engine support
1427#
1428# CONFIG_DMA_ENGINE is not set
1429
1430#
1431# DMA Clients
1432#
1433
1434#
1435# DMA Devices
1436#
1437
1438#
1439# File systems
1440#
1441CONFIG_EXT2_FS=y
1442# CONFIG_EXT2_FS_XATTR is not set
1443# CONFIG_EXT2_FS_XIP is not set
1444CONFIG_EXT3_FS=m
1445# CONFIG_EXT4DEV_FS is not set
1446# CONFIG_REISERFS_FS is not set
1447# CONFIG_JFS_FS is not set
1448CONFIG_FS_POSIX_ACL=y
1449# CONFIG_XFS_FS is not set
1450# CONFIG_GFS2_FS is not set
1451# CONFIG_OCFS2_FS is not set
1452# CONFIG_MINIX_FS is not set
1453# CONFIG_ROMFS_FS is not set
1454CONFIG_INOTIFY=y
1455CONFIG_INOTIFY_USER=y
1456# CONFIG_QUOTA is not set
1457CONFIG_DNOTIFY=y
1458# CONFIG_AUTOFS_FS is not set
1459# CONFIG_AUTOFS4_FS is not set
1460# CONFIG_FUSE_FS is not set
1461
1462#
1463# CD-ROM/DVD Filesystems
1464#
1465# CONFIG_ISO9660_FS is not set
1466# CONFIG_UDF_FS is not set
1467
1468#
1469# DOS/FAT/NT Filesystems
1470#
1471CONFIG_FAT_FS=y
1472# CONFIG_MSDOS_FS is not set
1473CONFIG_VFAT_FS=y
1474CONFIG_FAT_DEFAULT_CODEPAGE=437
1475CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1476# CONFIG_NTFS_FS is not set
1477
1478#
1479# Pseudo filesystems
1480#
1481CONFIG_PROC_FS=y
1482CONFIG_PROC_SYSCTL=y
1483CONFIG_SYSFS=y
1484CONFIG_TMPFS=y
1485# CONFIG_TMPFS_POSIX_ACL is not set
1486# CONFIG_HUGETLB_PAGE is not set
1487CONFIG_RAMFS=y
1488# CONFIG_CONFIGFS_FS is not set
1489
1490#
1491# Miscellaneous filesystems
1492#
1493# CONFIG_ADFS_FS is not set
1494# CONFIG_AFFS_FS is not set
1495# CONFIG_HFS_FS is not set
1496# CONFIG_HFSPLUS_FS is not set
1497# CONFIG_BEFS_FS is not set
1498# CONFIG_BFS_FS is not set
1499# CONFIG_EFS_FS is not set
1500CONFIG_JFFS2_FS=y
1501CONFIG_JFFS2_FS_DEBUG=0
1502CONFIG_JFFS2_FS_WRITEBUFFER=y
1503CONFIG_JFFS2_SUMMARY=y
1504# CONFIG_JFFS2_FS_XATTR is not set
1505# CONFIG_JFFS2_SYSFS is not set
1506CONFIG_JFFS2_COMPRESSION_OPTIONS=y
1507CONFIG_JFFS2_ZLIB=y
1508CONFIG_JFFS2_LZO=y
1509CONFIG_JFFS2_RTIME=y
1510CONFIG_JFFS2_RUBIN=y
1511# CONFIG_JFFS2_CMODE_NONE is not set
1512CONFIG_JFFS2_CMODE_PRIORITY=y
1513# CONFIG_JFFS2_CMODE_SIZE is not set
1514# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
1515CONFIG_CRAMFS=m
1516CONFIG_SQUASHFS=m
1517# CONFIG_SQUASHFS_EMBEDDED is not set
1518CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1519# CONFIG_SQUASHFS_VMALLOC is not set
1520# CONFIG_VXFS_FS is not set
1521# CONFIG_HPFS_FS is not set
1522# CONFIG_QNX4FS_FS is not set
1523# CONFIG_SYSV_FS is not set
1524# CONFIG_UFS_FS is not set
1525
1526#
1527# Network File Systems
1528#
1529CONFIG_NFS_FS=m
1530CONFIG_NFS_V3=y
1531# CONFIG_NFS_V3_ACL is not set
1532CONFIG_NFS_V4=y
1533# CONFIG_NFS_DIRECTIO is not set
1534CONFIG_NFSD=m
1535CONFIG_NFSD_V3=y
1536# CONFIG_NFSD_V3_ACL is not set
1537CONFIG_NFSD_V4=y
1538CONFIG_NFSD_TCP=y
1539CONFIG_LOCKD=m
1540CONFIG_LOCKD_V4=y
1541CONFIG_EXPORTFS=m
1542CONFIG_NFS_COMMON=y
1543CONFIG_SUNRPC=m
1544CONFIG_SUNRPC_GSS=m
1545# CONFIG_SUNRPC_BIND34 is not set
1546CONFIG_RPCSEC_GSS_KRB5=m
1547# CONFIG_RPCSEC_GSS_SPKM3 is not set
1548CONFIG_SMB_FS=m
1549CONFIG_SMB_NLS_DEFAULT=y
1550CONFIG_SMB_NLS_REMOTE="cp437"
1551CONFIG_CIFS=m
1552# CONFIG_CIFS_STATS is not set
1553# CONFIG_CIFS_WEAK_PW_HASH is not set
1554# CONFIG_CIFS_XATTR is not set
1555# CONFIG_CIFS_DEBUG2 is not set
1556# CONFIG_CIFS_EXPERIMENTAL is not set
1557# CONFIG_NCP_FS is not set
1558# CONFIG_CODA_FS is not set
1559# CONFIG_AFS_FS is not set
1560
1561#
1562# Partition Types
1563#
1564CONFIG_PARTITION_ADVANCED=y
1565# CONFIG_ACORN_PARTITION is not set
1566# CONFIG_OSF_PARTITION is not set
1567# CONFIG_AMIGA_PARTITION is not set
1568# CONFIG_ATARI_PARTITION is not set
1569# CONFIG_MAC_PARTITION is not set
1570CONFIG_MSDOS_PARTITION=y
1571# CONFIG_BSD_DISKLABEL is not set
1572# CONFIG_MINIX_SUBPARTITION is not set
1573# CONFIG_SOLARIS_X86_PARTITION is not set
1574# CONFIG_UNIXWARE_DISKLABEL is not set
1575# CONFIG_LDM_PARTITION is not set
1576# CONFIG_SGI_PARTITION is not set
1577# CONFIG_ULTRIX_PARTITION is not set
1578# CONFIG_SUN_PARTITION is not set
1579# CONFIG_KARMA_PARTITION is not set
1580# CONFIG_EFI_PARTITION is not set
1581# CONFIG_SYSV68_PARTITION is not set
1582
1583#
1584# Native Language Support
1585#
1586CONFIG_NLS=y
1587CONFIG_NLS_DEFAULT="cp437"
1588CONFIG_NLS_CODEPAGE_437=y
1589CONFIG_NLS_CODEPAGE_737=m
1590CONFIG_NLS_CODEPAGE_775=m
1591CONFIG_NLS_CODEPAGE_850=m
1592CONFIG_NLS_CODEPAGE_852=m
1593CONFIG_NLS_CODEPAGE_855=m
1594CONFIG_NLS_CODEPAGE_857=m
1595CONFIG_NLS_CODEPAGE_860=m
1596CONFIG_NLS_CODEPAGE_861=m
1597CONFIG_NLS_CODEPAGE_862=m
1598CONFIG_NLS_CODEPAGE_863=m
1599CONFIG_NLS_CODEPAGE_864=m
1600CONFIG_NLS_CODEPAGE_865=m
1601CONFIG_NLS_CODEPAGE_866=m
1602CONFIG_NLS_CODEPAGE_869=m
1603CONFIG_NLS_CODEPAGE_936=m
1604CONFIG_NLS_CODEPAGE_950=m
1605CONFIG_NLS_CODEPAGE_932=m
1606CONFIG_NLS_CODEPAGE_949=m
1607CONFIG_NLS_CODEPAGE_874=m
1608CONFIG_NLS_ISO8859_8=m
1609CONFIG_NLS_CODEPAGE_1250=m
1610CONFIG_NLS_CODEPAGE_1251=m
1611CONFIG_NLS_ASCII=m
1612CONFIG_NLS_ISO8859_1=y
1613CONFIG_NLS_ISO8859_2=m
1614CONFIG_NLS_ISO8859_3=m
1615CONFIG_NLS_ISO8859_4=m
1616CONFIG_NLS_ISO8859_5=m
1617CONFIG_NLS_ISO8859_6=m
1618CONFIG_NLS_ISO8859_7=m
1619CONFIG_NLS_ISO8859_9=m
1620CONFIG_NLS_ISO8859_13=m
1621CONFIG_NLS_ISO8859_14=m
1622CONFIG_NLS_ISO8859_15=m
1623CONFIG_NLS_KOI8_R=m
1624CONFIG_NLS_KOI8_U=m
1625CONFIG_NLS_UTF8=y
1626
1627#
1628# Distributed Lock Manager
1629#
1630# CONFIG_DLM is not set
1631
1632#
1633# Profiling support
1634#
1635CONFIG_PROFILING=y
1636CONFIG_OPROFILE=m
1637
1638#
1639# Kernel hacking
1640#
1641# CONFIG_PRINTK_TIME is not set
1642CONFIG_ENABLE_MUST_CHECK=y
1643CONFIG_MAGIC_SYSRQ=y
1644# CONFIG_UNUSED_SYMBOLS is not set
1645# CONFIG_DEBUG_FS is not set
1646# CONFIG_HEADERS_CHECK is not set
1647CONFIG_DEBUG_KERNEL=y
1648# CONFIG_DEBUG_SHIRQ is not set
1649CONFIG_DETECT_SOFTLOCKUP=y
1650CONFIG_SCHED_DEBUG=y
1651# CONFIG_SCHEDSTATS is not set
1652CONFIG_TIMER_STATS=y
1653# CONFIG_DEBUG_SLAB is not set
1654# CONFIG_DEBUG_PREEMPT is not set
1655# CONFIG_DEBUG_RT_MUTEXES is not set
1656# CONFIG_RT_MUTEX_TESTER is not set
1657# CONFIG_DEBUG_SPINLOCK is not set
1658# CONFIG_DEBUG_MUTEXES is not set
1659# CONFIG_DEBUG_LOCK_ALLOC is not set
1660# CONFIG_PROVE_LOCKING is not set
1661# CONFIG_LOCK_STAT is not set
1662# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1663# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1664# CONFIG_DEBUG_KOBJECT is not set
1665CONFIG_DEBUG_BUGVERBOSE=y
1666# CONFIG_DEBUG_INFO is not set
1667# CONFIG_DEBUG_VM is not set
1668# CONFIG_DEBUG_LIST is not set
1669CONFIG_FRAME_POINTER=y
1670# CONFIG_FORCED_INLINING is not set
1671# CONFIG_RCU_TORTURE_TEST is not set
1672# CONFIG_FAULT_INJECTION is not set
1673# CONFIG_DEBUG_USER is not set
1674CONFIG_DEBUG_ERRORS=y
1675# CONFIG_DEBUG_LL is not set
1676
1677#
1678# Security options
1679#
1680# CONFIG_KEYS is not set
1681# CONFIG_SECURITY is not set
1682CONFIG_CRYPTO=y
1683CONFIG_CRYPTO_ALGAPI=y
1684CONFIG_CRYPTO_BLKCIPHER=m
1685CONFIG_CRYPTO_HASH=y
1686CONFIG_CRYPTO_MANAGER=y
1687CONFIG_CRYPTO_HMAC=y
1688# CONFIG_CRYPTO_XCBC is not set
1689CONFIG_CRYPTO_NULL=m
1690CONFIG_CRYPTO_MD4=m
1691CONFIG_CRYPTO_MD5=m
1692CONFIG_CRYPTO_SHA1=m
1693CONFIG_CRYPTO_SHA256=m
1694CONFIG_CRYPTO_SHA512=m
1695CONFIG_CRYPTO_WP512=m
1696# CONFIG_CRYPTO_TGR192 is not set
1697# CONFIG_CRYPTO_GF128MUL is not set
1698CONFIG_CRYPTO_ECB=m
1699CONFIG_CRYPTO_CBC=m
1700CONFIG_CRYPTO_PCBC=m
1701# CONFIG_CRYPTO_LRW is not set
1702# CONFIG_CRYPTO_CRYPTD is not set
1703CONFIG_CRYPTO_DES=m
1704# CONFIG_CRYPTO_FCRYPT is not set
1705CONFIG_CRYPTO_BLOWFISH=m
1706CONFIG_CRYPTO_TWOFISH=m
1707CONFIG_CRYPTO_TWOFISH_COMMON=m
1708CONFIG_CRYPTO_SERPENT=m
1709CONFIG_CRYPTO_AES=m
1710CONFIG_CRYPTO_CAST5=m
1711CONFIG_CRYPTO_CAST6=m
1712CONFIG_CRYPTO_TEA=m
1713CONFIG_CRYPTO_ARC4=m
1714CONFIG_CRYPTO_KHAZAD=m
1715CONFIG_CRYPTO_ANUBIS=m
1716CONFIG_CRYPTO_DEFLATE=m
1717# CONFIG_CRYPTO_LZO is not set
1718CONFIG_CRYPTO_MICHAEL_MIC=m
1719CONFIG_CRYPTO_CRC32C=m
1720# CONFIG_CRYPTO_CAMELLIA is not set
1721CONFIG_CRYPTO_TEST=m
1722CONFIG_CRYPTO_HW=y
1723
1724#
1725# Library routines
1726#
1727CONFIG_BITREVERSE=y
1728CONFIG_CRC_CCITT=y
1729# CONFIG_CRC16 is not set
1730# CONFIG_CRC_ITU_T is not set
1731CONFIG_CRC32=y
1732# CONFIG_CRC7 is not set
1733CONFIG_LIBCRC32C=m
1734CONFIG_ZLIB_INFLATE=y
1735CONFIG_ZLIB_DEFLATE=y
1736CONFIG_LZO_COMPRESS=y
1737CONFIG_LZO_DECOMPRESS=y
1738CONFIG_PLIST=y
1739CONFIG_HAS_IOMEM=y
1740CONFIG_HAS_IOPORT=y
1741CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-collie b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-collie
new file mode 100644
index 0000000000..64e5090ae6
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-collie
@@ -0,0 +1,1790 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20.4
4# Fri Apr 6 23:20:59 2007
5#
6CONFIG_ARM=y
7# CONFIG_GENERIC_TIME is not set
8CONFIG_MMU=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_TRACE_IRQFLAGS_SUPPORT=y
11CONFIG_HARDIRQS_SW_RESEND=y
12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_RWSEM_GENERIC_SPINLOCK=y
14# CONFIG_ARCH_HAS_ILOG2_U32 is not set
15# CONFIG_ARCH_HAS_ILOG2_U64 is not set
16CONFIG_GENERIC_HWEIGHT=y
17CONFIG_GENERIC_CALIBRATE_DELAY=y
18CONFIG_ARCH_MTD_XIP=y
19CONFIG_VECTORS_BASE=0xffff0000
20CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
21
22#
23# Code maturity level options
24#
25CONFIG_EXPERIMENTAL=y
26CONFIG_BROKEN_ON_SMP=y
27CONFIG_LOCK_KERNEL=y
28CONFIG_INIT_ENV_ARG_LIMIT=32
29
30#
31# General setup
32#
33CONFIG_LOCALVERSION=""
34# CONFIG_LOCALVERSION_AUTO is not set
35CONFIG_SWAP=y
36CONFIG_SYSVIPC=y
37# CONFIG_IPC_NS is not set
38# CONFIG_POSIX_MQUEUE is not set
39CONFIG_BSD_PROCESS_ACCT=y
40CONFIG_BSD_PROCESS_ACCT_V3=y
41# CONFIG_TASKSTATS is not set
42# CONFIG_UTS_NS is not set
43# CONFIG_AUDIT is not set
44# CONFIG_IKCONFIG is not set
45# CONFIG_SYSFS_DEPRECATED is not set
46# CONFIG_RELAY is not set
47CONFIG_INITRAMFS_SOURCE=""
48CONFIG_CC_OPTIMIZE_FOR_SIZE=y
49CONFIG_SYSCTL=y
50CONFIG_EMBEDDED=y
51CONFIG_UID16=y
52CONFIG_SYSCTL_SYSCALL=y
53CONFIG_KALLSYMS=y
54# CONFIG_KALLSYMS_ALL is not set
55# CONFIG_KALLSYMS_EXTRA_PASS is not set
56CONFIG_HOTPLUG=y
57CONFIG_PRINTK=y
58CONFIG_BUG=y
59# CONFIG_ELF_CORE is not set
60CONFIG_BASE_FULL=y
61CONFIG_FUTEX=y
62CONFIG_EPOLL=y
63CONFIG_SHMEM=y
64CONFIG_SLAB=y
65CONFIG_VM_EVENT_COUNTERS=y
66CONFIG_RT_MUTEXES=y
67# CONFIG_TINY_SHMEM is not set
68CONFIG_BASE_SMALL=0
69# CONFIG_SLOB is not set
70
71#
72# Loadable module support
73#
74CONFIG_MODULES=y
75CONFIG_MODULE_UNLOAD=y
76CONFIG_MODULE_FORCE_UNLOAD=y
77# CONFIG_MODVERSIONS is not set
78# CONFIG_MODULE_SRCVERSION_ALL is not set
79CONFIG_KMOD=y
80
81#
82# Block layer
83#
84CONFIG_BLOCK=y
85# CONFIG_LBD is not set
86# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set
88
89#
90# IO Schedulers
91#
92CONFIG_IOSCHED_NOOP=y
93CONFIG_IOSCHED_AS=y
94CONFIG_IOSCHED_DEADLINE=m
95CONFIG_IOSCHED_CFQ=m
96CONFIG_DEFAULT_AS=y
97# CONFIG_DEFAULT_DEADLINE is not set
98# CONFIG_DEFAULT_CFQ is not set
99# CONFIG_DEFAULT_NOOP is not set
100CONFIG_DEFAULT_IOSCHED="anticipatory"
101
102#
103# System Type
104#
105# CONFIG_ARCH_AAEC2000 is not set
106# CONFIG_ARCH_INTEGRATOR is not set
107# CONFIG_ARCH_REALVIEW is not set
108# CONFIG_ARCH_VERSATILE is not set
109# CONFIG_ARCH_AT91 is not set
110# CONFIG_ARCH_CLPS7500 is not set
111# CONFIG_ARCH_CLPS711X is not set
112# CONFIG_ARCH_CO285 is not set
113# CONFIG_ARCH_EBSA110 is not set
114# CONFIG_ARCH_EP93XX is not set
115# CONFIG_ARCH_FOOTBRIDGE is not set
116# CONFIG_ARCH_NETX is not set
117# CONFIG_ARCH_H720X is not set
118# CONFIG_ARCH_IMX is not set
119# CONFIG_ARCH_IOP32X is not set
120# CONFIG_ARCH_IOP33X is not set
121# CONFIG_ARCH_IOP13XX is not set
122# CONFIG_ARCH_IXP4XX is not set
123# CONFIG_ARCH_IXP2000 is not set
124# CONFIG_ARCH_IXP23XX is not set
125# CONFIG_ARCH_L7200 is not set
126# CONFIG_ARCH_PNX4008 is not set
127# CONFIG_ARCH_PXA is not set
128# CONFIG_ARCH_RPC is not set
129CONFIG_ARCH_SA1100=y
130# CONFIG_ARCH_S3C2410 is not set
131# CONFIG_ARCH_SHARK is not set
132# CONFIG_ARCH_LH7A40X is not set
133# CONFIG_ARCH_OMAP is not set
134
135#
136# SA11x0 Implementations
137#
138# CONFIG_SA1100_ASSABET is not set
139# CONFIG_SA1100_CERF is not set
140CONFIG_SA1100_COLLIE=y
141# CONFIG_SA1100_H3100 is not set
142# CONFIG_SA1100_H3600 is not set
143# CONFIG_SA1100_H3800 is not set
144# CONFIG_SA1100_BADGE4 is not set
145# CONFIG_SA1100_JORNADA720 is not set
146# CONFIG_SA1100_HACKKIT is not set
147# CONFIG_SA1100_LART is not set
148# CONFIG_SA1100_PLEB is not set
149# CONFIG_SA1100_SHANNON is not set
150# CONFIG_SA1100_SIMPAD is not set
151# CONFIG_SA1100_SSP is not set
152
153#
154# Processor Type
155#
156CONFIG_CPU_32=y
157CONFIG_CPU_SA1100=y
158CONFIG_CPU_32v4=y
159CONFIG_CPU_ABRT_EV4=y
160CONFIG_CPU_CACHE_V4WB=y
161CONFIG_CPU_CACHE_VIVT=y
162CONFIG_CPU_TLB_V4WB=y
163CONFIG_CPU_CP15=y
164CONFIG_CPU_CP15_MMU=y
165
166#
167# Processor Features
168#
169# CONFIG_CPU_ICACHE_DISABLE is not set
170# CONFIG_CPU_DCACHE_DISABLE is not set
171CONFIG_SHARP_LOCOMO=y
172CONFIG_SHARP_PARAM=y
173CONFIG_SHARP_SCOOP=y
174
175#
176# Bus support
177#
178CONFIG_ISA=y
179
180#
181# PCCARD (PCMCIA/CardBus) support
182#
183CONFIG_PCCARD=y
184# CONFIG_PCMCIA_DEBUG is not set
185CONFIG_PCMCIA=y
186CONFIG_PCMCIA_LOAD_CIS=y
187CONFIG_PCMCIA_IOCTL=y
188
189#
190# PC-card bridges
191#
192# CONFIG_I82365 is not set
193# CONFIG_TCIC is not set
194CONFIG_PCMCIA_SA1100=y
195
196#
197# Kernel Features
198#
199CONFIG_PREEMPT=y
200CONFIG_NO_IDLE_HZ=y
201CONFIG_HZ=100
202# CONFIG_AEABI is not set
203CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
204CONFIG_NODES_SHIFT=2
205CONFIG_SELECT_MEMORY_MODEL=y
206# CONFIG_FLATMEM_MANUAL is not set
207CONFIG_DISCONTIGMEM_MANUAL=y
208# CONFIG_SPARSEMEM_MANUAL is not set
209CONFIG_DISCONTIGMEM=y
210CONFIG_FLAT_NODE_MEM_MAP=y
211CONFIG_NEED_MULTIPLE_NODES=y
212# CONFIG_SPARSEMEM_STATIC is not set
213CONFIG_SPLIT_PTLOCK_CPUS=4096
214# CONFIG_RESOURCES_64BIT is not set
215# CONFIG_LEDS is not set
216CONFIG_ALIGNMENT_TRAP=y
217
218#
219# Boot options
220#
221CONFIG_ZBOOT_ROM_TEXT=0x0
222CONFIG_ZBOOT_ROM_BSS=0x0
223# CONFIG_XIP_KERNEL is not set
224CONFIG_KEXEC=y
225CONFIG_ATAGS_PROC=y
226
227#
228# CPU Frequency scaling
229#
230# CONFIG_CPU_FREQ is not set
231
232#
233# Floating point emulation
234#
235
236#
237# At least one emulation must be selected
238#
239CONFIG_FPE_NWFPE=y
240# CONFIG_FPE_NWFPE_XP is not set
241# CONFIG_FPE_FASTFPE is not set
242
243#
244# Userspace binary formats
245#
246CONFIG_BINFMT_ELF=y
247CONFIG_BINFMT_AOUT=m
248CONFIG_BINFMT_MISC=m
249# CONFIG_ARTHUR is not set
250
251#
252# Power management options
253#
254CONFIG_PM=y
255# CONFIG_PM_LEGACY is not set
256# CONFIG_PM_DEBUG is not set
257# CONFIG_PM_SYSFS_DEPRECATED is not set
258CONFIG_APM=y
259
260#
261# Networking
262#
263CONFIG_NET=y
264
265#
266# Networking options
267#
268# CONFIG_NETDEBUG is not set
269CONFIG_PACKET=m
270CONFIG_PACKET_MMAP=y
271CONFIG_UNIX=y
272CONFIG_XFRM=y
273CONFIG_XFRM_USER=m
274# CONFIG_XFRM_SUB_POLICY is not set
275# CONFIG_NET_KEY is not set
276CONFIG_INET=y
277# CONFIG_IP_MULTICAST is not set
278# CONFIG_IP_ADVANCED_ROUTER is not set
279CONFIG_IP_FIB_HASH=y
280# CONFIG_IP_PNP is not set
281# CONFIG_NET_IPIP is not set
282# CONFIG_NET_IPGRE is not set
283# CONFIG_ARPD is not set
284CONFIG_SYN_COOKIES=y
285# CONFIG_INET_AH is not set
286# CONFIG_INET_ESP is not set
287# CONFIG_INET_IPCOMP is not set
288# CONFIG_INET_XFRM_TUNNEL is not set
289# CONFIG_INET_TUNNEL is not set
290CONFIG_INET_XFRM_MODE_TRANSPORT=y
291CONFIG_INET_XFRM_MODE_TUNNEL=y
292CONFIG_INET_XFRM_MODE_BEET=y
293CONFIG_INET_DIAG=m
294CONFIG_INET_TCP_DIAG=m
295# CONFIG_TCP_CONG_ADVANCED is not set
296CONFIG_TCP_CONG_CUBIC=y
297CONFIG_DEFAULT_TCP_CONG="cubic"
298# CONFIG_TCP_MD5SIG is not set
299
300#
301# IP: Virtual Server Configuration
302#
303# CONFIG_IP_VS is not set
304CONFIG_IPV6=m
305# CONFIG_IPV6_PRIVACY is not set
306# CONFIG_IPV6_ROUTER_PREF is not set
307CONFIG_INET6_AH=m
308CONFIG_INET6_ESP=m
309CONFIG_INET6_IPCOMP=m
310# CONFIG_IPV6_MIP6 is not set
311CONFIG_INET6_XFRM_TUNNEL=m
312CONFIG_INET6_TUNNEL=m
313CONFIG_INET6_XFRM_MODE_TRANSPORT=m
314CONFIG_INET6_XFRM_MODE_TUNNEL=m
315CONFIG_INET6_XFRM_MODE_BEET=m
316# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
317CONFIG_IPV6_SIT=m
318CONFIG_IPV6_TUNNEL=m
319# CONFIG_IPV6_MULTIPLE_TABLES is not set
320# CONFIG_NETWORK_SECMARK is not set
321CONFIG_NETFILTER=y
322# CONFIG_NETFILTER_DEBUG is not set
323
324#
325# Core Netfilter Configuration
326#
327# CONFIG_NETFILTER_NETLINK is not set
328# CONFIG_NF_CONNTRACK_ENABLED is not set
329# CONFIG_NF_CONNTRACK is not set
330CONFIG_NETFILTER_XTABLES=m
331# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
332# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
333# CONFIG_NETFILTER_XT_TARGET_MARK is not set
334# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
335# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
336# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
337# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
338# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
339# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
340# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
341# CONFIG_NETFILTER_XT_MATCH_ESP is not set
342# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
343# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
344# CONFIG_NETFILTER_XT_MATCH_MAC is not set
345# CONFIG_NETFILTER_XT_MATCH_MARK is not set
346# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
347# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
348# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
349# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
350# CONFIG_NETFILTER_XT_MATCH_REALM is not set
351# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
352# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
353# CONFIG_NETFILTER_XT_MATCH_STRING is not set
354# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
355# CONFIG_NETFILTER_XT_MATCH_U32 is not set
356# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
357
358#
359# IP: Netfilter Configuration
360#
361CONFIG_IP_NF_QUEUE=m
362CONFIG_IP_NF_IPTABLES=m
363CONFIG_IP_NF_MATCH_IPRANGE=m
364CONFIG_IP_NF_MATCH_TOS=m
365CONFIG_IP_NF_MATCH_RECENT=m
366CONFIG_IP_NF_MATCH_ECN=m
367CONFIG_IP_NF_MATCH_AH=m
368CONFIG_IP_NF_MATCH_TTL=m
369CONFIG_IP_NF_MATCH_OWNER=m
370CONFIG_IP_NF_MATCH_ADDRTYPE=m
371CONFIG_IP_NF_FILTER=m
372CONFIG_IP_NF_TARGET_REJECT=m
373CONFIG_IP_NF_TARGET_LOG=m
374CONFIG_IP_NF_TARGET_ULOG=m
375CONFIG_IP_NF_MANGLE=m
376CONFIG_IP_NF_TARGET_TOS=m
377CONFIG_IP_NF_TARGET_ECN=m
378CONFIG_IP_NF_TARGET_TTL=m
379CONFIG_IP_NF_RAW=m
380CONFIG_IP_NF_ARPTABLES=m
381CONFIG_IP_NF_ARPFILTER=m
382CONFIG_IP_NF_ARP_MANGLE=m
383
384#
385# IPv6: Netfilter Configuration (EXPERIMENTAL)
386#
387# CONFIG_IP6_NF_QUEUE is not set
388
389#
390# DCCP Configuration (EXPERIMENTAL)
391#
392# CONFIG_IP_DCCP is not set
393
394#
395# SCTP Configuration (EXPERIMENTAL)
396#
397# CONFIG_IP_SCTP is not set
398
399#
400# TIPC Configuration (EXPERIMENTAL)
401#
402# CONFIG_TIPC is not set
403# CONFIG_ATM is not set
404# CONFIG_BRIDGE is not set
405# CONFIG_VLAN_8021Q is not set
406# CONFIG_DECNET is not set
407# CONFIG_LLC2 is not set
408# CONFIG_IPX is not set
409# CONFIG_ATALK is not set
410# CONFIG_X25 is not set
411# CONFIG_LAPB is not set
412# CONFIG_ECONET is not set
413# CONFIG_WAN_ROUTER is not set
414
415#
416# QoS and/or fair queueing
417#
418# CONFIG_NET_SCHED is not set
419
420#
421# Network testing
422#
423# CONFIG_NET_PKTGEN is not set
424# CONFIG_HAMRADIO is not set
425CONFIG_IRDA=m
426
427#
428# IrDA protocols
429#
430CONFIG_IRLAN=m
431CONFIG_IRNET=m
432CONFIG_IRCOMM=m
433# CONFIG_IRDA_ULTRA is not set
434
435#
436# IrDA options
437#
438# CONFIG_IRDA_CACHE_LAST_LSAP is not set
439# CONFIG_IRDA_FAST_RR is not set
440# CONFIG_IRDA_DEBUG is not set
441
442#
443# Infrared-port device drivers
444#
445
446#
447# SIR device drivers
448#
449CONFIG_IRTTY_SIR=m
450
451#
452# Dongle support
453#
454# CONFIG_DONGLE is not set
455
456#
457# Old SIR device drivers
458#
459# CONFIG_IRPORT_SIR is not set
460
461#
462# Old Serial dongle support
463#
464
465#
466# FIR device drivers
467#
468CONFIG_USB_IRDA=m
469# CONFIG_SIGMATEL_FIR is not set
470CONFIG_SA1100_FIR=m
471# CONFIG_MCS_FIR is not set
472CONFIG_BT=m
473CONFIG_BT_L2CAP=m
474CONFIG_BT_SCO=m
475CONFIG_BT_RFCOMM=m
476CONFIG_BT_RFCOMM_TTY=y
477CONFIG_BT_BNEP=m
478CONFIG_BT_BNEP_MC_FILTER=y
479CONFIG_BT_BNEP_PROTO_FILTER=y
480CONFIG_BT_HIDP=m
481
482#
483# Bluetooth device drivers
484#
485# CONFIG_BT_HCIUSB is not set
486CONFIG_BT_HCIUART=m
487CONFIG_BT_HCIUART_H4=y
488CONFIG_BT_HCIUART_BCSP=y
489# CONFIG_BT_HCIBCM203X is not set
490# CONFIG_BT_HCIBPA10X is not set
491# CONFIG_BT_HCIBFUSB is not set
492CONFIG_BT_HCIDTL1=m
493CONFIG_BT_HCIBT3C=m
494CONFIG_BT_HCIBLUECARD=m
495CONFIG_BT_HCIBTUART=m
496CONFIG_BT_HCIVHCI=m
497CONFIG_IEEE80211=m
498# CONFIG_IEEE80211_DEBUG is not set
499CONFIG_IEEE80211_CRYPT_WEP=m
500CONFIG_IEEE80211_CRYPT_CCMP=m
501CONFIG_IEEE80211_CRYPT_TKIP=m
502# CONFIG_IEEE80211_SOFTMAC is not set
503CONFIG_WIRELESS_EXT=y
504
505#
506# Device Drivers
507#
508
509#
510# Generic Driver Options
511#
512CONFIG_STANDALONE=y
513CONFIG_PREVENT_FIRMWARE_BUILD=y
514CONFIG_FW_LOADER=y
515# CONFIG_DEBUG_DRIVER is not set
516# CONFIG_SYS_HYPERVISOR is not set
517
518#
519# Connector - unified userspace <-> kernelspace linker
520#
521# CONFIG_CONNECTOR is not set
522
523#
524# Memory Technology Devices (MTD)
525#
526CONFIG_MTD=y
527# CONFIG_MTD_DEBUG is not set
528# CONFIG_MTD_CONCAT is not set
529CONFIG_MTD_PARTITIONS=y
530# CONFIG_MTD_REDBOOT_PARTS is not set
531# CONFIG_MTD_CMDLINE_PARTS is not set
532# CONFIG_MTD_AFS_PARTS is not set
533
534#
535# User Modules And Translation Layers
536#
537CONFIG_MTD_CHAR=m
538CONFIG_MTD_BLKDEVS=y
539CONFIG_MTD_BLOCK=y
540# CONFIG_FTL is not set
541# CONFIG_NFTL is not set
542# CONFIG_INFTL is not set
543# CONFIG_RFD_FTL is not set
544# CONFIG_SSFDC is not set
545
546#
547# RAM/ROM/Flash chip drivers
548#
549# CONFIG_MTD_CFI is not set
550# CONFIG_MTD_JEDECPROBE is not set
551CONFIG_MTD_MAP_BANK_WIDTH_1=y
552CONFIG_MTD_MAP_BANK_WIDTH_2=y
553CONFIG_MTD_MAP_BANK_WIDTH_4=y
554# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
555# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
556# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
557CONFIG_MTD_CFI_I1=y
558CONFIG_MTD_CFI_I2=y
559# CONFIG_MTD_CFI_I4 is not set
560# CONFIG_MTD_CFI_I8 is not set
561# CONFIG_MTD_RAM is not set
562CONFIG_MTD_ROM=y
563# CONFIG_MTD_ABSENT is not set
564CONFIG_MTD_OBSOLETE_CHIPS=y
565CONFIG_MTD_SHARP=y
566
567#
568# Mapping drivers for chip access
569#
570# CONFIG_MTD_COMPLEX_MAPPINGS is not set
571# CONFIG_MTD_PHYSMAP is not set
572CONFIG_MTD_SA1100=y
573# CONFIG_MTD_PLATRAM is not set
574
575#
576# Self-contained MTD device drivers
577#
578# CONFIG_MTD_DATAFLASH is not set
579# CONFIG_MTD_M25P80 is not set
580# CONFIG_MTD_SLRAM is not set
581# CONFIG_MTD_PHRAM is not set
582# CONFIG_MTD_MTDRAM is not set
583# CONFIG_MTD_BLOCK2MTD is not set
584
585#
586# Disk-On-Chip Device Drivers
587#
588# CONFIG_MTD_DOC2000 is not set
589# CONFIG_MTD_DOC2001 is not set
590# CONFIG_MTD_DOC2001PLUS is not set
591
592#
593# NAND Flash Device Drivers
594#
595# CONFIG_MTD_NAND is not set
596
597#
598# OneNAND Flash Device Drivers
599#
600# CONFIG_MTD_ONENAND is not set
601
602#
603# Parallel port support
604#
605# CONFIG_PARPORT is not set
606
607#
608# Plug and Play support
609#
610# CONFIG_PNP is not set
611
612#
613# Block devices
614#
615# CONFIG_BLK_DEV_COW_COMMON is not set
616CONFIG_BLK_DEV_LOOP=m
617# CONFIG_BLK_DEV_CRYPTOLOOP is not set
618# CONFIG_BLK_DEV_NBD is not set
619# CONFIG_BLK_DEV_UB is not set
620# CONFIG_BLK_DEV_RAM is not set
621# CONFIG_BLK_DEV_INITRD is not set
622# CONFIG_CDROM_PKTCDVD is not set
623# CONFIG_ATA_OVER_ETH is not set
624
625#
626# ATA/ATAPI/MFM/RLL support
627#
628CONFIG_IDE=m
629CONFIG_IDE_MAX_HWIFS=4
630CONFIG_BLK_DEV_IDE=m
631
632#
633# Please see Documentation/ide.txt for help/info on IDE drives
634#
635# CONFIG_BLK_DEV_IDE_SATA is not set
636CONFIG_BLK_DEV_IDEDISK=m
637# CONFIG_IDEDISK_MULTI_MODE is not set
638CONFIG_BLK_DEV_IDECS=m
639# CONFIG_BLK_DEV_IDECD is not set
640# CONFIG_BLK_DEV_IDETAPE is not set
641# CONFIG_BLK_DEV_IDEFLOPPY is not set
642# CONFIG_BLK_DEV_IDESCSI is not set
643# CONFIG_IDE_TASK_IOCTL is not set
644
645#
646# IDE chipset support/bugfixes
647#
648# CONFIG_IDE_GENERIC is not set
649# CONFIG_IDE_ARM is not set
650# CONFIG_IDE_CHIPSETS is not set
651# CONFIG_BLK_DEV_IDEDMA is not set
652# CONFIG_IDEDMA_AUTO is not set
653# CONFIG_BLK_DEV_HD is not set
654
655#
656# SCSI device support
657#
658# CONFIG_RAID_ATTRS is not set
659CONFIG_SCSI=m
660# CONFIG_SCSI_TGT is not set
661# CONFIG_SCSI_NETLINK is not set
662CONFIG_SCSI_PROC_FS=y
663
664#
665# SCSI support type (disk, tape, CD-ROM)
666#
667CONFIG_BLK_DEV_SD=m
668CONFIG_CHR_DEV_ST=m
669CONFIG_CHR_DEV_OSST=m
670CONFIG_BLK_DEV_SR=m
671# CONFIG_BLK_DEV_SR_VENDOR is not set
672CONFIG_CHR_DEV_SG=m
673# CONFIG_CHR_DEV_SCH is not set
674
675#
676# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
677#
678CONFIG_SCSI_MULTI_LUN=y
679# CONFIG_SCSI_CONSTANTS is not set
680# CONFIG_SCSI_LOGGING is not set
681# CONFIG_SCSI_SCAN_ASYNC is not set
682
683#
684# SCSI Transports
685#
686# CONFIG_SCSI_SPI_ATTRS is not set
687# CONFIG_SCSI_FC_ATTRS is not set
688# CONFIG_SCSI_ISCSI_ATTRS is not set
689# CONFIG_SCSI_SAS_ATTRS is not set
690# CONFIG_SCSI_SAS_LIBSAS is not set
691
692#
693# SCSI low-level drivers
694#
695# CONFIG_ISCSI_TCP is not set
696# CONFIG_SCSI_AHA152X is not set
697# CONFIG_SCSI_AIC7XXX_OLD is not set
698# CONFIG_SCSI_IN2000 is not set
699# CONFIG_SCSI_DTC3280 is not set
700# CONFIG_SCSI_FUTURE_DOMAIN is not set
701# CONFIG_SCSI_GENERIC_NCR5380 is not set
702# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
703# CONFIG_SCSI_NCR53C406A is not set
704# CONFIG_SCSI_PAS16 is not set
705# CONFIG_SCSI_PSI240I is not set
706# CONFIG_SCSI_QLOGIC_FAS is not set
707# CONFIG_SCSI_SYM53C416 is not set
708# CONFIG_SCSI_T128 is not set
709# CONFIG_SCSI_DEBUG is not set
710
711#
712# PCMCIA SCSI adapter support
713#
714# CONFIG_PCMCIA_AHA152X is not set
715# CONFIG_PCMCIA_FDOMAIN is not set
716# CONFIG_PCMCIA_NINJA_SCSI is not set
717# CONFIG_PCMCIA_QLOGIC is not set
718# CONFIG_PCMCIA_SYM53C500 is not set
719
720#
721# Serial ATA (prod) and Parallel ATA (experimental) drivers
722#
723# CONFIG_ATA is not set
724
725#
726# Multi-device support (RAID and LVM)
727#
728CONFIG_MD=y
729# CONFIG_BLK_DEV_MD is not set
730CONFIG_BLK_DEV_DM=m
731# CONFIG_DM_DEBUG is not set
732CONFIG_DM_CRYPT=m
733CONFIG_DM_SNAPSHOT=m
734CONFIG_DM_MIRROR=m
735CONFIG_DM_ZERO=m
736CONFIG_DM_MULTIPATH=m
737CONFIG_DM_MULTIPATH_EMC=m
738
739#
740# Fusion MPT device support
741#
742# CONFIG_FUSION is not set
743
744#
745# IEEE 1394 (FireWire) support
746#
747
748#
749# I2O device support
750#
751
752#
753# Network device support
754#
755CONFIG_NETDEVICES=y
756# CONFIG_DUMMY is not set
757# CONFIG_BONDING is not set
758# CONFIG_EQUALIZER is not set
759CONFIG_TUN=m
760
761#
762# ARCnet devices
763#
764# CONFIG_ARCNET is not set
765
766#
767# PHY device support
768#
769# CONFIG_PHYLIB is not set
770
771#
772# Ethernet (10 or 100Mbit)
773#
774CONFIG_NET_ETHERNET=y
775CONFIG_MII=m
776# CONFIG_NET_VENDOR_3COM is not set
777# CONFIG_NET_VENDOR_SMC is not set
778# CONFIG_SMC91X is not set
779# CONFIG_DM9000 is not set
780# CONFIG_NET_VENDOR_RACAL is not set
781# CONFIG_AT1700 is not set
782# CONFIG_DEPCA is not set
783# CONFIG_HP100 is not set
784# CONFIG_NET_ISA is not set
785# CONFIG_NET_PCI is not set
786
787#
788# Ethernet (1000 Mbit)
789#
790
791#
792# Ethernet (10000 Mbit)
793#
794
795#
796# Token Ring devices
797#
798# CONFIG_TR is not set
799
800#
801# Wireless LAN (non-hamradio)
802#
803CONFIG_NET_RADIO=y
804# CONFIG_NET_WIRELESS_RTNETLINK is not set
805
806#
807# Obsolete Wireless cards support (pre-802.11)
808#
809# CONFIG_STRIP is not set
810# CONFIG_ARLAN is not set
811# CONFIG_WAVELAN is not set
812# CONFIG_PCMCIA_WAVELAN is not set
813# CONFIG_PCMCIA_NETWAVE is not set
814
815#
816# Wireless 802.11 Frequency Hopping cards support
817#
818# CONFIG_PCMCIA_RAYCS is not set
819
820#
821# Wireless 802.11b ISA/PCI cards support
822#
823CONFIG_HERMES=m
824# CONFIG_ATMEL is not set
825
826#
827# Wireless 802.11b Pcmcia/Cardbus cards support
828#
829CONFIG_PCMCIA_HERMES=m
830CONFIG_PCMCIA_SPECTRUM=m
831# CONFIG_AIRO_CS is not set
832# CONFIG_PCMCIA_WL3501 is not set
833# CONFIG_USB_ZD1201 is not set
834CONFIG_HOSTAP=m
835CONFIG_HOSTAP_FIRMWARE=y
836# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
837CONFIG_HOSTAP_CS=m
838CONFIG_NET_WIRELESS=y
839
840#
841# PCMCIA network device support
842#
843CONFIG_NET_PCMCIA=y
844# CONFIG_PCMCIA_3C589 is not set
845# CONFIG_PCMCIA_3C574 is not set
846# CONFIG_PCMCIA_FMVJ18X is not set
847CONFIG_PCMCIA_PCNET=m
848# CONFIG_PCMCIA_NMCLAN is not set
849# CONFIG_PCMCIA_SMC91C92 is not set
850# CONFIG_PCMCIA_XIRC2PS is not set
851# CONFIG_PCMCIA_AXNET is not set
852
853#
854# Wan interfaces
855#
856# CONFIG_WAN is not set
857CONFIG_PPP=m
858# CONFIG_PPP_MULTILINK is not set
859# CONFIG_PPP_FILTER is not set
860CONFIG_PPP_ASYNC=m
861# CONFIG_PPP_SYNC_TTY is not set
862CONFIG_PPP_DEFLATE=m
863CONFIG_PPP_BSDCOMP=m
864# CONFIG_PPP_MPPE is not set
865# CONFIG_PPPOE is not set
866# CONFIG_SLIP is not set
867CONFIG_SLHC=m
868# CONFIG_SHAPER is not set
869# CONFIG_NETCONSOLE is not set
870# CONFIG_NETPOLL is not set
871# CONFIG_NET_POLL_CONTROLLER is not set
872
873#
874# ISDN subsystem
875#
876# CONFIG_ISDN is not set
877
878#
879# Input device support
880#
881CONFIG_INPUT=y
882# CONFIG_INPUT_FF_MEMLESS is not set
883
884#
885# Userland interfaces
886#
887CONFIG_INPUT_MOUSEDEV=y
888# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
889CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
890CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
891# CONFIG_INPUT_JOYDEV is not set
892# CONFIG_INPUT_TSDEV is not set
893CONFIG_INPUT_EVDEV=y
894# CONFIG_INPUT_EVBUG is not set
895CONFIG_INPUT_POWER=y
896
897#
898# Input Device Drivers
899#
900CONFIG_INPUT_KEYBOARD=y
901# CONFIG_KEYBOARD_ATKBD is not set
902# CONFIG_KEYBOARD_SUNKBD is not set
903# CONFIG_KEYBOARD_LKKBD is not set
904CONFIG_KEYBOARD_LOCOMO=y
905# CONFIG_KEYBOARD_XTKBD is not set
906# CONFIG_KEYBOARD_NEWTON is not set
907# CONFIG_KEYBOARD_STOWAWAY is not set
908# CONFIG_INPUT_MOUSE is not set
909# CONFIG_INPUT_JOYSTICK is not set
910# CONFIG_INPUT_TOUCHSCREEN is not set
911# CONFIG_INPUT_MISC is not set
912
913#
914# Hardware I/O ports
915#
916# CONFIG_SERIO is not set
917# CONFIG_GAMEPORT is not set
918
919#
920# Character devices
921#
922CONFIG_VT=y
923CONFIG_VT_CONSOLE=y
924CONFIG_HW_CONSOLE=y
925# CONFIG_VT_HW_CONSOLE_BINDING is not set
926# CONFIG_SERIAL_NONSTANDARD is not set
927
928#
929# Serial drivers
930#
931CONFIG_SERIAL_8250=m
932CONFIG_SERIAL_8250_CS=m
933CONFIG_SERIAL_8250_NR_UARTS=4
934CONFIG_SERIAL_8250_RUNTIME_UARTS=4
935# CONFIG_SERIAL_8250_EXTENDED is not set
936
937#
938# Non-8250 serial port support
939#
940CONFIG_SERIAL_SA1100=y
941CONFIG_SERIAL_SA1100_CONSOLE=y
942CONFIG_SERIAL_CORE=y
943CONFIG_SERIAL_CORE_CONSOLE=y
944CONFIG_UNIX98_PTYS=y
945# CONFIG_LEGACY_PTYS is not set
946
947#
948# IPMI
949#
950# CONFIG_IPMI_HANDLER is not set
951
952#
953# Watchdog Cards
954#
955# CONFIG_WATCHDOG is not set
956CONFIG_HW_RANDOM=m
957# CONFIG_NVRAM is not set
958# CONFIG_DTLK is not set
959# CONFIG_R3964 is not set
960
961#
962# PCMCIA character devices
963#
964# CONFIG_SYNCLINK_CS is not set
965# CONFIG_CARDMAN_4000 is not set
966# CONFIG_CARDMAN_4040 is not set
967# CONFIG_RAW_DRIVER is not set
968
969#
970# TPM devices
971#
972# CONFIG_TCG_TPM is not set
973
974#
975# I2C support
976#
977CONFIG_I2C=m
978# CONFIG_I2C_CHARDEV is not set
979
980#
981# I2C Algorithms
982#
983# CONFIG_I2C_ALGOBIT is not set
984# CONFIG_I2C_ALGOPCF is not set
985# CONFIG_I2C_ALGOPCA is not set
986
987#
988# I2C Hardware Bus support
989#
990# CONFIG_I2C_ELEKTOR is not set
991# CONFIG_I2C_OCORES is not set
992# CONFIG_I2C_PARPORT_LIGHT is not set
993# CONFIG_I2C_STUB is not set
994# CONFIG_I2C_PCA_ISA is not set
995
996#
997# Miscellaneous I2C Chip support
998#
999# CONFIG_SENSORS_DS1337 is not set
1000# CONFIG_SENSORS_DS1374 is not set
1001# CONFIG_SENSORS_EEPROM is not set
1002# CONFIG_SENSORS_PCF8574 is not set
1003# CONFIG_SENSORS_PCA9539 is not set
1004# CONFIG_SENSORS_PCF8591 is not set
1005# CONFIG_SENSORS_MAX6875 is not set
1006# CONFIG_I2C_DEBUG_CORE is not set
1007# CONFIG_I2C_DEBUG_ALGO is not set
1008# CONFIG_I2C_DEBUG_BUS is not set
1009# CONFIG_I2C_DEBUG_CHIP is not set
1010
1011#
1012# SPI support
1013#
1014CONFIG_SPI=y
1015# CONFIG_SPI_DEBUG is not set
1016CONFIG_SPI_MASTER=y
1017
1018#
1019# SPI Master Controller Drivers
1020#
1021# CONFIG_SPI_BITBANG is not set
1022CONFIG_SPI_LOCOMO=m
1023
1024#
1025# SPI Protocol Masters
1026#
1027
1028#
1029# Dallas's 1-wire bus
1030#
1031# CONFIG_W1 is not set
1032
1033#
1034# Hardware Monitoring support
1035#
1036# CONFIG_HWMON is not set
1037# CONFIG_HWMON_VID is not set
1038
1039#
1040# Misc devices
1041#
1042# CONFIG_TIFM_CORE is not set
1043
1044#
1045# Multimedia Capabilities Port drivers
1046#
1047CONFIG_MCP=y
1048CONFIG_MCP_SA11X0=y
1049CONFIG_MCP_UCB1200=y
1050CONFIG_MCP_UCB1200_TS=m
1051
1052#
1053# Multi-Function Devices
1054#
1055
1056#
1057# LED devices
1058#
1059CONFIG_NEW_LEDS=y
1060CONFIG_LEDS_CLASS=m
1061
1062#
1063# LED drivers
1064#
1065CONFIG_LEDS_LOCOMO=m
1066
1067#
1068# LED Triggers
1069#
1070CONFIG_LEDS_TRIGGERS=y
1071CONFIG_LEDS_TRIGGER_TIMER=m
1072# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
1073CONFIG_LEDS_TRIGGER_HEARTBEAT=m
1074
1075#
1076# Multimedia devices
1077#
1078CONFIG_VIDEO_DEV=m
1079CONFIG_VIDEO_V4L1=y
1080CONFIG_VIDEO_V4L1_COMPAT=y
1081CONFIG_VIDEO_V4L2=y
1082
1083#
1084# Video Capture Adapters
1085#
1086
1087#
1088# Video Capture Adapters
1089#
1090# CONFIG_VIDEO_ADV_DEBUG is not set
1091CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1092# CONFIG_VIDEO_VIVI is not set
1093# CONFIG_VIDEO_PMS is not set
1094# CONFIG_VIDEO_CPIA is not set
1095# CONFIG_VIDEO_CPIA2 is not set
1096# CONFIG_VIDEO_SAA5246A is not set
1097# CONFIG_VIDEO_SAA5249 is not set
1098# CONFIG_TUNER_3036 is not set
1099
1100#
1101# V4L USB devices
1102#
1103# CONFIG_VIDEO_PVRUSB2 is not set
1104# CONFIG_VIDEO_EM28XX is not set
1105# CONFIG_VIDEO_USBVISION is not set
1106# CONFIG_USB_VICAM is not set
1107# CONFIG_USB_IBMCAM is not set
1108# CONFIG_USB_KONICAWC is not set
1109# CONFIG_USB_QUICKCAM_MESSENGER is not set
1110# CONFIG_USB_ET61X251 is not set
1111# CONFIG_VIDEO_OVCAMCHIP is not set
1112# CONFIG_USB_W9968CF is not set
1113# CONFIG_USB_OV511 is not set
1114# CONFIG_USB_SE401 is not set
1115# CONFIG_USB_SN9C102 is not set
1116# CONFIG_USB_STV680 is not set
1117# CONFIG_USB_ZC0301 is not set
1118# CONFIG_USB_PWC is not set
1119
1120#
1121# Radio Adapters
1122#
1123# CONFIG_RADIO_CADET is not set
1124# CONFIG_RADIO_RTRACK is not set
1125# CONFIG_RADIO_RTRACK2 is not set
1126# CONFIG_RADIO_AZTECH is not set
1127# CONFIG_RADIO_GEMTEK is not set
1128# CONFIG_RADIO_SF16FMI is not set
1129# CONFIG_RADIO_SF16FMR2 is not set
1130# CONFIG_RADIO_TERRATEC is not set
1131# CONFIG_RADIO_TRUST is not set
1132# CONFIG_RADIO_TYPHOON is not set
1133# CONFIG_RADIO_ZOLTRIX is not set
1134# CONFIG_USB_DSBR is not set
1135
1136#
1137# Digital Video Broadcasting Devices
1138#
1139# CONFIG_DVB is not set
1140# CONFIG_USB_DABUSB is not set
1141
1142#
1143# Graphics support
1144#
1145CONFIG_FIRMWARE_EDID=y
1146CONFIG_FB=y
1147CONFIG_FB_CFB_FILLRECT=y
1148CONFIG_FB_CFB_COPYAREA=y
1149CONFIG_FB_CFB_IMAGEBLIT=y
1150# CONFIG_FB_MACMODES is not set
1151# CONFIG_FB_BACKLIGHT is not set
1152# CONFIG_FB_MODE_HELPERS is not set
1153# CONFIG_FB_TILEBLITTING is not set
1154CONFIG_FB_SA1100=y
1155# CONFIG_FB_S1D13XXX is not set
1156# CONFIG_FB_VIRTUAL is not set
1157
1158#
1159# Console display driver support
1160#
1161# CONFIG_VGA_CONSOLE is not set
1162# CONFIG_MDA_CONSOLE is not set
1163CONFIG_DUMMY_CONSOLE=y
1164CONFIG_FRAMEBUFFER_CONSOLE=y
1165CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
1166CONFIG_FONTS=y
1167CONFIG_FONT_8x8=y
1168# CONFIG_FONT_8x16 is not set
1169# CONFIG_FONT_6x11 is not set
1170# CONFIG_FONT_7x14 is not set
1171# CONFIG_FONT_PEARL_8x8 is not set
1172# CONFIG_FONT_ACORN_8x8 is not set
1173# CONFIG_FONT_MINI_4x6 is not set
1174# CONFIG_FONT_SUN8x16 is not set
1175# CONFIG_FONT_SUN12x22 is not set
1176# CONFIG_FONT_10x18 is not set
1177
1178#
1179# Logo configuration
1180#
1181# CONFIG_LOGO is not set
1182CONFIG_BACKLIGHT_LCD_SUPPORT=y
1183CONFIG_BACKLIGHT_CLASS_DEVICE=y
1184CONFIG_BACKLIGHT_DEVICE=y
1185CONFIG_LCD_CLASS_DEVICE=m
1186CONFIG_LCD_DEVICE=y
1187CONFIG_BACKLIGHT_LOCOMO=y
1188
1189#
1190# Sound
1191#
1192CONFIG_SOUND=m
1193
1194#
1195# Advanced Linux Sound Architecture
1196#
1197CONFIG_SND=m
1198CONFIG_SND_TIMER=m
1199CONFIG_SND_PCM=m
1200# CONFIG_SND_SEQUENCER is not set
1201CONFIG_SND_OSSEMUL=y
1202CONFIG_SND_MIXER_OSS=m
1203CONFIG_SND_PCM_OSS=m
1204CONFIG_SND_PCM_OSS_PLUGINS=y
1205# CONFIG_SND_DYNAMIC_MINORS is not set
1206CONFIG_SND_SUPPORT_OLD_API=y
1207CONFIG_SND_VERBOSE_PROCFS=y
1208# CONFIG_SND_VERBOSE_PRINTK is not set
1209# CONFIG_SND_DEBUG is not set
1210
1211#
1212# Generic devices
1213#
1214CONFIG_SND_DUMMY=m
1215# CONFIG_SND_MTPAV is not set
1216# CONFIG_SND_SERIAL_U16550 is not set
1217# CONFIG_SND_MPU401 is not set
1218
1219#
1220# ALSA ARM devices
1221#
1222
1223#
1224# USB devices
1225#
1226# CONFIG_SND_USB_AUDIO is not set
1227
1228#
1229# PCMCIA devices
1230#
1231# CONFIG_SND_VXPOCKET is not set
1232# CONFIG_SND_PDAUDIOCF is not set
1233
1234#
1235# SoC audio support
1236#
1237# CONFIG_SND_SOC is not set
1238
1239#
1240# Open Sound System
1241#
1242# CONFIG_SOUND_PRIME is not set
1243
1244#
1245# HID Devices
1246#
1247CONFIG_HID=m
1248
1249#
1250# USB support
1251#
1252CONFIG_USB_ARCH_HAS_HCD=y
1253# CONFIG_USB_ARCH_HAS_OHCI is not set
1254# CONFIG_USB_ARCH_HAS_EHCI is not set
1255CONFIG_USB=m
1256# CONFIG_USB_DEBUG is not set
1257
1258#
1259# Miscellaneous USB options
1260#
1261CONFIG_USB_DEVICEFS=y
1262# CONFIG_USB_BANDWIDTH is not set
1263# CONFIG_USB_DYNAMIC_MINORS is not set
1264# CONFIG_USB_SUSPEND is not set
1265# CONFIG_USB_OTG is not set
1266
1267#
1268# USB Host Controller Drivers
1269#
1270# CONFIG_USB_ISP116X_HCD is not set
1271CONFIG_USB_SL811_HCD=m
1272CONFIG_USB_SL811_CS=m
1273
1274#
1275# USB Device Class drivers
1276#
1277# CONFIG_USB_ACM is not set
1278# CONFIG_USB_PRINTER is not set
1279
1280#
1281# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1282#
1283
1284#
1285# may also be needed; see USB_STORAGE Help for more information
1286#
1287CONFIG_USB_STORAGE=m
1288# CONFIG_USB_STORAGE_DEBUG is not set
1289# CONFIG_USB_STORAGE_DATAFAB is not set
1290# CONFIG_USB_STORAGE_FREECOM is not set
1291# CONFIG_USB_STORAGE_ISD200 is not set
1292# CONFIG_USB_STORAGE_DPCM is not set
1293# CONFIG_USB_STORAGE_USBAT is not set
1294# CONFIG_USB_STORAGE_SDDR09 is not set
1295# CONFIG_USB_STORAGE_SDDR55 is not set
1296# CONFIG_USB_STORAGE_JUMPSHOT is not set
1297# CONFIG_USB_STORAGE_ALAUDA is not set
1298# CONFIG_USB_STORAGE_KARMA is not set
1299# CONFIG_USB_LIBUSUAL is not set
1300
1301#
1302# USB Input Devices
1303#
1304CONFIG_USB_HID=m
1305# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1306# CONFIG_HID_FF is not set
1307# CONFIG_USB_HIDDEV is not set
1308
1309#
1310# USB HID Boot Protocol drivers
1311#
1312# CONFIG_USB_KBD is not set
1313# CONFIG_USB_MOUSE is not set
1314# CONFIG_USB_AIPTEK is not set
1315# CONFIG_USB_WACOM is not set
1316# CONFIG_USB_ACECAD is not set
1317# CONFIG_USB_KBTAB is not set
1318# CONFIG_USB_POWERMATE is not set
1319# CONFIG_USB_TOUCHSCREEN is not set
1320# CONFIG_USB_YEALINK is not set
1321# CONFIG_USB_XPAD is not set
1322# CONFIG_USB_ATI_REMOTE is not set
1323# CONFIG_USB_ATI_REMOTE2 is not set
1324# CONFIG_USB_KEYSPAN_REMOTE is not set
1325# CONFIG_USB_APPLETOUCH is not set
1326
1327#
1328# USB Imaging devices
1329#
1330# CONFIG_USB_MDC800 is not set
1331# CONFIG_USB_MICROTEK is not set
1332
1333#
1334# USB Network Adapters
1335#
1336# CONFIG_USB_CATC is not set
1337# CONFIG_USB_KAWETH is not set
1338# CONFIG_USB_PEGASUS is not set
1339# CONFIG_USB_RTL8150 is not set
1340CONFIG_USB_USBNET_MII=m
1341CONFIG_USB_USBNET=m
1342CONFIG_USB_NET_AX8817X=m
1343CONFIG_USB_NET_CDCETHER=m
1344# CONFIG_USB_NET_GL620A is not set
1345CONFIG_USB_NET_NET1080=m
1346# CONFIG_USB_NET_PLUSB is not set
1347# CONFIG_USB_NET_MCS7830 is not set
1348# CONFIG_USB_NET_RNDIS_HOST is not set
1349CONFIG_USB_NET_CDC_SUBSET=m
1350# CONFIG_USB_ALI_M5632 is not set
1351# CONFIG_USB_AN2720 is not set
1352CONFIG_USB_BELKIN=y
1353CONFIG_USB_ARMLINUX=y
1354# CONFIG_USB_EPSON2888 is not set
1355CONFIG_USB_NET_ZAURUS=m
1356CONFIG_USB_MON=y
1357
1358#
1359# USB port drivers
1360#
1361
1362#
1363# USB Serial Converter support
1364#
1365CONFIG_USB_SERIAL=m
1366CONFIG_USB_SERIAL_GENERIC=y
1367# CONFIG_USB_SERIAL_AIRCABLE is not set
1368CONFIG_USB_SERIAL_AIRPRIME=m
1369CONFIG_USB_SERIAL_ARK3116=m
1370CONFIG_USB_SERIAL_BELKIN=m
1371CONFIG_USB_SERIAL_WHITEHEAT=m
1372CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1373CONFIG_USB_SERIAL_CP2101=m
1374CONFIG_USB_SERIAL_CYPRESS_M8=m
1375CONFIG_USB_SERIAL_EMPEG=m
1376CONFIG_USB_SERIAL_FTDI_SIO=m
1377CONFIG_USB_SERIAL_FUNSOFT=m
1378CONFIG_USB_SERIAL_VISOR=m
1379CONFIG_USB_SERIAL_IPAQ=m
1380CONFIG_USB_SERIAL_IR=m
1381CONFIG_USB_SERIAL_EDGEPORT=m
1382CONFIG_USB_SERIAL_EDGEPORT_TI=m
1383CONFIG_USB_SERIAL_GARMIN=m
1384CONFIG_USB_SERIAL_IPW=m
1385CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1386CONFIG_USB_SERIAL_KEYSPAN=m
1387# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1388# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1389# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1390# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1391# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1392# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1393# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1394# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1395# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1396# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1397# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1398# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1399CONFIG_USB_SERIAL_KLSI=m
1400CONFIG_USB_SERIAL_KOBIL_SCT=m
1401CONFIG_USB_SERIAL_MCT_U232=m
1402# CONFIG_USB_SERIAL_MOS7720 is not set
1403# CONFIG_USB_SERIAL_MOS7840 is not set
1404# CONFIG_USB_SERIAL_NAVMAN is not set
1405CONFIG_USB_SERIAL_PL2303=m
1406CONFIG_USB_SERIAL_HP4X=m
1407CONFIG_USB_SERIAL_SAFE=m
1408# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1409# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1410CONFIG_USB_SERIAL_TI=m
1411CONFIG_USB_SERIAL_CYBERJACK=m
1412CONFIG_USB_SERIAL_XIRCOM=m
1413# CONFIG_USB_SERIAL_OPTION is not set
1414# CONFIG_USB_SERIAL_OMNINET is not set
1415# CONFIG_USB_SERIAL_DEBUG is not set
1416CONFIG_USB_EZUSB=y
1417
1418#
1419# USB Miscellaneous drivers
1420#
1421# CONFIG_USB_EMI62 is not set
1422# CONFIG_USB_EMI26 is not set
1423# CONFIG_USB_ADUTUX is not set
1424# CONFIG_USB_AUERSWALD is not set
1425# CONFIG_USB_RIO500 is not set
1426# CONFIG_USB_LEGOTOWER is not set
1427# CONFIG_USB_LCD is not set
1428# CONFIG_USB_LED is not set
1429# CONFIG_USB_CYPRESS_CY7C63 is not set
1430# CONFIG_USB_CYTHERM is not set
1431# CONFIG_USB_PHIDGET is not set
1432# CONFIG_USB_IDMOUSE is not set
1433# CONFIG_USB_FTDI_ELAN is not set
1434# CONFIG_USB_APPLEDISPLAY is not set
1435# CONFIG_USB_LD is not set
1436# CONFIG_USB_TRANCEVIBRATOR is not set
1437# CONFIG_USB_TEST is not set
1438
1439#
1440# USB DSL modem support
1441#
1442
1443#
1444# USB Gadget Support
1445#
1446# CONFIG_USB_GADGET is not set
1447# CONFIG_USB_GADGET_DEBUG_FILES is not set
1448# CONFIG_USB_GADGET_NET2280 is not set
1449# CONFIG_USB_GADGET_PXA2XX is not set
1450# CONFIG_USB_GADGET_PXA27X is not set
1451# CONFIG_USB_GADGET_GOKU is not set
1452# CONFIG_USB_GADGET_LH7A40X is not set
1453# CONFIG_USB_GADGET_OMAP is not set
1454# CONFIG_USB_GADGET_AT91 is not set
1455# CONFIG_USB_GADGET_DUMMY_HCD is not set
1456# CONFIG_USB_GADGET_DUALSPEED is not set
1457
1458#
1459# MMC/SD Card support
1460#
1461CONFIG_MMC=m
1462CONFIG_MMC_DEBUG=y
1463CONFIG_MMC_BLOCK=m
1464# CONFIG_MMC_TIFM_SD is not set
1465CONFIG_MMC_SPI=m
1466CONFIG_MMC_UNSAFE_RESUME=y
1467
1468
1469#
1470# Real Time Clock
1471#
1472CONFIG_RTC_LIB=y
1473CONFIG_RTC_CLASS=y
1474CONFIG_RTC_HCTOSYS=y
1475CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1476# CONFIG_RTC_DEBUG is not set
1477
1478#
1479# RTC interfaces
1480#
1481CONFIG_RTC_INTF_SYSFS=y
1482CONFIG_RTC_INTF_PROC=y
1483CONFIG_RTC_INTF_DEV=y
1484# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1485
1486#
1487# RTC drivers
1488#
1489# CONFIG_RTC_DRV_X1205 is not set
1490# CONFIG_RTC_DRV_DS1307 is not set
1491# CONFIG_RTC_DRV_DS1553 is not set
1492# CONFIG_RTC_DRV_ISL1208 is not set
1493# CONFIG_RTC_DRV_DS1672 is not set
1494# CONFIG_RTC_DRV_DS1742 is not set
1495# CONFIG_RTC_DRV_PCF8563 is not set
1496# CONFIG_RTC_DRV_PCF8583 is not set
1497# CONFIG_RTC_DRV_RS5C348 is not set
1498# CONFIG_RTC_DRV_RS5C372 is not set
1499# CONFIG_RTC_DRV_M48T86 is not set
1500CONFIG_RTC_DRV_SA1100=y
1501# CONFIG_RTC_DRV_TEST is not set
1502# CONFIG_RTC_DRV_MAX6902 is not set
1503# CONFIG_RTC_DRV_V3020 is not set
1504
1505#
1506# File systems
1507#
1508CONFIG_EXT2_FS=m
1509# CONFIG_EXT2_FS_XATTR is not set
1510# CONFIG_EXT2_FS_XIP is not set
1511CONFIG_EXT3_FS=m
1512# CONFIG_EXT4DEV_FS is not set
1513# CONFIG_REISERFS_FS is not set
1514# CONFIG_JFS_FS is not set
1515# CONFIG_FS_POSIX_ACL is not set
1516# CONFIG_XFS_FS is not set
1517# CONFIG_GFS2_FS is not set
1518# CONFIG_OCFS2_FS is not set
1519# CONFIG_MINIX_FS is not set
1520# CONFIG_ROMFS_FS is not set
1521CONFIG_INOTIFY=y
1522CONFIG_INOTIFY_USER=y
1523# CONFIG_QUOTA is not set
1524CONFIG_DNOTIFY=y
1525# CONFIG_AUTOFS_FS is not set
1526# CONFIG_AUTOFS4_FS is not set
1527CONFIG_FUSE_FS=m
1528
1529#
1530# CD-ROM/DVD Filesystems
1531#
1532# CONFIG_ISO9660_FS is not set
1533# CONFIG_UDF_FS is not set
1534
1535#
1536# DOS/FAT/NT Filesystems
1537#
1538CONFIG_FAT_FS=m
1539CONFIG_MSDOS_FS=m
1540CONFIG_VFAT_FS=m
1541CONFIG_FAT_DEFAULT_CODEPAGE=437
1542CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1543# CONFIG_NTFS_FS is not set
1544
1545#
1546# Pseudo filesystems
1547#
1548CONFIG_PROC_FS=y
1549CONFIG_PROC_SYSCTL=y
1550CONFIG_SYSFS=y
1551CONFIG_TMPFS=y
1552# CONFIG_TMPFS_POSIX_ACL is not set
1553# CONFIG_HUGETLB_PAGE is not set
1554CONFIG_RAMFS=y
1555# CONFIG_CONFIGFS_FS is not set
1556
1557#
1558# Miscellaneous filesystems
1559#
1560# CONFIG_ADFS_FS is not set
1561# CONFIG_AFFS_FS is not set
1562# CONFIG_HFS_FS is not set
1563# CONFIG_HFSPLUS_FS is not set
1564# CONFIG_BEFS_FS is not set
1565# CONFIG_BFS_FS is not set
1566# CONFIG_EFS_FS is not set
1567CONFIG_JFFS2_FS=y
1568CONFIG_JFFS2_FS_DEBUG=0
1569CONFIG_JFFS2_FS_WRITEBUFFER=y
1570# CONFIG_JFFS2_SUMMARY is not set
1571# CONFIG_JFFS2_FS_XATTR is not set
1572# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1573CONFIG_JFFS2_ZLIB=y
1574CONFIG_JFFS2_LZO=y
1575CONFIG_JFFS2_RTIME=y
1576# CONFIG_JFFS2_RUBIN is not set
1577CONFIG_CRAMFS=m
1578CONFIG_SQUASHFS=m
1579# CONFIG_SQUASHFS_EMBEDDED is not set
1580CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1581# CONFIG_SQUASHFS_VMALLOC is not set
1582# CONFIG_VXFS_FS is not set
1583# CONFIG_HPFS_FS is not set
1584# CONFIG_QNX4FS_FS is not set
1585# CONFIG_SYSV_FS is not set
1586# CONFIG_UFS_FS is not set
1587
1588#
1589# Network File Systems
1590#
1591CONFIG_NFS_FS=m
1592CONFIG_NFS_V3=y
1593# CONFIG_NFS_V3_ACL is not set
1594CONFIG_NFS_V4=y
1595# CONFIG_NFS_DIRECTIO is not set
1596# CONFIG_NFSD is not set
1597CONFIG_LOCKD=m
1598CONFIG_LOCKD_V4=y
1599CONFIG_NFS_COMMON=y
1600CONFIG_SUNRPC=m
1601CONFIG_SUNRPC_GSS=m
1602CONFIG_RPCSEC_GSS_KRB5=m
1603# CONFIG_RPCSEC_GSS_SPKM3 is not set
1604CONFIG_SMB_FS=m
1605CONFIG_SMB_NLS_DEFAULT=y
1606CONFIG_SMB_NLS_REMOTE="cp437"
1607CONFIG_CIFS=m
1608# CONFIG_CIFS_STATS is not set
1609# CONFIG_CIFS_WEAK_PW_HASH is not set
1610# CONFIG_CIFS_XATTR is not set
1611# CONFIG_CIFS_DEBUG2 is not set
1612# CONFIG_CIFS_EXPERIMENTAL is not set
1613# CONFIG_NCP_FS is not set
1614# CONFIG_CODA_FS is not set
1615# CONFIG_AFS_FS is not set
1616# CONFIG_9P_FS is not set
1617
1618#
1619# Partition Types
1620#
1621CONFIG_PARTITION_ADVANCED=y
1622# CONFIG_ACORN_PARTITION is not set
1623# CONFIG_OSF_PARTITION is not set
1624# CONFIG_AMIGA_PARTITION is not set
1625# CONFIG_ATARI_PARTITION is not set
1626# CONFIG_MAC_PARTITION is not set
1627CONFIG_MSDOS_PARTITION=y
1628# CONFIG_BSD_DISKLABEL is not set
1629# CONFIG_MINIX_SUBPARTITION is not set
1630# CONFIG_SOLARIS_X86_PARTITION is not set
1631# CONFIG_UNIXWARE_DISKLABEL is not set
1632# CONFIG_LDM_PARTITION is not set
1633# CONFIG_SGI_PARTITION is not set
1634# CONFIG_ULTRIX_PARTITION is not set
1635# CONFIG_SUN_PARTITION is not set
1636# CONFIG_KARMA_PARTITION is not set
1637# CONFIG_EFI_PARTITION is not set
1638
1639#
1640# Native Language Support
1641#
1642CONFIG_NLS=y
1643CONFIG_NLS_DEFAULT="cp437"
1644CONFIG_NLS_CODEPAGE_437=y
1645CONFIG_NLS_CODEPAGE_737=m
1646CONFIG_NLS_CODEPAGE_775=m
1647CONFIG_NLS_CODEPAGE_850=m
1648CONFIG_NLS_CODEPAGE_852=m
1649CONFIG_NLS_CODEPAGE_855=m
1650CONFIG_NLS_CODEPAGE_857=m
1651CONFIG_NLS_CODEPAGE_860=m
1652CONFIG_NLS_CODEPAGE_861=m
1653CONFIG_NLS_CODEPAGE_862=m
1654CONFIG_NLS_CODEPAGE_863=m
1655CONFIG_NLS_CODEPAGE_864=m
1656CONFIG_NLS_CODEPAGE_865=m
1657CONFIG_NLS_CODEPAGE_866=m
1658CONFIG_NLS_CODEPAGE_869=m
1659CONFIG_NLS_CODEPAGE_936=m
1660CONFIG_NLS_CODEPAGE_950=m
1661CONFIG_NLS_CODEPAGE_932=m
1662CONFIG_NLS_CODEPAGE_949=m
1663CONFIG_NLS_CODEPAGE_874=m
1664CONFIG_NLS_ISO8859_8=m
1665CONFIG_NLS_CODEPAGE_1250=m
1666CONFIG_NLS_CODEPAGE_1251=m
1667CONFIG_NLS_ASCII=m
1668CONFIG_NLS_ISO8859_1=y
1669CONFIG_NLS_ISO8859_2=m
1670CONFIG_NLS_ISO8859_3=m
1671CONFIG_NLS_ISO8859_4=m
1672CONFIG_NLS_ISO8859_5=m
1673CONFIG_NLS_ISO8859_6=m
1674CONFIG_NLS_ISO8859_7=m
1675CONFIG_NLS_ISO8859_9=m
1676CONFIG_NLS_ISO8859_13=m
1677CONFIG_NLS_ISO8859_14=m
1678CONFIG_NLS_ISO8859_15=m
1679CONFIG_NLS_KOI8_R=m
1680CONFIG_NLS_KOI8_U=m
1681CONFIG_NLS_UTF8=m
1682
1683#
1684# Distributed Lock Manager
1685#
1686# CONFIG_DLM is not set
1687
1688#
1689# Profiling support
1690#
1691# CONFIG_PROFILING is not set
1692
1693#
1694# Kernel hacking
1695#
1696# CONFIG_PRINTK_TIME is not set
1697CONFIG_ENABLE_MUST_CHECK=y
1698CONFIG_MAGIC_SYSRQ=y
1699# CONFIG_UNUSED_SYMBOLS is not set
1700# CONFIG_DEBUG_FS is not set
1701# CONFIG_HEADERS_CHECK is not set
1702CONFIG_DEBUG_KERNEL=y
1703CONFIG_LOG_BUF_SHIFT=14
1704CONFIG_DETECT_SOFTLOCKUP=y
1705# CONFIG_SCHEDSTATS is not set
1706# CONFIG_DEBUG_SLAB is not set
1707# CONFIG_DEBUG_PREEMPT is not set
1708# CONFIG_DEBUG_RT_MUTEXES is not set
1709# CONFIG_RT_MUTEX_TESTER is not set
1710# CONFIG_DEBUG_SPINLOCK is not set
1711# CONFIG_DEBUG_MUTEXES is not set
1712# CONFIG_DEBUG_RWSEMS is not set
1713# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1714# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1715# CONFIG_DEBUG_KOBJECT is not set
1716# CONFIG_DEBUG_BUGVERBOSE is not set
1717# CONFIG_DEBUG_INFO is not set
1718# CONFIG_DEBUG_VM is not set
1719# CONFIG_DEBUG_LIST is not set
1720CONFIG_FRAME_POINTER=y
1721# CONFIG_FORCED_INLINING is not set
1722# CONFIG_RCU_TORTURE_TEST is not set
1723# CONFIG_DEBUG_USER is not set
1724CONFIG_DEBUG_ERRORS=y
1725# CONFIG_DEBUG_LL is not set
1726
1727#
1728# Security options
1729#
1730# CONFIG_KEYS is not set
1731# CONFIG_SECURITY is not set
1732
1733#
1734# Cryptographic options
1735#
1736CONFIG_CRYPTO=y
1737CONFIG_CRYPTO_ALGAPI=y
1738CONFIG_CRYPTO_BLKCIPHER=m
1739CONFIG_CRYPTO_HASH=m
1740CONFIG_CRYPTO_MANAGER=y
1741CONFIG_CRYPTO_HMAC=m
1742# CONFIG_CRYPTO_XCBC is not set
1743CONFIG_CRYPTO_NULL=m
1744CONFIG_CRYPTO_MD4=m
1745CONFIG_CRYPTO_MD5=m
1746CONFIG_CRYPTO_SHA1=m
1747CONFIG_CRYPTO_SHA256=m
1748CONFIG_CRYPTO_SHA512=m
1749CONFIG_CRYPTO_WP512=m
1750# CONFIG_CRYPTO_TGR192 is not set
1751# CONFIG_CRYPTO_GF128MUL is not set
1752CONFIG_CRYPTO_ECB=m
1753CONFIG_CRYPTO_CBC=m
1754# CONFIG_CRYPTO_LRW is not set
1755CONFIG_CRYPTO_DES=m
1756CONFIG_CRYPTO_BLOWFISH=m
1757CONFIG_CRYPTO_TWOFISH=m
1758CONFIG_CRYPTO_TWOFISH_COMMON=m
1759CONFIG_CRYPTO_SERPENT=m
1760CONFIG_CRYPTO_AES=m
1761CONFIG_CRYPTO_CAST5=m
1762CONFIG_CRYPTO_CAST6=m
1763CONFIG_CRYPTO_TEA=m
1764CONFIG_CRYPTO_ARC4=m
1765CONFIG_CRYPTO_KHAZAD=m
1766CONFIG_CRYPTO_ANUBIS=m
1767CONFIG_CRYPTO_DEFLATE=m
1768# CONFIG_CRYPTO_LZO is not set
1769CONFIG_CRYPTO_MICHAEL_MIC=m
1770CONFIG_CRYPTO_CRC32C=m
1771CONFIG_CRYPTO_TEST=m
1772
1773#
1774# Hardware crypto devices
1775#
1776
1777#
1778# Library routines
1779#
1780CONFIG_BITREVERSE=y
1781CONFIG_CRC_CCITT=m
1782CONFIG_CRC16=m
1783CONFIG_CRC32=y
1784CONFIG_LIBCRC32C=m
1785CONFIG_LZO=y
1786CONFIG_ZLIB_INFLATE=y
1787CONFIG_ZLIB_DEFLATE=y
1788CONFIG_PLIST=y
1789CONFIG_IOMAP_COPY=y
1790# CONFIG_SHARPSL_RC is not set
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-htcuniversal b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-htcuniversal
new file mode 100644
index 0000000000..3f33b1446f
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-htcuniversal
@@ -0,0 +1,1313 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23-rc4
4# Wed Sep 26 17:55:32 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37# CONFIG_LOCALVERSION_AUTO is not set
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41# CONFIG_POSIX_MQUEUE is not set
42# CONFIG_BSD_PROCESS_ACCT is not set
43# CONFIG_TASKSTATS is not set
44# CONFIG_USER_NS is not set
45# CONFIG_AUDIT is not set
46CONFIG_IKCONFIG=y
47CONFIG_IKCONFIG_PROC=y
48CONFIG_LOG_BUF_SHIFT=16
49CONFIG_SYSFS_DEPRECATED=y
50# CONFIG_RELAY is not set
51# CONFIG_BLK_DEV_INITRD is not set
52CONFIG_CC_OPTIMIZE_FOR_SIZE=y
53CONFIG_SYSCTL=y
54CONFIG_EMBEDDED=y
55# CONFIG_UID16 is not set
56CONFIG_SYSCTL_SYSCALL=y
57CONFIG_KALLSYMS=y
58# CONFIG_KALLSYMS_ALL is not set
59# CONFIG_KALLSYMS_EXTRA_PASS is not set
60CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y
62CONFIG_BUG=y
63CONFIG_ELF_CORE=y
64CONFIG_BASE_FULL=y
65CONFIG_FUTEX=y
66CONFIG_ANON_INODES=y
67CONFIG_EPOLL=y
68CONFIG_SIGNALFD=y
69CONFIG_TIMERFD=y
70CONFIG_EVENTFD=y
71CONFIG_SHMEM=y
72CONFIG_VM_EVENT_COUNTERS=y
73CONFIG_SLAB=y
74# CONFIG_SLUB is not set
75# CONFIG_SLOB is not set
76CONFIG_RT_MUTEXES=y
77# CONFIG_TINY_SHMEM is not set
78CONFIG_BASE_SMALL=0
79CONFIG_MODULES=y
80CONFIG_MODULE_UNLOAD=y
81CONFIG_MODULE_FORCE_UNLOAD=y
82# CONFIG_MODVERSIONS is not set
83# CONFIG_MODULE_SRCVERSION_ALL is not set
84CONFIG_KMOD=y
85CONFIG_BLOCK=y
86# CONFIG_LBD is not set
87# CONFIG_BLK_DEV_IO_TRACE is not set
88# CONFIG_LSF is not set
89# CONFIG_BLK_DEV_BSG is not set
90
91#
92# IO Schedulers
93#
94CONFIG_IOSCHED_NOOP=y
95CONFIG_IOSCHED_AS=y
96CONFIG_IOSCHED_DEADLINE=y
97# CONFIG_IOSCHED_CFQ is not set
98CONFIG_DEFAULT_AS=y
99# CONFIG_DEFAULT_DEADLINE is not set
100# CONFIG_DEFAULT_CFQ is not set
101# CONFIG_DEFAULT_NOOP is not set
102CONFIG_DEFAULT_IOSCHED="anticipatory"
103
104#
105# System Type
106#
107# CONFIG_ARCH_AAEC2000 is not set
108# CONFIG_ARCH_INTEGRATOR is not set
109# CONFIG_ARCH_REALVIEW is not set
110# CONFIG_ARCH_VERSATILE is not set
111# CONFIG_ARCH_AT91 is not set
112# CONFIG_ARCH_CLPS7500 is not set
113# CONFIG_ARCH_CLPS711X is not set
114# CONFIG_ARCH_CO285 is not set
115# CONFIG_ARCH_EBSA110 is not set
116# CONFIG_ARCH_EP93XX is not set
117# CONFIG_ARCH_FOOTBRIDGE is not set
118# CONFIG_ARCH_NETX is not set
119# CONFIG_ARCH_H720X is not set
120# CONFIG_ARCH_IMX is not set
121# CONFIG_ARCH_IOP13XX is not set
122# CONFIG_ARCH_IOP32X is not set
123# CONFIG_ARCH_IOP33X is not set
124# CONFIG_ARCH_IXP23XX is not set
125# CONFIG_ARCH_IXP2000 is not set
126# CONFIG_ARCH_IXP4XX is not set
127# CONFIG_ARCH_L7200 is not set
128# CONFIG_ARCH_KS8695 is not set
129# CONFIG_ARCH_NS9XXX is not set
130# CONFIG_ARCH_MXC is not set
131# CONFIG_ARCH_PNX4008 is not set
132CONFIG_ARCH_PXA=y
133# CONFIG_ARCH_RPC is not set
134# CONFIG_ARCH_SA1100 is not set
135# CONFIG_ARCH_S3C2410 is not set
136# CONFIG_ARCH_SHARK is not set
137# CONFIG_ARCH_LH7A40X is not set
138# CONFIG_ARCH_DAVINCI is not set
139# CONFIG_ARCH_OMAP is not set
140
141#
142# Intel PXA2xx Implementations
143#
144# CONFIG_ARCH_LUBBOCK is not set
145# CONFIG_MACH_LOGICPD_PXA270 is not set
146# CONFIG_MACH_MAINSTONE is not set
147# CONFIG_ARCH_PXA_IDP is not set
148# CONFIG_PXA_SHARPSL is not set
149# CONFIG_MACH_TRIZEPS4 is not set
150# CONFIG_MACH_EM_X270 is not set
151# CONFIG_MACH_HX2750 is not set
152CONFIG_MACH_HTCUNIVERSAL=y
153
154#
155# HTC Universal support
156#
157CONFIG_HTCUNIVERSAL_CORE=y
158CONFIG_HTCUNIVERSAL_UDC=y
159CONFIG_HTCUNIVERSAL_POWER=y
160CONFIG_HTCUNIVERSAL_BACKLIGHT=y
161CONFIG_HTCUNIVERSAL_LCD=y
162CONFIG_HTCUNIVERSAL_TS2=y
163CONFIG_HTCUNIVERSAL_BUTTONS=y
164CONFIG_HTCUNIVERSAL_BLUETOOTH=m
165CONFIG_HTCUNIVERSAL_ASIC3_LEDS=y
166CONFIG_HTCUNIVERSAL_PHONE=m
167# CONFIG_HTCUNIVERSAL_AK4641 is not set
168CONFIG_PXA27x=y
169# CONFIG_PXA_KEYS is not set
170
171#
172# Boot options
173#
174
175#
176# Power management
177#
178
179#
180# Processor Type
181#
182CONFIG_CPU_32=y
183CONFIG_CPU_XSCALE=y
184CONFIG_CPU_32v5=y
185CONFIG_CPU_ABRT_EV5T=y
186CONFIG_CPU_CACHE_VIVT=y
187CONFIG_CPU_TLB_V4WBI=y
188CONFIG_CPU_CP15=y
189CONFIG_CPU_CP15_MMU=y
190
191#
192# Processor Features
193#
194CONFIG_ARM_THUMB=y
195# CONFIG_CPU_DCACHE_DISABLE is not set
196# CONFIG_OUTER_CACHE is not set
197CONFIG_IWMMXT=y
198CONFIG_XSCALE_PMU=y
199
200#
201# Bus support
202#
203# CONFIG_PCI_SYSCALL is not set
204# CONFIG_ARCH_SUPPORTS_MSI is not set
205
206#
207# PCCARD (PCMCIA/CardBus) support
208#
209# CONFIG_PCCARD is not set
210
211#
212# Kernel Features
213#
214# CONFIG_TICK_ONESHOT is not set
215# CONFIG_NO_HZ is not set
216# CONFIG_HIGH_RES_TIMERS is not set
217CONFIG_PREEMPT=y
218CONFIG_HZ=100
219CONFIG_AEABI=y
220CONFIG_OABI_COMPAT=y
221# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
222CONFIG_SELECT_MEMORY_MODEL=y
223CONFIG_FLATMEM_MANUAL=y
224# CONFIG_DISCONTIGMEM_MANUAL is not set
225# CONFIG_SPARSEMEM_MANUAL is not set
226CONFIG_FLATMEM=y
227CONFIG_FLAT_NODE_MEM_MAP=y
228# CONFIG_SPARSEMEM_STATIC is not set
229CONFIG_SPLIT_PTLOCK_CPUS=4096
230# CONFIG_RESOURCES_64BIT is not set
231CONFIG_ZONE_DMA_FLAG=1
232CONFIG_BOUNCE=y
233CONFIG_VIRT_TO_BUS=y
234CONFIG_ALIGNMENT_TRAP=y
235
236#
237# Boot options
238#
239CONFIG_ZBOOT_ROM_TEXT=0x0
240CONFIG_ZBOOT_ROM_BSS=0x0
241CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 dyntick=enable debug"
242# CONFIG_XIP_KERNEL is not set
243CONFIG_KEXEC=y
244CONFIG_ATAGS_PROC=y
245
246#
247# CPU Frequency scaling
248#
249CONFIG_CPU_FREQ=y
250CONFIG_CPU_FREQ_TABLE=y
251CONFIG_CPU_FREQ_DEBUG=y
252CONFIG_CPU_FREQ_STAT=y
253CONFIG_CPU_FREQ_STAT_DETAILS=y
254# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
255CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
256CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
257# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
258CONFIG_CPU_FREQ_GOV_USERSPACE=y
259# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
260CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
261
262#
263# Floating point emulation
264#
265
266#
267# At least one emulation must be selected
268#
269CONFIG_FPE_NWFPE=y
270# CONFIG_FPE_NWFPE_XP is not set
271# CONFIG_FPE_FASTFPE is not set
272
273#
274# Userspace binary formats
275#
276CONFIG_BINFMT_ELF=y
277# CONFIG_BINFMT_AOUT is not set
278# CONFIG_BINFMT_MISC is not set
279
280#
281# Power management options
282#
283CONFIG_PM=y
284# CONFIG_PM_LEGACY is not set
285# CONFIG_PM_DEBUG is not set
286# CONFIG_SUSPEND is not set
287CONFIG_APM_EMULATION=y
288
289#
290# Networking
291#
292CONFIG_NET=y
293
294#
295# Networking options
296#
297CONFIG_PACKET=m
298CONFIG_PACKET_MMAP=y
299CONFIG_UNIX=y
300# CONFIG_NET_KEY is not set
301CONFIG_INET=y
302CONFIG_IP_MULTICAST=y
303# CONFIG_IP_ADVANCED_ROUTER is not set
304CONFIG_IP_FIB_HASH=y
305CONFIG_IP_PNP=y
306# CONFIG_IP_PNP_DHCP is not set
307# CONFIG_IP_PNP_BOOTP is not set
308# CONFIG_IP_PNP_RARP is not set
309# CONFIG_NET_IPIP is not set
310# CONFIG_NET_IPGRE is not set
311# CONFIG_IP_MROUTE is not set
312# CONFIG_ARPD is not set
313# CONFIG_SYN_COOKIES is not set
314# CONFIG_INET_AH is not set
315# CONFIG_INET_ESP is not set
316# CONFIG_INET_IPCOMP is not set
317# CONFIG_INET_XFRM_TUNNEL is not set
318# CONFIG_INET_TUNNEL is not set
319# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
320# CONFIG_INET_XFRM_MODE_TUNNEL is not set
321# CONFIG_INET_XFRM_MODE_BEET is not set
322# CONFIG_INET_DIAG is not set
323# CONFIG_TCP_CONG_ADVANCED is not set
324CONFIG_TCP_CONG_CUBIC=y
325CONFIG_DEFAULT_TCP_CONG="cubic"
326# CONFIG_TCP_MD5SIG is not set
327# CONFIG_IP_VS is not set
328# CONFIG_IPV6 is not set
329# CONFIG_INET6_XFRM_TUNNEL is not set
330# CONFIG_INET6_TUNNEL is not set
331# CONFIG_NETWORK_SECMARK is not set
332CONFIG_NETFILTER=y
333# CONFIG_NETFILTER_DEBUG is not set
334
335#
336# Core Netfilter Configuration
337#
338# CONFIG_NETFILTER_NETLINK is not set
339# CONFIG_NF_CONNTRACK_ENABLED is not set
340# CONFIG_NF_CONNTRACK is not set
341CONFIG_NETFILTER_XTABLES=m
342# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
343# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
344# CONFIG_NETFILTER_XT_TARGET_MARK is not set
345# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
346# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
347# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
348# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
349# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
350# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
351# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
352# CONFIG_NETFILTER_XT_MATCH_ESP is not set
353# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
354# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
355# CONFIG_NETFILTER_XT_MATCH_MAC is not set
356# CONFIG_NETFILTER_XT_MATCH_MARK is not set
357# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
358# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
359# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
360# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
361# CONFIG_NETFILTER_XT_MATCH_REALM is not set
362# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
363# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
364# CONFIG_NETFILTER_XT_MATCH_STRING is not set
365# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
366# CONFIG_NETFILTER_XT_MATCH_U32 is not set
367# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
368
369#
370# IP: Netfilter Configuration
371#
372CONFIG_IP_NF_QUEUE=m
373CONFIG_IP_NF_IPTABLES=m
374CONFIG_IP_NF_MATCH_IPRANGE=m
375CONFIG_IP_NF_MATCH_TOS=m
376CONFIG_IP_NF_MATCH_RECENT=m
377CONFIG_IP_NF_MATCH_ECN=m
378CONFIG_IP_NF_MATCH_AH=m
379CONFIG_IP_NF_MATCH_TTL=m
380CONFIG_IP_NF_MATCH_OWNER=m
381CONFIG_IP_NF_MATCH_ADDRTYPE=m
382CONFIG_IP_NF_FILTER=m
383CONFIG_IP_NF_TARGET_REJECT=m
384CONFIG_IP_NF_TARGET_LOG=m
385CONFIG_IP_NF_TARGET_ULOG=m
386CONFIG_IP_NF_MANGLE=m
387CONFIG_IP_NF_TARGET_TOS=m
388CONFIG_IP_NF_TARGET_ECN=m
389CONFIG_IP_NF_TARGET_TTL=m
390CONFIG_IP_NF_RAW=m
391CONFIG_IP_NF_ARPTABLES=m
392CONFIG_IP_NF_ARPFILTER=m
393CONFIG_IP_NF_ARP_MANGLE=m
394
395#
396# QoS and/or fair queueing
397#
398# CONFIG_NET_SCHED is not set
399
400#
401# Network testing
402#
403# CONFIG_NET_PKTGEN is not set
404# CONFIG_HAMRADIO is not set
405CONFIG_IRDA=y
406
407#
408# IrDA protocols
409#
410CONFIG_IRLAN=y
411# CONFIG_IRNET is not set
412CONFIG_IRCOMM=y
413CONFIG_IRDA_ULTRA=y
414
415#
416# IrDA options
417#
418CONFIG_IRDA_CACHE_LAST_LSAP=y
419CONFIG_IRDA_FAST_RR=y
420CONFIG_IRDA_DEBUG=y
421
422#
423# Infrared-port device drivers
424#
425
426#
427# SIR device drivers
428#
429CONFIG_IRTTY_SIR=y
430
431#
432# Dongle support
433#
434# CONFIG_DONGLE is not set
435
436#
437# Old SIR device drivers
438#
439# CONFIG_IRPORT_SIR is not set
440
441#
442# Old Serial dongle support
443#
444
445#
446# FIR device drivers
447#
448CONFIG_PXA_FICP=y
449CONFIG_BT=m
450CONFIG_BT_L2CAP=m
451CONFIG_BT_SCO=m
452CONFIG_BT_RFCOMM=m
453CONFIG_BT_RFCOMM_TTY=y
454CONFIG_BT_BNEP=m
455CONFIG_BT_BNEP_MC_FILTER=y
456CONFIG_BT_BNEP_PROTO_FILTER=y
457CONFIG_BT_HIDP=m
458
459#
460# Bluetooth device drivers
461#
462CONFIG_BT_HCIUART=m
463CONFIG_BT_HCIUART_H4=y
464CONFIG_BT_HCIUART_BCSP=y
465# CONFIG_BT_HCIVHCI is not set
466# CONFIG_AF_RXRPC is not set
467
468#
469# Wireless
470#
471# CONFIG_CFG80211 is not set
472CONFIG_WIRELESS_EXT=y
473# CONFIG_MAC80211 is not set
474# CONFIG_IEEE80211 is not set
475# CONFIG_RFKILL is not set
476# CONFIG_NET_9P is not set
477
478#
479# Device Drivers
480#
481
482#
483# Generic Driver Options
484#
485CONFIG_STANDALONE=y
486CONFIG_PREVENT_FIRMWARE_BUILD=y
487CONFIG_FW_LOADER=y
488# CONFIG_DEBUG_DRIVER is not set
489# CONFIG_DEBUG_DEVRES is not set
490# CONFIG_SYS_HYPERVISOR is not set
491# CONFIG_CONNECTOR is not set
492CONFIG_MTD=y
493CONFIG_MTD_DEBUG=y
494CONFIG_MTD_DEBUG_VERBOSE=0
495# CONFIG_MTD_CONCAT is not set
496CONFIG_MTD_PARTITIONS=y
497# CONFIG_MTD_REDBOOT_PARTS is not set
498# CONFIG_MTD_CMDLINE_PARTS is not set
499# CONFIG_MTD_AFS_PARTS is not set
500
501#
502# User Modules And Translation Layers
503#
504# CONFIG_MTD_CHAR is not set
505# CONFIG_MTD_BLKDEVS is not set
506# CONFIG_MTD_BLOCK is not set
507# CONFIG_MTD_BLOCK_RO is not set
508# CONFIG_FTL is not set
509# CONFIG_NFTL is not set
510# CONFIG_INFTL is not set
511# CONFIG_RFD_FTL is not set
512# CONFIG_SSFDC is not set
513
514#
515# RAM/ROM/Flash chip drivers
516#
517# CONFIG_MTD_CFI is not set
518# CONFIG_MTD_JEDECPROBE is not set
519CONFIG_MTD_MAP_BANK_WIDTH_1=y
520CONFIG_MTD_MAP_BANK_WIDTH_2=y
521CONFIG_MTD_MAP_BANK_WIDTH_4=y
522# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
523# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
524# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
525CONFIG_MTD_CFI_I1=y
526CONFIG_MTD_CFI_I2=y
527# CONFIG_MTD_CFI_I4 is not set
528# CONFIG_MTD_CFI_I8 is not set
529# CONFIG_MTD_RAM is not set
530# CONFIG_MTD_ROM is not set
531# CONFIG_MTD_ABSENT is not set
532
533#
534# Mapping drivers for chip access
535#
536# CONFIG_MTD_COMPLEX_MAPPINGS is not set
537# CONFIG_MTD_SHARP_SL is not set
538# CONFIG_MTD_PLATRAM is not set
539
540#
541# Self-contained MTD device drivers
542#
543# CONFIG_MTD_SLRAM is not set
544# CONFIG_MTD_PHRAM is not set
545CONFIG_MTD_MTDRAM=m
546CONFIG_MTDRAM_TOTAL_SIZE=4096
547CONFIG_MTDRAM_ERASE_SIZE=128
548# CONFIG_MTD_BLOCK2MTD is not set
549
550#
551# Disk-On-Chip Device Drivers
552#
553# CONFIG_MTD_DOC2000 is not set
554# CONFIG_MTD_DOC2001 is not set
555# CONFIG_MTD_DOC2001PLUS is not set
556# CONFIG_MTD_NAND is not set
557# CONFIG_MTD_ONENAND is not set
558
559#
560# UBI - Unsorted block images
561#
562# CONFIG_MTD_UBI is not set
563# CONFIG_PARPORT is not set
564CONFIG_BLK_DEV=y
565# CONFIG_BLK_DEV_COW_COMMON is not set
566# CONFIG_BLK_DEV_LOOP is not set
567# CONFIG_BLK_DEV_NBD is not set
568# CONFIG_BLK_DEV_RAM is not set
569# CONFIG_CDROM_PKTCDVD is not set
570# CONFIG_ATA_OVER_ETH is not set
571# CONFIG_IDE is not set
572
573#
574# SCSI device support
575#
576# CONFIG_RAID_ATTRS is not set
577# CONFIG_SCSI is not set
578# CONFIG_SCSI_DMA is not set
579# CONFIG_SCSI_NETLINK is not set
580# CONFIG_ATA is not set
581# CONFIG_MD is not set
582CONFIG_NETDEVICES=y
583# CONFIG_NETDEVICES_MULTIQUEUE is not set
584# CONFIG_DUMMY is not set
585# CONFIG_BONDING is not set
586# CONFIG_MACVLAN is not set
587# CONFIG_EQUALIZER is not set
588# CONFIG_TUN is not set
589# CONFIG_NET_ETHERNET is not set
590# CONFIG_NETDEV_1000 is not set
591# CONFIG_NETDEV_10000 is not set
592
593#
594# Wireless LAN
595#
596CONFIG_NET_RADIO=y
597# CONFIG_NET_WIRELESS_RTNETLINK is not set
598# CONFIG_WLAN_PRE80211 is not set
599# CONFIG_WLAN_80211 is not set
600CONFIG_ACX=m
601CONFIG_ACX_MEM=y
602# CONFIG_ACX_CS is not set
603CONFIG_ACX_HTCUNIVERSAL=m
604# CONFIG_WAN is not set
605CONFIG_PPP=m
606# CONFIG_PPP_MULTILINK is not set
607# CONFIG_PPP_FILTER is not set
608CONFIG_PPP_ASYNC=m
609# CONFIG_PPP_SYNC_TTY is not set
610CONFIG_PPP_DEFLATE=m
611CONFIG_PPP_BSDCOMP=m
612CONFIG_PPP_MPPE=m
613# CONFIG_PPPOE is not set
614# CONFIG_PPPOL2TP is not set
615# CONFIG_SLIP is not set
616CONFIG_SLHC=m
617# CONFIG_SHAPER is not set
618# CONFIG_NETCONSOLE is not set
619# CONFIG_NETPOLL is not set
620# CONFIG_NET_POLL_CONTROLLER is not set
621# CONFIG_ISDN is not set
622
623#
624# Input device support
625#
626CONFIG_INPUT=y
627# CONFIG_INPUT_FF_MEMLESS is not set
628# CONFIG_INPUT_POLLDEV is not set
629
630#
631# Userland interfaces
632#
633# CONFIG_INPUT_MOUSEDEV is not set
634# CONFIG_INPUT_JOYDEV is not set
635# CONFIG_INPUT_TSDEV is not set
636CONFIG_INPUT_EVDEV=y
637# CONFIG_INPUT_EVBUG is not set
638# CONFIG_INPUT_POWER is not set
639
640#
641# Input Device Drivers
642#
643CONFIG_INPUT_KEYBOARD=y
644# CONFIG_KEYBOARD_ATKBD is not set
645# CONFIG_KEYBOARD_SUNKBD is not set
646# CONFIG_KEYBOARD_LKKBD is not set
647# CONFIG_KEYBOARD_XTKBD is not set
648# CONFIG_KEYBOARD_NEWTON is not set
649# CONFIG_KEYBOARD_STOWAWAY is not set
650CONFIG_KEYBOARD_PXA27x=y
651CONFIG_KEYBOARD_GPIO=y
652CONFIG_KEYBOARD_ASIC3=y
653CONFIG_INPUT_MOUSE=y
654# CONFIG_MOUSE_PS2 is not set
655# CONFIG_MOUSE_SERIAL is not set
656# CONFIG_MOUSE_APPLETOUCH is not set
657# CONFIG_MOUSE_VSXXXAA is not set
658# CONFIG_MOUSE_GPIO is not set
659# CONFIG_INPUT_JOYSTICK is not set
660# CONFIG_INPUT_TABLET is not set
661CONFIG_INPUT_TOUCHSCREEN=y
662# CONFIG_TOUCHSCREEN_FUJITSU is not set
663# CONFIG_TOUCHSCREEN_GUNZE is not set
664# CONFIG_TOUCHSCREEN_ELO is not set
665# CONFIG_TOUCHSCREEN_MTOUCH is not set
666# CONFIG_TOUCHSCREEN_MK712 is not set
667# CONFIG_TOUCHSCREEN_PENMOUNT is not set
668# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
669# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
670# CONFIG_TOUCHSCREEN_UCB1400 is not set
671# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
672CONFIG_INPUT_MISC=y
673# CONFIG_INPUT_ATI_REMOTE is not set
674# CONFIG_INPUT_ATI_REMOTE2 is not set
675# CONFIG_INPUT_KEYSPAN_REMOTE is not set
676# CONFIG_INPUT_POWERMATE is not set
677# CONFIG_INPUT_YEALINK is not set
678CONFIG_INPUT_UINPUT=m
679
680#
681# Hardware I/O ports
682#
683# CONFIG_SERIO is not set
684# CONFIG_GAMEPORT is not set
685
686#
687# Character devices
688#
689CONFIG_VT=y
690CONFIG_VT_CONSOLE=y
691CONFIG_HW_CONSOLE=y
692# CONFIG_VT_HW_CONSOLE_BINDING is not set
693# CONFIG_SERIAL_NONSTANDARD is not set
694
695#
696# Serial drivers
697#
698# CONFIG_SERIAL_8250 is not set
699
700#
701# Non-8250 serial port support
702#
703CONFIG_SERIAL_PXA=y
704CONFIG_SERIAL_PXA_CONSOLE=y
705CONFIG_SERIAL_CORE=y
706CONFIG_SERIAL_CORE_CONSOLE=y
707CONFIG_UNIX98_PTYS=y
708CONFIG_LEGACY_PTYS=y
709CONFIG_LEGACY_PTY_COUNT=32
710# CONFIG_IPMI_HANDLER is not set
711# CONFIG_WATCHDOG is not set
712# CONFIG_HW_RANDOM is not set
713# CONFIG_NVRAM is not set
714# CONFIG_R3964 is not set
715# CONFIG_RAW_DRIVER is not set
716# CONFIG_TCG_TPM is not set
717CONFIG_I2C=m
718CONFIG_I2C_BOARDINFO=y
719# CONFIG_I2C_CHARDEV is not set
720
721#
722# I2C Algorithms
723#
724# CONFIG_I2C_ALGOBIT is not set
725# CONFIG_I2C_ALGOPCF is not set
726# CONFIG_I2C_ALGOPCA is not set
727
728#
729# I2C Hardware Bus support
730#
731# CONFIG_I2C_GPIO is not set
732CONFIG_I2C_PXA=m
733# CONFIG_I2C_PXA_SLAVE is not set
734# CONFIG_I2C_OCORES is not set
735# CONFIG_I2C_PARPORT_LIGHT is not set
736# CONFIG_I2C_SIMTEC is not set
737# CONFIG_I2C_TAOS_EVM is not set
738# CONFIG_I2C_STUB is not set
739
740#
741# Miscellaneous I2C Chip support
742#
743# CONFIG_SENSORS_DS1337 is not set
744# CONFIG_SENSORS_DS1374 is not set
745# CONFIG_DS1682 is not set
746# CONFIG_SENSORS_EEPROM is not set
747# CONFIG_SENSORS_PCF8574 is not set
748# CONFIG_SENSORS_PCA9539 is not set
749# CONFIG_SENSORS_PCF8591 is not set
750# CONFIG_SENSORS_MAX6875 is not set
751# CONFIG_SENSORS_TSL2550 is not set
752# CONFIG_I2C_DEBUG_CORE is not set
753# CONFIG_I2C_DEBUG_ALGO is not set
754# CONFIG_I2C_DEBUG_BUS is not set
755# CONFIG_I2C_DEBUG_CHIP is not set
756
757#
758# SPI support
759#
760# CONFIG_SPI is not set
761# CONFIG_SPI_MASTER is not set
762CONFIG_W1=y
763
764#
765# 1-wire Bus Masters
766#
767# CONFIG_W1_MASTER_DS2482 is not set
768CONFIG_W1_MASTER_DS1WM=y
769
770#
771# 1-wire Slaves
772#
773# CONFIG_W1_SLAVE_THERM is not set
774# CONFIG_W1_SLAVE_SMEM is not set
775# CONFIG_W1_SLAVE_DS2433 is not set
776CONFIG_W1_SLAVE_DS2760=y
777CONFIG_POWER_SUPPLY=y
778# CONFIG_POWER_SUPPLY_DEBUG is not set
779CONFIG_PDA_POWER=y
780CONFIG_APM_POWER=y
781CONFIG_BATTERY_DS2760=y
782# CONFIG_HWMON is not set
783CONFIG_MISC_DEVICES=y
784# CONFIG_EEPROM_93CX6 is not set
785
786#
787# Multifunction device drivers
788#
789# CONFIG_MFD_SM501 is not set
790CONFIG_HTC_ASIC3=y
791CONFIG_HTC_ASIC3_DS1WM=y
792
793#
794# Multi-Function Devices
795#
796CONFIG_NEW_LEDS=y
797CONFIG_LEDS_CLASS=y
798
799#
800# LED drivers
801#
802# CONFIG_LEDS_GPIO is not set
803CONFIG_LEDS_ASIC3=y
804
805#
806# LED Triggers
807#
808CONFIG_LEDS_TRIGGERS=y
809CONFIG_LEDS_TRIGGER_TIMER=y
810# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
811
812#
813# Multimedia devices
814#
815# CONFIG_VIDEO_DEV is not set
816# CONFIG_DVB_CORE is not set
817CONFIG_DAB=y
818
819#
820# Graphics support
821#
822CONFIG_BACKLIGHT_LCD_SUPPORT=y
823CONFIG_LCD_CLASS_DEVICE=y
824CONFIG_BACKLIGHT_CLASS_DEVICE=y
825CONFIG_BACKLIGHT_CORGI=y
826
827#
828# Display device support
829#
830# CONFIG_DISPLAY_SUPPORT is not set
831# CONFIG_VGASTATE is not set
832CONFIG_VIDEO_OUTPUT_CONTROL=m
833CONFIG_FB=y
834# CONFIG_FIRMWARE_EDID is not set
835# CONFIG_FB_DDC is not set
836CONFIG_FB_CFB_FILLRECT=y
837CONFIG_FB_CFB_COPYAREA=y
838CONFIG_FB_CFB_IMAGEBLIT=y
839# CONFIG_FB_SYS_FILLRECT is not set
840# CONFIG_FB_SYS_COPYAREA is not set
841# CONFIG_FB_SYS_IMAGEBLIT is not set
842# CONFIG_FB_SYS_FOPS is not set
843CONFIG_FB_DEFERRED_IO=y
844# CONFIG_FB_SVGALIB is not set
845# CONFIG_FB_MACMODES is not set
846# CONFIG_FB_BACKLIGHT is not set
847# CONFIG_FB_MODE_HELPERS is not set
848# CONFIG_FB_TILEBLITTING is not set
849
850#
851# Frame buffer hardware drivers
852#
853# CONFIG_FB_S1D13XXX is not set
854CONFIG_FB_PXA=y
855CONFIG_FB_PXA_LCD_QVGA=y
856# CONFIG_FB_PXA_LCD_VGA is not set
857# CONFIG_FB_PXA_OVERLAY is not set
858# CONFIG_FB_PXA_PARAMETERS is not set
859# CONFIG_FB_MBX is not set
860# CONFIG_FB_VIRTUAL is not set
861
862#
863# Console display driver support
864#
865# CONFIG_VGA_CONSOLE is not set
866CONFIG_DUMMY_CONSOLE=y
867CONFIG_FRAMEBUFFER_CONSOLE=y
868# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
869CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
870CONFIG_FONTS=y
871CONFIG_FONT_8x8=y
872# CONFIG_FONT_8x16 is not set
873# CONFIG_FONT_6x11 is not set
874# CONFIG_FONT_7x14 is not set
875# CONFIG_FONT_PEARL_8x8 is not set
876# CONFIG_FONT_ACORN_8x8 is not set
877# CONFIG_FONT_MINI_4x6 is not set
878# CONFIG_FONT_SUN8x16 is not set
879# CONFIG_FONT_SUN12x22 is not set
880# CONFIG_FONT_10x18 is not set
881CONFIG_LOGO=y
882CONFIG_LOGO_LINUX_MONO=y
883CONFIG_LOGO_LINUX_VGA16=y
884# CONFIG_LOGO_LINUX_CLUT224 is not set
885CONFIG_LOGO_OHAND_CLUT224=y
886# CONFIG_LOGO_OZ240_CLUT224 is not set
887# CONFIG_LOGO_OZ480_CLUT224 is not set
888# CONFIG_LOGO_OZ640_CLUT224 is not set
889
890#
891# Sound
892#
893CONFIG_SOUND=y
894
895#
896# Advanced Linux Sound Architecture
897#
898CONFIG_SND=y
899CONFIG_SND_TIMER=y
900CONFIG_SND_PCM=y
901# CONFIG_SND_SEQUENCER is not set
902CONFIG_SND_OSSEMUL=y
903CONFIG_SND_MIXER_OSS=y
904CONFIG_SND_PCM_OSS=y
905CONFIG_SND_PCM_OSS_PLUGINS=y
906# CONFIG_SND_DYNAMIC_MINORS is not set
907CONFIG_SND_SUPPORT_OLD_API=y
908CONFIG_SND_VERBOSE_PROCFS=y
909# CONFIG_SND_VERBOSE_PRINTK is not set
910# CONFIG_SND_DEBUG is not set
911
912#
913# Generic devices
914#
915# CONFIG_SND_DUMMY is not set
916# CONFIG_SND_MTPAV is not set
917# CONFIG_SND_SERIAL_U16550 is not set
918# CONFIG_SND_MPU401 is not set
919
920#
921# ALSA ARM devices
922#
923# CONFIG_SND_PXA2XX_AC97 is not set
924
925#
926# System on Chip audio support
927#
928# CONFIG_SND_SOC is not set
929
930#
931# SoC Audio support for SuperH
932#
933
934#
935# Open Sound System
936#
937# CONFIG_SOUND_PRIME is not set
938CONFIG_HID_SUPPORT=y
939CONFIG_HID=m
940# CONFIG_HID_DEBUG is not set
941CONFIG_USB_SUPPORT=y
942CONFIG_USB_ARCH_HAS_HCD=y
943CONFIG_USB_ARCH_HAS_OHCI=y
944# CONFIG_USB_ARCH_HAS_EHCI is not set
945# CONFIG_USB is not set
946
947#
948# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
949#
950
951#
952# USB Gadget Support
953#
954CONFIG_USB_GADGET=y
955# CONFIG_USB_GADGET_DEBUG is not set
956# CONFIG_USB_GADGET_DEBUG_FILES is not set
957CONFIG_USB_GADGET_SELECTED=y
958# CONFIG_USB_GADGET_AMD5536UDC is not set
959# CONFIG_USB_GADGET_FSL_USB2 is not set
960# CONFIG_USB_GADGET_NET2280 is not set
961# CONFIG_USB_GADGET_PXA2XX is not set
962# CONFIG_USB_GADGET_M66592 is not set
963CONFIG_USB_GADGET_PXA27X=y
964CONFIG_USB_PXA27X=y
965# CONFIG_USB_GADGET_GOKU is not set
966# CONFIG_USB_GADGET_LH7A40X is not set
967# CONFIG_USB_GADGET_OMAP is not set
968# CONFIG_USB_GADGET_S3C2410 is not set
969# CONFIG_USB_GADGET_AT91 is not set
970# CONFIG_USB_GADGET_DUMMY_HCD is not set
971# CONFIG_USB_GADGET_DUALSPEED is not set
972# CONFIG_USB_ZERO is not set
973CONFIG_USB_ETH=y
974CONFIG_USB_ETH_RNDIS=y
975# CONFIG_USB_GADGETFS is not set
976# CONFIG_USB_FILE_STORAGE is not set
977# CONFIG_USB_G_SERIAL is not set
978# CONFIG_USB_MIDI_GADGET is not set
979CONFIG_MMC=y
980# CONFIG_MMC_DEBUG is not set
981CONFIG_MMC_UNSAFE_RESUME=y
982
983#
984# MMC/SD Card Drivers
985#
986CONFIG_MMC_BLOCK=y
987CONFIG_MMC_BLOCK_BOUNCE=y
988
989#
990# MMC/SD Host Controller Drivers
991#
992# CONFIG_MMC_PXA is not set
993CONFIG_MMC_ASIC3=y
994CONFIG_RTC_LIB=y
995CONFIG_RTC_CLASS=y
996CONFIG_RTC_HCTOSYS=y
997CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
998CONFIG_RTC_DEBUG=y
999
1000#
1001# RTC interfaces
1002#
1003CONFIG_RTC_INTF_SYSFS=y
1004CONFIG_RTC_INTF_PROC=y
1005CONFIG_RTC_INTF_DEV=y
1006# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1007# CONFIG_RTC_DRV_TEST is not set
1008
1009#
1010# I2C RTC drivers
1011#
1012# CONFIG_RTC_DRV_DS1307 is not set
1013# CONFIG_RTC_DRV_DS1672 is not set
1014# CONFIG_RTC_DRV_MAX6900 is not set
1015# CONFIG_RTC_DRV_RS5C372 is not set
1016# CONFIG_RTC_DRV_ISL1208 is not set
1017# CONFIG_RTC_DRV_X1205 is not set
1018# CONFIG_RTC_DRV_PCF8563 is not set
1019# CONFIG_RTC_DRV_PCF8583 is not set
1020# CONFIG_RTC_DRV_M41T80 is not set
1021
1022#
1023# SPI RTC drivers
1024#
1025
1026#
1027# Platform RTC drivers
1028#
1029# CONFIG_RTC_DRV_CMOS is not set
1030# CONFIG_RTC_DRV_DS1553 is not set
1031# CONFIG_RTC_DRV_STK17TA8 is not set
1032# CONFIG_RTC_DRV_DS1742 is not set
1033# CONFIG_RTC_DRV_M48T86 is not set
1034# CONFIG_RTC_DRV_M48T59 is not set
1035# CONFIG_RTC_DRV_V3020 is not set
1036
1037#
1038# on-CPU RTC drivers
1039#
1040CONFIG_RTC_DRV_SA1100=y
1041
1042#
1043# DMA Engine support
1044#
1045# CONFIG_DMA_ENGINE is not set
1046
1047#
1048# DMA Clients
1049#
1050
1051#
1052# DMA Devices
1053#
1054
1055#
1056# File systems
1057#
1058CONFIG_EXT2_FS=y
1059# CONFIG_EXT2_FS_XATTR is not set
1060# CONFIG_EXT2_FS_XIP is not set
1061CONFIG_EXT3_FS=y
1062# CONFIG_EXT3_FS_XATTR is not set
1063# CONFIG_EXT4DEV_FS is not set
1064CONFIG_JBD=y
1065# CONFIG_JBD_DEBUG is not set
1066# CONFIG_REISERFS_FS is not set
1067# CONFIG_JFS_FS is not set
1068# CONFIG_FS_POSIX_ACL is not set
1069# CONFIG_XFS_FS is not set
1070# CONFIG_GFS2_FS is not set
1071# CONFIG_OCFS2_FS is not set
1072# CONFIG_MINIX_FS is not set
1073# CONFIG_ROMFS_FS is not set
1074CONFIG_INOTIFY=y
1075CONFIG_INOTIFY_USER=y
1076# CONFIG_QUOTA is not set
1077CONFIG_DNOTIFY=y
1078# CONFIG_AUTOFS_FS is not set
1079# CONFIG_AUTOFS4_FS is not set
1080# CONFIG_FUSE_FS is not set
1081
1082#
1083# CD-ROM/DVD Filesystems
1084#
1085# CONFIG_ISO9660_FS is not set
1086# CONFIG_UDF_FS is not set
1087
1088#
1089# DOS/FAT/NT Filesystems
1090#
1091CONFIG_FAT_FS=y
1092CONFIG_MSDOS_FS=y
1093CONFIG_VFAT_FS=y
1094CONFIG_FAT_DEFAULT_CODEPAGE=437
1095CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1096# CONFIG_NTFS_FS is not set
1097
1098#
1099# Pseudo filesystems
1100#
1101CONFIG_PROC_FS=y
1102CONFIG_PROC_SYSCTL=y
1103CONFIG_SYSFS=y
1104CONFIG_TMPFS=y
1105# CONFIG_TMPFS_POSIX_ACL is not set
1106# CONFIG_HUGETLB_PAGE is not set
1107CONFIG_RAMFS=y
1108# CONFIG_CONFIGFS_FS is not set
1109
1110#
1111# Miscellaneous filesystems
1112#
1113# CONFIG_ADFS_FS is not set
1114# CONFIG_AFFS_FS is not set
1115# CONFIG_HFS_FS is not set
1116# CONFIG_HFSPLUS_FS is not set
1117# CONFIG_BEFS_FS is not set
1118# CONFIG_BFS_FS is not set
1119# CONFIG_EFS_FS is not set
1120# CONFIG_JFFS2_FS is not set
1121# CONFIG_CRAMFS is not set
1122# CONFIG_SQUASHFS is not set
1123# CONFIG_VXFS_FS is not set
1124# CONFIG_HPFS_FS is not set
1125# CONFIG_QNX4FS_FS is not set
1126# CONFIG_SYSV_FS is not set
1127# CONFIG_UFS_FS is not set
1128
1129#
1130# Network File Systems
1131#
1132CONFIG_NFS_FS=y
1133CONFIG_NFS_V3=y
1134# CONFIG_NFS_V3_ACL is not set
1135# CONFIG_NFS_V4 is not set
1136# CONFIG_NFS_DIRECTIO is not set
1137# CONFIG_NFSD is not set
1138CONFIG_ROOT_NFS=y
1139CONFIG_LOCKD=y
1140CONFIG_LOCKD_V4=y
1141CONFIG_NFS_COMMON=y
1142CONFIG_SUNRPC=y
1143# CONFIG_SUNRPC_BIND34 is not set
1144# CONFIG_RPCSEC_GSS_KRB5 is not set
1145# CONFIG_RPCSEC_GSS_SPKM3 is not set
1146# CONFIG_SMB_FS is not set
1147# CONFIG_CIFS is not set
1148# CONFIG_NCP_FS is not set
1149# CONFIG_CODA_FS is not set
1150# CONFIG_AFS_FS is not set
1151
1152#
1153# Partition Types
1154#
1155# CONFIG_PARTITION_ADVANCED is not set
1156CONFIG_MSDOS_PARTITION=y
1157
1158#
1159# Native Language Support
1160#
1161CONFIG_NLS=y
1162CONFIG_NLS_DEFAULT="iso8859-1"
1163CONFIG_NLS_CODEPAGE_437=y
1164# CONFIG_NLS_CODEPAGE_737 is not set
1165# CONFIG_NLS_CODEPAGE_775 is not set
1166# CONFIG_NLS_CODEPAGE_850 is not set
1167# CONFIG_NLS_CODEPAGE_852 is not set
1168# CONFIG_NLS_CODEPAGE_855 is not set
1169# CONFIG_NLS_CODEPAGE_857 is not set
1170# CONFIG_NLS_CODEPAGE_860 is not set
1171# CONFIG_NLS_CODEPAGE_861 is not set
1172# CONFIG_NLS_CODEPAGE_862 is not set
1173# CONFIG_NLS_CODEPAGE_863 is not set
1174# CONFIG_NLS_CODEPAGE_864 is not set
1175# CONFIG_NLS_CODEPAGE_865 is not set
1176# CONFIG_NLS_CODEPAGE_866 is not set
1177# CONFIG_NLS_CODEPAGE_869 is not set
1178# CONFIG_NLS_CODEPAGE_936 is not set
1179# CONFIG_NLS_CODEPAGE_950 is not set
1180# CONFIG_NLS_CODEPAGE_932 is not set
1181# CONFIG_NLS_CODEPAGE_949 is not set
1182# CONFIG_NLS_CODEPAGE_874 is not set
1183# CONFIG_NLS_ISO8859_8 is not set
1184CONFIG_NLS_CODEPAGE_1250=y
1185CONFIG_NLS_CODEPAGE_1251=y
1186# CONFIG_NLS_ASCII is not set
1187CONFIG_NLS_ISO8859_1=y
1188# CONFIG_NLS_ISO8859_2 is not set
1189# CONFIG_NLS_ISO8859_3 is not set
1190# CONFIG_NLS_ISO8859_4 is not set
1191# CONFIG_NLS_ISO8859_5 is not set
1192# CONFIG_NLS_ISO8859_6 is not set
1193# CONFIG_NLS_ISO8859_7 is not set
1194# CONFIG_NLS_ISO8859_9 is not set
1195# CONFIG_NLS_ISO8859_13 is not set
1196# CONFIG_NLS_ISO8859_14 is not set
1197# CONFIG_NLS_ISO8859_15 is not set
1198# CONFIG_NLS_KOI8_R is not set
1199# CONFIG_NLS_KOI8_U is not set
1200CONFIG_NLS_UTF8=y
1201
1202#
1203# Distributed Lock Manager
1204#
1205# CONFIG_DLM is not set
1206
1207#
1208# Profiling support
1209#
1210# CONFIG_PROFILING is not set
1211
1212#
1213# Kernel hacking
1214#
1215CONFIG_PRINTK_TIME=y
1216CONFIG_ENABLE_MUST_CHECK=y
1217# CONFIG_MAGIC_SYSRQ is not set
1218# CONFIG_UNUSED_SYMBOLS is not set
1219# CONFIG_DEBUG_FS is not set
1220# CONFIG_HEADERS_CHECK is not set
1221CONFIG_DEBUG_KERNEL=y
1222# CONFIG_DEBUG_SHIRQ is not set
1223CONFIG_DETECT_SOFTLOCKUP=y
1224CONFIG_SCHED_DEBUG=y
1225# CONFIG_SCHEDSTATS is not set
1226# CONFIG_TIMER_STATS is not set
1227# CONFIG_DEBUG_SLAB is not set
1228CONFIG_DEBUG_PREEMPT=y
1229# CONFIG_DEBUG_RT_MUTEXES is not set
1230# CONFIG_RT_MUTEX_TESTER is not set
1231# CONFIG_DEBUG_SPINLOCK is not set
1232CONFIG_DEBUG_MUTEXES=y
1233# CONFIG_DEBUG_LOCK_ALLOC is not set
1234# CONFIG_PROVE_LOCKING is not set
1235# CONFIG_LOCK_STAT is not set
1236# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1237# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1238# CONFIG_DEBUG_KOBJECT is not set
1239CONFIG_DEBUG_BUGVERBOSE=y
1240# CONFIG_DEBUG_INFO is not set
1241CONFIG_DEBUG_VM=y
1242# CONFIG_DEBUG_LIST is not set
1243CONFIG_FRAME_POINTER=y
1244CONFIG_FORCED_INLINING=y
1245# CONFIG_RCU_TORTURE_TEST is not set
1246# CONFIG_FAULT_INJECTION is not set
1247CONFIG_DEBUG_USER=y
1248CONFIG_DEBUG_ERRORS=y
1249CONFIG_DEBUG_LL=y
1250# CONFIG_DEBUG_ICEDCC is not set
1251
1252#
1253# Security options
1254#
1255# CONFIG_KEYS is not set
1256# CONFIG_SECURITY is not set
1257CONFIG_CRYPTO=y
1258CONFIG_CRYPTO_ALGAPI=y
1259CONFIG_CRYPTO_BLKCIPHER=m
1260CONFIG_CRYPTO_HASH=y
1261CONFIG_CRYPTO_MANAGER=y
1262CONFIG_CRYPTO_HMAC=y
1263# CONFIG_CRYPTO_XCBC is not set
1264# CONFIG_CRYPTO_NULL is not set
1265# CONFIG_CRYPTO_MD4 is not set
1266CONFIG_CRYPTO_MD5=y
1267CONFIG_CRYPTO_SHA1=y
1268# CONFIG_CRYPTO_SHA256 is not set
1269# CONFIG_CRYPTO_SHA512 is not set
1270# CONFIG_CRYPTO_WP512 is not set
1271# CONFIG_CRYPTO_TGR192 is not set
1272# CONFIG_CRYPTO_GF128MUL is not set
1273CONFIG_CRYPTO_ECB=m
1274# CONFIG_CRYPTO_CBC is not set
1275CONFIG_CRYPTO_PCBC=m
1276# CONFIG_CRYPTO_LRW is not set
1277# CONFIG_CRYPTO_CRYPTD is not set
1278CONFIG_CRYPTO_DES=y
1279# CONFIG_CRYPTO_FCRYPT is not set
1280# CONFIG_CRYPTO_BLOWFISH is not set
1281# CONFIG_CRYPTO_TWOFISH is not set
1282# CONFIG_CRYPTO_SERPENT is not set
1283# CONFIG_CRYPTO_AES is not set
1284# CONFIG_CRYPTO_CAST5 is not set
1285# CONFIG_CRYPTO_CAST6 is not set
1286# CONFIG_CRYPTO_TEA is not set
1287CONFIG_CRYPTO_ARC4=m
1288# CONFIG_CRYPTO_KHAZAD is not set
1289# CONFIG_CRYPTO_ANUBIS is not set
1290CONFIG_CRYPTO_DEFLATE=y
1291# CONFIG_CRYPTO_LZO is not set
1292# CONFIG_CRYPTO_MICHAEL_MIC is not set
1293# CONFIG_CRYPTO_CRC32C is not set
1294# CONFIG_CRYPTO_CAMELLIA is not set
1295# CONFIG_CRYPTO_TEST is not set
1296CONFIG_CRYPTO_HW=y
1297
1298#
1299# Library routines
1300#
1301CONFIG_BITREVERSE=y
1302CONFIG_CRC_CCITT=y
1303# CONFIG_CRC16 is not set
1304# CONFIG_CRC_ITU_T is not set
1305CONFIG_CRC32=y
1306# CONFIG_CRC7 is not set
1307# CONFIG_LIBCRC32C is not set
1308CONFIG_ZLIB_INFLATE=y
1309CONFIG_ZLIB_DEFLATE=y
1310CONFIG_PLIST=y
1311CONFIG_HAS_IOMEM=y
1312CONFIG_HAS_IOPORT=y
1313CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-hx2000 b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-hx2000
new file mode 100644
index 0000000000..447d26da80
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-hx2000
@@ -0,0 +1,1231 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20-rc2
4# Mon Jan 1 01:49:04 2007
5#
6CONFIG_ARM=y
7# CONFIG_GENERIC_TIME is not set
8CONFIG_MMU=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_TRACE_IRQFLAGS_SUPPORT=y
11CONFIG_HARDIRQS_SW_RESEND=y
12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_RWSEM_GENERIC_SPINLOCK=y
14# CONFIG_ARCH_HAS_ILOG2_U32 is not set
15# CONFIG_ARCH_HAS_ILOG2_U64 is not set
16CONFIG_GENERIC_HWEIGHT=y
17CONFIG_GENERIC_CALIBRATE_DELAY=y
18CONFIG_ARCH_MTD_XIP=y
19CONFIG_VECTORS_BASE=0xffff0000
20CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
21
22#
23# Code maturity level options
24#
25CONFIG_EXPERIMENTAL=y
26CONFIG_BROKEN_ON_SMP=y
27CONFIG_LOCK_KERNEL=y
28CONFIG_INIT_ENV_ARG_LIMIT=32
29
30#
31# General setup
32#
33CONFIG_LOCALVERSION=""
34# CONFIG_LOCALVERSION_AUTO is not set
35# CONFIG_SWAP is not set
36CONFIG_SYSVIPC=y
37# CONFIG_IPC_NS is not set
38# CONFIG_POSIX_MQUEUE is not set
39# CONFIG_BSD_PROCESS_ACCT is not set
40# CONFIG_TASKSTATS is not set
41# CONFIG_UTS_NS is not set
42# CONFIG_AUDIT is not set
43# CONFIG_IKCONFIG is not set
44CONFIG_SYSFS_DEPRECATED=y
45# CONFIG_RELAY is not set
46CONFIG_INITRAMFS_SOURCE=""
47CONFIG_CC_OPTIMIZE_FOR_SIZE=y
48CONFIG_SYSCTL=y
49CONFIG_EMBEDDED=y
50CONFIG_UID16=y
51CONFIG_SYSCTL_SYSCALL=y
52CONFIG_KALLSYMS=y
53# CONFIG_KALLSYMS_ALL is not set
54# CONFIG_KALLSYMS_EXTRA_PASS is not set
55CONFIG_HOTPLUG=y
56CONFIG_PRINTK=y
57CONFIG_BUG=y
58CONFIG_ELF_CORE=y
59CONFIG_BASE_FULL=y
60CONFIG_FUTEX=y
61CONFIG_EPOLL=y
62CONFIG_SHMEM=y
63CONFIG_SLAB=y
64CONFIG_VM_EVENT_COUNTERS=y
65CONFIG_RT_MUTEXES=y
66# CONFIG_TINY_SHMEM is not set
67CONFIG_BASE_SMALL=0
68# CONFIG_SLOB is not set
69
70#
71# Loadable module support
72#
73CONFIG_MODULES=y
74CONFIG_MODULE_UNLOAD=y
75# CONFIG_MODULE_FORCE_UNLOAD is not set
76# CONFIG_MODVERSIONS is not set
77# CONFIG_MODULE_SRCVERSION_ALL is not set
78# CONFIG_KMOD is not set
79
80#
81# Block layer
82#
83CONFIG_BLOCK=y
84# CONFIG_LBD is not set
85# CONFIG_BLK_DEV_IO_TRACE is not set
86# CONFIG_LSF is not set
87
88#
89# IO Schedulers
90#
91CONFIG_IOSCHED_NOOP=y
92CONFIG_IOSCHED_AS=y
93CONFIG_IOSCHED_DEADLINE=m
94CONFIG_IOSCHED_CFQ=m
95CONFIG_DEFAULT_AS=y
96# CONFIG_DEFAULT_DEADLINE is not set
97# CONFIG_DEFAULT_CFQ is not set
98# CONFIG_DEFAULT_NOOP is not set
99CONFIG_DEFAULT_IOSCHED="anticipatory"
100
101#
102# System Type
103#
104# CONFIG_ARCH_AAEC2000 is not set
105# CONFIG_ARCH_INTEGRATOR is not set
106# CONFIG_ARCH_REALVIEW is not set
107# CONFIG_ARCH_VERSATILE is not set
108# CONFIG_ARCH_AT91 is not set
109# CONFIG_ARCH_CLPS7500 is not set
110# CONFIG_ARCH_CLPS711X is not set
111# CONFIG_ARCH_CO285 is not set
112# CONFIG_ARCH_EBSA110 is not set
113# CONFIG_ARCH_EP93XX is not set
114# CONFIG_ARCH_FOOTBRIDGE is not set
115# CONFIG_ARCH_NETX is not set
116# CONFIG_ARCH_H720X is not set
117# CONFIG_ARCH_IMX is not set
118# CONFIG_ARCH_IOP32X is not set
119# CONFIG_ARCH_IOP33X is not set
120# CONFIG_ARCH_IOP13XX is not set
121# CONFIG_ARCH_IXP4XX is not set
122# CONFIG_ARCH_IXP2000 is not set
123# CONFIG_ARCH_IXP23XX is not set
124# CONFIG_ARCH_L7200 is not set
125# CONFIG_ARCH_PNX4008 is not set
126CONFIG_ARCH_PXA=y
127# CONFIG_ARCH_RPC is not set
128# CONFIG_ARCH_SA1100 is not set
129# CONFIG_ARCH_S3C2410 is not set
130# CONFIG_ARCH_SHARK is not set
131# CONFIG_ARCH_LH7A40X is not set
132# CONFIG_ARCH_OMAP is not set
133
134#
135# Intel PXA2xx Implementations
136#
137# CONFIG_ARCH_LUBBOCK is not set
138# CONFIG_MACH_LOGICPD_PXA270 is not set
139# CONFIG_MACH_MAINSTONE is not set
140# CONFIG_ARCH_PXA_IDP is not set
141# CONFIG_PXA_SHARPSL is not set
142# CONFIG_MACH_TRIZEPS4 is not set
143CONFIG_MACH_HX2750=y
144CONFIG_PXA27x=y
145CONFIG_PXA_SSP=y
146CONFIG_PXA_KEYS=y
147
148#
149# Processor Type
150#
151CONFIG_CPU_32=y
152CONFIG_CPU_XSCALE=y
153CONFIG_CPU_32v5=y
154CONFIG_CPU_ABRT_EV5T=y
155CONFIG_CPU_CACHE_VIVT=y
156CONFIG_CPU_TLB_V4WBI=y
157CONFIG_CPU_CP15=y
158CONFIG_CPU_CP15_MMU=y
159
160#
161# Processor Features
162#
163CONFIG_ARM_THUMB=y
164# CONFIG_CPU_DCACHE_DISABLE is not set
165CONFIG_IWMMXT=y
166CONFIG_XSCALE_PMU=y
167
168#
169# Bus support
170#
171
172#
173# PCCARD (PCMCIA/CardBus) support
174#
175CONFIG_PCCARD=y
176# CONFIG_PCMCIA_DEBUG is not set
177CONFIG_PCMCIA=y
178CONFIG_PCMCIA_LOAD_CIS=y
179CONFIG_PCMCIA_IOCTL=y
180
181#
182# PC-card bridges
183#
184CONFIG_PCMCIA_PXA2XX=y
185
186#
187# Kernel Features
188#
189CONFIG_PREEMPT=y
190CONFIG_NO_IDLE_HZ=y
191CONFIG_HZ=100
192CONFIG_AEABI=y
193CONFIG_OABI_COMPAT=y
194# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
195CONFIG_SELECT_MEMORY_MODEL=y
196CONFIG_FLATMEM_MANUAL=y
197# CONFIG_DISCONTIGMEM_MANUAL is not set
198# CONFIG_SPARSEMEM_MANUAL is not set
199CONFIG_FLATMEM=y
200CONFIG_FLAT_NODE_MEM_MAP=y
201# CONFIG_SPARSEMEM_STATIC is not set
202CONFIG_SPLIT_PTLOCK_CPUS=4096
203# CONFIG_RESOURCES_64BIT is not set
204CONFIG_ALIGNMENT_TRAP=y
205
206#
207# Boot options
208#
209CONFIG_ZBOOT_ROM_TEXT=0x0
210CONFIG_ZBOOT_ROM_BSS=0x0
211CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 dyntick=enable debug"
212# CONFIG_XIP_KERNEL is not set
213CONFIG_KEXEC=y
214CONFIG_ATAGS_PROC=y
215
216#
217# CPU Frequency scaling
218#
219# CONFIG_CPU_FREQ is not set
220
221#
222# Floating point emulation
223#
224
225#
226# At least one emulation must be selected
227#
228CONFIG_FPE_NWFPE=y
229# CONFIG_FPE_NWFPE_XP is not set
230# CONFIG_FPE_FASTFPE is not set
231
232#
233# Userspace binary formats
234#
235CONFIG_BINFMT_ELF=y
236# CONFIG_BINFMT_AOUT is not set
237# CONFIG_BINFMT_MISC is not set
238
239#
240# Power management options
241#
242CONFIG_PM=y
243# CONFIG_PM_LEGACY is not set
244CONFIG_PM_DEBUG=y
245# CONFIG_DISABLE_CONSOLE_SUSPEND is not set
246# CONFIG_PM_SYSFS_DEPRECATED is not set
247CONFIG_APM=y
248
249#
250# Networking
251#
252CONFIG_NET=y
253
254#
255# Networking options
256#
257# CONFIG_NETDEBUG is not set
258CONFIG_PACKET=m
259CONFIG_PACKET_MMAP=y
260CONFIG_UNIX=y
261CONFIG_XFRM=y
262# CONFIG_XFRM_USER is not set
263# CONFIG_XFRM_SUB_POLICY is not set
264# CONFIG_NET_KEY is not set
265CONFIG_INET=y
266# CONFIG_IP_MULTICAST is not set
267# CONFIG_IP_ADVANCED_ROUTER is not set
268CONFIG_IP_FIB_HASH=y
269# CONFIG_IP_PNP is not set
270# CONFIG_NET_IPIP is not set
271# CONFIG_NET_IPGRE is not set
272# CONFIG_ARPD is not set
273CONFIG_SYN_COOKIES=y
274# CONFIG_INET_AH is not set
275# CONFIG_INET_ESP is not set
276# CONFIG_INET_IPCOMP is not set
277# CONFIG_INET_XFRM_TUNNEL is not set
278# CONFIG_INET_TUNNEL is not set
279CONFIG_INET_XFRM_MODE_TRANSPORT=y
280CONFIG_INET_XFRM_MODE_TUNNEL=y
281CONFIG_INET_XFRM_MODE_BEET=y
282CONFIG_INET_DIAG=m
283CONFIG_INET_TCP_DIAG=m
284# CONFIG_TCP_CONG_ADVANCED is not set
285CONFIG_TCP_CONG_CUBIC=y
286CONFIG_DEFAULT_TCP_CONG="cubic"
287# CONFIG_TCP_MD5SIG is not set
288# CONFIG_IPV6 is not set
289# CONFIG_INET6_XFRM_TUNNEL is not set
290# CONFIG_INET6_TUNNEL is not set
291# CONFIG_NETWORK_SECMARK is not set
292CONFIG_NETFILTER=y
293# CONFIG_NETFILTER_DEBUG is not set
294
295#
296# Core Netfilter Configuration
297#
298# CONFIG_NETFILTER_NETLINK is not set
299# CONFIG_NF_CONNTRACK_ENABLED is not set
300# CONFIG_NF_CONNTRACK is not set
301CONFIG_NETFILTER_XTABLES=m
302# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
303# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
304# CONFIG_NETFILTER_XT_TARGET_MARK is not set
305# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
306# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
307# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
308# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
309# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
310# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
311# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
312# CONFIG_NETFILTER_XT_MATCH_ESP is not set
313# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
314# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
315# CONFIG_NETFILTER_XT_MATCH_MAC is not set
316# CONFIG_NETFILTER_XT_MATCH_MARK is not set
317# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
318# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
319# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
320# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
321# CONFIG_NETFILTER_XT_MATCH_REALM is not set
322# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
323# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
324# CONFIG_NETFILTER_XT_MATCH_STRING is not set
325# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
326# CONFIG_NETFILTER_XT_MATCH_U32 is not set
327# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
328
329#
330# IP: Netfilter Configuration
331#
332CONFIG_IP_NF_QUEUE=m
333CONFIG_IP_NF_IPTABLES=m
334CONFIG_IP_NF_MATCH_IPRANGE=m
335CONFIG_IP_NF_MATCH_TOS=m
336CONFIG_IP_NF_MATCH_RECENT=m
337CONFIG_IP_NF_MATCH_ECN=m
338CONFIG_IP_NF_MATCH_AH=m
339CONFIG_IP_NF_MATCH_TTL=m
340CONFIG_IP_NF_MATCH_OWNER=m
341CONFIG_IP_NF_MATCH_ADDRTYPE=m
342CONFIG_IP_NF_FILTER=m
343CONFIG_IP_NF_TARGET_REJECT=m
344CONFIG_IP_NF_TARGET_LOG=m
345CONFIG_IP_NF_TARGET_ULOG=m
346CONFIG_IP_NF_MANGLE=m
347CONFIG_IP_NF_TARGET_TOS=m
348CONFIG_IP_NF_TARGET_ECN=m
349CONFIG_IP_NF_TARGET_TTL=m
350CONFIG_IP_NF_RAW=m
351CONFIG_IP_NF_ARPTABLES=m
352CONFIG_IP_NF_ARPFILTER=m
353CONFIG_IP_NF_ARP_MANGLE=m
354
355
356#
357# DCCP Configuration (EXPERIMENTAL)
358#
359# CONFIG_IP_DCCP is not set
360
361#
362# SCTP Configuration (EXPERIMENTAL)
363#
364# CONFIG_IP_SCTP is not set
365
366#
367# TIPC Configuration (EXPERIMENTAL)
368#
369# CONFIG_TIPC is not set
370# CONFIG_ATM is not set
371# CONFIG_BRIDGE is not set
372# CONFIG_VLAN_8021Q is not set
373# CONFIG_DECNET is not set
374# CONFIG_LLC2 is not set
375# CONFIG_IPX is not set
376# CONFIG_ATALK is not set
377# CONFIG_X25 is not set
378# CONFIG_LAPB is not set
379# CONFIG_ECONET is not set
380# CONFIG_WAN_ROUTER is not set
381
382#
383# QoS and/or fair queueing
384#
385# CONFIG_NET_SCHED is not set
386
387#
388# Network testing
389#
390# CONFIG_NET_PKTGEN is not set
391# CONFIG_HAMRADIO is not set
392# CONFIG_IRDA is not set
393# CONFIG_BT is not set
394CONFIG_IEEE80211=m
395# CONFIG_IEEE80211_DEBUG is not set
396CONFIG_IEEE80211_CRYPT_WEP=m
397# CONFIG_IEEE80211_CRYPT_CCMP is not set
398# CONFIG_IEEE80211_CRYPT_TKIP is not set
399# CONFIG_IEEE80211_SOFTMAC is not set
400CONFIG_WIRELESS_EXT=y
401
402#
403# Device Drivers
404#
405
406#
407# Generic Driver Options
408#
409CONFIG_STANDALONE=y
410# CONFIG_PREVENT_FIRMWARE_BUILD is not set
411CONFIG_FW_LOADER=y
412# CONFIG_DEBUG_DRIVER is not set
413# CONFIG_SYS_HYPERVISOR is not set
414
415#
416# Connector - unified userspace <-> kernelspace linker
417#
418# CONFIG_CONNECTOR is not set
419
420#
421# Memory Technology Devices (MTD)
422#
423CONFIG_MTD=y
424# CONFIG_MTD_DEBUG is not set
425CONFIG_MTD_CONCAT=y
426CONFIG_MTD_PARTITIONS=y
427# CONFIG_MTD_REDBOOT_PARTS is not set
428CONFIG_MTD_CMDLINE_PARTS=y
429# CONFIG_MTD_AFS_PARTS is not set
430
431#
432# User Modules And Translation Layers
433#
434CONFIG_MTD_CHAR=y
435CONFIG_MTD_BLOCK=y
436# CONFIG_FTL is not set
437# CONFIG_NFTL is not set
438# CONFIG_INFTL is not set
439# CONFIG_RFD_FTL is not set
440# CONFIG_SSFDC is not set
441
442#
443# RAM/ROM/Flash chip drivers
444#
445CONFIG_MTD_CFI=y
446# CONFIG_MTD_JEDECPROBE is not set
447CONFIG_MTD_GEN_PROBE=y
448CONFIG_MTD_CFI_ADV_OPTIONS=y
449CONFIG_MTD_CFI_NOSWAP=y
450# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
451# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
452CONFIG_MTD_CFI_GEOMETRY=y
453CONFIG_MTD_MAP_BANK_WIDTH_1=y
454CONFIG_MTD_MAP_BANK_WIDTH_2=y
455CONFIG_MTD_MAP_BANK_WIDTH_4=y
456# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
457# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
458# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
459CONFIG_MTD_CFI_I1=y
460CONFIG_MTD_CFI_I2=y
461# CONFIG_MTD_CFI_I4 is not set
462# CONFIG_MTD_CFI_I8 is not set
463# CONFIG_MTD_OTP is not set
464CONFIG_MTD_CFI_INTELEXT=y
465# CONFIG_MTD_CFI_AMDSTD is not set
466# CONFIG_MTD_CFI_STAA is not set
467CONFIG_MTD_CFI_UTIL=y
468# CONFIG_MTD_RAM is not set
469# CONFIG_MTD_ROM is not set
470# CONFIG_MTD_ABSENT is not set
471# CONFIG_MTD_OBSOLETE_CHIPS is not set
472# CONFIG_MTD_XIP is not set
473
474#
475# Mapping drivers for chip access
476#
477# CONFIG_MTD_COMPLEX_MAPPINGS is not set
478# CONFIG_MTD_PHYSMAP is not set
479# CONFIG_MTD_ARM_INTEGRATOR is not set
480# CONFIG_MTD_SHARP_SL is not set
481# CONFIG_MTD_PLATRAM is not set
482
483#
484# Self-contained MTD device drivers
485#
486# CONFIG_MTD_SLRAM is not set
487# CONFIG_MTD_PHRAM is not set
488# CONFIG_MTD_MTDRAM is not set
489# CONFIG_MTD_BLOCK2MTD is not set
490
491#
492# Disk-On-Chip Device Drivers
493#
494# CONFIG_MTD_DOC2000 is not set
495# CONFIG_MTD_DOC2001 is not set
496# CONFIG_MTD_DOC2001PLUS is not set
497
498#
499# NAND Flash Device Drivers
500#
501# CONFIG_MTD_NAND is not set
502
503#
504# OneNAND Flash Device Drivers
505#
506# CONFIG_MTD_ONENAND is not set
507
508#
509# Parallel port support
510#
511# CONFIG_PARPORT is not set
512
513#
514# Plug and Play support
515#
516
517#
518# Block devices
519#
520# CONFIG_BLK_DEV_COW_COMMON is not set
521CONFIG_BLK_DEV_LOOP=y
522# CONFIG_BLK_DEV_CRYPTOLOOP is not set
523# CONFIG_BLK_DEV_NBD is not set
524CONFIG_BLK_DEV_RAM=y
525CONFIG_BLK_DEV_RAM_COUNT=16
526CONFIG_BLK_DEV_RAM_SIZE=8192
527CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
528CONFIG_BLK_DEV_INITRD=y
529# CONFIG_CDROM_PKTCDVD is not set
530# CONFIG_ATA_OVER_ETH is not set
531
532#
533# ATA/ATAPI/MFM/RLL support
534#
535CONFIG_IDE=y
536CONFIG_IDE_MAX_HWIFS=4
537CONFIG_BLK_DEV_IDE=y
538
539#
540# Please see Documentation/ide.txt for help/info on IDE drives
541#
542# CONFIG_BLK_DEV_IDE_SATA is not set
543CONFIG_BLK_DEV_IDEDISK=y
544# CONFIG_IDEDISK_MULTI_MODE is not set
545CONFIG_BLK_DEV_IDECS=y
546# CONFIG_BLK_DEV_IDECD is not set
547# CONFIG_BLK_DEV_IDETAPE is not set
548# CONFIG_BLK_DEV_IDEFLOPPY is not set
549# CONFIG_IDE_TASK_IOCTL is not set
550
551#
552# IDE chipset support/bugfixes
553#
554CONFIG_IDE_GENERIC=y
555# CONFIG_IDE_ARM is not set
556# CONFIG_BLK_DEV_IDEDMA is not set
557# CONFIG_IDEDMA_AUTO is not set
558# CONFIG_BLK_DEV_HD is not set
559
560#
561# SCSI device support
562#
563# CONFIG_RAID_ATTRS is not set
564# CONFIG_SCSI is not set
565# CONFIG_SCSI_NETLINK is not set
566
567#
568# Serial ATA (prod) and Parallel ATA (experimental) drivers
569#
570# CONFIG_ATA is not set
571
572#
573# Multi-device support (RAID and LVM)
574#
575# CONFIG_MD is not set
576
577#
578# Fusion MPT device support
579#
580# CONFIG_FUSION is not set
581
582#
583# IEEE 1394 (FireWire) support
584#
585
586#
587# I2O device support
588#
589
590#
591# Network device support
592#
593CONFIG_NETDEVICES=y
594# CONFIG_DUMMY is not set
595# CONFIG_BONDING is not set
596# CONFIG_EQUALIZER is not set
597CONFIG_TUN=m
598
599#
600# PHY device support
601#
602# CONFIG_PHYLIB is not set
603
604#
605# Ethernet (10 or 100Mbit)
606#
607CONFIG_NET_ETHERNET=y
608CONFIG_MII=m
609# CONFIG_SMC91X is not set
610# CONFIG_DM9000 is not set
611# CONFIG_SMC911X is not set
612
613#
614# Ethernet (1000 Mbit)
615#
616
617#
618# Ethernet (10000 Mbit)
619#
620
621#
622# Token Ring devices
623#
624
625#
626# Wireless LAN (non-hamradio)
627#
628CONFIG_NET_RADIO=y
629# CONFIG_NET_WIRELESS_RTNETLINK is not set
630
631#
632# Obsolete Wireless cards support (pre-802.11)
633#
634# CONFIG_STRIP is not set
635# CONFIG_PCMCIA_WAVELAN is not set
636# CONFIG_PCMCIA_NETWAVE is not set
637
638#
639# Wireless 802.11 Frequency Hopping cards support
640#
641# CONFIG_PCMCIA_RAYCS is not set
642
643#
644# Wireless 802.11b ISA/PCI cards support
645#
646CONFIG_HERMES=m
647# CONFIG_ATMEL is not set
648
649#
650# Wireless 802.11b Pcmcia/Cardbus cards support
651#
652CONFIG_PCMCIA_HERMES=m
653CONFIG_PCMCIA_SPECTRUM=m
654# CONFIG_AIRO_CS is not set
655# CONFIG_PCMCIA_WL3501 is not set
656CONFIG_HOSTAP=m
657CONFIG_HOSTAP_FIRMWARE=y
658# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
659CONFIG_HOSTAP_CS=m
660CONFIG_NET_WIRELESS=y
661
662#
663# PCMCIA network device support
664#
665CONFIG_NET_PCMCIA=y
666# CONFIG_PCMCIA_3C589 is not set
667# CONFIG_PCMCIA_3C574 is not set
668# CONFIG_PCMCIA_FMVJ18X is not set
669CONFIG_PCMCIA_PCNET=m
670# CONFIG_PCMCIA_NMCLAN is not set
671# CONFIG_PCMCIA_SMC91C92 is not set
672# CONFIG_PCMCIA_XIRC2PS is not set
673# CONFIG_PCMCIA_AXNET is not set
674
675#
676# Wan interfaces
677#
678# CONFIG_WAN is not set
679CONFIG_PPP=m
680# CONFIG_PPP_MULTILINK is not set
681# CONFIG_PPP_FILTER is not set
682CONFIG_PPP_ASYNC=m
683# CONFIG_PPP_SYNC_TTY is not set
684CONFIG_PPP_DEFLATE=m
685CONFIG_PPP_BSDCOMP=m
686# CONFIG_PPP_MPPE is not set
687# CONFIG_PPPOE is not set
688# CONFIG_SLIP is not set
689CONFIG_SLHC=m
690# CONFIG_SHAPER is not set
691# CONFIG_NETCONSOLE is not set
692# CONFIG_NETPOLL is not set
693# CONFIG_NET_POLL_CONTROLLER is not set
694
695#
696# ISDN subsystem
697#
698# CONFIG_ISDN is not set
699
700#
701# Input device support
702#
703CONFIG_INPUT=y
704# CONFIG_INPUT_FF_MEMLESS is not set
705
706#
707# Userland interfaces
708#
709CONFIG_INPUT_MOUSEDEV=m
710# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
711CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
712CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
713# CONFIG_INPUT_JOYDEV is not set
714# CONFIG_INPUT_TSDEV is not set
715CONFIG_INPUT_EVDEV=y
716# CONFIG_INPUT_EVBUG is not set
717CONFIG_INPUT_POWER=y
718
719#
720# Input Device Drivers
721#
722# CONFIG_INPUT_KEYBOARD is not set
723# CONFIG_INPUT_MOUSE is not set
724# CONFIG_INPUT_JOYSTICK is not set
725CONFIG_INPUT_TOUCHSCREEN=y
726# CONFIG_TOUCHSCREEN_GUNZE is not set
727# CONFIG_TOUCHSCREEN_ELO is not set
728# CONFIG_TOUCHSCREEN_MTOUCH is not set
729# CONFIG_TOUCHSCREEN_MK712 is not set
730# CONFIG_TOUCHSCREEN_PENMOUNT is not set
731# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
732# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
733# CONFIG_TOUCHSCREEN_UCB1400 is not set
734CONFIG_TOUCHSCREEN_TSC2101=y
735# CONFIG_INPUT_MISC is not set
736
737#
738# Hardware I/O ports
739#
740# CONFIG_SERIO is not set
741# CONFIG_GAMEPORT is not set
742
743#
744# Character devices
745#
746CONFIG_VT=y
747CONFIG_VT_CONSOLE=y
748CONFIG_HW_CONSOLE=y
749# CONFIG_VT_HW_CONSOLE_BINDING is not set
750# CONFIG_SERIAL_NONSTANDARD is not set
751
752#
753# Serial drivers
754#
755# CONFIG_SERIAL_8250 is not set
756
757#
758# Non-8250 serial port support
759#
760CONFIG_SERIAL_PXA=y
761CONFIG_SERIAL_PXA_CONSOLE=y
762CONFIG_SERIAL_CORE=y
763CONFIG_SERIAL_CORE_CONSOLE=y
764CONFIG_UNIX98_PTYS=y
765# CONFIG_LEGACY_PTYS is not set
766
767#
768# IPMI
769#
770# CONFIG_IPMI_HANDLER is not set
771
772#
773# Watchdog Cards
774#
775# CONFIG_WATCHDOG is not set
776CONFIG_HW_RANDOM=m
777# CONFIG_NVRAM is not set
778# CONFIG_DTLK is not set
779# CONFIG_R3964 is not set
780
781#
782# PCMCIA character devices
783#
784# CONFIG_SYNCLINK_CS is not set
785# CONFIG_CARDMAN_4000 is not set
786# CONFIG_CARDMAN_4040 is not set
787# CONFIG_RAW_DRIVER is not set
788
789#
790# TPM devices
791#
792# CONFIG_TCG_TPM is not set
793
794#
795# I2C support
796#
797# CONFIG_I2C is not set
798
799#
800# SPI support
801#
802# CONFIG_SPI is not set
803# CONFIG_SPI_MASTER is not set
804
805#
806# Dallas's 1-wire bus
807#
808# CONFIG_W1 is not set
809
810#
811# Hardware Monitoring support
812#
813# CONFIG_HWMON is not set
814# CONFIG_HWMON_VID is not set
815
816#
817# Misc devices
818#
819# CONFIG_TIFM_CORE is not set
820
821#
822# Multi-Function Devices
823#
824CONFIG_MFD_TSC2101=y
825
826#
827# LED devices
828#
829# CONFIG_NEW_LEDS is not set
830
831#
832# LED drivers
833#
834
835#
836# LED Triggers
837#
838
839#
840# Multimedia devices
841#
842CONFIG_VIDEO_DEV=m
843CONFIG_VIDEO_V4L1=y
844CONFIG_VIDEO_V4L1_COMPAT=y
845CONFIG_VIDEO_V4L2=y
846
847#
848# Digital Video Broadcasting Devices
849#
850# CONFIG_DVB is not set
851
852#
853# Graphics support
854#
855CONFIG_FIRMWARE_EDID=y
856CONFIG_FB=y
857CONFIG_FB_CFB_FILLRECT=y
858CONFIG_FB_CFB_COPYAREA=y
859CONFIG_FB_CFB_IMAGEBLIT=y
860# CONFIG_FB_MACMODES is not set
861# CONFIG_FB_BACKLIGHT is not set
862# CONFIG_FB_MODE_HELPERS is not set
863# CONFIG_FB_TILEBLITTING is not set
864# CONFIG_FB_S1D13XXX is not set
865CONFIG_FB_PXA=y
866CONFIG_FB_PXA_LCD_QVGA=y
867# CONFIG_FB_PXA_LCD_VGA is not set
868# CONFIG_FB_PXA_OVERLAY is not set
869# CONFIG_FB_PXA_PARAMETERS is not set
870# CONFIG_FB_MBX is not set
871# CONFIG_FB_VIRTUAL is not set
872
873#
874# Console display driver support
875#
876# CONFIG_VGA_CONSOLE is not set
877CONFIG_DUMMY_CONSOLE=y
878CONFIG_FRAMEBUFFER_CONSOLE=y
879# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
880# CONFIG_FONTS is not set
881CONFIG_FONT_8x8=y
882CONFIG_FONT_8x16=y
883
884#
885# Logo configuration
886#
887CONFIG_LOGO=y
888CONFIG_LOGO_LINUX_MONO=y
889CONFIG_LOGO_LINUX_VGA16=y
890# CONFIG_LOGO_LINUX_CLUT224 is not set
891CONFIG_LOGO_OHAND_CLUT224=y
892# CONFIG_LOGO_OZ240_CLUT224 is not set
893# CONFIG_LOGO_OZ480_CLUT224 is not set
894# CONFIG_LOGO_OZ640_CLUT224 is not set
895CONFIG_BACKLIGHT_LCD_SUPPORT=y
896CONFIG_BACKLIGHT_CLASS_DEVICE=y
897CONFIG_BACKLIGHT_DEVICE=y
898CONFIG_LCD_CLASS_DEVICE=y
899CONFIG_LCD_DEVICE=y
900CONFIG_BACKLIGHT_HX2750=y
901
902#
903# Sound
904#
905# CONFIG_SOUND is not set
906
907#
908# HID Devices
909#
910CONFIG_HID=m
911
912#
913# USB support
914#
915CONFIG_USB_ARCH_HAS_HCD=y
916CONFIG_USB_ARCH_HAS_OHCI=y
917# CONFIG_USB_ARCH_HAS_EHCI is not set
918# CONFIG_USB is not set
919
920#
921# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
922#
923
924#
925# USB Gadget Support
926#
927# CONFIG_USB_GADGET is not set
928
929#
930# MMC/SD Card support
931#
932CONFIG_MMC=y
933# CONFIG_MMC_DEBUG is not set
934CONFIG_MMC_BLOCK=y
935CONFIG_MMC_PXA=y
936# CONFIG_MMC_TIFM_SD is not set
937CONFIG_MMC_UNSAFE_RESUME=y
938
939
940#
941# Real Time Clock
942#
943CONFIG_RTC_LIB=y
944CONFIG_RTC_CLASS=y
945CONFIG_RTC_HCTOSYS=y
946CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
947# CONFIG_RTC_DEBUG is not set
948
949#
950# RTC interfaces
951#
952CONFIG_RTC_INTF_SYSFS=y
953CONFIG_RTC_INTF_PROC=y
954CONFIG_RTC_INTF_DEV=y
955# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
956
957#
958# RTC drivers
959#
960# CONFIG_RTC_DRV_DS1553 is not set
961# CONFIG_RTC_DRV_DS1742 is not set
962# CONFIG_RTC_DRV_M48T86 is not set
963CONFIG_RTC_DRV_SA1100=y
964# CONFIG_RTC_DRV_TEST is not set
965# CONFIG_RTC_DRV_V3020 is not set
966
967#
968# File systems
969#
970CONFIG_EXT2_FS=y
971# CONFIG_EXT2_FS_XATTR is not set
972# CONFIG_EXT2_FS_XIP is not set
973CONFIG_EXT3_FS=m
974# CONFIG_EXT4DEV_FS is not set
975# CONFIG_REISERFS_FS is not set
976# CONFIG_JFS_FS is not set
977# CONFIG_FS_POSIX_ACL is not set
978# CONFIG_XFS_FS is not set
979# CONFIG_GFS2_FS is not set
980# CONFIG_OCFS2_FS is not set
981# CONFIG_MINIX_FS is not set
982# CONFIG_ROMFS_FS is not set
983CONFIG_INOTIFY=y
984CONFIG_INOTIFY_USER=y
985# CONFIG_QUOTA is not set
986CONFIG_DNOTIFY=y
987# CONFIG_AUTOFS_FS is not set
988# CONFIG_AUTOFS4_FS is not set
989# CONFIG_FUSE_FS is not set
990
991#
992# CD-ROM/DVD Filesystems
993#
994# CONFIG_ISO9660_FS is not set
995# CONFIG_UDF_FS is not set
996
997#
998# DOS/FAT/NT Filesystems
999#
1000CONFIG_FAT_FS=y
1001# CONFIG_MSDOS_FS is not set
1002CONFIG_VFAT_FS=y
1003CONFIG_FAT_DEFAULT_CODEPAGE=437
1004CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1005# CONFIG_NTFS_FS is not set
1006
1007#
1008# Pseudo filesystems
1009#
1010CONFIG_PROC_FS=y
1011CONFIG_PROC_SYSCTL=y
1012CONFIG_SYSFS=y
1013CONFIG_TMPFS=y
1014# CONFIG_TMPFS_POSIX_ACL is not set
1015# CONFIG_HUGETLB_PAGE is not set
1016CONFIG_RAMFS=y
1017# CONFIG_CONFIGFS_FS is not set
1018
1019#
1020# Miscellaneous filesystems
1021#
1022# CONFIG_ADFS_FS is not set
1023# CONFIG_AFFS_FS is not set
1024# CONFIG_HFS_FS is not set
1025# CONFIG_HFSPLUS_FS is not set
1026# CONFIG_BEFS_FS is not set
1027# CONFIG_BFS_FS is not set
1028# CONFIG_EFS_FS is not set
1029CONFIG_JFFS2_FS=y
1030CONFIG_JFFS2_FS_DEBUG=0
1031CONFIG_JFFS2_FS_WRITEBUFFER=y
1032# CONFIG_JFFS2_SUMMARY is not set
1033# CONFIG_JFFS2_FS_XATTR is not set
1034# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1035CONFIG_JFFS2_ZLIB=y
1036CONFIG_JFFS2_RTIME=y
1037# CONFIG_JFFS2_RUBIN is not set
1038CONFIG_CRAMFS=y
1039CONFIG_SQUASHFS=m
1040# CONFIG_SQUASHFS_EMBEDDED is not set
1041CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1042# CONFIG_SQUASHFS_VMALLOC is not set
1043# CONFIG_VXFS_FS is not set
1044# CONFIG_HPFS_FS is not set
1045# CONFIG_QNX4FS_FS is not set
1046# CONFIG_SYSV_FS is not set
1047# CONFIG_UFS_FS is not set
1048
1049#
1050# Network File Systems
1051#
1052CONFIG_NFS_FS=m
1053# CONFIG_NFSD is not set
1054# CONFIG_SMB_FS is not set
1055# CONFIG_CIFS is not set
1056# CONFIG_NCP_FS is not set
1057# CONFIG_CODA_FS is not set
1058# CONFIG_AFS_FS is not set
1059# CONFIG_9P_FS is not set
1060
1061#
1062# Partition Types
1063#
1064CONFIG_PARTITION_ADVANCED=y
1065# CONFIG_ACORN_PARTITION is not set
1066# CONFIG_OSF_PARTITION is not set
1067# CONFIG_AMIGA_PARTITION is not set
1068# CONFIG_ATARI_PARTITION is not set
1069# CONFIG_MAC_PARTITION is not set
1070CONFIG_MSDOS_PARTITION=y
1071# CONFIG_BSD_DISKLABEL is not set
1072# CONFIG_MINIX_SUBPARTITION is not set
1073# CONFIG_SOLARIS_X86_PARTITION is not set
1074# CONFIG_UNIXWARE_DISKLABEL is not set
1075# CONFIG_LDM_PARTITION is not set
1076# CONFIG_SGI_PARTITION is not set
1077# CONFIG_ULTRIX_PARTITION is not set
1078# CONFIG_SUN_PARTITION is not set
1079# CONFIG_KARMA_PARTITION is not set
1080# CONFIG_EFI_PARTITION is not set
1081
1082#
1083# Native Language Support
1084#
1085CONFIG_NLS=y
1086CONFIG_NLS_DEFAULT="cp437"
1087CONFIG_NLS_CODEPAGE_437=y
1088# CONFIG_NLS_CODEPAGE_737 is not set
1089# CONFIG_NLS_CODEPAGE_775 is not set
1090# CONFIG_NLS_CODEPAGE_850 is not set
1091# CONFIG_NLS_CODEPAGE_852 is not set
1092# CONFIG_NLS_CODEPAGE_855 is not set
1093# CONFIG_NLS_CODEPAGE_857 is not set
1094# CONFIG_NLS_CODEPAGE_860 is not set
1095# CONFIG_NLS_CODEPAGE_861 is not set
1096# CONFIG_NLS_CODEPAGE_862 is not set
1097# CONFIG_NLS_CODEPAGE_863 is not set
1098# CONFIG_NLS_CODEPAGE_864 is not set
1099# CONFIG_NLS_CODEPAGE_865 is not set
1100# CONFIG_NLS_CODEPAGE_866 is not set
1101# CONFIG_NLS_CODEPAGE_869 is not set
1102# CONFIG_NLS_CODEPAGE_936 is not set
1103# CONFIG_NLS_CODEPAGE_950 is not set
1104# CONFIG_NLS_CODEPAGE_932 is not set
1105# CONFIG_NLS_CODEPAGE_949 is not set
1106# CONFIG_NLS_CODEPAGE_874 is not set
1107# CONFIG_NLS_ISO8859_8 is not set
1108# CONFIG_NLS_CODEPAGE_1250 is not set
1109# CONFIG_NLS_CODEPAGE_1251 is not set
1110# CONFIG_NLS_ASCII is not set
1111CONFIG_NLS_ISO8859_1=y
1112# CONFIG_NLS_ISO8859_2 is not set
1113# CONFIG_NLS_ISO8859_3 is not set
1114# CONFIG_NLS_ISO8859_4 is not set
1115# CONFIG_NLS_ISO8859_5 is not set
1116# CONFIG_NLS_ISO8859_6 is not set
1117# CONFIG_NLS_ISO8859_7 is not set
1118# CONFIG_NLS_ISO8859_9 is not set
1119# CONFIG_NLS_ISO8859_13 is not set
1120# CONFIG_NLS_ISO8859_14 is not set
1121# CONFIG_NLS_ISO8859_15 is not set
1122# CONFIG_NLS_KOI8_R is not set
1123# CONFIG_NLS_KOI8_U is not set
1124CONFIG_NLS_UTF8=y
1125
1126#
1127# Distributed Lock Manager
1128#
1129# CONFIG_DLM is not set
1130
1131#
1132# Profiling support
1133#
1134# CONFIG_PROFILING is not set
1135
1136#
1137# Kernel hacking
1138#
1139# CONFIG_PRINTK_TIME is not set
1140CONFIG_ENABLE_MUST_CHECK=y
1141# CONFIG_MAGIC_SYSRQ is not set
1142# CONFIG_UNUSED_SYMBOLS is not set
1143# CONFIG_DEBUG_FS is not set
1144# CONFIG_HEADERS_CHECK is not set
1145CONFIG_TIMER_STATS=y
1146CONFIG_DEBUG_KERNEL=y
1147CONFIG_LOG_BUF_SHIFT=14
1148CONFIG_DETECT_SOFTLOCKUP=y
1149# CONFIG_SCHEDSTATS is not set
1150# CONFIG_DEBUG_SLAB is not set
1151CONFIG_DEBUG_PREEMPT=y
1152# CONFIG_DEBUG_RT_MUTEXES is not set
1153# CONFIG_RT_MUTEX_TESTER is not set
1154# CONFIG_DEBUG_SPINLOCK is not set
1155# CONFIG_DEBUG_MUTEXES is not set
1156# CONFIG_DEBUG_RWSEMS is not set
1157# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1158# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1159# CONFIG_DEBUG_KOBJECT is not set
1160# CONFIG_DEBUG_BUGVERBOSE is not set
1161# CONFIG_DEBUG_INFO is not set
1162# CONFIG_DEBUG_VM is not set
1163# CONFIG_DEBUG_LIST is not set
1164CONFIG_FRAME_POINTER=y
1165CONFIG_FORCED_INLINING=y
1166# CONFIG_RCU_TORTURE_TEST is not set
1167# CONFIG_DEBUG_USER is not set
1168CONFIG_DEBUG_ERRORS=y
1169CONFIG_DEBUG_LL=y
1170# CONFIG_DEBUG_ICEDCC is not set
1171
1172#
1173# Security options
1174#
1175# CONFIG_KEYS is not set
1176# CONFIG_SECURITY is not set
1177
1178#
1179# Cryptographic options
1180#
1181CONFIG_CRYPTO=y
1182CONFIG_CRYPTO_ALGAPI=y
1183CONFIG_CRYPTO_BLKCIPHER=m
1184CONFIG_CRYPTO_MANAGER=m
1185# CONFIG_CRYPTO_HMAC is not set
1186# CONFIG_CRYPTO_XCBC is not set
1187# CONFIG_CRYPTO_NULL is not set
1188# CONFIG_CRYPTO_MD4 is not set
1189# CONFIG_CRYPTO_MD5 is not set
1190# CONFIG_CRYPTO_SHA1 is not set
1191# CONFIG_CRYPTO_SHA256 is not set
1192# CONFIG_CRYPTO_SHA512 is not set
1193# CONFIG_CRYPTO_WP512 is not set
1194# CONFIG_CRYPTO_TGR192 is not set
1195# CONFIG_CRYPTO_GF128MUL is not set
1196CONFIG_CRYPTO_ECB=m
1197CONFIG_CRYPTO_CBC=m
1198# CONFIG_CRYPTO_LRW is not set
1199# CONFIG_CRYPTO_DES is not set
1200# CONFIG_CRYPTO_BLOWFISH is not set
1201# CONFIG_CRYPTO_TWOFISH is not set
1202# CONFIG_CRYPTO_SERPENT is not set
1203# CONFIG_CRYPTO_AES is not set
1204# CONFIG_CRYPTO_CAST5 is not set
1205# CONFIG_CRYPTO_CAST6 is not set
1206# CONFIG_CRYPTO_TEA is not set
1207CONFIG_CRYPTO_ARC4=m
1208# CONFIG_CRYPTO_KHAZAD is not set
1209# CONFIG_CRYPTO_ANUBIS is not set
1210CONFIG_CRYPTO_DEFLATE=y
1211# CONFIG_CRYPTO_MICHAEL_MIC is not set
1212CONFIG_CRYPTO_CRC32C=y
1213# CONFIG_CRYPTO_TEST is not set
1214
1215#
1216# Hardware crypto devices
1217#
1218
1219#
1220# Library routines
1221#
1222CONFIG_BITREVERSE=y
1223CONFIG_CRC_CCITT=m
1224# CONFIG_CRC16 is not set
1225CONFIG_CRC32=y
1226CONFIG_LIBCRC32C=y
1227CONFIG_ZLIB_INFLATE=y
1228CONFIG_ZLIB_DEFLATE=y
1229CONFIG_PLIST=y
1230CONFIG_IOMAP_COPY=y
1231# CONFIG_SHARPSL_RC is not set
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-poodle b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-poodle
new file mode 100644
index 0000000000..5afa7c556b
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-poodle
@@ -0,0 +1,1741 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Fri Dec 28 17:28:59 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37# CONFIG_LOCALVERSION_AUTO is not set
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41# CONFIG_POSIX_MQUEUE is not set
42CONFIG_BSD_PROCESS_ACCT=y
43CONFIG_BSD_PROCESS_ACCT_V3=y
44# CONFIG_TASKSTATS is not set
45# CONFIG_USER_NS is not set
46# CONFIG_AUDIT is not set
47# CONFIG_IKCONFIG is not set
48CONFIG_LOG_BUF_SHIFT=14
49CONFIG_SYSFS_DEPRECATED=y
50# CONFIG_RELAY is not set
51# CONFIG_BLK_DEV_INITRD is not set
52CONFIG_CC_OPTIMIZE_FOR_SIZE=y
53CONFIG_SYSCTL=y
54CONFIG_EMBEDDED=y
55CONFIG_UID16=y
56CONFIG_SYSCTL_SYSCALL=y
57CONFIG_KALLSYMS=y
58# CONFIG_KALLSYMS_ALL is not set
59# CONFIG_KALLSYMS_EXTRA_PASS is not set
60CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y
62CONFIG_BUG=y
63CONFIG_ELF_CORE=y
64CONFIG_BASE_FULL=y
65CONFIG_FUTEX=y
66CONFIG_ANON_INODES=y
67CONFIG_EPOLL=y
68CONFIG_SIGNALFD=y
69CONFIG_EVENTFD=y
70CONFIG_SHMEM=y
71CONFIG_VM_EVENT_COUNTERS=y
72CONFIG_SLAB=y
73# CONFIG_SLUB is not set
74# CONFIG_SLOB is not set
75CONFIG_RT_MUTEXES=y
76# CONFIG_TINY_SHMEM is not set
77CONFIG_BASE_SMALL=0
78CONFIG_MODULES=y
79CONFIG_MODULE_UNLOAD=y
80CONFIG_MODULE_FORCE_UNLOAD=y
81# CONFIG_MODVERSIONS is not set
82# CONFIG_MODULE_SRCVERSION_ALL is not set
83CONFIG_KMOD=y
84CONFIG_BLOCK=y
85# CONFIG_LBD is not set
86# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set
88# CONFIG_BLK_DEV_BSG is not set
89
90#
91# IO Schedulers
92#
93CONFIG_IOSCHED_NOOP=y
94CONFIG_IOSCHED_AS=y
95CONFIG_IOSCHED_DEADLINE=m
96CONFIG_IOSCHED_CFQ=m
97CONFIG_DEFAULT_AS=y
98# CONFIG_DEFAULT_DEADLINE is not set
99# CONFIG_DEFAULT_CFQ is not set
100# CONFIG_DEFAULT_NOOP is not set
101CONFIG_DEFAULT_IOSCHED="anticipatory"
102
103#
104# System Type
105#
106# CONFIG_ARCH_AAEC2000 is not set
107# CONFIG_ARCH_INTEGRATOR is not set
108# CONFIG_ARCH_REALVIEW is not set
109# CONFIG_ARCH_VERSATILE is not set
110# CONFIG_ARCH_AT91 is not set
111# CONFIG_ARCH_CLPS7500 is not set
112# CONFIG_ARCH_CLPS711X is not set
113# CONFIG_ARCH_CO285 is not set
114# CONFIG_ARCH_EBSA110 is not set
115# CONFIG_ARCH_EP93XX is not set
116# CONFIG_ARCH_FOOTBRIDGE is not set
117# CONFIG_ARCH_NETX is not set
118# CONFIG_ARCH_H720X is not set
119# CONFIG_ARCH_IMX is not set
120# CONFIG_ARCH_IOP13XX is not set
121# CONFIG_ARCH_IOP32X is not set
122# CONFIG_ARCH_IOP33X is not set
123# CONFIG_ARCH_IXP23XX is not set
124# CONFIG_ARCH_IXP2000 is not set
125# CONFIG_ARCH_IXP4XX is not set
126# CONFIG_ARCH_L7200 is not set
127# CONFIG_ARCH_KS8695 is not set
128# CONFIG_ARCH_NS9XXX is not set
129# CONFIG_ARCH_MXC is not set
130# CONFIG_ARCH_PNX4008 is not set
131CONFIG_ARCH_PXA=y
132# CONFIG_ARCH_RPC is not set
133# CONFIG_ARCH_SA1100 is not set
134# CONFIG_ARCH_S3C2410 is not set
135# CONFIG_ARCH_SHARK is not set
136# CONFIG_ARCH_LH7A40X is not set
137# CONFIG_ARCH_DAVINCI is not set
138# CONFIG_ARCH_OMAP is not set
139
140#
141# Intel PXA2xx Implementations
142#
143# CONFIG_ARCH_LUBBOCK is not set
144# CONFIG_MACH_LOGICPD_PXA270 is not set
145# CONFIG_MACH_MAINSTONE is not set
146# CONFIG_ARCH_PXA_IDP is not set
147CONFIG_PXA_SHARPSL=y
148# CONFIG_MACH_TRIZEPS4 is not set
149# CONFIG_MACH_EM_X270 is not set
150# CONFIG_MACH_HX2750 is not set
151# CONFIG_MACH_HTCUNIVERSAL is not set
152CONFIG_PXA_SHARPSL_25x=y
153# CONFIG_PXA_SHARPSL_27x is not set
154CONFIG_MACH_POODLE=y
155# CONFIG_MACH_CORGI is not set
156# CONFIG_MACH_SHEPHERD is not set
157# CONFIG_MACH_HUSKY is not set
158# CONFIG_MACH_TOSA is not set
159CONFIG_PXA25x=y
160CONFIG_PXA_SSP=y
161# CONFIG_PXA_KEYS is not set
162
163#
164# Boot options
165#
166
167#
168# Power management
169#
170
171#
172# Processor Type
173#
174CONFIG_CPU_32=y
175CONFIG_CPU_XSCALE=y
176CONFIG_CPU_32v5=y
177CONFIG_CPU_ABRT_EV5T=y
178CONFIG_CPU_CACHE_VIVT=y
179CONFIG_CPU_TLB_V4WBI=y
180CONFIG_CPU_CP15=y
181CONFIG_CPU_CP15_MMU=y
182
183#
184# Processor Features
185#
186CONFIG_ARM_THUMB=y
187# CONFIG_CPU_DCACHE_DISABLE is not set
188# CONFIG_OUTER_CACHE is not set
189# CONFIG_IWMMXT is not set
190CONFIG_XSCALE_PMU=y
191CONFIG_SHARP_LOCOMO=y
192CONFIG_SHARP_PARAM=y
193CONFIG_SHARPSL_PM=y
194CONFIG_SHARP_SCOOP=y
195
196#
197# Bus support
198#
199# CONFIG_PCI_SYSCALL is not set
200# CONFIG_ARCH_SUPPORTS_MSI is not set
201
202#
203# PCCARD (PCMCIA/CardBus) support
204#
205CONFIG_PCCARD=y
206# CONFIG_PCMCIA_DEBUG is not set
207CONFIG_PCMCIA=y
208CONFIG_PCMCIA_LOAD_CIS=y
209CONFIG_PCMCIA_IOCTL=y
210
211#
212# PC-card bridges
213#
214CONFIG_PCMCIA_PXA2XX=y
215
216#
217# Kernel Features
218#
219# CONFIG_TICK_ONESHOT is not set
220# CONFIG_NO_HZ is not set
221# CONFIG_HIGH_RES_TIMERS is not set
222CONFIG_PREEMPT=y
223CONFIG_HZ=100
224CONFIG_AEABI=y
225CONFIG_OABI_COMPAT=y
226# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
227CONFIG_SELECT_MEMORY_MODEL=y
228CONFIG_FLATMEM_MANUAL=y
229# CONFIG_DISCONTIGMEM_MANUAL is not set
230# CONFIG_SPARSEMEM_MANUAL is not set
231CONFIG_FLATMEM=y
232CONFIG_FLAT_NODE_MEM_MAP=y
233# CONFIG_SPARSEMEM_STATIC is not set
234CONFIG_SPLIT_PTLOCK_CPUS=4096
235# CONFIG_RESOURCES_64BIT is not set
236CONFIG_ZONE_DMA_FLAG=1
237CONFIG_BOUNCE=y
238CONFIG_VIRT_TO_BUS=y
239CONFIG_ALIGNMENT_TRAP=y
240
241#
242# Boot options
243#
244CONFIG_ZBOOT_ROM_TEXT=0x0
245CONFIG_ZBOOT_ROM_BSS=0x0
246CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1 dyntick=enable debug"
247# CONFIG_XIP_KERNEL is not set
248CONFIG_KEXEC=y
249CONFIG_ATAGS_PROC=y
250CONFIG_CPU_FREQ_PXA25x=y
251
252#
253# CPU Frequency scaling
254#
255CONFIG_CPU_FREQ=y
256CONFIG_CPU_FREQ_TABLE=y
257CONFIG_CPU_FREQ_DEBUG=y
258CONFIG_CPU_FREQ_STAT=y
259# CONFIG_CPU_FREQ_STAT_DETAILS is not set
260CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
261# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
262CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
263CONFIG_CPU_FREQ_GOV_POWERSAVE=y
264CONFIG_CPU_FREQ_GOV_USERSPACE=y
265CONFIG_CPU_FREQ_GOV_ONDEMAND=y
266CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
267
268#
269# Floating point emulation
270#
271
272#
273# At least one emulation must be selected
274#
275CONFIG_FPE_NWFPE=y
276# CONFIG_FPE_NWFPE_XP is not set
277# CONFIG_FPE_FASTFPE is not set
278
279#
280# Userspace binary formats
281#
282CONFIG_BINFMT_ELF=y
283CONFIG_BINFMT_AOUT=m
284CONFIG_BINFMT_MISC=m
285
286#
287# Power management options
288#
289CONFIG_PM=y
290# CONFIG_PM_LEGACY is not set
291# CONFIG_PM_DEBUG is not set
292CONFIG_PM_SLEEP=y
293CONFIG_SUSPEND_UP_POSSIBLE=y
294CONFIG_SUSPEND=y
295CONFIG_APM_EMULATION=y
296
297#
298# Networking
299#
300CONFIG_NET=y
301
302#
303# Networking options
304#
305CONFIG_PACKET=m
306CONFIG_PACKET_MMAP=y
307CONFIG_UNIX=y
308CONFIG_XFRM=y
309# CONFIG_XFRM_USER is not set
310# CONFIG_XFRM_SUB_POLICY is not set
311# CONFIG_XFRM_MIGRATE is not set
312# CONFIG_NET_KEY is not set
313CONFIG_INET=y
314# CONFIG_IP_MULTICAST is not set
315# CONFIG_IP_ADVANCED_ROUTER is not set
316CONFIG_IP_FIB_HASH=y
317# CONFIG_IP_PNP is not set
318# CONFIG_NET_IPIP is not set
319# CONFIG_NET_IPGRE is not set
320# CONFIG_ARPD is not set
321CONFIG_SYN_COOKIES=y
322# CONFIG_INET_AH is not set
323# CONFIG_INET_ESP is not set
324# CONFIG_INET_IPCOMP is not set
325# CONFIG_INET_XFRM_TUNNEL is not set
326CONFIG_INET_TUNNEL=m
327CONFIG_INET_XFRM_MODE_TRANSPORT=m
328CONFIG_INET_XFRM_MODE_TUNNEL=m
329CONFIG_INET_XFRM_MODE_BEET=m
330CONFIG_INET_DIAG=m
331CONFIG_INET_TCP_DIAG=m
332# CONFIG_TCP_CONG_ADVANCED is not set
333CONFIG_TCP_CONG_CUBIC=y
334CONFIG_DEFAULT_TCP_CONG="cubic"
335# CONFIG_TCP_MD5SIG is not set
336# CONFIG_IP_VS is not set
337CONFIG_IPV6=m
338# CONFIG_IPV6_PRIVACY is not set
339# CONFIG_IPV6_ROUTER_PREF is not set
340# CONFIG_IPV6_OPTIMISTIC_DAD is not set
341CONFIG_INET6_AH=m
342CONFIG_INET6_ESP=m
343CONFIG_INET6_IPCOMP=m
344# CONFIG_IPV6_MIP6 is not set
345CONFIG_INET6_XFRM_TUNNEL=m
346CONFIG_INET6_TUNNEL=m
347CONFIG_INET6_XFRM_MODE_TRANSPORT=m
348CONFIG_INET6_XFRM_MODE_TUNNEL=m
349CONFIG_INET6_XFRM_MODE_BEET=m
350# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
351CONFIG_IPV6_SIT=m
352CONFIG_IPV6_TUNNEL=m
353# CONFIG_IPV6_MULTIPLE_TABLES is not set
354# CONFIG_NETWORK_SECMARK is not set
355CONFIG_NETFILTER=y
356# CONFIG_NETFILTER_DEBUG is not set
357
358#
359# Core Netfilter Configuration
360#
361# CONFIG_NETFILTER_NETLINK is not set
362# CONFIG_NF_CONNTRACK_ENABLED is not set
363# CONFIG_NF_CONNTRACK is not set
364CONFIG_NETFILTER_XTABLES=m
365# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
366# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
367# CONFIG_NETFILTER_XT_TARGET_MARK is not set
368# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
369# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
370# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
371# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
372# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
373# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
374# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
375# CONFIG_NETFILTER_XT_MATCH_ESP is not set
376# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
377# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
378# CONFIG_NETFILTER_XT_MATCH_MAC is not set
379# CONFIG_NETFILTER_XT_MATCH_MARK is not set
380# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
381# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
382# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
383# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
384# CONFIG_NETFILTER_XT_MATCH_REALM is not set
385# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
386# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
387# CONFIG_NETFILTER_XT_MATCH_STRING is not set
388# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
389# CONFIG_NETFILTER_XT_MATCH_U32 is not set
390# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
391
392#
393# IP: Netfilter Configuration
394#
395CONFIG_IP_NF_QUEUE=m
396CONFIG_IP_NF_IPTABLES=m
397CONFIG_IP_NF_MATCH_IPRANGE=m
398CONFIG_IP_NF_MATCH_TOS=m
399CONFIG_IP_NF_MATCH_RECENT=m
400CONFIG_IP_NF_MATCH_ECN=m
401CONFIG_IP_NF_MATCH_AH=m
402CONFIG_IP_NF_MATCH_TTL=m
403CONFIG_IP_NF_MATCH_OWNER=m
404CONFIG_IP_NF_MATCH_ADDRTYPE=m
405CONFIG_IP_NF_FILTER=m
406CONFIG_IP_NF_TARGET_REJECT=m
407CONFIG_IP_NF_TARGET_LOG=m
408CONFIG_IP_NF_TARGET_ULOG=m
409CONFIG_IP_NF_MANGLE=m
410CONFIG_IP_NF_TARGET_TOS=m
411CONFIG_IP_NF_TARGET_ECN=m
412CONFIG_IP_NF_TARGET_TTL=m
413CONFIG_IP_NF_RAW=m
414CONFIG_IP_NF_ARPTABLES=m
415CONFIG_IP_NF_ARPFILTER=m
416CONFIG_IP_NF_ARP_MANGLE=m
417
418#
419# IPv6: Netfilter Configuration (EXPERIMENTAL)
420#
421# CONFIG_IP6_NF_QUEUE is not set
422# CONFIG_IP6_NF_IPTABLES is not set
423# CONFIG_IP_DCCP is not set
424# CONFIG_IP_SCTP is not set
425# CONFIG_TIPC is not set
426# CONFIG_ATM is not set
427# CONFIG_BRIDGE is not set
428# CONFIG_VLAN_8021Q is not set
429# CONFIG_DECNET is not set
430# CONFIG_LLC2 is not set
431# CONFIG_IPX is not set
432# CONFIG_ATALK is not set
433# CONFIG_X25 is not set
434# CONFIG_LAPB is not set
435# CONFIG_ECONET is not set
436# CONFIG_WAN_ROUTER is not set
437
438#
439# QoS and/or fair queueing
440#
441# CONFIG_NET_SCHED is not set
442
443#
444# Network testing
445#
446# CONFIG_NET_PKTGEN is not set
447# CONFIG_HAMRADIO is not set
448CONFIG_IRDA=m
449
450#
451# IrDA protocols
452#
453CONFIG_IRLAN=m
454CONFIG_IRNET=m
455CONFIG_IRCOMM=m
456# CONFIG_IRDA_ULTRA is not set
457
458#
459# IrDA options
460#
461# CONFIG_IRDA_CACHE_LAST_LSAP is not set
462# CONFIG_IRDA_FAST_RR is not set
463# CONFIG_IRDA_DEBUG is not set
464
465#
466# Infrared-port device drivers
467#
468
469#
470# SIR device drivers
471#
472# CONFIG_IRTTY_SIR is not set
473
474#
475# Dongle support
476#
477# CONFIG_KINGSUN_DONGLE is not set
478
479#
480# Old SIR device drivers
481#
482# CONFIG_IRPORT_SIR is not set
483
484#
485# Old Serial dongle support
486#
487
488#
489# FIR device drivers
490#
491# CONFIG_USB_IRDA is not set
492# CONFIG_SIGMATEL_FIR is not set
493CONFIG_PXA_FICP=m
494# CONFIG_MCS_FIR is not set
495CONFIG_BT=m
496CONFIG_BT_L2CAP=m
497CONFIG_BT_SCO=m
498CONFIG_BT_RFCOMM=m
499CONFIG_BT_RFCOMM_TTY=y
500CONFIG_BT_BNEP=m
501CONFIG_BT_BNEP_MC_FILTER=y
502CONFIG_BT_BNEP_PROTO_FILTER=y
503CONFIG_BT_HIDP=m
504
505#
506# Bluetooth device drivers
507#
508CONFIG_BT_HCIUSB=m
509# CONFIG_BT_HCIUSB_SCO is not set
510CONFIG_BT_HCIUART=m
511CONFIG_BT_HCIUART_H4=y
512CONFIG_BT_HCIUART_BCSP=y
513CONFIG_BT_HCIBCM203X=m
514CONFIG_BT_HCIBPA10X=m
515CONFIG_BT_HCIBFUSB=m
516CONFIG_BT_HCIDTL1=m
517CONFIG_BT_HCIBT3C=m
518CONFIG_BT_HCIBLUECARD=m
519CONFIG_BT_HCIBTUART=m
520CONFIG_BT_HCIVHCI=m
521# CONFIG_AF_RXRPC is not set
522
523#
524# Wireless
525#
526# CONFIG_CFG80211 is not set
527CONFIG_WIRELESS_EXT=y
528# CONFIG_MAC80211 is not set
529CONFIG_IEEE80211=m
530# CONFIG_IEEE80211_DEBUG is not set
531CONFIG_IEEE80211_CRYPT_WEP=m
532CONFIG_IEEE80211_CRYPT_CCMP=m
533CONFIG_IEEE80211_CRYPT_TKIP=m
534CONFIG_IEEE80211_SOFTMAC=m
535# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
536# CONFIG_RFKILL is not set
537# CONFIG_NET_9P is not set
538
539#
540# Device Drivers
541#
542
543#
544# Generic Driver Options
545#
546CONFIG_STANDALONE=y
547CONFIG_PREVENT_FIRMWARE_BUILD=y
548CONFIG_FW_LOADER=y
549# CONFIG_DEBUG_DRIVER is not set
550# CONFIG_DEBUG_DEVRES is not set
551# CONFIG_SYS_HYPERVISOR is not set
552# CONFIG_CONNECTOR is not set
553CONFIG_MTD=y
554# CONFIG_MTD_DEBUG is not set
555# CONFIG_MTD_CONCAT is not set
556CONFIG_MTD_PARTITIONS=y
557# CONFIG_MTD_REDBOOT_PARTS is not set
558CONFIG_MTD_CMDLINE_PARTS=y
559# CONFIG_MTD_AFS_PARTS is not set
560
561#
562# User Modules And Translation Layers
563#
564CONFIG_MTD_CHAR=y
565CONFIG_MTD_BLKDEVS=y
566CONFIG_MTD_BLOCK=y
567# CONFIG_FTL is not set
568# CONFIG_NFTL is not set
569# CONFIG_INFTL is not set
570# CONFIG_RFD_FTL is not set
571# CONFIG_SSFDC is not set
572
573#
574# RAM/ROM/Flash chip drivers
575#
576# CONFIG_MTD_CFI is not set
577# CONFIG_MTD_JEDECPROBE is not set
578CONFIG_MTD_MAP_BANK_WIDTH_1=y
579CONFIG_MTD_MAP_BANK_WIDTH_2=y
580CONFIG_MTD_MAP_BANK_WIDTH_4=y
581# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
582# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
583# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
584CONFIG_MTD_CFI_I1=y
585CONFIG_MTD_CFI_I2=y
586# CONFIG_MTD_CFI_I4 is not set
587# CONFIG_MTD_CFI_I8 is not set
588# CONFIG_MTD_RAM is not set
589CONFIG_MTD_ROM=y
590# CONFIG_MTD_ABSENT is not set
591
592#
593# Mapping drivers for chip access
594#
595CONFIG_MTD_COMPLEX_MAPPINGS=y
596# CONFIG_MTD_PHYSMAP is not set
597CONFIG_MTD_SHARP_SL=y
598# CONFIG_MTD_PLATRAM is not set
599
600#
601# Self-contained MTD device drivers
602#
603# CONFIG_MTD_SLRAM is not set
604# CONFIG_MTD_PHRAM is not set
605# CONFIG_MTD_MTDRAM is not set
606# CONFIG_MTD_BLOCK2MTD is not set
607
608#
609# Disk-On-Chip Device Drivers
610#
611# CONFIG_MTD_DOC2000 is not set
612# CONFIG_MTD_DOC2001 is not set
613# CONFIG_MTD_DOC2001PLUS is not set
614CONFIG_MTD_NAND=y
615CONFIG_MTD_NAND_VERIFY_WRITE=y
616# CONFIG_MTD_NAND_ECC_SMC is not set
617# CONFIG_MTD_NAND_MUSEUM_IDS is not set
618# CONFIG_MTD_NAND_H1900 is not set
619CONFIG_MTD_NAND_IDS=y
620# CONFIG_MTD_NAND_DISKONCHIP is not set
621CONFIG_MTD_NAND_SHARPSL=y
622# CONFIG_MTD_NAND_NANDSIM is not set
623# CONFIG_MTD_NAND_PLATFORM is not set
624# CONFIG_MTD_ONENAND is not set
625
626#
627# UBI - Unsorted block images
628#
629# CONFIG_MTD_UBI is not set
630# CONFIG_PARPORT is not set
631CONFIG_BLK_DEV=y
632# CONFIG_BLK_DEV_COW_COMMON is not set
633CONFIG_BLK_DEV_LOOP=y
634# CONFIG_BLK_DEV_CRYPTOLOOP is not set
635# CONFIG_BLK_DEV_NBD is not set
636# CONFIG_BLK_DEV_UB is not set
637# CONFIG_BLK_DEV_RAM is not set
638# CONFIG_CDROM_PKTCDVD is not set
639# CONFIG_ATA_OVER_ETH is not set
640CONFIG_IDE=y
641CONFIG_IDE_MAX_HWIFS=4
642CONFIG_BLK_DEV_IDE=y
643
644#
645# Please see Documentation/ide.txt for help/info on IDE drives
646#
647# CONFIG_BLK_DEV_IDE_SATA is not set
648CONFIG_BLK_DEV_IDEDISK=y
649# CONFIG_IDEDISK_MULTI_MODE is not set
650CONFIG_BLK_DEV_IDECS=y
651# CONFIG_BLK_DEV_IDECD is not set
652# CONFIG_BLK_DEV_IDETAPE is not set
653# CONFIG_BLK_DEV_IDEFLOPPY is not set
654# CONFIG_BLK_DEV_IDESCSI is not set
655# CONFIG_IDE_TASK_IOCTL is not set
656CONFIG_IDE_PROC_FS=y
657
658#
659# IDE chipset support/bugfixes
660#
661CONFIG_IDE_GENERIC=y
662# CONFIG_IDEPCI_PCIBUS_ORDER is not set
663# CONFIG_IDE_ARM is not set
664# CONFIG_BLK_DEV_IDEDMA is not set
665# CONFIG_BLK_DEV_HD is not set
666
667#
668# SCSI device support
669#
670# CONFIG_RAID_ATTRS is not set
671CONFIG_SCSI=m
672CONFIG_SCSI_DMA=y
673# CONFIG_SCSI_TGT is not set
674# CONFIG_SCSI_NETLINK is not set
675CONFIG_SCSI_PROC_FS=y
676
677#
678# SCSI support type (disk, tape, CD-ROM)
679#
680CONFIG_BLK_DEV_SD=m
681CONFIG_CHR_DEV_ST=m
682CONFIG_CHR_DEV_OSST=m
683CONFIG_BLK_DEV_SR=m
684# CONFIG_BLK_DEV_SR_VENDOR is not set
685CONFIG_CHR_DEV_SG=m
686# CONFIG_CHR_DEV_SCH is not set
687
688#
689# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
690#
691CONFIG_SCSI_MULTI_LUN=y
692# CONFIG_SCSI_CONSTANTS is not set
693# CONFIG_SCSI_LOGGING is not set
694# CONFIG_SCSI_SCAN_ASYNC is not set
695CONFIG_SCSI_WAIT_SCAN=m
696
697#
698# SCSI Transports
699#
700# CONFIG_SCSI_SPI_ATTRS is not set
701# CONFIG_SCSI_FC_ATTRS is not set
702# CONFIG_SCSI_ISCSI_ATTRS is not set
703# CONFIG_SCSI_SAS_LIBSAS is not set
704CONFIG_SCSI_LOWLEVEL=y
705# CONFIG_ISCSI_TCP is not set
706# CONFIG_SCSI_DEBUG is not set
707# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
708# CONFIG_ATA is not set
709CONFIG_MD=y
710# CONFIG_BLK_DEV_MD is not set
711CONFIG_BLK_DEV_DM=m
712# CONFIG_DM_DEBUG is not set
713CONFIG_DM_CRYPT=m
714CONFIG_DM_SNAPSHOT=m
715CONFIG_DM_MIRROR=m
716CONFIG_DM_ZERO=m
717CONFIG_DM_MULTIPATH=m
718CONFIG_DM_MULTIPATH_EMC=m
719# CONFIG_DM_MULTIPATH_RDAC is not set
720# CONFIG_DM_DELAY is not set
721CONFIG_NETDEVICES=y
722# CONFIG_NETDEVICES_MULTIQUEUE is not set
723# CONFIG_DUMMY is not set
724# CONFIG_BONDING is not set
725# CONFIG_MACVLAN is not set
726# CONFIG_EQUALIZER is not set
727CONFIG_TUN=m
728# CONFIG_PHYLIB is not set
729CONFIG_NET_ETHERNET=y
730CONFIG_MII=m
731# CONFIG_AX88796 is not set
732# CONFIG_SMC91X is not set
733# CONFIG_DM9000 is not set
734# CONFIG_SMC911X is not set
735CONFIG_NETDEV_1000=y
736CONFIG_NETDEV_10000=y
737
738#
739# Wireless LAN
740#
741# CONFIG_WLAN_PRE80211 is not set
742CONFIG_WLAN_80211=y
743# CONFIG_PCMCIA_RAYCS is not set
744# CONFIG_LIBERTAS is not set
745CONFIG_HERMES=m
746# CONFIG_ATMEL is not set
747CONFIG_PCMCIA_HERMES=m
748CONFIG_PCMCIA_SPECTRUM=m
749# CONFIG_AIRO_CS is not set
750# CONFIG_PCMCIA_WL3501 is not set
751# CONFIG_USB_ZD1201 is not set
752# CONFIG_RTL8187 is not set
753CONFIG_HOSTAP=m
754CONFIG_HOSTAP_FIRMWARE=y
755# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
756CONFIG_HOSTAP_CS=m
757# CONFIG_ZD1211RW is not set
758
759#
760# USB Network Adapters
761#
762CONFIG_USB_CATC=m
763CONFIG_USB_KAWETH=m
764CONFIG_USB_PEGASUS=m
765CONFIG_USB_RTL8150=m
766CONFIG_USB_USBNET_MII=m
767CONFIG_USB_USBNET=m
768CONFIG_USB_NET_AX8817X=m
769CONFIG_USB_NET_CDCETHER=m
770# CONFIG_USB_NET_DM9601 is not set
771# CONFIG_USB_NET_GL620A is not set
772CONFIG_USB_NET_NET1080=m
773# CONFIG_USB_NET_PLUSB is not set
774# CONFIG_USB_NET_MCS7830 is not set
775# CONFIG_USB_NET_RNDIS_HOST is not set
776# CONFIG_USB_NET_CDC_SUBSET is not set
777CONFIG_USB_NET_ZAURUS=m
778CONFIG_NET_PCMCIA=y
779# CONFIG_PCMCIA_3C589 is not set
780# CONFIG_PCMCIA_3C574 is not set
781# CONFIG_PCMCIA_FMVJ18X is not set
782CONFIG_PCMCIA_PCNET=m
783# CONFIG_PCMCIA_NMCLAN is not set
784# CONFIG_PCMCIA_SMC91C92 is not set
785# CONFIG_PCMCIA_XIRC2PS is not set
786# CONFIG_PCMCIA_AXNET is not set
787# CONFIG_WAN is not set
788CONFIG_PPP=m
789# CONFIG_PPP_MULTILINK is not set
790# CONFIG_PPP_FILTER is not set
791CONFIG_PPP_ASYNC=m
792# CONFIG_PPP_SYNC_TTY is not set
793CONFIG_PPP_DEFLATE=m
794CONFIG_PPP_BSDCOMP=m
795# CONFIG_PPP_MPPE is not set
796# CONFIG_PPPOE is not set
797# CONFIG_PPPOL2TP is not set
798# CONFIG_SLIP is not set
799CONFIG_SLHC=m
800# CONFIG_SHAPER is not set
801# CONFIG_NETCONSOLE is not set
802# CONFIG_NETPOLL is not set
803# CONFIG_NET_POLL_CONTROLLER is not set
804# CONFIG_ISDN is not set
805
806#
807# Input device support
808#
809CONFIG_INPUT=y
810# CONFIG_INPUT_FF_MEMLESS is not set
811# CONFIG_INPUT_POLLDEV is not set
812
813#
814# Userland interfaces
815#
816CONFIG_INPUT_MOUSEDEV=m
817# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
818CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
819CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
820# CONFIG_INPUT_JOYDEV is not set
821# CONFIG_INPUT_TSDEV is not set
822CONFIG_INPUT_EVDEV=y
823# CONFIG_INPUT_EVBUG is not set
824CONFIG_INPUT_POWER=y
825
826#
827# Input Device Drivers
828#
829CONFIG_INPUT_KEYBOARD=y
830# CONFIG_KEYBOARD_ATKBD is not set
831# CONFIG_KEYBOARD_SUNKBD is not set
832# CONFIG_KEYBOARD_LKKBD is not set
833CONFIG_KEYBOARD_LOCOMO=y
834# CONFIG_KEYBOARD_XTKBD is not set
835# CONFIG_KEYBOARD_NEWTON is not set
836# CONFIG_KEYBOARD_STOWAWAY is not set
837# CONFIG_KEYBOARD_CORGI is not set
838# CONFIG_KEYBOARD_SPITZ is not set
839# CONFIG_KEYBOARD_GPIO is not set
840# CONFIG_INPUT_MOUSE is not set
841# CONFIG_INPUT_JOYSTICK is not set
842# CONFIG_INPUT_TABLET is not set
843CONFIG_INPUT_TOUCHSCREEN=y
844CONFIG_TOUCHSCREEN_CORGI=y
845# CONFIG_TOUCHSCREEN_FUJITSU is not set
846# CONFIG_TOUCHSCREEN_GUNZE is not set
847# CONFIG_TOUCHSCREEN_ELO is not set
848# CONFIG_TOUCHSCREEN_MTOUCH is not set
849# CONFIG_TOUCHSCREEN_MK712 is not set
850# CONFIG_TOUCHSCREEN_PENMOUNT is not set
851# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
852# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
853# CONFIG_TOUCHSCREEN_UCB1400 is not set
854# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
855CONFIG_INPUT_MISC=y
856# CONFIG_INPUT_ATI_REMOTE is not set
857# CONFIG_INPUT_ATI_REMOTE2 is not set
858# CONFIG_INPUT_KEYSPAN_REMOTE is not set
859# CONFIG_INPUT_POWERMATE is not set
860# CONFIG_INPUT_YEALINK is not set
861CONFIG_INPUT_UINPUT=m
862
863#
864# Hardware I/O ports
865#
866# CONFIG_SERIO is not set
867# CONFIG_GAMEPORT is not set
868
869#
870# Character devices
871#
872CONFIG_VT=y
873CONFIG_VT_CONSOLE=y
874CONFIG_HW_CONSOLE=y
875# CONFIG_VT_HW_CONSOLE_BINDING is not set
876# CONFIG_SERIAL_NONSTANDARD is not set
877
878#
879# Serial drivers
880#
881CONFIG_SERIAL_8250=m
882CONFIG_SERIAL_8250_CS=m
883CONFIG_SERIAL_8250_NR_UARTS=4
884CONFIG_SERIAL_8250_RUNTIME_UARTS=4
885# CONFIG_SERIAL_8250_EXTENDED is not set
886
887#
888# Non-8250 serial port support
889#
890CONFIG_SERIAL_PXA=y
891CONFIG_SERIAL_PXA_CONSOLE=y
892CONFIG_SERIAL_CORE=y
893CONFIG_SERIAL_CORE_CONSOLE=y
894CONFIG_UNIX98_PTYS=y
895# CONFIG_LEGACY_PTYS is not set
896# CONFIG_IPMI_HANDLER is not set
897# CONFIG_WATCHDOG is not set
898CONFIG_HW_RANDOM=m
899# CONFIG_NVRAM is not set
900# CONFIG_R3964 is not set
901
902#
903# PCMCIA character devices
904#
905# CONFIG_SYNCLINK_CS is not set
906# CONFIG_CARDMAN_4000 is not set
907# CONFIG_CARDMAN_4040 is not set
908# CONFIG_RAW_DRIVER is not set
909# CONFIG_TCG_TPM is not set
910CONFIG_I2C=y
911CONFIG_I2C_BOARDINFO=y
912# CONFIG_I2C_CHARDEV is not set
913
914#
915# I2C Algorithms
916#
917CONFIG_I2C_ALGOBIT=y
918# CONFIG_I2C_ALGOPCF is not set
919# CONFIG_I2C_ALGOPCA is not set
920
921#
922# I2C Hardware Bus support
923#
924# CONFIG_I2C_GPIO is not set
925CONFIG_I2C_PXA=y
926# CONFIG_I2C_PXA_SLAVE is not set
927# CONFIG_I2C_OCORES is not set
928# CONFIG_I2C_PARPORT_LIGHT is not set
929# CONFIG_I2C_SIMTEC is not set
930# CONFIG_I2C_TAOS_EVM is not set
931# CONFIG_I2C_STUB is not set
932# CONFIG_I2C_TINY_USB is not set
933
934#
935# Miscellaneous I2C Chip support
936#
937# CONFIG_SENSORS_DS1337 is not set
938# CONFIG_SENSORS_DS1374 is not set
939# CONFIG_DS1682 is not set
940# CONFIG_SENSORS_EEPROM is not set
941# CONFIG_SENSORS_PCF8574 is not set
942# CONFIG_SENSORS_PCA9539 is not set
943# CONFIG_SENSORS_PCF8591 is not set
944# CONFIG_SENSORS_MAX6875 is not set
945# CONFIG_SENSORS_TSL2550 is not set
946# CONFIG_I2C_DEBUG_CORE is not set
947# CONFIG_I2C_DEBUG_ALGO is not set
948# CONFIG_I2C_DEBUG_BUS is not set
949# CONFIG_I2C_DEBUG_CHIP is not set
950
951#
952# SPI support
953#
954# CONFIG_SPI is not set
955# CONFIG_SPI_MASTER is not set
956# CONFIG_W1 is not set
957# CONFIG_POWER_SUPPLY is not set
958# CONFIG_HWMON is not set
959CONFIG_MISC_DEVICES=y
960# CONFIG_EEPROM_93CX6 is not set
961
962#
963# Multifunction device drivers
964#
965# CONFIG_MFD_SM501 is not set
966# CONFIG_HTC_ASIC3 is not set
967# CONFIG_HTC_ASIC3_DS1WM is not set
968
969#
970# Multi-Function Devices
971#
972CONFIG_NEW_LEDS=y
973CONFIG_LEDS_CLASS=y
974
975#
976# LED drivers
977#
978CONFIG_LEDS_LOCOMO=y
979# CONFIG_LEDS_TOSA is not set
980# CONFIG_LEDS_GPIO is not set
981
982#
983# LED Triggers
984#
985CONFIG_LEDS_TRIGGERS=y
986CONFIG_LEDS_TRIGGER_TIMER=y
987CONFIG_LEDS_TRIGGER_IDE_DISK=y
988# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
989
990#
991# Multimedia devices
992#
993CONFIG_VIDEO_DEV=m
994CONFIG_VIDEO_V4L1=y
995CONFIG_VIDEO_V4L1_COMPAT=y
996CONFIG_VIDEO_V4L2=y
997CONFIG_VIDEO_CAPTURE_DRIVERS=y
998# CONFIG_VIDEO_ADV_DEBUG is not set
999CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1000# CONFIG_VIDEO_CPIA is not set
1001# CONFIG_VIDEO_CPIA2 is not set
1002# CONFIG_VIDEO_SAA5246A is not set
1003# CONFIG_VIDEO_SAA5249 is not set
1004# CONFIG_TUNER_3036 is not set
1005# CONFIG_TUNER_TEA5761 is not set
1006CONFIG_V4L_USB_DRIVERS=y
1007# CONFIG_VIDEO_PVRUSB2 is not set
1008# CONFIG_VIDEO_EM28XX is not set
1009# CONFIG_VIDEO_USBVISION is not set
1010CONFIG_VIDEO_USBVIDEO=m
1011CONFIG_USB_VICAM=m
1012CONFIG_USB_IBMCAM=m
1013CONFIG_USB_KONICAWC=m
1014# CONFIG_USB_QUICKCAM_MESSENGER is not set
1015# CONFIG_USB_ET61X251 is not set
1016# CONFIG_VIDEO_OVCAMCHIP is not set
1017# CONFIG_USB_W9968CF is not set
1018CONFIG_USB_OV511=m
1019CONFIG_USB_SE401=m
1020CONFIG_USB_SN9C102=m
1021CONFIG_USB_STV680=m
1022# CONFIG_USB_ZC0301 is not set
1023# CONFIG_USB_PWC is not set
1024# CONFIG_USB_ZR364XX is not set
1025CONFIG_RADIO_ADAPTERS=y
1026CONFIG_USB_DSBR=m
1027# CONFIG_DVB_CORE is not set
1028CONFIG_DAB=y
1029CONFIG_USB_DABUSB=m
1030
1031#
1032# Graphics support
1033#
1034CONFIG_BACKLIGHT_LCD_SUPPORT=y
1035CONFIG_LCD_CLASS_DEVICE=m
1036CONFIG_BACKLIGHT_CLASS_DEVICE=y
1037# CONFIG_BACKLIGHT_CORGI is not set
1038CONFIG_BACKLIGHT_LOCOMO=y
1039
1040#
1041# Display device support
1042#
1043# CONFIG_DISPLAY_SUPPORT is not set
1044# CONFIG_VGASTATE is not set
1045CONFIG_VIDEO_OUTPUT_CONTROL=m
1046CONFIG_FB=y
1047# CONFIG_FIRMWARE_EDID is not set
1048# CONFIG_FB_DDC is not set
1049CONFIG_FB_CFB_FILLRECT=y
1050CONFIG_FB_CFB_COPYAREA=y
1051CONFIG_FB_CFB_IMAGEBLIT=y
1052# CONFIG_FB_SYS_FILLRECT is not set
1053# CONFIG_FB_SYS_COPYAREA is not set
1054# CONFIG_FB_SYS_IMAGEBLIT is not set
1055# CONFIG_FB_SYS_FOPS is not set
1056CONFIG_FB_DEFERRED_IO=y
1057# CONFIG_FB_SVGALIB is not set
1058# CONFIG_FB_MACMODES is not set
1059# CONFIG_FB_BACKLIGHT is not set
1060CONFIG_FB_MODE_HELPERS=y
1061# CONFIG_FB_TILEBLITTING is not set
1062
1063#
1064# Frame buffer hardware drivers
1065#
1066# CONFIG_FB_S1D13XXX is not set
1067CONFIG_FB_PXA=y
1068CONFIG_FB_PXA_LCD_QVGA=y
1069# CONFIG_FB_PXA_LCD_VGA is not set
1070# CONFIG_FB_PXA_OVERLAY is not set
1071# CONFIG_FB_PXA_PARAMETERS is not set
1072# CONFIG_FB_MBX is not set
1073# CONFIG_FB_W100 is not set
1074# CONFIG_FB_VIRTUAL is not set
1075
1076#
1077# Console display driver support
1078#
1079# CONFIG_VGA_CONSOLE is not set
1080CONFIG_DUMMY_CONSOLE=y
1081CONFIG_FRAMEBUFFER_CONSOLE=y
1082# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1083CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
1084CONFIG_FONTS=y
1085# CONFIG_FONT_8x8 is not set
1086# CONFIG_FONT_8x16 is not set
1087# CONFIG_FONT_6x11 is not set
1088# CONFIG_FONT_7x14 is not set
1089# CONFIG_FONT_PEARL_8x8 is not set
1090# CONFIG_FONT_ACORN_8x8 is not set
1091CONFIG_FONT_MINI_4x6=y
1092# CONFIG_FONT_SUN8x16 is not set
1093# CONFIG_FONT_SUN12x22 is not set
1094# CONFIG_FONT_10x18 is not set
1095CONFIG_LOGO=y
1096CONFIG_LOGO_LINUX_MONO=y
1097CONFIG_LOGO_LINUX_VGA16=y
1098# CONFIG_LOGO_LINUX_CLUT224 is not set
1099CONFIG_LOGO_OHAND_CLUT224=y
1100# CONFIG_LOGO_OZ240_CLUT224 is not set
1101# CONFIG_LOGO_OZ480_CLUT224 is not set
1102# CONFIG_LOGO_OZ640_CLUT224 is not set
1103
1104#
1105# Sound
1106#
1107CONFIG_SOUND=m
1108
1109#
1110# Advanced Linux Sound Architecture
1111#
1112CONFIG_SND=m
1113CONFIG_SND_TIMER=m
1114CONFIG_SND_PCM=m
1115# CONFIG_SND_SEQUENCER is not set
1116CONFIG_SND_OSSEMUL=y
1117CONFIG_SND_MIXER_OSS=m
1118CONFIG_SND_PCM_OSS=m
1119CONFIG_SND_PCM_OSS_PLUGINS=y
1120# CONFIG_SND_DYNAMIC_MINORS is not set
1121CONFIG_SND_SUPPORT_OLD_API=y
1122CONFIG_SND_VERBOSE_PROCFS=y
1123# CONFIG_SND_VERBOSE_PRINTK is not set
1124# CONFIG_SND_DEBUG is not set
1125
1126#
1127# Generic devices
1128#
1129# CONFIG_SND_DUMMY is not set
1130# CONFIG_SND_MTPAV is not set
1131# CONFIG_SND_SERIAL_U16550 is not set
1132# CONFIG_SND_MPU401 is not set
1133
1134#
1135# ALSA ARM devices
1136#
1137# CONFIG_SND_PXA2XX_AC97 is not set
1138
1139#
1140# USB devices
1141#
1142# CONFIG_SND_USB_AUDIO is not set
1143# CONFIG_SND_USB_CAIAQ is not set
1144
1145#
1146# PCMCIA devices
1147#
1148# CONFIG_SND_VXPOCKET is not set
1149# CONFIG_SND_PDAUDIOCF is not set
1150
1151#
1152# System on Chip audio support
1153#
1154CONFIG_SND_SOC=m
1155CONFIG_SND_PXA2XX_SOC=m
1156CONFIG_SND_PXA2XX_SOC_I2S=m
1157CONFIG_SND_PXA2XX_SOC_POODLE=m
1158
1159#
1160# SoC Audio support for SuperH
1161#
1162CONFIG_SND_SOC_WM8731=m
1163
1164#
1165# Open Sound System
1166#
1167# CONFIG_SOUND_PRIME is not set
1168CONFIG_HID_SUPPORT=y
1169CONFIG_HID=m
1170# CONFIG_HID_DEBUG is not set
1171
1172#
1173# USB Input Devices
1174#
1175CONFIG_USB_HID=m
1176# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1177# CONFIG_HID_FF is not set
1178# CONFIG_USB_HIDDEV is not set
1179
1180#
1181# USB HID Boot Protocol drivers
1182#
1183CONFIG_USB_KBD=m
1184CONFIG_USB_MOUSE=m
1185CONFIG_USB_SUPPORT=y
1186CONFIG_USB_ARCH_HAS_HCD=y
1187# CONFIG_USB_ARCH_HAS_OHCI is not set
1188# CONFIG_USB_ARCH_HAS_EHCI is not set
1189CONFIG_USB=m
1190# CONFIG_USB_DEBUG is not set
1191
1192#
1193# Miscellaneous USB options
1194#
1195CONFIG_USB_DEVICEFS=y
1196CONFIG_USB_DEVICE_CLASS=y
1197# CONFIG_USB_DYNAMIC_MINORS is not set
1198# CONFIG_USB_SUSPEND is not set
1199# CONFIG_USB_PERSIST is not set
1200# CONFIG_USB_OTG is not set
1201
1202#
1203# USB Host Controller Drivers
1204#
1205# CONFIG_USB_ISP116X_HCD is not set
1206CONFIG_USB_SL811_HCD=m
1207CONFIG_USB_SL811_CS=m
1208# CONFIG_USB_R8A66597_HCD is not set
1209
1210#
1211# USB Device Class drivers
1212#
1213CONFIG_USB_ACM=m
1214CONFIG_USB_PRINTER=m
1215
1216#
1217# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1218#
1219
1220#
1221# may also be needed; see USB_STORAGE Help for more information
1222#
1223CONFIG_USB_STORAGE=m
1224# CONFIG_USB_STORAGE_DEBUG is not set
1225# CONFIG_USB_STORAGE_DATAFAB is not set
1226# CONFIG_USB_STORAGE_FREECOM is not set
1227# CONFIG_USB_STORAGE_ISD200 is not set
1228# CONFIG_USB_STORAGE_DPCM is not set
1229# CONFIG_USB_STORAGE_USBAT is not set
1230# CONFIG_USB_STORAGE_SDDR09 is not set
1231# CONFIG_USB_STORAGE_SDDR55 is not set
1232# CONFIG_USB_STORAGE_JUMPSHOT is not set
1233# CONFIG_USB_STORAGE_ALAUDA is not set
1234# CONFIG_USB_STORAGE_KARMA is not set
1235# CONFIG_USB_LIBUSUAL is not set
1236
1237#
1238# USB Imaging devices
1239#
1240CONFIG_USB_MDC800=m
1241CONFIG_USB_MICROTEK=m
1242CONFIG_USB_MON=y
1243
1244#
1245# USB port drivers
1246#
1247
1248#
1249# USB Serial Converter support
1250#
1251CONFIG_USB_SERIAL=m
1252CONFIG_USB_SERIAL_GENERIC=y
1253# CONFIG_USB_SERIAL_AIRCABLE is not set
1254# CONFIG_USB_SERIAL_AIRPRIME is not set
1255# CONFIG_USB_SERIAL_ARK3116 is not set
1256CONFIG_USB_SERIAL_BELKIN=m
1257# CONFIG_USB_SERIAL_WHITEHEAT is not set
1258CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1259# CONFIG_USB_SERIAL_CP2101 is not set
1260CONFIG_USB_SERIAL_CYPRESS_M8=m
1261CONFIG_USB_SERIAL_EMPEG=m
1262CONFIG_USB_SERIAL_FTDI_SIO=m
1263# CONFIG_USB_SERIAL_FUNSOFT is not set
1264CONFIG_USB_SERIAL_VISOR=m
1265CONFIG_USB_SERIAL_IPAQ=m
1266CONFIG_USB_SERIAL_IR=m
1267CONFIG_USB_SERIAL_EDGEPORT=m
1268CONFIG_USB_SERIAL_EDGEPORT_TI=m
1269CONFIG_USB_SERIAL_GARMIN=m
1270CONFIG_USB_SERIAL_IPW=m
1271CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1272CONFIG_USB_SERIAL_KEYSPAN=m
1273# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1274# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1275# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1276# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1277# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1278# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1279# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1280# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1281# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1282# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1283# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1284# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1285CONFIG_USB_SERIAL_KLSI=m
1286CONFIG_USB_SERIAL_KOBIL_SCT=m
1287CONFIG_USB_SERIAL_MCT_U232=m
1288# CONFIG_USB_SERIAL_MOS7720 is not set
1289# CONFIG_USB_SERIAL_MOS7840 is not set
1290# CONFIG_USB_SERIAL_NAVMAN is not set
1291CONFIG_USB_SERIAL_PL2303=m
1292# CONFIG_USB_SERIAL_OTI6858 is not set
1293# CONFIG_USB_SERIAL_HP4X is not set
1294CONFIG_USB_SERIAL_SAFE=m
1295# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1296# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1297CONFIG_USB_SERIAL_TI=m
1298CONFIG_USB_SERIAL_CYBERJACK=m
1299CONFIG_USB_SERIAL_XIRCOM=m
1300# CONFIG_USB_SERIAL_OPTION is not set
1301CONFIG_USB_SERIAL_OMNINET=m
1302# CONFIG_USB_SERIAL_DEBUG is not set
1303CONFIG_USB_EZUSB=y
1304
1305#
1306# USB Miscellaneous drivers
1307#
1308CONFIG_USB_EMI62=m
1309CONFIG_USB_EMI26=m
1310# CONFIG_USB_ADUTUX is not set
1311CONFIG_USB_AUERSWALD=m
1312CONFIG_USB_RIO500=m
1313CONFIG_USB_LEGOTOWER=m
1314CONFIG_USB_LCD=m
1315# CONFIG_USB_BERRY_CHARGE is not set
1316CONFIG_USB_LED=m
1317# CONFIG_USB_CYPRESS_CY7C63 is not set
1318CONFIG_USB_CYTHERM=m
1319# CONFIG_USB_PHIDGET is not set
1320CONFIG_USB_IDMOUSE=m
1321# CONFIG_USB_FTDI_ELAN is not set
1322# CONFIG_USB_APPLEDISPLAY is not set
1323# CONFIG_USB_LD is not set
1324# CONFIG_USB_TRANCEVIBRATOR is not set
1325# CONFIG_USB_IOWARRIOR is not set
1326# CONFIG_USB_TEST is not set
1327
1328#
1329# USB DSL modem support
1330#
1331
1332#
1333# USB Gadget Support
1334#
1335CONFIG_USB_GADGET=y
1336# CONFIG_USB_GADGET_DEBUG is not set
1337# CONFIG_USB_GADGET_DEBUG_FILES is not set
1338CONFIG_USB_GADGET_SELECTED=y
1339# CONFIG_USB_GADGET_AMD5536UDC is not set
1340# CONFIG_USB_GADGET_FSL_USB2 is not set
1341# CONFIG_USB_GADGET_NET2280 is not set
1342CONFIG_USB_GADGET_PXA2XX=y
1343CONFIG_USB_PXA2XX=y
1344# CONFIG_USB_PXA2XX_SMALL is not set
1345# CONFIG_USB_GADGET_M66592 is not set
1346# CONFIG_USB_GADGET_PXA27X is not set
1347# CONFIG_USB_GADGET_GOKU is not set
1348# CONFIG_USB_GADGET_LH7A40X is not set
1349# CONFIG_USB_GADGET_OMAP is not set
1350# CONFIG_USB_GADGET_S3C2410 is not set
1351# CONFIG_USB_GADGET_AT91 is not set
1352# CONFIG_USB_GADGET_DUMMY_HCD is not set
1353# CONFIG_USB_GADGET_DUALSPEED is not set
1354CONFIG_USB_ZERO=m
1355CONFIG_USB_ETH=m
1356CONFIG_USB_ETH_RNDIS=y
1357CONFIG_USB_GADGETFS=m
1358CONFIG_USB_FILE_STORAGE=m
1359# CONFIG_USB_FILE_STORAGE_TEST is not set
1360CONFIG_USB_G_SERIAL=m
1361# CONFIG_USB_MIDI_GADGET is not set
1362CONFIG_MMC=y
1363# CONFIG_MMC_DEBUG is not set
1364CONFIG_MMC_UNSAFE_RESUME=y
1365
1366#
1367# MMC/SD Card Drivers
1368#
1369CONFIG_MMC_BLOCK=y
1370CONFIG_MMC_BLOCK_BOUNCE=y
1371
1372#
1373# MMC/SD Host Controller Drivers
1374#
1375CONFIG_MMC_PXA=y
1376CONFIG_RTC_LIB=y
1377CONFIG_RTC_CLASS=y
1378CONFIG_RTC_HCTOSYS=y
1379CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1380# CONFIG_RTC_DEBUG is not set
1381
1382#
1383# RTC interfaces
1384#
1385CONFIG_RTC_INTF_SYSFS=y
1386CONFIG_RTC_INTF_PROC=y
1387CONFIG_RTC_INTF_DEV=y
1388# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1389# CONFIG_RTC_DRV_TEST is not set
1390
1391#
1392# I2C RTC drivers
1393#
1394# CONFIG_RTC_DRV_DS1307 is not set
1395# CONFIG_RTC_DRV_DS1672 is not set
1396# CONFIG_RTC_DRV_MAX6900 is not set
1397# CONFIG_RTC_DRV_RS5C372 is not set
1398# CONFIG_RTC_DRV_ISL1208 is not set
1399# CONFIG_RTC_DRV_X1205 is not set
1400# CONFIG_RTC_DRV_PCF8563 is not set
1401# CONFIG_RTC_DRV_PCF8583 is not set
1402# CONFIG_RTC_DRV_M41T80 is not set
1403
1404#
1405# SPI RTC drivers
1406#
1407
1408#
1409# Platform RTC drivers
1410#
1411# CONFIG_RTC_DRV_CMOS is not set
1412# CONFIG_RTC_DRV_DS1553 is not set
1413# CONFIG_RTC_DRV_STK17TA8 is not set
1414# CONFIG_RTC_DRV_DS1742 is not set
1415# CONFIG_RTC_DRV_M48T86 is not set
1416# CONFIG_RTC_DRV_M48T59 is not set
1417# CONFIG_RTC_DRV_V3020 is not set
1418
1419#
1420# on-CPU RTC drivers
1421#
1422CONFIG_RTC_DRV_SA1100=m
1423
1424#
1425# DMA Engine support
1426#
1427# CONFIG_DMA_ENGINE is not set
1428
1429#
1430# DMA Clients
1431#
1432
1433#
1434# DMA Devices
1435#
1436
1437#
1438# File systems
1439#
1440CONFIG_EXT2_FS=y
1441# CONFIG_EXT2_FS_XATTR is not set
1442# CONFIG_EXT2_FS_XIP is not set
1443CONFIG_EXT3_FS=m
1444CONFIG_EXT3_FS_XATTR=y
1445# CONFIG_EXT3_FS_POSIX_ACL is not set
1446# CONFIG_EXT3_FS_SECURITY is not set
1447# CONFIG_EXT4DEV_FS is not set
1448CONFIG_JBD=m
1449# CONFIG_JBD_DEBUG is not set
1450CONFIG_FS_MBCACHE=y
1451# CONFIG_REISERFS_FS is not set
1452# CONFIG_JFS_FS is not set
1453# CONFIG_FS_POSIX_ACL is not set
1454# CONFIG_XFS_FS is not set
1455# CONFIG_GFS2_FS is not set
1456# CONFIG_OCFS2_FS is not set
1457# CONFIG_MINIX_FS is not set
1458# CONFIG_ROMFS_FS is not set
1459CONFIG_INOTIFY=y
1460CONFIG_INOTIFY_USER=y
1461# CONFIG_QUOTA is not set
1462CONFIG_DNOTIFY=y
1463# CONFIG_AUTOFS_FS is not set
1464# CONFIG_AUTOFS4_FS is not set
1465# CONFIG_FUSE_FS is not set
1466
1467#
1468# CD-ROM/DVD Filesystems
1469#
1470# CONFIG_ISO9660_FS is not set
1471# CONFIG_UDF_FS is not set
1472
1473#
1474# DOS/FAT/NT Filesystems
1475#
1476CONFIG_FAT_FS=y
1477# CONFIG_MSDOS_FS is not set
1478CONFIG_VFAT_FS=y
1479CONFIG_FAT_DEFAULT_CODEPAGE=437
1480CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1481# CONFIG_NTFS_FS is not set
1482
1483#
1484# Pseudo filesystems
1485#
1486CONFIG_PROC_FS=y
1487CONFIG_PROC_SYSCTL=y
1488CONFIG_SYSFS=y
1489CONFIG_TMPFS=y
1490# CONFIG_TMPFS_POSIX_ACL is not set
1491# CONFIG_HUGETLB_PAGE is not set
1492CONFIG_RAMFS=y
1493# CONFIG_CONFIGFS_FS is not set
1494
1495#
1496# Miscellaneous filesystems
1497#
1498# CONFIG_ADFS_FS is not set
1499# CONFIG_AFFS_FS is not set
1500# CONFIG_HFS_FS is not set
1501# CONFIG_HFSPLUS_FS is not set
1502# CONFIG_BEFS_FS is not set
1503# CONFIG_BFS_FS is not set
1504# CONFIG_EFS_FS is not set
1505CONFIG_JFFS2_FS=y
1506CONFIG_JFFS2_FS_DEBUG=0
1507CONFIG_JFFS2_FS_WRITEBUFFER=y
1508CONFIG_JFFS2_SUMMARY=y
1509# CONFIG_JFFS2_FS_XATTR is not set
1510# CONFIG_JFFS2_SYSFS is not set
1511CONFIG_JFFS2_COMPRESSION_OPTIONS=y
1512CONFIG_JFFS2_ZLIB=y
1513CONFIG_JFFS2_LZO=y
1514CONFIG_JFFS2_RTIME=y
1515CONFIG_JFFS2_RUBIN=y
1516# CONFIG_JFFS2_CMODE_NONE is not set
1517CONFIG_JFFS2_CMODE_PRIORITY=y
1518# CONFIG_JFFS2_CMODE_SIZE is not set
1519# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
1520CONFIG_CRAMFS=m
1521CONFIG_SQUASHFS=m
1522# CONFIG_SQUASHFS_EMBEDDED is not set
1523CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1524# CONFIG_SQUASHFS_VMALLOC is not set
1525# CONFIG_VXFS_FS is not set
1526# CONFIG_HPFS_FS is not set
1527# CONFIG_QNX4FS_FS is not set
1528# CONFIG_SYSV_FS is not set
1529# CONFIG_UFS_FS is not set
1530
1531#
1532# Network File Systems
1533#
1534CONFIG_NFS_FS=m
1535CONFIG_NFS_V3=y
1536# CONFIG_NFS_V3_ACL is not set
1537CONFIG_NFS_V4=y
1538# CONFIG_NFS_DIRECTIO is not set
1539# CONFIG_NFSD is not set
1540CONFIG_LOCKD=m
1541CONFIG_LOCKD_V4=y
1542CONFIG_NFS_COMMON=y
1543CONFIG_SUNRPC=m
1544CONFIG_SUNRPC_GSS=m
1545# CONFIG_SUNRPC_BIND34 is not set
1546CONFIG_RPCSEC_GSS_KRB5=m
1547# CONFIG_RPCSEC_GSS_SPKM3 is not set
1548CONFIG_SMB_FS=m
1549CONFIG_SMB_NLS_DEFAULT=y
1550CONFIG_SMB_NLS_REMOTE="cp437"
1551CONFIG_CIFS=m
1552# CONFIG_CIFS_STATS is not set
1553# CONFIG_CIFS_WEAK_PW_HASH is not set
1554# CONFIG_CIFS_XATTR is not set
1555# CONFIG_CIFS_DEBUG2 is not set
1556# CONFIG_CIFS_EXPERIMENTAL is not set
1557# CONFIG_NCP_FS is not set
1558# CONFIG_CODA_FS is not set
1559# CONFIG_AFS_FS is not set
1560
1561#
1562# Partition Types
1563#
1564CONFIG_PARTITION_ADVANCED=y
1565# CONFIG_ACORN_PARTITION is not set
1566# CONFIG_OSF_PARTITION is not set
1567# CONFIG_AMIGA_PARTITION is not set
1568# CONFIG_ATARI_PARTITION is not set
1569# CONFIG_MAC_PARTITION is not set
1570CONFIG_MSDOS_PARTITION=y
1571# CONFIG_BSD_DISKLABEL is not set
1572# CONFIG_MINIX_SUBPARTITION is not set
1573# CONFIG_SOLARIS_X86_PARTITION is not set
1574# CONFIG_UNIXWARE_DISKLABEL is not set
1575# CONFIG_LDM_PARTITION is not set
1576# CONFIG_SGI_PARTITION is not set
1577# CONFIG_ULTRIX_PARTITION is not set
1578# CONFIG_SUN_PARTITION is not set
1579# CONFIG_KARMA_PARTITION is not set
1580# CONFIG_EFI_PARTITION is not set
1581# CONFIG_SYSV68_PARTITION is not set
1582
1583#
1584# Native Language Support
1585#
1586CONFIG_NLS=y
1587CONFIG_NLS_DEFAULT="cp437"
1588CONFIG_NLS_CODEPAGE_437=y
1589CONFIG_NLS_CODEPAGE_737=m
1590CONFIG_NLS_CODEPAGE_775=m
1591CONFIG_NLS_CODEPAGE_850=m
1592CONFIG_NLS_CODEPAGE_852=m
1593CONFIG_NLS_CODEPAGE_855=m
1594CONFIG_NLS_CODEPAGE_857=m
1595CONFIG_NLS_CODEPAGE_860=m
1596CONFIG_NLS_CODEPAGE_861=m
1597CONFIG_NLS_CODEPAGE_862=m
1598CONFIG_NLS_CODEPAGE_863=m
1599CONFIG_NLS_CODEPAGE_864=m
1600CONFIG_NLS_CODEPAGE_865=m
1601CONFIG_NLS_CODEPAGE_866=m
1602CONFIG_NLS_CODEPAGE_869=m
1603CONFIG_NLS_CODEPAGE_936=m
1604CONFIG_NLS_CODEPAGE_950=m
1605CONFIG_NLS_CODEPAGE_932=m
1606CONFIG_NLS_CODEPAGE_949=m
1607CONFIG_NLS_CODEPAGE_874=m
1608CONFIG_NLS_ISO8859_8=m
1609CONFIG_NLS_CODEPAGE_1250=m
1610CONFIG_NLS_CODEPAGE_1251=m
1611CONFIG_NLS_ASCII=m
1612CONFIG_NLS_ISO8859_1=y
1613CONFIG_NLS_ISO8859_2=m
1614CONFIG_NLS_ISO8859_3=m
1615CONFIG_NLS_ISO8859_4=m
1616CONFIG_NLS_ISO8859_5=m
1617CONFIG_NLS_ISO8859_6=m
1618CONFIG_NLS_ISO8859_7=m
1619CONFIG_NLS_ISO8859_9=m
1620CONFIG_NLS_ISO8859_13=m
1621CONFIG_NLS_ISO8859_14=m
1622CONFIG_NLS_ISO8859_15=m
1623CONFIG_NLS_KOI8_R=m
1624CONFIG_NLS_KOI8_U=m
1625CONFIG_NLS_UTF8=y
1626
1627#
1628# Distributed Lock Manager
1629#
1630# CONFIG_DLM is not set
1631
1632#
1633# Profiling support
1634#
1635CONFIG_PROFILING=y
1636CONFIG_OPROFILE=m
1637
1638#
1639# Kernel hacking
1640#
1641# CONFIG_PRINTK_TIME is not set
1642CONFIG_ENABLE_MUST_CHECK=y
1643CONFIG_MAGIC_SYSRQ=y
1644# CONFIG_UNUSED_SYMBOLS is not set
1645# CONFIG_DEBUG_FS is not set
1646# CONFIG_HEADERS_CHECK is not set
1647CONFIG_DEBUG_KERNEL=y
1648# CONFIG_DEBUG_SHIRQ is not set
1649# CONFIG_DETECT_SOFTLOCKUP is not set
1650# CONFIG_SCHED_DEBUG is not set
1651# CONFIG_SCHEDSTATS is not set
1652CONFIG_TIMER_STATS=y
1653# CONFIG_DEBUG_SLAB is not set
1654# CONFIG_DEBUG_PREEMPT is not set
1655# CONFIG_DEBUG_RT_MUTEXES is not set
1656# CONFIG_RT_MUTEX_TESTER is not set
1657# CONFIG_DEBUG_SPINLOCK is not set
1658# CONFIG_DEBUG_MUTEXES is not set
1659# CONFIG_DEBUG_LOCK_ALLOC is not set
1660# CONFIG_PROVE_LOCKING is not set
1661# CONFIG_LOCK_STAT is not set
1662# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1663# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1664# CONFIG_DEBUG_KOBJECT is not set
1665CONFIG_DEBUG_BUGVERBOSE=y
1666# CONFIG_DEBUG_INFO is not set
1667# CONFIG_DEBUG_VM is not set
1668# CONFIG_DEBUG_LIST is not set
1669CONFIG_FRAME_POINTER=y
1670# CONFIG_FORCED_INLINING is not set
1671# CONFIG_RCU_TORTURE_TEST is not set
1672# CONFIG_FAULT_INJECTION is not set
1673# CONFIG_DEBUG_USER is not set
1674CONFIG_DEBUG_ERRORS=y
1675# CONFIG_DEBUG_LL is not set
1676
1677#
1678# Security options
1679#
1680# CONFIG_KEYS is not set
1681# CONFIG_SECURITY is not set
1682CONFIG_CRYPTO=y
1683CONFIG_CRYPTO_ALGAPI=m
1684CONFIG_CRYPTO_BLKCIPHER=m
1685CONFIG_CRYPTO_HASH=m
1686CONFIG_CRYPTO_MANAGER=m
1687CONFIG_CRYPTO_HMAC=m
1688# CONFIG_CRYPTO_XCBC is not set
1689CONFIG_CRYPTO_NULL=m
1690CONFIG_CRYPTO_MD4=m
1691CONFIG_CRYPTO_MD5=m
1692CONFIG_CRYPTO_SHA1=m
1693CONFIG_CRYPTO_SHA256=m
1694CONFIG_CRYPTO_SHA512=m
1695CONFIG_CRYPTO_WP512=m
1696# CONFIG_CRYPTO_TGR192 is not set
1697# CONFIG_CRYPTO_GF128MUL is not set
1698CONFIG_CRYPTO_ECB=m
1699CONFIG_CRYPTO_CBC=m
1700CONFIG_CRYPTO_PCBC=m
1701# CONFIG_CRYPTO_LRW is not set
1702# CONFIG_CRYPTO_CRYPTD is not set
1703CONFIG_CRYPTO_DES=m
1704# CONFIG_CRYPTO_FCRYPT is not set
1705CONFIG_CRYPTO_BLOWFISH=m
1706CONFIG_CRYPTO_TWOFISH=m
1707CONFIG_CRYPTO_TWOFISH_COMMON=m
1708CONFIG_CRYPTO_SERPENT=m
1709CONFIG_CRYPTO_AES=m
1710CONFIG_CRYPTO_CAST5=m
1711CONFIG_CRYPTO_CAST6=m
1712CONFIG_CRYPTO_TEA=m
1713CONFIG_CRYPTO_ARC4=m
1714CONFIG_CRYPTO_KHAZAD=m
1715CONFIG_CRYPTO_ANUBIS=m
1716CONFIG_CRYPTO_DEFLATE=m
1717CONFIG_CRYPTO_LZO=m
1718CONFIG_CRYPTO_MICHAEL_MIC=m
1719CONFIG_CRYPTO_CRC32C=m
1720CONFIG_CRYPTO_CAMELLIA=m
1721CONFIG_CRYPTO_TEST=m
1722CONFIG_CRYPTO_HW=y
1723
1724#
1725# Library routines
1726#
1727CONFIG_BITREVERSE=y
1728CONFIG_CRC_CCITT=y
1729# CONFIG_CRC16 is not set
1730# CONFIG_CRC_ITU_T is not set
1731CONFIG_CRC32=y
1732# CONFIG_CRC7 is not set
1733CONFIG_LIBCRC32C=m
1734CONFIG_ZLIB_INFLATE=y
1735CONFIG_ZLIB_DEFLATE=y
1736CONFIG_LZO_COMPRESS=y
1737CONFIG_LZO_DECOMPRESS=y
1738CONFIG_PLIST=y
1739CONFIG_HAS_IOMEM=y
1740CONFIG_HAS_IOPORT=y
1741CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemuarm b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemuarm
new file mode 100644
index 0000000000..78f08bea40
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemuarm
@@ -0,0 +1,1397 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Fri Jan 11 00:23:17 2008
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8# CONFIG_GENERIC_GPIO is not set
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27
28#
29# General setup
30#
31CONFIG_EXPERIMENTAL=y
32CONFIG_BROKEN_ON_SMP=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36CONFIG_SWAP=y
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39# CONFIG_POSIX_MQUEUE is not set
40# CONFIG_BSD_PROCESS_ACCT is not set
41# CONFIG_TASKSTATS is not set
42# CONFIG_USER_NS is not set
43# CONFIG_AUDIT is not set
44CONFIG_IKCONFIG=y
45CONFIG_IKCONFIG_PROC=y
46CONFIG_LOG_BUF_SHIFT=14
47CONFIG_SYSFS_DEPRECATED=y
48# CONFIG_RELAY is not set
49CONFIG_BLK_DEV_INITRD=y
50CONFIG_INITRAMFS_SOURCE=""
51CONFIG_CC_OPTIMIZE_FOR_SIZE=y
52CONFIG_SYSCTL=y
53CONFIG_EMBEDDED=y
54CONFIG_UID16=y
55CONFIG_SYSCTL_SYSCALL=y
56CONFIG_KALLSYMS=y
57# CONFIG_KALLSYMS_ALL is not set
58# CONFIG_KALLSYMS_EXTRA_PASS is not set
59CONFIG_HOTPLUG=y
60CONFIG_PRINTK=y
61CONFIG_BUG=y
62CONFIG_ELF_CORE=y
63CONFIG_BASE_FULL=y
64CONFIG_FUTEX=y
65CONFIG_ANON_INODES=y
66CONFIG_EPOLL=y
67CONFIG_SIGNALFD=y
68CONFIG_EVENTFD=y
69CONFIG_SHMEM=y
70CONFIG_VM_EVENT_COUNTERS=y
71CONFIG_SLAB=y
72# CONFIG_SLUB is not set
73# CONFIG_SLOB is not set
74CONFIG_RT_MUTEXES=y
75# CONFIG_TINY_SHMEM is not set
76CONFIG_BASE_SMALL=0
77CONFIG_MODULES=y
78CONFIG_MODULE_UNLOAD=y
79# CONFIG_MODULE_FORCE_UNLOAD is not set
80# CONFIG_MODVERSIONS is not set
81# CONFIG_MODULE_SRCVERSION_ALL is not set
82CONFIG_KMOD=y
83CONFIG_BLOCK=y
84# CONFIG_LBD is not set
85# CONFIG_BLK_DEV_IO_TRACE is not set
86# CONFIG_LSF is not set
87# CONFIG_BLK_DEV_BSG is not set
88
89#
90# IO Schedulers
91#
92CONFIG_IOSCHED_NOOP=y
93CONFIG_IOSCHED_AS=y
94CONFIG_IOSCHED_DEADLINE=y
95CONFIG_IOSCHED_CFQ=y
96CONFIG_DEFAULT_AS=y
97# CONFIG_DEFAULT_DEADLINE is not set
98# CONFIG_DEFAULT_CFQ is not set
99# CONFIG_DEFAULT_NOOP is not set
100CONFIG_DEFAULT_IOSCHED="anticipatory"
101
102#
103# System Type
104#
105# CONFIG_ARCH_AAEC2000 is not set
106# CONFIG_ARCH_INTEGRATOR is not set
107# CONFIG_ARCH_REALVIEW is not set
108CONFIG_ARCH_VERSATILE=y
109# CONFIG_ARCH_AT91 is not set
110# CONFIG_ARCH_CLPS7500 is not set
111# CONFIG_ARCH_CLPS711X is not set
112# CONFIG_ARCH_CO285 is not set
113# CONFIG_ARCH_EBSA110 is not set
114# CONFIG_ARCH_EP93XX is not set
115# CONFIG_ARCH_FOOTBRIDGE is not set
116# CONFIG_ARCH_NETX is not set
117# CONFIG_ARCH_H720X is not set
118# CONFIG_ARCH_IMX is not set
119# CONFIG_ARCH_IOP13XX is not set
120# CONFIG_ARCH_IOP32X is not set
121# CONFIG_ARCH_IOP33X is not set
122# CONFIG_ARCH_IXP23XX is not set
123# CONFIG_ARCH_IXP2000 is not set
124# CONFIG_ARCH_IXP4XX is not set
125# CONFIG_ARCH_L7200 is not set
126# CONFIG_ARCH_KS8695 is not set
127# CONFIG_ARCH_NS9XXX is not set
128# CONFIG_ARCH_MXC is not set
129# CONFIG_ARCH_PNX4008 is not set
130# CONFIG_ARCH_PXA is not set
131# CONFIG_ARCH_RPC is not set
132# CONFIG_ARCH_SA1100 is not set
133# CONFIG_ARCH_S3C2410 is not set
134# CONFIG_ARCH_SHARK is not set
135# CONFIG_ARCH_LH7A40X is not set
136# CONFIG_ARCH_DAVINCI is not set
137# CONFIG_ARCH_OMAP is not set
138
139#
140# Boot options
141#
142
143#
144# Power management
145#
146
147#
148# Versatile platform type
149#
150CONFIG_ARCH_VERSATILE_PB=y
151# CONFIG_MACH_VERSATILE_AB is not set
152
153#
154# Processor Type
155#
156CONFIG_CPU_32=y
157CONFIG_CPU_ARM926T=y
158CONFIG_CPU_32v5=y
159CONFIG_CPU_ABRT_EV5TJ=y
160CONFIG_CPU_CACHE_VIVT=y
161CONFIG_CPU_COPY_V4WB=y
162CONFIG_CPU_TLB_V4WBI=y
163CONFIG_CPU_CP15=y
164CONFIG_CPU_CP15_MMU=y
165
166#
167# Processor Features
168#
169CONFIG_ARM_THUMB=y
170# CONFIG_CPU_ICACHE_DISABLE is not set
171# CONFIG_CPU_DCACHE_DISABLE is not set
172# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
173# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
174# CONFIG_OUTER_CACHE is not set
175CONFIG_ARM_VIC=y
176CONFIG_ICST307=y
177
178#
179# Bus support
180#
181CONFIG_ARM_AMBA=y
182CONFIG_PCI=y
183CONFIG_PCI_SYSCALL=y
184# CONFIG_ARCH_SUPPORTS_MSI is not set
185# CONFIG_PCI_DEBUG is not set
186
187#
188# PCCARD (PCMCIA/CardBus) support
189#
190# CONFIG_PCCARD is not set
191
192#
193# Kernel Features
194#
195# CONFIG_TICK_ONESHOT is not set
196# CONFIG_NO_HZ is not set
197# CONFIG_HIGH_RES_TIMERS is not set
198# CONFIG_PREEMPT is not set
199CONFIG_HZ=100
200CONFIG_AEABI=y
201CONFIG_OABI_COMPAT=y
202# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
203CONFIG_SELECT_MEMORY_MODEL=y
204CONFIG_FLATMEM_MANUAL=y
205# CONFIG_DISCONTIGMEM_MANUAL is not set
206# CONFIG_SPARSEMEM_MANUAL is not set
207CONFIG_FLATMEM=y
208CONFIG_FLAT_NODE_MEM_MAP=y
209# CONFIG_SPARSEMEM_STATIC is not set
210CONFIG_SPLIT_PTLOCK_CPUS=4096
211# CONFIG_RESOURCES_64BIT is not set
212CONFIG_ZONE_DMA_FLAG=1
213CONFIG_BOUNCE=y
214CONFIG_VIRT_TO_BUS=y
215CONFIG_LEDS=y
216CONFIG_LEDS_CPU=y
217CONFIG_ALIGNMENT_TRAP=y
218
219#
220# Boot options
221#
222CONFIG_ZBOOT_ROM_TEXT=0x0
223CONFIG_ZBOOT_ROM_BSS=0x0
224CONFIG_CMDLINE="console=ttyAMA0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 dyntick=enable debug"
225# CONFIG_XIP_KERNEL is not set
226CONFIG_KEXEC=y
227CONFIG_ATAGS_PROC=y
228
229#
230# Floating point emulation
231#
232
233#
234# At least one emulation must be selected
235#
236CONFIG_FPE_NWFPE=y
237# CONFIG_FPE_NWFPE_XP is not set
238# CONFIG_FPE_FASTFPE is not set
239CONFIG_VFP=y
240
241#
242# Userspace binary formats
243#
244CONFIG_BINFMT_ELF=y
245# CONFIG_BINFMT_AOUT is not set
246# CONFIG_BINFMT_MISC is not set
247
248#
249# Power management options
250#
251CONFIG_PM=y
252# CONFIG_PM_LEGACY is not set
253# CONFIG_PM_DEBUG is not set
254CONFIG_PM_SLEEP=y
255CONFIG_SUSPEND_UP_POSSIBLE=y
256CONFIG_SUSPEND=y
257# CONFIG_APM_EMULATION is not set
258
259#
260# Networking
261#
262CONFIG_NET=y
263
264#
265# Networking options
266#
267CONFIG_PACKET=m
268CONFIG_PACKET_MMAP=y
269CONFIG_UNIX=y
270CONFIG_XFRM=y
271# CONFIG_XFRM_USER is not set
272# CONFIG_XFRM_SUB_POLICY is not set
273# CONFIG_XFRM_MIGRATE is not set
274# CONFIG_NET_KEY is not set
275CONFIG_INET=y
276CONFIG_IP_MULTICAST=y
277# CONFIG_IP_ADVANCED_ROUTER is not set
278CONFIG_IP_FIB_HASH=y
279CONFIG_IP_PNP=y
280CONFIG_IP_PNP_DHCP=y
281CONFIG_IP_PNP_BOOTP=y
282# CONFIG_IP_PNP_RARP is not set
283# CONFIG_NET_IPIP is not set
284# CONFIG_NET_IPGRE is not set
285# CONFIG_IP_MROUTE is not set
286# CONFIG_ARPD is not set
287# CONFIG_SYN_COOKIES is not set
288# CONFIG_INET_AH is not set
289# CONFIG_INET_ESP is not set
290# CONFIG_INET_IPCOMP is not set
291# CONFIG_INET_XFRM_TUNNEL is not set
292# CONFIG_INET_TUNNEL is not set
293CONFIG_INET_XFRM_MODE_TRANSPORT=y
294CONFIG_INET_XFRM_MODE_TUNNEL=y
295CONFIG_INET_XFRM_MODE_BEET=y
296CONFIG_INET_DIAG=y
297CONFIG_INET_TCP_DIAG=y
298# CONFIG_TCP_CONG_ADVANCED is not set
299CONFIG_TCP_CONG_CUBIC=y
300CONFIG_DEFAULT_TCP_CONG="cubic"
301# CONFIG_TCP_MD5SIG is not set
302# CONFIG_IP_VS is not set
303# CONFIG_IPV6 is not set
304# CONFIG_INET6_XFRM_TUNNEL is not set
305# CONFIG_INET6_TUNNEL is not set
306# CONFIG_NETWORK_SECMARK is not set
307CONFIG_NETFILTER=y
308# CONFIG_NETFILTER_DEBUG is not set
309
310#
311# Core Netfilter Configuration
312#
313# CONFIG_NETFILTER_NETLINK is not set
314# CONFIG_NF_CONNTRACK_ENABLED is not set
315# CONFIG_NF_CONNTRACK is not set
316CONFIG_NETFILTER_XTABLES=m
317# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
318# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
319# CONFIG_NETFILTER_XT_TARGET_MARK is not set
320# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
321# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
322# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
323# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
324# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
325# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
326# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
327# CONFIG_NETFILTER_XT_MATCH_ESP is not set
328# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
329# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
330# CONFIG_NETFILTER_XT_MATCH_MAC is not set
331# CONFIG_NETFILTER_XT_MATCH_MARK is not set
332# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
333# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
334# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
335# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
336# CONFIG_NETFILTER_XT_MATCH_REALM is not set
337# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
338# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
339# CONFIG_NETFILTER_XT_MATCH_STRING is not set
340# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
341# CONFIG_NETFILTER_XT_MATCH_U32 is not set
342# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
343
344#
345# IP: Netfilter Configuration
346#
347CONFIG_IP_NF_QUEUE=m
348CONFIG_IP_NF_IPTABLES=m
349CONFIG_IP_NF_MATCH_IPRANGE=m
350CONFIG_IP_NF_MATCH_TOS=m
351CONFIG_IP_NF_MATCH_RECENT=m
352CONFIG_IP_NF_MATCH_ECN=m
353CONFIG_IP_NF_MATCH_AH=m
354CONFIG_IP_NF_MATCH_TTL=m
355CONFIG_IP_NF_MATCH_OWNER=m
356CONFIG_IP_NF_MATCH_ADDRTYPE=m
357CONFIG_IP_NF_FILTER=m
358CONFIG_IP_NF_TARGET_REJECT=m
359CONFIG_IP_NF_TARGET_LOG=m
360CONFIG_IP_NF_TARGET_ULOG=m
361CONFIG_IP_NF_MANGLE=m
362CONFIG_IP_NF_TARGET_TOS=m
363CONFIG_IP_NF_TARGET_ECN=m
364CONFIG_IP_NF_TARGET_TTL=m
365CONFIG_IP_NF_RAW=m
366CONFIG_IP_NF_ARPTABLES=m
367CONFIG_IP_NF_ARPFILTER=m
368CONFIG_IP_NF_ARP_MANGLE=m
369# CONFIG_IP_DCCP is not set
370# CONFIG_IP_SCTP is not set
371# CONFIG_TIPC is not set
372# CONFIG_ATM is not set
373# CONFIG_BRIDGE is not set
374# CONFIG_VLAN_8021Q is not set
375# CONFIG_DECNET is not set
376# CONFIG_LLC2 is not set
377# CONFIG_IPX is not set
378# CONFIG_ATALK is not set
379# CONFIG_X25 is not set
380# CONFIG_LAPB is not set
381# CONFIG_ECONET is not set
382# CONFIG_WAN_ROUTER is not set
383
384#
385# QoS and/or fair queueing
386#
387# CONFIG_NET_SCHED is not set
388
389#
390# Network testing
391#
392# CONFIG_NET_PKTGEN is not set
393# CONFIG_HAMRADIO is not set
394# CONFIG_IRDA is not set
395# CONFIG_BT is not set
396# CONFIG_AF_RXRPC is not set
397
398#
399# Wireless
400#
401# CONFIG_CFG80211 is not set
402# CONFIG_WIRELESS_EXT is not set
403# CONFIG_MAC80211 is not set
404# CONFIG_IEEE80211 is not set
405# CONFIG_RFKILL is not set
406# CONFIG_NET_9P is not set
407
408#
409# Device Drivers
410#
411
412#
413# Generic Driver Options
414#
415CONFIG_STANDALONE=y
416CONFIG_PREVENT_FIRMWARE_BUILD=y
417# CONFIG_FW_LOADER is not set
418# CONFIG_DEBUG_DRIVER is not set
419# CONFIG_DEBUG_DEVRES is not set
420# CONFIG_SYS_HYPERVISOR is not set
421# CONFIG_CONNECTOR is not set
422CONFIG_MTD=y
423# CONFIG_MTD_DEBUG is not set
424# CONFIG_MTD_CONCAT is not set
425CONFIG_MTD_PARTITIONS=y
426# CONFIG_MTD_REDBOOT_PARTS is not set
427CONFIG_MTD_CMDLINE_PARTS=y
428CONFIG_MTD_AFS_PARTS=y
429
430#
431# User Modules And Translation Layers
432#
433CONFIG_MTD_CHAR=y
434CONFIG_MTD_BLKDEVS=y
435CONFIG_MTD_BLOCK=y
436# CONFIG_FTL is not set
437# CONFIG_NFTL is not set
438# CONFIG_INFTL is not set
439# CONFIG_RFD_FTL is not set
440# CONFIG_SSFDC is not set
441
442#
443# RAM/ROM/Flash chip drivers
444#
445CONFIG_MTD_CFI=y
446# CONFIG_MTD_JEDECPROBE is not set
447CONFIG_MTD_GEN_PROBE=y
448CONFIG_MTD_CFI_ADV_OPTIONS=y
449CONFIG_MTD_CFI_NOSWAP=y
450# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
451# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
452# CONFIG_MTD_CFI_GEOMETRY is not set
453CONFIG_MTD_MAP_BANK_WIDTH_1=y
454CONFIG_MTD_MAP_BANK_WIDTH_2=y
455CONFIG_MTD_MAP_BANK_WIDTH_4=y
456# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
457# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
458# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
459CONFIG_MTD_CFI_I1=y
460CONFIG_MTD_CFI_I2=y
461# CONFIG_MTD_CFI_I4 is not set
462# CONFIG_MTD_CFI_I8 is not set
463# CONFIG_MTD_OTP is not set
464CONFIG_MTD_CFI_INTELEXT=y
465# CONFIG_MTD_CFI_AMDSTD is not set
466# CONFIG_MTD_CFI_STAA is not set
467CONFIG_MTD_CFI_UTIL=y
468# CONFIG_MTD_RAM is not set
469# CONFIG_MTD_ROM is not set
470# CONFIG_MTD_ABSENT is not set
471
472#
473# Mapping drivers for chip access
474#
475# CONFIG_MTD_COMPLEX_MAPPINGS is not set
476# CONFIG_MTD_PHYSMAP is not set
477# CONFIG_MTD_ARM_INTEGRATOR is not set
478# CONFIG_MTD_PLATRAM is not set
479
480#
481# Self-contained MTD device drivers
482#
483# CONFIG_MTD_PMC551 is not set
484# CONFIG_MTD_SLRAM is not set
485# CONFIG_MTD_PHRAM is not set
486# CONFIG_MTD_MTDRAM is not set
487# CONFIG_MTD_BLOCK2MTD is not set
488
489#
490# Disk-On-Chip Device Drivers
491#
492# CONFIG_MTD_DOC2000 is not set
493# CONFIG_MTD_DOC2001 is not set
494# CONFIG_MTD_DOC2001PLUS is not set
495# CONFIG_MTD_NAND is not set
496# CONFIG_MTD_ONENAND is not set
497
498#
499# UBI - Unsorted block images
500#
501# CONFIG_MTD_UBI is not set
502# CONFIG_PARPORT is not set
503CONFIG_BLK_DEV=y
504# CONFIG_BLK_CPQ_DA is not set
505# CONFIG_BLK_CPQ_CISS_DA is not set
506# CONFIG_BLK_DEV_DAC960 is not set
507# CONFIG_BLK_DEV_UMEM is not set
508# CONFIG_BLK_DEV_COW_COMMON is not set
509CONFIG_BLK_DEV_LOOP=y
510# CONFIG_BLK_DEV_CRYPTOLOOP is not set
511# CONFIG_BLK_DEV_NBD is not set
512# CONFIG_BLK_DEV_SX8 is not set
513# CONFIG_BLK_DEV_UB is not set
514CONFIG_BLK_DEV_RAM=y
515CONFIG_BLK_DEV_RAM_COUNT=16
516CONFIG_BLK_DEV_RAM_SIZE=51200
517CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
518# CONFIG_CDROM_PKTCDVD is not set
519# CONFIG_ATA_OVER_ETH is not set
520
521#
522# SCSI device support
523#
524# CONFIG_RAID_ATTRS is not set
525CONFIG_SCSI=y
526CONFIG_SCSI_DMA=y
527# CONFIG_SCSI_TGT is not set
528# CONFIG_SCSI_NETLINK is not set
529CONFIG_SCSI_PROC_FS=y
530
531#
532# SCSI support type (disk, tape, CD-ROM)
533#
534CONFIG_BLK_DEV_SD=y
535# CONFIG_CHR_DEV_ST is not set
536# CONFIG_CHR_DEV_OSST is not set
537# CONFIG_BLK_DEV_SR is not set
538# CONFIG_CHR_DEV_SG is not set
539# CONFIG_CHR_DEV_SCH is not set
540
541#
542# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
543#
544# CONFIG_SCSI_MULTI_LUN is not set
545# CONFIG_SCSI_CONSTANTS is not set
546# CONFIG_SCSI_LOGGING is not set
547# CONFIG_SCSI_SCAN_ASYNC is not set
548CONFIG_SCSI_WAIT_SCAN=m
549
550#
551# SCSI Transports
552#
553CONFIG_SCSI_SPI_ATTRS=y
554# CONFIG_SCSI_FC_ATTRS is not set
555# CONFIG_SCSI_ISCSI_ATTRS is not set
556# CONFIG_SCSI_SAS_LIBSAS is not set
557CONFIG_SCSI_LOWLEVEL=y
558# CONFIG_ISCSI_TCP is not set
559# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
560# CONFIG_SCSI_3W_9XXX is not set
561# CONFIG_SCSI_ACARD is not set
562# CONFIG_SCSI_AACRAID is not set
563# CONFIG_SCSI_AIC7XXX is not set
564# CONFIG_SCSI_AIC7XXX_OLD is not set
565# CONFIG_SCSI_AIC79XX is not set
566# CONFIG_SCSI_AIC94XX is not set
567# CONFIG_SCSI_DPT_I2O is not set
568# CONFIG_SCSI_ARCMSR is not set
569# CONFIG_MEGARAID_NEWGEN is not set
570# CONFIG_MEGARAID_LEGACY is not set
571# CONFIG_MEGARAID_SAS is not set
572# CONFIG_SCSI_HPTIOP is not set
573# CONFIG_SCSI_DMX3191D is not set
574# CONFIG_SCSI_FUTURE_DOMAIN is not set
575# CONFIG_SCSI_IPS is not set
576# CONFIG_SCSI_INITIO is not set
577# CONFIG_SCSI_INIA100 is not set
578# CONFIG_SCSI_STEX is not set
579CONFIG_SCSI_SYM53C8XX_2=y
580CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
581CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
582CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
583CONFIG_SCSI_SYM53C8XX_MMIO=y
584# CONFIG_SCSI_QLOGIC_1280 is not set
585# CONFIG_SCSI_QLA_FC is not set
586# CONFIG_SCSI_QLA_ISCSI is not set
587# CONFIG_SCSI_LPFC is not set
588# CONFIG_SCSI_DC395x is not set
589# CONFIG_SCSI_DC390T is not set
590# CONFIG_SCSI_NSP32 is not set
591# CONFIG_SCSI_DEBUG is not set
592# CONFIG_SCSI_SRP is not set
593# CONFIG_ATA is not set
594CONFIG_MD=y
595# CONFIG_BLK_DEV_MD is not set
596CONFIG_BLK_DEV_DM=m
597# CONFIG_DM_DEBUG is not set
598CONFIG_DM_CRYPT=m
599CONFIG_DM_SNAPSHOT=m
600CONFIG_DM_MIRROR=m
601CONFIG_DM_ZERO=m
602CONFIG_DM_MULTIPATH=m
603CONFIG_DM_MULTIPATH_EMC=m
604# CONFIG_DM_MULTIPATH_RDAC is not set
605# CONFIG_DM_DELAY is not set
606
607#
608# Fusion MPT device support
609#
610# CONFIG_FUSION is not set
611# CONFIG_FUSION_SPI is not set
612# CONFIG_FUSION_FC is not set
613# CONFIG_FUSION_SAS is not set
614
615#
616# IEEE 1394 (FireWire) support
617#
618# CONFIG_FIREWIRE is not set
619# CONFIG_IEEE1394 is not set
620# CONFIG_I2O is not set
621CONFIG_NETDEVICES=y
622# CONFIG_NETDEVICES_MULTIQUEUE is not set
623# CONFIG_DUMMY is not set
624# CONFIG_BONDING is not set
625# CONFIG_MACVLAN is not set
626# CONFIG_EQUALIZER is not set
627CONFIG_TUN=m
628# CONFIG_ARCNET is not set
629# CONFIG_PHYLIB is not set
630CONFIG_NET_ETHERNET=y
631CONFIG_MII=y
632# CONFIG_AX88796 is not set
633# CONFIG_HAPPYMEAL is not set
634# CONFIG_SUNGEM is not set
635# CONFIG_CASSINI is not set
636# CONFIG_NET_VENDOR_3COM is not set
637CONFIG_SMC91X=y
638# CONFIG_DM9000 is not set
639# CONFIG_NET_TULIP is not set
640# CONFIG_HP100 is not set
641# CONFIG_NET_PCI is not set
642CONFIG_NETDEV_1000=y
643# CONFIG_ACENIC is not set
644# CONFIG_DL2K is not set
645# CONFIG_E1000 is not set
646# CONFIG_NS83820 is not set
647# CONFIG_HAMACHI is not set
648# CONFIG_YELLOWFIN is not set
649# CONFIG_R8169 is not set
650# CONFIG_SIS190 is not set
651# CONFIG_SKGE is not set
652# CONFIG_SKY2 is not set
653# CONFIG_SK98LIN is not set
654# CONFIG_VIA_VELOCITY is not set
655# CONFIG_TIGON3 is not set
656# CONFIG_BNX2 is not set
657# CONFIG_QLA3XXX is not set
658# CONFIG_ATL1 is not set
659CONFIG_NETDEV_10000=y
660# CONFIG_CHELSIO_T1 is not set
661# CONFIG_CHELSIO_T3 is not set
662# CONFIG_IXGB is not set
663# CONFIG_S2IO is not set
664# CONFIG_MYRI10GE is not set
665# CONFIG_NETXEN_NIC is not set
666# CONFIG_MLX4_CORE is not set
667# CONFIG_TR is not set
668
669#
670# Wireless LAN
671#
672# CONFIG_WLAN_PRE80211 is not set
673# CONFIG_WLAN_80211 is not set
674
675#
676# USB Network Adapters
677#
678# CONFIG_USB_CATC is not set
679# CONFIG_USB_KAWETH is not set
680# CONFIG_USB_PEGASUS is not set
681# CONFIG_USB_RTL8150 is not set
682# CONFIG_USB_USBNET_MII is not set
683# CONFIG_USB_USBNET is not set
684# CONFIG_WAN is not set
685# CONFIG_FDDI is not set
686# CONFIG_HIPPI is not set
687# CONFIG_PPP is not set
688# CONFIG_SLIP is not set
689# CONFIG_NET_FC is not set
690# CONFIG_SHAPER is not set
691# CONFIG_NETCONSOLE is not set
692# CONFIG_NETPOLL is not set
693# CONFIG_NET_POLL_CONTROLLER is not set
694# CONFIG_ISDN is not set
695
696#
697# Input device support
698#
699CONFIG_INPUT=y
700# CONFIG_INPUT_FF_MEMLESS is not set
701# CONFIG_INPUT_POLLDEV is not set
702
703#
704# Userland interfaces
705#
706# CONFIG_INPUT_MOUSEDEV is not set
707# CONFIG_INPUT_JOYDEV is not set
708# CONFIG_INPUT_TSDEV is not set
709CONFIG_INPUT_EVDEV=y
710# CONFIG_INPUT_EVBUG is not set
711# CONFIG_INPUT_POWER is not set
712
713#
714# Input Device Drivers
715#
716CONFIG_INPUT_KEYBOARD=y
717CONFIG_KEYBOARD_ATKBD=y
718# CONFIG_KEYBOARD_SUNKBD is not set
719# CONFIG_KEYBOARD_LKKBD is not set
720# CONFIG_KEYBOARD_XTKBD is not set
721# CONFIG_KEYBOARD_NEWTON is not set
722# CONFIG_KEYBOARD_STOWAWAY is not set
723# CONFIG_INPUT_MOUSE is not set
724# CONFIG_INPUT_JOYSTICK is not set
725CONFIG_INPUT_TABLET=y
726# CONFIG_TABLET_USB_ACECAD is not set
727# CONFIG_TABLET_USB_AIPTEK is not set
728# CONFIG_TABLET_USB_GTCO is not set
729# CONFIG_TABLET_USB_KBTAB is not set
730CONFIG_TABLET_USB_WACOM=y
731# CONFIG_INPUT_TOUCHSCREEN is not set
732CONFIG_INPUT_MISC=y
733# CONFIG_INPUT_ATI_REMOTE is not set
734# CONFIG_INPUT_ATI_REMOTE2 is not set
735# CONFIG_INPUT_KEYSPAN_REMOTE is not set
736# CONFIG_INPUT_POWERMATE is not set
737# CONFIG_INPUT_YEALINK is not set
738# CONFIG_INPUT_UINPUT is not set
739
740#
741# Hardware I/O ports
742#
743CONFIG_SERIO=y
744# CONFIG_SERIO_SERPORT is not set
745CONFIG_SERIO_AMBAKMI=y
746# CONFIG_SERIO_PCIPS2 is not set
747CONFIG_SERIO_LIBPS2=y
748# CONFIG_SERIO_RAW is not set
749# CONFIG_GAMEPORT is not set
750
751#
752# Character devices
753#
754CONFIG_VT=y
755CONFIG_VT_CONSOLE=y
756CONFIG_HW_CONSOLE=y
757# CONFIG_VT_HW_CONSOLE_BINDING is not set
758# CONFIG_SERIAL_NONSTANDARD is not set
759
760#
761# Serial drivers
762#
763# CONFIG_SERIAL_8250 is not set
764
765#
766# Non-8250 serial port support
767#
768CONFIG_SERIAL_AMBA_PL011=y
769CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
770CONFIG_SERIAL_CORE=y
771CONFIG_SERIAL_CORE_CONSOLE=y
772# CONFIG_SERIAL_JSM is not set
773CONFIG_UNIX98_PTYS=y
774# CONFIG_LEGACY_PTYS is not set
775# CONFIG_IPMI_HANDLER is not set
776# CONFIG_WATCHDOG is not set
777CONFIG_HW_RANDOM=m
778# CONFIG_NVRAM is not set
779# CONFIG_R3964 is not set
780# CONFIG_APPLICOM is not set
781# CONFIG_DRM is not set
782# CONFIG_RAW_DRIVER is not set
783# CONFIG_TCG_TPM is not set
784CONFIG_DEVPORT=y
785# CONFIG_I2C is not set
786
787#
788# SPI support
789#
790# CONFIG_SPI is not set
791# CONFIG_SPI_MASTER is not set
792# CONFIG_W1 is not set
793# CONFIG_POWER_SUPPLY is not set
794CONFIG_HWMON=y
795# CONFIG_HWMON_VID is not set
796# CONFIG_SENSORS_ABITUGURU is not set
797# CONFIG_SENSORS_ABITUGURU3 is not set
798# CONFIG_SENSORS_F71805F is not set
799# CONFIG_SENSORS_IT87 is not set
800# CONFIG_SENSORS_PC87360 is not set
801# CONFIG_SENSORS_PC87427 is not set
802# CONFIG_SENSORS_SIS5595 is not set
803# CONFIG_SENSORS_SMSC47M1 is not set
804# CONFIG_SENSORS_SMSC47B397 is not set
805# CONFIG_SENSORS_VIA686A is not set
806# CONFIG_SENSORS_VT1211 is not set
807# CONFIG_SENSORS_VT8231 is not set
808# CONFIG_SENSORS_W83627HF is not set
809# CONFIG_SENSORS_W83627EHF is not set
810# CONFIG_HWMON_DEBUG_CHIP is not set
811CONFIG_MISC_DEVICES=y
812# CONFIG_PHANTOM is not set
813# CONFIG_EEPROM_93CX6 is not set
814# CONFIG_SGI_IOC4 is not set
815# CONFIG_TIFM_CORE is not set
816
817#
818# Multifunction device drivers
819#
820# CONFIG_MFD_SM501 is not set
821# CONFIG_HTC_ASIC3 is not set
822# CONFIG_HTC_ASIC3_DS1WM is not set
823
824#
825# Multi-Function Devices
826#
827CONFIG_NEW_LEDS=y
828# CONFIG_LEDS_CLASS is not set
829
830#
831# LED drivers
832#
833
834#
835# LED Triggers
836#
837# CONFIG_LEDS_TRIGGERS is not set
838
839#
840# Multimedia devices
841#
842CONFIG_VIDEO_DEV=m
843CONFIG_VIDEO_V4L1=y
844CONFIG_VIDEO_V4L1_COMPAT=y
845CONFIG_VIDEO_V4L2=y
846CONFIG_VIDEO_CAPTURE_DRIVERS=y
847# CONFIG_VIDEO_ADV_DEBUG is not set
848CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
849# CONFIG_VIDEO_VIVI is not set
850# CONFIG_VIDEO_CPIA is not set
851# CONFIG_VIDEO_CPIA2 is not set
852# CONFIG_VIDEO_STRADIS is not set
853CONFIG_V4L_USB_DRIVERS=y
854# CONFIG_USB_VICAM is not set
855# CONFIG_USB_IBMCAM is not set
856# CONFIG_USB_KONICAWC is not set
857# CONFIG_USB_QUICKCAM_MESSENGER is not set
858# CONFIG_USB_ET61X251 is not set
859# CONFIG_USB_OV511 is not set
860# CONFIG_USB_SE401 is not set
861# CONFIG_USB_SN9C102 is not set
862# CONFIG_USB_STV680 is not set
863# CONFIG_USB_ZC0301 is not set
864# CONFIG_USB_PWC is not set
865# CONFIG_USB_ZR364XX is not set
866CONFIG_RADIO_ADAPTERS=y
867# CONFIG_RADIO_GEMTEK_PCI is not set
868# CONFIG_RADIO_MAXIRADIO is not set
869# CONFIG_RADIO_MAESTRO is not set
870# CONFIG_USB_DSBR is not set
871# CONFIG_DVB_CORE is not set
872CONFIG_DAB=y
873# CONFIG_USB_DABUSB is not set
874
875#
876# Graphics support
877#
878# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
879
880#
881# Display device support
882#
883# CONFIG_DISPLAY_SUPPORT is not set
884# CONFIG_VGASTATE is not set
885CONFIG_VIDEO_OUTPUT_CONTROL=m
886CONFIG_FB=y
887# CONFIG_FIRMWARE_EDID is not set
888# CONFIG_FB_DDC is not set
889CONFIG_FB_CFB_FILLRECT=y
890CONFIG_FB_CFB_COPYAREA=y
891CONFIG_FB_CFB_IMAGEBLIT=y
892# CONFIG_FB_SYS_FILLRECT is not set
893# CONFIG_FB_SYS_COPYAREA is not set
894# CONFIG_FB_SYS_IMAGEBLIT is not set
895# CONFIG_FB_SYS_FOPS is not set
896CONFIG_FB_DEFERRED_IO=y
897# CONFIG_FB_SVGALIB is not set
898# CONFIG_FB_MACMODES is not set
899# CONFIG_FB_BACKLIGHT is not set
900CONFIG_FB_MODE_HELPERS=y
901CONFIG_FB_TILEBLITTING=y
902
903#
904# Frame buffer hardware drivers
905#
906# CONFIG_FB_CIRRUS is not set
907# CONFIG_FB_PM2 is not set
908CONFIG_FB_ARMCLCD=y
909# CONFIG_FB_CYBER2000 is not set
910# CONFIG_FB_ASILIANT is not set
911# CONFIG_FB_IMSTT is not set
912# CONFIG_FB_S1D13XXX is not set
913# CONFIG_FB_NVIDIA is not set
914# CONFIG_FB_RIVA is not set
915# CONFIG_FB_MATROX is not set
916# CONFIG_FB_RADEON is not set
917# CONFIG_FB_ATY128 is not set
918# CONFIG_FB_ATY is not set
919# CONFIG_FB_S3 is not set
920# CONFIG_FB_SAVAGE is not set
921# CONFIG_FB_SIS is not set
922# CONFIG_FB_NEOMAGIC is not set
923# CONFIG_FB_KYRO is not set
924# CONFIG_FB_3DFX is not set
925# CONFIG_FB_VOODOO1 is not set
926# CONFIG_FB_VT8623 is not set
927# CONFIG_FB_TRIDENT is not set
928# CONFIG_FB_ARK is not set
929# CONFIG_FB_PM3 is not set
930# CONFIG_FB_VIRTUAL is not set
931
932#
933# Console display driver support
934#
935CONFIG_DUMMY_CONSOLE=y
936CONFIG_FRAMEBUFFER_CONSOLE=y
937# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
938# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
939# CONFIG_FONTS is not set
940CONFIG_FONT_8x8=y
941CONFIG_FONT_8x16=y
942CONFIG_LOGO=y
943CONFIG_LOGO_LINUX_MONO=y
944CONFIG_LOGO_LINUX_VGA16=y
945# CONFIG_LOGO_LINUX_CLUT224 is not set
946CONFIG_LOGO_OHAND_CLUT224=y
947# CONFIG_LOGO_OZ240_CLUT224 is not set
948# CONFIG_LOGO_OZ480_CLUT224 is not set
949# CONFIG_LOGO_OZ640_CLUT224 is not set
950
951#
952# Sound
953#
954# CONFIG_SOUND is not set
955CONFIG_HID_SUPPORT=y
956CONFIG_HID=m
957# CONFIG_HID_DEBUG is not set
958
959#
960# USB Input Devices
961#
962CONFIG_USB_HID=y
963# CONFIG_USB_HIDINPUT_POWERBOOK is not set
964# CONFIG_HID_FF is not set
965# CONFIG_USB_HIDDEV is not set
966CONFIG_USB_SUPPORT=y
967CONFIG_USB_ARCH_HAS_HCD=y
968CONFIG_USB_ARCH_HAS_OHCI=y
969CONFIG_USB_ARCH_HAS_EHCI=y
970CONFIG_USB=y
971# CONFIG_USB_DEBUG is not set
972
973#
974# Miscellaneous USB options
975#
976# CONFIG_USB_DEVICEFS is not set
977CONFIG_USB_DEVICE_CLASS=y
978# CONFIG_USB_DYNAMIC_MINORS is not set
979# CONFIG_USB_SUSPEND is not set
980# CONFIG_USB_PERSIST is not set
981# CONFIG_USB_OTG is not set
982
983#
984# USB Host Controller Drivers
985#
986# CONFIG_USB_EHCI_HCD is not set
987# CONFIG_USB_ISP116X_HCD is not set
988CONFIG_USB_OHCI_HCD=y
989# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
990# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
991CONFIG_USB_OHCI_LITTLE_ENDIAN=y
992# CONFIG_USB_UHCI_HCD is not set
993# CONFIG_USB_SL811_HCD is not set
994# CONFIG_USB_R8A66597_HCD is not set
995
996#
997# USB Device Class drivers
998#
999# CONFIG_USB_ACM is not set
1000# CONFIG_USB_PRINTER is not set
1001
1002#
1003# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1004#
1005
1006#
1007# may also be needed; see USB_STORAGE Help for more information
1008#
1009# CONFIG_USB_STORAGE is not set
1010# CONFIG_USB_LIBUSUAL is not set
1011
1012#
1013# USB Imaging devices
1014#
1015# CONFIG_USB_MDC800 is not set
1016# CONFIG_USB_MICROTEK is not set
1017CONFIG_USB_MON=y
1018
1019#
1020# USB port drivers
1021#
1022
1023#
1024# USB Serial Converter support
1025#
1026# CONFIG_USB_SERIAL is not set
1027
1028#
1029# USB Miscellaneous drivers
1030#
1031# CONFIG_USB_EMI62 is not set
1032# CONFIG_USB_EMI26 is not set
1033# CONFIG_USB_ADUTUX is not set
1034# CONFIG_USB_AUERSWALD is not set
1035# CONFIG_USB_RIO500 is not set
1036# CONFIG_USB_LEGOTOWER is not set
1037# CONFIG_USB_LCD is not set
1038# CONFIG_USB_BERRY_CHARGE is not set
1039# CONFIG_USB_LED is not set
1040# CONFIG_USB_CYPRESS_CY7C63 is not set
1041# CONFIG_USB_CYTHERM is not set
1042# CONFIG_USB_PHIDGET is not set
1043# CONFIG_USB_IDMOUSE is not set
1044# CONFIG_USB_FTDI_ELAN is not set
1045# CONFIG_USB_APPLEDISPLAY is not set
1046# CONFIG_USB_LD is not set
1047# CONFIG_USB_TRANCEVIBRATOR is not set
1048# CONFIG_USB_IOWARRIOR is not set
1049
1050#
1051# USB DSL modem support
1052#
1053
1054#
1055# USB Gadget Support
1056#
1057# CONFIG_USB_GADGET is not set
1058# CONFIG_MMC is not set
1059CONFIG_RTC_LIB=y
1060CONFIG_RTC_CLASS=y
1061CONFIG_RTC_HCTOSYS=y
1062CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1063# CONFIG_RTC_DEBUG is not set
1064
1065#
1066# RTC interfaces
1067#
1068CONFIG_RTC_INTF_SYSFS=y
1069CONFIG_RTC_INTF_PROC=y
1070CONFIG_RTC_INTF_DEV=y
1071# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1072# CONFIG_RTC_DRV_TEST is not set
1073
1074#
1075# SPI RTC drivers
1076#
1077
1078#
1079# Platform RTC drivers
1080#
1081# CONFIG_RTC_DRV_CMOS is not set
1082# CONFIG_RTC_DRV_DS1553 is not set
1083# CONFIG_RTC_DRV_STK17TA8 is not set
1084# CONFIG_RTC_DRV_DS1742 is not set
1085# CONFIG_RTC_DRV_M48T86 is not set
1086# CONFIG_RTC_DRV_M48T59 is not set
1087# CONFIG_RTC_DRV_V3020 is not set
1088
1089#
1090# on-CPU RTC drivers
1091#
1092# CONFIG_RTC_DRV_PL031 is not set
1093
1094#
1095# DMA Engine support
1096#
1097# CONFIG_DMA_ENGINE is not set
1098
1099#
1100# DMA Clients
1101#
1102
1103#
1104# DMA Devices
1105#
1106
1107#
1108# File systems
1109#
1110CONFIG_EXT2_FS=y
1111# CONFIG_EXT2_FS_XATTR is not set
1112# CONFIG_EXT2_FS_XIP is not set
1113CONFIG_EXT3_FS=m
1114CONFIG_EXT3_FS_XATTR=y
1115# CONFIG_EXT3_FS_POSIX_ACL is not set
1116# CONFIG_EXT3_FS_SECURITY is not set
1117# CONFIG_EXT4DEV_FS is not set
1118CONFIG_JBD=m
1119# CONFIG_JBD_DEBUG is not set
1120CONFIG_FS_MBCACHE=y
1121# CONFIG_REISERFS_FS is not set
1122# CONFIG_JFS_FS is not set
1123# CONFIG_FS_POSIX_ACL is not set
1124# CONFIG_XFS_FS is not set
1125# CONFIG_GFS2_FS is not set
1126# CONFIG_OCFS2_FS is not set
1127# CONFIG_MINIX_FS is not set
1128# CONFIG_ROMFS_FS is not set
1129CONFIG_INOTIFY=y
1130CONFIG_INOTIFY_USER=y
1131# CONFIG_QUOTA is not set
1132CONFIG_DNOTIFY=y
1133# CONFIG_AUTOFS_FS is not set
1134# CONFIG_AUTOFS4_FS is not set
1135# CONFIG_FUSE_FS is not set
1136
1137#
1138# CD-ROM/DVD Filesystems
1139#
1140# CONFIG_ISO9660_FS is not set
1141# CONFIG_UDF_FS is not set
1142
1143#
1144# DOS/FAT/NT Filesystems
1145#
1146# CONFIG_MSDOS_FS is not set
1147# CONFIG_VFAT_FS is not set
1148# CONFIG_NTFS_FS is not set
1149
1150#
1151# Pseudo filesystems
1152#
1153CONFIG_PROC_FS=y
1154CONFIG_PROC_SYSCTL=y
1155CONFIG_SYSFS=y
1156CONFIG_TMPFS=y
1157# CONFIG_TMPFS_POSIX_ACL is not set
1158# CONFIG_HUGETLB_PAGE is not set
1159CONFIG_RAMFS=y
1160# CONFIG_CONFIGFS_FS is not set
1161
1162#
1163# Miscellaneous filesystems
1164#
1165# CONFIG_ADFS_FS is not set
1166# CONFIG_AFFS_FS is not set
1167# CONFIG_HFS_FS is not set
1168# CONFIG_HFSPLUS_FS is not set
1169# CONFIG_BEFS_FS is not set
1170# CONFIG_BFS_FS is not set
1171# CONFIG_EFS_FS is not set
1172CONFIG_JFFS2_FS=y
1173CONFIG_JFFS2_FS_DEBUG=0
1174CONFIG_JFFS2_FS_WRITEBUFFER=y
1175# CONFIG_JFFS2_SUMMARY is not set
1176# CONFIG_JFFS2_FS_XATTR is not set
1177# CONFIG_JFFS2_SYSFS is not set
1178# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1179CONFIG_JFFS2_ZLIB=y
1180CONFIG_JFFS2_LZO=y
1181CONFIG_JFFS2_RTIME=y
1182# CONFIG_JFFS2_RUBIN is not set
1183CONFIG_CRAMFS=y
1184# CONFIG_SQUASHFS is not set
1185# CONFIG_VXFS_FS is not set
1186# CONFIG_HPFS_FS is not set
1187# CONFIG_QNX4FS_FS is not set
1188# CONFIG_SYSV_FS is not set
1189# CONFIG_UFS_FS is not set
1190
1191#
1192# Network File Systems
1193#
1194CONFIG_NFS_FS=y
1195CONFIG_NFS_V3=y
1196# CONFIG_NFS_V3_ACL is not set
1197# CONFIG_NFS_V4 is not set
1198# CONFIG_NFS_DIRECTIO is not set
1199CONFIG_NFSD=y
1200CONFIG_NFSD_V3=y
1201# CONFIG_NFSD_V3_ACL is not set
1202# CONFIG_NFSD_V4 is not set
1203# CONFIG_NFSD_TCP is not set
1204CONFIG_ROOT_NFS=y
1205CONFIG_LOCKD=y
1206CONFIG_LOCKD_V4=y
1207CONFIG_EXPORTFS=y
1208CONFIG_NFS_COMMON=y
1209CONFIG_SUNRPC=y
1210# CONFIG_SUNRPC_BIND34 is not set
1211# CONFIG_RPCSEC_GSS_KRB5 is not set
1212# CONFIG_RPCSEC_GSS_SPKM3 is not set
1213CONFIG_SMB_FS=y
1214# CONFIG_SMB_NLS_DEFAULT is not set
1215# CONFIG_CIFS is not set
1216# CONFIG_NCP_FS is not set
1217# CONFIG_CODA_FS is not set
1218# CONFIG_AFS_FS is not set
1219
1220#
1221# Partition Types
1222#
1223CONFIG_PARTITION_ADVANCED=y
1224# CONFIG_ACORN_PARTITION is not set
1225# CONFIG_OSF_PARTITION is not set
1226# CONFIG_AMIGA_PARTITION is not set
1227# CONFIG_ATARI_PARTITION is not set
1228# CONFIG_MAC_PARTITION is not set
1229CONFIG_MSDOS_PARTITION=y
1230# CONFIG_BSD_DISKLABEL is not set
1231# CONFIG_MINIX_SUBPARTITION is not set
1232# CONFIG_SOLARIS_X86_PARTITION is not set
1233# CONFIG_UNIXWARE_DISKLABEL is not set
1234# CONFIG_LDM_PARTITION is not set
1235# CONFIG_SGI_PARTITION is not set
1236# CONFIG_ULTRIX_PARTITION is not set
1237# CONFIG_SUN_PARTITION is not set
1238# CONFIG_KARMA_PARTITION is not set
1239# CONFIG_EFI_PARTITION is not set
1240# CONFIG_SYSV68_PARTITION is not set
1241
1242#
1243# Native Language Support
1244#
1245CONFIG_NLS=y
1246CONFIG_NLS_DEFAULT="iso8859-1"
1247# CONFIG_NLS_CODEPAGE_437 is not set
1248# CONFIG_NLS_CODEPAGE_737 is not set
1249# CONFIG_NLS_CODEPAGE_775 is not set
1250# CONFIG_NLS_CODEPAGE_850 is not set
1251# CONFIG_NLS_CODEPAGE_852 is not set
1252# CONFIG_NLS_CODEPAGE_855 is not set
1253# CONFIG_NLS_CODEPAGE_857 is not set
1254# CONFIG_NLS_CODEPAGE_860 is not set
1255# CONFIG_NLS_CODEPAGE_861 is not set
1256# CONFIG_NLS_CODEPAGE_862 is not set
1257# CONFIG_NLS_CODEPAGE_863 is not set
1258# CONFIG_NLS_CODEPAGE_864 is not set
1259# CONFIG_NLS_CODEPAGE_865 is not set
1260# CONFIG_NLS_CODEPAGE_866 is not set
1261# CONFIG_NLS_CODEPAGE_869 is not set
1262# CONFIG_NLS_CODEPAGE_936 is not set
1263# CONFIG_NLS_CODEPAGE_950 is not set
1264# CONFIG_NLS_CODEPAGE_932 is not set
1265# CONFIG_NLS_CODEPAGE_949 is not set
1266# CONFIG_NLS_CODEPAGE_874 is not set
1267# CONFIG_NLS_ISO8859_8 is not set
1268# CONFIG_NLS_CODEPAGE_1250 is not set
1269# CONFIG_NLS_CODEPAGE_1251 is not set
1270# CONFIG_NLS_ASCII is not set
1271# CONFIG_NLS_ISO8859_1 is not set
1272# CONFIG_NLS_ISO8859_2 is not set
1273# CONFIG_NLS_ISO8859_3 is not set
1274# CONFIG_NLS_ISO8859_4 is not set
1275# CONFIG_NLS_ISO8859_5 is not set
1276# CONFIG_NLS_ISO8859_6 is not set
1277# CONFIG_NLS_ISO8859_7 is not set
1278# CONFIG_NLS_ISO8859_9 is not set
1279# CONFIG_NLS_ISO8859_13 is not set
1280# CONFIG_NLS_ISO8859_14 is not set
1281# CONFIG_NLS_ISO8859_15 is not set
1282# CONFIG_NLS_KOI8_R is not set
1283# CONFIG_NLS_KOI8_U is not set
1284# CONFIG_NLS_UTF8 is not set
1285
1286#
1287# Distributed Lock Manager
1288#
1289# CONFIG_DLM is not set
1290
1291#
1292# Profiling support
1293#
1294CONFIG_PROFILING=y
1295CONFIG_OPROFILE=m
1296
1297#
1298# Kernel hacking
1299#
1300# CONFIG_PRINTK_TIME is not set
1301CONFIG_ENABLE_MUST_CHECK=y
1302CONFIG_MAGIC_SYSRQ=y
1303# CONFIG_UNUSED_SYMBOLS is not set
1304# CONFIG_DEBUG_FS is not set
1305# CONFIG_HEADERS_CHECK is not set
1306CONFIG_DEBUG_KERNEL=y
1307# CONFIG_DEBUG_SHIRQ is not set
1308CONFIG_DETECT_SOFTLOCKUP=y
1309CONFIG_SCHED_DEBUG=y
1310# CONFIG_SCHEDSTATS is not set
1311CONFIG_TIMER_STATS=y
1312# CONFIG_DEBUG_SLAB is not set
1313# CONFIG_DEBUG_RT_MUTEXES is not set
1314# CONFIG_RT_MUTEX_TESTER is not set
1315# CONFIG_DEBUG_SPINLOCK is not set
1316# CONFIG_DEBUG_MUTEXES is not set
1317# CONFIG_DEBUG_LOCK_ALLOC is not set
1318# CONFIG_PROVE_LOCKING is not set
1319# CONFIG_LOCK_STAT is not set
1320# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1321# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1322# CONFIG_DEBUG_KOBJECT is not set
1323CONFIG_DEBUG_BUGVERBOSE=y
1324CONFIG_DEBUG_INFO=y
1325# CONFIG_DEBUG_VM is not set
1326# CONFIG_DEBUG_LIST is not set
1327CONFIG_FRAME_POINTER=y
1328CONFIG_FORCED_INLINING=y
1329# CONFIG_RCU_TORTURE_TEST is not set
1330# CONFIG_FAULT_INJECTION is not set
1331# CONFIG_DEBUG_USER is not set
1332CONFIG_DEBUG_ERRORS=y
1333# CONFIG_DEBUG_LL is not set
1334
1335#
1336# Security options
1337#
1338# CONFIG_KEYS is not set
1339# CONFIG_SECURITY is not set
1340CONFIG_CRYPTO=y
1341CONFIG_CRYPTO_ALGAPI=m
1342CONFIG_CRYPTO_BLKCIPHER=m
1343CONFIG_CRYPTO_MANAGER=m
1344# CONFIG_CRYPTO_HMAC is not set
1345# CONFIG_CRYPTO_XCBC is not set
1346# CONFIG_CRYPTO_NULL is not set
1347# CONFIG_CRYPTO_MD4 is not set
1348# CONFIG_CRYPTO_MD5 is not set
1349# CONFIG_CRYPTO_SHA1 is not set
1350# CONFIG_CRYPTO_SHA256 is not set
1351# CONFIG_CRYPTO_SHA512 is not set
1352# CONFIG_CRYPTO_WP512 is not set
1353# CONFIG_CRYPTO_TGR192 is not set
1354# CONFIG_CRYPTO_GF128MUL is not set
1355CONFIG_CRYPTO_ECB=m
1356CONFIG_CRYPTO_CBC=m
1357CONFIG_CRYPTO_PCBC=m
1358# CONFIG_CRYPTO_LRW is not set
1359# CONFIG_CRYPTO_CRYPTD is not set
1360# CONFIG_CRYPTO_DES is not set
1361# CONFIG_CRYPTO_FCRYPT is not set
1362# CONFIG_CRYPTO_BLOWFISH is not set
1363# CONFIG_CRYPTO_TWOFISH is not set
1364# CONFIG_CRYPTO_SERPENT is not set
1365# CONFIG_CRYPTO_AES is not set
1366# CONFIG_CRYPTO_CAST5 is not set
1367# CONFIG_CRYPTO_CAST6 is not set
1368# CONFIG_CRYPTO_TEA is not set
1369# CONFIG_CRYPTO_ARC4 is not set
1370# CONFIG_CRYPTO_KHAZAD is not set
1371# CONFIG_CRYPTO_ANUBIS is not set
1372# CONFIG_CRYPTO_DEFLATE is not set
1373# CONFIG_CRYPTO_LZO is not set
1374# CONFIG_CRYPTO_MICHAEL_MIC is not set
1375# CONFIG_CRYPTO_CRC32C is not set
1376# CONFIG_CRYPTO_CAMELLIA is not set
1377# CONFIG_CRYPTO_TEST is not set
1378CONFIG_CRYPTO_HW=y
1379
1380#
1381# Library routines
1382#
1383CONFIG_BITREVERSE=y
1384# CONFIG_CRC_CCITT is not set
1385# CONFIG_CRC16 is not set
1386# CONFIG_CRC_ITU_T is not set
1387CONFIG_CRC32=y
1388# CONFIG_CRC7 is not set
1389# CONFIG_LIBCRC32C is not set
1390CONFIG_ZLIB_INFLATE=y
1391CONFIG_ZLIB_DEFLATE=y
1392CONFIG_LZO_COMPRESS=y
1393CONFIG_LZO_DECOMPRESS=y
1394CONFIG_PLIST=y
1395CONFIG_HAS_IOMEM=y
1396CONFIG_HAS_IOPORT=y
1397CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemux86 b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemux86
new file mode 100644
index 0000000000..62bbaceaf9
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-qemux86
@@ -0,0 +1,1756 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Thu Jan 10 23:22:30 2008
5#
6CONFIG_X86_32=y
7CONFIG_GENERIC_TIME=y
8CONFIG_GENERIC_CMOS_UPDATE=y
9CONFIG_CLOCKSOURCE_WATCHDOG=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
12CONFIG_LOCKDEP_SUPPORT=y
13CONFIG_STACKTRACE_SUPPORT=y
14CONFIG_SEMAPHORE_SLEEPERS=y
15CONFIG_X86=y
16CONFIG_MMU=y
17CONFIG_ZONE_DMA=y
18CONFIG_QUICKLIST=y
19CONFIG_GENERIC_ISA_DMA=y
20CONFIG_GENERIC_IOMAP=y
21CONFIG_GENERIC_BUG=y
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_ARCH_MAY_HAVE_PC_FDC=y
24CONFIG_DMI=y
25CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
26
27#
28# General setup
29#
30CONFIG_EXPERIMENTAL=y
31CONFIG_LOCK_KERNEL=y
32CONFIG_INIT_ENV_ARG_LIMIT=32
33CONFIG_LOCALVERSION=""
34# CONFIG_LOCALVERSION_AUTO is not set
35CONFIG_SWAP=y
36CONFIG_SYSVIPC=y
37CONFIG_SYSVIPC_SYSCTL=y
38CONFIG_POSIX_MQUEUE=y
39# CONFIG_BSD_PROCESS_ACCT is not set
40# CONFIG_TASKSTATS is not set
41# CONFIG_USER_NS is not set
42CONFIG_AUDIT=y
43CONFIG_AUDITSYSCALL=y
44# CONFIG_IKCONFIG is not set
45CONFIG_LOG_BUF_SHIFT=15
46# CONFIG_CPUSETS is not set
47CONFIG_SYSFS_DEPRECATED=y
48# CONFIG_RELAY is not set
49CONFIG_BLK_DEV_INITRD=y
50CONFIG_INITRAMFS_SOURCE=""
51# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
52CONFIG_SYSCTL=y
53CONFIG_EMBEDDED=y
54CONFIG_UID16=y
55CONFIG_SYSCTL_SYSCALL=y
56CONFIG_KALLSYMS=y
57# CONFIG_KALLSYMS_EXTRA_PASS is not set
58CONFIG_HOTPLUG=y
59CONFIG_PRINTK=y
60CONFIG_BUG=y
61CONFIG_ELF_CORE=y
62CONFIG_BASE_FULL=y
63CONFIG_FUTEX=y
64CONFIG_ANON_INODES=y
65CONFIG_EPOLL=y
66CONFIG_SIGNALFD=y
67CONFIG_EVENTFD=y
68CONFIG_SHMEM=y
69CONFIG_VM_EVENT_COUNTERS=y
70CONFIG_SLAB=y
71# CONFIG_SLUB is not set
72# CONFIG_SLOB is not set
73CONFIG_RT_MUTEXES=y
74# CONFIG_TINY_SHMEM is not set
75CONFIG_BASE_SMALL=0
76CONFIG_MODULES=y
77# CONFIG_MODULE_UNLOAD is not set
78# CONFIG_MODVERSIONS is not set
79# CONFIG_MODULE_SRCVERSION_ALL is not set
80CONFIG_KMOD=y
81CONFIG_STOP_MACHINE=y
82CONFIG_BLOCK=y
83CONFIG_LBD=y
84# CONFIG_BLK_DEV_IO_TRACE is not set
85# CONFIG_LSF is not set
86# CONFIG_BLK_DEV_BSG is not set
87
88#
89# IO Schedulers
90#
91CONFIG_IOSCHED_NOOP=y
92CONFIG_IOSCHED_AS=y
93CONFIG_IOSCHED_DEADLINE=y
94CONFIG_IOSCHED_CFQ=y
95CONFIG_DEFAULT_AS=y
96# CONFIG_DEFAULT_DEADLINE is not set
97# CONFIG_DEFAULT_CFQ is not set
98# CONFIG_DEFAULT_NOOP is not set
99CONFIG_DEFAULT_IOSCHED="anticipatory"
100
101#
102# Processor type and features
103#
104# CONFIG_TICK_ONESHOT is not set
105# CONFIG_NO_HZ is not set
106# CONFIG_HIGH_RES_TIMERS is not set
107CONFIG_SMP=y
108CONFIG_X86_PC=y
109# CONFIG_X86_ELAN is not set
110# CONFIG_X86_VOYAGER is not set
111# CONFIG_X86_NUMAQ is not set
112# CONFIG_X86_SUMMIT is not set
113# CONFIG_X86_BIGSMP is not set
114# CONFIG_X86_VISWS is not set
115# CONFIG_X86_GENERICARCH is not set
116# CONFIG_X86_ES7000 is not set
117# CONFIG_PARAVIRT is not set
118CONFIG_M386=y
119# CONFIG_M486 is not set
120# CONFIG_M586 is not set
121# CONFIG_M586TSC is not set
122# CONFIG_M586MMX is not set
123# CONFIG_M686 is not set
124# CONFIG_MPENTIUMII is not set
125# CONFIG_MPENTIUMIII is not set
126# CONFIG_MPENTIUMM is not set
127# CONFIG_MCORE2 is not set
128# CONFIG_MPENTIUM4 is not set
129# CONFIG_MK6 is not set
130# CONFIG_MK7 is not set
131# CONFIG_MK8 is not set
132# CONFIG_MCRUSOE is not set
133# CONFIG_MEFFICEON is not set
134# CONFIG_MWINCHIPC6 is not set
135# CONFIG_MWINCHIP2 is not set
136# CONFIG_MWINCHIP3D is not set
137# CONFIG_MGEODEGX1 is not set
138# CONFIG_MGEODE_LX is not set
139# CONFIG_MCYRIXIII is not set
140# CONFIG_MVIAC3_2 is not set
141# CONFIG_MVIAC7 is not set
142CONFIG_X86_GENERIC=y
143CONFIG_X86_L1_CACHE_SHIFT=7
144CONFIG_RWSEM_GENERIC_SPINLOCK=y
145# CONFIG_ARCH_HAS_ILOG2_U32 is not set
146# CONFIG_ARCH_HAS_ILOG2_U64 is not set
147CONFIG_GENERIC_CALIBRATE_DELAY=y
148CONFIG_X86_PPRO_FENCE=y
149CONFIG_X86_F00F_BUG=y
150CONFIG_X86_INTEL_USERCOPY=y
151CONFIG_X86_MINIMUM_CPU_FAMILY=3
152# CONFIG_HPET_TIMER is not set
153CONFIG_NR_CPUS=8
154CONFIG_SCHED_SMT=y
155CONFIG_SCHED_MC=y
156CONFIG_PREEMPT_NONE=y
157# CONFIG_PREEMPT_VOLUNTARY is not set
158# CONFIG_PREEMPT is not set
159CONFIG_PREEMPT_BKL=y
160CONFIG_X86_LOCAL_APIC=y
161CONFIG_X86_IO_APIC=y
162CONFIG_X86_MCE=y
163CONFIG_X86_MCE_NONFATAL=y
164CONFIG_X86_MCE_P4THERMAL=y
165CONFIG_VM86=y
166# CONFIG_TOSHIBA is not set
167# CONFIG_I8K is not set
168# CONFIG_X86_REBOOTFIXUPS is not set
169# CONFIG_MICROCODE is not set
170# CONFIG_X86_MSR is not set
171# CONFIG_X86_CPUID is not set
172
173#
174# Firmware Drivers
175#
176# CONFIG_EDD is not set
177# CONFIG_DELL_RBU is not set
178# CONFIG_DCDBAS is not set
179CONFIG_DMIID=y
180CONFIG_NOHIGHMEM=y
181# CONFIG_HIGHMEM4G is not set
182# CONFIG_HIGHMEM64G is not set
183CONFIG_VMSPLIT_3G=y
184# CONFIG_VMSPLIT_3G_OPT is not set
185# CONFIG_VMSPLIT_2G is not set
186# CONFIG_VMSPLIT_2G_OPT is not set
187# CONFIG_VMSPLIT_1G is not set
188CONFIG_PAGE_OFFSET=0xC0000000
189# CONFIG_X86_PAE is not set
190CONFIG_ARCH_FLATMEM_ENABLE=y
191CONFIG_ARCH_SPARSEMEM_ENABLE=y
192CONFIG_ARCH_SELECT_MEMORY_MODEL=y
193CONFIG_ARCH_POPULATES_NODE_MAP=y
194CONFIG_SELECT_MEMORY_MODEL=y
195CONFIG_FLATMEM_MANUAL=y
196# CONFIG_DISCONTIGMEM_MANUAL is not set
197# CONFIG_SPARSEMEM_MANUAL is not set
198CONFIG_FLATMEM=y
199CONFIG_FLAT_NODE_MEM_MAP=y
200CONFIG_SPARSEMEM_STATIC=y
201CONFIG_SPLIT_PTLOCK_CPUS=4
202# CONFIG_RESOURCES_64BIT is not set
203CONFIG_ZONE_DMA_FLAG=1
204CONFIG_BOUNCE=y
205CONFIG_NR_QUICK=1
206CONFIG_VIRT_TO_BUS=y
207# CONFIG_MATH_EMULATION is not set
208CONFIG_MTRR=y
209# CONFIG_EFI is not set
210CONFIG_IRQBALANCE=y
211CONFIG_SECCOMP=y
212# CONFIG_HZ_100 is not set
213CONFIG_HZ_250=y
214# CONFIG_HZ_300 is not set
215# CONFIG_HZ_1000 is not set
216CONFIG_HZ=250
217CONFIG_KEXEC=y
218CONFIG_PHYSICAL_START=0x100000
219# CONFIG_RELOCATABLE is not set
220CONFIG_PHYSICAL_ALIGN=0x100000
221CONFIG_HOTPLUG_CPU=y
222CONFIG_COMPAT_VDSO=y
223
224#
225# Power management options (ACPI, APM)
226#
227CONFIG_PM=y
228CONFIG_PM_LEGACY=y
229# CONFIG_PM_DEBUG is not set
230CONFIG_PM_SLEEP_SMP=y
231CONFIG_PM_SLEEP=y
232CONFIG_SUSPEND_SMP_POSSIBLE=y
233CONFIG_SUSPEND=y
234CONFIG_HIBERNATION_SMP_POSSIBLE=y
235# CONFIG_HIBERNATION is not set
236CONFIG_ACPI=y
237CONFIG_ACPI_SLEEP=y
238# CONFIG_ACPI_PROCFS is not set
239CONFIG_ACPI_PROC_EVENT=y
240CONFIG_ACPI_AC=y
241CONFIG_ACPI_BATTERY=y
242CONFIG_ACPI_BUTTON=y
243CONFIG_ACPI_FAN=y
244# CONFIG_ACPI_DOCK is not set
245CONFIG_ACPI_PROCESSOR=y
246CONFIG_ACPI_HOTPLUG_CPU=y
247CONFIG_ACPI_THERMAL=y
248# CONFIG_ACPI_ASUS is not set
249# CONFIG_ACPI_TOSHIBA is not set
250CONFIG_ACPI_BLACKLIST_YEAR=0
251# CONFIG_ACPI_DEBUG is not set
252CONFIG_ACPI_EC=y
253CONFIG_ACPI_POWER=y
254CONFIG_ACPI_SYSTEM=y
255CONFIG_X86_PM_TIMER=y
256CONFIG_ACPI_CONTAINER=y
257# CONFIG_ACPI_SBS is not set
258# CONFIG_APM is not set
259
260#
261# CPU Frequency scaling
262#
263# CONFIG_CPU_FREQ is not set
264
265#
266# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
267#
268CONFIG_PCI=y
269# CONFIG_PCI_GOBIOS is not set
270# CONFIG_PCI_GOMMCONFIG is not set
271# CONFIG_PCI_GODIRECT is not set
272CONFIG_PCI_GOANY=y
273CONFIG_PCI_BIOS=y
274CONFIG_PCI_DIRECT=y
275CONFIG_PCI_MMCONFIG=y
276# CONFIG_PCIEPORTBUS is not set
277CONFIG_ARCH_SUPPORTS_MSI=y
278# CONFIG_PCI_MSI is not set
279CONFIG_HT_IRQ=y
280CONFIG_ISA_DMA_API=y
281CONFIG_ISA=y
282# CONFIG_EISA is not set
283# CONFIG_MCA is not set
284# CONFIG_SCx200 is not set
285
286#
287# PCCARD (PCMCIA/CardBus) support
288#
289# CONFIG_PCCARD is not set
290# CONFIG_HOTPLUG_PCI is not set
291
292#
293# Executable file formats
294#
295CONFIG_BINFMT_ELF=y
296CONFIG_BINFMT_AOUT=y
297CONFIG_BINFMT_MISC=y
298
299#
300# Networking
301#
302CONFIG_NET=y
303
304#
305# Networking options
306#
307CONFIG_PACKET=m
308# CONFIG_PACKET_MMAP is not set
309CONFIG_UNIX=y
310CONFIG_XFRM=y
311# CONFIG_XFRM_USER is not set
312# CONFIG_XFRM_SUB_POLICY is not set
313# CONFIG_XFRM_MIGRATE is not set
314# CONFIG_NET_KEY is not set
315CONFIG_INET=y
316CONFIG_IP_MULTICAST=y
317# CONFIG_IP_ADVANCED_ROUTER is not set
318CONFIG_IP_FIB_HASH=y
319CONFIG_IP_PNP=y
320CONFIG_IP_PNP_DHCP=y
321CONFIG_IP_PNP_BOOTP=y
322# CONFIG_IP_PNP_RARP is not set
323# CONFIG_NET_IPIP is not set
324# CONFIG_NET_IPGRE is not set
325# CONFIG_IP_MROUTE is not set
326# CONFIG_ARPD is not set
327# CONFIG_SYN_COOKIES is not set
328# CONFIG_INET_AH is not set
329# CONFIG_INET_ESP is not set
330# CONFIG_INET_IPCOMP is not set
331# CONFIG_INET_XFRM_TUNNEL is not set
332# CONFIG_INET_TUNNEL is not set
333CONFIG_INET_XFRM_MODE_TRANSPORT=y
334CONFIG_INET_XFRM_MODE_TUNNEL=y
335CONFIG_INET_XFRM_MODE_BEET=y
336CONFIG_INET_DIAG=y
337CONFIG_INET_TCP_DIAG=y
338# CONFIG_TCP_CONG_ADVANCED is not set
339CONFIG_TCP_CONG_CUBIC=y
340CONFIG_DEFAULT_TCP_CONG="cubic"
341# CONFIG_TCP_MD5SIG is not set
342# CONFIG_IP_VS is not set
343# CONFIG_IPV6 is not set
344# CONFIG_INET6_XFRM_TUNNEL is not set
345# CONFIG_INET6_TUNNEL is not set
346# CONFIG_NETWORK_SECMARK is not set
347CONFIG_NETFILTER=y
348# CONFIG_NETFILTER_DEBUG is not set
349
350#
351# Core Netfilter Configuration
352#
353CONFIG_NETFILTER_NETLINK=m
354CONFIG_NETFILTER_NETLINK_QUEUE=m
355CONFIG_NETFILTER_NETLINK_LOG=m
356CONFIG_NF_CONNTRACK_ENABLED=m
357CONFIG_NF_CONNTRACK=m
358CONFIG_NF_CT_ACCT=y
359CONFIG_NF_CONNTRACK_MARK=y
360# CONFIG_NF_CONNTRACK_EVENTS is not set
361CONFIG_NF_CT_PROTO_GRE=m
362CONFIG_NF_CT_PROTO_SCTP=m
363CONFIG_NF_CT_PROTO_UDPLITE=m
364CONFIG_NF_CONNTRACK_AMANDA=m
365CONFIG_NF_CONNTRACK_FTP=m
366CONFIG_NF_CONNTRACK_H323=m
367CONFIG_NF_CONNTRACK_IRC=m
368CONFIG_NF_CONNTRACK_NETBIOS_NS=m
369CONFIG_NF_CONNTRACK_PPTP=m
370CONFIG_NF_CONNTRACK_SANE=m
371CONFIG_NF_CONNTRACK_SIP=m
372CONFIG_NF_CONNTRACK_TFTP=m
373CONFIG_NF_CT_NETLINK=m
374CONFIG_NETFILTER_XTABLES=m
375CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
376CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
377CONFIG_NETFILTER_XT_TARGET_DSCP=m
378CONFIG_NETFILTER_XT_TARGET_MARK=m
379CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
380CONFIG_NETFILTER_XT_TARGET_NFLOG=m
381CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
382CONFIG_NETFILTER_XT_TARGET_TRACE=m
383CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
384CONFIG_NETFILTER_XT_MATCH_COMMENT=m
385CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
386CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
387CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
388CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
389CONFIG_NETFILTER_XT_MATCH_DCCP=m
390CONFIG_NETFILTER_XT_MATCH_DSCP=m
391CONFIG_NETFILTER_XT_MATCH_ESP=m
392CONFIG_NETFILTER_XT_MATCH_HELPER=m
393CONFIG_NETFILTER_XT_MATCH_LENGTH=m
394CONFIG_NETFILTER_XT_MATCH_LIMIT=m
395CONFIG_NETFILTER_XT_MATCH_MAC=m
396CONFIG_NETFILTER_XT_MATCH_MARK=m
397CONFIG_NETFILTER_XT_MATCH_POLICY=m
398CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
399CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
400CONFIG_NETFILTER_XT_MATCH_QUOTA=m
401CONFIG_NETFILTER_XT_MATCH_REALM=m
402CONFIG_NETFILTER_XT_MATCH_SCTP=m
403CONFIG_NETFILTER_XT_MATCH_STATE=m
404CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
405CONFIG_NETFILTER_XT_MATCH_STRING=m
406CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
407CONFIG_NETFILTER_XT_MATCH_U32=m
408CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
409
410#
411# IP: Netfilter Configuration
412#
413CONFIG_NF_CONNTRACK_IPV4=m
414CONFIG_NF_CONNTRACK_PROC_COMPAT=y
415CONFIG_IP_NF_QUEUE=m
416CONFIG_IP_NF_IPTABLES=m
417CONFIG_IP_NF_MATCH_IPRANGE=m
418CONFIG_IP_NF_MATCH_TOS=m
419CONFIG_IP_NF_MATCH_RECENT=m
420CONFIG_IP_NF_MATCH_ECN=m
421CONFIG_IP_NF_MATCH_AH=m
422CONFIG_IP_NF_MATCH_TTL=m
423CONFIG_IP_NF_MATCH_OWNER=m
424CONFIG_IP_NF_MATCH_ADDRTYPE=m
425CONFIG_IP_NF_FILTER=m
426CONFIG_IP_NF_TARGET_REJECT=m
427CONFIG_IP_NF_TARGET_LOG=m
428CONFIG_IP_NF_TARGET_ULOG=m
429CONFIG_NF_NAT=m
430CONFIG_NF_NAT_NEEDED=y
431CONFIG_IP_NF_TARGET_MASQUERADE=m
432CONFIG_IP_NF_TARGET_REDIRECT=m
433CONFIG_IP_NF_TARGET_NETMAP=m
434CONFIG_IP_NF_TARGET_SAME=m
435CONFIG_NF_NAT_SNMP_BASIC=m
436CONFIG_NF_NAT_PROTO_GRE=m
437CONFIG_NF_NAT_FTP=m
438CONFIG_NF_NAT_IRC=m
439CONFIG_NF_NAT_TFTP=m
440CONFIG_NF_NAT_AMANDA=m
441CONFIG_NF_NAT_PPTP=m
442CONFIG_NF_NAT_H323=m
443CONFIG_NF_NAT_SIP=m
444CONFIG_IP_NF_MANGLE=m
445CONFIG_IP_NF_TARGET_TOS=m
446CONFIG_IP_NF_TARGET_ECN=m
447CONFIG_IP_NF_TARGET_TTL=m
448CONFIG_IP_NF_TARGET_CLUSTERIP=m
449CONFIG_IP_NF_RAW=m
450CONFIG_IP_NF_ARPTABLES=m
451CONFIG_IP_NF_ARPFILTER=m
452CONFIG_IP_NF_ARP_MANGLE=m
453# CONFIG_IP_DCCP is not set
454# CONFIG_IP_SCTP is not set
455# CONFIG_TIPC is not set
456# CONFIG_ATM is not set
457# CONFIG_BRIDGE is not set
458# CONFIG_VLAN_8021Q is not set
459# CONFIG_DECNET is not set
460# CONFIG_LLC2 is not set
461# CONFIG_IPX is not set
462# CONFIG_ATALK is not set
463# CONFIG_X25 is not set
464# CONFIG_LAPB is not set
465# CONFIG_ECONET is not set
466# CONFIG_WAN_ROUTER is not set
467
468#
469# QoS and/or fair queueing
470#
471# CONFIG_NET_SCHED is not set
472CONFIG_NET_CLS_ROUTE=y
473
474#
475# Network testing
476#
477# CONFIG_NET_PKTGEN is not set
478# CONFIG_HAMRADIO is not set
479# CONFIG_IRDA is not set
480# CONFIG_BT is not set
481# CONFIG_AF_RXRPC is not set
482
483#
484# Wireless
485#
486# CONFIG_CFG80211 is not set
487CONFIG_WIRELESS_EXT=y
488# CONFIG_MAC80211 is not set
489# CONFIG_IEEE80211 is not set
490# CONFIG_RFKILL is not set
491# CONFIG_NET_9P is not set
492
493#
494# Device Drivers
495#
496
497#
498# Generic Driver Options
499#
500CONFIG_STANDALONE=y
501CONFIG_PREVENT_FIRMWARE_BUILD=y
502CONFIG_FW_LOADER=m
503# CONFIG_SYS_HYPERVISOR is not set
504CONFIG_CONNECTOR=y
505CONFIG_PROC_EVENTS=y
506# CONFIG_MTD is not set
507CONFIG_PARPORT=y
508CONFIG_PARPORT_PC=y
509# CONFIG_PARPORT_SERIAL is not set
510# CONFIG_PARPORT_PC_FIFO is not set
511# CONFIG_PARPORT_PC_SUPERIO is not set
512# CONFIG_PARPORT_GSC is not set
513# CONFIG_PARPORT_AX88796 is not set
514# CONFIG_PARPORT_1284 is not set
515CONFIG_PNP=y
516# CONFIG_PNP_DEBUG is not set
517
518#
519# Protocols
520#
521# CONFIG_ISAPNP is not set
522# CONFIG_PNPBIOS is not set
523CONFIG_PNPACPI=y
524CONFIG_BLK_DEV=y
525CONFIG_BLK_DEV_FD=y
526# CONFIG_BLK_DEV_XD is not set
527# CONFIG_PARIDE is not set
528# CONFIG_BLK_CPQ_DA is not set
529# CONFIG_BLK_CPQ_CISS_DA is not set
530# CONFIG_BLK_DEV_DAC960 is not set
531# CONFIG_BLK_DEV_UMEM is not set
532# CONFIG_BLK_DEV_COW_COMMON is not set
533# CONFIG_BLK_DEV_LOOP is not set
534# CONFIG_BLK_DEV_NBD is not set
535# CONFIG_BLK_DEV_SX8 is not set
536# CONFIG_BLK_DEV_UB is not set
537CONFIG_BLK_DEV_RAM=y
538CONFIG_BLK_DEV_RAM_COUNT=16
539CONFIG_BLK_DEV_RAM_SIZE=51200
540CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
541# CONFIG_CDROM_PKTCDVD is not set
542# CONFIG_ATA_OVER_ETH is not set
543CONFIG_MISC_DEVICES=y
544# CONFIG_IBM_ASM is not set
545# CONFIG_PHANTOM is not set
546# CONFIG_EEPROM_93CX6 is not set
547# CONFIG_SGI_IOC4 is not set
548# CONFIG_TIFM_CORE is not set
549# CONFIG_SONY_LAPTOP is not set
550# CONFIG_THINKPAD_ACPI is not set
551CONFIG_IDE=y
552CONFIG_IDE_MAX_HWIFS=4
553CONFIG_BLK_DEV_IDE=y
554
555#
556# Please see Documentation/ide.txt for help/info on IDE drives
557#
558# CONFIG_BLK_DEV_IDE_SATA is not set
559# CONFIG_BLK_DEV_HD_IDE is not set
560CONFIG_BLK_DEV_IDEDISK=y
561CONFIG_IDEDISK_MULTI_MODE=y
562CONFIG_BLK_DEV_IDECD=y
563# CONFIG_BLK_DEV_IDETAPE is not set
564# CONFIG_BLK_DEV_IDEFLOPPY is not set
565# CONFIG_BLK_DEV_IDESCSI is not set
566# CONFIG_BLK_DEV_IDEACPI is not set
567# CONFIG_IDE_TASK_IOCTL is not set
568CONFIG_IDE_PROC_FS=y
569
570#
571# IDE chipset support/bugfixes
572#
573CONFIG_IDE_GENERIC=y
574CONFIG_BLK_DEV_CMD640=y
575# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
576# CONFIG_BLK_DEV_IDEPNP is not set
577CONFIG_BLK_DEV_IDEPCI=y
578CONFIG_IDEPCI_SHARE_IRQ=y
579CONFIG_IDEPCI_PCIBUS_ORDER=y
580# CONFIG_BLK_DEV_OFFBOARD is not set
581CONFIG_BLK_DEV_GENERIC=y
582# CONFIG_BLK_DEV_OPTI621 is not set
583CONFIG_BLK_DEV_RZ1000=y
584CONFIG_BLK_DEV_IDEDMA_PCI=y
585# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
586# CONFIG_IDEDMA_ONLYDISK is not set
587# CONFIG_BLK_DEV_AEC62XX is not set
588# CONFIG_BLK_DEV_ALI15X3 is not set
589# CONFIG_BLK_DEV_AMD74XX is not set
590# CONFIG_BLK_DEV_ATIIXP is not set
591# CONFIG_BLK_DEV_CMD64X is not set
592# CONFIG_BLK_DEV_TRIFLEX is not set
593# CONFIG_BLK_DEV_CY82C693 is not set
594# CONFIG_BLK_DEV_CS5520 is not set
595# CONFIG_BLK_DEV_CS5530 is not set
596# CONFIG_BLK_DEV_CS5535 is not set
597# CONFIG_BLK_DEV_HPT34X is not set
598# CONFIG_BLK_DEV_HPT366 is not set
599# CONFIG_BLK_DEV_JMICRON is not set
600# CONFIG_BLK_DEV_SC1200 is not set
601CONFIG_BLK_DEV_PIIX=y
602# CONFIG_BLK_DEV_IT8213 is not set
603# CONFIG_BLK_DEV_IT821X is not set
604# CONFIG_BLK_DEV_NS87415 is not set
605# CONFIG_BLK_DEV_PDC202XX_OLD is not set
606# CONFIG_BLK_DEV_PDC202XX_NEW is not set
607# CONFIG_BLK_DEV_SVWKS is not set
608# CONFIG_BLK_DEV_SIIMAGE is not set
609# CONFIG_BLK_DEV_SIS5513 is not set
610# CONFIG_BLK_DEV_SLC90E66 is not set
611# CONFIG_BLK_DEV_TRM290 is not set
612# CONFIG_BLK_DEV_VIA82CXXX is not set
613# CONFIG_BLK_DEV_TC86C001 is not set
614# CONFIG_IDE_ARM is not set
615# CONFIG_IDE_CHIPSETS is not set
616CONFIG_BLK_DEV_IDEDMA=y
617# CONFIG_IDEDMA_IVB is not set
618# CONFIG_BLK_DEV_HD is not set
619
620#
621# SCSI device support
622#
623# CONFIG_RAID_ATTRS is not set
624CONFIG_SCSI=y
625CONFIG_SCSI_DMA=y
626# CONFIG_SCSI_TGT is not set
627# CONFIG_SCSI_NETLINK is not set
628CONFIG_SCSI_PROC_FS=y
629
630#
631# SCSI support type (disk, tape, CD-ROM)
632#
633CONFIG_BLK_DEV_SD=y
634# CONFIG_CHR_DEV_ST is not set
635# CONFIG_CHR_DEV_OSST is not set
636# CONFIG_BLK_DEV_SR is not set
637CONFIG_CHR_DEV_SG=y
638# CONFIG_CHR_DEV_SCH is not set
639
640#
641# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
642#
643# CONFIG_SCSI_MULTI_LUN is not set
644# CONFIG_SCSI_CONSTANTS is not set
645# CONFIG_SCSI_LOGGING is not set
646# CONFIG_SCSI_SCAN_ASYNC is not set
647CONFIG_SCSI_WAIT_SCAN=m
648
649#
650# SCSI Transports
651#
652# CONFIG_SCSI_SPI_ATTRS is not set
653# CONFIG_SCSI_FC_ATTRS is not set
654# CONFIG_SCSI_ISCSI_ATTRS is not set
655# CONFIG_SCSI_SAS_LIBSAS is not set
656CONFIG_SCSI_LOWLEVEL=y
657# CONFIG_ISCSI_TCP is not set
658# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
659# CONFIG_SCSI_3W_9XXX is not set
660# CONFIG_SCSI_7000FASST is not set
661# CONFIG_SCSI_ACARD is not set
662# CONFIG_SCSI_AHA152X is not set
663# CONFIG_SCSI_AHA1542 is not set
664# CONFIG_SCSI_AACRAID is not set
665# CONFIG_SCSI_AIC7XXX is not set
666# CONFIG_SCSI_AIC7XXX_OLD is not set
667# CONFIG_SCSI_AIC79XX is not set
668# CONFIG_SCSI_AIC94XX is not set
669CONFIG_SCSI_DPT_I2O=m
670# CONFIG_SCSI_ADVANSYS is not set
671# CONFIG_SCSI_IN2000 is not set
672# CONFIG_SCSI_ARCMSR is not set
673# CONFIG_MEGARAID_NEWGEN is not set
674# CONFIG_MEGARAID_LEGACY is not set
675# CONFIG_MEGARAID_SAS is not set
676# CONFIG_SCSI_HPTIOP is not set
677# CONFIG_SCSI_BUSLOGIC is not set
678# CONFIG_SCSI_DMX3191D is not set
679# CONFIG_SCSI_DTC3280 is not set
680# CONFIG_SCSI_EATA is not set
681# CONFIG_SCSI_FUTURE_DOMAIN is not set
682# CONFIG_SCSI_GDTH is not set
683# CONFIG_SCSI_GENERIC_NCR5380 is not set
684# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
685# CONFIG_SCSI_IPS is not set
686# CONFIG_SCSI_INITIO is not set
687# CONFIG_SCSI_INIA100 is not set
688# CONFIG_SCSI_PPA is not set
689# CONFIG_SCSI_IMM is not set
690# CONFIG_SCSI_NCR53C406A is not set
691# CONFIG_SCSI_STEX is not set
692# CONFIG_SCSI_SYM53C8XX_2 is not set
693# CONFIG_SCSI_PAS16 is not set
694# CONFIG_SCSI_PSI240I is not set
695# CONFIG_SCSI_QLOGIC_FAS is not set
696# CONFIG_SCSI_QLOGIC_1280 is not set
697# CONFIG_SCSI_QLA_FC is not set
698# CONFIG_SCSI_QLA_ISCSI is not set
699# CONFIG_SCSI_LPFC is not set
700# CONFIG_SCSI_SEAGATE is not set
701# CONFIG_SCSI_SYM53C416 is not set
702# CONFIG_SCSI_DC395x is not set
703# CONFIG_SCSI_DC390T is not set
704# CONFIG_SCSI_T128 is not set
705# CONFIG_SCSI_U14_34F is not set
706# CONFIG_SCSI_ULTRASTOR is not set
707# CONFIG_SCSI_NSP32 is not set
708# CONFIG_SCSI_DEBUG is not set
709# CONFIG_SCSI_SRP is not set
710# CONFIG_ATA is not set
711CONFIG_MD=y
712# CONFIG_BLK_DEV_MD is not set
713CONFIG_BLK_DEV_DM=m
714# CONFIG_DM_DEBUG is not set
715CONFIG_DM_CRYPT=m
716CONFIG_DM_SNAPSHOT=m
717CONFIG_DM_MIRROR=m
718CONFIG_DM_ZERO=m
719CONFIG_DM_MULTIPATH=m
720CONFIG_DM_MULTIPATH_EMC=m
721# CONFIG_DM_MULTIPATH_RDAC is not set
722# CONFIG_DM_DELAY is not set
723
724#
725# Fusion MPT device support
726#
727# CONFIG_FUSION is not set
728# CONFIG_FUSION_SPI is not set
729# CONFIG_FUSION_FC is not set
730# CONFIG_FUSION_SAS is not set
731
732#
733# IEEE 1394 (FireWire) support
734#
735# CONFIG_FIREWIRE is not set
736CONFIG_IEEE1394=y
737
738#
739# Subsystem Options
740#
741# CONFIG_IEEE1394_VERBOSEDEBUG is not set
742
743#
744# Controllers
745#
746
747#
748# Texas Instruments PCILynx requires I2C
749#
750CONFIG_IEEE1394_OHCI1394=y
751
752#
753# Protocols
754#
755# CONFIG_IEEE1394_VIDEO1394 is not set
756# CONFIG_IEEE1394_SBP2 is not set
757# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set
758# CONFIG_IEEE1394_ETH1394 is not set
759# CONFIG_IEEE1394_DV1394 is not set
760CONFIG_IEEE1394_RAWIO=y
761# CONFIG_I2O is not set
762# CONFIG_MACINTOSH_DRIVERS is not set
763CONFIG_NETDEVICES=y
764# CONFIG_NETDEVICES_MULTIQUEUE is not set
765CONFIG_DUMMY=m
766# CONFIG_BONDING is not set
767# CONFIG_MACVLAN is not set
768# CONFIG_EQUALIZER is not set
769# CONFIG_TUN is not set
770# CONFIG_NET_SB1000 is not set
771# CONFIG_ARCNET is not set
772# CONFIG_PHYLIB is not set
773CONFIG_NET_ETHERNET=y
774CONFIG_MII=y
775# CONFIG_HAPPYMEAL is not set
776# CONFIG_SUNGEM is not set
777# CONFIG_CASSINI is not set
778# CONFIG_NET_VENDOR_3COM is not set
779# CONFIG_LANCE is not set
780# CONFIG_NET_VENDOR_SMC is not set
781# CONFIG_NET_VENDOR_RACAL is not set
782# CONFIG_NET_TULIP is not set
783# CONFIG_AT1700 is not set
784# CONFIG_DEPCA is not set
785# CONFIG_HP100 is not set
786CONFIG_NET_ISA=y
787# CONFIG_E2100 is not set
788# CONFIG_EWRK3 is not set
789# CONFIG_EEXPRESS is not set
790# CONFIG_EEXPRESS_PRO is not set
791# CONFIG_HPLAN_PLUS is not set
792# CONFIG_HPLAN is not set
793# CONFIG_LP486E is not set
794# CONFIG_ETH16I is not set
795CONFIG_NE2000=y
796# CONFIG_ZNET is not set
797# CONFIG_SEEQ8005 is not set
798CONFIG_NET_PCI=y
799# CONFIG_PCNET32 is not set
800# CONFIG_AMD8111_ETH is not set
801# CONFIG_ADAPTEC_STARFIRE is not set
802# CONFIG_AC3200 is not set
803# CONFIG_APRICOT is not set
804# CONFIG_B44 is not set
805# CONFIG_FORCEDETH is not set
806# CONFIG_CS89x0 is not set
807# CONFIG_DGRS is not set
808# CONFIG_EEPRO100 is not set
809# CONFIG_E100 is not set
810# CONFIG_FEALNX is not set
811# CONFIG_NATSEMI is not set
812CONFIG_NE2K_PCI=y
813# CONFIG_8139CP is not set
814CONFIG_8139TOO=y
815CONFIG_8139TOO_PIO=y
816# CONFIG_8139TOO_TUNE_TWISTER is not set
817# CONFIG_8139TOO_8129 is not set
818# CONFIG_8139_OLD_RX_RESET is not set
819# CONFIG_SIS900 is not set
820# CONFIG_EPIC100 is not set
821# CONFIG_SUNDANCE is not set
822# CONFIG_TLAN is not set
823# CONFIG_VIA_RHINE is not set
824# CONFIG_SC92031 is not set
825# CONFIG_NET_POCKET is not set
826CONFIG_NETDEV_1000=y
827# CONFIG_ACENIC is not set
828# CONFIG_DL2K is not set
829# CONFIG_E1000 is not set
830# CONFIG_NS83820 is not set
831# CONFIG_HAMACHI is not set
832# CONFIG_YELLOWFIN is not set
833# CONFIG_R8169 is not set
834# CONFIG_SIS190 is not set
835# CONFIG_SKGE is not set
836# CONFIG_SKY2 is not set
837# CONFIG_SK98LIN is not set
838# CONFIG_VIA_VELOCITY is not set
839# CONFIG_TIGON3 is not set
840# CONFIG_BNX2 is not set
841# CONFIG_QLA3XXX is not set
842# CONFIG_ATL1 is not set
843CONFIG_NETDEV_10000=y
844# CONFIG_CHELSIO_T1 is not set
845# CONFIG_CHELSIO_T3 is not set
846# CONFIG_IXGB is not set
847CONFIG_S2IO=m
848# CONFIG_S2IO_NAPI is not set
849# CONFIG_MYRI10GE is not set
850# CONFIG_NETXEN_NIC is not set
851# CONFIG_MLX4_CORE is not set
852# CONFIG_TR is not set
853
854#
855# Wireless LAN
856#
857# CONFIG_WLAN_PRE80211 is not set
858# CONFIG_WLAN_80211 is not set
859
860#
861# USB Network Adapters
862#
863# CONFIG_USB_CATC is not set
864# CONFIG_USB_KAWETH is not set
865# CONFIG_USB_PEGASUS is not set
866# CONFIG_USB_RTL8150 is not set
867# CONFIG_USB_USBNET_MII is not set
868# CONFIG_USB_USBNET is not set
869# CONFIG_WAN is not set
870# CONFIG_FDDI is not set
871# CONFIG_HIPPI is not set
872# CONFIG_PLIP is not set
873# CONFIG_PPP is not set
874# CONFIG_SLIP is not set
875# CONFIG_NET_FC is not set
876# CONFIG_SHAPER is not set
877# CONFIG_NETCONSOLE is not set
878# CONFIG_NETPOLL is not set
879# CONFIG_NET_POLL_CONTROLLER is not set
880# CONFIG_ISDN is not set
881# CONFIG_PHONE is not set
882
883#
884# Input device support
885#
886CONFIG_INPUT=y
887# CONFIG_INPUT_FF_MEMLESS is not set
888# CONFIG_INPUT_POLLDEV is not set
889
890#
891# Userland interfaces
892#
893# CONFIG_INPUT_MOUSEDEV is not set
894# CONFIG_INPUT_JOYDEV is not set
895# CONFIG_INPUT_TSDEV is not set
896CONFIG_INPUT_EVDEV=y
897# CONFIG_INPUT_EVBUG is not set
898# CONFIG_INPUT_POWER is not set
899
900#
901# Input Device Drivers
902#
903CONFIG_INPUT_KEYBOARD=y
904CONFIG_KEYBOARD_ATKBD=y
905# CONFIG_KEYBOARD_SUNKBD is not set
906# CONFIG_KEYBOARD_LKKBD is not set
907# CONFIG_KEYBOARD_XTKBD is not set
908# CONFIG_KEYBOARD_NEWTON is not set
909# CONFIG_KEYBOARD_STOWAWAY is not set
910# CONFIG_INPUT_MOUSE is not set
911# CONFIG_INPUT_JOYSTICK is not set
912CONFIG_INPUT_TABLET=y
913# CONFIG_TABLET_USB_ACECAD is not set
914# CONFIG_TABLET_USB_AIPTEK is not set
915# CONFIG_TABLET_USB_GTCO is not set
916# CONFIG_TABLET_USB_KBTAB is not set
917CONFIG_TABLET_USB_WACOM=y
918# CONFIG_INPUT_TOUCHSCREEN is not set
919# CONFIG_INPUT_MISC is not set
920
921#
922# Hardware I/O ports
923#
924CONFIG_SERIO=y
925CONFIG_SERIO_I8042=y
926# CONFIG_SERIO_SERPORT is not set
927# CONFIG_SERIO_CT82C710 is not set
928# CONFIG_SERIO_PARKBD is not set
929# CONFIG_SERIO_PCIPS2 is not set
930CONFIG_SERIO_LIBPS2=y
931# CONFIG_SERIO_RAW is not set
932# CONFIG_GAMEPORT is not set
933
934#
935# Character devices
936#
937CONFIG_VT=y
938CONFIG_VT_CONSOLE=y
939CONFIG_HW_CONSOLE=y
940# CONFIG_VT_HW_CONSOLE_BINDING is not set
941# CONFIG_SERIAL_NONSTANDARD is not set
942
943#
944# Serial drivers
945#
946CONFIG_SERIAL_8250=y
947# CONFIG_SERIAL_8250_CONSOLE is not set
948CONFIG_FIX_EARLYCON_MEM=y
949CONFIG_SERIAL_8250_PCI=y
950CONFIG_SERIAL_8250_PNP=y
951CONFIG_SERIAL_8250_NR_UARTS=4
952CONFIG_SERIAL_8250_RUNTIME_UARTS=4
953# CONFIG_SERIAL_8250_EXTENDED is not set
954
955#
956# Non-8250 serial port support
957#
958CONFIG_SERIAL_CORE=y
959# CONFIG_SERIAL_JSM is not set
960CONFIG_UNIX98_PTYS=y
961# CONFIG_LEGACY_PTYS is not set
962CONFIG_PRINTER=y
963# CONFIG_LP_CONSOLE is not set
964# CONFIG_PPDEV is not set
965# CONFIG_TIPAR is not set
966# CONFIG_IPMI_HANDLER is not set
967# CONFIG_WATCHDOG is not set
968# CONFIG_HW_RANDOM is not set
969# CONFIG_NVRAM is not set
970# CONFIG_RTC is not set
971# CONFIG_GEN_RTC is not set
972# CONFIG_DTLK is not set
973# CONFIG_R3964 is not set
974# CONFIG_APPLICOM is not set
975# CONFIG_SONYPI is not set
976CONFIG_AGP=y
977# CONFIG_AGP_ALI is not set
978# CONFIG_AGP_ATI is not set
979# CONFIG_AGP_AMD is not set
980# CONFIG_AGP_AMD64 is not set
981CONFIG_AGP_INTEL=y
982# CONFIG_AGP_NVIDIA is not set
983# CONFIG_AGP_SIS is not set
984# CONFIG_AGP_SWORKS is not set
985# CONFIG_AGP_VIA is not set
986# CONFIG_AGP_EFFICEON is not set
987CONFIG_DRM=y
988# CONFIG_DRM_TDFX is not set
989# CONFIG_DRM_R128 is not set
990# CONFIG_DRM_RADEON is not set
991# CONFIG_DRM_I810 is not set
992# CONFIG_DRM_I830 is not set
993# CONFIG_DRM_I915 is not set
994# CONFIG_DRM_MGA is not set
995# CONFIG_DRM_SIS is not set
996# CONFIG_DRM_VIA is not set
997# CONFIG_DRM_SAVAGE is not set
998# CONFIG_MWAVE is not set
999# CONFIG_PC8736x_GPIO is not set
1000# CONFIG_NSC_GPIO is not set
1001# CONFIG_CS5535_GPIO is not set
1002# CONFIG_RAW_DRIVER is not set
1003# CONFIG_HPET is not set
1004# CONFIG_HANGCHECK_TIMER is not set
1005# CONFIG_TCG_TPM is not set
1006# CONFIG_TELCLOCK is not set
1007CONFIG_DEVPORT=y
1008# CONFIG_I2C is not set
1009
1010#
1011# SPI support
1012#
1013# CONFIG_SPI is not set
1014# CONFIG_SPI_MASTER is not set
1015# CONFIG_W1 is not set
1016# CONFIG_POWER_SUPPLY is not set
1017CONFIG_HWMON=y
1018# CONFIG_HWMON_VID is not set
1019# CONFIG_SENSORS_ABITUGURU is not set
1020# CONFIG_SENSORS_ABITUGURU3 is not set
1021# CONFIG_SENSORS_K8TEMP is not set
1022# CONFIG_SENSORS_F71805F is not set
1023# CONFIG_SENSORS_CORETEMP is not set
1024# CONFIG_SENSORS_IT87 is not set
1025# CONFIG_SENSORS_PC87360 is not set
1026# CONFIG_SENSORS_PC87427 is not set
1027# CONFIG_SENSORS_SIS5595 is not set
1028# CONFIG_SENSORS_SMSC47M1 is not set
1029# CONFIG_SENSORS_SMSC47B397 is not set
1030# CONFIG_SENSORS_VIA686A is not set
1031# CONFIG_SENSORS_VT1211 is not set
1032# CONFIG_SENSORS_VT8231 is not set
1033# CONFIG_SENSORS_W83627HF is not set
1034# CONFIG_SENSORS_W83627EHF is not set
1035# CONFIG_SENSORS_HDAPS is not set
1036# CONFIG_SENSORS_APPLESMC is not set
1037# CONFIG_HWMON_DEBUG_CHIP is not set
1038
1039#
1040# Multifunction device drivers
1041#
1042# CONFIG_MFD_SM501 is not set
1043# CONFIG_HTC_ASIC3 is not set
1044# CONFIG_HTC_ASIC3_DS1WM is not set
1045
1046#
1047# Multi-Function Devices
1048#
1049
1050#
1051# Multimedia devices
1052#
1053CONFIG_VIDEO_DEV=m
1054CONFIG_VIDEO_V4L1=y
1055CONFIG_VIDEO_V4L1_COMPAT=y
1056CONFIG_VIDEO_V4L2=y
1057CONFIG_VIDEO_CAPTURE_DRIVERS=y
1058# CONFIG_VIDEO_ADV_DEBUG is not set
1059CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1060# CONFIG_VIDEO_VIVI is not set
1061# CONFIG_VIDEO_PMS is not set
1062# CONFIG_VIDEO_BWQCAM is not set
1063# CONFIG_VIDEO_CQCAM is not set
1064# CONFIG_VIDEO_CPIA is not set
1065# CONFIG_VIDEO_CPIA2 is not set
1066# CONFIG_VIDEO_STRADIS is not set
1067CONFIG_V4L_USB_DRIVERS=y
1068# CONFIG_USB_VICAM is not set
1069# CONFIG_USB_IBMCAM is not set
1070# CONFIG_USB_KONICAWC is not set
1071# CONFIG_USB_QUICKCAM_MESSENGER is not set
1072# CONFIG_USB_ET61X251 is not set
1073# CONFIG_USB_OV511 is not set
1074# CONFIG_USB_SE401 is not set
1075# CONFIG_USB_SN9C102 is not set
1076# CONFIG_USB_STV680 is not set
1077# CONFIG_USB_ZC0301 is not set
1078# CONFIG_USB_PWC is not set
1079# CONFIG_USB_ZR364XX is not set
1080CONFIG_RADIO_ADAPTERS=y
1081# CONFIG_RADIO_CADET is not set
1082# CONFIG_RADIO_RTRACK is not set
1083# CONFIG_RADIO_RTRACK2 is not set
1084# CONFIG_RADIO_AZTECH is not set
1085# CONFIG_RADIO_GEMTEK is not set
1086# CONFIG_RADIO_GEMTEK_PCI is not set
1087# CONFIG_RADIO_MAXIRADIO is not set
1088# CONFIG_RADIO_MAESTRO is not set
1089# CONFIG_RADIO_SF16FMI is not set
1090# CONFIG_RADIO_SF16FMR2 is not set
1091# CONFIG_RADIO_TERRATEC is not set
1092# CONFIG_RADIO_TRUST is not set
1093# CONFIG_RADIO_TYPHOON is not set
1094# CONFIG_RADIO_ZOLTRIX is not set
1095# CONFIG_USB_DSBR is not set
1096# CONFIG_DVB_CORE is not set
1097CONFIG_DAB=y
1098# CONFIG_USB_DABUSB is not set
1099
1100#
1101# Graphics support
1102#
1103# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1104
1105#
1106# Display device support
1107#
1108# CONFIG_DISPLAY_SUPPORT is not set
1109# CONFIG_VGASTATE is not set
1110CONFIG_VIDEO_OUTPUT_CONTROL=m
1111CONFIG_FB=y
1112# CONFIG_FIRMWARE_EDID is not set
1113# CONFIG_FB_DDC is not set
1114CONFIG_FB_CFB_FILLRECT=m
1115CONFIG_FB_CFB_COPYAREA=m
1116CONFIG_FB_CFB_IMAGEBLIT=m
1117# CONFIG_FB_SYS_FILLRECT is not set
1118# CONFIG_FB_SYS_COPYAREA is not set
1119# CONFIG_FB_SYS_IMAGEBLIT is not set
1120# CONFIG_FB_SYS_FOPS is not set
1121CONFIG_FB_DEFERRED_IO=y
1122# CONFIG_FB_SVGALIB is not set
1123# CONFIG_FB_MACMODES is not set
1124# CONFIG_FB_BACKLIGHT is not set
1125CONFIG_FB_MODE_HELPERS=y
1126# CONFIG_FB_TILEBLITTING is not set
1127
1128#
1129# Frame buffer hardware drivers
1130#
1131# CONFIG_FB_CIRRUS is not set
1132# CONFIG_FB_PM2 is not set
1133# CONFIG_FB_CYBER2000 is not set
1134# CONFIG_FB_ARC is not set
1135# CONFIG_FB_ASILIANT is not set
1136# CONFIG_FB_IMSTT is not set
1137# CONFIG_FB_VGA16 is not set
1138CONFIG_FB_UVESA=m
1139# CONFIG_FB_VESA is not set
1140# CONFIG_FB_HECUBA is not set
1141# CONFIG_FB_HGA is not set
1142# CONFIG_FB_S1D13XXX is not set
1143# CONFIG_FB_NVIDIA is not set
1144# CONFIG_FB_RIVA is not set
1145# CONFIG_FB_I810 is not set
1146# CONFIG_FB_LE80578 is not set
1147# CONFIG_FB_INTEL is not set
1148# CONFIG_FB_MATROX is not set
1149# CONFIG_FB_RADEON is not set
1150# CONFIG_FB_ATY128 is not set
1151# CONFIG_FB_ATY is not set
1152# CONFIG_FB_S3 is not set
1153# CONFIG_FB_SAVAGE is not set
1154# CONFIG_FB_SIS is not set
1155# CONFIG_FB_NEOMAGIC is not set
1156# CONFIG_FB_KYRO is not set
1157# CONFIG_FB_3DFX is not set
1158# CONFIG_FB_VOODOO1 is not set
1159# CONFIG_FB_VT8623 is not set
1160# CONFIG_FB_CYBLA is not set
1161# CONFIG_FB_TRIDENT is not set
1162# CONFIG_FB_ARK is not set
1163# CONFIG_FB_PM3 is not set
1164# CONFIG_FB_GEODE is not set
1165# CONFIG_FB_VIRTUAL is not set
1166
1167#
1168# Console display driver support
1169#
1170CONFIG_VGA_CONSOLE=y
1171# CONFIG_VGACON_SOFT_SCROLLBACK is not set
1172CONFIG_VIDEO_SELECT=y
1173# CONFIG_MDA_CONSOLE is not set
1174CONFIG_DUMMY_CONSOLE=y
1175CONFIG_FRAMEBUFFER_CONSOLE=y
1176# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1177# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1178CONFIG_FONTS=y
1179CONFIG_FONT_8x8=y
1180CONFIG_FONT_8x16=y
1181# CONFIG_FONT_6x11 is not set
1182# CONFIG_FONT_7x14 is not set
1183# CONFIG_FONT_PEARL_8x8 is not set
1184# CONFIG_FONT_ACORN_8x8 is not set
1185# CONFIG_FONT_MINI_4x6 is not set
1186# CONFIG_FONT_SUN8x16 is not set
1187# CONFIG_FONT_SUN12x22 is not set
1188# CONFIG_FONT_10x18 is not set
1189CONFIG_LOGO=y
1190# CONFIG_LOGO_LINUX_MONO is not set
1191# CONFIG_LOGO_LINUX_VGA16 is not set
1192# CONFIG_LOGO_LINUX_CLUT224 is not set
1193CONFIG_LOGO_OHAND_CLUT224=y
1194# CONFIG_LOGO_OZ240_CLUT224 is not set
1195# CONFIG_LOGO_OZ480_CLUT224 is not set
1196# CONFIG_LOGO_OZ640_CLUT224 is not set
1197
1198#
1199# Sound
1200#
1201CONFIG_SOUND=y
1202
1203#
1204# Advanced Linux Sound Architecture
1205#
1206CONFIG_SND=y
1207CONFIG_SND_TIMER=y
1208CONFIG_SND_PCM=y
1209CONFIG_SND_SEQUENCER=y
1210# CONFIG_SND_SEQ_DUMMY is not set
1211CONFIG_SND_OSSEMUL=y
1212CONFIG_SND_MIXER_OSS=y
1213CONFIG_SND_PCM_OSS=y
1214CONFIG_SND_PCM_OSS_PLUGINS=y
1215CONFIG_SND_SEQUENCER_OSS=y
1216# CONFIG_SND_DYNAMIC_MINORS is not set
1217CONFIG_SND_SUPPORT_OLD_API=y
1218CONFIG_SND_VERBOSE_PROCFS=y
1219# CONFIG_SND_VERBOSE_PRINTK is not set
1220# CONFIG_SND_DEBUG is not set
1221
1222#
1223# Generic devices
1224#
1225CONFIG_SND_AC97_CODEC=y
1226# CONFIG_SND_DUMMY is not set
1227# CONFIG_SND_VIRMIDI is not set
1228# CONFIG_SND_MTPAV is not set
1229# CONFIG_SND_MTS64 is not set
1230# CONFIG_SND_SERIAL_U16550 is not set
1231# CONFIG_SND_MPU401 is not set
1232# CONFIG_SND_PORTMAN2X4 is not set
1233
1234#
1235# ISA devices
1236#
1237# CONFIG_SND_ADLIB is not set
1238# CONFIG_SND_AD1816A is not set
1239# CONFIG_SND_AD1848 is not set
1240# CONFIG_SND_ALS100 is not set
1241# CONFIG_SND_AZT2320 is not set
1242# CONFIG_SND_CMI8330 is not set
1243# CONFIG_SND_CS4231 is not set
1244# CONFIG_SND_CS4232 is not set
1245# CONFIG_SND_CS4236 is not set
1246# CONFIG_SND_DT019X is not set
1247# CONFIG_SND_ES968 is not set
1248# CONFIG_SND_ES1688 is not set
1249# CONFIG_SND_ES18XX is not set
1250# CONFIG_SND_GUSCLASSIC is not set
1251# CONFIG_SND_GUSEXTREME is not set
1252# CONFIG_SND_GUSMAX is not set
1253# CONFIG_SND_INTERWAVE is not set
1254# CONFIG_SND_INTERWAVE_STB is not set
1255# CONFIG_SND_OPL3SA2 is not set
1256# CONFIG_SND_OPTI92X_AD1848 is not set
1257# CONFIG_SND_OPTI92X_CS4231 is not set
1258# CONFIG_SND_OPTI93X is not set
1259# CONFIG_SND_MIRO is not set
1260# CONFIG_SND_SB8 is not set
1261# CONFIG_SND_SB16 is not set
1262# CONFIG_SND_SBAWE is not set
1263# CONFIG_SND_SGALAXY is not set
1264# CONFIG_SND_SSCAPE is not set
1265# CONFIG_SND_WAVEFRONT is not set
1266
1267#
1268# PCI devices
1269#
1270# CONFIG_SND_AD1889 is not set
1271# CONFIG_SND_ALS300 is not set
1272# CONFIG_SND_ALS4000 is not set
1273# CONFIG_SND_ALI5451 is not set
1274# CONFIG_SND_ATIIXP is not set
1275# CONFIG_SND_ATIIXP_MODEM is not set
1276# CONFIG_SND_AU8810 is not set
1277# CONFIG_SND_AU8820 is not set
1278# CONFIG_SND_AU8830 is not set
1279# CONFIG_SND_AZT3328 is not set
1280# CONFIG_SND_BT87X is not set
1281# CONFIG_SND_CA0106 is not set
1282# CONFIG_SND_CMIPCI is not set
1283# CONFIG_SND_CS4281 is not set
1284# CONFIG_SND_CS46XX is not set
1285# CONFIG_SND_CS5530 is not set
1286# CONFIG_SND_CS5535AUDIO is not set
1287# CONFIG_SND_DARLA20 is not set
1288# CONFIG_SND_GINA20 is not set
1289# CONFIG_SND_LAYLA20 is not set
1290# CONFIG_SND_DARLA24 is not set
1291# CONFIG_SND_GINA24 is not set
1292# CONFIG_SND_LAYLA24 is not set
1293# CONFIG_SND_MONA is not set
1294# CONFIG_SND_MIA is not set
1295# CONFIG_SND_ECHO3G is not set
1296# CONFIG_SND_INDIGO is not set
1297# CONFIG_SND_INDIGOIO is not set
1298# CONFIG_SND_INDIGODJ is not set
1299# CONFIG_SND_EMU10K1 is not set
1300# CONFIG_SND_EMU10K1X is not set
1301# CONFIG_SND_ENS1370 is not set
1302# CONFIG_SND_ENS1371 is not set
1303# CONFIG_SND_ES1938 is not set
1304# CONFIG_SND_ES1968 is not set
1305# CONFIG_SND_FM801 is not set
1306# CONFIG_SND_HDA_INTEL is not set
1307# CONFIG_SND_HDSP is not set
1308# CONFIG_SND_HDSPM is not set
1309# CONFIG_SND_ICE1712 is not set
1310# CONFIG_SND_ICE1724 is not set
1311CONFIG_SND_INTEL8X0=y
1312# CONFIG_SND_INTEL8X0M is not set
1313# CONFIG_SND_KORG1212 is not set
1314# CONFIG_SND_MAESTRO3 is not set
1315# CONFIG_SND_MIXART is not set
1316# CONFIG_SND_NM256 is not set
1317# CONFIG_SND_PCXHR is not set
1318# CONFIG_SND_RIPTIDE is not set
1319# CONFIG_SND_RME32 is not set
1320# CONFIG_SND_RME96 is not set
1321# CONFIG_SND_RME9652 is not set
1322# CONFIG_SND_SONICVIBES is not set
1323# CONFIG_SND_TRIDENT is not set
1324# CONFIG_SND_VIA82XX is not set
1325# CONFIG_SND_VIA82XX_MODEM is not set
1326# CONFIG_SND_VX222 is not set
1327# CONFIG_SND_YMFPCI is not set
1328# CONFIG_SND_AC97_POWER_SAVE is not set
1329
1330#
1331# USB devices
1332#
1333# CONFIG_SND_USB_AUDIO is not set
1334# CONFIG_SND_USB_USX2Y is not set
1335# CONFIG_SND_USB_CAIAQ is not set
1336
1337#
1338# System on Chip audio support
1339#
1340# CONFIG_SND_SOC is not set
1341
1342#
1343# SoC Audio support for SuperH
1344#
1345
1346#
1347# Open Sound System
1348#
1349# CONFIG_SOUND_PRIME is not set
1350CONFIG_AC97_BUS=y
1351CONFIG_HID_SUPPORT=y
1352CONFIG_HID=y
1353# CONFIG_HID_DEBUG is not set
1354
1355#
1356# USB Input Devices
1357#
1358CONFIG_USB_HID=y
1359# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1360# CONFIG_HID_FF is not set
1361# CONFIG_USB_HIDDEV is not set
1362CONFIG_USB_SUPPORT=y
1363CONFIG_USB_ARCH_HAS_HCD=y
1364CONFIG_USB_ARCH_HAS_OHCI=y
1365CONFIG_USB_ARCH_HAS_EHCI=y
1366CONFIG_USB=y
1367# CONFIG_USB_DEBUG is not set
1368
1369#
1370# Miscellaneous USB options
1371#
1372CONFIG_USB_DEVICEFS=y
1373CONFIG_USB_DEVICE_CLASS=y
1374# CONFIG_USB_DYNAMIC_MINORS is not set
1375# CONFIG_USB_SUSPEND is not set
1376# CONFIG_USB_PERSIST is not set
1377# CONFIG_USB_OTG is not set
1378
1379#
1380# USB Host Controller Drivers
1381#
1382CONFIG_USB_EHCI_HCD=y
1383# CONFIG_USB_EHCI_SPLIT_ISO is not set
1384# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1385# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1386# CONFIG_USB_ISP116X_HCD is not set
1387CONFIG_USB_OHCI_HCD=y
1388# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1389# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1390CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1391CONFIG_USB_UHCI_HCD=y
1392# CONFIG_USB_SL811_HCD is not set
1393# CONFIG_USB_R8A66597_HCD is not set
1394
1395#
1396# USB Device Class drivers
1397#
1398# CONFIG_USB_ACM is not set
1399CONFIG_USB_PRINTER=y
1400
1401#
1402# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1403#
1404
1405#
1406# may also be needed; see USB_STORAGE Help for more information
1407#
1408CONFIG_USB_STORAGE=y
1409# CONFIG_USB_STORAGE_DEBUG is not set
1410# CONFIG_USB_STORAGE_DATAFAB is not set
1411# CONFIG_USB_STORAGE_FREECOM is not set
1412# CONFIG_USB_STORAGE_ISD200 is not set
1413# CONFIG_USB_STORAGE_DPCM is not set
1414# CONFIG_USB_STORAGE_USBAT is not set
1415# CONFIG_USB_STORAGE_SDDR09 is not set
1416# CONFIG_USB_STORAGE_SDDR55 is not set
1417# CONFIG_USB_STORAGE_JUMPSHOT is not set
1418# CONFIG_USB_STORAGE_ALAUDA is not set
1419# CONFIG_USB_STORAGE_KARMA is not set
1420# CONFIG_USB_LIBUSUAL is not set
1421
1422#
1423# USB Imaging devices
1424#
1425# CONFIG_USB_MDC800 is not set
1426# CONFIG_USB_MICROTEK is not set
1427CONFIG_USB_MON=y
1428
1429#
1430# USB port drivers
1431#
1432# CONFIG_USB_USS720 is not set
1433
1434#
1435# USB Serial Converter support
1436#
1437# CONFIG_USB_SERIAL is not set
1438
1439#
1440# USB Miscellaneous drivers
1441#
1442# CONFIG_USB_EMI62 is not set
1443# CONFIG_USB_EMI26 is not set
1444# CONFIG_USB_ADUTUX is not set
1445# CONFIG_USB_AUERSWALD is not set
1446# CONFIG_USB_RIO500 is not set
1447# CONFIG_USB_LEGOTOWER is not set
1448# CONFIG_USB_LCD is not set
1449# CONFIG_USB_BERRY_CHARGE is not set
1450# CONFIG_USB_LED is not set
1451# CONFIG_USB_CYPRESS_CY7C63 is not set
1452CONFIG_USB_CYTHERM=m
1453# CONFIG_USB_PHIDGET is not set
1454# CONFIG_USB_IDMOUSE is not set
1455# CONFIG_USB_FTDI_ELAN is not set
1456# CONFIG_USB_APPLEDISPLAY is not set
1457# CONFIG_USB_SISUSBVGA is not set
1458# CONFIG_USB_LD is not set
1459# CONFIG_USB_TRANCEVIBRATOR is not set
1460# CONFIG_USB_IOWARRIOR is not set
1461# CONFIG_USB_TEST is not set
1462
1463#
1464# USB DSL modem support
1465#
1466
1467#
1468# USB Gadget Support
1469#
1470# CONFIG_USB_GADGET is not set
1471# CONFIG_MMC is not set
1472# CONFIG_NEW_LEDS is not set
1473# CONFIG_INFINIBAND is not set
1474# CONFIG_EDAC is not set
1475# CONFIG_RTC_CLASS is not set
1476
1477#
1478# DMA Engine support
1479#
1480# CONFIG_DMA_ENGINE is not set
1481
1482#
1483# DMA Clients
1484#
1485
1486#
1487# DMA Devices
1488#
1489# CONFIG_AUXDISPLAY is not set
1490CONFIG_VIRTUALIZATION=y
1491# CONFIG_KVM is not set
1492
1493#
1494# Userspace I/O
1495#
1496# CONFIG_UIO is not set
1497
1498#
1499# File systems
1500#
1501CONFIG_EXT2_FS=y
1502# CONFIG_EXT2_FS_XATTR is not set
1503# CONFIG_EXT2_FS_XIP is not set
1504CONFIG_EXT3_FS=y
1505CONFIG_EXT3_FS_XATTR=y
1506# CONFIG_EXT3_FS_POSIX_ACL is not set
1507# CONFIG_EXT3_FS_SECURITY is not set
1508# CONFIG_EXT4DEV_FS is not set
1509CONFIG_JBD=y
1510# CONFIG_JBD_DEBUG is not set
1511CONFIG_FS_MBCACHE=y
1512# CONFIG_REISERFS_FS is not set
1513# CONFIG_JFS_FS is not set
1514# CONFIG_FS_POSIX_ACL is not set
1515# CONFIG_XFS_FS is not set
1516# CONFIG_GFS2_FS is not set
1517# CONFIG_OCFS2_FS is not set
1518# CONFIG_MINIX_FS is not set
1519# CONFIG_ROMFS_FS is not set
1520CONFIG_INOTIFY=y
1521CONFIG_INOTIFY_USER=y
1522# CONFIG_QUOTA is not set
1523CONFIG_DNOTIFY=y
1524# CONFIG_AUTOFS_FS is not set
1525CONFIG_AUTOFS4_FS=y
1526# CONFIG_FUSE_FS is not set
1527
1528#
1529# CD-ROM/DVD Filesystems
1530#
1531CONFIG_ISO9660_FS=y
1532CONFIG_JOLIET=y
1533# CONFIG_ZISOFS is not set
1534CONFIG_UDF_FS=y
1535CONFIG_UDF_NLS=y
1536
1537#
1538# DOS/FAT/NT Filesystems
1539#
1540CONFIG_FAT_FS=y
1541CONFIG_MSDOS_FS=y
1542CONFIG_VFAT_FS=y
1543CONFIG_FAT_DEFAULT_CODEPAGE=437
1544CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1545# CONFIG_NTFS_FS is not set
1546
1547#
1548# Pseudo filesystems
1549#
1550CONFIG_PROC_FS=y
1551CONFIG_PROC_KCORE=y
1552CONFIG_PROC_SYSCTL=y
1553CONFIG_SYSFS=y
1554CONFIG_TMPFS=y
1555# CONFIG_TMPFS_POSIX_ACL is not set
1556# CONFIG_HUGETLBFS is not set
1557# CONFIG_HUGETLB_PAGE is not set
1558CONFIG_RAMFS=y
1559# CONFIG_CONFIGFS_FS is not set
1560
1561#
1562# Miscellaneous filesystems
1563#
1564# CONFIG_ADFS_FS is not set
1565# CONFIG_AFFS_FS is not set
1566# CONFIG_HFS_FS is not set
1567# CONFIG_HFSPLUS_FS is not set
1568# CONFIG_BEFS_FS is not set
1569# CONFIG_BFS_FS is not set
1570# CONFIG_EFS_FS is not set
1571# CONFIG_CRAMFS is not set
1572# CONFIG_SQUASHFS is not set
1573# CONFIG_VXFS_FS is not set
1574# CONFIG_HPFS_FS is not set
1575# CONFIG_QNX4FS_FS is not set
1576# CONFIG_SYSV_FS is not set
1577# CONFIG_UFS_FS is not set
1578
1579#
1580# Network File Systems
1581#
1582CONFIG_NFS_FS=y
1583# CONFIG_NFS_V3 is not set
1584# CONFIG_NFS_V4 is not set
1585# CONFIG_NFS_DIRECTIO is not set
1586CONFIG_NFSD=y
1587# CONFIG_NFSD_V3 is not set
1588CONFIG_NFSD_TCP=y
1589CONFIG_ROOT_NFS=y
1590CONFIG_LOCKD=y
1591CONFIG_EXPORTFS=y
1592CONFIG_NFS_COMMON=y
1593CONFIG_SUNRPC=y
1594# CONFIG_SUNRPC_BIND34 is not set
1595# CONFIG_RPCSEC_GSS_KRB5 is not set
1596# CONFIG_RPCSEC_GSS_SPKM3 is not set
1597# CONFIG_SMB_FS is not set
1598# CONFIG_CIFS is not set
1599# CONFIG_NCP_FS is not set
1600# CONFIG_CODA_FS is not set
1601# CONFIG_AFS_FS is not set
1602
1603#
1604# Partition Types
1605#
1606# CONFIG_PARTITION_ADVANCED is not set
1607CONFIG_MSDOS_PARTITION=y
1608
1609#
1610# Native Language Support
1611#
1612CONFIG_NLS=y
1613CONFIG_NLS_DEFAULT="iso8859-1"
1614CONFIG_NLS_CODEPAGE_437=y
1615# CONFIG_NLS_CODEPAGE_737 is not set
1616# CONFIG_NLS_CODEPAGE_775 is not set
1617# CONFIG_NLS_CODEPAGE_850 is not set
1618# CONFIG_NLS_CODEPAGE_852 is not set
1619# CONFIG_NLS_CODEPAGE_855 is not set
1620# CONFIG_NLS_CODEPAGE_857 is not set
1621# CONFIG_NLS_CODEPAGE_860 is not set
1622# CONFIG_NLS_CODEPAGE_861 is not set
1623# CONFIG_NLS_CODEPAGE_862 is not set
1624# CONFIG_NLS_CODEPAGE_863 is not set
1625# CONFIG_NLS_CODEPAGE_864 is not set
1626# CONFIG_NLS_CODEPAGE_865 is not set
1627# CONFIG_NLS_CODEPAGE_866 is not set
1628# CONFIG_NLS_CODEPAGE_869 is not set
1629# CONFIG_NLS_CODEPAGE_936 is not set
1630# CONFIG_NLS_CODEPAGE_950 is not set
1631# CONFIG_NLS_CODEPAGE_932 is not set
1632# CONFIG_NLS_CODEPAGE_949 is not set
1633# CONFIG_NLS_CODEPAGE_874 is not set
1634# CONFIG_NLS_ISO8859_8 is not set
1635# CONFIG_NLS_CODEPAGE_1250 is not set
1636# CONFIG_NLS_CODEPAGE_1251 is not set
1637# CONFIG_NLS_ASCII is not set
1638CONFIG_NLS_ISO8859_1=y
1639# CONFIG_NLS_ISO8859_2 is not set
1640# CONFIG_NLS_ISO8859_3 is not set
1641# CONFIG_NLS_ISO8859_4 is not set
1642# CONFIG_NLS_ISO8859_5 is not set
1643# CONFIG_NLS_ISO8859_6 is not set
1644# CONFIG_NLS_ISO8859_7 is not set
1645# CONFIG_NLS_ISO8859_9 is not set
1646# CONFIG_NLS_ISO8859_13 is not set
1647# CONFIG_NLS_ISO8859_14 is not set
1648# CONFIG_NLS_ISO8859_15 is not set
1649# CONFIG_NLS_KOI8_R is not set
1650# CONFIG_NLS_KOI8_U is not set
1651# CONFIG_NLS_UTF8 is not set
1652
1653#
1654# Distributed Lock Manager
1655#
1656# CONFIG_DLM is not set
1657CONFIG_INSTRUMENTATION=y
1658CONFIG_PROFILING=y
1659CONFIG_OPROFILE=y
1660# CONFIG_KPROBES is not set
1661
1662#
1663# Kernel hacking
1664#
1665CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1666# CONFIG_PRINTK_TIME is not set
1667CONFIG_ENABLE_MUST_CHECK=y
1668# CONFIG_MAGIC_SYSRQ is not set
1669CONFIG_UNUSED_SYMBOLS=y
1670# CONFIG_DEBUG_FS is not set
1671# CONFIG_HEADERS_CHECK is not set
1672# CONFIG_DEBUG_KERNEL is not set
1673# CONFIG_DEBUG_BUGVERBOSE is not set
1674CONFIG_EARLY_PRINTK=y
1675CONFIG_X86_FIND_SMP_CONFIG=y
1676CONFIG_X86_MPPARSE=y
1677CONFIG_DOUBLEFAULT=y
1678
1679#
1680# Security options
1681#
1682# CONFIG_KEYS is not set
1683# CONFIG_SECURITY is not set
1684CONFIG_CRYPTO=y
1685CONFIG_CRYPTO_ALGAPI=m
1686CONFIG_CRYPTO_BLKCIPHER=m
1687CONFIG_CRYPTO_MANAGER=m
1688# CONFIG_CRYPTO_HMAC is not set
1689# CONFIG_CRYPTO_XCBC is not set
1690# CONFIG_CRYPTO_NULL is not set
1691# CONFIG_CRYPTO_MD4 is not set
1692# CONFIG_CRYPTO_MD5 is not set
1693CONFIG_CRYPTO_SHA1=m
1694CONFIG_CRYPTO_SHA256=m
1695# CONFIG_CRYPTO_SHA512 is not set
1696# CONFIG_CRYPTO_WP512 is not set
1697# CONFIG_CRYPTO_TGR192 is not set
1698# CONFIG_CRYPTO_GF128MUL is not set
1699CONFIG_CRYPTO_ECB=m
1700CONFIG_CRYPTO_CBC=m
1701CONFIG_CRYPTO_PCBC=m
1702# CONFIG_CRYPTO_LRW is not set
1703# CONFIG_CRYPTO_CRYPTD is not set
1704# CONFIG_CRYPTO_DES is not set
1705# CONFIG_CRYPTO_FCRYPT is not set
1706# CONFIG_CRYPTO_BLOWFISH is not set
1707# CONFIG_CRYPTO_TWOFISH is not set
1708# CONFIG_CRYPTO_TWOFISH_586 is not set
1709# CONFIG_CRYPTO_SERPENT is not set
1710# CONFIG_CRYPTO_AES is not set
1711# CONFIG_CRYPTO_AES_586 is not set
1712# CONFIG_CRYPTO_CAST5 is not set
1713# CONFIG_CRYPTO_CAST6 is not set
1714# CONFIG_CRYPTO_TEA is not set
1715# CONFIG_CRYPTO_ARC4 is not set
1716# CONFIG_CRYPTO_KHAZAD is not set
1717# CONFIG_CRYPTO_ANUBIS is not set
1718# CONFIG_CRYPTO_DEFLATE is not set
1719# CONFIG_CRYPTO_LZO is not set
1720# CONFIG_CRYPTO_MICHAEL_MIC is not set
1721# CONFIG_CRYPTO_CRC32C is not set
1722# CONFIG_CRYPTO_CAMELLIA is not set
1723# CONFIG_CRYPTO_TEST is not set
1724CONFIG_CRYPTO_HW=y
1725CONFIG_CRYPTO_DEV_PADLOCK=m
1726CONFIG_CRYPTO_DEV_PADLOCK_AES=m
1727CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
1728CONFIG_CRYPTO_DEV_GEODE=m
1729
1730#
1731# Library routines
1732#
1733CONFIG_BITREVERSE=y
1734# CONFIG_CRC_CCITT is not set
1735# CONFIG_CRC16 is not set
1736# CONFIG_CRC_ITU_T is not set
1737CONFIG_CRC32=y
1738# CONFIG_CRC7 is not set
1739CONFIG_LIBCRC32C=m
1740CONFIG_AUDIT_GENERIC=y
1741CONFIG_TEXTSEARCH=y
1742CONFIG_TEXTSEARCH_KMP=m
1743CONFIG_TEXTSEARCH_BM=m
1744CONFIG_TEXTSEARCH_FSM=m
1745CONFIG_PLIST=y
1746CONFIG_HAS_IOMEM=y
1747CONFIG_HAS_IOPORT=y
1748CONFIG_HAS_DMA=y
1749CONFIG_GENERIC_HARDIRQS=y
1750CONFIG_GENERIC_IRQ_PROBE=y
1751CONFIG_GENERIC_PENDING_IRQ=y
1752CONFIG_X86_SMP=y
1753CONFIG_X86_HT=y
1754CONFIG_X86_BIOS_REBOOT=y
1755CONFIG_X86_TRAMPOLINE=y
1756CONFIG_KTIME_SCALAR=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-spitz b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-spitz
new file mode 100644
index 0000000000..d3512f2a4b
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-spitz
@@ -0,0 +1,1741 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Thu Dec 27 17:03:44 2007
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_LOCK_KERNEL=y
35CONFIG_INIT_ENV_ARG_LIMIT=32
36CONFIG_LOCALVERSION=""
37# CONFIG_LOCALVERSION_AUTO is not set
38CONFIG_SWAP=y
39CONFIG_SYSVIPC=y
40CONFIG_SYSVIPC_SYSCTL=y
41# CONFIG_POSIX_MQUEUE is not set
42CONFIG_BSD_PROCESS_ACCT=y
43CONFIG_BSD_PROCESS_ACCT_V3=y
44# CONFIG_TASKSTATS is not set
45# CONFIG_USER_NS is not set
46# CONFIG_AUDIT is not set
47# CONFIG_IKCONFIG is not set
48CONFIG_LOG_BUF_SHIFT=14
49CONFIG_SYSFS_DEPRECATED=y
50# CONFIG_RELAY is not set
51# CONFIG_BLK_DEV_INITRD is not set
52CONFIG_CC_OPTIMIZE_FOR_SIZE=y
53CONFIG_SYSCTL=y
54CONFIG_EMBEDDED=y
55CONFIG_UID16=y
56CONFIG_SYSCTL_SYSCALL=y
57CONFIG_KALLSYMS=y
58# CONFIG_KALLSYMS_ALL is not set
59# CONFIG_KALLSYMS_EXTRA_PASS is not set
60CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y
62CONFIG_BUG=y
63CONFIG_ELF_CORE=y
64CONFIG_BASE_FULL=y
65CONFIG_FUTEX=y
66CONFIG_ANON_INODES=y
67CONFIG_EPOLL=y
68CONFIG_SIGNALFD=y
69CONFIG_EVENTFD=y
70CONFIG_SHMEM=y
71CONFIG_VM_EVENT_COUNTERS=y
72CONFIG_SLAB=y
73# CONFIG_SLUB is not set
74# CONFIG_SLOB is not set
75CONFIG_RT_MUTEXES=y
76# CONFIG_TINY_SHMEM is not set
77CONFIG_BASE_SMALL=0
78CONFIG_MODULES=y
79CONFIG_MODULE_UNLOAD=y
80CONFIG_MODULE_FORCE_UNLOAD=y
81# CONFIG_MODVERSIONS is not set
82# CONFIG_MODULE_SRCVERSION_ALL is not set
83CONFIG_KMOD=y
84CONFIG_BLOCK=y
85# CONFIG_LBD is not set
86# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set
88# CONFIG_BLK_DEV_BSG is not set
89
90#
91# IO Schedulers
92#
93CONFIG_IOSCHED_NOOP=y
94CONFIG_IOSCHED_AS=y
95CONFIG_IOSCHED_DEADLINE=m
96CONFIG_IOSCHED_CFQ=m
97CONFIG_DEFAULT_AS=y
98# CONFIG_DEFAULT_DEADLINE is not set
99# CONFIG_DEFAULT_CFQ is not set
100# CONFIG_DEFAULT_NOOP is not set
101CONFIG_DEFAULT_IOSCHED="anticipatory"
102
103#
104# System Type
105#
106# CONFIG_ARCH_AAEC2000 is not set
107# CONFIG_ARCH_INTEGRATOR is not set
108# CONFIG_ARCH_REALVIEW is not set
109# CONFIG_ARCH_VERSATILE is not set
110# CONFIG_ARCH_AT91 is not set
111# CONFIG_ARCH_CLPS7500 is not set
112# CONFIG_ARCH_CLPS711X is not set
113# CONFIG_ARCH_CO285 is not set
114# CONFIG_ARCH_EBSA110 is not set
115# CONFIG_ARCH_EP93XX is not set
116# CONFIG_ARCH_FOOTBRIDGE is not set
117# CONFIG_ARCH_NETX is not set
118# CONFIG_ARCH_H720X is not set
119# CONFIG_ARCH_IMX is not set
120# CONFIG_ARCH_IOP13XX is not set
121# CONFIG_ARCH_IOP32X is not set
122# CONFIG_ARCH_IOP33X is not set
123# CONFIG_ARCH_IXP23XX is not set
124# CONFIG_ARCH_IXP2000 is not set
125# CONFIG_ARCH_IXP4XX is not set
126# CONFIG_ARCH_L7200 is not set
127# CONFIG_ARCH_KS8695 is not set
128# CONFIG_ARCH_NS9XXX is not set
129# CONFIG_ARCH_MXC is not set
130# CONFIG_ARCH_PNX4008 is not set
131CONFIG_ARCH_PXA=y
132# CONFIG_ARCH_RPC is not set
133# CONFIG_ARCH_SA1100 is not set
134# CONFIG_ARCH_S3C2410 is not set
135# CONFIG_ARCH_SHARK is not set
136# CONFIG_ARCH_LH7A40X is not set
137# CONFIG_ARCH_DAVINCI is not set
138# CONFIG_ARCH_OMAP is not set
139
140#
141# Intel PXA2xx Implementations
142#
143# CONFIG_ARCH_LUBBOCK is not set
144# CONFIG_MACH_LOGICPD_PXA270 is not set
145# CONFIG_MACH_MAINSTONE is not set
146# CONFIG_ARCH_PXA_IDP is not set
147CONFIG_PXA_SHARPSL=y
148# CONFIG_MACH_TRIZEPS4 is not set
149# CONFIG_MACH_EM_X270 is not set
150# CONFIG_MACH_HX2750 is not set
151# CONFIG_MACH_HTCUNIVERSAL is not set
152# CONFIG_PXA_SHARPSL_25x is not set
153CONFIG_PXA_SHARPSL_27x=y
154CONFIG_MACH_AKITA=y
155CONFIG_MACH_SPITZ=y
156CONFIG_MACH_BORZOI=y
157CONFIG_PXA27x=y
158CONFIG_PXA_SHARP_Cxx00=y
159CONFIG_PXA_SSP=y
160# CONFIG_PXA_KEYS is not set
161
162#
163# Boot options
164#
165
166#
167# Power management
168#
169
170#
171# Processor Type
172#
173CONFIG_CPU_32=y
174CONFIG_CPU_XSCALE=y
175CONFIG_CPU_32v5=y
176CONFIG_CPU_ABRT_EV5T=y
177CONFIG_CPU_CACHE_VIVT=y
178CONFIG_CPU_TLB_V4WBI=y
179CONFIG_CPU_CP15=y
180CONFIG_CPU_CP15_MMU=y
181
182#
183# Processor Features
184#
185CONFIG_ARM_THUMB=y
186# CONFIG_CPU_DCACHE_DISABLE is not set
187# CONFIG_OUTER_CACHE is not set
188CONFIG_IWMMXT=y
189CONFIG_XSCALE_PMU=y
190CONFIG_SHARP_PARAM=y
191CONFIG_SHARPSL_PM=y
192CONFIG_SHARP_SCOOP=y
193
194#
195# Bus support
196#
197# CONFIG_PCI_SYSCALL is not set
198# CONFIG_ARCH_SUPPORTS_MSI is not set
199
200#
201# PCCARD (PCMCIA/CardBus) support
202#
203CONFIG_PCCARD=y
204# CONFIG_PCMCIA_DEBUG is not set
205CONFIG_PCMCIA=y
206CONFIG_PCMCIA_LOAD_CIS=y
207CONFIG_PCMCIA_IOCTL=y
208
209#
210# PC-card bridges
211#
212CONFIG_PCMCIA_PXA2XX=y
213
214#
215# Kernel Features
216#
217# CONFIG_TICK_ONESHOT is not set
218# CONFIG_NO_HZ is not set
219# CONFIG_HIGH_RES_TIMERS is not set
220CONFIG_PREEMPT=y
221CONFIG_HZ=100
222CONFIG_AEABI=y
223CONFIG_OABI_COMPAT=y
224# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
225CONFIG_SELECT_MEMORY_MODEL=y
226CONFIG_FLATMEM_MANUAL=y
227# CONFIG_DISCONTIGMEM_MANUAL is not set
228# CONFIG_SPARSEMEM_MANUAL is not set
229CONFIG_FLATMEM=y
230CONFIG_FLAT_NODE_MEM_MAP=y
231# CONFIG_SPARSEMEM_STATIC is not set
232CONFIG_SPLIT_PTLOCK_CPUS=4096
233# CONFIG_RESOURCES_64BIT is not set
234CONFIG_ZONE_DMA_FLAG=1
235CONFIG_BOUNCE=y
236CONFIG_VIRT_TO_BUS=y
237CONFIG_ALIGNMENT_TRAP=y
238
239#
240# Boot options
241#
242CONFIG_ZBOOT_ROM_TEXT=0x0
243CONFIG_ZBOOT_ROM_BSS=0x0
244CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/hda1 rootfstype=ext3 rootdelay=1 rw fbcon=rotate:1 dyntick=enable debug"
245# CONFIG_XIP_KERNEL is not set
246CONFIG_KEXEC=y
247CONFIG_ATAGS_PROC=y
248
249#
250# CPU Frequency scaling
251#
252# CONFIG_CPU_FREQ is not set
253
254#
255# Floating point emulation
256#
257
258#
259# At least one emulation must be selected
260#
261CONFIG_FPE_NWFPE=y
262# CONFIG_FPE_NWFPE_XP is not set
263# CONFIG_FPE_FASTFPE is not set
264
265#
266# Userspace binary formats
267#
268CONFIG_BINFMT_ELF=y
269CONFIG_BINFMT_AOUT=m
270CONFIG_BINFMT_MISC=m
271
272#
273# Power management options
274#
275CONFIG_PM=y
276# CONFIG_PM_LEGACY is not set
277# CONFIG_PM_DEBUG is not set
278CONFIG_PM_SLEEP=y
279CONFIG_SUSPEND_UP_POSSIBLE=y
280CONFIG_SUSPEND=y
281CONFIG_APM_EMULATION=y
282
283#
284# Networking
285#
286CONFIG_NET=y
287
288#
289# Networking options
290#
291CONFIG_PACKET=m
292CONFIG_PACKET_MMAP=y
293CONFIG_UNIX=y
294CONFIG_XFRM=y
295# CONFIG_XFRM_USER is not set
296# CONFIG_XFRM_SUB_POLICY is not set
297# CONFIG_XFRM_MIGRATE is not set
298# CONFIG_NET_KEY is not set
299CONFIG_INET=y
300# CONFIG_IP_MULTICAST is not set
301# CONFIG_IP_ADVANCED_ROUTER is not set
302CONFIG_IP_FIB_HASH=y
303# CONFIG_IP_PNP is not set
304# CONFIG_NET_IPIP is not set
305# CONFIG_NET_IPGRE is not set
306# CONFIG_ARPD is not set
307CONFIG_SYN_COOKIES=y
308# CONFIG_INET_AH is not set
309# CONFIG_INET_ESP is not set
310# CONFIG_INET_IPCOMP is not set
311# CONFIG_INET_XFRM_TUNNEL is not set
312CONFIG_INET_TUNNEL=m
313CONFIG_INET_XFRM_MODE_TRANSPORT=y
314CONFIG_INET_XFRM_MODE_TUNNEL=y
315CONFIG_INET_XFRM_MODE_BEET=y
316CONFIG_INET_DIAG=m
317CONFIG_INET_TCP_DIAG=m
318# CONFIG_TCP_CONG_ADVANCED is not set
319CONFIG_TCP_CONG_CUBIC=y
320CONFIG_DEFAULT_TCP_CONG="cubic"
321# CONFIG_TCP_MD5SIG is not set
322# CONFIG_IP_VS is not set
323CONFIG_IPV6=m
324# CONFIG_IPV6_PRIVACY is not set
325# CONFIG_IPV6_ROUTER_PREF is not set
326# CONFIG_IPV6_OPTIMISTIC_DAD is not set
327CONFIG_INET6_AH=m
328CONFIG_INET6_ESP=m
329CONFIG_INET6_IPCOMP=m
330# CONFIG_IPV6_MIP6 is not set
331CONFIG_INET6_XFRM_TUNNEL=m
332CONFIG_INET6_TUNNEL=m
333CONFIG_INET6_XFRM_MODE_TRANSPORT=m
334CONFIG_INET6_XFRM_MODE_TUNNEL=m
335CONFIG_INET6_XFRM_MODE_BEET=m
336# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
337CONFIG_IPV6_SIT=m
338CONFIG_IPV6_TUNNEL=m
339# CONFIG_IPV6_MULTIPLE_TABLES is not set
340# CONFIG_NETWORK_SECMARK is not set
341CONFIG_NETFILTER=y
342# CONFIG_NETFILTER_DEBUG is not set
343
344#
345# Core Netfilter Configuration
346#
347# CONFIG_NETFILTER_NETLINK is not set
348# CONFIG_NF_CONNTRACK_ENABLED is not set
349# CONFIG_NF_CONNTRACK is not set
350CONFIG_NETFILTER_XTABLES=m
351# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
352# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
353# CONFIG_NETFILTER_XT_TARGET_MARK is not set
354# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
355# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
356# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
357# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
358# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
359# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
360# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
361# CONFIG_NETFILTER_XT_MATCH_ESP is not set
362# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
363# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
364# CONFIG_NETFILTER_XT_MATCH_MAC is not set
365# CONFIG_NETFILTER_XT_MATCH_MARK is not set
366# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
367# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
368# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
369# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
370# CONFIG_NETFILTER_XT_MATCH_REALM is not set
371# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
372# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
373# CONFIG_NETFILTER_XT_MATCH_STRING is not set
374# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
375# CONFIG_NETFILTER_XT_MATCH_U32 is not set
376# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
377
378#
379# IP: Netfilter Configuration
380#
381CONFIG_IP_NF_QUEUE=m
382CONFIG_IP_NF_IPTABLES=m
383CONFIG_IP_NF_MATCH_IPRANGE=m
384CONFIG_IP_NF_MATCH_TOS=m
385CONFIG_IP_NF_MATCH_RECENT=m
386CONFIG_IP_NF_MATCH_ECN=m
387CONFIG_IP_NF_MATCH_AH=m
388CONFIG_IP_NF_MATCH_TTL=m
389CONFIG_IP_NF_MATCH_OWNER=m
390CONFIG_IP_NF_MATCH_ADDRTYPE=m
391CONFIG_IP_NF_FILTER=m
392CONFIG_IP_NF_TARGET_REJECT=m
393CONFIG_IP_NF_TARGET_LOG=m
394CONFIG_IP_NF_TARGET_ULOG=m
395CONFIG_IP_NF_MANGLE=m
396CONFIG_IP_NF_TARGET_TOS=m
397CONFIG_IP_NF_TARGET_ECN=m
398CONFIG_IP_NF_TARGET_TTL=m
399CONFIG_IP_NF_RAW=m
400CONFIG_IP_NF_ARPTABLES=m
401CONFIG_IP_NF_ARPFILTER=m
402CONFIG_IP_NF_ARP_MANGLE=m
403
404#
405# IPv6: Netfilter Configuration (EXPERIMENTAL)
406#
407# CONFIG_IP6_NF_QUEUE is not set
408# CONFIG_IP6_NF_IPTABLES is not set
409# CONFIG_IP_DCCP is not set
410# CONFIG_IP_SCTP is not set
411# CONFIG_TIPC is not set
412# CONFIG_ATM is not set
413# CONFIG_BRIDGE is not set
414# CONFIG_VLAN_8021Q is not set
415# CONFIG_DECNET is not set
416# CONFIG_LLC2 is not set
417# CONFIG_IPX is not set
418# CONFIG_ATALK is not set
419# CONFIG_X25 is not set
420# CONFIG_LAPB is not set
421# CONFIG_ECONET is not set
422# CONFIG_WAN_ROUTER is not set
423
424#
425# QoS and/or fair queueing
426#
427# CONFIG_NET_SCHED is not set
428
429#
430# Network testing
431#
432# CONFIG_NET_PKTGEN is not set
433# CONFIG_HAMRADIO is not set
434CONFIG_IRDA=m
435
436#
437# IrDA protocols
438#
439CONFIG_IRLAN=m
440CONFIG_IRNET=m
441CONFIG_IRCOMM=m
442# CONFIG_IRDA_ULTRA is not set
443
444#
445# IrDA options
446#
447# CONFIG_IRDA_CACHE_LAST_LSAP is not set
448# CONFIG_IRDA_FAST_RR is not set
449# CONFIG_IRDA_DEBUG is not set
450
451#
452# Infrared-port device drivers
453#
454
455#
456# SIR device drivers
457#
458# CONFIG_IRTTY_SIR is not set
459
460#
461# Dongle support
462#
463# CONFIG_KINGSUN_DONGLE is not set
464
465#
466# Old SIR device drivers
467#
468# CONFIG_IRPORT_SIR is not set
469
470#
471# Old Serial dongle support
472#
473
474#
475# FIR device drivers
476#
477# CONFIG_USB_IRDA is not set
478# CONFIG_SIGMATEL_FIR is not set
479CONFIG_PXA_FICP=m
480# CONFIG_MCS_FIR is not set
481CONFIG_BT=m
482CONFIG_BT_L2CAP=m
483CONFIG_BT_SCO=m
484CONFIG_BT_RFCOMM=m
485CONFIG_BT_RFCOMM_TTY=y
486CONFIG_BT_BNEP=m
487CONFIG_BT_BNEP_MC_FILTER=y
488CONFIG_BT_BNEP_PROTO_FILTER=y
489CONFIG_BT_HIDP=m
490
491#
492# Bluetooth device drivers
493#
494CONFIG_BT_HCIUSB=m
495# CONFIG_BT_HCIUSB_SCO is not set
496CONFIG_BT_HCIUART=m
497CONFIG_BT_HCIUART_H4=y
498CONFIG_BT_HCIUART_BCSP=y
499CONFIG_BT_HCIBCM203X=m
500CONFIG_BT_HCIBPA10X=m
501CONFIG_BT_HCIBFUSB=m
502CONFIG_BT_HCIDTL1=m
503CONFIG_BT_HCIBT3C=m
504CONFIG_BT_HCIBLUECARD=m
505CONFIG_BT_HCIBTUART=m
506CONFIG_BT_HCIVHCI=m
507# CONFIG_AF_RXRPC is not set
508
509#
510# Wireless
511#
512# CONFIG_CFG80211 is not set
513CONFIG_WIRELESS_EXT=y
514# CONFIG_MAC80211 is not set
515CONFIG_IEEE80211=m
516# CONFIG_IEEE80211_DEBUG is not set
517CONFIG_IEEE80211_CRYPT_WEP=m
518CONFIG_IEEE80211_CRYPT_CCMP=m
519CONFIG_IEEE80211_CRYPT_TKIP=m
520# CONFIG_IEEE80211_SOFTMAC is not set
521# CONFIG_RFKILL is not set
522# CONFIG_NET_9P is not set
523
524#
525# Device Drivers
526#
527
528#
529# Generic Driver Options
530#
531CONFIG_STANDALONE=y
532CONFIG_PREVENT_FIRMWARE_BUILD=y
533CONFIG_FW_LOADER=y
534# CONFIG_DEBUG_DRIVER is not set
535# CONFIG_DEBUG_DEVRES is not set
536# CONFIG_SYS_HYPERVISOR is not set
537# CONFIG_CONNECTOR is not set
538CONFIG_MTD=m
539# CONFIG_MTD_DEBUG is not set
540# CONFIG_MTD_CONCAT is not set
541CONFIG_MTD_PARTITIONS=y
542# CONFIG_MTD_REDBOOT_PARTS is not set
543# CONFIG_MTD_AFS_PARTS is not set
544
545#
546# User Modules And Translation Layers
547#
548CONFIG_MTD_CHAR=m
549CONFIG_MTD_BLKDEVS=m
550CONFIG_MTD_BLOCK=m
551# CONFIG_MTD_BLOCK_RO is not set
552# CONFIG_FTL is not set
553# CONFIG_NFTL is not set
554# CONFIG_INFTL is not set
555# CONFIG_RFD_FTL is not set
556# CONFIG_SSFDC is not set
557
558#
559# RAM/ROM/Flash chip drivers
560#
561# CONFIG_MTD_CFI is not set
562# CONFIG_MTD_JEDECPROBE is not set
563CONFIG_MTD_MAP_BANK_WIDTH_1=y
564CONFIG_MTD_MAP_BANK_WIDTH_2=y
565CONFIG_MTD_MAP_BANK_WIDTH_4=y
566# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
567# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
568# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
569CONFIG_MTD_CFI_I1=y
570CONFIG_MTD_CFI_I2=y
571# CONFIG_MTD_CFI_I4 is not set
572# CONFIG_MTD_CFI_I8 is not set
573# CONFIG_MTD_RAM is not set
574CONFIG_MTD_ROM=m
575# CONFIG_MTD_ABSENT is not set
576
577#
578# Mapping drivers for chip access
579#
580CONFIG_MTD_COMPLEX_MAPPINGS=y
581# CONFIG_MTD_PHYSMAP is not set
582CONFIG_MTD_SHARP_SL=m
583# CONFIG_MTD_PLATRAM is not set
584
585#
586# Self-contained MTD device drivers
587#
588# CONFIG_MTD_SLRAM is not set
589# CONFIG_MTD_PHRAM is not set
590# CONFIG_MTD_MTDRAM is not set
591# CONFIG_MTD_BLOCK2MTD is not set
592
593#
594# Disk-On-Chip Device Drivers
595#
596# CONFIG_MTD_DOC2000 is not set
597# CONFIG_MTD_DOC2001 is not set
598# CONFIG_MTD_DOC2001PLUS is not set
599CONFIG_MTD_NAND=m
600CONFIG_MTD_NAND_VERIFY_WRITE=y
601# CONFIG_MTD_NAND_ECC_SMC is not set
602# CONFIG_MTD_NAND_MUSEUM_IDS is not set
603# CONFIG_MTD_NAND_H1900 is not set
604CONFIG_MTD_NAND_IDS=m
605# CONFIG_MTD_NAND_DISKONCHIP is not set
606CONFIG_MTD_NAND_SHARPSL=m
607# CONFIG_MTD_NAND_NANDSIM is not set
608# CONFIG_MTD_NAND_PLATFORM is not set
609# CONFIG_MTD_ONENAND is not set
610
611#
612# UBI - Unsorted block images
613#
614# CONFIG_MTD_UBI is not set
615# CONFIG_PARPORT is not set
616CONFIG_BLK_DEV=y
617# CONFIG_BLK_DEV_COW_COMMON is not set
618CONFIG_BLK_DEV_LOOP=y
619# CONFIG_BLK_DEV_CRYPTOLOOP is not set
620# CONFIG_BLK_DEV_NBD is not set
621# CONFIG_BLK_DEV_UB is not set
622# CONFIG_BLK_DEV_RAM is not set
623# CONFIG_CDROM_PKTCDVD is not set
624# CONFIG_ATA_OVER_ETH is not set
625CONFIG_IDE=y
626CONFIG_IDE_MAX_HWIFS=4
627CONFIG_BLK_DEV_IDE=y
628
629#
630# Please see Documentation/ide.txt for help/info on IDE drives
631#
632# CONFIG_BLK_DEV_IDE_SATA is not set
633CONFIG_BLK_DEV_IDEDISK=y
634# CONFIG_IDEDISK_MULTI_MODE is not set
635CONFIG_BLK_DEV_IDECS=y
636# CONFIG_BLK_DEV_IDECD is not set
637# CONFIG_BLK_DEV_IDETAPE is not set
638# CONFIG_BLK_DEV_IDEFLOPPY is not set
639# CONFIG_BLK_DEV_IDESCSI is not set
640# CONFIG_IDE_TASK_IOCTL is not set
641CONFIG_IDE_PROC_FS=y
642
643#
644# IDE chipset support/bugfixes
645#
646CONFIG_IDE_GENERIC=y
647# CONFIG_IDEPCI_PCIBUS_ORDER is not set
648# CONFIG_IDE_ARM is not set
649# CONFIG_BLK_DEV_IDEDMA is not set
650# CONFIG_BLK_DEV_HD is not set
651
652#
653# SCSI device support
654#
655# CONFIG_RAID_ATTRS is not set
656CONFIG_SCSI=m
657CONFIG_SCSI_DMA=y
658# CONFIG_SCSI_TGT is not set
659# CONFIG_SCSI_NETLINK is not set
660CONFIG_SCSI_PROC_FS=y
661
662#
663# SCSI support type (disk, tape, CD-ROM)
664#
665CONFIG_BLK_DEV_SD=m
666CONFIG_CHR_DEV_ST=m
667CONFIG_CHR_DEV_OSST=m
668CONFIG_BLK_DEV_SR=m
669# CONFIG_BLK_DEV_SR_VENDOR is not set
670CONFIG_CHR_DEV_SG=m
671# CONFIG_CHR_DEV_SCH is not set
672
673#
674# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
675#
676CONFIG_SCSI_MULTI_LUN=y
677# CONFIG_SCSI_CONSTANTS is not set
678# CONFIG_SCSI_LOGGING is not set
679# CONFIG_SCSI_SCAN_ASYNC is not set
680CONFIG_SCSI_WAIT_SCAN=m
681
682#
683# SCSI Transports
684#
685# CONFIG_SCSI_SPI_ATTRS is not set
686# CONFIG_SCSI_FC_ATTRS is not set
687# CONFIG_SCSI_ISCSI_ATTRS is not set
688# CONFIG_SCSI_SAS_LIBSAS is not set
689CONFIG_SCSI_LOWLEVEL=y
690# CONFIG_ISCSI_TCP is not set
691# CONFIG_SCSI_DEBUG is not set
692# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
693# CONFIG_ATA is not set
694CONFIG_MD=y
695# CONFIG_BLK_DEV_MD is not set
696CONFIG_BLK_DEV_DM=m
697# CONFIG_DM_DEBUG is not set
698CONFIG_DM_CRYPT=m
699CONFIG_DM_SNAPSHOT=m
700CONFIG_DM_MIRROR=m
701CONFIG_DM_ZERO=m
702CONFIG_DM_MULTIPATH=m
703CONFIG_DM_MULTIPATH_EMC=m
704# CONFIG_DM_MULTIPATH_RDAC is not set
705# CONFIG_DM_DELAY is not set
706CONFIG_NETDEVICES=y
707# CONFIG_NETDEVICES_MULTIQUEUE is not set
708# CONFIG_DUMMY is not set
709# CONFIG_BONDING is not set
710# CONFIG_MACVLAN is not set
711# CONFIG_EQUALIZER is not set
712CONFIG_TUN=m
713# CONFIG_PHYLIB is not set
714CONFIG_NET_ETHERNET=y
715CONFIG_MII=m
716# CONFIG_AX88796 is not set
717# CONFIG_SMC91X is not set
718# CONFIG_DM9000 is not set
719# CONFIG_SMC911X is not set
720CONFIG_NETDEV_1000=y
721CONFIG_NETDEV_10000=y
722
723#
724# Wireless LAN
725#
726CONFIG_WLAN_PRE80211=y
727# CONFIG_STRIP is not set
728# CONFIG_PCMCIA_WAVELAN is not set
729# CONFIG_PCMCIA_NETWAVE is not set
730CONFIG_WLAN_80211=y
731# CONFIG_PCMCIA_RAYCS is not set
732# CONFIG_LIBERTAS is not set
733CONFIG_HERMES=m
734# CONFIG_ATMEL is not set
735CONFIG_PCMCIA_HERMES=m
736CONFIG_PCMCIA_SPECTRUM=m
737CONFIG_AIRO_CS=m
738# CONFIG_PCMCIA_WL3501 is not set
739# CONFIG_USB_ZD1201 is not set
740CONFIG_HOSTAP=m
741CONFIG_HOSTAP_FIRMWARE=y
742# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
743CONFIG_HOSTAP_CS=m
744
745#
746# USB Network Adapters
747#
748CONFIG_USB_CATC=m
749CONFIG_USB_KAWETH=m
750CONFIG_USB_PEGASUS=m
751CONFIG_USB_RTL8150=m
752CONFIG_USB_USBNET_MII=m
753CONFIG_USB_USBNET=m
754CONFIG_USB_NET_AX8817X=m
755CONFIG_USB_NET_CDCETHER=m
756# CONFIG_USB_NET_DM9601 is not set
757# CONFIG_USB_NET_GL620A is not set
758CONFIG_USB_NET_NET1080=m
759# CONFIG_USB_NET_PLUSB is not set
760# CONFIG_USB_NET_MCS7830 is not set
761# CONFIG_USB_NET_RNDIS_HOST is not set
762# CONFIG_USB_NET_CDC_SUBSET is not set
763CONFIG_USB_NET_ZAURUS=m
764CONFIG_NET_PCMCIA=y
765# CONFIG_PCMCIA_3C589 is not set
766# CONFIG_PCMCIA_3C574 is not set
767# CONFIG_PCMCIA_FMVJ18X is not set
768CONFIG_PCMCIA_PCNET=m
769# CONFIG_PCMCIA_NMCLAN is not set
770# CONFIG_PCMCIA_SMC91C92 is not set
771# CONFIG_PCMCIA_XIRC2PS is not set
772# CONFIG_PCMCIA_AXNET is not set
773# CONFIG_WAN is not set
774CONFIG_PPP=m
775# CONFIG_PPP_MULTILINK is not set
776# CONFIG_PPP_FILTER is not set
777CONFIG_PPP_ASYNC=m
778# CONFIG_PPP_SYNC_TTY is not set
779CONFIG_PPP_DEFLATE=m
780CONFIG_PPP_BSDCOMP=m
781# CONFIG_PPP_MPPE is not set
782# CONFIG_PPPOE is not set
783# CONFIG_PPPOL2TP is not set
784# CONFIG_SLIP is not set
785CONFIG_SLHC=m
786# CONFIG_SHAPER is not set
787# CONFIG_NETCONSOLE is not set
788# CONFIG_NETPOLL is not set
789# CONFIG_NET_POLL_CONTROLLER is not set
790# CONFIG_ISDN is not set
791
792#
793# Input device support
794#
795CONFIG_INPUT=y
796# CONFIG_INPUT_FF_MEMLESS is not set
797# CONFIG_INPUT_POLLDEV is not set
798
799#
800# Userland interfaces
801#
802CONFIG_INPUT_MOUSEDEV=m
803# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
804CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
805CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
806# CONFIG_INPUT_JOYDEV is not set
807# CONFIG_INPUT_TSDEV is not set
808CONFIG_INPUT_EVDEV=y
809# CONFIG_INPUT_EVBUG is not set
810CONFIG_INPUT_POWER=y
811
812#
813# Input Device Drivers
814#
815CONFIG_INPUT_KEYBOARD=y
816# CONFIG_KEYBOARD_ATKBD is not set
817# CONFIG_KEYBOARD_SUNKBD is not set
818# CONFIG_KEYBOARD_LKKBD is not set
819# CONFIG_KEYBOARD_XTKBD is not set
820# CONFIG_KEYBOARD_NEWTON is not set
821# CONFIG_KEYBOARD_STOWAWAY is not set
822# CONFIG_KEYBOARD_CORGI is not set
823CONFIG_KEYBOARD_SPITZ=y
824CONFIG_SHARPSL_RC=m
825# CONFIG_KEYBOARD_PXA27x is not set
826# CONFIG_KEYBOARD_GPIO is not set
827# CONFIG_INPUT_MOUSE is not set
828# CONFIG_INPUT_JOYSTICK is not set
829# CONFIG_INPUT_TABLET is not set
830CONFIG_INPUT_TOUCHSCREEN=y
831CONFIG_TOUCHSCREEN_CORGI=y
832# CONFIG_TOUCHSCREEN_FUJITSU is not set
833# CONFIG_TOUCHSCREEN_GUNZE is not set
834# CONFIG_TOUCHSCREEN_ELO is not set
835# CONFIG_TOUCHSCREEN_MTOUCH is not set
836# CONFIG_TOUCHSCREEN_MK712 is not set
837# CONFIG_TOUCHSCREEN_PENMOUNT is not set
838# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
839# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
840# CONFIG_TOUCHSCREEN_UCB1400 is not set
841# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
842CONFIG_INPUT_MISC=y
843# CONFIG_INPUT_ATI_REMOTE is not set
844# CONFIG_INPUT_ATI_REMOTE2 is not set
845# CONFIG_INPUT_KEYSPAN_REMOTE is not set
846# CONFIG_INPUT_POWERMATE is not set
847# CONFIG_INPUT_YEALINK is not set
848CONFIG_INPUT_UINPUT=m
849
850#
851# Hardware I/O ports
852#
853# CONFIG_SERIO is not set
854# CONFIG_GAMEPORT is not set
855
856#
857# Character devices
858#
859CONFIG_VT=y
860CONFIG_VT_CONSOLE=y
861CONFIG_HW_CONSOLE=y
862# CONFIG_VT_HW_CONSOLE_BINDING is not set
863# CONFIG_SERIAL_NONSTANDARD is not set
864
865#
866# Serial drivers
867#
868CONFIG_SERIAL_8250=m
869CONFIG_SERIAL_8250_CS=m
870CONFIG_SERIAL_8250_NR_UARTS=4
871CONFIG_SERIAL_8250_RUNTIME_UARTS=4
872# CONFIG_SERIAL_8250_EXTENDED is not set
873
874#
875# Non-8250 serial port support
876#
877CONFIG_SERIAL_PXA=y
878CONFIG_SERIAL_PXA_CONSOLE=y
879CONFIG_SERIAL_CORE=y
880CONFIG_SERIAL_CORE_CONSOLE=y
881CONFIG_UNIX98_PTYS=y
882# CONFIG_LEGACY_PTYS is not set
883# CONFIG_IPMI_HANDLER is not set
884# CONFIG_WATCHDOG is not set
885CONFIG_HW_RANDOM=m
886# CONFIG_NVRAM is not set
887# CONFIG_R3964 is not set
888
889#
890# PCMCIA character devices
891#
892# CONFIG_SYNCLINK_CS is not set
893# CONFIG_CARDMAN_4000 is not set
894# CONFIG_CARDMAN_4040 is not set
895# CONFIG_RAW_DRIVER is not set
896# CONFIG_TCG_TPM is not set
897CONFIG_I2C=y
898CONFIG_I2C_BOARDINFO=y
899# CONFIG_I2C_CHARDEV is not set
900
901#
902# I2C Algorithms
903#
904# CONFIG_I2C_ALGOBIT is not set
905# CONFIG_I2C_ALGOPCF is not set
906# CONFIG_I2C_ALGOPCA is not set
907
908#
909# I2C Hardware Bus support
910#
911# CONFIG_I2C_GPIO is not set
912CONFIG_I2C_PXA=y
913# CONFIG_I2C_PXA_SLAVE is not set
914# CONFIG_I2C_OCORES is not set
915# CONFIG_I2C_PARPORT_LIGHT is not set
916# CONFIG_I2C_SIMTEC is not set
917# CONFIG_I2C_TAOS_EVM is not set
918# CONFIG_I2C_STUB is not set
919# CONFIG_I2C_TINY_USB is not set
920
921#
922# Miscellaneous I2C Chip support
923#
924# CONFIG_SENSORS_DS1337 is not set
925# CONFIG_SENSORS_DS1374 is not set
926# CONFIG_DS1682 is not set
927# CONFIG_SENSORS_EEPROM is not set
928# CONFIG_SENSORS_PCF8574 is not set
929# CONFIG_SENSORS_PCA9539 is not set
930# CONFIG_SENSORS_PCF8591 is not set
931# CONFIG_SENSORS_MAX6875 is not set
932# CONFIG_SENSORS_TSL2550 is not set
933# CONFIG_I2C_DEBUG_CORE is not set
934# CONFIG_I2C_DEBUG_ALGO is not set
935# CONFIG_I2C_DEBUG_BUS is not set
936# CONFIG_I2C_DEBUG_CHIP is not set
937
938#
939# SPI support
940#
941# CONFIG_SPI is not set
942# CONFIG_SPI_MASTER is not set
943# CONFIG_W1 is not set
944# CONFIG_POWER_SUPPLY is not set
945# CONFIG_HWMON is not set
946CONFIG_MISC_DEVICES=y
947# CONFIG_EEPROM_93CX6 is not set
948
949#
950# Multifunction device drivers
951#
952# CONFIG_MFD_SM501 is not set
953# CONFIG_HTC_ASIC3 is not set
954# CONFIG_HTC_ASIC3_DS1WM is not set
955
956#
957# Multi-Function Devices
958#
959CONFIG_NEW_LEDS=y
960CONFIG_LEDS_CLASS=y
961
962#
963# LED drivers
964#
965CONFIG_LEDS_SPITZ=y
966# CONFIG_LEDS_TOSA is not set
967# CONFIG_LEDS_GPIO is not set
968
969#
970# LED Triggers
971#
972CONFIG_LEDS_TRIGGERS=y
973CONFIG_LEDS_TRIGGER_TIMER=y
974CONFIG_LEDS_TRIGGER_IDE_DISK=y
975# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
976
977#
978# Multimedia devices
979#
980CONFIG_VIDEO_DEV=m
981CONFIG_VIDEO_V4L1=y
982CONFIG_VIDEO_V4L1_COMPAT=y
983CONFIG_VIDEO_V4L2=y
984CONFIG_VIDEO_CAPTURE_DRIVERS=y
985# CONFIG_VIDEO_ADV_DEBUG is not set
986CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
987# CONFIG_VIDEO_CPIA is not set
988# CONFIG_VIDEO_CPIA2 is not set
989# CONFIG_VIDEO_SAA5246A is not set
990# CONFIG_VIDEO_SAA5249 is not set
991# CONFIG_TUNER_3036 is not set
992# CONFIG_TUNER_TEA5761 is not set
993CONFIG_V4L_USB_DRIVERS=y
994# CONFIG_VIDEO_PVRUSB2 is not set
995# CONFIG_VIDEO_EM28XX is not set
996# CONFIG_VIDEO_USBVISION is not set
997# CONFIG_USB_VICAM is not set
998# CONFIG_USB_IBMCAM is not set
999# CONFIG_USB_KONICAWC is not set
1000# CONFIG_USB_QUICKCAM_MESSENGER is not set
1001# CONFIG_USB_ET61X251 is not set
1002# CONFIG_VIDEO_OVCAMCHIP is not set
1003# CONFIG_USB_W9968CF is not set
1004# CONFIG_USB_OV511 is not set
1005# CONFIG_USB_SE401 is not set
1006# CONFIG_USB_SN9C102 is not set
1007# CONFIG_USB_STV680 is not set
1008# CONFIG_USB_ZC0301 is not set
1009# CONFIG_USB_PWC is not set
1010# CONFIG_USB_ZR364XX is not set
1011CONFIG_RADIO_ADAPTERS=y
1012# CONFIG_USB_DSBR is not set
1013# CONFIG_DVB_CORE is not set
1014CONFIG_DAB=y
1015CONFIG_USB_DABUSB=m
1016
1017#
1018# Graphics support
1019#
1020CONFIG_BACKLIGHT_LCD_SUPPORT=y
1021CONFIG_LCD_CLASS_DEVICE=y
1022CONFIG_BACKLIGHT_CLASS_DEVICE=y
1023CONFIG_BACKLIGHT_CORGI=y
1024
1025#
1026# Display device support
1027#
1028# CONFIG_DISPLAY_SUPPORT is not set
1029# CONFIG_VGASTATE is not set
1030CONFIG_VIDEO_OUTPUT_CONTROL=m
1031CONFIG_FB=y
1032CONFIG_FIRMWARE_EDID=y
1033# CONFIG_FB_DDC is not set
1034CONFIG_FB_CFB_FILLRECT=y
1035CONFIG_FB_CFB_COPYAREA=y
1036CONFIG_FB_CFB_IMAGEBLIT=y
1037# CONFIG_FB_SYS_FILLRECT is not set
1038# CONFIG_FB_SYS_COPYAREA is not set
1039# CONFIG_FB_SYS_IMAGEBLIT is not set
1040# CONFIG_FB_SYS_FOPS is not set
1041CONFIG_FB_DEFERRED_IO=y
1042# CONFIG_FB_SVGALIB is not set
1043# CONFIG_FB_MACMODES is not set
1044# CONFIG_FB_BACKLIGHT is not set
1045# CONFIG_FB_MODE_HELPERS is not set
1046# CONFIG_FB_TILEBLITTING is not set
1047
1048#
1049# Frame buffer hardware drivers
1050#
1051# CONFIG_FB_S1D13XXX is not set
1052CONFIG_FB_PXA=y
1053CONFIG_FB_PXA_LCD_QVGA=y
1054# CONFIG_FB_PXA_LCD_VGA is not set
1055CONFIG_FB_PXA_OVERLAY=y
1056# CONFIG_FB_PXA_PARAMETERS is not set
1057# CONFIG_FB_MBX is not set
1058# CONFIG_FB_W100 is not set
1059# CONFIG_FB_VIRTUAL is not set
1060
1061#
1062# Console display driver support
1063#
1064# CONFIG_VGA_CONSOLE is not set
1065CONFIG_DUMMY_CONSOLE=y
1066CONFIG_FRAMEBUFFER_CONSOLE=y
1067# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1068CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
1069CONFIG_FONTS=y
1070# CONFIG_FONT_8x8 is not set
1071CONFIG_FONT_8x16=y
1072# CONFIG_FONT_6x11 is not set
1073# CONFIG_FONT_7x14 is not set
1074# CONFIG_FONT_PEARL_8x8 is not set
1075# CONFIG_FONT_ACORN_8x8 is not set
1076# CONFIG_FONT_MINI_4x6 is not set
1077# CONFIG_FONT_SUN8x16 is not set
1078# CONFIG_FONT_SUN12x22 is not set
1079# CONFIG_FONT_10x18 is not set
1080CONFIG_LOGO=y
1081CONFIG_LOGO_LINUX_MONO=y
1082CONFIG_LOGO_LINUX_VGA16=y
1083# CONFIG_LOGO_LINUX_CLUT224 is not set
1084CONFIG_LOGO_OHAND_CLUT224=y
1085# CONFIG_LOGO_OZ240_CLUT224 is not set
1086# CONFIG_LOGO_OZ480_CLUT224 is not set
1087# CONFIG_LOGO_OZ640_CLUT224 is not set
1088
1089#
1090# Sound
1091#
1092CONFIG_SOUND=m
1093
1094#
1095# Advanced Linux Sound Architecture
1096#
1097CONFIG_SND=m
1098CONFIG_SND_TIMER=m
1099CONFIG_SND_PCM=m
1100CONFIG_SND_HWDEP=m
1101CONFIG_SND_RAWMIDI=m
1102CONFIG_SND_SEQUENCER=m
1103# CONFIG_SND_SEQ_DUMMY is not set
1104CONFIG_SND_OSSEMUL=y
1105CONFIG_SND_MIXER_OSS=m
1106CONFIG_SND_PCM_OSS=m
1107CONFIG_SND_PCM_OSS_PLUGINS=y
1108# CONFIG_SND_SEQUENCER_OSS is not set
1109# CONFIG_SND_DYNAMIC_MINORS is not set
1110CONFIG_SND_SUPPORT_OLD_API=y
1111CONFIG_SND_VERBOSE_PROCFS=y
1112CONFIG_SND_VERBOSE_PRINTK=y
1113CONFIG_SND_DEBUG=y
1114# CONFIG_SND_DEBUG_DETECT is not set
1115# CONFIG_SND_PCM_XRUN_DEBUG is not set
1116
1117#
1118# Generic devices
1119#
1120CONFIG_SND_AC97_CODEC=m
1121# CONFIG_SND_DUMMY is not set
1122# CONFIG_SND_VIRMIDI is not set
1123# CONFIG_SND_MTPAV is not set
1124# CONFIG_SND_SERIAL_U16550 is not set
1125# CONFIG_SND_MPU401 is not set
1126
1127#
1128# ALSA ARM devices
1129#
1130CONFIG_SND_PXA2XX_PCM=m
1131CONFIG_SND_PXA2XX_AC97=m
1132
1133#
1134# USB devices
1135#
1136CONFIG_SND_USB_AUDIO=m
1137# CONFIG_SND_USB_CAIAQ is not set
1138
1139#
1140# PCMCIA devices
1141#
1142# CONFIG_SND_VXPOCKET is not set
1143# CONFIG_SND_PDAUDIOCF is not set
1144
1145#
1146# System on Chip audio support
1147#
1148CONFIG_SND_SOC=m
1149CONFIG_SND_PXA2XX_SOC=m
1150CONFIG_SND_PXA2XX_SOC_I2S=m
1151CONFIG_SND_PXA2XX_SOC_SPITZ=m
1152
1153#
1154# SoC Audio support for SuperH
1155#
1156CONFIG_SND_SOC_WM8750=m
1157
1158#
1159# Open Sound System
1160#
1161# CONFIG_SOUND_PRIME is not set
1162CONFIG_AC97_BUS=m
1163CONFIG_HID_SUPPORT=y
1164CONFIG_HID=m
1165# CONFIG_HID_DEBUG is not set
1166
1167#
1168# USB Input Devices
1169#
1170CONFIG_USB_HID=m
1171# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1172# CONFIG_HID_FF is not set
1173# CONFIG_USB_HIDDEV is not set
1174
1175#
1176# USB HID Boot Protocol drivers
1177#
1178CONFIG_USB_KBD=m
1179CONFIG_USB_MOUSE=m
1180CONFIG_USB_SUPPORT=y
1181CONFIG_USB_ARCH_HAS_HCD=y
1182CONFIG_USB_ARCH_HAS_OHCI=y
1183# CONFIG_USB_ARCH_HAS_EHCI is not set
1184CONFIG_USB=m
1185# CONFIG_USB_DEBUG is not set
1186
1187#
1188# Miscellaneous USB options
1189#
1190CONFIG_USB_DEVICEFS=y
1191CONFIG_USB_DEVICE_CLASS=y
1192# CONFIG_USB_DYNAMIC_MINORS is not set
1193# CONFIG_USB_SUSPEND is not set
1194# CONFIG_USB_PERSIST is not set
1195# CONFIG_USB_OTG is not set
1196
1197#
1198# USB Host Controller Drivers
1199#
1200# CONFIG_USB_ISP116X_HCD is not set
1201CONFIG_USB_OHCI_HCD=m
1202# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1203# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1204CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1205CONFIG_USB_SL811_HCD=m
1206CONFIG_USB_SL811_CS=m
1207# CONFIG_USB_R8A66597_HCD is not set
1208
1209#
1210# USB Device Class drivers
1211#
1212CONFIG_USB_ACM=m
1213CONFIG_USB_PRINTER=m
1214
1215#
1216# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1217#
1218
1219#
1220# may also be needed; see USB_STORAGE Help for more information
1221#
1222CONFIG_USB_STORAGE=m
1223# CONFIG_USB_STORAGE_DEBUG is not set
1224# CONFIG_USB_STORAGE_DATAFAB is not set
1225# CONFIG_USB_STORAGE_FREECOM is not set
1226# CONFIG_USB_STORAGE_ISD200 is not set
1227# CONFIG_USB_STORAGE_DPCM is not set
1228# CONFIG_USB_STORAGE_USBAT is not set
1229# CONFIG_USB_STORAGE_SDDR09 is not set
1230# CONFIG_USB_STORAGE_SDDR55 is not set
1231# CONFIG_USB_STORAGE_JUMPSHOT is not set
1232# CONFIG_USB_STORAGE_ALAUDA is not set
1233# CONFIG_USB_STORAGE_KARMA is not set
1234# CONFIG_USB_LIBUSUAL is not set
1235
1236#
1237# USB Imaging devices
1238#
1239CONFIG_USB_MDC800=m
1240CONFIG_USB_MICROTEK=m
1241CONFIG_USB_MON=y
1242
1243#
1244# USB port drivers
1245#
1246
1247#
1248# USB Serial Converter support
1249#
1250CONFIG_USB_SERIAL=m
1251CONFIG_USB_SERIAL_GENERIC=y
1252# CONFIG_USB_SERIAL_AIRCABLE is not set
1253# CONFIG_USB_SERIAL_AIRPRIME is not set
1254# CONFIG_USB_SERIAL_ARK3116 is not set
1255CONFIG_USB_SERIAL_BELKIN=m
1256# CONFIG_USB_SERIAL_WHITEHEAT is not set
1257CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1258# CONFIG_USB_SERIAL_CP2101 is not set
1259CONFIG_USB_SERIAL_CYPRESS_M8=m
1260CONFIG_USB_SERIAL_EMPEG=m
1261CONFIG_USB_SERIAL_FTDI_SIO=m
1262# CONFIG_USB_SERIAL_FUNSOFT is not set
1263CONFIG_USB_SERIAL_VISOR=m
1264CONFIG_USB_SERIAL_IPAQ=m
1265CONFIG_USB_SERIAL_IR=m
1266CONFIG_USB_SERIAL_EDGEPORT=m
1267CONFIG_USB_SERIAL_EDGEPORT_TI=m
1268CONFIG_USB_SERIAL_GARMIN=m
1269CONFIG_USB_SERIAL_IPW=m
1270CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1271CONFIG_USB_SERIAL_KEYSPAN=m
1272# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1273# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1274# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1275# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1276# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1277# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1278# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1279# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1280# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1281# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1282# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1283# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1284CONFIG_USB_SERIAL_KLSI=m
1285CONFIG_USB_SERIAL_KOBIL_SCT=m
1286CONFIG_USB_SERIAL_MCT_U232=m
1287# CONFIG_USB_SERIAL_MOS7720 is not set
1288# CONFIG_USB_SERIAL_MOS7840 is not set
1289# CONFIG_USB_SERIAL_NAVMAN is not set
1290CONFIG_USB_SERIAL_PL2303=m
1291# CONFIG_USB_SERIAL_OTI6858 is not set
1292# CONFIG_USB_SERIAL_HP4X is not set
1293CONFIG_USB_SERIAL_SAFE=m
1294# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1295# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1296CONFIG_USB_SERIAL_TI=m
1297CONFIG_USB_SERIAL_CYBERJACK=m
1298CONFIG_USB_SERIAL_XIRCOM=m
1299# CONFIG_USB_SERIAL_OPTION is not set
1300CONFIG_USB_SERIAL_OMNINET=m
1301# CONFIG_USB_SERIAL_DEBUG is not set
1302CONFIG_USB_EZUSB=y
1303
1304#
1305# USB Miscellaneous drivers
1306#
1307CONFIG_USB_EMI62=m
1308CONFIG_USB_EMI26=m
1309# CONFIG_USB_ADUTUX is not set
1310CONFIG_USB_AUERSWALD=m
1311CONFIG_USB_RIO500=m
1312CONFIG_USB_LEGOTOWER=m
1313CONFIG_USB_LCD=m
1314# CONFIG_USB_BERRY_CHARGE is not set
1315CONFIG_USB_LED=m
1316# CONFIG_USB_CYPRESS_CY7C63 is not set
1317CONFIG_USB_CYTHERM=m
1318# CONFIG_USB_PHIDGET is not set
1319CONFIG_USB_IDMOUSE=m
1320# CONFIG_USB_FTDI_ELAN is not set
1321# CONFIG_USB_APPLEDISPLAY is not set
1322# CONFIG_USB_LD is not set
1323# CONFIG_USB_TRANCEVIBRATOR is not set
1324# CONFIG_USB_IOWARRIOR is not set
1325# CONFIG_USB_TEST is not set
1326
1327#
1328# USB DSL modem support
1329#
1330
1331#
1332# USB Gadget Support
1333#
1334CONFIG_USB_GADGET=m
1335# CONFIG_USB_GADGET_DEBUG is not set
1336# CONFIG_USB_GADGET_DEBUG_FILES is not set
1337CONFIG_USB_GADGET_SELECTED=y
1338# CONFIG_USB_GADGET_AMD5536UDC is not set
1339# CONFIG_USB_GADGET_FSL_USB2 is not set
1340# CONFIG_USB_GADGET_NET2280 is not set
1341# CONFIG_USB_GADGET_PXA2XX is not set
1342# CONFIG_USB_GADGET_M66592 is not set
1343CONFIG_USB_GADGET_PXA27X=y
1344CONFIG_USB_PXA27X=m
1345# CONFIG_USB_GADGET_GOKU is not set
1346# CONFIG_USB_GADGET_LH7A40X is not set
1347# CONFIG_USB_GADGET_OMAP is not set
1348# CONFIG_USB_GADGET_S3C2410 is not set
1349# CONFIG_USB_GADGET_AT91 is not set
1350# CONFIG_USB_GADGET_DUMMY_HCD is not set
1351# CONFIG_USB_GADGET_DUALSPEED is not set
1352CONFIG_USB_ZERO=m
1353CONFIG_USB_ETH=m
1354CONFIG_USB_ETH_RNDIS=y
1355CONFIG_USB_GADGETFS=m
1356CONFIG_USB_FILE_STORAGE=m
1357# CONFIG_USB_FILE_STORAGE_TEST is not set
1358CONFIG_USB_G_SERIAL=m
1359# CONFIG_USB_MIDI_GADGET is not set
1360CONFIG_MMC=y
1361# CONFIG_MMC_DEBUG is not set
1362CONFIG_MMC_UNSAFE_RESUME=y
1363
1364#
1365# MMC/SD Card Drivers
1366#
1367CONFIG_MMC_BLOCK=y
1368CONFIG_MMC_BLOCK_BOUNCE=y
1369
1370#
1371# MMC/SD Host Controller Drivers
1372#
1373CONFIG_MMC_PXA=y
1374CONFIG_RTC_LIB=y
1375CONFIG_RTC_CLASS=y
1376CONFIG_RTC_HCTOSYS=y
1377CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1378# CONFIG_RTC_DEBUG is not set
1379
1380#
1381# RTC interfaces
1382#
1383CONFIG_RTC_INTF_SYSFS=y
1384CONFIG_RTC_INTF_PROC=y
1385CONFIG_RTC_INTF_DEV=y
1386# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1387# CONFIG_RTC_DRV_TEST is not set
1388
1389#
1390# I2C RTC drivers
1391#
1392# CONFIG_RTC_DRV_DS1307 is not set
1393# CONFIG_RTC_DRV_DS1672 is not set
1394# CONFIG_RTC_DRV_MAX6900 is not set
1395# CONFIG_RTC_DRV_RS5C372 is not set
1396# CONFIG_RTC_DRV_ISL1208 is not set
1397# CONFIG_RTC_DRV_X1205 is not set
1398# CONFIG_RTC_DRV_PCF8563 is not set
1399# CONFIG_RTC_DRV_PCF8583 is not set
1400# CONFIG_RTC_DRV_M41T80 is not set
1401
1402#
1403# SPI RTC drivers
1404#
1405
1406#
1407# Platform RTC drivers
1408#
1409# CONFIG_RTC_DRV_CMOS is not set
1410# CONFIG_RTC_DRV_DS1553 is not set
1411# CONFIG_RTC_DRV_STK17TA8 is not set
1412# CONFIG_RTC_DRV_DS1742 is not set
1413# CONFIG_RTC_DRV_M48T86 is not set
1414# CONFIG_RTC_DRV_M48T59 is not set
1415# CONFIG_RTC_DRV_V3020 is not set
1416
1417#
1418# on-CPU RTC drivers
1419#
1420CONFIG_RTC_DRV_SA1100=y
1421
1422#
1423# DMA Engine support
1424#
1425# CONFIG_DMA_ENGINE is not set
1426
1427#
1428# DMA Clients
1429#
1430
1431#
1432# DMA Devices
1433#
1434
1435#
1436# File systems
1437#
1438CONFIG_EXT2_FS=y
1439# CONFIG_EXT2_FS_XATTR is not set
1440# CONFIG_EXT2_FS_XIP is not set
1441CONFIG_EXT3_FS=y
1442# CONFIG_EXT3_FS_XATTR is not set
1443# CONFIG_EXT4DEV_FS is not set
1444CONFIG_JBD=y
1445# CONFIG_JBD_DEBUG is not set
1446# CONFIG_REISERFS_FS is not set
1447# CONFIG_JFS_FS is not set
1448CONFIG_FS_POSIX_ACL=y
1449# CONFIG_XFS_FS is not set
1450# CONFIG_GFS2_FS is not set
1451# CONFIG_OCFS2_FS is not set
1452# CONFIG_MINIX_FS is not set
1453# CONFIG_ROMFS_FS is not set
1454CONFIG_INOTIFY=y
1455CONFIG_INOTIFY_USER=y
1456# CONFIG_QUOTA is not set
1457CONFIG_DNOTIFY=y
1458# CONFIG_AUTOFS_FS is not set
1459# CONFIG_AUTOFS4_FS is not set
1460# CONFIG_FUSE_FS is not set
1461
1462#
1463# CD-ROM/DVD Filesystems
1464#
1465# CONFIG_ISO9660_FS is not set
1466# CONFIG_UDF_FS is not set
1467
1468#
1469# DOS/FAT/NT Filesystems
1470#
1471CONFIG_FAT_FS=y
1472# CONFIG_MSDOS_FS is not set
1473CONFIG_VFAT_FS=y
1474CONFIG_FAT_DEFAULT_CODEPAGE=437
1475CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1476# CONFIG_NTFS_FS is not set
1477
1478#
1479# Pseudo filesystems
1480#
1481CONFIG_PROC_FS=y
1482CONFIG_PROC_SYSCTL=y
1483CONFIG_SYSFS=y
1484CONFIG_TMPFS=y
1485# CONFIG_TMPFS_POSIX_ACL is not set
1486# CONFIG_HUGETLB_PAGE is not set
1487CONFIG_RAMFS=y
1488# CONFIG_CONFIGFS_FS is not set
1489
1490#
1491# Miscellaneous filesystems
1492#
1493# CONFIG_ADFS_FS is not set
1494# CONFIG_AFFS_FS is not set
1495# CONFIG_HFS_FS is not set
1496# CONFIG_HFSPLUS_FS is not set
1497# CONFIG_BEFS_FS is not set
1498# CONFIG_BFS_FS is not set
1499# CONFIG_EFS_FS is not set
1500CONFIG_JFFS2_FS=m
1501CONFIG_JFFS2_FS_DEBUG=0
1502CONFIG_JFFS2_FS_WRITEBUFFER=y
1503CONFIG_JFFS2_SUMMARY=y
1504# CONFIG_JFFS2_FS_XATTR is not set
1505# CONFIG_JFFS2_SYSFS is not set
1506CONFIG_JFFS2_COMPRESSION_OPTIONS=y
1507CONFIG_JFFS2_ZLIB=y
1508CONFIG_JFFS2_LZO=y
1509CONFIG_JFFS2_RTIME=y
1510CONFIG_JFFS2_RUBIN=y
1511# CONFIG_JFFS2_CMODE_NONE is not set
1512CONFIG_JFFS2_CMODE_PRIORITY=y
1513# CONFIG_JFFS2_CMODE_SIZE is not set
1514# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
1515CONFIG_CRAMFS=m
1516CONFIG_SQUASHFS=m
1517# CONFIG_SQUASHFS_EMBEDDED is not set
1518CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1519# CONFIG_SQUASHFS_VMALLOC is not set
1520# CONFIG_VXFS_FS is not set
1521# CONFIG_HPFS_FS is not set
1522# CONFIG_QNX4FS_FS is not set
1523# CONFIG_SYSV_FS is not set
1524# CONFIG_UFS_FS is not set
1525
1526#
1527# Network File Systems
1528#
1529CONFIG_NFS_FS=m
1530CONFIG_NFS_V3=y
1531# CONFIG_NFS_V3_ACL is not set
1532CONFIG_NFS_V4=y
1533# CONFIG_NFS_DIRECTIO is not set
1534CONFIG_NFSD=m
1535CONFIG_NFSD_V3=y
1536# CONFIG_NFSD_V3_ACL is not set
1537CONFIG_NFSD_V4=y
1538CONFIG_NFSD_TCP=y
1539CONFIG_LOCKD=m
1540CONFIG_LOCKD_V4=y
1541CONFIG_EXPORTFS=m
1542CONFIG_NFS_COMMON=y
1543CONFIG_SUNRPC=m
1544CONFIG_SUNRPC_GSS=m
1545# CONFIG_SUNRPC_BIND34 is not set
1546CONFIG_RPCSEC_GSS_KRB5=m
1547# CONFIG_RPCSEC_GSS_SPKM3 is not set
1548CONFIG_SMB_FS=m
1549CONFIG_SMB_NLS_DEFAULT=y
1550CONFIG_SMB_NLS_REMOTE="cp437"
1551CONFIG_CIFS=m
1552# CONFIG_CIFS_STATS is not set
1553# CONFIG_CIFS_WEAK_PW_HASH is not set
1554# CONFIG_CIFS_XATTR is not set
1555# CONFIG_CIFS_DEBUG2 is not set
1556# CONFIG_CIFS_EXPERIMENTAL is not set
1557# CONFIG_NCP_FS is not set
1558# CONFIG_CODA_FS is not set
1559# CONFIG_AFS_FS is not set
1560
1561#
1562# Partition Types
1563#
1564CONFIG_PARTITION_ADVANCED=y
1565# CONFIG_ACORN_PARTITION is not set
1566# CONFIG_OSF_PARTITION is not set
1567# CONFIG_AMIGA_PARTITION is not set
1568# CONFIG_ATARI_PARTITION is not set
1569# CONFIG_MAC_PARTITION is not set
1570CONFIG_MSDOS_PARTITION=y
1571# CONFIG_BSD_DISKLABEL is not set
1572# CONFIG_MINIX_SUBPARTITION is not set
1573# CONFIG_SOLARIS_X86_PARTITION is not set
1574# CONFIG_UNIXWARE_DISKLABEL is not set
1575# CONFIG_LDM_PARTITION is not set
1576# CONFIG_SGI_PARTITION is not set
1577# CONFIG_ULTRIX_PARTITION is not set
1578# CONFIG_SUN_PARTITION is not set
1579# CONFIG_KARMA_PARTITION is not set
1580# CONFIG_EFI_PARTITION is not set
1581# CONFIG_SYSV68_PARTITION is not set
1582
1583#
1584# Native Language Support
1585#
1586CONFIG_NLS=y
1587CONFIG_NLS_DEFAULT="cp437"
1588CONFIG_NLS_CODEPAGE_437=y
1589CONFIG_NLS_CODEPAGE_737=m
1590CONFIG_NLS_CODEPAGE_775=m
1591CONFIG_NLS_CODEPAGE_850=m
1592CONFIG_NLS_CODEPAGE_852=m
1593CONFIG_NLS_CODEPAGE_855=m
1594CONFIG_NLS_CODEPAGE_857=m
1595CONFIG_NLS_CODEPAGE_860=m
1596CONFIG_NLS_CODEPAGE_861=m
1597CONFIG_NLS_CODEPAGE_862=m
1598CONFIG_NLS_CODEPAGE_863=m
1599CONFIG_NLS_CODEPAGE_864=m
1600CONFIG_NLS_CODEPAGE_865=m
1601CONFIG_NLS_CODEPAGE_866=m
1602CONFIG_NLS_CODEPAGE_869=m
1603CONFIG_NLS_CODEPAGE_936=m
1604CONFIG_NLS_CODEPAGE_950=m
1605CONFIG_NLS_CODEPAGE_932=m
1606CONFIG_NLS_CODEPAGE_949=m
1607CONFIG_NLS_CODEPAGE_874=m
1608CONFIG_NLS_ISO8859_8=m
1609CONFIG_NLS_CODEPAGE_1250=m
1610CONFIG_NLS_CODEPAGE_1251=m
1611CONFIG_NLS_ASCII=m
1612CONFIG_NLS_ISO8859_1=y
1613CONFIG_NLS_ISO8859_2=m
1614CONFIG_NLS_ISO8859_3=m
1615CONFIG_NLS_ISO8859_4=m
1616CONFIG_NLS_ISO8859_5=m
1617CONFIG_NLS_ISO8859_6=m
1618CONFIG_NLS_ISO8859_7=m
1619CONFIG_NLS_ISO8859_9=m
1620CONFIG_NLS_ISO8859_13=m
1621CONFIG_NLS_ISO8859_14=m
1622CONFIG_NLS_ISO8859_15=m
1623CONFIG_NLS_KOI8_R=m
1624CONFIG_NLS_KOI8_U=m
1625CONFIG_NLS_UTF8=y
1626
1627#
1628# Distributed Lock Manager
1629#
1630# CONFIG_DLM is not set
1631
1632#
1633# Profiling support
1634#
1635CONFIG_PROFILING=y
1636CONFIG_OPROFILE=m
1637
1638#
1639# Kernel hacking
1640#
1641# CONFIG_PRINTK_TIME is not set
1642CONFIG_ENABLE_MUST_CHECK=y
1643CONFIG_MAGIC_SYSRQ=y
1644# CONFIG_UNUSED_SYMBOLS is not set
1645# CONFIG_DEBUG_FS is not set
1646# CONFIG_HEADERS_CHECK is not set
1647CONFIG_DEBUG_KERNEL=y
1648# CONFIG_DEBUG_SHIRQ is not set
1649# CONFIG_DETECT_SOFTLOCKUP is not set
1650# CONFIG_SCHED_DEBUG is not set
1651# CONFIG_SCHEDSTATS is not set
1652CONFIG_TIMER_STATS=y
1653# CONFIG_DEBUG_SLAB is not set
1654# CONFIG_DEBUG_PREEMPT is not set
1655# CONFIG_DEBUG_RT_MUTEXES is not set
1656# CONFIG_RT_MUTEX_TESTER is not set
1657# CONFIG_DEBUG_SPINLOCK is not set
1658# CONFIG_DEBUG_MUTEXES is not set
1659# CONFIG_DEBUG_LOCK_ALLOC is not set
1660# CONFIG_PROVE_LOCKING is not set
1661# CONFIG_LOCK_STAT is not set
1662# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1663# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1664# CONFIG_DEBUG_KOBJECT is not set
1665CONFIG_DEBUG_BUGVERBOSE=y
1666# CONFIG_DEBUG_INFO is not set
1667# CONFIG_DEBUG_VM is not set
1668# CONFIG_DEBUG_LIST is not set
1669CONFIG_FRAME_POINTER=y
1670# CONFIG_FORCED_INLINING is not set
1671# CONFIG_RCU_TORTURE_TEST is not set
1672# CONFIG_FAULT_INJECTION is not set
1673# CONFIG_DEBUG_USER is not set
1674CONFIG_DEBUG_ERRORS=y
1675# CONFIG_DEBUG_LL is not set
1676
1677#
1678# Security options
1679#
1680# CONFIG_KEYS is not set
1681# CONFIG_SECURITY is not set
1682CONFIG_CRYPTO=y
1683CONFIG_CRYPTO_ALGAPI=y
1684CONFIG_CRYPTO_BLKCIPHER=m
1685CONFIG_CRYPTO_HASH=y
1686CONFIG_CRYPTO_MANAGER=y
1687CONFIG_CRYPTO_HMAC=y
1688# CONFIG_CRYPTO_XCBC is not set
1689CONFIG_CRYPTO_NULL=m
1690CONFIG_CRYPTO_MD4=m
1691CONFIG_CRYPTO_MD5=m
1692CONFIG_CRYPTO_SHA1=m
1693CONFIG_CRYPTO_SHA256=m
1694CONFIG_CRYPTO_SHA512=m
1695CONFIG_CRYPTO_WP512=m
1696# CONFIG_CRYPTO_TGR192 is not set
1697# CONFIG_CRYPTO_GF128MUL is not set
1698CONFIG_CRYPTO_ECB=m
1699CONFIG_CRYPTO_CBC=m
1700CONFIG_CRYPTO_PCBC=m
1701# CONFIG_CRYPTO_LRW is not set
1702# CONFIG_CRYPTO_CRYPTD is not set
1703CONFIG_CRYPTO_DES=m
1704# CONFIG_CRYPTO_FCRYPT is not set
1705CONFIG_CRYPTO_BLOWFISH=m
1706CONFIG_CRYPTO_TWOFISH=m
1707CONFIG_CRYPTO_TWOFISH_COMMON=m
1708CONFIG_CRYPTO_SERPENT=m
1709CONFIG_CRYPTO_AES=m
1710CONFIG_CRYPTO_CAST5=m
1711CONFIG_CRYPTO_CAST6=m
1712CONFIG_CRYPTO_TEA=m
1713CONFIG_CRYPTO_ARC4=m
1714CONFIG_CRYPTO_KHAZAD=m
1715CONFIG_CRYPTO_ANUBIS=m
1716CONFIG_CRYPTO_DEFLATE=m
1717# CONFIG_CRYPTO_LZO is not set
1718CONFIG_CRYPTO_MICHAEL_MIC=m
1719CONFIG_CRYPTO_CRC32C=m
1720# CONFIG_CRYPTO_CAMELLIA is not set
1721CONFIG_CRYPTO_TEST=m
1722# CONFIG_CRYPTO_HW is not set
1723
1724#
1725# Library routines
1726#
1727CONFIG_BITREVERSE=y
1728CONFIG_CRC_CCITT=y
1729# CONFIG_CRC16 is not set
1730# CONFIG_CRC_ITU_T is not set
1731CONFIG_CRC32=y
1732# CONFIG_CRC7 is not set
1733CONFIG_LIBCRC32C=m
1734CONFIG_ZLIB_INFLATE=m
1735CONFIG_ZLIB_DEFLATE=m
1736CONFIG_LZO_COMPRESS=m
1737CONFIG_LZO_DECOMPRESS=m
1738CONFIG_PLIST=y
1739CONFIG_HAS_IOMEM=y
1740CONFIG_HAS_IOPORT=y
1741CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-tosa b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-tosa
new file mode 100644
index 0000000000..d005193a34
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-tosa
@@ -0,0 +1,1665 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16-rc5-git5
4# Tue Mar 14 09:05:26 2006
5#
6CONFIG_ARM=y
7CONFIG_MMU=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_ARCH_MTD_XIP=y
11
12#
13# Code maturity level options
14#
15CONFIG_EXPERIMENTAL=y
16CONFIG_BROKEN_ON_SMP=y
17CONFIG_LOCK_KERNEL=y
18CONFIG_INIT_ENV_ARG_LIMIT=32
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24# CONFIG_LOCALVERSION_AUTO is not set
25CONFIG_SWAP=y
26CONFIG_SYSVIPC=y
27# CONFIG_POSIX_MQUEUE is not set
28CONFIG_BSD_PROCESS_ACCT=y
29CONFIG_BSD_PROCESS_ACCT_V3=y
30CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set
32# CONFIG_IKCONFIG is not set
33CONFIG_INITRAMFS_SOURCE=""
34CONFIG_UID16=y
35CONFIG_CC_OPTIMIZE_FOR_SIZE=y
36CONFIG_EMBEDDED=y
37CONFIG_KALLSYMS=y
38# CONFIG_KALLSYMS_ALL is not set
39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_ELF_CORE=y
44CONFIG_BASE_FULL=y
45CONFIG_FUTEX=y
46CONFIG_EPOLL=y
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52CONFIG_SLAB=y
53# CONFIG_TINY_SHMEM is not set
54CONFIG_BASE_SMALL=0
55# CONFIG_SLOB is not set
56
57#
58# Loadable module support
59#
60CONFIG_MODULES=y
61CONFIG_MODULE_UNLOAD=y
62CONFIG_MODULE_FORCE_UNLOAD=y
63CONFIG_OBSOLETE_MODPARM=y
64# CONFIG_MODVERSIONS is not set
65# CONFIG_MODULE_SRCVERSION_ALL is not set
66CONFIG_KMOD=y
67
68#
69# Block layer
70#
71
72#
73# IO Schedulers
74#
75CONFIG_IOSCHED_NOOP=y
76CONFIG_IOSCHED_AS=y
77CONFIG_IOSCHED_DEADLINE=m
78CONFIG_IOSCHED_CFQ=m
79CONFIG_DEFAULT_AS=y
80# CONFIG_DEFAULT_DEADLINE is not set
81# CONFIG_DEFAULT_CFQ is not set
82# CONFIG_DEFAULT_NOOP is not set
83CONFIG_DEFAULT_IOSCHED="anticipatory"
84
85#
86# System Type
87#
88# CONFIG_ARCH_CLPS7500 is not set
89# CONFIG_ARCH_CLPS711X is not set
90# CONFIG_ARCH_CO285 is not set
91# CONFIG_ARCH_EBSA110 is not set
92# CONFIG_ARCH_FOOTBRIDGE is not set
93# CONFIG_ARCH_INTEGRATOR is not set
94# CONFIG_ARCH_IOP3XX is not set
95# CONFIG_ARCH_IXP4XX is not set
96# CONFIG_ARCH_IXP2000 is not set
97# CONFIG_ARCH_L7200 is not set
98CONFIG_ARCH_PXA=y
99# CONFIG_ARCH_RPC is not set
100# CONFIG_ARCH_SA1100 is not set
101# CONFIG_ARCH_S3C2410 is not set
102# CONFIG_ARCH_SHARK is not set
103# CONFIG_ARCH_LH7A40X is not set
104# CONFIG_ARCH_OMAP is not set
105# CONFIG_ARCH_VERSATILE is not set
106# CONFIG_ARCH_REALVIEW is not set
107# CONFIG_ARCH_IMX is not set
108# CONFIG_ARCH_H720X is not set
109# CONFIG_ARCH_AAEC2000 is not set
110# CONFIG_ARCH_AT91RM9200 is not set
111
112#
113# Intel PXA2xx Implementations
114#
115# CONFIG_ARCH_LUBBOCK is not set
116# CONFIG_MACH_MAINSTONE is not set
117# CONFIG_ARCH_PXA_IDP is not set
118CONFIG_PXA_SHARPSL=y
119# CONFIG_MACH_HX2750 is not set
120CONFIG_PXA_SHARPSL_25x=y
121# CONFIG_PXA_SHARPSL_27x is not set
122# CONFIG_MACH_POODLE is not set
123# CONFIG_MACH_CORGI is not set
124# CONFIG_MACH_SHEPHERD is not set
125# CONFIG_MACH_HUSKY is not set
126CONFIG_MACH_TOSA=y
127CONFIG_PXA25x=y
128# CONFIG_PXA_KEYS is not set
129
130#
131# Processor Type
132#
133CONFIG_CPU_32=y
134CONFIG_CPU_XSCALE=y
135CONFIG_CPU_32v5=y
136CONFIG_CPU_ABRT_EV5T=y
137CONFIG_CPU_CACHE_VIVT=y
138CONFIG_CPU_TLB_V4WBI=y
139
140#
141# Processor Features
142#
143CONFIG_ARM_THUMB=y
144CONFIG_XSCALE_PMU=y
145CONFIG_KEXEC=y
146CONFIG_ATAGS_PROC=y
147CONFIG_SHARP_PARAM=y
148CONFIG_SHARPSL_PM=y
149CONFIG_SHARP_SCOOP=y
150CONFIG_TOSHIBA_TC6393XB=y
151
152#
153# Bus support
154#
155
156#
157# PCCARD (PCMCIA/CardBus) support
158#
159CONFIG_PCCARD=y
160# CONFIG_PCMCIA_DEBUG is not set
161CONFIG_PCMCIA=y
162CONFIG_PCMCIA_LOAD_CIS=y
163CONFIG_PCMCIA_IOCTL=y
164
165#
166# PC-card bridges
167#
168CONFIG_PCMCIA_PXA2XX=y
169
170#
171# Kernel Features
172#
173CONFIG_PREEMPT=y
174CONFIG_NO_IDLE_HZ=y
175# CONFIG_AEABI is not set
176# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
177CONFIG_SELECT_MEMORY_MODEL=y
178CONFIG_FLATMEM_MANUAL=y
179# CONFIG_DISCONTIGMEM_MANUAL is not set
180# CONFIG_SPARSEMEM_MANUAL is not set
181CONFIG_FLATMEM=y
182CONFIG_FLAT_NODE_MEM_MAP=y
183# CONFIG_SPARSEMEM_STATIC is not set
184CONFIG_SPLIT_PTLOCK_CPUS=4096
185CONFIG_ALIGNMENT_TRAP=y
186
187#
188# Boot options
189#
190CONFIG_ZBOOT_ROM_TEXT=0x0
191CONFIG_ZBOOT_ROM_BSS=0x0
192# CONFIG_XIP_KERNEL is not set
193
194#
195# CPU Frequency scaling
196#
197CONFIG_CPU_FREQ=y
198CONFIG_CPU_FREQ_TABLE=y
199# CONFIG_CPU_FREQ_DEBUG is not set
200CONFIG_CPU_FREQ_STAT=y
201# CONFIG_CPU_FREQ_STAT_DETAILS is not set
202CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
203# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
204CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
205CONFIG_CPU_FREQ_GOV_POWERSAVE=m
206CONFIG_CPU_FREQ_GOV_USERSPACE=m
207CONFIG_CPU_FREQ_GOV_ONDEMAND=m
208CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
209CONFIG_CPU_FREQ_PXA25x=y
210
211#
212# Floating point emulation
213#
214
215#
216# At least one emulation must be selected
217#
218CONFIG_FPE_NWFPE=y
219# CONFIG_FPE_NWFPE_XP is not set
220# CONFIG_FPE_FASTFPE is not set
221
222#
223# Userspace binary formats
224#
225CONFIG_BINFMT_ELF=y
226CONFIG_BINFMT_AOUT=m
227CONFIG_BINFMT_MISC=m
228# CONFIG_ARTHUR is not set
229
230#
231# Power management options
232#
233CONFIG_PM=y
234# CONFIG_PM_LEGACY is not set
235# CONFIG_PM_DEBUG is not set
236CONFIG_APM=y
237
238#
239# Networking
240#
241CONFIG_NET=y
242
243#
244# Networking options
245#
246# CONFIG_NETDEBUG is not set
247CONFIG_PACKET=m
248CONFIG_PACKET_MMAP=y
249CONFIG_UNIX=y
250CONFIG_XFRM=y
251CONFIG_XFRM_USER=m
252CONFIG_NET_KEY=m
253CONFIG_INET=y
254# CONFIG_IP_MULTICAST is not set
255# CONFIG_IP_ADVANCED_ROUTER is not set
256CONFIG_IP_FIB_HASH=y
257# CONFIG_IP_PNP is not set
258# CONFIG_NET_IPIP is not set
259# CONFIG_NET_IPGRE is not set
260# CONFIG_ARPD is not set
261CONFIG_SYN_COOKIES=y
262# CONFIG_INET_AH is not set
263# CONFIG_INET_ESP is not set
264# CONFIG_INET_IPCOMP is not set
265# CONFIG_INET_TUNNEL is not set
266CONFIG_INET_XFRM_MODE_TRANSPORT=m
267CONFIG_INET_XFRM_MODE_TUNNEL=m
268CONFIG_INET_XFRM_MODE_BEET=m
269CONFIG_INET_DIAG=m
270CONFIG_INET_TCP_DIAG=m
271# CONFIG_TCP_CONG_ADVANCED is not set
272CONFIG_TCP_CONG_BIC=y
273
274#
275# IP: Virtual Server Configuration
276#
277# CONFIG_IP_VS is not set
278CONFIG_IPV6=m
279# CONFIG_IPV6_PRIVACY is not set
280CONFIG_INET6_AH=m
281CONFIG_INET6_ESP=m
282CONFIG_INET6_IPCOMP=m
283CONFIG_INET6_TUNNEL=m
284CONFIG_IPV6_TUNNEL=m
285CONFIG_NETFILTER=y
286# CONFIG_NETFILTER_DEBUG is not set
287
288#
289# Core Netfilter Configuration
290#
291# CONFIG_NETFILTER_NETLINK is not set
292# CONFIG_NF_CONNTRACK_ENABLED is not set
293# CONFIG_NF_CONNTRACK is not set
294
295CONFIG_NETFILTER_XTABLES=m
296# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
297# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
298# CONFIG_NETFILTER_XT_TARGET_MARK is not set
299# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
300# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
301# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
302# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
303# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
304# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
305# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
306# CONFIG_NETFILTER_XT_MATCH_ESP is not set
307# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
308# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
309# CONFIG_NETFILTER_XT_MATCH_MAC is not set
310# CONFIG_NETFILTER_XT_MATCH_MARK is not set
311# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
312# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
313# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
314# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
315# CONFIG_NETFILTER_XT_MATCH_REALM is not set
316# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
317# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
318# CONFIG_NETFILTER_XT_MATCH_STRING is not set
319# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
320# CONFIG_NETFILTER_XT_MATCH_U32 is not set
321# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
322
323#
324# IP: Netfilter Configuration
325#
326CONFIG_IP_NF_QUEUE=m
327CONFIG_IP_NF_IPTABLES=m
328CONFIG_IP_NF_MATCH_IPRANGE=m
329CONFIG_IP_NF_MATCH_TOS=m
330CONFIG_IP_NF_MATCH_RECENT=m
331CONFIG_IP_NF_MATCH_ECN=m
332CONFIG_IP_NF_MATCH_AH=m
333CONFIG_IP_NF_MATCH_TTL=m
334CONFIG_IP_NF_MATCH_OWNER=m
335CONFIG_IP_NF_MATCH_ADDRTYPE=m
336CONFIG_IP_NF_FILTER=m
337CONFIG_IP_NF_TARGET_REJECT=m
338CONFIG_IP_NF_TARGET_LOG=m
339CONFIG_IP_NF_TARGET_ULOG=m
340CONFIG_IP_NF_MANGLE=m
341CONFIG_IP_NF_TARGET_TOS=m
342CONFIG_IP_NF_TARGET_ECN=m
343CONFIG_IP_NF_TARGET_TTL=m
344CONFIG_IP_NF_RAW=m
345CONFIG_IP_NF_ARPTABLES=m
346CONFIG_IP_NF_ARPFILTER=m
347CONFIG_IP_NF_ARP_MANGLE=m
348
349#
350
351#
352# IPv6: Netfilter Configuration (EXPERIMENTAL)
353#
354# CONFIG_IP6_NF_QUEUE is not set
355
356#
357# DCCP Configuration (EXPERIMENTAL)
358#
359# CONFIG_IP_DCCP is not set
360
361#
362# SCTP Configuration (EXPERIMENTAL)
363#
364# CONFIG_IP_SCTP is not set
365
366#
367# TIPC Configuration (EXPERIMENTAL)
368#
369# CONFIG_TIPC is not set
370# CONFIG_ATM is not set
371# CONFIG_BRIDGE is not set
372# CONFIG_VLAN_8021Q is not set
373# CONFIG_DECNET is not set
374# CONFIG_LLC2 is not set
375# CONFIG_IPX is not set
376# CONFIG_ATALK is not set
377# CONFIG_X25 is not set
378# CONFIG_LAPB is not set
379# CONFIG_NET_DIVERT is not set
380# CONFIG_ECONET is not set
381# CONFIG_WAN_ROUTER is not set
382
383#
384# QoS and/or fair queueing
385#
386# CONFIG_NET_SCHED is not set
387
388#
389# Network testing
390#
391# CONFIG_NET_PKTGEN is not set
392# CONFIG_HAMRADIO is not set
393CONFIG_IRDA=m
394
395#
396# IrDA protocols
397#
398CONFIG_IRLAN=m
399CONFIG_IRNET=m
400CONFIG_IRCOMM=m
401# CONFIG_IRDA_ULTRA is not set
402
403#
404# IrDA options
405#
406# CONFIG_IRDA_CACHE_LAST_LSAP is not set
407# CONFIG_IRDA_FAST_RR is not set
408# CONFIG_IRDA_DEBUG is not set
409
410#
411# Infrared-port device drivers
412#
413
414#
415# SIR device drivers
416#
417# CONFIG_IRTTY_SIR is not set
418
419#
420# Dongle support
421#
422
423#
424# Old SIR device drivers
425#
426# CONFIG_IRPORT_SIR is not set
427
428#
429# Old Serial dongle support
430#
431
432#
433# FIR device drivers
434#
435# CONFIG_USB_IRDA is not set
436# CONFIG_SIGMATEL_FIR is not set
437CONFIG_PXA_FICP=m
438CONFIG_BT=m
439CONFIG_BT_L2CAP=m
440CONFIG_BT_SCO=m
441CONFIG_BT_RFCOMM=m
442CONFIG_BT_RFCOMM_TTY=y
443CONFIG_BT_BNEP=m
444CONFIG_BT_BNEP_MC_FILTER=y
445CONFIG_BT_BNEP_PROTO_FILTER=y
446CONFIG_BT_HIDP=m
447
448#
449# Bluetooth device drivers
450#
451CONFIG_BT_HCIUSB=m
452# CONFIG_BT_HCIUSB_SCO is not set
453CONFIG_BT_HCIUART=m
454CONFIG_BT_HCIUART_H4=y
455CONFIG_BT_HCIUART_BCSP=y
456CONFIG_BT_HCIBCM203X=m
457CONFIG_BT_HCIBPA10X=m
458CONFIG_BT_HCIBFUSB=m
459CONFIG_BT_HCIDTL1=m
460CONFIG_BT_HCIBT3C=m
461CONFIG_BT_HCIBLUECARD=m
462CONFIG_BT_HCIBTUART=m
463CONFIG_BT_HCIVHCI=m
464CONFIG_IEEE80211=m
465# CONFIG_IEEE80211_DEBUG is not set
466CONFIG_IEEE80211_CRYPT_WEP=m
467CONFIG_IEEE80211_CRYPT_CCMP=m
468CONFIG_IEEE80211_CRYPT_TKIP=m
469
470#
471# Device Drivers
472#
473
474#
475# Generic Driver Options
476#
477CONFIG_STANDALONE=y
478CONFIG_PREVENT_FIRMWARE_BUILD=y
479CONFIG_FW_LOADER=m
480# CONFIG_DEBUG_DRIVER is not set
481
482#
483# Connector - unified userspace <-> kernelspace linker
484#
485# CONFIG_CONNECTOR is not set
486
487#
488# Memory Technology Devices (MTD)
489#
490CONFIG_MTD=y
491# CONFIG_MTD_DEBUG is not set
492# CONFIG_MTD_CONCAT is not set
493CONFIG_MTD_PARTITIONS=y
494# CONFIG_MTD_REDBOOT_PARTS is not set
495# CONFIG_MTD_CMDLINE_PARTS is not set
496# CONFIG_MTD_AFS_PARTS is not set
497
498#
499# User Modules And Translation Layers
500#
501CONFIG_MTD_CHAR=y
502CONFIG_MTD_BLOCK=y
503# CONFIG_FTL is not set
504# CONFIG_NFTL is not set
505# CONFIG_INFTL is not set
506# CONFIG_RFD_FTL is not set
507
508#
509# RAM/ROM/Flash chip drivers
510#
511# CONFIG_MTD_CFI is not set
512# CONFIG_MTD_JEDECPROBE is not set
513CONFIG_MTD_MAP_BANK_WIDTH_1=y
514CONFIG_MTD_MAP_BANK_WIDTH_2=y
515CONFIG_MTD_MAP_BANK_WIDTH_4=y
516# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
517# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
518# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
519CONFIG_MTD_CFI_I1=y
520CONFIG_MTD_CFI_I2=y
521# CONFIG_MTD_CFI_I4 is not set
522# CONFIG_MTD_CFI_I8 is not set
523# CONFIG_MTD_RAM is not set
524CONFIG_MTD_ROM=y
525# CONFIG_MTD_ABSENT is not set
526# CONFIG_MTD_OBSOLETE_CHIPS is not set
527
528#
529# Mapping drivers for chip access
530#
531# CONFIG_MTD_COMPLEX_MAPPINGS is not set
532CONFIG_MTD_SHARP_SL=y
533# CONFIG_MTD_PLATRAM is not set
534
535#
536# Self-contained MTD device drivers
537#
538# CONFIG_MTD_SLRAM is not set
539# CONFIG_MTD_PHRAM is not set
540# CONFIG_MTD_MTDRAM is not set
541# CONFIG_MTD_BLKMTD is not set
542# CONFIG_MTD_BLOCK2MTD is not set
543
544#
545# Disk-On-Chip Device Drivers
546#
547# CONFIG_MTD_DOC2000 is not set
548# CONFIG_MTD_DOC2001 is not set
549# CONFIG_MTD_DOC2001PLUS is not set
550
551#
552# NAND Flash Device Drivers
553#
554CONFIG_MTD_NAND=y
555CONFIG_MTD_NAND_VERIFY_WRITE=y
556# CONFIG_MTD_NAND_H1900 is not set
557CONFIG_MTD_NAND_TMIO=y
558CONFIG_MTD_NAND_IDS=y
559# CONFIG_MTD_NAND_DISKONCHIP is not set
560# CONFIG_MTD_NAND_SHARPSL is not set
561# CONFIG_MTD_NAND_NANDSIM is not set
562
563#
564# OneNAND Flash Device Drivers
565#
566# CONFIG_MTD_ONENAND is not set
567
568#
569# Parallel port support
570#
571# CONFIG_PARPORT is not set
572
573#
574# Plug and Play support
575#
576
577#
578# Block devices
579#
580# CONFIG_BLK_DEV_COW_COMMON is not set
581CONFIG_BLK_DEV_LOOP=m
582# CONFIG_BLK_DEV_CRYPTOLOOP is not set
583# CONFIG_BLK_DEV_NBD is not set
584# CONFIG_BLK_DEV_UB is not set
585# CONFIG_BLK_DEV_RAM is not set
586CONFIG_BLK_DEV_RAM_COUNT=16
587# CONFIG_CDROM_PKTCDVD is not set
588# CONFIG_ATA_OVER_ETH is not set
589
590#
591# ATA/ATAPI/MFM/RLL support
592#
593CONFIG_IDE=y
594CONFIG_BLK_DEV_IDE=y
595
596#
597# Please see Documentation/ide.txt for help/info on IDE drives
598#
599# CONFIG_BLK_DEV_IDE_SATA is not set
600CONFIG_BLK_DEV_IDEDISK=y
601# CONFIG_IDEDISK_MULTI_MODE is not set
602CONFIG_BLK_DEV_IDECS=y
603# CONFIG_BLK_DEV_IDECD is not set
604# CONFIG_BLK_DEV_IDETAPE is not set
605# CONFIG_BLK_DEV_IDEFLOPPY is not set
606# CONFIG_BLK_DEV_IDESCSI is not set
607# CONFIG_IDE_TASK_IOCTL is not set
608
609#
610# IDE chipset support/bugfixes
611#
612# CONFIG_IDE_GENERIC is not set
613# CONFIG_IDE_ARM is not set
614# CONFIG_BLK_DEV_IDEDMA is not set
615# CONFIG_IDEDMA_AUTO is not set
616# CONFIG_BLK_DEV_HD is not set
617
618#
619# SCSI device support
620#
621# CONFIG_RAID_ATTRS is not set
622CONFIG_SCSI=m
623CONFIG_SCSI_PROC_FS=y
624
625#
626# SCSI support type (disk, tape, CD-ROM)
627#
628CONFIG_BLK_DEV_SD=m
629CONFIG_CHR_DEV_ST=m
630CONFIG_CHR_DEV_OSST=m
631CONFIG_BLK_DEV_SR=m
632# CONFIG_BLK_DEV_SR_VENDOR is not set
633CONFIG_CHR_DEV_SG=m
634# CONFIG_CHR_DEV_SCH is not set
635
636#
637# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
638#
639CONFIG_SCSI_MULTI_LUN=y
640# CONFIG_SCSI_CONSTANTS is not set
641# CONFIG_SCSI_LOGGING is not set
642
643#
644# SCSI Transport Attributes
645#
646# CONFIG_SCSI_SPI_ATTRS is not set
647# CONFIG_SCSI_FC_ATTRS is not set
648# CONFIG_SCSI_ISCSI_ATTRS is not set
649# CONFIG_SCSI_SAS_ATTRS is not set
650
651#
652# SCSI low-level drivers
653#
654# CONFIG_ISCSI_TCP is not set
655# CONFIG_SCSI_SATA is not set
656# CONFIG_SCSI_DEBUG is not set
657
658#
659# PCMCIA SCSI adapter support
660#
661# CONFIG_PCMCIA_AHA152X is not set
662# CONFIG_PCMCIA_FDOMAIN is not set
663# CONFIG_PCMCIA_NINJA_SCSI is not set
664# CONFIG_PCMCIA_QLOGIC is not set
665# CONFIG_PCMCIA_SYM53C500 is not set
666
667#
668# Multi-device support (RAID and LVM)
669#
670CONFIG_MD=y
671CONFIG_BLK_DEV_DM=m
672CONFIG_DM_CRYPT=m
673CONFIG_DM_SNAPSHOT=m
674CONFIG_DM_MIRROR=m
675CONFIG_DM_ZERO=m
676CONFIG_DM_MULTIPATH=m
677CONFIG_DM_MULTIPATH_EMC=m
678
679#
680# Fusion MPT device support
681#
682# CONFIG_FUSION is not set
683
684#
685# IEEE 1394 (FireWire) support
686#
687
688#
689# I2O device support
690#
691
692#
693# Network device support
694#
695CONFIG_NETDEVICES=y
696# CONFIG_DUMMY is not set
697# CONFIG_BONDING is not set
698# CONFIG_EQUALIZER is not set
699CONFIG_TUN=m
700
701#
702# PHY device support
703#
704# CONFIG_PHYLIB is not set
705
706#
707# Ethernet (10 or 100Mbit)
708#
709CONFIG_NET_ETHERNET=y
710CONFIG_MII=m
711# CONFIG_SMC91X is not set
712# CONFIG_DM9000 is not set
713
714#
715# Ethernet (1000 Mbit)
716#
717
718#
719# Ethernet (10000 Mbit)
720#
721
722#
723# Token Ring devices
724#
725
726#
727# Wireless LAN (non-hamradio)
728#
729CONFIG_NET_RADIO=y
730
731#
732# Obsolete Wireless cards support (pre-802.11)
733#
734# CONFIG_STRIP is not set
735# CONFIG_PCMCIA_WAVELAN is not set
736# CONFIG_PCMCIA_NETWAVE is not set
737
738#
739# Wireless 802.11 Frequency Hopping cards support
740#
741# CONFIG_PCMCIA_RAYCS is not set
742
743#
744# Wireless 802.11b ISA/PCI cards support
745#
746CONFIG_HERMES=m
747# CONFIG_ATMEL is not set
748
749#
750# Wireless 802.11b Pcmcia/Cardbus cards support
751#
752CONFIG_PCMCIA_HERMES=m
753CONFIG_PCMCIA_SPECTRUM=m
754# CONFIG_AIRO_CS is not set
755# CONFIG_PCMCIA_WL3501 is not set
756CONFIG_HOSTAP=m
757CONFIG_HOSTAP_FIRMWARE=y
758# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
759CONFIG_HOSTAP_CS=m
760CONFIG_NET_WIRELESS=y
761
762#
763# PCMCIA network device support
764#
765CONFIG_NET_PCMCIA=y
766# CONFIG_PCMCIA_3C589 is not set
767# CONFIG_PCMCIA_3C574 is not set
768# CONFIG_PCMCIA_FMVJ18X is not set
769CONFIG_PCMCIA_PCNET=m
770# CONFIG_PCMCIA_NMCLAN is not set
771# CONFIG_PCMCIA_SMC91C92 is not set
772# CONFIG_PCMCIA_XIRC2PS is not set
773# CONFIG_PCMCIA_AXNET is not set
774
775#
776# Wan interfaces
777#
778# CONFIG_WAN is not set
779CONFIG_PPP=m
780# CONFIG_PPP_MULTILINK is not set
781# CONFIG_PPP_FILTER is not set
782CONFIG_PPP_ASYNC=m
783# CONFIG_PPP_SYNC_TTY is not set
784CONFIG_PPP_DEFLATE=m
785CONFIG_PPP_BSDCOMP=m
786# CONFIG_PPP_MPPE is not set
787# CONFIG_PPPOE is not set
788# CONFIG_SLIP is not set
789# CONFIG_SHAPER is not set
790# CONFIG_NETCONSOLE is not set
791# CONFIG_NETPOLL is not set
792# CONFIG_NET_POLL_CONTROLLER is not set
793
794#
795# ISDN subsystem
796#
797# CONFIG_ISDN is not set
798
799#
800# Input device support
801#
802CONFIG_INPUT=y
803
804#
805# Userland interfaces
806#
807CONFIG_INPUT_MOUSEDEV=m
808# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
809CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
810CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
811# CONFIG_INPUT_JOYDEV is not set
812# CONFIG_INPUT_TSDEV is not set
813CONFIG_INPUT_EVDEV=y
814# CONFIG_INPUT_EVBUG is not set
815CONFIG_INPUT_POWER=y
816
817#
818# Input Device Drivers
819#
820CONFIG_INPUT_KEYBOARD=y
821# CONFIG_KEYBOARD_ATKBD is not set
822# CONFIG_KEYBOARD_SUNKBD is not set
823# CONFIG_KEYBOARD_LKKBD is not set
824# CONFIG_KEYBOARD_XTKBD is not set
825# CONFIG_KEYBOARD_NEWTON is not set
826# CONFIG_KEYBOARD_CORGI is not set
827# CONFIG_KEYBOARD_SPITZ is not set
828CONFIG_KEYBOARD_TOSA=y
829# CONFIG_INPUT_MOUSE is not set
830# CONFIG_INPUT_JOYSTICK is not set
831CONFIG_INPUT_TOUCHSCREEN=y
832# CONFIG_TOUCHSCREEN_CORGI is not set
833# CONFIG_TOUCHSCREEN_GUNZE is not set
834# CONFIG_TOUCHSCREEN_ELO is not set
835# CONFIG_TOUCHSCREEN_MTOUCH is not set
836# CONFIG_TOUCHSCREEN_MK712 is not set
837CONFIG_TOUCHSCREEN_WM97XX=y
838# CONFIG_TOUCHSCREEN_WM9705 is not set
839CONFIG_TOUCHSCREEN_WM9712=y
840CONFIG_TOUCHSCREEN_TOSA=y
841# CONFIG_TOUCHSCREEN_WM9713 is not set
842# CONFIG_TOUCHSCREEN_WM97XX_PXA is not set
843CONFIG_INPUT_MISC=y
844CONFIG_INPUT_UINPUT=m
845
846#
847# Hardware I/O ports
848#
849# CONFIG_SERIO is not set
850# CONFIG_GAMEPORT is not set
851
852#
853# Character devices
854#
855CONFIG_VT=y
856CONFIG_VT_CONSOLE=y
857CONFIG_HW_CONSOLE=y
858# CONFIG_SERIAL_NONSTANDARD is not set
859
860#
861# Serial drivers
862#
863CONFIG_SERIAL_8250=m
864CONFIG_SERIAL_8250_CS=m
865CONFIG_SERIAL_8250_NR_UARTS=4
866CONFIG_SERIAL_8250_RUNTIME_UARTS=4
867# CONFIG_SERIAL_8250_EXTENDED is not set
868
869#
870# Non-8250 serial port support
871#
872CONFIG_SERIAL_PXA=y
873CONFIG_SERIAL_PXA_CONSOLE=y
874CONFIG_SERIAL_CORE=y
875CONFIG_SERIAL_CORE_CONSOLE=y
876CONFIG_UNIX98_PTYS=y
877# CONFIG_LEGACY_PTYS is not set
878
879#
880# IPMI
881#
882# CONFIG_IPMI_HANDLER is not set
883
884#
885# Watchdog Cards
886#
887# CONFIG_WATCHDOG is not set
888# CONFIG_NVRAM is not set
889# CONFIG_DTLK is not set
890# CONFIG_R3964 is not set
891
892#
893# Ftape, the floppy tape device driver
894#
895
896#
897# PCMCIA character devices
898#
899# CONFIG_SYNCLINK_CS is not set
900# CONFIG_CARDMAN_4000 is not set
901# CONFIG_CARDMAN_4040 is not set
902# CONFIG_RAW_DRIVER is not set
903
904#
905# TPM devices
906#
907# CONFIG_TCG_TPM is not set
908# CONFIG_TELCLOCK is not set
909
910#
911# I2C support
912#
913CONFIG_I2C=y
914# CONFIG_I2C_CHARDEV is not set
915
916#
917# I2C Algorithms
918#
919# CONFIG_I2C_ALGOBIT is not set
920# CONFIG_I2C_ALGOPCF is not set
921# CONFIG_I2C_ALGOPCA is not set
922
923#
924# I2C Hardware Bus support
925#
926CONFIG_I2C_PXA=y
927# CONFIG_I2C_PXA_SLAVE is not set
928# CONFIG_I2C_PARPORT_LIGHT is not set
929# CONFIG_I2C_STUB is not set
930# CONFIG_I2C_PCA_ISA is not set
931
932#
933# Miscellaneous I2C Chip support
934#
935# CONFIG_SENSORS_DS1337 is not set
936# CONFIG_SENSORS_DS1374 is not set
937# CONFIG_SENSORS_EEPROM is not set
938# CONFIG_SENSORS_PCF8574 is not set
939# CONFIG_SENSORS_PCA9539 is not set
940# CONFIG_SENSORS_PCF8591 is not set
941# CONFIG_SENSORS_MAX6875 is not set
942# CONFIG_I2C_DEBUG_CORE is not set
943# CONFIG_I2C_DEBUG_ALGO is not set
944# CONFIG_I2C_DEBUG_BUS is not set
945# CONFIG_I2C_DEBUG_CHIP is not set
946
947#
948# SPI support
949#
950# CONFIG_SPI is not set
951# CONFIG_SPI_MASTER is not set
952
953#
954# Hardware Monitoring support
955#
956# CONFIG_HWMON is not set
957# CONFIG_HWMON_VID is not set
958
959#
960# Misc devices
961#
962
963#
964# Multimedia Capabilities Port drivers
965#
966
967#
968# Multi-Function Devices
969#
970
971#
972# LED devices
973#
974CONFIG_NEW_LEDS=y
975CONFIG_LEDS_CLASS=y
976CONFIG_LEDS_TRIGGERS=y
977CONFIG_LEDS_TOSA=y
978CONFIG_LEDS_TRIGGER_TIMER=m
979CONFIG_LEDS_TRIGGER_IDE_DISK=y
980
981#
982# Multimedia devices
983#
984CONFIG_VIDEO_DEV=m
985CONFIG_VIDEO_V4L1=y
986CONFIG_VIDEO_V4L1_COMPAT=y
987CONFIG_VIDEO_V4L2=y
988
989#
990# Video For Linux
991#
992
993#
994# Video Adapters
995#
996# CONFIG_VIDEO_ADV_DEBUG is not set
997# CONFIG_VIDEO_CPIA is not set
998# CONFIG_VIDEO_SAA5246A is not set
999# CONFIG_VIDEO_SAA5249 is not set
1000# CONFIG_TUNER_3036 is not set
1001# CONFIG_VIDEO_EM28XX is not set
1002# CONFIG_VIDEO_OVCAMCHIP is not set
1003# CONFIG_VIDEO_AUDIO_DECODER is not set
1004# CONFIG_VIDEO_DECODER is not set
1005
1006#
1007# Radio Adapters
1008#
1009# CONFIG_RADIO_MAESTRO is not set
1010
1011#
1012# Digital Video Broadcasting Devices
1013#
1014# CONFIG_DVB is not set
1015
1016#
1017# Graphics support
1018#
1019CONFIG_FB=y
1020CONFIG_FB_CFB_FILLRECT=y
1021CONFIG_FB_CFB_COPYAREA=y
1022CONFIG_FB_CFB_IMAGEBLIT=y
1023# CONFIG_FB_MACMODES is not set
1024# CONFIG_FB_MODE_HELPERS is not set
1025# CONFIG_FB_TILEBLITTING is not set
1026# CONFIG_FB_S1D13XXX is not set
1027# CONFIG_FB_PXA is not set
1028# CONFIG_FB_W100 is not set
1029CONFIG_FB_TMIO=y
1030# CONFIG_FB_VIRTUAL is not set
1031
1032#
1033# Console display driver support
1034#
1035# CONFIG_VGA_CONSOLE is not set
1036CONFIG_DUMMY_CONSOLE=y
1037CONFIG_FRAMEBUFFER_CONSOLE=y
1038# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1039CONFIG_FONTS=y
1040CONFIG_FONT_8x8=y
1041# CONFIG_FONT_8x16 is not set
1042# CONFIG_FONT_6x11 is not set
1043# CONFIG_FONT_7x14 is not set
1044# CONFIG_FONT_PEARL_8x8 is not set
1045# CONFIG_FONT_ACORN_8x8 is not set
1046# CONFIG_FONT_MINI_4x6 is not set
1047# CONFIG_FONT_SUN8x16 is not set
1048# CONFIG_FONT_SUN12x22 is not set
1049# CONFIG_FONT_10x18 is not set
1050
1051#
1052# Logo configuration
1053#
1054# CONFIG_LOGO is not set
1055# CONFIG_LOGO_LINUX_MONO is not set
1056# CONFIG_LOGO_LINUX_VGA16 is not set
1057# CONFIG_LOGO_LINUX_CLUT224 is not set
1058CONFIG_BACKLIGHT_LCD_SUPPORT=y
1059CONFIG_BACKLIGHT_CLASS_DEVICE=y
1060CONFIG_BACKLIGHT_DEVICE=y
1061# CONFIG_LCD_CLASS_DEVICE is not set
1062CONFIG_BACKLIGHT_CORGI=y
1063# CONFIG_BACKLIGHT_HP680 is not set
1064
1065#
1066# Sound
1067#
1068CONFIG_SOUND=y
1069
1070#
1071# Advanced Linux Sound Architecture
1072#
1073CONFIG_SND=y
1074CONFIG_SND_TIMER=y
1075CONFIG_SND_PCM=y
1076CONFIG_SND_HWDEP=m
1077CONFIG_SND_RAWMIDI=m
1078# CONFIG_SND_SEQUENCER is not set
1079CONFIG_SND_OSSEMUL=y
1080CONFIG_SND_MIXER_OSS=m
1081CONFIG_SND_PCM_OSS=m
1082# CONFIG_SND_DYNAMIC_MINORS is not set
1083# CONFIG_SND_SUPPORT_OLD_API is not set
1084# CONFIG_SND_VERBOSE_PRINTK is not set
1085# CONFIG_SND_DEBUG is not set
1086
1087#
1088# Generic devices
1089#
1090CONFIG_AC97_BUS=y
1091CONFIG_SND_DUMMY=m
1092# CONFIG_SND_MTPAV is not set
1093# CONFIG_SND_SERIAL_U16550 is not set
1094# CONFIG_SND_MPU401 is not set
1095
1096#
1097# ALSA ARM devices
1098#
1099# CONFIG_SND_PXA2XX_AC97 is not set
1100
1101#
1102# USB devices
1103#
1104CONFIG_SND_USB_AUDIO=m
1105
1106#
1107# PCMCIA devices
1108#
1109
1110#
1111# SoC audio support
1112#
1113CONFIG_SND_SOC=y
1114
1115#
1116# Soc Platforms
1117#
1118
1119#
1120# SoC Audio for the Intel PXA2xx
1121#
1122CONFIG_SND_PXA2XX_SOC=y
1123CONFIG_SND_PXA2XX_SOC_AC97=y
1124# CONFIG_SND_PXA2XX_SOC_MAINSTONE is not set
1125# CONFIG_SND_PXA2XX_SOC_MAINSTONE_WM8753 is not set
1126# CONFIG_SND_PXA2XX_SOC_MAINSTONE_WM9713 is not set
1127# CONFIG_SND_PXA2XX_SOC_MAINSTONE_WM9712 is not set
1128# CONFIG_SND_PXA2XX_SOC_CORGI is not set
1129# CONFIG_SND_PXA2XX_SOC_SPITZ is not set
1130CONFIG_SND_PXA2XX_SOC_TOSA=y
1131
1132#
1133# Soc Codecs
1134#
1135# CONFIG_SND_SOC_AC97_CODEC is not set
1136# CONFIG_SND_SOC_WM8731 is not set
1137# CONFIG_SND_SOC_WM8750 is not set
1138# CONFIG_SND_SOC_WM8753 is not set
1139# CONFIG_SND_SOC_WM8772 is not set
1140# CONFIG_SND_SOC_WM8971 is not set
1141# CONFIG_SND_SOC_WM9713 is not set
1142CONFIG_SND_SOC_WM9712=y
1143# CONFIG_SND_SOC_UDA1380 is not set
1144# CONFIG_SND_SOC_AK4535 is not set
1145
1146#
1147# Open Sound System
1148#
1149# CONFIG_SOUND_PRIME is not set
1150CONFIG_HID_SUPPORT=y
1151CONFIG_HID=m
1152
1153
1154#
1155# USB support
1156#
1157CONFIG_USB_ARCH_HAS_HCD=y
1158CONFIG_USB_ARCH_HAS_OHCI=y
1159CONFIG_USB=m
1160# CONFIG_USB_DEBUG is not set
1161
1162#
1163# Miscellaneous USB options
1164#
1165CONFIG_USB_DEVICEFS=y
1166# CONFIG_USB_BANDWIDTH is not set
1167# CONFIG_USB_DYNAMIC_MINORS is not set
1168# CONFIG_USB_SUSPEND is not set
1169# CONFIG_USB_OTG is not set
1170
1171#
1172# USB Host Controller Drivers
1173#
1174# CONFIG_USB_ISP116X_HCD is not set
1175CONFIG_USB_OHCI_HCD=m
1176# CONFIG_USB_OHCI_BIG_ENDIAN is not set
1177CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1178CONFIG_USB_SL811_HCD=m
1179CONFIG_USB_SL811_CS=m
1180
1181#
1182# USB Device Class drivers
1183#
1184# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
1185CONFIG_USB_ACM=m
1186CONFIG_USB_PRINTER=m
1187
1188#
1189# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1190#
1191
1192#
1193# may also be needed; see USB_STORAGE Help for more information
1194#
1195CONFIG_USB_STORAGE=m
1196# CONFIG_USB_STORAGE_DEBUG is not set
1197# CONFIG_USB_STORAGE_DATAFAB is not set
1198# CONFIG_USB_STORAGE_FREECOM is not set
1199# CONFIG_USB_STORAGE_ISD200 is not set
1200# CONFIG_USB_STORAGE_DPCM is not set
1201# CONFIG_USB_STORAGE_USBAT is not set
1202# CONFIG_USB_STORAGE_SDDR09 is not set
1203# CONFIG_USB_STORAGE_SDDR55 is not set
1204# CONFIG_USB_STORAGE_JUMPSHOT is not set
1205# CONFIG_USB_STORAGE_ALAUDA is not set
1206# CONFIG_USB_LIBUSUAL is not set
1207
1208#
1209# USB Input Devices
1210#
1211CONFIG_USB_HID=m
1212CONFIG_USB_HIDINPUT=y
1213# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1214# CONFIG_HID_FF is not set
1215# CONFIG_USB_HIDDEV is not set
1216
1217#
1218# USB HID Boot Protocol drivers
1219#
1220CONFIG_USB_KBD=m
1221CONFIG_USB_MOUSE=m
1222CONFIG_USB_AIPTEK=m
1223CONFIG_USB_WACOM=m
1224# CONFIG_USB_ACECAD is not set
1225CONFIG_USB_KBTAB=m
1226CONFIG_USB_POWERMATE=m
1227CONFIG_USB_MTOUCH=m
1228# CONFIG_USB_ITMTOUCH is not set
1229CONFIG_USB_EGALAX=m
1230# CONFIG_USB_YEALINK is not set
1231CONFIG_USB_XPAD=m
1232CONFIG_USB_ATI_REMOTE=m
1233# CONFIG_USB_ATI_REMOTE2 is not set
1234# CONFIG_USB_KEYSPAN_REMOTE is not set
1235# CONFIG_USB_APPLETOUCH is not set
1236
1237#
1238# USB Imaging devices
1239#
1240CONFIG_USB_MDC800=m
1241CONFIG_USB_MICROTEK=m
1242
1243#
1244# USB Multimedia devices
1245#
1246CONFIG_USB_DABUSB=m
1247CONFIG_USB_VICAM=m
1248CONFIG_USB_DSBR=m
1249# CONFIG_USB_ET61X251 is not set
1250CONFIG_USB_IBMCAM=m
1251CONFIG_USB_KONICAWC=m
1252CONFIG_USB_OV511=m
1253CONFIG_USB_SE401=m
1254CONFIG_USB_SN9C102=m
1255CONFIG_USB_STV680=m
1256# CONFIG_USB_PWC is not set
1257
1258#
1259# USB Network Adapters
1260#
1261CONFIG_USB_CATC=m
1262CONFIG_USB_KAWETH=m
1263CONFIG_USB_PEGASUS=m
1264CONFIG_USB_RTL8150=m
1265CONFIG_USB_USBNET=m
1266CONFIG_USB_NET_AX8817X=m
1267CONFIG_USB_NET_CDCETHER=m
1268CONFIG_USB_NET_GL620A=m
1269CONFIG_USB_NET_NET1080=m
1270CONFIG_USB_NET_PLUSB=m
1271# CONFIG_USB_NET_RNDIS_HOST is not set
1272# CONFIG_USB_NET_CDC_SUBSET is not set
1273# CONFIG_USB_NET_ZAURUS is not set
1274# CONFIG_USB_ZD1201 is not set
1275CONFIG_USB_MON=y
1276
1277#
1278# USB port drivers
1279#
1280
1281#
1282# USB Serial Converter support
1283#
1284CONFIG_USB_SERIAL=m
1285CONFIG_USB_SERIAL_GENERIC=y
1286# CONFIG_USB_SERIAL_AIRPRIME is not set
1287# CONFIG_USB_SERIAL_ANYDATA is not set
1288CONFIG_USB_SERIAL_BELKIN=m
1289# CONFIG_USB_SERIAL_WHITEHEAT is not set
1290CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1291# CONFIG_USB_SERIAL_CP2101 is not set
1292CONFIG_USB_SERIAL_CYPRESS_M8=m
1293CONFIG_USB_SERIAL_EMPEG=m
1294CONFIG_USB_SERIAL_FTDI_SIO=m
1295CONFIG_USB_SERIAL_VISOR=m
1296CONFIG_USB_SERIAL_IPAQ=m
1297CONFIG_USB_SERIAL_IR=m
1298CONFIG_USB_SERIAL_EDGEPORT=m
1299CONFIG_USB_SERIAL_EDGEPORT_TI=m
1300CONFIG_USB_SERIAL_GARMIN=m
1301CONFIG_USB_SERIAL_IPW=m
1302CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1303CONFIG_USB_SERIAL_KEYSPAN=m
1304# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1305# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1306# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1307# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1308# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1309# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1310# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1311# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1312# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1313# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1314# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1315# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1316CONFIG_USB_SERIAL_KLSI=m
1317CONFIG_USB_SERIAL_KOBIL_SCT=m
1318CONFIG_USB_SERIAL_MCT_U232=m
1319CONFIG_USB_SERIAL_PL2303=m
1320# CONFIG_USB_SERIAL_HP4X is not set
1321CONFIG_USB_SERIAL_SAFE=m
1322# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1323CONFIG_USB_SERIAL_TI=m
1324CONFIG_USB_SERIAL_CYBERJACK=m
1325CONFIG_USB_SERIAL_XIRCOM=m
1326# CONFIG_USB_SERIAL_OPTION is not set
1327CONFIG_USB_SERIAL_OMNINET=m
1328CONFIG_USB_EZUSB=y
1329
1330#
1331# USB Miscellaneous drivers
1332#
1333CONFIG_USB_EMI62=m
1334CONFIG_USB_EMI26=m
1335CONFIG_USB_AUERSWALD=m
1336CONFIG_USB_RIO500=m
1337CONFIG_USB_LEGOTOWER=m
1338CONFIG_USB_LCD=m
1339CONFIG_USB_LED=m
1340CONFIG_USB_CYTHERM=m
1341CONFIG_USB_PHIDGETKIT=m
1342CONFIG_USB_PHIDGETSERVO=m
1343CONFIG_USB_IDMOUSE=m
1344# CONFIG_USB_LD is not set
1345# CONFIG_USB_TEST is not set
1346
1347#
1348# USB DSL modem support
1349#
1350
1351#
1352# USB Gadget Support
1353#
1354CONFIG_USB_GADGET=m
1355# CONFIG_USB_GADGET_DEBUG_FILES is not set
1356CONFIG_USB_GADGET_SELECTED=y
1357# CONFIG_USB_GADGET_NET2280 is not set
1358CONFIG_USB_GADGET_PXA2XX=y
1359# CONFIG_USB_PXA2XX_SMALL is not set
1360# CONFIG_USB_GADGET_PXA27X is not set
1361# CONFIG_USB_GADGET_GOKU is not set
1362# CONFIG_USB_GADGET_LH7A40X is not set
1363# CONFIG_USB_GADGET_OMAP is not set
1364# CONFIG_USB_GADGET_DUMMY_HCD is not set
1365# CONFIG_USB_GADGET_DUALSPEED is not set
1366CONFIG_USB_ZERO=m
1367CONFIG_USB_ETH=m
1368CONFIG_USB_ETH_RNDIS=y
1369CONFIG_USB_GADGETFS=m
1370CONFIG_USB_FILE_STORAGE=m
1371# CONFIG_USB_FILE_STORAGE_TEST is not set
1372CONFIG_USB_G_SERIAL=m
1373
1374#
1375# MMC/SD Card support
1376#
1377CONFIG_MMC=y
1378# CONFIG_MMC_DEBUG is not set
1379CONFIG_MMC_BLOCK=y
1380CONFIG_MMC_PXA=y
1381CONFIG_MMC_UNSAFE_RESUME=y
1382
1383#
1384# Real Time Clock
1385#
1386CONFIG_RTC_CLASS=y
1387CONFIG_RTC_HCTOSYS=y
1388CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1389
1390#
1391# RTC interfaces
1392#
1393CONFIG_RTC_INTF_SYSFS=y
1394CONFIG_RTC_INTF_PROC=y
1395CONFIG_RTC_INTF_DEV=y
1396
1397#
1398# RTC drivers
1399#
1400# CONFIG_RTC_DRV_X1205 is not set
1401# CONFIG_RTC_DRV_DS1672 is not set
1402# CONFIG_RTC_DRV_PCF8563 is not set
1403# CONFIG_RTC_DRV_RS5C372 is not set
1404CONFIG_RTC_DRV_SA1100=y
1405# CONFIG_RTC_DRV_TEST is not set
1406
1407#
1408# File systems
1409#
1410CONFIG_EXT2_FS=y
1411# CONFIG_EXT2_FS_XATTR is not set
1412# CONFIG_EXT2_FS_XIP is not set
1413CONFIG_EXT3_FS=m
1414# CONFIG_REISERFS_FS is not set
1415# CONFIG_JFS_FS is not set
1416# CONFIG_FS_POSIX_ACL is not set
1417# CONFIG_XFS_FS is not set
1418# CONFIG_OCFS2_FS is not set
1419# CONFIG_MINIX_FS is not set
1420# CONFIG_ROMFS_FS is not set
1421CONFIG_INOTIFY=y
1422# CONFIG_QUOTA is not set
1423CONFIG_DNOTIFY=y
1424# CONFIG_AUTOFS_FS is not set
1425# CONFIG_AUTOFS4_FS is not set
1426CONFIG_FUSE_FS=m
1427
1428#
1429# CD-ROM/DVD Filesystems
1430#
1431CONFIG_ISO9660_FS=m
1432# CONFIG_UDF_FS is not set
1433
1434#
1435# DOS/FAT/NT Filesystems
1436#
1437CONFIG_FAT_FS=m
1438CONFIG_MSDOS_FS=m
1439CONFIG_VFAT_FS=m
1440CONFIG_FAT_DEFAULT_CODEPAGE=437
1441CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1442# CONFIG_NTFS_FS is not set
1443
1444#
1445# Pseudo filesystems
1446#
1447CONFIG_PROC_FS=y
1448CONFIG_SYSFS=y
1449CONFIG_TMPFS=y
1450# CONFIG_HUGETLB_PAGE is not set
1451# CONFIG_RAMFS is not set
1452# CONFIG_RELAYFS_FS is not set
1453# CONFIG_CONFIGFS_FS is not set
1454
1455#
1456# Miscellaneous filesystems
1457#
1458# CONFIG_ADFS_FS is not set
1459# CONFIG_AFFS_FS is not set
1460# CONFIG_HFS_FS is not set
1461# CONFIG_HFSPLUS_FS is not set
1462# CONFIG_BEFS_FS is not set
1463# CONFIG_BFS_FS is not set
1464# CONFIG_EFS_FS is not set
1465# CONFIG_JFFS_FS is not set
1466CONFIG_JFFS2_FS=y
1467CONFIG_JFFS2_FS_DEBUG=0
1468CONFIG_JFFS2_FS_WRITEBUFFER=y
1469CONFIG_JFFS2_SUMMARY=y
1470CONFIG_JFFS2_COMPRESSION_OPTIONS=y
1471CONFIG_JFFS2_ZLIB=y
1472CONFIG_JFFS2_RTIME=y
1473CONFIG_JFFS2_RUBIN=y
1474# CONFIG_JFFS2_CMODE_NONE is not set
1475CONFIG_JFFS2_CMODE_PRIORITY=y
1476# CONFIG_JFFS2_CMODE_SIZE is not set
1477CONFIG_CRAMFS=m
1478CONFIG_SQUASHFS=m
1479# CONFIG_SQUASHFS_EMBEDDED is not set
1480CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1481# CONFIG_SQUASHFS_VMALLOC is not set
1482# CONFIG_VXFS_FS is not set
1483# CONFIG_HPFS_FS is not set
1484# CONFIG_QNX4FS_FS is not set
1485# CONFIG_SYSV_FS is not set
1486# CONFIG_UFS_FS is not set
1487
1488#
1489# Network File Systems
1490#
1491CONFIG_NFS_FS=m
1492CONFIG_NFS_V3=y
1493# CONFIG_NFS_V3_ACL is not set
1494CONFIG_NFS_V4=y
1495# CONFIG_NFS_DIRECTIO is not set
1496# CONFIG_NFSD is not set
1497CONFIG_LOCKD=m
1498CONFIG_LOCKD_V4=y
1499CONFIG_NFS_COMMON=y
1500CONFIG_SUNRPC=m
1501CONFIG_SUNRPC_GSS=m
1502CONFIG_RPCSEC_GSS_KRB5=m
1503# CONFIG_RPCSEC_GSS_SPKM3 is not set
1504CONFIG_SMB_FS=m
1505CONFIG_SMB_NLS_DEFAULT=y
1506CONFIG_SMB_NLS_REMOTE="cp437"
1507CONFIG_CIFS=m
1508# CONFIG_CIFS_STATS is not set
1509# CONFIG_CIFS_XATTR is not set
1510# CONFIG_CIFS_EXPERIMENTAL is not set
1511# CONFIG_NCP_FS is not set
1512# CONFIG_CODA_FS is not set
1513# CONFIG_AFS_FS is not set
1514# CONFIG_9P_FS is not set
1515
1516#
1517# Partition Types
1518#
1519CONFIG_PARTITION_ADVANCED=y
1520# CONFIG_ACORN_PARTITION is not set
1521# CONFIG_OSF_PARTITION is not set
1522# CONFIG_AMIGA_PARTITION is not set
1523# CONFIG_ATARI_PARTITION is not set
1524# CONFIG_MAC_PARTITION is not set
1525CONFIG_MSDOS_PARTITION=y
1526# CONFIG_BSD_DISKLABEL is not set
1527# CONFIG_MINIX_SUBPARTITION is not set
1528# CONFIG_SOLARIS_X86_PARTITION is not set
1529# CONFIG_UNIXWARE_DISKLABEL is not set
1530# CONFIG_LDM_PARTITION is not set
1531# CONFIG_SGI_PARTITION is not set
1532# CONFIG_ULTRIX_PARTITION is not set
1533# CONFIG_SUN_PARTITION is not set
1534# CONFIG_KARMA_PARTITION is not set
1535# CONFIG_EFI_PARTITION is not set
1536
1537#
1538# Native Language Support
1539#
1540CONFIG_NLS=m
1541CONFIG_NLS_DEFAULT="cp437"
1542CONFIG_NLS_CODEPAGE_437=m
1543CONFIG_NLS_CODEPAGE_737=m
1544CONFIG_NLS_CODEPAGE_775=m
1545CONFIG_NLS_CODEPAGE_850=m
1546CONFIG_NLS_CODEPAGE_852=m
1547CONFIG_NLS_CODEPAGE_855=m
1548CONFIG_NLS_CODEPAGE_857=m
1549CONFIG_NLS_CODEPAGE_860=m
1550CONFIG_NLS_CODEPAGE_861=m
1551CONFIG_NLS_CODEPAGE_862=m
1552CONFIG_NLS_CODEPAGE_863=m
1553CONFIG_NLS_CODEPAGE_864=m
1554CONFIG_NLS_CODEPAGE_865=m
1555CONFIG_NLS_CODEPAGE_866=m
1556CONFIG_NLS_CODEPAGE_869=m
1557CONFIG_NLS_CODEPAGE_936=m
1558CONFIG_NLS_CODEPAGE_950=m
1559CONFIG_NLS_CODEPAGE_932=m
1560CONFIG_NLS_CODEPAGE_949=m
1561CONFIG_NLS_CODEPAGE_874=m
1562CONFIG_NLS_ISO8859_8=m
1563CONFIG_NLS_CODEPAGE_1250=m
1564CONFIG_NLS_CODEPAGE_1251=m
1565CONFIG_NLS_ASCII=m
1566CONFIG_NLS_ISO8859_1=m
1567CONFIG_NLS_ISO8859_2=m
1568CONFIG_NLS_ISO8859_3=m
1569CONFIG_NLS_ISO8859_4=m
1570CONFIG_NLS_ISO8859_5=m
1571CONFIG_NLS_ISO8859_6=m
1572CONFIG_NLS_ISO8859_7=m
1573CONFIG_NLS_ISO8859_9=m
1574CONFIG_NLS_ISO8859_13=m
1575CONFIG_NLS_ISO8859_14=m
1576CONFIG_NLS_ISO8859_15=m
1577CONFIG_NLS_KOI8_R=m
1578CONFIG_NLS_KOI8_U=m
1579CONFIG_NLS_UTF8=m
1580
1581#
1582# Profiling support
1583#
1584# CONFIG_PROFILING is not set
1585
1586#
1587# Kernel hacking
1588#
1589# CONFIG_PRINTK_TIME is not set
1590CONFIG_MAGIC_SYSRQ=y
1591CONFIG_DEBUG_KERNEL=y
1592CONFIG_LOG_BUF_SHIFT=14
1593CONFIG_DETECT_SOFTLOCKUP=y
1594CONFIG_TIMER_STATS=y
1595# CONFIG_SCHED_DEBUG is not set
1596# CONFIG_SCHEDSTATS is not set
1597# CONFIG_DEBUG_SLAB is not set
1598# CONFIG_DEBUG_PREEMPT is not set
1599# CONFIG_DEBUG_MUTEXES is not set
1600# CONFIG_DEBUG_SPINLOCK is not set
1601# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1602# CONFIG_DEBUG_KOBJECT is not set
1603# CONFIG_DEBUG_BUGVERBOSE is not set
1604# CONFIG_DEBUG_INFO is not set
1605# CONFIG_DEBUG_FS is not set
1606# CONFIG_DEBUG_VM is not set
1607CONFIG_FRAME_POINTER=y
1608# CONFIG_FORCED_INLINING is not set
1609# CONFIG_RCU_TORTURE_TEST is not set
1610# CONFIG_DEBUG_USER is not set
1611# CONFIG_DEBUG_WAITQ is not set
1612CONFIG_DEBUG_ERRORS=y
1613# CONFIG_DEBUG_LL is not set
1614
1615#
1616# Security options
1617#
1618# CONFIG_KEYS is not set
1619# CONFIG_SECURITY is not set
1620
1621#
1622# Cryptographic options
1623#
1624CONFIG_CRYPTO=y
1625CONFIG_CRYPTO_ALGAPI=m
1626CONFIG_CRYPTO_HMAC=m
1627CONFIG_CRYPTO_NULL=m
1628CONFIG_CRYPTO_MD4=m
1629CONFIG_CRYPTO_MD5=m
1630CONFIG_CRYPTO_SHA1=m
1631CONFIG_CRYPTO_SHA256=m
1632CONFIG_CRYPTO_SHA512=m
1633CONFIG_CRYPTO_WP512=m
1634# CONFIG_CRYPTO_TGR192 is not set
1635CONFIG_CRYPTO_DES=m
1636CONFIG_CRYPTO_BLOWFISH=m
1637CONFIG_CRYPTO_TWOFISH=m
1638CONFIG_CRYPTO_SERPENT=m
1639CONFIG_CRYPTO_AES=m
1640CONFIG_CRYPTO_CAST5=m
1641CONFIG_CRYPTO_CAST6=m
1642CONFIG_CRYPTO_TEA=m
1643CONFIG_CRYPTO_ARC4=m
1644CONFIG_CRYPTO_KHAZAD=m
1645CONFIG_CRYPTO_ANUBIS=m
1646CONFIG_CRYPTO_DEFLATE=m
1647CONFIG_CRYPTO_MICHAEL_MIC=m
1648CONFIG_CRYPTO_CRC32C=m
1649CONFIG_CRYPTO_TEST=m
1650
1651#
1652# Hardware crypto devices
1653#
1654
1655#
1656# Library routines
1657#
1658CONFIG_CRC_CCITT=m
1659# CONFIG_CRC16 is not set
1660CONFIG_CRC32=y
1661CONFIG_LIBCRC32C=m
1662CONFIG_ZLIB_INFLATE=y
1663CONFIG_ZLIB_DEFLATE=y
1664CONFIG_GENERIC_ALLOCATOR=y
1665# CONFIG_SHARPSL_RC is not set
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-zylonite b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-zylonite
new file mode 100644
index 0000000000..d98974989f
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/defconfig-zylonite
@@ -0,0 +1,1527 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Mon Feb 18 01:42:46 2008
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_ARCH_MTD_XIP=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_INIT_ENV_ARG_LIMIT=32
35CONFIG_LOCALVERSION=""
36# CONFIG_LOCALVERSION_AUTO is not set
37CONFIG_SWAP=y
38CONFIG_SYSVIPC=y
39CONFIG_SYSVIPC_SYSCTL=y
40# CONFIG_POSIX_MQUEUE is not set
41# CONFIG_BSD_PROCESS_ACCT is not set
42# CONFIG_TASKSTATS is not set
43# CONFIG_USER_NS is not set
44# CONFIG_AUDIT is not set
45# CONFIG_IKCONFIG is not set
46CONFIG_LOG_BUF_SHIFT=14
47CONFIG_SYSFS_DEPRECATED=y
48# CONFIG_RELAY is not set
49CONFIG_BLK_DEV_INITRD=y
50CONFIG_INITRAMFS_SOURCE=""
51CONFIG_CC_OPTIMIZE_FOR_SIZE=y
52CONFIG_SYSCTL=y
53# CONFIG_EMBEDDED is not set
54CONFIG_UID16=y
55CONFIG_SYSCTL_SYSCALL=y
56CONFIG_KALLSYMS=y
57# CONFIG_KALLSYMS_ALL is not set
58# CONFIG_KALLSYMS_EXTRA_PASS is not set
59CONFIG_HOTPLUG=y
60CONFIG_PRINTK=y
61CONFIG_BUG=y
62CONFIG_ELF_CORE=y
63CONFIG_BASE_FULL=y
64CONFIG_FUTEX=y
65CONFIG_ANON_INODES=y
66CONFIG_EPOLL=y
67CONFIG_SIGNALFD=y
68CONFIG_EVENTFD=y
69CONFIG_SHMEM=y
70CONFIG_VM_EVENT_COUNTERS=y
71CONFIG_SLAB=y
72# CONFIG_SLUB is not set
73# CONFIG_SLOB is not set
74CONFIG_RT_MUTEXES=y
75# CONFIG_TINY_SHMEM is not set
76CONFIG_BASE_SMALL=0
77CONFIG_MODULES=y
78CONFIG_MODULE_UNLOAD=y
79CONFIG_MODULE_FORCE_UNLOAD=y
80# CONFIG_MODVERSIONS is not set
81# CONFIG_MODULE_SRCVERSION_ALL is not set
82# CONFIG_KMOD is not set
83CONFIG_BLOCK=y
84# CONFIG_LBD is not set
85# CONFIG_BLK_DEV_IO_TRACE is not set
86# CONFIG_LSF is not set
87# CONFIG_BLK_DEV_BSG is not set
88
89#
90# IO Schedulers
91#
92CONFIG_IOSCHED_NOOP=y
93CONFIG_IOSCHED_AS=y
94CONFIG_IOSCHED_DEADLINE=y
95CONFIG_IOSCHED_CFQ=y
96# CONFIG_DEFAULT_AS is not set
97# CONFIG_DEFAULT_DEADLINE is not set
98CONFIG_DEFAULT_CFQ=y
99# CONFIG_DEFAULT_NOOP is not set
100CONFIG_DEFAULT_IOSCHED="cfq"
101
102#
103# System Type
104#
105# CONFIG_ARCH_AAEC2000 is not set
106# CONFIG_ARCH_INTEGRATOR is not set
107# CONFIG_ARCH_REALVIEW is not set
108# CONFIG_ARCH_VERSATILE is not set
109# CONFIG_ARCH_AT91 is not set
110# CONFIG_ARCH_CLPS7500 is not set
111# CONFIG_ARCH_CLPS711X is not set
112# CONFIG_ARCH_CO285 is not set
113# CONFIG_ARCH_EBSA110 is not set
114# CONFIG_ARCH_EP93XX is not set
115# CONFIG_ARCH_FOOTBRIDGE is not set
116# CONFIG_ARCH_NETX is not set
117# CONFIG_ARCH_H720X is not set
118# CONFIG_ARCH_IMX is not set
119# CONFIG_ARCH_IOP13XX is not set
120# CONFIG_ARCH_IOP32X is not set
121# CONFIG_ARCH_IOP33X is not set
122# CONFIG_ARCH_IXP23XX is not set
123# CONFIG_ARCH_IXP2000 is not set
124# CONFIG_ARCH_IXP4XX is not set
125# CONFIG_ARCH_L7200 is not set
126# CONFIG_ARCH_KS8695 is not set
127# CONFIG_ARCH_NS9XXX is not set
128# CONFIG_ARCH_MXC is not set
129# CONFIG_ARCH_PNX4008 is not set
130CONFIG_ARCH_PXA=y
131# CONFIG_ARCH_RPC is not set
132# CONFIG_ARCH_SA1100 is not set
133# CONFIG_ARCH_S3C2410 is not set
134# CONFIG_ARCH_SHARK is not set
135# CONFIG_ARCH_LH7A40X is not set
136# CONFIG_ARCH_DAVINCI is not set
137# CONFIG_ARCH_OMAP is not set
138
139#
140# Intel PXA2xx/PXA3xx Implementations
141#
142
143#
144# Supported PXA3xx Processor Variants
145#
146CONFIG_CPU_PXA300=y
147CONFIG_CPU_PXA310=y
148CONFIG_CPU_PXA320=y
149# CONFIG_ARCH_LUBBOCK is not set
150# CONFIG_MACH_LOGICPD_PXA270 is not set
151# CONFIG_MACH_MAINSTONE is not set
152# CONFIG_ARCH_PXA_IDP is not set
153# CONFIG_PXA_SHARPSL is not set
154# CONFIG_MACH_TRIZEPS4 is not set
155# CONFIG_MACH_EM_X270 is not set
156CONFIG_MACH_ZYLONITE=y
157# CONFIG_MACH_HX2750 is not set
158# CONFIG_MACH_HTCUNIVERSAL is not set
159CONFIG_PXA3xx=y
160
161#
162# Boot options
163#
164
165#
166# Power management
167#
168
169#
170# Processor Type
171#
172CONFIG_CPU_32=y
173CONFIG_CPU_XSC3=y
174CONFIG_CPU_32v5=y
175CONFIG_CPU_ABRT_EV5T=y
176CONFIG_CPU_CACHE_VIVT=y
177CONFIG_CPU_TLB_V4WBI=y
178CONFIG_CPU_CP15=y
179CONFIG_CPU_CP15_MMU=y
180CONFIG_IO_36=y
181
182#
183# Processor Features
184#
185# CONFIG_ARM_THUMB is not set
186# CONFIG_CPU_DCACHE_DISABLE is not set
187# CONFIG_CPU_BPREDICT_DISABLE is not set
188# CONFIG_OUTER_CACHE is not set
189CONFIG_IWMMXT=y
190
191#
192# Bus support
193#
194# CONFIG_PCI_SYSCALL is not set
195# CONFIG_ARCH_SUPPORTS_MSI is not set
196
197#
198# PCCARD (PCMCIA/CardBus) support
199#
200# CONFIG_PCCARD is not set
201
202#
203# Kernel Features
204#
205# CONFIG_TICK_ONESHOT is not set
206# CONFIG_NO_HZ is not set
207# CONFIG_HIGH_RES_TIMERS is not set
208# CONFIG_PREEMPT is not set
209CONFIG_HZ=100
210CONFIG_AEABI=y
211CONFIG_OABI_COMPAT=y
212# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
213CONFIG_SELECT_MEMORY_MODEL=y
214CONFIG_FLATMEM_MANUAL=y
215# CONFIG_DISCONTIGMEM_MANUAL is not set
216# CONFIG_SPARSEMEM_MANUAL is not set
217CONFIG_FLATMEM=y
218CONFIG_FLAT_NODE_MEM_MAP=y
219# CONFIG_SPARSEMEM_STATIC is not set
220CONFIG_SPLIT_PTLOCK_CPUS=4096
221CONFIG_RESOURCES_64BIT=y
222CONFIG_ZONE_DMA_FLAG=1
223CONFIG_BOUNCE=y
224CONFIG_VIRT_TO_BUS=y
225CONFIG_ALIGNMENT_TRAP=y
226
227#
228# Boot options
229#
230CONFIG_ZBOOT_ROM_TEXT=0x0
231CONFIG_ZBOOT_ROM_BSS=0x0
232CONFIG_CMDLINE="console=ttyS0,38400 root=/dev/mtdblock2 rootfstype=jffs2 mem=64M dyntick=enable debug"
233# CONFIG_XIP_KERNEL is not set
234CONFIG_KEXEC=y
235CONFIG_ATAGS_PROC=y
236
237#
238# CPU Frequency scaling
239#
240# CONFIG_CPU_FREQ is not set
241
242#
243# Floating point emulation
244#
245
246#
247# At least one emulation must be selected
248#
249CONFIG_FPE_NWFPE=y
250# CONFIG_FPE_NWFPE_XP is not set
251# CONFIG_FPE_FASTFPE is not set
252
253#
254# Userspace binary formats
255#
256CONFIG_BINFMT_ELF=y
257# CONFIG_BINFMT_AOUT is not set
258# CONFIG_BINFMT_MISC is not set
259
260#
261# Power management options
262#
263# CONFIG_PM is not set
264CONFIG_SUSPEND_UP_POSSIBLE=y
265
266#
267# Networking
268#
269CONFIG_NET=y
270
271#
272# Networking options
273#
274CONFIG_PACKET=m
275# CONFIG_PACKET_MMAP is not set
276CONFIG_UNIX=y
277CONFIG_XFRM=y
278# CONFIG_XFRM_USER is not set
279# CONFIG_XFRM_SUB_POLICY is not set
280# CONFIG_XFRM_MIGRATE is not set
281# CONFIG_NET_KEY is not set
282CONFIG_INET=y
283# CONFIG_IP_MULTICAST is not set
284# CONFIG_IP_ADVANCED_ROUTER is not set
285CONFIG_IP_FIB_HASH=y
286CONFIG_IP_PNP=y
287# CONFIG_IP_PNP_DHCP is not set
288# CONFIG_IP_PNP_BOOTP is not set
289# CONFIG_IP_PNP_RARP is not set
290# CONFIG_NET_IPIP is not set
291# CONFIG_NET_IPGRE is not set
292# CONFIG_ARPD is not set
293# CONFIG_SYN_COOKIES is not set
294# CONFIG_INET_AH is not set
295# CONFIG_INET_ESP is not set
296# CONFIG_INET_IPCOMP is not set
297# CONFIG_INET_XFRM_TUNNEL is not set
298# CONFIG_INET_TUNNEL is not set
299CONFIG_INET_XFRM_MODE_TRANSPORT=y
300CONFIG_INET_XFRM_MODE_TUNNEL=y
301CONFIG_INET_XFRM_MODE_BEET=y
302CONFIG_INET_DIAG=y
303CONFIG_INET_TCP_DIAG=y
304# CONFIG_TCP_CONG_ADVANCED is not set
305CONFIG_TCP_CONG_CUBIC=y
306CONFIG_DEFAULT_TCP_CONG="cubic"
307# CONFIG_TCP_MD5SIG is not set
308# CONFIG_IP_VS is not set
309# CONFIG_IPV6 is not set
310# CONFIG_INET6_XFRM_TUNNEL is not set
311# CONFIG_INET6_TUNNEL is not set
312# CONFIG_NETWORK_SECMARK is not set
313CONFIG_NETFILTER=y
314# CONFIG_NETFILTER_DEBUG is not set
315
316#
317# Core Netfilter Configuration
318#
319# CONFIG_NETFILTER_NETLINK is not set
320# CONFIG_NF_CONNTRACK_ENABLED is not set
321# CONFIG_NF_CONNTRACK is not set
322CONFIG_NETFILTER_XTABLES=m
323# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
324# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
325# CONFIG_NETFILTER_XT_TARGET_MARK is not set
326# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
327# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
328# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
329# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
330# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
331# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
332# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
333# CONFIG_NETFILTER_XT_MATCH_ESP is not set
334# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
335# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
336# CONFIG_NETFILTER_XT_MATCH_MAC is not set
337# CONFIG_NETFILTER_XT_MATCH_MARK is not set
338# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
339# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
340# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
341# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
342# CONFIG_NETFILTER_XT_MATCH_REALM is not set
343# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
344# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
345# CONFIG_NETFILTER_XT_MATCH_STRING is not set
346# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
347# CONFIG_NETFILTER_XT_MATCH_U32 is not set
348# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
349
350#
351# IP: Netfilter Configuration
352#
353CONFIG_IP_NF_QUEUE=m
354CONFIG_IP_NF_IPTABLES=m
355CONFIG_IP_NF_MATCH_IPRANGE=m
356CONFIG_IP_NF_MATCH_TOS=m
357CONFIG_IP_NF_MATCH_RECENT=m
358CONFIG_IP_NF_MATCH_ECN=m
359CONFIG_IP_NF_MATCH_AH=m
360CONFIG_IP_NF_MATCH_TTL=m
361CONFIG_IP_NF_MATCH_OWNER=m
362CONFIG_IP_NF_MATCH_ADDRTYPE=m
363CONFIG_IP_NF_FILTER=m
364CONFIG_IP_NF_TARGET_REJECT=m
365CONFIG_IP_NF_TARGET_LOG=m
366CONFIG_IP_NF_TARGET_ULOG=m
367CONFIG_IP_NF_MANGLE=m
368CONFIG_IP_NF_TARGET_TOS=m
369CONFIG_IP_NF_TARGET_ECN=m
370CONFIG_IP_NF_TARGET_TTL=m
371CONFIG_IP_NF_RAW=m
372CONFIG_IP_NF_ARPTABLES=m
373CONFIG_IP_NF_ARPFILTER=m
374CONFIG_IP_NF_ARP_MANGLE=m
375# CONFIG_IP_DCCP is not set
376# CONFIG_IP_SCTP is not set
377# CONFIG_TIPC is not set
378# CONFIG_ATM is not set
379# CONFIG_BRIDGE is not set
380# CONFIG_VLAN_8021Q is not set
381# CONFIG_DECNET is not set
382# CONFIG_LLC2 is not set
383# CONFIG_IPX is not set
384# CONFIG_ATALK is not set
385# CONFIG_X25 is not set
386# CONFIG_LAPB is not set
387# CONFIG_ECONET is not set
388# CONFIG_WAN_ROUTER is not set
389
390#
391# QoS and/or fair queueing
392#
393# CONFIG_NET_SCHED is not set
394
395#
396# Network testing
397#
398# CONFIG_NET_PKTGEN is not set
399# CONFIG_HAMRADIO is not set
400CONFIG_IRDA=y
401
402#
403# IrDA protocols
404#
405# CONFIG_IRLAN is not set
406# CONFIG_IRCOMM is not set
407# CONFIG_IRDA_ULTRA is not set
408
409#
410# IrDA options
411#
412# CONFIG_IRDA_CACHE_LAST_LSAP is not set
413# CONFIG_IRDA_FAST_RR is not set
414# CONFIG_IRDA_DEBUG is not set
415
416#
417# Infrared-port device drivers
418#
419
420#
421# SIR device drivers
422#
423# CONFIG_IRTTY_SIR is not set
424
425#
426# Dongle support
427#
428# CONFIG_KINGSUN_DONGLE is not set
429
430#
431# Old SIR device drivers
432#
433# CONFIG_IRPORT_SIR is not set
434
435#
436# Old Serial dongle support
437#
438
439#
440# FIR device drivers
441#
442# CONFIG_USB_IRDA is not set
443# CONFIG_SIGMATEL_FIR is not set
444# CONFIG_PXA_FICP is not set
445# CONFIG_MCS_FIR is not set
446# CONFIG_BT is not set
447# CONFIG_AF_RXRPC is not set
448
449#
450# Wireless
451#
452# CONFIG_CFG80211 is not set
453# CONFIG_WIRELESS_EXT is not set
454# CONFIG_MAC80211 is not set
455# CONFIG_IEEE80211 is not set
456# CONFIG_RFKILL is not set
457# CONFIG_NET_9P is not set
458
459#
460# Device Drivers
461#
462
463#
464# Generic Driver Options
465#
466# CONFIG_STANDALONE is not set
467# CONFIG_PREVENT_FIRMWARE_BUILD is not set
468CONFIG_FW_LOADER=y
469# CONFIG_DEBUG_DRIVER is not set
470# CONFIG_DEBUG_DEVRES is not set
471# CONFIG_SYS_HYPERVISOR is not set
472# CONFIG_CONNECTOR is not set
473CONFIG_MTD=y
474# CONFIG_MTD_DEBUG is not set
475# CONFIG_MTD_CONCAT is not set
476CONFIG_MTD_PARTITIONS=y
477# CONFIG_MTD_REDBOOT_PARTS is not set
478CONFIG_MTD_CMDLINE_PARTS=y
479# CONFIG_MTD_AFS_PARTS is not set
480
481#
482# User Modules And Translation Layers
483#
484CONFIG_MTD_CHAR=y
485CONFIG_MTD_BLKDEVS=y
486CONFIG_MTD_BLOCK=y
487# CONFIG_FTL is not set
488# CONFIG_NFTL is not set
489# CONFIG_INFTL is not set
490# CONFIG_RFD_FTL is not set
491# CONFIG_SSFDC is not set
492
493#
494# RAM/ROM/Flash chip drivers
495#
496CONFIG_MTD_CFI=y
497# CONFIG_MTD_JEDECPROBE is not set
498CONFIG_MTD_GEN_PROBE=y
499CONFIG_MTD_CFI_ADV_OPTIONS=y
500CONFIG_MTD_CFI_NOSWAP=y
501# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
502# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
503CONFIG_MTD_CFI_GEOMETRY=y
504CONFIG_MTD_MAP_BANK_WIDTH_1=y
505CONFIG_MTD_MAP_BANK_WIDTH_2=y
506CONFIG_MTD_MAP_BANK_WIDTH_4=y
507# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
508# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
509# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
510CONFIG_MTD_CFI_I1=y
511CONFIG_MTD_CFI_I2=y
512# CONFIG_MTD_CFI_I4 is not set
513# CONFIG_MTD_CFI_I8 is not set
514# CONFIG_MTD_OTP is not set
515CONFIG_MTD_CFI_INTELEXT=y
516# CONFIG_MTD_CFI_AMDSTD is not set
517# CONFIG_MTD_CFI_STAA is not set
518CONFIG_MTD_CFI_UTIL=y
519# CONFIG_MTD_RAM is not set
520CONFIG_MTD_ROM=y
521# CONFIG_MTD_ABSENT is not set
522# CONFIG_MTD_XIP is not set
523
524#
525# Mapping drivers for chip access
526#
527# CONFIG_MTD_COMPLEX_MAPPINGS is not set
528# CONFIG_MTD_PHYSMAP is not set
529# CONFIG_MTD_ARM_INTEGRATOR is not set
530# CONFIG_MTD_SHARP_SL is not set
531# CONFIG_MTD_PLATRAM is not set
532
533#
534# Self-contained MTD device drivers
535#
536# CONFIG_MTD_SLRAM is not set
537# CONFIG_MTD_PHRAM is not set
538# CONFIG_MTD_MTDRAM is not set
539# CONFIG_MTD_BLOCK2MTD is not set
540
541#
542# Disk-On-Chip Device Drivers
543#
544# CONFIG_MTD_DOC2000 is not set
545# CONFIG_MTD_DOC2001 is not set
546# CONFIG_MTD_DOC2001PLUS is not set
547CONFIG_MTD_NAND=y
548# CONFIG_MTD_NAND_VERIFY_WRITE is not set
549# CONFIG_MTD_NAND_ECC_SMC is not set
550# CONFIG_MTD_NAND_MUSEUM_IDS is not set
551# CONFIG_MTD_NAND_H1900 is not set
552CONFIG_MTD_NAND_IDS=y
553# CONFIG_MTD_NAND_DISKONCHIP is not set
554# CONFIG_MTD_NAND_SHARPSL is not set
555CONFIG_MTD_NAND_ZYLONITE=y
556# CONFIG_MTD_NAND_NANDSIM is not set
557# CONFIG_MTD_NAND_PLATFORM is not set
558# CONFIG_MTD_ONENAND is not set
559
560#
561# UBI - Unsorted block images
562#
563# CONFIG_MTD_UBI is not set
564# CONFIG_PARPORT is not set
565CONFIG_BLK_DEV=y
566# CONFIG_BLK_DEV_COW_COMMON is not set
567CONFIG_BLK_DEV_LOOP=y
568# CONFIG_BLK_DEV_CRYPTOLOOP is not set
569# CONFIG_BLK_DEV_NBD is not set
570# CONFIG_BLK_DEV_UB is not set
571CONFIG_BLK_DEV_RAM=y
572CONFIG_BLK_DEV_RAM_COUNT=16
573CONFIG_BLK_DEV_RAM_SIZE=4096
574CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
575# CONFIG_CDROM_PKTCDVD is not set
576# CONFIG_ATA_OVER_ETH is not set
577CONFIG_IDE=y
578CONFIG_BLK_DEV_IDE=y
579
580#
581# Please see Documentation/ide.txt for help/info on IDE drives
582#
583# CONFIG_BLK_DEV_IDE_SATA is not set
584CONFIG_BLK_DEV_IDEDISK=y
585# CONFIG_IDEDISK_MULTI_MODE is not set
586# CONFIG_BLK_DEV_IDECD is not set
587# CONFIG_BLK_DEV_IDETAPE is not set
588# CONFIG_BLK_DEV_IDEFLOPPY is not set
589# CONFIG_BLK_DEV_IDESCSI is not set
590# CONFIG_IDE_TASK_IOCTL is not set
591CONFIG_IDE_PROC_FS=y
592
593#
594# IDE chipset support/bugfixes
595#
596# CONFIG_IDE_GENERIC is not set
597# CONFIG_IDEPCI_PCIBUS_ORDER is not set
598# CONFIG_IDE_ARM is not set
599# CONFIG_BLK_DEV_IDEDMA is not set
600# CONFIG_BLK_DEV_HD is not set
601
602#
603# SCSI device support
604#
605# CONFIG_RAID_ATTRS is not set
606CONFIG_SCSI=y
607CONFIG_SCSI_DMA=y
608# CONFIG_SCSI_TGT is not set
609# CONFIG_SCSI_NETLINK is not set
610CONFIG_SCSI_PROC_FS=y
611
612#
613# SCSI support type (disk, tape, CD-ROM)
614#
615CONFIG_BLK_DEV_SD=y
616# CONFIG_CHR_DEV_ST is not set
617# CONFIG_CHR_DEV_OSST is not set
618# CONFIG_BLK_DEV_SR is not set
619# CONFIG_CHR_DEV_SG is not set
620# CONFIG_CHR_DEV_SCH is not set
621
622#
623# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
624#
625# CONFIG_SCSI_MULTI_LUN is not set
626# CONFIG_SCSI_CONSTANTS is not set
627# CONFIG_SCSI_LOGGING is not set
628# CONFIG_SCSI_SCAN_ASYNC is not set
629CONFIG_SCSI_WAIT_SCAN=m
630
631#
632# SCSI Transports
633#
634# CONFIG_SCSI_SPI_ATTRS is not set
635# CONFIG_SCSI_FC_ATTRS is not set
636# CONFIG_SCSI_ISCSI_ATTRS is not set
637# CONFIG_SCSI_SAS_LIBSAS is not set
638CONFIG_SCSI_LOWLEVEL=y
639# CONFIG_ISCSI_TCP is not set
640# CONFIG_SCSI_DEBUG is not set
641# CONFIG_ATA is not set
642# CONFIG_MD is not set
643CONFIG_NETDEVICES=y
644# CONFIG_NETDEVICES_MULTIQUEUE is not set
645# CONFIG_DUMMY is not set
646# CONFIG_BONDING is not set
647# CONFIG_MACVLAN is not set
648# CONFIG_EQUALIZER is not set
649# CONFIG_TUN is not set
650# CONFIG_PHYLIB is not set
651CONFIG_NET_ETHERNET=y
652CONFIG_MII=y
653# CONFIG_AX88796 is not set
654CONFIG_SMC91X=y
655# CONFIG_DM9000 is not set
656# CONFIG_SMC911X is not set
657CONFIG_NETDEV_1000=y
658CONFIG_NETDEV_10000=y
659
660#
661# Wireless LAN
662#
663# CONFIG_WLAN_PRE80211 is not set
664# CONFIG_WLAN_80211 is not set
665
666#
667# USB Network Adapters
668#
669# CONFIG_USB_CATC is not set
670# CONFIG_USB_KAWETH is not set
671# CONFIG_USB_PEGASUS is not set
672# CONFIG_USB_RTL8150 is not set
673# CONFIG_USB_USBNET_MII is not set
674CONFIG_USB_USBNET=y
675# CONFIG_USB_NET_AX8817X is not set
676CONFIG_USB_NET_CDCETHER=y
677# CONFIG_USB_NET_DM9601 is not set
678# CONFIG_USB_NET_GL620A is not set
679# CONFIG_USB_NET_NET1080 is not set
680# CONFIG_USB_NET_PLUSB is not set
681# CONFIG_USB_NET_MCS7830 is not set
682# CONFIG_USB_NET_RNDIS_HOST is not set
683CONFIG_USB_NET_CDC_SUBSET=y
684# CONFIG_USB_ALI_M5632 is not set
685# CONFIG_USB_AN2720 is not set
686# CONFIG_USB_BELKIN is not set
687CONFIG_USB_ARMLINUX=y
688# CONFIG_USB_EPSON2888 is not set
689# CONFIG_USB_KC2190 is not set
690# CONFIG_USB_NET_ZAURUS is not set
691# CONFIG_WAN is not set
692# CONFIG_PPP is not set
693# CONFIG_SLIP is not set
694# CONFIG_SHAPER is not set
695# CONFIG_NETCONSOLE is not set
696# CONFIG_NETPOLL is not set
697# CONFIG_NET_POLL_CONTROLLER is not set
698# CONFIG_ISDN is not set
699
700#
701# Input device support
702#
703CONFIG_INPUT=y
704# CONFIG_INPUT_FF_MEMLESS is not set
705# CONFIG_INPUT_POLLDEV is not set
706
707#
708# Userland interfaces
709#
710CONFIG_INPUT_MOUSEDEV=y
711# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
712CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
713CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
714# CONFIG_INPUT_JOYDEV is not set
715CONFIG_INPUT_TSDEV=y
716CONFIG_INPUT_TSDEV_SCREEN_X=240
717CONFIG_INPUT_TSDEV_SCREEN_Y=320
718CONFIG_INPUT_EVDEV=y
719# CONFIG_INPUT_EVBUG is not set
720# CONFIG_INPUT_POWER is not set
721
722#
723# Input Device Drivers
724#
725CONFIG_INPUT_KEYBOARD=y
726CONFIG_KEYBOARD_ATKBD=y
727# CONFIG_KEYBOARD_SUNKBD is not set
728# CONFIG_KEYBOARD_LKKBD is not set
729# CONFIG_KEYBOARD_XTKBD is not set
730# CONFIG_KEYBOARD_NEWTON is not set
731# CONFIG_KEYBOARD_STOWAWAY is not set
732CONFIG_KEYBOARD_PXA27x=y
733# CONFIG_KEYBOARD_GPIO is not set
734# CONFIG_INPUT_MOUSE is not set
735# CONFIG_INPUT_JOYSTICK is not set
736# CONFIG_INPUT_TABLET is not set
737CONFIG_INPUT_TOUCHSCREEN=y
738CONFIG_TOUCHSCREEN_ZYLONITE=y
739# CONFIG_TOUCHSCREEN_FUJITSU is not set
740# CONFIG_TOUCHSCREEN_GUNZE is not set
741# CONFIG_TOUCHSCREEN_ELO is not set
742# CONFIG_TOUCHSCREEN_MTOUCH is not set
743# CONFIG_TOUCHSCREEN_MK712 is not set
744# CONFIG_TOUCHSCREEN_PENMOUNT is not set
745# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
746# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
747# CONFIG_TOUCHSCREEN_UCB1400 is not set
748# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
749# CONFIG_INPUT_MISC is not set
750
751#
752# Hardware I/O ports
753#
754CONFIG_SERIO=y
755# CONFIG_SERIO_SERPORT is not set
756CONFIG_SERIO_LIBPS2=y
757# CONFIG_SERIO_RAW is not set
758# CONFIG_GAMEPORT is not set
759
760#
761# Character devices
762#
763CONFIG_VT=y
764CONFIG_VT_CONSOLE=y
765CONFIG_HW_CONSOLE=y
766# CONFIG_VT_HW_CONSOLE_BINDING is not set
767# CONFIG_SERIAL_NONSTANDARD is not set
768
769#
770# Serial drivers
771#
772# CONFIG_SERIAL_8250 is not set
773
774#
775# Non-8250 serial port support
776#
777CONFIG_SERIAL_PXA=y
778CONFIG_SERIAL_PXA_CONSOLE=y
779CONFIG_SERIAL_CORE=y
780CONFIG_SERIAL_CORE_CONSOLE=y
781CONFIG_UNIX98_PTYS=y
782# CONFIG_LEGACY_PTYS is not set
783# CONFIG_IPMI_HANDLER is not set
784# CONFIG_WATCHDOG is not set
785# CONFIG_HW_RANDOM is not set
786# CONFIG_NVRAM is not set
787# CONFIG_R3964 is not set
788# CONFIG_RAW_DRIVER is not set
789# CONFIG_TCG_TPM is not set
790CONFIG_I2C=y
791CONFIG_I2C_BOARDINFO=y
792CONFIG_I2C_CHARDEV=y
793
794#
795# I2C Algorithms
796#
797# CONFIG_I2C_ALGOBIT is not set
798# CONFIG_I2C_ALGOPCF is not set
799# CONFIG_I2C_ALGOPCA is not set
800
801#
802# I2C Hardware Bus support
803#
804# CONFIG_I2C_GPIO is not set
805CONFIG_I2C_PXA=y
806# CONFIG_I2C_PXA_SLAVE is not set
807# CONFIG_I2C_OCORES is not set
808# CONFIG_I2C_PARPORT_LIGHT is not set
809# CONFIG_I2C_SIMTEC is not set
810# CONFIG_I2C_TAOS_EVM is not set
811# CONFIG_I2C_STUB is not set
812# CONFIG_I2C_TINY_USB is not set
813
814#
815# Miscellaneous I2C Chip support
816#
817# CONFIG_SENSORS_DS1337 is not set
818# CONFIG_SENSORS_DS1374 is not set
819# CONFIG_DS1682 is not set
820# CONFIG_SENSORS_EEPROM is not set
821# CONFIG_SENSORS_PCF8574 is not set
822# CONFIG_SENSORS_PCA9539 is not set
823# CONFIG_SENSORS_PCF8591 is not set
824# CONFIG_SENSORS_MAX6875 is not set
825# CONFIG_SENSORS_TSL2550 is not set
826# CONFIG_I2C_DEBUG_CORE is not set
827# CONFIG_I2C_DEBUG_ALGO is not set
828# CONFIG_I2C_DEBUG_BUS is not set
829# CONFIG_I2C_DEBUG_CHIP is not set
830
831#
832# SPI support
833#
834# CONFIG_SPI is not set
835# CONFIG_SPI_MASTER is not set
836CONFIG_W1=y
837
838#
839# 1-wire Bus Masters
840#
841# CONFIG_W1_MASTER_DS2490 is not set
842# CONFIG_W1_MASTER_DS2482 is not set
843# CONFIG_W1_MASTER_DS1WM is not set
844
845#
846# 1-wire Slaves
847#
848# CONFIG_W1_SLAVE_THERM is not set
849# CONFIG_W1_SLAVE_SMEM is not set
850# CONFIG_W1_SLAVE_DS2433 is not set
851# CONFIG_W1_SLAVE_DS2760 is not set
852# CONFIG_POWER_SUPPLY is not set
853# CONFIG_HWMON is not set
854CONFIG_MISC_DEVICES=y
855# CONFIG_EEPROM_93CX6 is not set
856
857#
858# Multifunction device drivers
859#
860# CONFIG_MFD_SM501 is not set
861# CONFIG_HTC_ASIC3 is not set
862# CONFIG_HTC_ASIC3_DS1WM is not set
863
864#
865# Multi-Function Devices
866#
867# CONFIG_NEW_LEDS is not set
868
869#
870# Multimedia devices
871#
872CONFIG_VIDEO_DEV=y
873CONFIG_VIDEO_V4L1=y
874CONFIG_VIDEO_V4L1_COMPAT=y
875CONFIG_VIDEO_V4L2=y
876CONFIG_VIDEO_CAPTURE_DRIVERS=y
877# CONFIG_VIDEO_ADV_DEBUG is not set
878CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
879# CONFIG_VIDEO_CPIA is not set
880# CONFIG_VIDEO_CPIA2 is not set
881# CONFIG_VIDEO_SAA5246A is not set
882# CONFIG_VIDEO_SAA5249 is not set
883# CONFIG_TUNER_3036 is not set
884# CONFIG_TUNER_TEA5761 is not set
885CONFIG_V4L_USB_DRIVERS=y
886# CONFIG_VIDEO_PVRUSB2 is not set
887# CONFIG_VIDEO_EM28XX is not set
888# CONFIG_VIDEO_USBVISION is not set
889# CONFIG_USB_VICAM is not set
890# CONFIG_USB_IBMCAM is not set
891# CONFIG_USB_KONICAWC is not set
892# CONFIG_USB_QUICKCAM_MESSENGER is not set
893# CONFIG_USB_ET61X251 is not set
894# CONFIG_VIDEO_OVCAMCHIP is not set
895# CONFIG_USB_W9968CF is not set
896# CONFIG_USB_OV511 is not set
897# CONFIG_USB_SE401 is not set
898# CONFIG_USB_SN9C102 is not set
899# CONFIG_USB_STV680 is not set
900# CONFIG_USB_ZC0301 is not set
901# CONFIG_USB_PWC is not set
902# CONFIG_USB_ZR364XX is not set
903CONFIG_RADIO_ADAPTERS=y
904# CONFIG_USB_DSBR is not set
905# CONFIG_DVB_CORE is not set
906CONFIG_DAB=y
907# CONFIG_USB_DABUSB is not set
908
909#
910# Graphics support
911#
912# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
913
914#
915# Display device support
916#
917# CONFIG_DISPLAY_SUPPORT is not set
918# CONFIG_VGASTATE is not set
919CONFIG_VIDEO_OUTPUT_CONTROL=y
920CONFIG_FB=y
921# CONFIG_FIRMWARE_EDID is not set
922# CONFIG_FB_DDC is not set
923CONFIG_FB_CFB_FILLRECT=y
924CONFIG_FB_CFB_COPYAREA=y
925CONFIG_FB_CFB_IMAGEBLIT=y
926# CONFIG_FB_SYS_FILLRECT is not set
927# CONFIG_FB_SYS_COPYAREA is not set
928# CONFIG_FB_SYS_IMAGEBLIT is not set
929# CONFIG_FB_SYS_FOPS is not set
930CONFIG_FB_DEFERRED_IO=y
931# CONFIG_FB_SVGALIB is not set
932# CONFIG_FB_MACMODES is not set
933# CONFIG_FB_BACKLIGHT is not set
934CONFIG_FB_MODE_HELPERS=y
935# CONFIG_FB_TILEBLITTING is not set
936
937#
938# Frame buffer hardware drivers
939#
940# CONFIG_FB_S1D13XXX is not set
941CONFIG_FB_PXA=y
942# CONFIG_FB_PXA_LCD_QVGA is not set
943CONFIG_FB_PXA_LCD_VGA=y
944CONFIG_FB_PXA_OVERLAY=y
945# CONFIG_FB_PXA_PARAMETERS is not set
946# CONFIG_FB_MBX is not set
947# CONFIG_FB_VIRTUAL is not set
948
949#
950# Console display driver support
951#
952# CONFIG_VGA_CONSOLE is not set
953CONFIG_DUMMY_CONSOLE=y
954CONFIG_FRAMEBUFFER_CONSOLE=y
955# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
956# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
957CONFIG_FONTS=y
958# CONFIG_FONT_8x8 is not set
959CONFIG_FONT_8x16=y
960# CONFIG_FONT_6x11 is not set
961# CONFIG_FONT_7x14 is not set
962# CONFIG_FONT_PEARL_8x8 is not set
963# CONFIG_FONT_ACORN_8x8 is not set
964# CONFIG_FONT_MINI_4x6 is not set
965# CONFIG_FONT_SUN8x16 is not set
966# CONFIG_FONT_SUN12x22 is not set
967# CONFIG_FONT_10x18 is not set
968CONFIG_LOGO=y
969CONFIG_LOGO_LINUX_MONO=y
970CONFIG_LOGO_LINUX_VGA16=y
971# CONFIG_LOGO_LINUX_CLUT224 is not set
972CONFIG_LOGO_OHAND_CLUT224=y
973
974#
975# Sound
976#
977CONFIG_SOUND=y
978
979#
980# Advanced Linux Sound Architecture
981#
982CONFIG_SND=y
983CONFIG_SND_TIMER=y
984CONFIG_SND_PCM=y
985# CONFIG_SND_SEQUENCER is not set
986CONFIG_SND_OSSEMUL=y
987CONFIG_SND_MIXER_OSS=y
988CONFIG_SND_PCM_OSS=y
989CONFIG_SND_PCM_OSS_PLUGINS=y
990# CONFIG_SND_DYNAMIC_MINORS is not set
991CONFIG_SND_SUPPORT_OLD_API=y
992CONFIG_SND_VERBOSE_PROCFS=y
993# CONFIG_SND_VERBOSE_PRINTK is not set
994# CONFIG_SND_DEBUG is not set
995
996#
997# Generic devices
998#
999# CONFIG_SND_DUMMY is not set
1000# CONFIG_SND_MTPAV is not set
1001# CONFIG_SND_SERIAL_U16550 is not set
1002# CONFIG_SND_MPU401 is not set
1003
1004#
1005# ALSA ARM devices
1006#
1007# CONFIG_SND_PXA2XX_AC97 is not set
1008
1009#
1010# USB devices
1011#
1012# CONFIG_SND_USB_AUDIO is not set
1013# CONFIG_SND_USB_CAIAQ is not set
1014
1015#
1016# System on Chip audio support
1017#
1018# CONFIG_SND_SOC is not set
1019
1020#
1021# SoC Audio support for SuperH
1022#
1023
1024#
1025# Open Sound System
1026#
1027# CONFIG_SOUND_PRIME is not set
1028CONFIG_HID_SUPPORT=y
1029CONFIG_HID=m
1030# CONFIG_HID_DEBUG is not set
1031
1032#
1033# USB Input Devices
1034#
1035CONFIG_USB_HID=y
1036# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1037# CONFIG_HID_FF is not set
1038# CONFIG_USB_HIDDEV is not set
1039CONFIG_USB_SUPPORT=y
1040CONFIG_USB_ARCH_HAS_HCD=y
1041# CONFIG_USB_ARCH_HAS_OHCI is not set
1042# CONFIG_USB_ARCH_HAS_EHCI is not set
1043CONFIG_USB=y
1044# CONFIG_USB_DEBUG is not set
1045
1046#
1047# Miscellaneous USB options
1048#
1049# CONFIG_USB_DEVICEFS is not set
1050CONFIG_USB_DEVICE_CLASS=y
1051# CONFIG_USB_DYNAMIC_MINORS is not set
1052# CONFIG_USB_OTG is not set
1053
1054#
1055# USB Host Controller Drivers
1056#
1057# CONFIG_USB_ISP116X_HCD is not set
1058# CONFIG_USB_SL811_HCD is not set
1059# CONFIG_USB_R8A66597_HCD is not set
1060
1061#
1062# USB Device Class drivers
1063#
1064CONFIG_USB_ACM=y
1065# CONFIG_USB_PRINTER is not set
1066
1067#
1068# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1069#
1070
1071#
1072# may also be needed; see USB_STORAGE Help for more information
1073#
1074CONFIG_USB_STORAGE=y
1075# CONFIG_USB_STORAGE_DEBUG is not set
1076# CONFIG_USB_STORAGE_DATAFAB is not set
1077# CONFIG_USB_STORAGE_FREECOM is not set
1078# CONFIG_USB_STORAGE_ISD200 is not set
1079# CONFIG_USB_STORAGE_DPCM is not set
1080# CONFIG_USB_STORAGE_USBAT is not set
1081# CONFIG_USB_STORAGE_SDDR09 is not set
1082# CONFIG_USB_STORAGE_SDDR55 is not set
1083# CONFIG_USB_STORAGE_JUMPSHOT is not set
1084# CONFIG_USB_STORAGE_ALAUDA is not set
1085# CONFIG_USB_STORAGE_ONETOUCH is not set
1086# CONFIG_USB_STORAGE_KARMA is not set
1087# CONFIG_USB_LIBUSUAL is not set
1088
1089#
1090# USB Imaging devices
1091#
1092# CONFIG_USB_MDC800 is not set
1093# CONFIG_USB_MICROTEK is not set
1094CONFIG_USB_MON=y
1095
1096#
1097# USB port drivers
1098#
1099
1100#
1101# USB Serial Converter support
1102#
1103# CONFIG_USB_SERIAL is not set
1104
1105#
1106# USB Miscellaneous drivers
1107#
1108# CONFIG_USB_EMI62 is not set
1109# CONFIG_USB_EMI26 is not set
1110# CONFIG_USB_ADUTUX is not set
1111# CONFIG_USB_AUERSWALD is not set
1112# CONFIG_USB_RIO500 is not set
1113# CONFIG_USB_LEGOTOWER is not set
1114# CONFIG_USB_LCD is not set
1115# CONFIG_USB_BERRY_CHARGE is not set
1116# CONFIG_USB_LED is not set
1117# CONFIG_USB_CYPRESS_CY7C63 is not set
1118# CONFIG_USB_CYTHERM is not set
1119# CONFIG_USB_PHIDGET is not set
1120# CONFIG_USB_IDMOUSE is not set
1121# CONFIG_USB_FTDI_ELAN is not set
1122# CONFIG_USB_APPLEDISPLAY is not set
1123# CONFIG_USB_LD is not set
1124# CONFIG_USB_TRANCEVIBRATOR is not set
1125# CONFIG_USB_IOWARRIOR is not set
1126
1127#
1128# USB DSL modem support
1129#
1130
1131#
1132# USB Gadget Support
1133#
1134CONFIG_USB_GADGET=y
1135# CONFIG_USB_GADGET_DEBUG is not set
1136# CONFIG_USB_GADGET_DEBUG_FILES is not set
1137CONFIG_USB_GADGET_SELECTED=y
1138# CONFIG_USB_GADGET_AMD5536UDC is not set
1139# CONFIG_USB_GADGET_FSL_USB2 is not set
1140# CONFIG_USB_GADGET_NET2280 is not set
1141# CONFIG_USB_GADGET_PXA2XX is not set
1142CONFIG_USB_GADGET_M66592=y
1143CONFIG_USB_M66592=y
1144# CONFIG_USB_GADGET_PXA27X is not set
1145# CONFIG_USB_GADGET_GOKU is not set
1146# CONFIG_USB_GADGET_LH7A40X is not set
1147# CONFIG_USB_GADGET_OMAP is not set
1148# CONFIG_USB_GADGET_S3C2410 is not set
1149# CONFIG_USB_GADGET_AT91 is not set
1150# CONFIG_USB_GADGET_DUMMY_HCD is not set
1151CONFIG_USB_GADGET_DUALSPEED=y
1152# CONFIG_USB_ZERO is not set
1153# CONFIG_USB_ETH is not set
1154# CONFIG_USB_GADGETFS is not set
1155CONFIG_USB_FILE_STORAGE=y
1156# CONFIG_USB_FILE_STORAGE_TEST is not set
1157# CONFIG_USB_G_SERIAL is not set
1158# CONFIG_USB_MIDI_GADGET is not set
1159CONFIG_MMC=y
1160# CONFIG_MMC_DEBUG is not set
1161# CONFIG_MMC_UNSAFE_RESUME is not set
1162
1163#
1164# MMC/SD Card Drivers
1165#
1166CONFIG_MMC_BLOCK=y
1167CONFIG_MMC_BLOCK_BOUNCE=y
1168
1169#
1170# MMC/SD Host Controller Drivers
1171#
1172CONFIG_MMC_PXA=y
1173CONFIG_RTC_LIB=y
1174CONFIG_RTC_CLASS=y
1175CONFIG_RTC_HCTOSYS=y
1176CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1177# CONFIG_RTC_DEBUG is not set
1178
1179#
1180# RTC interfaces
1181#
1182CONFIG_RTC_INTF_SYSFS=y
1183CONFIG_RTC_INTF_PROC=y
1184CONFIG_RTC_INTF_DEV=y
1185# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1186# CONFIG_RTC_DRV_TEST is not set
1187
1188#
1189# I2C RTC drivers
1190#
1191# CONFIG_RTC_DRV_DS1307 is not set
1192# CONFIG_RTC_DRV_DS1672 is not set
1193# CONFIG_RTC_DRV_MAX6900 is not set
1194# CONFIG_RTC_DRV_RS5C372 is not set
1195# CONFIG_RTC_DRV_ISL1208 is not set
1196# CONFIG_RTC_DRV_X1205 is not set
1197# CONFIG_RTC_DRV_PCF8563 is not set
1198# CONFIG_RTC_DRV_PCF8583 is not set
1199# CONFIG_RTC_DRV_M41T80 is not set
1200
1201#
1202# SPI RTC drivers
1203#
1204
1205#
1206# Platform RTC drivers
1207#
1208# CONFIG_RTC_DRV_CMOS is not set
1209# CONFIG_RTC_DRV_DS1553 is not set
1210# CONFIG_RTC_DRV_STK17TA8 is not set
1211# CONFIG_RTC_DRV_DS1742 is not set
1212# CONFIG_RTC_DRV_M48T86 is not set
1213# CONFIG_RTC_DRV_M48T59 is not set
1214# CONFIG_RTC_DRV_V3020 is not set
1215
1216#
1217# on-CPU RTC drivers
1218#
1219CONFIG_RTC_DRV_SA1100=y
1220
1221#
1222# DMA Engine support
1223#
1224# CONFIG_DMA_ENGINE is not set
1225
1226#
1227# DMA Clients
1228#
1229
1230#
1231# DMA Devices
1232#
1233
1234#
1235# File systems
1236#
1237CONFIG_EXT2_FS=y
1238# CONFIG_EXT2_FS_XATTR is not set
1239# CONFIG_EXT2_FS_XIP is not set
1240CONFIG_EXT3_FS=m
1241CONFIG_EXT3_FS_XATTR=y
1242# CONFIG_EXT3_FS_POSIX_ACL is not set
1243# CONFIG_EXT3_FS_SECURITY is not set
1244# CONFIG_EXT4DEV_FS is not set
1245CONFIG_JBD=m
1246# CONFIG_JBD_DEBUG is not set
1247CONFIG_FS_MBCACHE=y
1248# CONFIG_REISERFS_FS is not set
1249# CONFIG_JFS_FS is not set
1250# CONFIG_FS_POSIX_ACL is not set
1251# CONFIG_XFS_FS is not set
1252# CONFIG_GFS2_FS is not set
1253# CONFIG_OCFS2_FS is not set
1254# CONFIG_MINIX_FS is not set
1255# CONFIG_ROMFS_FS is not set
1256CONFIG_INOTIFY=y
1257CONFIG_INOTIFY_USER=y
1258# CONFIG_QUOTA is not set
1259CONFIG_DNOTIFY=y
1260# CONFIG_AUTOFS_FS is not set
1261# CONFIG_AUTOFS4_FS is not set
1262# CONFIG_FUSE_FS is not set
1263
1264#
1265# CD-ROM/DVD Filesystems
1266#
1267# CONFIG_ISO9660_FS is not set
1268# CONFIG_UDF_FS is not set
1269
1270#
1271# DOS/FAT/NT Filesystems
1272#
1273CONFIG_FAT_FS=y
1274CONFIG_MSDOS_FS=y
1275CONFIG_VFAT_FS=y
1276CONFIG_FAT_DEFAULT_CODEPAGE=437
1277CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1278# CONFIG_NTFS_FS is not set
1279
1280#
1281# Pseudo filesystems
1282#
1283CONFIG_PROC_FS=y
1284CONFIG_PROC_SYSCTL=y
1285CONFIG_SYSFS=y
1286CONFIG_TMPFS=y
1287# CONFIG_TMPFS_POSIX_ACL is not set
1288# CONFIG_HUGETLB_PAGE is not set
1289CONFIG_RAMFS=y
1290# CONFIG_CONFIGFS_FS is not set
1291
1292#
1293# Miscellaneous filesystems
1294#
1295# CONFIG_ADFS_FS is not set
1296# CONFIG_AFFS_FS is not set
1297# CONFIG_HFS_FS is not set
1298# CONFIG_HFSPLUS_FS is not set
1299# CONFIG_BEFS_FS is not set
1300# CONFIG_BFS_FS is not set
1301# CONFIG_EFS_FS is not set
1302CONFIG_JFFS2_FS=y
1303CONFIG_JFFS2_FS_DEBUG=0
1304CONFIG_JFFS2_FS_WRITEBUFFER=y
1305# CONFIG_JFFS2_SUMMARY is not set
1306# CONFIG_JFFS2_FS_XATTR is not set
1307# CONFIG_JFFS2_SYSFS is not set
1308CONFIG_JFFS2_COMPRESSION_OPTIONS=y
1309CONFIG_JFFS2_ZLIB=y
1310CONFIG_JFFS2_LZO=y
1311CONFIG_JFFS2_RTIME=y
1312# CONFIG_JFFS2_RUBIN is not set
1313# CONFIG_JFFS2_CMODE_NONE is not set
1314CONFIG_JFFS2_CMODE_PRIORITY=y
1315# CONFIG_JFFS2_CMODE_SIZE is not set
1316# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
1317# CONFIG_CRAMFS is not set
1318# CONFIG_SQUASHFS is not set
1319# CONFIG_VXFS_FS is not set
1320# CONFIG_HPFS_FS is not set
1321# CONFIG_QNX4FS_FS is not set
1322# CONFIG_SYSV_FS is not set
1323# CONFIG_UFS_FS is not set
1324
1325#
1326# Network File Systems
1327#
1328CONFIG_NFS_FS=y
1329CONFIG_NFS_V3=y
1330# CONFIG_NFS_V3_ACL is not set
1331CONFIG_NFS_V4=y
1332# CONFIG_NFS_DIRECTIO is not set
1333# CONFIG_NFSD is not set
1334# CONFIG_ROOT_NFS is not set
1335CONFIG_LOCKD=y
1336CONFIG_LOCKD_V4=y
1337CONFIG_NFS_COMMON=y
1338CONFIG_SUNRPC=y
1339CONFIG_SUNRPC_GSS=y
1340# CONFIG_SUNRPC_BIND34 is not set
1341CONFIG_RPCSEC_GSS_KRB5=y
1342# CONFIG_RPCSEC_GSS_SPKM3 is not set
1343# CONFIG_SMB_FS is not set
1344# CONFIG_CIFS is not set
1345# CONFIG_NCP_FS is not set
1346# CONFIG_CODA_FS is not set
1347# CONFIG_AFS_FS is not set
1348
1349#
1350# Partition Types
1351#
1352CONFIG_PARTITION_ADVANCED=y
1353# CONFIG_ACORN_PARTITION is not set
1354# CONFIG_OSF_PARTITION is not set
1355# CONFIG_AMIGA_PARTITION is not set
1356# CONFIG_ATARI_PARTITION is not set
1357# CONFIG_MAC_PARTITION is not set
1358CONFIG_MSDOS_PARTITION=y
1359# CONFIG_BSD_DISKLABEL is not set
1360# CONFIG_MINIX_SUBPARTITION is not set
1361# CONFIG_SOLARIS_X86_PARTITION is not set
1362# CONFIG_UNIXWARE_DISKLABEL is not set
1363# CONFIG_LDM_PARTITION is not set
1364# CONFIG_SGI_PARTITION is not set
1365# CONFIG_ULTRIX_PARTITION is not set
1366# CONFIG_SUN_PARTITION is not set
1367# CONFIG_KARMA_PARTITION is not set
1368# CONFIG_EFI_PARTITION is not set
1369# CONFIG_SYSV68_PARTITION is not set
1370
1371#
1372# Native Language Support
1373#
1374CONFIG_NLS=y
1375CONFIG_NLS_DEFAULT="iso8859-1"
1376CONFIG_NLS_CODEPAGE_437=y
1377# CONFIG_NLS_CODEPAGE_737 is not set
1378# CONFIG_NLS_CODEPAGE_775 is not set
1379# CONFIG_NLS_CODEPAGE_850 is not set
1380# CONFIG_NLS_CODEPAGE_852 is not set
1381# CONFIG_NLS_CODEPAGE_855 is not set
1382# CONFIG_NLS_CODEPAGE_857 is not set
1383# CONFIG_NLS_CODEPAGE_860 is not set
1384# CONFIG_NLS_CODEPAGE_861 is not set
1385# CONFIG_NLS_CODEPAGE_862 is not set
1386# CONFIG_NLS_CODEPAGE_863 is not set
1387# CONFIG_NLS_CODEPAGE_864 is not set
1388# CONFIG_NLS_CODEPAGE_865 is not set
1389# CONFIG_NLS_CODEPAGE_866 is not set
1390# CONFIG_NLS_CODEPAGE_869 is not set
1391# CONFIG_NLS_CODEPAGE_936 is not set
1392# CONFIG_NLS_CODEPAGE_950 is not set
1393# CONFIG_NLS_CODEPAGE_932 is not set
1394# CONFIG_NLS_CODEPAGE_949 is not set
1395# CONFIG_NLS_CODEPAGE_874 is not set
1396# CONFIG_NLS_ISO8859_8 is not set
1397# CONFIG_NLS_CODEPAGE_1250 is not set
1398# CONFIG_NLS_CODEPAGE_1251 is not set
1399# CONFIG_NLS_ASCII is not set
1400CONFIG_NLS_ISO8859_1=y
1401# CONFIG_NLS_ISO8859_2 is not set
1402# CONFIG_NLS_ISO8859_3 is not set
1403# CONFIG_NLS_ISO8859_4 is not set
1404# CONFIG_NLS_ISO8859_5 is not set
1405# CONFIG_NLS_ISO8859_6 is not set
1406# CONFIG_NLS_ISO8859_7 is not set
1407# CONFIG_NLS_ISO8859_9 is not set
1408# CONFIG_NLS_ISO8859_13 is not set
1409# CONFIG_NLS_ISO8859_14 is not set
1410# CONFIG_NLS_ISO8859_15 is not set
1411# CONFIG_NLS_KOI8_R is not set
1412# CONFIG_NLS_KOI8_U is not set
1413# CONFIG_NLS_UTF8 is not set
1414
1415#
1416# Distributed Lock Manager
1417#
1418# CONFIG_DLM is not set
1419
1420#
1421# Profiling support
1422#
1423CONFIG_PROFILING=y
1424# CONFIG_OPROFILE is not set
1425
1426#
1427# Kernel hacking
1428#
1429# CONFIG_PRINTK_TIME is not set
1430CONFIG_ENABLE_MUST_CHECK=y
1431CONFIG_MAGIC_SYSRQ=y
1432# CONFIG_UNUSED_SYMBOLS is not set
1433CONFIG_DEBUG_FS=y
1434# CONFIG_HEADERS_CHECK is not set
1435CONFIG_DEBUG_KERNEL=y
1436# CONFIG_DEBUG_SHIRQ is not set
1437CONFIG_DETECT_SOFTLOCKUP=y
1438CONFIG_SCHED_DEBUG=y
1439# CONFIG_SCHEDSTATS is not set
1440# CONFIG_TIMER_STATS is not set
1441# CONFIG_DEBUG_SLAB is not set
1442# CONFIG_DEBUG_RT_MUTEXES is not set
1443# CONFIG_RT_MUTEX_TESTER is not set
1444# CONFIG_DEBUG_SPINLOCK is not set
1445# CONFIG_DEBUG_MUTEXES is not set
1446# CONFIG_DEBUG_LOCK_ALLOC is not set
1447# CONFIG_PROVE_LOCKING is not set
1448# CONFIG_LOCK_STAT is not set
1449# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1450# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1451# CONFIG_DEBUG_KOBJECT is not set
1452CONFIG_DEBUG_BUGVERBOSE=y
1453CONFIG_DEBUG_INFO=y
1454# CONFIG_DEBUG_VM is not set
1455# CONFIG_DEBUG_LIST is not set
1456CONFIG_FRAME_POINTER=y
1457CONFIG_FORCED_INLINING=y
1458# CONFIG_RCU_TORTURE_TEST is not set
1459# CONFIG_FAULT_INJECTION is not set
1460CONFIG_DEBUG_USER=y
1461CONFIG_DEBUG_ERRORS=y
1462CONFIG_DEBUG_LL=y
1463# CONFIG_DEBUG_ICEDCC is not set
1464
1465#
1466# Security options
1467#
1468# CONFIG_KEYS is not set
1469# CONFIG_SECURITY is not set
1470CONFIG_CRYPTO=y
1471CONFIG_CRYPTO_ALGAPI=y
1472CONFIG_CRYPTO_BLKCIPHER=y
1473CONFIG_CRYPTO_MANAGER=y
1474# CONFIG_CRYPTO_HMAC is not set
1475# CONFIG_CRYPTO_XCBC is not set
1476# CONFIG_CRYPTO_NULL is not set
1477# CONFIG_CRYPTO_MD4 is not set
1478CONFIG_CRYPTO_MD5=y
1479# CONFIG_CRYPTO_SHA1 is not set
1480# CONFIG_CRYPTO_SHA256 is not set
1481# CONFIG_CRYPTO_SHA512 is not set
1482# CONFIG_CRYPTO_WP512 is not set
1483# CONFIG_CRYPTO_TGR192 is not set
1484# CONFIG_CRYPTO_GF128MUL is not set
1485CONFIG_CRYPTO_ECB=y
1486CONFIG_CRYPTO_CBC=y
1487CONFIG_CRYPTO_PCBC=y
1488# CONFIG_CRYPTO_LRW is not set
1489# CONFIG_CRYPTO_CRYPTD is not set
1490CONFIG_CRYPTO_DES=y
1491# CONFIG_CRYPTO_FCRYPT is not set
1492# CONFIG_CRYPTO_BLOWFISH is not set
1493# CONFIG_CRYPTO_TWOFISH is not set
1494# CONFIG_CRYPTO_SERPENT is not set
1495# CONFIG_CRYPTO_AES is not set
1496# CONFIG_CRYPTO_CAST5 is not set
1497# CONFIG_CRYPTO_CAST6 is not set
1498# CONFIG_CRYPTO_TEA is not set
1499# CONFIG_CRYPTO_ARC4 is not set
1500# CONFIG_CRYPTO_KHAZAD is not set
1501# CONFIG_CRYPTO_ANUBIS is not set
1502# CONFIG_CRYPTO_DEFLATE is not set
1503# CONFIG_CRYPTO_LZO is not set
1504# CONFIG_CRYPTO_MICHAEL_MIC is not set
1505# CONFIG_CRYPTO_CRC32C is not set
1506# CONFIG_CRYPTO_CAMELLIA is not set
1507# CONFIG_CRYPTO_TEST is not set
1508CONFIG_CRYPTO_HW=y
1509
1510#
1511# Library routines
1512#
1513CONFIG_BITREVERSE=y
1514CONFIG_CRC_CCITT=y
1515# CONFIG_CRC16 is not set
1516# CONFIG_CRC_ITU_T is not set
1517CONFIG_CRC32=y
1518# CONFIG_CRC7 is not set
1519# CONFIG_LIBCRC32C is not set
1520CONFIG_ZLIB_INFLATE=y
1521CONFIG_ZLIB_DEFLATE=y
1522CONFIG_LZO_COMPRESS=y
1523CONFIG_LZO_DECOMPRESS=y
1524CONFIG_PLIST=y
1525CONFIG_HAS_IOMEM=y
1526CONFIG_HAS_IOPORT=y
1527CONFIG_HAS_DMA=y
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/hostap-monitor-mode.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/hostap-monitor-mode.patch
new file mode 100644
index 0000000000..641fd19e50
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/hostap-monitor-mode.patch
@@ -0,0 +1,209 @@
1This is a patch that I've been maintaining for a few years, and I'd
2really like to see it added to the mainstream zaurus kernel so I can
3finally stop distributing my own.
4
5This patch only effects the card while in monitor mode, and does not
6cause any known stability issues.
7
8http://patches.aircrack-ng.org/hostap-kernel-2.6.18.patch
9
10Rick Farina (Zero_Chaos)
11
12diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_80211_tx.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_80211_tx.c
13--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-09-21 01:26:27.000000000 -0400
14+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-09-21 01:30:18.000000000 -0400
15@@ -69,6 +69,9 @@
16 iface = netdev_priv(dev);
17 local = iface->local;
18
19+ if (local->iw_mode == IW_MODE_MONITOR)
20+ goto xmit;
21+
22 if (skb->len < ETH_HLEN) {
23 printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
24 "(len=%d)\n", dev->name, skb->len);
25@@ -234,6 +237,7 @@
26 memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN);
27 }
28
29+xmit:
30 iface->stats.tx_packets++;
31 iface->stats.tx_bytes += skb->len;
32
33@@ -404,8 +408,6 @@
34 }
35
36 if (skb->len < 24) {
37- printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
38- "(len=%d)\n", dev->name, skb->len);
39 ret = 0;
40 iface->stats.tx_dropped++;
41 goto fail;
42Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_cs.c.orig
43Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_cs.c.rej
44diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_hw.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_hw.c
45--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_hw.c 2006-09-21 01:26:27.000000000 -0400
46+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_hw.c 2006-09-21 01:30:18.000000000 -0400
47@@ -1005,6 +1005,35 @@
48 return fid;
49 }
50
51+static int prism2_monitor_enable(struct net_device *dev)
52+{
53+ if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, 5)) {
54+ printk(KERN_DEBUG "Port type setting for monitor mode "
55+ "failed\n");
56+ return -EOPNOTSUPP;
57+ }
58+
59+ if (hfa384x_cmd(dev, HFA384X_CMDCODE_TEST | (0x0a << 8),
60+ 0, NULL, NULL)) {
61+ printk(KERN_DEBUG "Could not enter testmode 0x0a\n");
62+ return -EOPNOTSUPP;
63+ }
64+
65+ if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
66+ HFA384X_WEPFLAGS_PRIVACYINVOKED |
67+ HFA384X_WEPFLAGS_HOSTENCRYPT |
68+ HFA384X_WEPFLAGS_HOSTDECRYPT)) {
69+ printk(KERN_DEBUG "WEP flags setting failed\n");
70+ return -EOPNOTSUPP;
71+ }
72+
73+ if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, 1)) {
74+ printk(KERN_DEBUG "Could not set promiscuous mode\n");
75+ return -EOPNOTSUPP;
76+ }
77+
78+ return 0;
79+}
80
81 static int prism2_reset_port(struct net_device *dev)
82 {
83@@ -1031,6 +1060,10 @@
84 "port\n", dev->name);
85 }
86
87+ if (local->iw_mode == IW_MODE_MONITOR)
88+ /* force mode 0x0a after port 0 reset */
89+ return prism2_monitor_enable(dev);
90+
91 /* It looks like at least some STA firmware versions reset
92 * fragmentation threshold back to 2346 after enable command. Restore
93 * the configured value, if it differs from this default. */
94@@ -1466,6 +1499,10 @@
95 return 1;
96 }
97
98+ if (local->iw_mode == IW_MODE_MONITOR)
99+ /* force mode 0x0a after port 0 reset */
100+ prism2_monitor_enable(dev);
101+
102 local->hw_ready = 1;
103 local->hw_reset_tries = 0;
104 local->hw_resetting = 0;
105@@ -3156,6 +3193,7 @@
106 local->func->hw_config = prism2_hw_config;
107 local->func->hw_reset = prism2_hw_reset;
108 local->func->hw_shutdown = prism2_hw_shutdown;
109+ local->func->monitor_enable = prism2_monitor_enable;
110 local->func->reset_port = prism2_reset_port;
111 local->func->schedule_reset = prism2_schedule_reset;
112 #ifdef PRISM2_DOWNLOAD_SUPPORT
113Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_hw.c.orig
114diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_ioctl.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_ioctl.c
115--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_ioctl.c 2006-09-21 01:26:27.000000000 -0400
116+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_ioctl.c 2006-09-21 01:30:18.000000000 -0400
117@@ -1104,33 +1104,7 @@
118
119 printk(KERN_DEBUG "Enabling monitor mode\n");
120 hostap_monitor_set_type(local);
121-
122- if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
123- HFA384X_PORTTYPE_PSEUDO_IBSS)) {
124- printk(KERN_DEBUG "Port type setting for monitor mode "
125- "failed\n");
126- return -EOPNOTSUPP;
127- }
128-
129- /* Host decrypt is needed to get the IV and ICV fields;
130- * however, monitor mode seems to remove WEP flag from frame
131- * control field */
132- if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
133- HFA384X_WEPFLAGS_HOSTENCRYPT |
134- HFA384X_WEPFLAGS_HOSTDECRYPT)) {
135- printk(KERN_DEBUG "WEP flags setting failed\n");
136- return -EOPNOTSUPP;
137- }
138-
139- if (local->func->reset_port(dev) ||
140- local->func->cmd(dev, HFA384X_CMDCODE_TEST |
141- (HFA384X_TEST_MONITOR << 8),
142- 0, NULL, NULL)) {
143- printk(KERN_DEBUG "Setting monitor mode failed\n");
144- return -EOPNOTSUPP;
145- }
146-
147- return 0;
148+ return local->func->reset_port(dev);
149 }
150
151
152@@ -1199,7 +1173,7 @@
153 local->iw_mode = *mode;
154
155 if (local->iw_mode == IW_MODE_MONITOR)
156- hostap_monitor_mode_enable(local);
157+ return hostap_monitor_mode_enable(local);
158 else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
159 !local->fw_encrypt_ok) {
160 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
161diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_main.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_main.c
162--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_main.c 2006-09-21 01:26:27.000000000 -0400
163+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_main.c 2006-09-21 01:30:18.000000000 -0400
164@@ -331,7 +331,7 @@
165 if (local->iw_mode == IW_MODE_REPEAT)
166 return HFA384X_PORTTYPE_WDS;
167 if (local->iw_mode == IW_MODE_MONITOR)
168- return HFA384X_PORTTYPE_PSEUDO_IBSS;
169+ return 5; /*HFA384X_PORTTYPE_PSEUDO_IBSS;*/
170 return HFA384X_PORTTYPE_HOSTAP;
171 }
172
173Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_main.c.orig
174diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_pci.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_pci.c
175--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_pci.c 2006-09-21 01:26:27.000000000 -0400
176+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_pci.c 2006-09-21 01:30:18.000000000 -0400
177@@ -48,6 +48,8 @@
178 { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID },
179 /* Samsung MagicLAN SWL-2210P */
180 { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID },
181+ /* NETGEAR MA311 */
182+ { 0x1385, 0x3872, PCI_ANY_ID, PCI_ANY_ID },
183 { 0 }
184 };
185
186Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_pci.c.orig
187diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_plx.c linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_plx.c
188--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_plx.c 2006-09-21 01:26:27.000000000 -0400
189+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_plx.c 2006-09-21 01:30:18.000000000 -0400
190@@ -101,6 +101,7 @@
191 { 0xc250, 0x0002 } /* EMTAC A2424i */,
192 { 0xd601, 0x0002 } /* Z-Com XI300 */,
193 { 0xd601, 0x0005 } /* Zcomax XI-325H 200mW */,
194+ { 0xd601, 0x0010 } /* Zcomax XI-325H 100mW */,
195 { 0, 0}
196 };
197
198Only in linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap: hostap_plx.c.orig
199diff -ur linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_wlan.h linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_wlan.h
200--- linux-2.6.18-gentoo/drivers/net/wireless/hostap/hostap_wlan.h 2006-09-21 01:26:27.000000000 -0400
201+++ linux-2.6.18-gentoo-rawtx/drivers/net/wireless/hostap/hostap_wlan.h 2006-09-21 01:30:18.000000000 -0400
202@@ -575,6 +575,7 @@
203 int (*hw_config)(struct net_device *dev, int initial);
204 void (*hw_reset)(struct net_device *dev);
205 void (*hw_shutdown)(struct net_device *dev, int no_disable);
206+ int (*monitor_enable)(struct net_device *dev);
207 int (*reset_port)(struct net_device *dev);
208 void (*schedule_reset)(local_info_t *local);
209 int (*download)(local_info_t *local,
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/hrw-add-wcf11-to-hostap.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/hrw-add-wcf11-to-hostap.patch
new file mode 100644
index 0000000000..5ee8b2042c
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/hrw-add-wcf11-to-hostap.patch
@@ -0,0 +1,31 @@
1From: Marcin Juszkiewicz <openembedded@haerwu.biz>
2
3Linksys WCF11 submitted by Ångström user.
4
5"The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P", "RevA",
60xa5f472c2, 0x9c05598d, 0xc9049a39, 0x57a66194
7manfid: 0x0274, 0x3301
8
9Signed-off-by: Marcin Juszkiewicz <openembedded@haerwu.biz>
10Acked-by: Pavel Roskin <proski@gnu.org>
11
12---
13 drivers/net/wireless/hostap/hostap_cs.c | 3 +++
14 1 file changed, 3 insertions(+)
15
16--- linux-2.6.23.orig/drivers/net/wireless/hostap/hostap_cs.c
17+++ linux-2.6.23/drivers/net/wireless/hostap/hostap_cs.c
18@@ -887,10 +887,13 @@ static struct pcmcia_device_id hostap_cs
19 "Ver. 1.00",
20 0x5cd01705, 0x4271660f, 0x9d08ee12),
21 PCMCIA_DEVICE_PROD_ID123(
22 "corega", "WL PCCL-11", "ISL37300P",
23 0xa21501a, 0x59868926, 0xc9049a39),
24+ PCMCIA_DEVICE_PROD_ID123(
25+ "The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
26+ 0xa5f472c2, 0x9c05598d, 0xc9049a39),
27 PCMCIA_DEVICE_NULL
28 };
29 MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
30
31
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni-acx.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni-acx.patch
new file mode 100644
index 0000000000..769674c935
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni-acx.patch
@@ -0,0 +1,33526 @@
1---
2 drivers/net/wireless/Kconfig | 31
3 drivers/net/wireless/Makefile | 2
4 drivers/net/wireless/acx/Kconfig | 113
5 drivers/net/wireless/acx/Makefile | 21
6 drivers/net/wireless/acx/acx.h | 14
7 drivers/net/wireless/acx/acx_config.h | 50
8 drivers/net/wireless/acx/acx_func.h | 710 ++
9 drivers/net/wireless/acx/acx_hw.h | 18
10 drivers/net/wireless/acx/acx_struct.h | 2114 ++++++++
11 drivers/net/wireless/acx/common.c | 7388 ++++++++++++++++++++++++++++
12 drivers/net/wireless/acx/conv.c | 504 +
13 drivers/net/wireless/acx/cs.c | 5703 +++++++++++++++++++++
14 drivers/net/wireless/acx/htcsable_acx.c | 118
15 drivers/net/wireless/acx/htcuniversal_acx.c | 108
16 drivers/net/wireless/acx/hx4700_acx.c | 108
17 drivers/net/wireless/acx/ioctl.c | 2748 ++++++++++
18 drivers/net/wireless/acx/mem.c | 5363 ++++++++++++++++++++
19 drivers/net/wireless/acx/pci.c | 4234 ++++++++++++++++
20 drivers/net/wireless/acx/rx3000_acx.c | 110
21 drivers/net/wireless/acx/setrate.c | 213
22 drivers/net/wireless/acx/usb.c | 1922 +++++++
23 drivers/net/wireless/acx/wlan.c | 424 +
24 drivers/net/wireless/acx/wlan_compat.h | 260
25 drivers/net/wireless/acx/wlan_hdr.h | 497 +
26 drivers/net/wireless/acx/wlan_mgmt.h | 582 ++
27 25 files changed, 33355 insertions(+)
28
29Index: linux-2.6.22/drivers/net/wireless/acx/acx_config.h
30===================================================================
31--- /dev/null 1970-01-01 00:00:00.000000000 +0000
32+++ linux-2.6.22/drivers/net/wireless/acx/acx_config.h 2007-08-23 18:46:40.000000000 +0200
33@@ -0,0 +1,50 @@
34+#define ACX_RELEASE "v0.3.36"
35+
36+/*
37+ * Test out all the channels in reg domain 0x10
38+ */
39+#define ACX_ALLOW_ALLCHANNELS
40+
41+/* set to 0 if you don't want any debugging code to be compiled in */
42+/* set to 1 if you want some debugging */
43+/* set to 2 if you want extensive debug log */
44+#define ACX_DEBUG 0
45+
46+/*
47+ * Since we'll be changing channels a lot
48+#define ACX_DEFAULT_MSG (L_ASSOC|L_INIT)
49+*/
50+#define ACX_DEFAULT_MSG (L_ASSOC|L_INIT)
51+
52+/* assume 32bit I/O width
53+ * (16bit is also compatible with Compact Flash) */
54+#define ACX_IO_WIDTH 32
55+
56+/* Set this to 1 if you want monitor mode to use
57+ * phy header. Currently it is not useful anyway since we
58+ * don't know what useful info (if any) is in phy header.
59+ * If you want faster/smaller code, say 0 here */
60+#define WANT_PHY_HDR 0
61+
62+/* whether to do Tx descriptor cleanup in softirq (i.e. not in IRQ
63+ * handler) or not. Note that doing it later does slightly increase
64+ * system load, so still do that stuff in the IRQ handler for now,
65+ * even if that probably means worse latency */
66+#define TX_CLEANUP_IN_SOFTIRQ 0
67+
68+/* if you want very experimental 802.11 power save mode features */
69+#define POWER_SAVE_80211 0
70+
71+/* if you want very early packet fragmentation bits and pieces */
72+#define ACX_FRAGMENTATION 0
73+
74+/* Locking: */
75+/* very talkative */
76+/* #define PARANOID_LOCKING 1 */
77+/* normal (use when bug-free) */
78+#define DO_LOCKING 1
79+/* else locking is disabled! */
80+
81+/* 0 - normal mode */
82+/* 1 - development/debug: probe for IEs on modprobe */
83+#define CMD_DISCOVERY 0
84Index: linux-2.6.22/drivers/net/wireless/acx/acx_func.h
85===================================================================
86--- /dev/null 1970-01-01 00:00:00.000000000 +0000
87+++ linux-2.6.22/drivers/net/wireless/acx/acx_func.h 2007-08-23 18:34:19.000000000 +0200
88@@ -0,0 +1,710 @@
89+/***********************************************************************
90+** Copyright (C) 2003 ACX100 Open Source Project
91+**
92+** The contents of this file are subject to the Mozilla Public
93+** License Version 1.1 (the "License"); you may not use this file
94+** except in compliance with the License. You may obtain a copy of
95+** the License at http://www.mozilla.org/MPL/
96+**
97+** Software distributed under the License is distributed on an "AS
98+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
99+** implied. See the License for the specific language governing
100+** rights and limitations under the License.
101+**
102+** Alternatively, the contents of this file may be used under the
103+** terms of the GNU Public License version 2 (the "GPL"), in which
104+** case the provisions of the GPL are applicable instead of the
105+** above. If you wish to allow the use of your version of this file
106+** only under the terms of the GPL and not to allow others to use
107+** your version of this file under the MPL, indicate your decision
108+** by deleting the provisions above and replace them with the notice
109+** and other provisions required by the GPL. If you do not delete
110+** the provisions above, a recipient may use your version of this
111+** file under either the MPL or the GPL.
112+** ---------------------------------------------------------------------
113+** Inquiries regarding the ACX100 Open Source Project can be
114+** made directly to:
115+**
116+** acx100-users@lists.sf.net
117+** http://acx100.sf.net
118+** ---------------------------------------------------------------------
119+*/
120+
121+
122+/***********************************************************************
123+** LOGGING
124+**
125+** - Avoid SHOUTING needlessly. Avoid excessive verbosity.
126+** Gradually remove messages which are old debugging aids.
127+**
128+** - Use printk() for messages which are to be always logged.
129+** Supply either 'acx:' or '<devname>:' prefix so that user
130+** can figure out who's speaking among other kernel chatter.
131+** acx: is for general issues (e.g. "acx: no firmware image!")
132+** while <devname>: is related to a particular device
133+** (think about multi-card setup). Double check that message
134+** is not confusing to the average user.
135+**
136+** - use printk KERN_xxx level only if message is not a WARNING
137+** but is INFO, ERR etc.
138+**
139+** - Use printk_ratelimited() for messages which may flood
140+** (e.g. "rx DUP pkt!").
141+**
142+** - Use log() for messages which may be omitted (and they
143+** _will_ be omitted in non-debug builds). Note that
144+** message levels may be disabled at compile-time selectively,
145+** thus select them wisely. Example: L_DEBUG is the lowest
146+** (most likely to be compiled out) -> use for less important stuff.
147+**
148+** - Do not print important stuff with log(), or else people
149+** will never build non-debug driver.
150+**
151+** Style:
152+** hex: capital letters, zero filled (e.g. 0x02AC)
153+** str: dont start from capitals, no trailing periods ("tx: queue is stopped")
154+*/
155+#if ACX_DEBUG > 1
156+
157+void log_fn_enter(const char *funcname);
158+void log_fn_exit(const char *funcname);
159+void log_fn_exit_v(const char *funcname, int v);
160+
161+#define FN_ENTER \
162+ do { \
163+ if (unlikely(acx_debug & L_FUNC)) { \
164+ log_fn_enter(__func__); \
165+ } \
166+ } while (0)
167+
168+#define FN_EXIT1(v) \
169+ do { \
170+ if (unlikely(acx_debug & L_FUNC)) { \
171+ log_fn_exit_v(__func__, v); \
172+ } \
173+ } while (0)
174+#define FN_EXIT0 \
175+ do { \
176+ if (unlikely(acx_debug & L_FUNC)) { \
177+ log_fn_exit(__func__); \
178+ } \
179+ } while (0)
180+
181+#else
182+
183+#define FN_ENTER
184+#define FN_EXIT1(v)
185+#define FN_EXIT0
186+
187+#endif /* ACX_DEBUG > 1 */
188+
189+
190+#if ACX_DEBUG
191+
192+#define log(chan, args...) \
193+ do { \
194+ if (acx_debug & (chan)) \
195+ printk(KERN_DEBUG args); \
196+ } while (0)
197+#define printk_ratelimited(args...) printk(args)
198+
199+#else /* Non-debug build: */
200+
201+#define log(chan, args...)
202+/* Standard way of log flood prevention */
203+#define printk_ratelimited(args...) \
204+do { \
205+ if (printk_ratelimit()) \
206+ printk(args); \
207+} while (0)
208+
209+#endif /* ACX_DEBUG */
210+
211+void acx_print_mac(const char *head, const u8 *mac, const char *tail);
212+
213+/* Optimized out to nothing in non-debug build */
214+static inline void
215+acxlog_mac(int level, const char *head, const u8 *mac, const char *tail)
216+{
217+ if (acx_debug & level) {
218+ acx_print_mac(head, mac, tail);
219+ }
220+}
221+
222+
223+/***********************************************************************
224+** MAC address helpers
225+*/
226+static inline void
227+MAC_COPY(u8 *mac, const u8 *src)
228+{
229+ *(u32*)mac = *(u32*)src;
230+ ((u16*)mac)[2] = ((u16*)src)[2];
231+ /* kernel's memcpy will do the same: memcpy(dst, src, ETH_ALEN); */
232+}
233+
234+static inline void
235+MAC_FILL(u8 *mac, u8 val)
236+{
237+ memset(mac, val, ETH_ALEN);
238+}
239+
240+static inline void
241+MAC_BCAST(u8 *mac)
242+{
243+ ((u16*)mac)[2] = *(u32*)mac = -1;
244+}
245+
246+static inline void
247+MAC_ZERO(u8 *mac)
248+{
249+ ((u16*)mac)[2] = *(u32*)mac = 0;
250+}
251+
252+static inline int
253+mac_is_equal(const u8 *a, const u8 *b)
254+{
255+ /* can't beat this */
256+ return memcmp(a, b, ETH_ALEN) == 0;
257+}
258+
259+static inline int
260+mac_is_bcast(const u8 *mac)
261+{
262+ /* AND together 4 first bytes with sign-extended 2 last bytes
263+ ** Only bcast address gives 0xffffffff. +1 gives 0 */
264+ return ( *(s32*)mac & ((s16*)mac)[2] ) + 1 == 0;
265+}
266+
267+static inline int
268+mac_is_zero(const u8 *mac)
269+{
270+ return ( *(u32*)mac | ((u16*)mac)[2] ) == 0;
271+}
272+
273+static inline int
274+mac_is_directed(const u8 *mac)
275+{
276+ return (mac[0] & 1)==0;
277+}
278+
279+static inline int
280+mac_is_mcast(const u8 *mac)
281+{
282+ return (mac[0] & 1) && !mac_is_bcast(mac);
283+}
284+
285+#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
286+#define MAC(bytevector) \
287+ ((unsigned char *)bytevector)[0], \
288+ ((unsigned char *)bytevector)[1], \
289+ ((unsigned char *)bytevector)[2], \
290+ ((unsigned char *)bytevector)[3], \
291+ ((unsigned char *)bytevector)[4], \
292+ ((unsigned char *)bytevector)[5]
293+
294+
295+/***********************************************************************
296+** Random helpers
297+*/
298+#define TO_STRING(x) #x
299+#define STRING(x) TO_STRING(x)
300+
301+#define CLEAR_BIT(val, mask) ((val) &= ~(mask))
302+#define SET_BIT(val, mask) ((val) |= (mask))
303+
304+/* undefined if v==0 */
305+static inline unsigned int
306+lowest_bit(u16 v)
307+{
308+ unsigned int n = 0;
309+ while (!(v & 0xf)) { v>>=4; n+=4; }
310+ while (!(v & 1)) { v>>=1; n++; }
311+ return n;
312+}
313+
314+/* undefined if v==0 */
315+static inline unsigned int
316+highest_bit(u16 v)
317+{
318+ unsigned int n = 0;
319+ while (v>0xf) { v>>=4; n+=4; }
320+ while (v>1) { v>>=1; n++; }
321+ return n;
322+}
323+
324+/* undefined if v==0 */
325+static inline int
326+has_only_one_bit(u16 v)
327+{
328+ return ((v-1) ^ v) >= v;
329+}
330+
331+
332+static inline int
333+is_hidden_essid(char *essid)
334+{
335+ return (('\0' == essid[0]) ||
336+ ((' ' == essid[0]) && ('\0' == essid[1])));
337+}
338+
339+/***********************************************************************
340+** LOCKING
341+** We have adev->sem and adev->lock.
342+**
343+** We employ following naming convention in order to get locking right:
344+**
345+** acx_e_xxxx - external entry points called from process context.
346+** It is okay to sleep. adev->sem is to be taken on entry.
347+** acx_i_xxxx - external entry points possibly called from atomic context.
348+** Sleeping is not allowed (and thus down(sem) is not legal!)
349+** acx_s_xxxx - potentially sleeping functions. Do not ever call under lock!
350+** acx_l_xxxx - functions which expect lock to be already taken.
351+** rest - non-sleeping functions which do not require locking
352+** but may be run under lock
353+**
354+** A small number of local helpers do not have acx_[eisl]_ prefix.
355+** They are always close to caller and are to be reviewed locally.
356+**
357+** Theory of operation:
358+**
359+** All process-context entry points (_e_ functions) take sem
360+** immediately. IRQ handler and other 'atomic-context' entry points
361+** (_i_ functions) take lock immediately on entry, but dont take sem
362+** because that might sleep.
363+**
364+** Thus *all* code is either protected by sem or lock, or both.
365+**
366+** Code which must not run concurrently with IRQ takes lock.
367+** Such code is marked with _l_.
368+**
369+** This results in the following rules of thumb useful in code review:
370+**
371+** + If a function calls _s_ fn, it must be an _s_ itself.
372+** + You can call _l_ fn only (a) from another _l_ fn
373+** or (b) from _s_, _e_ or _i_ fn by taking lock, calling _l_,
374+** and dropping lock.
375+** + All IRQ code runs under lock.
376+** + Any _s_ fn is running under sem.
377+** + Code under sem can race only with IRQ code.
378+** + Code under sem+lock cannot race with anything.
379+*/
380+
381+/* These functions *must* be inline or they will break horribly on SPARC, due
382+ * to its weird semantics for save/restore flags */
383+
384+#if defined(PARANOID_LOCKING) /* Lock debugging */
385+
386+void acx_lock_debug(acx_device_t *adev, const char* where);
387+void acx_unlock_debug(acx_device_t *adev, const char* where);
388+void acx_down_debug(acx_device_t *adev, const char* where);
389+void acx_up_debug(acx_device_t *adev, const char* where);
390+void acx_lock_unhold(void);
391+void acx_sem_unhold(void);
392+
393+static inline void
394+acx_lock_helper(acx_device_t *adev, unsigned long *fp, const char* where)
395+{
396+ acx_lock_debug(adev, where);
397+ spin_lock_irqsave(&adev->lock, *fp);
398+}
399+static inline void
400+acx_unlock_helper(acx_device_t *adev, unsigned long *fp, const char* where)
401+{
402+ acx_unlock_debug(adev, where);
403+ spin_unlock_irqrestore(&adev->lock, *fp);
404+}
405+static inline void
406+acx_down_helper(acx_device_t *adev, const char* where)
407+{
408+ acx_down_debug(adev, where);
409+}
410+static inline void
411+acx_up_helper(acx_device_t *adev, const char* where)
412+{
413+ acx_up_debug(adev, where);
414+}
415+#define acx_lock(adev, flags) acx_lock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__))
416+#define acx_unlock(adev, flags) acx_unlock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__))
417+#define acx_sem_lock(adev) acx_down_helper(adev, __FILE__ ":" STRING(__LINE__))
418+#define acx_sem_unlock(adev) acx_up_helper(adev, __FILE__ ":" STRING(__LINE__))
419+
420+#elif defined(DO_LOCKING)
421+
422+#define acx_lock(adev, flags) spin_lock_irqsave(&adev->lock, flags)
423+#define acx_unlock(adev, flags) spin_unlock_irqrestore(&adev->lock, flags)
424+#define acx_sem_lock(adev) down(&adev->sem)
425+#define acx_sem_unlock(adev) up(&adev->sem)
426+#define acx_lock_unhold() ((void)0)
427+#define acx_sem_unhold() ((void)0)
428+
429+#else /* no locking! :( */
430+
431+#define acx_lock(adev, flags) ((void)0)
432+#define acx_unlock(adev, flags) ((void)0)
433+#define acx_sem_lock(adev) ((void)0)
434+#define acx_sem_unlock(adev) ((void)0)
435+#define acx_lock_unhold() ((void)0)
436+#define acx_sem_unhold() ((void)0)
437+
438+#endif
439+
440+
441+/***********************************************************************
442+*/
443+
444+/* Can race with rx path (which is not protected by sem):
445+** rx -> process_[re]assocresp() -> set_status(ASSOCIATED) -> wake_queue()
446+** Can race with tx_complete IRQ:
447+** IRQ -> acxpci_l_clean_txdesc -> acx_wake_queue
448+** Review carefully all callsites */
449+static inline void
450+acx_stop_queue(struct net_device *ndev, const char *msg)
451+{
452+ if (netif_queue_stopped(ndev))
453+ return;
454+
455+ netif_stop_queue(ndev);
456+ if (msg)
457+ log(L_BUFT, "tx: stop queue %s\n", msg);
458+}
459+
460+static inline int
461+acx_queue_stopped(struct net_device *ndev)
462+{
463+ return netif_queue_stopped(ndev);
464+}
465+
466+/*
467+static inline void
468+acx_start_queue(struct net_device *ndev, const char *msg)
469+{
470+ netif_start_queue(ndev);
471+ if (msg)
472+ log(L_BUFT, "tx: start queue %s\n", msg);
473+}
474+*/
475+
476+static inline void
477+acx_wake_queue(struct net_device *ndev, const char *msg)
478+{
479+ netif_wake_queue(ndev);
480+ if (msg)
481+ log(L_BUFT, "tx: wake queue %s\n", msg);
482+}
483+
484+static inline void
485+acx_carrier_off(struct net_device *ndev, const char *msg)
486+{
487+ netif_carrier_off(ndev);
488+ if (msg)
489+ log(L_BUFT, "tx: carrier off %s\n", msg);
490+}
491+
492+static inline void
493+acx_carrier_on(struct net_device *ndev, const char *msg)
494+{
495+ netif_carrier_on(ndev);
496+ if (msg)
497+ log(L_BUFT, "tx: carrier on %s\n", msg);
498+}
499+
500+/* This function does not need locking UNLESS you call it
501+** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can
502+** wake queue. This can race with stop_queue elsewhere. */
503+void acx_set_status(acx_device_t *adev, u16 status);
504+
505+
506+/***********************************************************************
507+** Communication with firmware
508+*/
509+#define CMD_TIMEOUT_MS(n) (n)
510+#define ACX_CMD_TIMEOUT_DEFAULT CMD_TIMEOUT_MS(50)
511+
512+#if ACX_DEBUG
513+
514+/* We want to log cmd names */
515+int acxpci_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr);
516+int acxmem_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr);
517+int acxusb_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr);
518+static inline int
519+acx_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr)
520+{
521+ if (IS_MEM(adev))
522+ return acxmem_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr);
523+ if (IS_PCI(adev))
524+ return acxpci_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr);
525+ return acxusb_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr);
526+}
527+#define acx_s_issue_cmd(adev,cmd,param,len) \
528+ acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,ACX_CMD_TIMEOUT_DEFAULT,#cmd)
529+#define acx_s_issue_cmd_timeo(adev,cmd,param,len,timeo) \
530+ acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,timeo,#cmd)
531+int acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* str);
532+#define acx_s_configure(adev,pdr,type) \
533+ acx_s_configure_debug(adev,pdr,type,#type)
534+int acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, const char* str);
535+#define acx_s_interrogate(adev,pdr,type) \
536+ acx_s_interrogate_debug(adev,pdr,type,#type)
537+
538+#else
539+
540+int acxpci_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout);
541+int acxmem_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout);
542+int acxusb_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout);
543+static inline int
544+acx_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout)
545+{
546+ if (IS_MEM(adev))
547+ return acxmem_s_issue_cmd_timeo(adev, cmd, param, len, timeout);
548+ if (IS_PCI(adev))
549+ return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, timeout);
550+ return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, timeout);
551+}
552+static inline int
553+acx_s_issue_cmd(acx_device_t *adev, unsigned cmd, void *param, unsigned len)
554+{
555+ if (IS_MEM(adev))
556+ return acxmem_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT);
557+ if (IS_PCI(adev))
558+ return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT);
559+ return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT);
560+}
561+int acx_s_configure(acx_device_t *adev, void *pdr, int type);
562+int acx_s_interrogate(acx_device_t *adev, void *pdr, int type);
563+
564+#endif
565+
566+void acx_s_cmd_start_scan(acx_device_t *adev);
567+
568+
569+/***********************************************************************
570+** Ioctls
571+*/
572+int
573+acx111pci_ioctl_info(
574+ struct net_device *ndev,
575+ struct iw_request_info *info,
576+ struct iw_param *vwrq,
577+ char *extra);
578+int
579+acx100pci_ioctl_set_phy_amp_bias(
580+ struct net_device *ndev,
581+ struct iw_request_info *info,
582+ struct iw_param *vwrq,
583+ char *extra);
584+int
585+acx100mem_ioctl_set_phy_amp_bias(
586+ struct net_device *ndev,
587+ struct iw_request_info *info,
588+ struct iw_param *vwrq,
589+ char *extra);
590+
591+
592+/***********************************************************************
593+** /proc
594+*/
595+#ifdef CONFIG_PROC_FS
596+int acx_proc_register_entries(const struct net_device *ndev);
597+int acx_proc_unregister_entries(const struct net_device *ndev);
598+#else
599+static inline int
600+acx_proc_register_entries(const struct net_device *ndev) { return OK; }
601+static inline int
602+acx_proc_unregister_entries(const struct net_device *ndev) { return OK; }
603+#endif
604+
605+
606+/***********************************************************************
607+*/
608+firmware_image_t *acx_s_read_fw(struct device *dev, const char *file, u32 *size);
609+int acxpci_s_upload_radio(acx_device_t *adev);
610+int acxmem_s_upload_radio(acx_device_t *adev);
611+
612+
613+/***********************************************************************
614+** Unsorted yet :)
615+*/
616+int acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf);
617+int acxmem_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf);
618+int acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf);
619+static inline int
620+acx_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf)
621+{
622+ if (IS_MEM(adev))
623+ return acxmem_s_read_phy_reg(adev, reg, charbuf);
624+ if (IS_PCI(adev))
625+ return acxpci_s_read_phy_reg(adev, reg, charbuf);
626+ return acxusb_s_read_phy_reg(adev, reg, charbuf);
627+}
628+
629+int acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value);
630+int acxmem_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value);
631+int acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value);
632+static inline int
633+acx_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value)
634+{
635+ if (IS_MEM(adev))
636+ return acxmem_s_write_phy_reg(adev, reg, value);
637+ if (IS_PCI(adev))
638+ return acxpci_s_write_phy_reg(adev, reg, value);
639+ return acxusb_s_write_phy_reg(adev, reg, value);
640+}
641+
642+tx_t* acxpci_l_alloc_tx(acx_device_t *adev);
643+tx_t* acxmem_l_alloc_tx(acx_device_t *adev);
644+tx_t* acxusb_l_alloc_tx(acx_device_t *adev);
645+static inline tx_t*
646+acx_l_alloc_tx(acx_device_t *adev)
647+{
648+ if (IS_MEM(adev))
649+ return acxmem_l_alloc_tx(adev);
650+ if (IS_PCI(adev))
651+ return acxpci_l_alloc_tx(adev);
652+ return acxusb_l_alloc_tx(adev);
653+}
654+
655+void acxusb_l_dealloc_tx(tx_t *tx_opaque);
656+void acxmem_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque);
657+static inline void
658+acx_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque)
659+{
660+#ifdef ACX_MEM
661+ acxmem_l_dealloc_tx (adev, tx_opaque);
662+#else
663+ if (IS_USB(adev))
664+ acxusb_l_dealloc_tx(tx_opaque);
665+#endif
666+}
667+
668+void* acxpci_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque);
669+void* acxmem_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque);
670+void* acxusb_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque);
671+static inline void*
672+acx_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque)
673+{
674+#if defined (ACX_MEM)
675+ return acxmem_l_get_txbuf(adev, tx_opaque);
676+#else
677+ if (IS_PCI(adev))
678+ return acxpci_l_get_txbuf(adev, tx_opaque);
679+ return acxusb_l_get_txbuf(adev, tx_opaque);
680+#endif
681+}
682+
683+void acxpci_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len);
684+void acxmem_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len);
685+void acxusb_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len);
686+static inline void
687+acx_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len)
688+{
689+#if defined (ACX_MEM)
690+ acxmem_l_tx_data(adev, tx_opaque, len);
691+#else
692+ if (IS_PCI(adev))
693+ acxpci_l_tx_data(adev, tx_opaque, len);
694+ else
695+ acxusb_l_tx_data(adev, tx_opaque, len);
696+#endif
697+}
698+
699+static inline wlan_hdr_t*
700+acx_get_wlan_hdr(acx_device_t *adev, const rxbuffer_t *rxbuf)
701+{
702+ return (wlan_hdr_t*)((u8*)&rxbuf->hdr_a3 + adev->phy_header_len);
703+}
704+
705+void acxpci_l_power_led(acx_device_t *adev, int enable);
706+int acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf);
707+unsigned int acxpci_l_clean_txdesc(acx_device_t *adev);
708+void acxpci_l_clean_txdesc_emergency(acx_device_t *adev);
709+int acxpci_s_create_hostdesc_queues(acx_device_t *adev);
710+void acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start);
711+void acxpci_free_desc_queues(acx_device_t *adev);
712+char* acxpci_s_proc_diag_output(char *p, acx_device_t *adev);
713+int acxpci_proc_eeprom_output(char *p, acx_device_t *adev);
714+void acxpci_set_interrupt_mask(acx_device_t *adev);
715+int acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm);
716+
717+void acxmem_l_power_led(acx_device_t *adev, int enable);
718+int acxmem_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf);
719+unsigned int acxmem_l_clean_txdesc(acx_device_t *adev);
720+void acxmem_l_clean_txdesc_emergency(acx_device_t *adev);
721+int acxmem_s_create_hostdesc_queues(acx_device_t *adev);
722+void acxmem_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start);
723+void acxmem_free_desc_queues(acx_device_t *adev);
724+char* acxmem_s_proc_diag_output(char *p, acx_device_t *adev);
725+int acxmem_proc_eeprom_output(char *p, acx_device_t *adev);
726+void acxmem_set_interrupt_mask(acx_device_t *adev);
727+int acx100mem_s_set_tx_level(acx_device_t *adev, u8 level_dbm);
728+
729+void acx_s_msleep(int ms);
730+int acx_s_init_mac(acx_device_t *adev);
731+void acx_set_reg_domain(acx_device_t *adev, unsigned char reg_dom_id);
732+void acx_set_timer(acx_device_t *adev, int timeout_us);
733+void acx_update_capabilities(acx_device_t *adev);
734+void acx_s_start(acx_device_t *adev);
735+
736+void acx_s_update_card_settings(acx_device_t *adev);
737+void acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg);
738+void acx_l_update_ratevector(acx_device_t *adev);
739+
740+void acx_init_task_scheduler(acx_device_t *adev);
741+void acx_schedule_task(acx_device_t *adev, unsigned int set_flag);
742+
743+int acx_e_ioctl_old(struct net_device *ndev, struct ifreq *ifr, int cmd);
744+
745+client_t *acx_l_sta_list_get(acx_device_t *adev, const u8 *address);
746+void acx_l_sta_list_del(acx_device_t *adev, client_t *clt);
747+
748+int acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt);
749+void acx_i_timer(unsigned long a);
750+int acx_s_complete_scan(acx_device_t *adev);
751+
752+struct sk_buff *acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf);
753+int acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb);
754+
755+u8 acx_signal_determine_quality(u8 signal, u8 noise);
756+
757+void acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf);
758+void acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc,
759+ u16 intended_rate, u8 rate100, u16 rate111, u8 error,
760+ int pkts_to_ignore);
761+
762+void acx_dump_bytes(const void *, int);
763+void acx_log_bad_eid(wlan_hdr_t* hdr, int len, wlan_ie_t* ie_ptr);
764+
765+u8 acx_rate111to100(u16);
766+
767+void acx_s_set_defaults(acx_device_t *adev);
768+
769+#if !ACX_DEBUG
770+static inline const char* acx_get_packet_type_string(u16 fc) { return ""; }
771+#else
772+const char* acx_get_packet_type_string(u16 fc);
773+#endif
774+const char* acx_cmd_status_str(unsigned int state);
775+
776+int acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev);
777+
778+void great_inquisitor(acx_device_t *adev);
779+
780+void acx_s_get_firmware_version(acx_device_t *adev);
781+void acx_display_hardware_details(acx_device_t *adev);
782+
783+int acx_e_change_mtu(struct net_device *ndev, int mtu);
784+struct net_device_stats* acx_e_get_stats(struct net_device *ndev);
785+struct iw_statistics* acx_e_get_wireless_stats(struct net_device *ndev);
786+
787+#ifdef ACX_MEM
788+int __init acxmem_e_init_module(void);
789+void __exit acxmem_e_cleanup_module(void);
790+void acxmem_e_release(struct device *dev);
791+#else
792+int __init acxpci_e_init_module(void);
793+int __init acxusb_e_init_module(void);
794+void __exit acxpci_e_cleanup_module(void);
795+void __exit acxusb_e_cleanup_module(void);
796+#endif
797+int __init acx_cs_init(void);
798+void __exit acx_cs_cleanup(void);
799Index: linux-2.6.22/drivers/net/wireless/acx/acx.h
800===================================================================
801--- /dev/null 1970-01-01 00:00:00.000000000 +0000
802+++ linux-2.6.22/drivers/net/wireless/acx/acx.h 2007-08-23 18:34:19.000000000 +0200
803@@ -0,0 +1,14 @@
804+#if defined(CONFIG_ACX_MEM) && !defined(ACX_MEM)
805+#define ACX_MEM
806+#endif
807+
808+#if defined(CONFIG_ACX_CS) && !defined(ACX_MEM)
809+#define ACX_MEM
810+#endif
811+
812+#include "acx_config.h"
813+#include "wlan_compat.h"
814+#include "wlan_hdr.h"
815+#include "wlan_mgmt.h"
816+#include "acx_struct.h"
817+#include "acx_func.h"
818Index: linux-2.6.22/drivers/net/wireless/acx/acx_hw.h
819===================================================================
820--- /dev/null 1970-01-01 00:00:00.000000000 +0000
821+++ linux-2.6.22/drivers/net/wireless/acx/acx_hw.h 2007-08-23 18:34:19.000000000 +0200
822@@ -0,0 +1,18 @@
823+/*
824+ * Interface for ACX slave memory driver
825+ *
826+ * Copyright (c) 2006 SDG Systems, LLC
827+ *
828+ * GPL
829+ *
830+ */
831+
832+#ifndef _ACX_HW_H
833+#define _ACX_HW_H
834+
835+struct acx_hardware_data {
836+ int (*start_hw)( void );
837+ int (*stop_hw)( void );
838+};
839+
840+#endif /* _ACX_HW_H */
841Index: linux-2.6.22/drivers/net/wireless/acx/acx_struct.h
842===================================================================
843--- /dev/null 1970-01-01 00:00:00.000000000 +0000
844+++ linux-2.6.22/drivers/net/wireless/acx/acx_struct.h 2007-08-23 18:34:19.000000000 +0200
845@@ -0,0 +1,2114 @@
846+/***********************************************************************
847+** Copyright (C) 2003 ACX100 Open Source Project
848+**
849+** The contents of this file are subject to the Mozilla Public
850+** License Version 1.1 (the "License"); you may not use this file
851+** except in compliance with the License. You may obtain a copy of
852+** the License at http://www.mozilla.org/MPL/
853+**
854+** Software distributed under the License is distributed on an "AS
855+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
856+** implied. See the License for the specific language governing
857+** rights and limitations under the License.
858+**
859+** Alternatively, the contents of this file may be used under the
860+** terms of the GNU Public License version 2 (the "GPL"), in which
861+** case the provisions of the GPL are applicable instead of the
862+** above. If you wish to allow the use of your version of this file
863+** only under the terms of the GPL and not to allow others to use
864+** your version of this file under the MPL, indicate your decision
865+** by deleting the provisions above and replace them with the notice
866+** and other provisions required by the GPL. If you do not delete
867+** the provisions above, a recipient may use your version of this
868+** file under either the MPL or the GPL.
869+** ---------------------------------------------------------------------
870+** Inquiries regarding the ACX100 Open Source Project can be
871+** made directly to:
872+**
873+** acx100-users@lists.sf.net
874+** http://acx100.sf.net
875+** ---------------------------------------------------------------------
876+*/
877+
878+/***********************************************************************
879+** Forward declarations of types
880+*/
881+typedef struct tx tx_t;
882+typedef struct acx_device acx_device_t;
883+typedef struct client client_t;
884+typedef struct rxdesc rxdesc_t;
885+typedef struct txdesc txdesc_t;
886+typedef struct rxhostdesc rxhostdesc_t;
887+typedef struct txhostdesc txhostdesc_t;
888+
889+
890+/***********************************************************************
891+** Debug / log functionality
892+*/
893+enum {
894+ L_LOCK = (ACX_DEBUG>1)*0x0001, /* locking debug log */
895+ L_INIT = (ACX_DEBUG>0)*0x0002, /* special card initialization logging */
896+ L_IRQ = (ACX_DEBUG>0)*0x0004, /* interrupt stuff */
897+ L_ASSOC = (ACX_DEBUG>0)*0x0008, /* assocation (network join) and station log */
898+ L_FUNC = (ACX_DEBUG>1)*0x0020, /* logging of function enter / leave */
899+ L_XFER = (ACX_DEBUG>1)*0x0080, /* logging of transfers and mgmt */
900+ L_DATA = (ACX_DEBUG>1)*0x0100, /* logging of transfer data */
901+ L_DEBUG = (ACX_DEBUG>1)*0x0200, /* log of debug info */
902+ L_IOCTL = (ACX_DEBUG>0)*0x0400, /* log ioctl calls */
903+ L_CTL = (ACX_DEBUG>1)*0x0800, /* log of low-level ctl commands */
904+ L_BUFR = (ACX_DEBUG>1)*0x1000, /* debug rx buffer mgmt (ring buffer etc.) */
905+ L_XFER_BEACON = (ACX_DEBUG>1)*0x2000, /* also log beacon packets */
906+ L_BUFT = (ACX_DEBUG>1)*0x4000, /* debug tx buffer mgmt (ring buffer etc.) */
907+ L_USBRXTX = (ACX_DEBUG>0)*0x8000, /* debug USB rx/tx operations */
908+ L_BUF = L_BUFR + L_BUFT,
909+ L_ANY = 0xffff
910+};
911+
912+#if ACX_DEBUG
913+extern unsigned int acx_debug;
914+#else
915+enum { acx_debug = 0 };
916+#endif
917+
918+
919+/***********************************************************************
920+** Random helpers
921+*/
922+#define ACX_PACKED __attribute__ ((packed))
923+
924+#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
925+
926+/* Use worker_queues for 2.5/2.6 kernels and queue tasks for 2.4 kernels
927+ (used for the 'bottom half' of the interrupt routine) */
928+
929+#include <linux/workqueue.h>
930+#define USE_WORKER_TASKS
931+#define WORK_STRUCT struct work_struct
932+#define SCHEDULE_WORK schedule_work
933+#define FLUSH_SCHEDULED_WORK flush_scheduled_work
934+
935+
936+/***********************************************************************
937+** Constants
938+*/
939+#define OK 0
940+#define NOT_OK 1
941+
942+/* The supported chip models */
943+#define CHIPTYPE_ACX100 1
944+#define CHIPTYPE_ACX111 2
945+
946+#define IS_ACX100(adev) ((adev)->chip_type == CHIPTYPE_ACX100)
947+#define IS_ACX111(adev) ((adev)->chip_type == CHIPTYPE_ACX111)
948+
949+/* Supported interfaces */
950+#define DEVTYPE_PCI 0
951+#define DEVTYPE_USB 1
952+#define DEVTYPE_MEM 2
953+
954+#if !defined(CONFIG_ACX_PCI) && !defined(CONFIG_ACX_USB) && !defined(CONFIG_ACX_MEM) && !defined(CONFIG_ACX_CS)
955+#error Driver must include PCI, USB, PCMCIA or memory mapped interface support. You selected none of them.
956+#endif
957+
958+#if defined(CONFIG_ACX_PCI)
959+ #if !defined(CONFIG_ACX_USB)
960+ #define IS_PCI(adev) 1
961+ #else
962+ #define IS_PCI(adev) ((adev)->dev_type == DEVTYPE_PCI)
963+ #endif
964+#else
965+ #define IS_PCI(adev) 0
966+#endif
967+
968+#if defined(CONFIG_ACX_USB)
969+ #if !defined(CONFIG_ACX_PCI)
970+ #define IS_USB(adev) 1
971+ #else
972+ #define IS_USB(adev) ((adev)->dev_type == DEVTYPE_USB)
973+ #endif
974+#else
975+ #define IS_USB(adev) 0
976+#endif
977+
978+#if defined(CONFIG_ACX_MEM) || defined(CONFIG_ACX_CS)
979+ #define IS_MEM(adev) 1
980+#else
981+ #define IS_MEM(adev) 0
982+#endif
983+
984+/* Driver defaults */
985+#define DEFAULT_DTIM_INTERVAL 10
986+/* used to be 2048, but FreeBSD driver changed it to 4096 to work properly
987+** in noisy wlans */
988+#define DEFAULT_MSDU_LIFETIME 4096
989+#define DEFAULT_RTS_THRESHOLD 2312 /* max. size: disable RTS mechanism */
990+#define DEFAULT_BEACON_INTERVAL 100
991+
992+#define ACX100_BAP_DATALEN_MAX 4096
993+#define ACX100_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
994+#define ACX100_RIDDATA_MAXLEN ACX100_RID_GUESSING_MAXLEN
995+
996+/* Support Constants */
997+/* Radio type names, found in Win98 driver's TIACXLN.INF */
998+#define RADIO_MAXIM_0D 0x0d
999+#define RADIO_RFMD_11 0x11
1000+#define RADIO_RALINK_15 0x15
1001+/* used in ACX111 cards (WG311v2, WL-121, ...): */
1002+#define RADIO_RADIA_16 0x16
1003+/* most likely *sometimes* used in ACX111 cards: */
1004+#define RADIO_UNKNOWN_17 0x17
1005+/* FwRad19.bin was found in a Safecom driver; must be an ACX111 radio: */
1006+#define RADIO_UNKNOWN_19 0x19
1007+#define RADIO_UNKNOWN_1B 0x1b /* radio in SafeCom SWLUT-54125 USB adapter; entirely unknown!! */
1008+
1009+/* Controller Commands */
1010+/* can be found in table cmdTable in firmware "Rev. 1.5.0" (FW150) */
1011+#define ACX1xx_CMD_RESET 0x00
1012+#define ACX1xx_CMD_INTERROGATE 0x01
1013+#define ACX1xx_CMD_CONFIGURE 0x02
1014+#define ACX1xx_CMD_ENABLE_RX 0x03
1015+#define ACX1xx_CMD_ENABLE_TX 0x04
1016+#define ACX1xx_CMD_DISABLE_RX 0x05
1017+#define ACX1xx_CMD_DISABLE_TX 0x06
1018+#define ACX1xx_CMD_FLUSH_QUEUE 0x07
1019+#define ACX1xx_CMD_SCAN 0x08
1020+#define ACX1xx_CMD_STOP_SCAN 0x09
1021+#define ACX1xx_CMD_CONFIG_TIM 0x0a
1022+#define ACX1xx_CMD_JOIN 0x0b
1023+#define ACX1xx_CMD_WEP_MGMT 0x0c
1024+#ifdef OLD_FIRMWARE_VERSIONS
1025+#define ACX100_CMD_HALT 0x0e /* mapped to unknownCMD in FW150 */
1026+#else
1027+#define ACX1xx_CMD_MEM_READ 0x0d
1028+#define ACX1xx_CMD_MEM_WRITE 0x0e
1029+#endif
1030+#define ACX1xx_CMD_SLEEP 0x0f
1031+#define ACX1xx_CMD_WAKE 0x10
1032+#define ACX1xx_CMD_UNKNOWN_11 0x11 /* mapped to unknownCMD in FW150 */
1033+#define ACX100_CMD_INIT_MEMORY 0x12
1034+#define ACX1FF_CMD_DISABLE_RADIO 0x12 /* new firmware? TNETW1450? */
1035+#define ACX1xx_CMD_CONFIG_BEACON 0x13
1036+#define ACX1xx_CMD_CONFIG_PROBE_RESPONSE 0x14
1037+#define ACX1xx_CMD_CONFIG_NULL_DATA 0x15
1038+#define ACX1xx_CMD_CONFIG_PROBE_REQUEST 0x16
1039+#define ACX1xx_CMD_FCC_TEST 0x17
1040+#define ACX1xx_CMD_RADIOINIT 0x18
1041+#define ACX111_CMD_RADIOCALIB 0x19
1042+#define ACX1FF_CMD_NOISE_HISTOGRAM 0x1c /* new firmware? TNETW1450? */
1043+#define ACX1FF_CMD_RX_RESET 0x1d /* new firmware? TNETW1450? */
1044+#define ACX1FF_CMD_LNA_CONTROL 0x20 /* new firmware? TNETW1450? */
1045+#define ACX1FF_CMD_CONTROL_DBG_TRACE 0x21 /* new firmware? TNETW1450? */
1046+
1047+/* 'After Interrupt' Commands */
1048+#define ACX_AFTER_IRQ_CMD_STOP_SCAN 0x01
1049+#define ACX_AFTER_IRQ_CMD_ASSOCIATE 0x02
1050+#define ACX_AFTER_IRQ_CMD_RADIO_RECALIB 0x04
1051+#define ACX_AFTER_IRQ_UPDATE_CARD_CFG 0x08
1052+#define ACX_AFTER_IRQ_TX_CLEANUP 0x10
1053+#define ACX_AFTER_IRQ_COMPLETE_SCAN 0x20
1054+#define ACX_AFTER_IRQ_RESTART_SCAN 0x40
1055+
1056+/***********************************************************************
1057+** Tx/Rx buffer sizes and watermarks
1058+**
1059+** This will alloc and use DMAable buffers of
1060+** WLAN_A4FR_MAXLEN_WEP_FCS * (RX_CNT + TX_CNT) bytes
1061+** RX/TX_CNT=32 -> ~150k DMA buffers
1062+** RX/TX_CNT=16 -> ~75k DMA buffers
1063+**
1064+** 2005-10-10: reduced memory usage by lowering both to 16
1065+*/
1066+#define RX_CNT 16
1067+#define TX_CNT 16
1068+
1069+/* we clean up txdescs when we have N free txdesc: */
1070+#define TX_CLEAN_BACKLOG (TX_CNT/4)
1071+#define TX_START_CLEAN (TX_CNT - TX_CLEAN_BACKLOG)
1072+#define TX_EMERG_CLEAN 2
1073+/* we stop queue if we have < N free txbufs: */
1074+#define TX_STOP_QUEUE 3
1075+/* we start queue if we have >= N free txbufs: */
1076+#define TX_START_QUEUE 5
1077+
1078+/***********************************************************************
1079+** Interrogate/Configure cmd constants
1080+**
1081+** NB: length includes JUST the data part of the IE
1082+** (does not include size of the (type,len) pair)
1083+**
1084+** TODO: seems that acx100, acx100usb, acx111 have some differences,
1085+** fix code with regard to this!
1086+*/
1087+
1088+#define DEF_IE(name, val, len) enum { ACX##name=val, ACX##name##_LEN=len }
1089+
1090+/* Information Elements: Network Parameters, Static Configuration Entities */
1091+/* these are handled by real_cfgtable in firmware "Rev 1.5.0" (FW150) */
1092+DEF_IE(1xx_IE_UNKNOWN_00 ,0x0000, -1); /* mapped to cfgInvalid in FW150 */
1093+DEF_IE(100_IE_ACX_TIMER ,0x0001, 0x10);
1094+DEF_IE(1xx_IE_POWER_MGMT ,0x0002, 0x06); /* TNETW1450: length 0x18!! */
1095+DEF_IE(1xx_IE_QUEUE_CONFIG ,0x0003, 0x1c);
1096+DEF_IE(100_IE_BLOCK_SIZE ,0x0004, 0x02);
1097+DEF_IE(1FF_IE_SLOT_TIME ,0x0004, 0x08); /* later firmware versions only? */
1098+DEF_IE(1xx_IE_MEMORY_CONFIG_OPTIONS ,0x0005, 0x14);
1099+DEF_IE(1FF_IE_QUEUE_HEAD ,0x0005, 0x14 /* FIXME: length? */);
1100+DEF_IE(1xx_IE_RATE_FALLBACK ,0x0006, 0x01); /* TNETW1450: length 2 */
1101+DEF_IE(100_IE_WEP_OPTIONS ,0x0007, 0x03);
1102+DEF_IE(111_IE_RADIO_BAND ,0x0007, -1);
1103+DEF_IE(1FF_IE_TIMING_CFG ,0x0007, -1); /* later firmware versions; TNETW1450 only? */
1104+DEF_IE(100_IE_SSID ,0x0008, 0x20); /* huh? */
1105+DEF_IE(1xx_IE_MEMORY_MAP ,0x0008, 0x28); /* huh? TNETW1450 has length 0x40!! */
1106+DEF_IE(1xx_IE_SCAN_STATUS ,0x0009, 0x04); /* mapped to cfgInvalid in FW150 */
1107+DEF_IE(1xx_IE_ASSOC_ID ,0x000a, 0x02);
1108+DEF_IE(1xx_IE_UNKNOWN_0B ,0x000b, -1); /* mapped to cfgInvalid in FW150 */
1109+DEF_IE(1FF_IE_TX_POWER_LEVEL_TABLE ,0x000b, 0x18); /* later firmware versions; TNETW1450 only? */
1110+DEF_IE(100_IE_UNKNOWN_0C ,0x000c, -1); /* very small implementation in FW150! */
1111+/* ACX100 has an equivalent struct in the cmd mailbox directly after reset.
1112+ * 0x14c seems extremely large, will trash stack on failure (memset!)
1113+ * in case of small input struct --> OOPS! */
1114+DEF_IE(111_IE_CONFIG_OPTIONS ,0x000c, 0x14c);
1115+DEF_IE(1xx_IE_FWREV ,0x000d, 0x18);
1116+DEF_IE(1xx_IE_FCS_ERROR_COUNT ,0x000e, 0x04);
1117+DEF_IE(1xx_IE_MEDIUM_USAGE ,0x000f, 0x08);
1118+DEF_IE(1xx_IE_RXCONFIG ,0x0010, 0x04);
1119+DEF_IE(100_IE_UNKNOWN_11 ,0x0011, -1); /* NONBINARY: large implementation in FW150! link quality readings or so? */
1120+DEF_IE(111_IE_QUEUE_THRESH ,0x0011, -1);
1121+DEF_IE(100_IE_UNKNOWN_12 ,0x0012, -1); /* NONBINARY: VERY large implementation in FW150!! */
1122+DEF_IE(111_IE_BSS_POWER_SAVE ,0x0012, /* -1 */ 2);
1123+DEF_IE(1xx_IE_FIRMWARE_STATISTICS ,0x0013, 0x9c); /* TNETW1450: length 0x134!! */
1124+DEF_IE(1FF_IE_RX_INTR_CONFIG ,0x0014, 0x14); /* later firmware versions, TNETW1450 only? */
1125+DEF_IE(1xx_IE_FEATURE_CONFIG ,0x0015, 0x08);
1126+DEF_IE(111_IE_KEY_CHOOSE ,0x0016, 0x04); /* for rekeying. really len=4?? */
1127+DEF_IE(1FF_IE_MISC_CONFIG_TABLE ,0x0017, 0x04); /* later firmware versions, TNETW1450 only? */
1128+DEF_IE(1FF_IE_WONE_CONFIG ,0x0018, -1); /* later firmware versions, TNETW1450 only? */
1129+DEF_IE(1FF_IE_TID_CONFIG ,0x001a, 0x2c); /* later firmware versions, TNETW1450 only? */
1130+DEF_IE(1FF_IE_CALIB_ASSESSMENT ,0x001e, 0x04); /* later firmware versions, TNETW1450 only? */
1131+DEF_IE(1FF_IE_BEACON_FILTER_OPTIONS ,0x001f, 0x02); /* later firmware versions, TNETW1450 only? */
1132+DEF_IE(1FF_IE_LOW_RSSI_THRESH_OPT ,0x0020, 0x04); /* later firmware versions, TNETW1450 only? */
1133+DEF_IE(1FF_IE_NOISE_HISTOGRAM_RESULTS ,0x0021, 0x30); /* later firmware versions, TNETW1450 only? */
1134+DEF_IE(1FF_IE_PACKET_DETECT_THRESH ,0x0023, 0x04); /* later firmware versions, TNETW1450 only? */
1135+DEF_IE(1FF_IE_TX_CONFIG_OPTIONS ,0x0024, 0x04); /* later firmware versions, TNETW1450 only? */
1136+DEF_IE(1FF_IE_CCA_THRESHOLD ,0x0025, 0x02); /* later firmware versions, TNETW1450 only? */
1137+DEF_IE(1FF_IE_EVENT_MASK ,0x0026, 0x08); /* later firmware versions, TNETW1450 only? */
1138+DEF_IE(1FF_IE_DTIM_PERIOD ,0x0027, 0x02); /* later firmware versions, TNETW1450 only? */
1139+DEF_IE(1FF_IE_ACI_CONFIG_SET ,0x0029, 0x06); /* later firmware versions; maybe TNETW1450 only? */
1140+DEF_IE(1FF_IE_EEPROM_VER ,0x0030, 0x04); /* later firmware versions; maybe TNETW1450 only? */
1141+DEF_IE(1xx_IE_DOT11_STATION_ID ,0x1001, 0x06);
1142+DEF_IE(100_IE_DOT11_UNKNOWN_1002 ,0x1002, -1); /* mapped to cfgInvalid in FW150 */
1143+DEF_IE(111_IE_DOT11_FRAG_THRESH ,0x1002, -1); /* mapped to cfgInvalid in FW150; TNETW1450 has length 2!! */
1144+DEF_IE(100_IE_DOT11_BEACON_PERIOD ,0x1003, 0x02); /* mapped to cfgInvalid in FW150 */
1145+DEF_IE(1xx_IE_DOT11_DTIM_PERIOD ,0x1004, -1); /* mapped to cfgInvalid in FW150 */
1146+DEF_IE(1FF_IE_DOT11_MAX_RX_LIFETIME ,0x1004, -1); /* later firmware versions; maybe TNETW1450 only? */
1147+DEF_IE(1xx_IE_DOT11_SHORT_RETRY_LIMIT ,0x1005, 0x01); /* TNETW1450: length 2 */
1148+DEF_IE(1xx_IE_DOT11_LONG_RETRY_LIMIT ,0x1006, 0x01); /* TNETW1450: length 2 */
1149+DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE ,0x1007, 0x20); /* configure default keys; TNETW1450 has length 0x24!! */
1150+DEF_IE(1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME ,0x1008, 0x04);
1151+DEF_IE(1xx_IE_DOT11_GROUP_ADDR ,0x1009, -1);
1152+DEF_IE(1xx_IE_DOT11_CURRENT_REG_DOMAIN ,0x100a, 0x02);
1153+/* It's harmless to have larger struct. Use USB case always. */
1154+DEF_IE(1xx_IE_DOT11_CURRENT_ANTENNA ,0x100b, 0x02); /* in fact len=1 for PCI */
1155+DEF_IE(1xx_IE_DOT11_UNKNOWN_100C ,0x100c, -1); /* mapped to cfgInvalid in FW150 */
1156+DEF_IE(1xx_IE_DOT11_TX_POWER_LEVEL ,0x100d, 0x01); /* TNETW1450 has length 2!! */
1157+DEF_IE(1xx_IE_DOT11_CURRENT_CCA_MODE ,0x100e, 0x02); /* in fact len=1 for PCI */
1158+/* USB doesn't return anything - len==0?! */
1159+DEF_IE(100_IE_DOT11_ED_THRESHOLD ,0x100f, 0x04);
1160+DEF_IE(1xx_IE_DOT11_WEP_DEFAULT_KEY_SET ,0x1010, 0x01); /* set default key ID; TNETW1450: length 2 */
1161+DEF_IE(100_IE_DOT11_UNKNOWN_1011 ,0x1011, -1); /* mapped to cfgInvalid in FW150 */
1162+DEF_IE(1FF_IE_DOT11_CURR_5GHZ_REGDOM ,0x1011, -1); /* later firmware versions; maybe TNETW1450 only? */
1163+DEF_IE(100_IE_DOT11_UNKNOWN_1012 ,0x1012, -1); /* mapped to cfgInvalid in FW150 */
1164+DEF_IE(100_IE_DOT11_UNKNOWN_1013 ,0x1013, -1); /* mapped to cfgInvalid in FW150 */
1165+
1166+#if 0
1167+/* Experimentally obtained on acx100, fw 1.9.8.b
1168+** -1 means that fw returned 'invalid IE'
1169+** 0200 FC00 nnnn... are test read contents: u16 type, u16 len, data
1170+** (AA are poison bytes marking bytes not written by fw)
1171+**
1172+** Looks like acx100 fw does not update len field (thus len=256-4=FC here)
1173+** A number of IEs seem to trash type,len fields
1174+** IEs marked 'huge' return gobs of data (no poison bytes remain)
1175+*/
1176+DEF_IE(100_IE_INVAL_00, 0x0000, -1);
1177+DEF_IE(100_IE_INVAL_01, 0x0001, -1); /* IE_ACX_TIMER, len=16 on older fw */
1178+DEF_IE(100_IE_POWER_MGMT, 0x0002, 4); /* 0200FC00 00040000 AAAAAAAA */
1179+DEF_IE(100_IE_QUEUE_CONFIG, 0x0003, 28); /* 0300FC00 48060000 9CAD0000 0101AAAA DCB00000 E4B00000 9CAA0000 00AAAAAA */
1180+DEF_IE(100_IE_BLOCK_SIZE, 0x0004, 2); /* 0400FC00 0001AAAA AAAAAAAA AAAAAAAA */
1181+/* write only: */
1182+DEF_IE(100_IE_MEMORY_CONFIG_OPTIONS, 0x0005, 20);
1183+DEF_IE(100_IE_RATE_FALLBACK, 0x0006, 1); /* 0600FC00 00AAAAAA AAAAAAAA AAAAAAAA */
1184+/* write only: */
1185+DEF_IE(100_IE_WEP_OPTIONS, 0x0007, 3);
1186+DEF_IE(100_IE_MEMORY_MAP, 0x0008, 40); /* huge: 0800FC00 30000000 6CA20000 70A20000... */
1187+/* gives INVAL on read: */
1188+DEF_IE(100_IE_SCAN_STATUS, 0x0009, -1);
1189+DEF_IE(100_IE_ASSOC_ID, 0x000a, 2); /* huge: 0A00FC00 00000000 01040800 00000000... */
1190+DEF_IE(100_IE_INVAL_0B, 0x000b, -1);
1191+/* 'command rejected': */
1192+DEF_IE(100_IE_CONFIG_OPTIONS, 0x000c, -3);
1193+DEF_IE(100_IE_FWREV, 0x000d, 24); /* 0D00FC00 52657620 312E392E 382E6200 AAAAAAAA AAAAAAAA 05050201 AAAAAAAA */
1194+DEF_IE(100_IE_FCS_ERROR_COUNT, 0x000e, 4);
1195+DEF_IE(100_IE_MEDIUM_USAGE, 0x000f, 8); /* E41F0000 2D780300 FCC91300 AAAAAAAA */
1196+DEF_IE(100_IE_RXCONFIG, 0x0010, 4); /* 1000FC00 00280000 AAAAAAAA AAAAAAAA */
1197+DEF_IE(100_IE_QUEUE_THRESH, 0x0011, 12); /* 1100FC00 AAAAAAAA 00000000 00000000 */
1198+DEF_IE(100_IE_BSS_POWER_SAVE, 0x0012, 1); /* 1200FC00 00AAAAAA AAAAAAAA AAAAAAAA */
1199+/* read only, variable len */
1200+DEF_IE(100_IE_FIRMWARE_STATISTICS, 0x0013, 256); /* 0000AC00 00000000 ... */
1201+DEF_IE(100_IE_INT_CONFIG, 0x0014, 20); /* 00000000 00000000 00000000 00000000 5D74D105 00000000 AAAAAAAA AAAAAAAA */
1202+DEF_IE(100_IE_FEATURE_CONFIG, 0x0015, 8); /* 1500FC00 16000000 AAAAAAAA AAAAAAAA */
1203+/* returns 'invalid MAC': */
1204+DEF_IE(100_IE_KEY_CHOOSE, 0x0016, -4);
1205+DEF_IE(100_IE_INVAL_17, 0x0017, -1);
1206+DEF_IE(100_IE_UNKNOWN_18, 0x0018, 0); /* null len?! 1800FC00 AAAAAAAA AAAAAAAA AAAAAAAA */
1207+DEF_IE(100_IE_UNKNOWN_19, 0x0019, 256); /* huge: 1900FC00 9C1F00EA FEFFFFEA FEFFFFEA... */
1208+DEF_IE(100_IE_INVAL_1A, 0x001A, -1);
1209+
1210+DEF_IE(100_IE_DOT11_INVAL_1000, 0x1000, -1);
1211+DEF_IE(100_IE_DOT11_STATION_ID, 0x1001, 6); /* huge: 0110FC00 58B10E2F 03000000 00000000... */
1212+DEF_IE(100_IE_DOT11_INVAL_1002, 0x1002, -1);
1213+DEF_IE(100_IE_DOT11_INVAL_1003, 0x1003, -1);
1214+DEF_IE(100_IE_DOT11_INVAL_1004, 0x1004, -1);
1215+DEF_IE(100_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1);
1216+DEF_IE(100_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1);
1217+/* write only: */
1218+DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, 32);
1219+DEF_IE(100_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4); /* huge: 0810FC00 00020000 F4010000 00000000... */
1220+/* undoc but returns something */
1221+DEF_IE(100_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* huge: 0910FC00 00000000 00000000 00000000... */
1222+DEF_IE(100_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1); /* 0A10FC00 30AAAAAA AAAAAAAA AAAAAAAA */
1223+DEF_IE(100_IE_DOT11_CURRENT_ANTENNA, 0x100b, 1); /* 0B10FC00 8FAAAAAA AAAAAAAA AAAAAAAA */
1224+DEF_IE(100_IE_DOT11_INVAL_100C, 0x100c, -1);
1225+DEF_IE(100_IE_DOT11_TX_POWER_LEVEL, 0x100d, 2); /* 00000000 0100AAAA AAAAAAAA AAAAAAAA */
1226+DEF_IE(100_IE_DOT11_CURRENT_CCA_MODE, 0x100e, 1); /* 0E10FC00 0DAAAAAA AAAAAAAA AAAAAAAA */
1227+DEF_IE(100_IE_DOT11_ED_THRESHOLD, 0x100f, 4); /* 0F10FC00 70000000 AAAAAAAA AAAAAAAA */
1228+/* set default key ID */
1229+DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1); /* 1010FC00 00AAAAAA AAAAAAAA AAAAAAAA */
1230+DEF_IE(100_IE_DOT11_INVAL_1011, 0x1011, -1);
1231+DEF_IE(100_IE_DOT11_INVAL_1012, 0x1012, -1);
1232+DEF_IE(100_IE_DOT11_INVAL_1013, 0x1013, -1);
1233+DEF_IE(100_IE_DOT11_UNKNOWN_1014, 0x1014, 256); /* huge */
1234+DEF_IE(100_IE_DOT11_UNKNOWN_1015, 0x1015, 256); /* huge */
1235+DEF_IE(100_IE_DOT11_UNKNOWN_1016, 0x1016, 256); /* huge */
1236+DEF_IE(100_IE_DOT11_UNKNOWN_1017, 0x1017, 256); /* huge */
1237+DEF_IE(100_IE_DOT11_UNKNOWN_1018, 0x1018, 256); /* huge */
1238+DEF_IE(100_IE_DOT11_UNKNOWN_1019, 0x1019, 256); /* huge */
1239+#endif
1240+
1241+#if 0
1242+/* Experimentally obtained on PCI acx111 Xterasys XN-2522g, fw 1.2.1.34
1243+** -1 means that fw returned 'invalid IE'
1244+** 0400 0800 nnnn... are test read contents: u16 type, u16 len, data
1245+** (AA are poison bytes marking bytes not written by fw)
1246+**
1247+** Looks like acx111 fw reports real len!
1248+*/
1249+DEF_IE(111_IE_INVAL_00, 0x0000, -1);
1250+DEF_IE(111_IE_INVAL_01, 0x0001, -1);
1251+DEF_IE(111_IE_POWER_MGMT, 0x0002, 12);
1252+/* write only, variable len: 12 + rxqueue_cnt*8 + txqueue_cnt*4: */
1253+DEF_IE(111_IE_MEMORY_CONFIG, 0x0003, 24);
1254+DEF_IE(111_IE_BLOCK_SIZE, 0x0004, 8); /* 04000800 AA00AAAA AAAAAAAA */
1255+/* variable len: 8 + rxqueue_cnt*8 + txqueue_cnt*8: */
1256+DEF_IE(111_IE_QUEUE_HEAD, 0x0005, 24);
1257+DEF_IE(111_IE_RATE_FALLBACK, 0x0006, 1);
1258+/* acx100 name:WEP_OPTIONS */
1259+/* said to have len:1 (not true, actually returns 12 bytes): */
1260+DEF_IE(111_IE_RADIO_BAND, 0x0007, 12); /* 07000C00 AAAA1F00 FF03AAAA AAAAAAAA */
1261+DEF_IE(111_IE_MEMORY_MAP, 0x0008, 48);
1262+/* said to have len:4, but gives INVAL on read: */
1263+DEF_IE(111_IE_SCAN_STATUS, 0x0009, -1);
1264+DEF_IE(111_IE_ASSOC_ID, 0x000a, 2);
1265+/* write only, len is not known: */
1266+DEF_IE(111_IE_UNKNOWN_0B, 0x000b, 0);
1267+/* read only, variable len. I see 67 byte reads: */
1268+DEF_IE(111_IE_CONFIG_OPTIONS, 0x000c, 67); /* 0C004300 01160500 ... */
1269+DEF_IE(111_IE_FWREV, 0x000d, 24);
1270+DEF_IE(111_IE_FCS_ERROR_COUNT, 0x000e, 4);
1271+DEF_IE(111_IE_MEDIUM_USAGE, 0x000f, 8);
1272+DEF_IE(111_IE_RXCONFIG, 0x0010, 4);
1273+DEF_IE(111_IE_QUEUE_THRESH, 0x0011, 12);
1274+DEF_IE(111_IE_BSS_POWER_SAVE, 0x0012, 1);
1275+/* read only, variable len. I see 240 byte reads: */
1276+DEF_IE(111_IE_FIRMWARE_STATISTICS, 0x0013, 240); /* 1300F000 00000000 ... */
1277+/* said to have len=17. looks like fw pads it to 20: */
1278+DEF_IE(111_IE_INT_CONFIG, 0x0014, 20); /* 14001400 00000000 00000000 00000000 00000000 00000000 */
1279+DEF_IE(111_IE_FEATURE_CONFIG, 0x0015, 8);
1280+/* said to be name:KEY_INDICATOR, len:4, but gives INVAL on read: */
1281+DEF_IE(111_IE_KEY_CHOOSE, 0x0016, -1);
1282+/* said to have len:4, but in fact returns 8: */
1283+DEF_IE(111_IE_MAX_USB_XFR, 0x0017, 8); /* 17000800 00014000 00000000 */
1284+DEF_IE(111_IE_INVAL_18, 0x0018, -1);
1285+DEF_IE(111_IE_INVAL_19, 0x0019, -1);
1286+/* undoc but returns something: */
1287+/* huh, fw indicates len=20 but uses 4 more bytes in buffer??? */
1288+DEF_IE(111_IE_UNKNOWN_1A, 0x001A, 20); /* 1A001400 AA00AAAA 0000020F FF030000 00020000 00000007 04000000 */
1289+
1290+DEF_IE(111_IE_DOT11_INVAL_1000, 0x1000, -1);
1291+DEF_IE(111_IE_DOT11_STATION_ID, 0x1001, 6);
1292+DEF_IE(111_IE_DOT11_FRAG_THRESH, 0x1002, 2);
1293+/* acx100 only? gives INVAL on read: */
1294+DEF_IE(111_IE_DOT11_BEACON_PERIOD, 0x1003, -1);
1295+/* said to be MAX_RECV_MSDU_LIFETIME: */
1296+DEF_IE(111_IE_DOT11_DTIM_PERIOD, 0x1004, 4);
1297+DEF_IE(111_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1);
1298+DEF_IE(111_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1);
1299+/* acx100 only? gives INVAL on read: */
1300+DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, -1);
1301+DEF_IE(111_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4);
1302+/* undoc but returns something. maybe it's 2 multicast MACs to listen to? */
1303+DEF_IE(111_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* 09100C00 00000000 00000000 00000000 */
1304+DEF_IE(111_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1);
1305+DEF_IE(111_IE_DOT11_CURRENT_ANTENNA, 0x100b, 2);
1306+DEF_IE(111_IE_DOT11_INVAL_100C, 0x100c, -1);
1307+DEF_IE(111_IE_DOT11_TX_POWER_LEVEL, 0x100d, 1);
1308+/* said to have len=1 but gives INVAL on read: */
1309+DEF_IE(111_IE_DOT11_CURRENT_CCA_MODE, 0x100e, -1);
1310+/* said to have len=4 but gives INVAL on read: */
1311+DEF_IE(111_IE_DOT11_ED_THRESHOLD, 0x100f, -1);
1312+/* set default key ID. write only: */
1313+DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1);
1314+/* undoc but returns something: */
1315+DEF_IE(111_IE_DOT11_UNKNOWN_1011, 0x1011, 1); /* 11100100 20 */
1316+DEF_IE(111_IE_DOT11_INVAL_1012, 0x1012, -1);
1317+DEF_IE(111_IE_DOT11_INVAL_1013, 0x1013, -1);
1318+#endif
1319+
1320+
1321+/***********************************************************************
1322+**Information Frames Structures
1323+*/
1324+
1325+/* Used in beacon frames and the like */
1326+#define DOT11RATEBYTE_1 (1*2)
1327+#define DOT11RATEBYTE_2 (2*2)
1328+#define DOT11RATEBYTE_5_5 (5*2+1)
1329+#define DOT11RATEBYTE_11 (11*2)
1330+#define DOT11RATEBYTE_22 (22*2)
1331+#define DOT11RATEBYTE_6_G (6*2)
1332+#define DOT11RATEBYTE_9_G (9*2)
1333+#define DOT11RATEBYTE_12_G (12*2)
1334+#define DOT11RATEBYTE_18_G (18*2)
1335+#define DOT11RATEBYTE_24_G (24*2)
1336+#define DOT11RATEBYTE_36_G (36*2)
1337+#define DOT11RATEBYTE_48_G (48*2)
1338+#define DOT11RATEBYTE_54_G (54*2)
1339+#define DOT11RATEBYTE_BASIC 0x80 /* flags rates included in basic rate set */
1340+
1341+
1342+/***********************************************************************
1343+** rxbuffer_t
1344+**
1345+** This is the format of rx data returned by acx
1346+*/
1347+
1348+/* I've hoped it's a 802.11 PHY header, but no...
1349+ * so far, I've seen on acx111:
1350+ * 0000 3a00 0000 0000 IBSS Beacons
1351+ * 0000 3c00 0000 0000 ESS Beacons
1352+ * 0000 2700 0000 0000 Probe requests
1353+ * --vda
1354+ */
1355+typedef struct phy_hdr {
1356+ u8 unknown[4];
1357+ u8 acx111_unknown[4];
1358+} ACX_PACKED phy_hdr_t;
1359+
1360+/* seems to be a bit similar to hfa384x_rx_frame.
1361+ * These fields are still not quite obvious, though.
1362+ * Some seem to have different meanings... */
1363+
1364+#define RXBUF_HDRSIZE 12
1365+#define RXBUF_BYTES_RCVD(adev, rxbuf) \
1366+ ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) - (adev)->phy_header_len)
1367+#define RXBUF_BYTES_USED(rxbuf) \
1368+ ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) + RXBUF_HDRSIZE)
1369+/* USBism */
1370+#define RXBUF_IS_TXSTAT(rxbuf) (le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0x8000)
1371+/*
1372+mac_cnt_rcvd:
1373+ 12 bits: length of frame from control field to first byte of FCS
1374+ 3 bits: reserved
1375+ 1 bit: 1 = it's a tx status info, not a rx packet (USB only)
1376+
1377+mac_cnt_mblks:
1378+ 6 bits: number of memory block used to store frame in adapter memory
1379+ 1 bit: Traffic Indicator bit in TIM of received Beacon was set
1380+
1381+mac_status: 1 byte (bitmap):
1382+ 7 Matching BSSID
1383+ 6 Matching SSID
1384+ 5 BDCST Address 1 field is a broadcast
1385+ 4 VBM received beacon frame has more than one set bit (?!)
1386+ 3 TIM Set bit representing this station is set in TIM of received beacon
1387+ 2 GROUP Address 1 is a multicast
1388+ 1 ADDR1 Address 1 matches our MAC
1389+ 0 FCSGD FSC is good
1390+
1391+phy_stat_baseband: 1 byte (bitmap):
1392+ 7 Preamble frame had a long preamble
1393+ 6 PLCP Error CRC16 error in PLCP header
1394+ 5 Unsup_Mod unsupported modulation
1395+ 4 Selected Antenna antenna 1 was used to receive this frame
1396+ 3 PBCC/CCK frame used: 1=PBCC, 0=CCK modulation
1397+ 2 OFDM frame used OFDM modulation
1398+ 1 TI Protection protection frame was detected
1399+ 0 Reserved
1400+
1401+phy_plcp_signal: 1 byte:
1402+ Receive PLCP Signal field from the Baseband Processor
1403+
1404+phy_level: 1 byte:
1405+ receive AGC gain level (can be used to measure receive signal strength)
1406+
1407+phy_snr: 1 byte:
1408+ estimated noise power of equalized receive signal
1409+ at input of FEC decoder (can be used to measure receive signal quality)
1410+
1411+time: 4 bytes:
1412+ timestamp sampled from either the Access Manager TSF counter
1413+ or free-running microsecond counter when the MAC receives
1414+ first byte of PLCP header.
1415+*/
1416+
1417+typedef struct rxbuffer {
1418+ u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */
1419+ u8 mac_cnt_mblks;
1420+ u8 mac_status;
1421+ u8 phy_stat_baseband; /* bit 0x80: used LNA (Low-Noise Amplifier) */
1422+ u8 phy_plcp_signal;
1423+ u8 phy_level; /* PHY stat */
1424+ u8 phy_snr; /* PHY stat */
1425+ u32 time; /* timestamp upon MAC rcv first byte */
1426+/* 4-byte (acx100) or 8-byte (acx111) phy header will be here
1427+** if RX_CFG1_INCLUDE_PHY_HDR is in effect:
1428+** phy_hdr_t phy */
1429+ wlan_hdr_a3_t hdr_a3;
1430+ /* maximally sized data part of wlan packet */
1431+ u8 data_a3[WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN];
1432+ /* can add hdr/data_a4 if needed */
1433+} ACX_PACKED rxbuffer_t;
1434+
1435+
1436+/*--- Firmware statistics ----------------------------------------------------*/
1437+
1438+/* define a random 100 bytes more to catch firmware versions which
1439+ * provide a bigger struct */
1440+#define FW_STATS_FUTURE_EXTENSION 100
1441+
1442+typedef struct fw_stats_tx {
1443+ u32 tx_desc_of;
1444+} ACX_PACKED fw_stats_tx_t;
1445+
1446+typedef struct fw_stats_rx {
1447+ u32 rx_oom;
1448+ u32 rx_hdr_of;
1449+ u32 rx_hw_stuck; /* old: u32 rx_hdr_use_next */
1450+ u32 rx_dropped_frame;
1451+ u32 rx_frame_ptr_err;
1452+ u32 rx_xfr_hint_trig;
1453+ u32 rx_aci_events; /* later versions only */
1454+ u32 rx_aci_resets; /* later versions only */
1455+} ACX_PACKED fw_stats_rx_t;
1456+
1457+typedef struct fw_stats_dma {
1458+ u32 rx_dma_req;
1459+ u32 rx_dma_err;
1460+ u32 tx_dma_req;
1461+ u32 tx_dma_err;
1462+} ACX_PACKED fw_stats_dma_t;
1463+
1464+typedef struct fw_stats_irq {
1465+ u32 cmd_cplt;
1466+ u32 fiq;
1467+ u32 rx_hdrs;
1468+ u32 rx_cmplt;
1469+ u32 rx_mem_of;
1470+ u32 rx_rdys;
1471+ u32 irqs;
1472+ u32 tx_procs;
1473+ u32 decrypt_done;
1474+ u32 dma_0_done;
1475+ u32 dma_1_done;
1476+ u32 tx_exch_complet;
1477+ u32 commands;
1478+ u32 rx_procs;
1479+ u32 hw_pm_mode_changes;
1480+ u32 host_acks;
1481+ u32 pci_pm;
1482+ u32 acm_wakeups;
1483+} ACX_PACKED fw_stats_irq_t;
1484+
1485+typedef struct fw_stats_wep {
1486+ u32 wep_key_count;
1487+ u32 wep_default_key_count;
1488+ u32 dot11_def_key_mib;
1489+ u32 wep_key_not_found;
1490+ u32 wep_decrypt_fail;
1491+ u32 wep_pkt_decrypt;
1492+ u32 wep_decrypt_irqs;
1493+} ACX_PACKED fw_stats_wep_t;
1494+
1495+typedef struct fw_stats_pwr {
1496+ u32 tx_start_ctr;
1497+ u32 no_ps_tx_too_short;
1498+ u32 rx_start_ctr;
1499+ u32 no_ps_rx_too_short;
1500+ u32 lppd_started;
1501+ u32 no_lppd_too_noisy;
1502+ u32 no_lppd_too_short;
1503+ u32 no_lppd_matching_frame;
1504+} ACX_PACKED fw_stats_pwr_t;
1505+
1506+typedef struct fw_stats_mic {
1507+ u32 mic_rx_pkts;
1508+ u32 mic_calc_fail;
1509+} ACX_PACKED fw_stats_mic_t;
1510+
1511+typedef struct fw_stats_aes {
1512+ u32 aes_enc_fail;
1513+ u32 aes_dec_fail;
1514+ u32 aes_enc_pkts;
1515+ u32 aes_dec_pkts;
1516+ u32 aes_enc_irq;
1517+ u32 aes_dec_irq;
1518+} ACX_PACKED fw_stats_aes_t;
1519+
1520+typedef struct fw_stats_event {
1521+ u32 heartbeat;
1522+ u32 calibration;
1523+ u32 rx_mismatch;
1524+ u32 rx_mem_empty;
1525+ u32 rx_pool;
1526+ u32 oom_late;
1527+ u32 phy_tx_err;
1528+ u32 tx_stuck;
1529+} ACX_PACKED fw_stats_event_t;
1530+
1531+/* mainly for size calculation only */
1532+typedef struct fw_stats {
1533+ u16 type;
1534+ u16 len;
1535+ fw_stats_tx_t tx;
1536+ fw_stats_rx_t rx;
1537+ fw_stats_dma_t dma;
1538+ fw_stats_irq_t irq;
1539+ fw_stats_wep_t wep;
1540+ fw_stats_pwr_t pwr;
1541+ fw_stats_mic_t mic;
1542+ fw_stats_aes_t aes;
1543+ fw_stats_event_t evt;
1544+ u8 _padding[FW_STATS_FUTURE_EXTENSION];
1545+} fw_stats_t;
1546+
1547+/* Firmware version struct */
1548+
1549+typedef struct fw_ver {
1550+ u16 cmd;
1551+ u16 size;
1552+ char fw_id[20];
1553+ u32 hw_id;
1554+} ACX_PACKED fw_ver_t;
1555+
1556+#define FW_ID_SIZE 20
1557+
1558+typedef struct shared_queueindicator {
1559+ u32 indicator;
1560+ u16 host_lock;
1561+ u16 fw_lock;
1562+} ACX_PACKED queueindicator_t;
1563+
1564+/*--- WEP stuff --------------------------------------------------------------*/
1565+#define DOT11_MAX_DEFAULT_WEP_KEYS 4
1566+
1567+/* non-firmware struct, no packing necessary */
1568+typedef struct wep_key {
1569+ size_t size; /* most often used member first */
1570+ u8 index;
1571+ u8 key[29];
1572+ u16 strange_filler;
1573+} wep_key_t; /* size = 264 bytes (33*8) */
1574+/* FIXME: We don't have size 264! Or is there 2 bytes beyond the key
1575+ * (strange_filler)? */
1576+
1577+/* non-firmware struct, no packing necessary */
1578+typedef struct key_struct {
1579+ u8 addr[ETH_ALEN]; /* 0x00 */
1580+ u16 filler1; /* 0x06 */
1581+ u32 filler2; /* 0x08 */
1582+ u32 index; /* 0x0c */
1583+ u16 len; /* 0x10 */
1584+ u8 key[29]; /* 0x12; is this long enough??? */
1585+} key_struct_t; /* size = 276. FIXME: where is the remaining space?? */
1586+
1587+
1588+/*--- Client (peer) info -----------------------------------------------------*/
1589+/* adev->sta_list[] is used for:
1590+** accumulating and processing of scan results
1591+** keeping client info in AP mode
1592+** keeping AP info in STA mode (AP is the only one 'client')
1593+** keeping peer info in ad-hoc mode
1594+** non-firmware struct --> no packing necessary */
1595+enum {
1596+ CLIENT_EMPTY_SLOT_0 = 0,
1597+ CLIENT_EXIST_1 = 1,
1598+ CLIENT_AUTHENTICATED_2 = 2,
1599+ CLIENT_ASSOCIATED_3 = 3,
1600+ CLIENT_JOIN_CANDIDATE = 4
1601+};
1602+struct client {
1603+ /* most frequent access first */
1604+ u8 used; /* misnamed, more like 'status' */
1605+ struct client* next;
1606+ unsigned long mtime; /* last time we heard it, in jiffies */
1607+ size_t essid_len; /* length of ESSID (without '\0') */
1608+ u32 sir; /* Standard IR */
1609+ u32 snr; /* Signal to Noise Ratio */
1610+ u16 aid; /* association ID */
1611+ u16 seq; /* from client's auth req */
1612+ u16 auth_alg; /* from client's auth req */
1613+ u16 cap_info; /* from client's assoc req */
1614+ u16 rate_cap; /* what client supports (all rates) */
1615+ u16 rate_bas; /* what client supports (basic rates) */
1616+ u16 rate_cfg; /* what is allowed (by iwconfig etc) */
1617+ u16 rate_cur; /* currently used rate mask */
1618+ u8 rate_100; /* currently used rate byte (acx100 only) */
1619+ u8 address[ETH_ALEN];
1620+ u8 bssid[ETH_ALEN]; /* ad-hoc hosts can have bssid != mac */
1621+ u8 channel;
1622+ u8 auth_step;
1623+ u8 ignore_count;
1624+ u8 fallback_count;
1625+ u8 stepup_count;
1626+ char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID and trailing '\0' */
1627+/* FIXME: this one is too damn big */
1628+ char challenge_text[WLAN_CHALLENGE_LEN];
1629+};
1630+
1631+
1632+/***********************************************************************
1633+** Hardware structures
1634+*/
1635+
1636+/* An opaque typesafe helper type
1637+ *
1638+ * Some hardware fields are actually pointers,
1639+ * but they have to remain u32, since using ptr instead
1640+ * (8 bytes on 64bit systems!) would disrupt the fixed descriptor
1641+ * format the acx firmware expects in the non-user area.
1642+ * Since we cannot cram an 8 byte ptr into 4 bytes, we need to
1643+ * enforce that pointed to data remains in low memory
1644+ * (address value needs to fit in 4 bytes) on 64bit systems.
1645+ *
1646+ * This is easy to get wrong, thus we are using a small struct
1647+ * and special macros to access it. Macros will check for
1648+ * attempts to overflow an acx_ptr with value > 0xffffffff.
1649+ *
1650+ * Attempts to use acx_ptr without macros result in compile-time errors */
1651+
1652+typedef struct {
1653+ u32 v;
1654+} ACX_PACKED acx_ptr;
1655+
1656+#if ACX_DEBUG
1657+#define CHECK32(n) BUG_ON(sizeof(n)>4 && (long)(n)>0xffffff00)
1658+#else
1659+#define CHECK32(n) ((void)0)
1660+#endif
1661+
1662+/* acx_ptr <-> integer conversion */
1663+#define cpu2acx(n) ({ CHECK32(n); ((acx_ptr){ .v = cpu_to_le32(n) }); })
1664+#define acx2cpu(a) (le32_to_cpu(a.v))
1665+
1666+/* acx_ptr <-> pointer conversion */
1667+#define ptr2acx(p) ({ CHECK32(p); ((acx_ptr){ .v = cpu_to_le32((u32)(long)(p)) }); })
1668+#define acx2ptr(a) ((void*)le32_to_cpu(a.v))
1669+
1670+/* Values for rate field (acx100 only) */
1671+#define RATE100_1 10
1672+#define RATE100_2 20
1673+#define RATE100_5 55
1674+#define RATE100_11 110
1675+#define RATE100_22 220
1676+/* This bit denotes use of PBCC:
1677+** (PBCC encoding is usable with 11 and 22 Mbps speeds only) */
1678+#define RATE100_PBCC511 0x80
1679+
1680+/* Bit values for rate111 field */
1681+#define RATE111_1 0x0001 /* DBPSK */
1682+#define RATE111_2 0x0002 /* DQPSK */
1683+#define RATE111_5 0x0004 /* CCK or PBCC */
1684+#define RATE111_6 0x0008 /* CCK-OFDM or OFDM */
1685+#define RATE111_9 0x0010 /* CCK-OFDM or OFDM */
1686+#define RATE111_11 0x0020 /* CCK or PBCC */
1687+#define RATE111_12 0x0040 /* CCK-OFDM or OFDM */
1688+#define RATE111_18 0x0080 /* CCK-OFDM or OFDM */
1689+#define RATE111_22 0x0100 /* PBCC */
1690+#define RATE111_24 0x0200 /* CCK-OFDM or OFDM */
1691+#define RATE111_36 0x0400 /* CCK-OFDM or OFDM */
1692+#define RATE111_48 0x0800 /* CCK-OFDM or OFDM */
1693+#define RATE111_54 0x1000 /* CCK-OFDM or OFDM */
1694+#define RATE111_RESERVED 0x2000
1695+#define RATE111_PBCC511 0x4000 /* PBCC mod at 5.5 or 11Mbit (else CCK) */
1696+#define RATE111_SHORTPRE 0x8000 /* short preamble */
1697+/* Special 'try everything' value */
1698+#define RATE111_ALL 0x1fff
1699+/* These bits denote acx100 compatible settings */
1700+#define RATE111_ACX100_COMPAT 0x0127
1701+/* These bits denote 802.11b compatible settings */
1702+#define RATE111_80211B_COMPAT 0x0027
1703+
1704+/* Descriptor Ctl field bits
1705+ * init value is 0x8e, "idle" value is 0x82 (in idle tx descs)
1706+ */
1707+#define DESC_CTL_SHORT_PREAMBLE 0x01 /* preamble type: 0 = long; 1 = short */
1708+#define DESC_CTL_FIRSTFRAG 0x02 /* this is the 1st frag of the frame */
1709+#define DESC_CTL_AUTODMA 0x04
1710+#define DESC_CTL_RECLAIM 0x08 /* ready to reuse */
1711+#define DESC_CTL_HOSTDONE 0x20 /* host has finished processing */
1712+#define DESC_CTL_ACXDONE 0x40 /* acx has finished processing */
1713+/* host owns the desc [has to be released last, AFTER modifying all other desc fields!] */
1714+#define DESC_CTL_HOSTOWN 0x80
1715+#define DESC_CTL_ACXDONE_HOSTOWN (DESC_CTL_ACXDONE | DESC_CTL_HOSTOWN)
1716+
1717+/* Descriptor Status field
1718+ */
1719+#define DESC_STATUS_FULL (1 << 31)
1720+
1721+/* NB: some bits may be interesting for Monitor mode tx (aka Raw tx): */
1722+#define DESC_CTL2_SEQ 0x01 /* don't increase sequence field */
1723+#define DESC_CTL2_FCS 0x02 /* don't add the FCS */
1724+#define DESC_CTL2_MORE_FRAG 0x04
1725+#define DESC_CTL2_RETRY 0x08 /* don't increase retry field */
1726+#define DESC_CTL2_POWER 0x10 /* don't increase power mgmt. field */
1727+#define DESC_CTL2_RTS 0x20 /* do RTS/CTS magic before sending */
1728+#define DESC_CTL2_WEP 0x40 /* encrypt this frame */
1729+#define DESC_CTL2_DUR 0x80 /* don't increase duration field */
1730+
1731+/***********************************************************************
1732+** PCI structures
1733+*/
1734+/* IRQ Constants
1735+** (outside of "#ifdef PCI" because USB (mis)uses HOST_INT_SCAN_COMPLETE) */
1736+#define HOST_INT_RX_DATA 0x0001
1737+#define HOST_INT_TX_COMPLETE 0x0002
1738+#define HOST_INT_TX_XFER 0x0004
1739+#define HOST_INT_RX_COMPLETE 0x0008
1740+#define HOST_INT_DTIM 0x0010
1741+#define HOST_INT_BEACON 0x0020
1742+#define HOST_INT_TIMER 0x0040
1743+#define HOST_INT_KEY_NOT_FOUND 0x0080
1744+#define HOST_INT_IV_ICV_FAILURE 0x0100
1745+#define HOST_INT_CMD_COMPLETE 0x0200
1746+#define HOST_INT_INFO 0x0400
1747+#define HOST_INT_OVERFLOW 0x0800
1748+#define HOST_INT_PROCESS_ERROR 0x1000
1749+#define HOST_INT_SCAN_COMPLETE 0x2000
1750+#define HOST_INT_FCS_THRESHOLD 0x4000
1751+#define HOST_INT_UNKNOWN 0x8000
1752+
1753+/* Outside of "#ifdef PCI" because USB needs to know sizeof()
1754+** of txdesc and rxdesc: */
1755+struct txdesc {
1756+ acx_ptr pNextDesc; /* pointer to next txdesc */
1757+ acx_ptr HostMemPtr; /* 0x04 */
1758+ acx_ptr AcxMemPtr; /* 0x08 */
1759+ u32 tx_time; /* 0x0c */
1760+ u16 total_length; /* 0x10 */
1761+ u16 Reserved; /* 0x12 */
1762+
1763+/* The following 16 bytes do not change when acx100 owns the descriptor */
1764+/* BUG: fw clears last byte of this area which is supposedly reserved
1765+** for driver use. amd64 blew up. We dare not use it now */
1766+ u32 dummy[4];
1767+
1768+ u8 Ctl_8; /* 0x24, 8bit value */
1769+ u8 Ctl2_8; /* 0x25, 8bit value */
1770+ u8 error; /* 0x26 */
1771+ u8 ack_failures; /* 0x27 */
1772+
1773+ union {
1774+ /*
1775+ * Packing doesn't work correctly on ARM unless unions are on
1776+ * 4 byte boundaries.
1777+ */
1778+ struct {
1779+ u8 rts_failures; /* 0x28 */
1780+ u8 rts_ok; /* 0x29 */
1781+ u16 d1;
1782+ } ACX_PACKED rts;
1783+ struct {
1784+ u16 d1;
1785+ u8 rate; /* 0x2a */
1786+ u8 queue_ctrl; /* 0x2b */
1787+ } ACX_PACKED r1;
1788+ struct {
1789+ u16 d1;
1790+ u16 rate111; /* 0x2a */
1791+ } ACX_PACKED r2;
1792+ } ACX_PACKED u;
1793+ u32 queue_info; /* 0x2c (acx100, reserved on acx111) */
1794+} ACX_PACKED; /* size : 48 = 0x30 */
1795+/* NB: acx111 txdesc structure is 4 byte larger */
1796+/* All these 4 extra bytes are reserved. tx alloc code takes them into account */
1797+
1798+struct rxdesc {
1799+ acx_ptr pNextDesc; /* 0x00 */
1800+ acx_ptr HostMemPtr; /* 0x04 */
1801+ acx_ptr ACXMemPtr; /* 0x08 */
1802+ u32 rx_time; /* 0x0c */
1803+ u16 total_length; /* 0x10 */
1804+ u16 WEP_length; /* 0x12 */
1805+ u32 WEP_ofs; /* 0x14 */
1806+
1807+/* the following 16 bytes do not change when acx100 owns the descriptor */
1808+ u8 driverWorkspace[16]; /* 0x18 */
1809+
1810+ u8 Ctl_8;
1811+ u8 rate;
1812+ u8 error;
1813+ u8 SNR; /* Signal-to-Noise Ratio */
1814+ u8 RxLevel;
1815+ u8 queue_ctrl;
1816+ u16 unknown;
1817+ u32 unknown2;
1818+} ACX_PACKED; /* size 52 = 0x34 */
1819+
1820+#if defined(ACX_PCI) || defined(ACX_MEM)
1821+
1822+/* Register I/O offsets */
1823+#define ACX100_EEPROM_ID_OFFSET 0x380
1824+
1825+/* please add further ACX hardware register definitions only when
1826+ it turns out you need them in the driver, and please try to use
1827+ firmware functionality instead, since using direct I/O access instead
1828+ of letting the firmware do it might confuse the firmware's state
1829+ machine */
1830+
1831+/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION
1832+** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */
1833+enum {
1834+ IO_ACX_SOFT_RESET = 0,
1835+
1836+ IO_ACX_SLV_MEM_ADDR,
1837+ IO_ACX_SLV_MEM_DATA,
1838+ IO_ACX_SLV_MEM_CTL,
1839+ IO_ACX_SLV_END_CTL,
1840+
1841+ IO_ACX_FEMR, /* Function Event Mask */
1842+
1843+ IO_ACX_INT_TRIG,
1844+ IO_ACX_IRQ_MASK,
1845+ IO_ACX_IRQ_STATUS_NON_DES,
1846+ IO_ACX_IRQ_STATUS_CLEAR, /* CLEAR = clear on read */
1847+ IO_ACX_IRQ_ACK,
1848+ IO_ACX_HINT_TRIG,
1849+
1850+ IO_ACX_ENABLE,
1851+
1852+ IO_ACX_EEPROM_CTL,
1853+ IO_ACX_EEPROM_ADDR,
1854+ IO_ACX_EEPROM_DATA,
1855+ IO_ACX_EEPROM_CFG,
1856+
1857+ IO_ACX_PHY_ADDR,
1858+ IO_ACX_PHY_DATA,
1859+ IO_ACX_PHY_CTL,
1860+
1861+ IO_ACX_GPIO_OE,
1862+
1863+ IO_ACX_GPIO_OUT,
1864+
1865+ IO_ACX_CMD_MAILBOX_OFFS,
1866+ IO_ACX_INFO_MAILBOX_OFFS,
1867+ IO_ACX_EEPROM_INFORMATION,
1868+
1869+ IO_ACX_EE_START,
1870+ IO_ACX_SOR_CFG,
1871+ IO_ACX_ECPU_CTRL
1872+};
1873+/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION
1874+** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */
1875+
1876+/* Values for IO_ACX_INT_TRIG register: */
1877+/* inform hw that rxdesc in queue needs processing */
1878+#define INT_TRIG_RXPRC 0x08
1879+/* inform hw that txdesc in queue needs processing */
1880+#define INT_TRIG_TXPRC 0x04
1881+/* ack that we received info from info mailbox */
1882+#define INT_TRIG_INFOACK 0x02
1883+/* inform hw that we have filled command mailbox */
1884+#define INT_TRIG_CMD 0x01
1885+
1886+struct txhostdesc {
1887+ acx_ptr data_phy; /* 0x00 [u8 *] */
1888+ u16 data_offset; /* 0x04 */
1889+ u16 reserved; /* 0x06 */
1890+ u16 Ctl_16; /* 16bit value, endianness!! */
1891+ u16 length; /* 0x0a */
1892+ acx_ptr desc_phy_next; /* 0x0c [txhostdesc *] */
1893+ acx_ptr pNext; /* 0x10 [txhostdesc *] */
1894+ u32 Status; /* 0x14, unused on Tx */
1895+/* From here on you can use this area as you want (variable length, too!) */
1896+ u8 *data;
1897+} ACX_PACKED;
1898+
1899+struct rxhostdesc {
1900+ acx_ptr data_phy; /* 0x00 [rxbuffer_t *] */
1901+ u16 data_offset; /* 0x04 */
1902+ u16 reserved; /* 0x06 */
1903+ u16 Ctl_16; /* 0x08; 16bit value, endianness!! */
1904+ u16 length; /* 0x0a */
1905+ acx_ptr desc_phy_next; /* 0x0c [rxhostdesc_t *] */
1906+ acx_ptr pNext; /* 0x10 [rxhostdesc_t *] */
1907+ u32 Status; /* 0x14 */
1908+/* From here on you can use this area as you want (variable length, too!) */
1909+ rxbuffer_t *data;
1910+} ACX_PACKED;
1911+
1912+#endif /* ACX_PCI */
1913+
1914+/***********************************************************************
1915+** USB structures and constants
1916+*/
1917+#ifdef ACX_USB
1918+
1919+/* Used for usb_txbuffer.desc field */
1920+#define USB_TXBUF_TXDESC 0xA
1921+/* Size of header (everything up to data[]) */
1922+#define USB_TXBUF_HDRSIZE 14
1923+typedef struct usb_txbuffer {
1924+ u16 desc;
1925+ u16 mpdu_len;
1926+ u8 queue_index;
1927+ u8 rate;
1928+ u32 hostdata;
1929+ u8 ctrl1;
1930+ u8 ctrl2;
1931+ u16 data_len;
1932+ /* wlan packet content is placed here: */
1933+ u8 data[WLAN_A4FR_MAXLEN_WEP_FCS];
1934+} ACX_PACKED usb_txbuffer_t;
1935+
1936+/* USB returns either rx packets (see rxbuffer) or
1937+** these "tx status" structs: */
1938+typedef struct usb_txstatus {
1939+ u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */
1940+ u8 queue_index;
1941+ u8 mac_status; /* seen 0x20 on tx failure */
1942+ u32 hostdata;
1943+ u8 rate;
1944+ u8 ack_failures;
1945+ u8 rts_failures;
1946+ u8 rts_ok;
1947+} ACX_PACKED usb_txstatus_t;
1948+
1949+typedef struct usb_tx {
1950+ unsigned busy:1;
1951+ struct urb *urb;
1952+ acx_device_t *adev;
1953+ /* actual USB bulk output data block is here: */
1954+ usb_txbuffer_t bulkout;
1955+} usb_tx_t;
1956+
1957+struct usb_rx_plain {
1958+ unsigned busy:1;
1959+ struct urb *urb;
1960+ acx_device_t *adev;
1961+ rxbuffer_t bulkin;
1962+};
1963+
1964+typedef struct usb_rx {
1965+ unsigned busy:1;
1966+ struct urb *urb;
1967+ acx_device_t *adev;
1968+ rxbuffer_t bulkin;
1969+ /* Make entire structure 4k. Report if it breaks something. */
1970+ u8 padding[4*1024 - sizeof(struct usb_rx_plain)];
1971+} usb_rx_t;
1972+#endif /* ACX_USB */
1973+
1974+
1975+/* Config Option structs */
1976+
1977+typedef struct co_antennas {
1978+ u8 type;
1979+ u8 len;
1980+ u8 list[2];
1981+} ACX_PACKED co_antennas_t;
1982+
1983+typedef struct co_powerlevels {
1984+ u8 type;
1985+ u8 len;
1986+ u16 list[8];
1987+} ACX_PACKED co_powerlevels_t;
1988+
1989+typedef struct co_datarates {
1990+ u8 type;
1991+ u8 len;
1992+ u8 list[8];
1993+} ACX_PACKED co_datarates_t;
1994+
1995+typedef struct co_domains {
1996+ u8 type;
1997+ u8 len;
1998+ u8 list[6];
1999+} ACX_PACKED co_domains_t;
2000+
2001+typedef struct co_product_id {
2002+ u8 type;
2003+ u8 len;
2004+ u8 list[128];
2005+} ACX_PACKED co_product_id_t;
2006+
2007+typedef struct co_manuf_id {
2008+ u8 type;
2009+ u8 len;
2010+ u8 list[128];
2011+} ACX_PACKED co_manuf_t;
2012+
2013+typedef struct co_fixed {
2014+ char NVSv[8];
2015+/* u16 NVS_vendor_offs; ACX111-only */
2016+/* u16 unknown; ACX111-only */
2017+ u8 MAC[6]; /* ACX100-only */
2018+ u16 probe_delay; /* ACX100-only */
2019+ u32 eof_memory;
2020+ u8 dot11CCAModes;
2021+ u8 dot11Diversity;
2022+ u8 dot11ShortPreambleOption;
2023+ u8 dot11PBCCOption;
2024+ u8 dot11ChannelAgility;
2025+ u8 dot11PhyType; /* FIXME: does 802.11 call it "dot11PHYType"? */
2026+ u8 dot11TempType;
2027+ u8 table_count;
2028+} ACX_PACKED co_fixed_t;
2029+
2030+typedef struct acx111_ie_configoption {
2031+ u16 type;
2032+ u16 len;
2033+/* Do not access below members directly, they are in fact variable length */
2034+ co_fixed_t fixed;
2035+ co_antennas_t antennas;
2036+ co_powerlevels_t power_levels;
2037+ co_datarates_t data_rates;
2038+ co_domains_t domains;
2039+ co_product_id_t product_id;
2040+ co_manuf_t manufacturer;
2041+ u8 _padding[4];
2042+} ACX_PACKED acx111_ie_configoption_t;
2043+
2044+
2045+/***********************************************************************
2046+** Main acx per-device data structure
2047+*/
2048+#define ACX_STATE_FW_LOADED 0x01
2049+#define ACX_STATE_IFACE_UP 0x02
2050+
2051+/* MAC mode (BSS type) defines
2052+ * Note that they shouldn't be redefined, since they are also used
2053+ * during communication with firmware */
2054+#define ACX_MODE_0_ADHOC 0
2055+#define ACX_MODE_1_UNUSED 1
2056+#define ACX_MODE_2_STA 2
2057+#define ACX_MODE_3_AP 3
2058+/* These are our own inventions. Sending these to firmware
2059+** makes it stop emitting beacons, which is exactly what we want
2060+** for these modes */
2061+#define ACX_MODE_MONITOR 0xfe
2062+#define ACX_MODE_OFF 0xff
2063+/* 'Submode': identifies exact status of ADHOC/STA host */
2064+#define ACX_STATUS_0_STOPPED 0
2065+#define ACX_STATUS_1_SCANNING 1
2066+#define ACX_STATUS_2_WAIT_AUTH 2
2067+#define ACX_STATUS_3_AUTHENTICATED 3
2068+#define ACX_STATUS_4_ASSOCIATED 4
2069+
2070+/* FIXME: this should be named something like struct acx_priv (typedef'd to
2071+ * acx_priv_t) */
2072+
2073+/* non-firmware struct, no packing necessary */
2074+struct acx_device {
2075+ /* most frequent accesses first (dereferencing and cache line!) */
2076+
2077+ /*** Locking ***/
2078+ /* FIXME: try to convert semaphore to more efficient mutex according
2079+ to Ingo Molnar's docs (but not before driver is in mainline or
2080+ pre-mutex Linux 2.6.10 is very outdated). */
2081+ struct semaphore sem;
2082+ spinlock_t lock;
2083+#if defined(PARANOID_LOCKING) /* Lock debugging */
2084+ const char *last_sem;
2085+ const char *last_lock;
2086+ unsigned long sem_time;
2087+ unsigned long lock_time;
2088+#endif
2089+#ifdef ACX_MEM
2090+ spinlock_t txbuf_lock;
2091+#endif
2092+
2093+ /*** Linux network device ***/
2094+ struct net_device *ndev; /* pointer to linux netdevice */
2095+
2096+ /*** Device statistics ***/
2097+ struct net_device_stats stats; /* net device statistics */
2098+#ifdef WIRELESS_EXT
2099+ struct iw_statistics wstats; /* wireless statistics */
2100+#endif
2101+ /*** Power managment ***/
2102+ struct pm_dev *pm; /* PM crap */
2103+
2104+ /*** Management timer ***/
2105+ struct timer_list mgmt_timer;
2106+
2107+ /*** Hardware identification ***/
2108+ const char *chip_name;
2109+ u8 dev_type;
2110+ u8 chip_type;
2111+ u8 form_factor;
2112+ u8 radio_type;
2113+ u8 eeprom_version;
2114+
2115+ /*** Config retrieved from EEPROM ***/
2116+ char cfgopt_NVSv[8];
2117+ u16 cfgopt_NVS_vendor_offs;
2118+ u8 cfgopt_MAC[6];
2119+ u16 cfgopt_probe_delay;
2120+ u32 cfgopt_eof_memory;
2121+ u8 cfgopt_dot11CCAModes;
2122+ u8 cfgopt_dot11Diversity;
2123+ u8 cfgopt_dot11ShortPreambleOption;
2124+ u8 cfgopt_dot11PBCCOption;
2125+ u8 cfgopt_dot11ChannelAgility;
2126+ u8 cfgopt_dot11PhyType;
2127+ u8 cfgopt_dot11TempType;
2128+ co_antennas_t cfgopt_antennas;
2129+ co_powerlevels_t cfgopt_power_levels;
2130+ co_datarates_t cfgopt_data_rates;
2131+ co_domains_t cfgopt_domains;
2132+ co_product_id_t cfgopt_product_id;
2133+ co_manuf_t cfgopt_manufacturer;
2134+
2135+ /*** Firmware identification ***/
2136+ char firmware_version[FW_ID_SIZE+1];
2137+ u32 firmware_numver;
2138+ u32 firmware_id;
2139+ const u16 *ie_len;
2140+ const u16 *ie_len_dot11;
2141+
2142+ /*** Device state ***/
2143+ u16 dev_state_mask;
2144+ u8 led_power; /* power LED status */
2145+ u32 get_mask; /* mask of settings to fetch from the card */
2146+ u32 set_mask; /* mask of settings to write to the card */
2147+
2148+ /* Barely used in USB case */
2149+ u16 irq_status;
2150+
2151+ u8 after_interrupt_jobs; /* mini job list for doing actions after an interrupt occurred */
2152+ WORK_STRUCT after_interrupt_task; /* our task for after interrupt actions */
2153+
2154+ /*** scanning ***/
2155+ u16 scan_count; /* number of times to do channel scan */
2156+ u8 scan_mode; /* 0 == active, 1 == passive, 2 == background */
2157+ u8 scan_rate;
2158+ u16 scan_duration;
2159+ u16 scan_probe_delay;
2160+#if WIRELESS_EXT > 15
2161+ struct iw_spy_data spy_data; /* FIXME: needs to be implemented! */
2162+#endif
2163+
2164+ /*** Wireless network settings ***/
2165+ /* copy of the device address (ifconfig hw ether) that we actually use
2166+ ** for 802.11; copied over from the network device's MAC address
2167+ ** (ifconfig) when it makes sense only */
2168+ u8 dev_addr[MAX_ADDR_LEN];
2169+ u8 bssid[ETH_ALEN]; /* the BSSID after having joined */
2170+ u8 ap[ETH_ALEN]; /* The AP we want, FF:FF:FF:FF:FF:FF is any */
2171+ u16 aid; /* The Association ID sent from the AP / last used AID if we're an AP */
2172+ u16 mode; /* mode from iwconfig */
2173+ int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
2174+ u16 status; /* 802.11 association status */
2175+ u8 essid_active; /* specific ESSID active, or select any? */
2176+ u8 essid_len; /* to avoid dozens of strlen() */
2177+ /* INCLUDES \0 termination for easy printf - but many places
2178+ ** simply want the string data memcpy'd plus a length indicator!
2179+ ** Keep that in mind... */
2180+ char essid[IW_ESSID_MAX_SIZE+1];
2181+ /* essid we are going to use for association, in case of "essid 'any'"
2182+ ** and in case of hidden ESSID (use configured ESSID then) */
2183+ char essid_for_assoc[IW_ESSID_MAX_SIZE+1];
2184+ char nick[IW_ESSID_MAX_SIZE+1]; /* see essid! */
2185+ u8 channel;
2186+ u8 reg_dom_id; /* reg domain setting */
2187+ u16 reg_dom_chanmask;
2188+ u16 auth_or_assoc_retries;
2189+ u16 scan_retries;
2190+ unsigned long scan_start; /* YES, jiffies is defined as "unsigned long" */
2191+
2192+ /* stations known to us (if we're an ap) */
2193+ client_t sta_list[32]; /* tab is larger than list, so that */
2194+ client_t *sta_hash_tab[64]; /* hash collisions are not likely */
2195+ client_t *ap_client; /* this one is our AP (STA mode only) */
2196+
2197+ int dup_count;
2198+ int nondup_count;
2199+ unsigned long dup_msg_expiry;
2200+ u16 last_seq_ctrl; /* duplicate packet detection */
2201+
2202+ /* 802.11 power save mode */
2203+ u8 ps_wakeup_cfg;
2204+ u8 ps_listen_interval;
2205+ u8 ps_options;
2206+ u8 ps_hangover_period;
2207+ u32 ps_enhanced_transition_time;
2208+ u32 ps_beacon_rx_time;
2209+
2210+ /*** PHY settings ***/
2211+ u8 fallback_threshold;
2212+ u8 stepup_threshold;
2213+ u16 rate_basic;
2214+ u16 rate_oper;
2215+ u16 rate_bcast;
2216+ u16 rate_bcast100;
2217+ u8 rate_auto; /* false if "iwconfig rate N" (WITHOUT 'auto'!) */
2218+ u8 preamble_mode; /* 0 == Long Preamble, 1 == Short, 2 == Auto */
2219+ u8 preamble_cur;
2220+
2221+ u8 tx_disabled;
2222+ u8 tx_level_dbm;
2223+ /* u8 tx_level_val; */
2224+ /* u8 tx_level_auto; whether to do automatic power adjustment */
2225+
2226+ unsigned long recalib_time_last_success;
2227+ unsigned long recalib_time_last_attempt;
2228+ int recalib_failure_count;
2229+ int recalib_msg_ratelimit;
2230+ int retry_errors_msg_ratelimit;
2231+
2232+ unsigned long brange_time_last_state_change; /* time the power LED was last changed */
2233+ u8 brange_last_state; /* last state of the LED */
2234+ u8 brange_max_quality; /* maximum quality that equates to full speed */
2235+
2236+ u8 sensitivity;
2237+ u8 antenna; /* antenna settings */
2238+ u8 ed_threshold; /* energy detect threshold */
2239+ u8 cca; /* clear channel assessment */
2240+
2241+ u16 rts_threshold;
2242+ u16 frag_threshold;
2243+ u32 short_retry;
2244+ u32 long_retry;
2245+ u16 msdu_lifetime;
2246+ u16 listen_interval; /* given in units of beacon interval */
2247+ u32 beacon_interval;
2248+
2249+ u16 capabilities;
2250+ u8 rate_supported_len;
2251+ u8 rate_supported[13];
2252+
2253+ /*** Encryption settings (WEP) ***/
2254+ u32 auth_alg; /* used in transmit_authen1 */
2255+ u8 wep_enabled;
2256+ u8 wep_restricted;
2257+ u8 wep_current_index;
2258+ wep_key_t wep_keys[DOT11_MAX_DEFAULT_WEP_KEYS]; /* the default WEP keys */
2259+ key_struct_t wep_key_struct[10];
2260+
2261+ /*** Unknown ***/
2262+ u8 dtim_interval;
2263+
2264+#ifdef ACX_MEM
2265+ u32 acx_txbuf_start;
2266+ int acx_txbuf_numblocks;
2267+ u32 acx_txbuf_free; /* addr of head of free list */
2268+ int acx_txbuf_blocks_free; /* how many are still open */
2269+ queueindicator_t *acx_queue_indicator;
2270+#endif
2271+
2272+ /*** Card Rx/Tx management ***/
2273+ u16 rx_config_1;
2274+ u16 rx_config_2;
2275+ u16 memblocksize;
2276+ unsigned int tx_free;
2277+ unsigned int tx_head; /* keep as close as possible to Tx stuff below (cache line) */
2278+ u16 phy_header_len;
2279+
2280+/*************************************************************************
2281+ *** PCI/USB/... must be last or else hw agnostic code breaks horribly ***
2282+ *************************************************************************/
2283+
2284+ /* hack to let common code compile. FIXME */
2285+ dma_addr_t rxhostdesc_startphy;
2286+
2287+ /*** PCI stuff ***/
2288+#if defined(ACX_PCI) || defined(ACX_MEM)
2289+ /* pointers to tx buffers, tx host descriptors (in host memory)
2290+ ** and tx descs in device memory */
2291+ unsigned int tx_tail;
2292+ u8 *txbuf_start;
2293+ txhostdesc_t *txhostdesc_start;
2294+ txdesc_t *txdesc_start; /* points to PCI-mapped memory */
2295+ dma_addr_t txbuf_startphy;
2296+ dma_addr_t txhostdesc_startphy;
2297+ /* sizes of above host memory areas */
2298+ unsigned int txbuf_area_size;
2299+ unsigned int txhostdesc_area_size;
2300+
2301+ unsigned int txdesc_size; /* size of txdesc; ACX111 = ACX100 + 4 */
2302+ client_t *txc[TX_CNT];
2303+ u16 txr[TX_CNT];
2304+
2305+ /* same for rx */
2306+ unsigned int rx_tail;
2307+ rxbuffer_t *rxbuf_start;
2308+ rxhostdesc_t *rxhostdesc_start;
2309+ rxdesc_t *rxdesc_start;
2310+ /* physical addresses of above host memory areas */
2311+ dma_addr_t rxbuf_startphy;
2312+ /* dma_addr_t rxhostdesc_startphy; */
2313+ unsigned int rxbuf_area_size;
2314+ unsigned int rxhostdesc_area_size;
2315+
2316+ u8 need_radio_fw;
2317+ u8 irqs_active; /* whether irq sending is activated */
2318+
2319+ const u16 *io; /* points to ACX100 or ACX111 PCI I/O register address set */
2320+
2321+#ifdef ACX_PCI
2322+ struct pci_dev *pdev;
2323+#endif
2324+#ifdef ACX_MEM
2325+ struct device *dev;
2326+#endif
2327+
2328+#ifdef ACX_PCI
2329+ unsigned long membase;
2330+#endif
2331+#ifdef ACX_MEM
2332+ volatile u32 *membase;
2333+#endif
2334+ unsigned long membase2;
2335+#ifdef ACX_PCI
2336+ void __iomem *iobase;
2337+#endif
2338+#ifdef ACX_MEM
2339+ volatile u32 *iobase;
2340+#endif
2341+ void __iomem *iobase2;
2342+ /* command interface */
2343+ u8 __iomem *cmd_area;
2344+ u8 __iomem *info_area;
2345+
2346+ u16 irq_mask; /* interrupt types to mask out (not wanted) with many IRQs activated */
2347+ u16 irq_mask_off; /* interrupt types to mask out (not wanted) with IRQs off */
2348+ unsigned int irq_loops_this_jiffy;
2349+ unsigned long irq_last_jiffies;
2350+#endif
2351+
2352+ /*** USB stuff ***/
2353+#ifdef ACX_USB
2354+ struct usb_device *usbdev;
2355+
2356+ rxbuffer_t rxtruncbuf;
2357+
2358+ usb_tx_t *usb_tx;
2359+ usb_rx_t *usb_rx;
2360+
2361+ int bulkinep; /* bulk-in endpoint */
2362+ int bulkoutep; /* bulk-out endpoint */
2363+ int rxtruncsize;
2364+#endif
2365+
2366+};
2367+
2368+static inline acx_device_t*
2369+ndev2adev(struct net_device *ndev)
2370+{
2371+ return netdev_priv(ndev);
2372+}
2373+
2374+
2375+/* For use with ACX1xx_IE_RXCONFIG */
2376+/* bit description
2377+ * 13 include additional header (length etc.) *required*
2378+ * struct is defined in 'struct rxbuffer'
2379+ * is this bit acx100 only? does acx111 always put the header,
2380+ * and bit setting is irrelevant? --vda
2381+ * 10 receive frames only with SSID used in last join cmd
2382+ * 9 discard broadcast
2383+ * 8 receive packets for multicast address 1
2384+ * 7 receive packets for multicast address 0
2385+ * 6 discard all multicast packets
2386+ * 5 discard frames from foreign BSSID
2387+ * 4 discard frames with foreign destination MAC address
2388+ * 3 promiscuous mode (receive ALL frames, disable filter)
2389+ * 2 include FCS
2390+ * 1 include phy header
2391+ * 0 ???
2392+ */
2393+#define RX_CFG1_INCLUDE_RXBUF_HDR 0x2000 /* ACX100 only */
2394+#define RX_CFG1_FILTER_SSID 0x0400
2395+#define RX_CFG1_FILTER_BCAST 0x0200
2396+#define RX_CFG1_RCV_MC_ADDR1 0x0100
2397+#define RX_CFG1_RCV_MC_ADDR0 0x0080
2398+#define RX_CFG1_FILTER_ALL_MULTI 0x0040
2399+#define RX_CFG1_FILTER_BSSID 0x0020
2400+#define RX_CFG1_FILTER_MAC 0x0010
2401+#define RX_CFG1_RCV_PROMISCUOUS 0x0008
2402+#define RX_CFG1_INCLUDE_FCS 0x0004
2403+#define RX_CFG1_INCLUDE_PHY_HDR (WANT_PHY_HDR ? 0x0002 : 0)
2404+/* bit description
2405+ * 11 receive association requests etc.
2406+ * 10 receive authentication frames
2407+ * 9 receive beacon frames
2408+ * 8 receive contention free packets
2409+ * 7 receive control frames
2410+ * 6 receive data frames
2411+ * 5 receive broken frames
2412+ * 4 receive management frames
2413+ * 3 receive probe requests
2414+ * 2 receive probe responses
2415+ * 1 receive RTS/CTS/ACK frames
2416+ * 0 receive other
2417+ */
2418+#define RX_CFG2_RCV_ASSOC_REQ 0x0800
2419+#define RX_CFG2_RCV_AUTH_FRAMES 0x0400
2420+#define RX_CFG2_RCV_BEACON_FRAMES 0x0200
2421+#define RX_CFG2_RCV_CONTENTION_FREE 0x0100
2422+#define RX_CFG2_RCV_CTRL_FRAMES 0x0080
2423+#define RX_CFG2_RCV_DATA_FRAMES 0x0040
2424+#define RX_CFG2_RCV_BROKEN_FRAMES 0x0020
2425+#define RX_CFG2_RCV_MGMT_FRAMES 0x0010
2426+#define RX_CFG2_RCV_PROBE_REQ 0x0008
2427+#define RX_CFG2_RCV_PROBE_RESP 0x0004
2428+#define RX_CFG2_RCV_ACK_FRAMES 0x0002
2429+#define RX_CFG2_RCV_OTHER 0x0001
2430+
2431+/* For use with ACX1xx_IE_FEATURE_CONFIG */
2432+#define FEATURE1_80MHZ_CLOCK 0x00000040L
2433+#define FEATURE1_4X 0x00000020L
2434+#define FEATURE1_LOW_RX 0x00000008L
2435+#define FEATURE1_EXTRA_LOW_RX 0x00000001L
2436+
2437+#define FEATURE2_SNIFFER 0x00000080L
2438+#define FEATURE2_NO_TXCRYPT 0x00000001L
2439+
2440+/*-- get and set mask values --*/
2441+#define GETSET_LED_POWER 0x00000001L
2442+#define GETSET_STATION_ID 0x00000002L
2443+#define SET_TEMPLATES 0x00000004L
2444+#define SET_STA_LIST 0x00000008L
2445+#define GETSET_TX 0x00000010L
2446+#define GETSET_RX 0x00000020L
2447+#define SET_RXCONFIG 0x00000040L
2448+#define GETSET_ANTENNA 0x00000080L
2449+#define GETSET_SENSITIVITY 0x00000100L
2450+#define GETSET_TXPOWER 0x00000200L
2451+#define GETSET_ED_THRESH 0x00000400L
2452+#define GETSET_CCA 0x00000800L
2453+#define GETSET_POWER_80211 0x00001000L
2454+#define GETSET_RETRY 0x00002000L
2455+#define GETSET_REG_DOMAIN 0x00004000L
2456+#define GETSET_CHANNEL 0x00008000L
2457+/* Used when ESSID changes etc and we need to scan for AP anew */
2458+#define GETSET_RESCAN 0x00010000L
2459+#define GETSET_MODE 0x00020000L
2460+#define GETSET_WEP 0x00040000L
2461+#define SET_WEP_OPTIONS 0x00080000L
2462+#define SET_MSDU_LIFETIME 0x00100000L
2463+#define SET_RATE_FALLBACK 0x00200000L
2464+
2465+/* keep in sync with the above */
2466+#define GETSET_ALL (0 \
2467+/* GETSET_LED_POWER */ | 0x00000001L \
2468+/* GETSET_STATION_ID */ | 0x00000002L \
2469+/* SET_TEMPLATES */ | 0x00000004L \
2470+/* SET_STA_LIST */ | 0x00000008L \
2471+/* GETSET_TX */ | 0x00000010L \
2472+/* GETSET_RX */ | 0x00000020L \
2473+/* SET_RXCONFIG */ | 0x00000040L \
2474+/* GETSET_ANTENNA */ | 0x00000080L \
2475+/* GETSET_SENSITIVITY */| 0x00000100L \
2476+/* GETSET_TXPOWER */ | 0x00000200L \
2477+/* GETSET_ED_THRESH */ | 0x00000400L \
2478+/* GETSET_CCA */ | 0x00000800L \
2479+/* GETSET_POWER_80211 */| 0x00001000L \
2480+/* GETSET_RETRY */ | 0x00002000L \
2481+/* GETSET_REG_DOMAIN */ | 0x00004000L \
2482+/* GETSET_CHANNEL */ | 0x00008000L \
2483+/* GETSET_RESCAN */ | 0x00010000L \
2484+/* GETSET_MODE */ | 0x00020000L \
2485+/* GETSET_WEP */ | 0x00040000L \
2486+/* SET_WEP_OPTIONS */ | 0x00080000L \
2487+/* SET_MSDU_LIFETIME */ | 0x00100000L \
2488+/* SET_RATE_FALLBACK */ | 0x00200000L \
2489+ )
2490+
2491+
2492+/***********************************************************************
2493+** Firmware loading
2494+*/
2495+#include <linux/firmware.h> /* request_firmware() */
2496+#include <linux/pci.h> /* struct pci_device */
2497+
2498+
2499+/***********************************************************************
2500+*/
2501+typedef struct acx100_ie_memblocksize {
2502+ u16 type;
2503+ u16 len;
2504+ u16 size;
2505+} ACX_PACKED acx100_ie_memblocksize_t;
2506+
2507+typedef struct acx100_ie_queueconfig {
2508+ u16 type;
2509+ u16 len;
2510+ u32 AreaSize;
2511+ u32 RxQueueStart;
2512+ u8 QueueOptions;
2513+ u8 NumTxQueues;
2514+ u8 NumRxDesc; /* for USB only */
2515+ u8 pad1;
2516+ u32 QueueEnd;
2517+ u32 HostQueueEnd; /* QueueEnd2 */
2518+ u32 TxQueueStart;
2519+ u8 TxQueuePri;
2520+ u8 NumTxDesc;
2521+ u16 pad2;
2522+} ACX_PACKED acx100_ie_queueconfig_t;
2523+
2524+typedef struct acx111_ie_queueconfig {
2525+ u16 type;
2526+ u16 len;
2527+ u32 tx_memory_block_address;
2528+ u32 rx_memory_block_address;
2529+ u32 rx1_queue_address;
2530+ u32 reserved1;
2531+ u32 tx1_queue_address;
2532+ u8 tx1_attributes;
2533+ u16 reserved2;
2534+ u8 reserved3;
2535+} ACX_PACKED acx111_ie_queueconfig_t;
2536+
2537+typedef struct acx100_ie_memconfigoption {
2538+ u16 type;
2539+ u16 len;
2540+ u32 DMA_config;
2541+ acx_ptr pRxHostDesc;
2542+ u32 rx_mem;
2543+ u32 tx_mem;
2544+ u16 RxBlockNum;
2545+ u16 TxBlockNum;
2546+} ACX_PACKED acx100_ie_memconfigoption_t;
2547+
2548+typedef struct acx111_ie_memoryconfig {
2549+ u16 type;
2550+ u16 len;
2551+ u16 no_of_stations;
2552+ u16 memory_block_size;
2553+ u8 tx_rx_memory_block_allocation;
2554+ u8 count_rx_queues;
2555+ u8 count_tx_queues;
2556+ u8 options;
2557+ u8 fragmentation;
2558+ u16 reserved1;
2559+ u8 reserved2;
2560+
2561+ /* start of rx1 block */
2562+ u8 rx_queue1_count_descs;
2563+ u8 rx_queue1_reserved1;
2564+ u8 rx_queue1_type; /* must be set to 7 */
2565+ u8 rx_queue1_prio; /* must be set to 0 */
2566+ acx_ptr rx_queue1_host_rx_start;
2567+ /* end of rx1 block */
2568+
2569+ /* start of tx1 block */
2570+ u8 tx_queue1_count_descs;
2571+ u8 tx_queue1_reserved1;
2572+ u8 tx_queue1_reserved2;
2573+ u8 tx_queue1_attributes;
2574+ /* end of tx1 block */
2575+} ACX_PACKED acx111_ie_memoryconfig_t;
2576+
2577+typedef struct acx_ie_memmap {
2578+ u16 type;
2579+ u16 len;
2580+ u32 CodeStart;
2581+ u32 CodeEnd;
2582+ u32 WEPCacheStart;
2583+ u32 WEPCacheEnd;
2584+ u32 PacketTemplateStart;
2585+ u32 PacketTemplateEnd;
2586+ u32 QueueStart;
2587+ u32 QueueEnd;
2588+ u32 PoolStart;
2589+ u32 PoolEnd;
2590+} ACX_PACKED acx_ie_memmap_t;
2591+
2592+typedef struct acx111_ie_feature_config {
2593+ u16 type;
2594+ u16 len;
2595+ u32 feature_options;
2596+ u32 data_flow_options;
2597+} ACX_PACKED acx111_ie_feature_config_t;
2598+
2599+typedef struct acx111_ie_tx_level {
2600+ u16 type;
2601+ u16 len;
2602+ u8 level;
2603+} ACX_PACKED acx111_ie_tx_level_t;
2604+
2605+#define PS_CFG_ENABLE 0x80
2606+#define PS_CFG_PENDING 0x40 /* status flag when entering PS */
2607+#define PS_CFG_WAKEUP_MODE_MASK 0x07
2608+#define PS_CFG_WAKEUP_BY_HOST 0x03
2609+#define PS_CFG_WAKEUP_EACH_ITVL 0x02
2610+#define PS_CFG_WAKEUP_ON_DTIM 0x01
2611+#define PS_CFG_WAKEUP_ALL_BEAC 0x00
2612+
2613+/* Enhanced PS mode: sleep until Rx Beacon w/ the STA's AID bit set
2614+** in the TIM; newer firmwares only(?) */
2615+#define PS_OPT_ENA_ENHANCED_PS 0x04
2616+#define PS_OPT_TX_PSPOLL 0x02 /* send PSPoll frame to fetch waiting frames from AP (on frame with matching AID) */
2617+#define PS_OPT_STILL_RCV_BCASTS 0x01
2618+
2619+typedef struct acx100_ie_powersave {
2620+ u16 type;
2621+ u16 len;
2622+ u8 wakeup_cfg;
2623+ u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */
2624+ u8 options;
2625+ u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */
2626+ u16 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */
2627+} ACX_PACKED acx100_ie_powersave_t;
2628+
2629+typedef struct acx111_ie_powersave {
2630+ u16 type;
2631+ u16 len;
2632+ u8 wakeup_cfg;
2633+ u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */
2634+ u8 options;
2635+ u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */
2636+ u32 beacon_rx_time;
2637+ u32 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */
2638+} ACX_PACKED acx111_ie_powersave_t;
2639+
2640+
2641+/***********************************************************************
2642+** Commands and template structures
2643+*/
2644+
2645+/*
2646+** SCAN command structure
2647+**
2648+** even though acx100 scan rates match RATE100 constants,
2649+** acx111 ones do not match! Therefore we do not use RATE100 #defines */
2650+#define ACX_SCAN_RATE_1 10
2651+#define ACX_SCAN_RATE_2 20
2652+#define ACX_SCAN_RATE_5 55
2653+#define ACX_SCAN_RATE_11 110
2654+#define ACX_SCAN_RATE_22 220
2655+#define ACX_SCAN_RATE_PBCC 0x80 /* OR with this if needed */
2656+#define ACX_SCAN_OPT_ACTIVE 0x00 /* a bit mask */
2657+#define ACX_SCAN_OPT_PASSIVE 0x01
2658+/* Background scan: we go into Power Save mode (by transmitting
2659+** NULL data frame to AP with the power mgmt bit set), do the scan,
2660+** and then exit Power Save mode. A plus is that AP buffers frames
2661+** for us while we do background scan. Thus we avoid frame losses.
2662+** Background scan can be active or passive, just like normal one */
2663+#define ACX_SCAN_OPT_BACKGROUND 0x02
2664+typedef struct acx100_scan {
2665+ u16 count; /* number of scans to do, 0xffff == continuous */
2666+ u16 start_chan;
2667+ u16 flags; /* channel list mask; 0x8000 == all channels? */
2668+ u8 max_rate; /* max. probe rate */
2669+ u8 options; /* bit mask, see defines above */
2670+ u16 chan_duration;
2671+ u16 max_probe_delay;
2672+} ACX_PACKED acx100_scan_t; /* length 0xc */
2673+
2674+#define ACX111_SCAN_RATE_6 0x0B
2675+#define ACX111_SCAN_RATE_9 0x0F
2676+#define ACX111_SCAN_RATE_12 0x0A
2677+#define ACX111_SCAN_RATE_18 0x0E
2678+#define ACX111_SCAN_RATE_24 0x09
2679+#define ACX111_SCAN_RATE_36 0x0D
2680+#define ACX111_SCAN_RATE_48 0x08
2681+#define ACX111_SCAN_RATE_54 0x0C
2682+#define ACX111_SCAN_OPT_5GHZ 0x04 /* else 2.4GHZ */
2683+#define ACX111_SCAN_MOD_SHORTPRE 0x01 /* you can combine SHORTPRE and PBCC */
2684+#define ACX111_SCAN_MOD_PBCC 0x80
2685+#define ACX111_SCAN_MOD_OFDM 0x40
2686+typedef struct acx111_scan {
2687+ u16 count; /* number of scans to do */
2688+ u8 channel_list_select; /* 0: scan all channels, 1: from chan_list only */
2689+ u16 reserved1;
2690+ u8 reserved2;
2691+ u8 rate; /* rate for probe requests (if active scan) */
2692+ u8 options; /* bit mask, see defines above */
2693+ u16 chan_duration; /* min time to wait for reply on one channel (in TU) */
2694+ /* (active scan only) (802.11 section 11.1.3.2.2) */
2695+ u16 max_probe_delay; /* max time to wait for reply on one channel (active scan) */
2696+ /* time to listen on a channel (passive scan) */
2697+ u8 modulation;
2698+ u8 channel_list[26]; /* bits 7:0 first byte: channels 8:1 */
2699+ /* bits 7:0 second byte: channels 16:9 */
2700+ /* 26 bytes is enough to cover 802.11a */
2701+} ACX_PACKED acx111_scan_t;
2702+
2703+
2704+/*
2705+** Radio calibration command structure
2706+*/
2707+typedef struct acx111_cmd_radiocalib {
2708+/* 0x80000000 == automatic calibration by firmware, according to interval;
2709+ * bits 0..3: select calibration methods to go through:
2710+ * calib based on DC, AfeDC, Tx mismatch, Tx equilization */
2711+ u32 methods;
2712+ u32 interval;
2713+} ACX_PACKED acx111_cmd_radiocalib_t;
2714+
2715+
2716+/*
2717+** Packet template structures
2718+**
2719+** Packet templates store contents of Beacon, Probe response, Probe request,
2720+** Null data frame, and TIM data frame. Firmware automatically transmits
2721+** contents of template at appropriate time:
2722+** - Beacon: when configured as AP or Ad-hoc
2723+** - Probe response: when configured as AP or Ad-hoc, whenever
2724+** a Probe request frame is received
2725+** - Probe request: when host issues SCAN command (active)
2726+** - Null data frame: when entering 802.11 power save mode
2727+** - TIM data: at the end of Beacon frames (if no TIM template
2728+** is configured, then transmits default TIM)
2729+** NB:
2730+** - size field must be set to size of actual template
2731+** (NOT sizeof(struct) - templates are variable in length),
2732+** size field is not itself counted.
2733+** - members flagged with an asterisk must be initialized with host,
2734+** rest must be zero filled.
2735+** - variable length fields shown only in comments */
2736+typedef struct acx_template_tim {
2737+ u16 size;
2738+ u8 tim_eid; /* 00 1 TIM IE ID * */
2739+ u8 len; /* 01 1 Length * */
2740+ u8 dtim_cnt; /* 02 1 DTIM Count */
2741+ u8 dtim_period; /* 03 1 DTIM Period */
2742+ u8 bitmap_ctrl; /* 04 1 Bitmap Control * (except bit0) */
2743+ /* 05 n Partial Virtual Bitmap * */
2744+ u8 variable[0x100 - 1-1-1-1-1];
2745+} ACX_PACKED acx_template_tim_t;
2746+
2747+typedef struct acx_template_probereq {
2748+ u16 size;
2749+ u16 fc; /* 00 2 fc * */
2750+ u16 dur; /* 02 2 Duration */
2751+ u8 da[6]; /* 04 6 Destination Address * */
2752+ u8 sa[6]; /* 0A 6 Source Address * */
2753+ u8 bssid[6]; /* 10 6 BSSID * */
2754+ u16 seq; /* 16 2 Sequence Control */
2755+ /* 18 n SSID * */
2756+ /* nn n Supported Rates * */
2757+ u8 variable[0x44 - 2-2-6-6-6-2];
2758+} ACX_PACKED acx_template_probereq_t;
2759+
2760+typedef struct acx_template_proberesp {
2761+ u16 size;
2762+ u16 fc; /* 00 2 fc * (bits [15:12] and [10:8] per 802.11 section 7.1.3.1) */
2763+ u16 dur; /* 02 2 Duration */
2764+ u8 da[6]; /* 04 6 Destination Address */
2765+ u8 sa[6]; /* 0A 6 Source Address */
2766+ u8 bssid[6]; /* 10 6 BSSID */
2767+ u16 seq; /* 16 2 Sequence Control */
2768+ u8 timestamp[8];/* 18 8 Timestamp */
2769+ u16 beacon_interval; /* 20 2 Beacon Interval * */
2770+ u16 cap; /* 22 2 Capability Information * */
2771+ /* 24 n SSID * */
2772+ /* nn n Supported Rates * */
2773+ /* nn 1 DS Parameter Set * */
2774+ u8 variable[0x54 - 2-2-6-6-6-2-8-2-2];
2775+} ACX_PACKED acx_template_proberesp_t;
2776+#define acx_template_beacon_t acx_template_proberesp_t
2777+#define acx_template_beacon acx_template_proberesp
2778+
2779+typedef struct acx_template_nullframe {
2780+ u16 size;
2781+ struct wlan_hdr_a3 hdr;
2782+} ACX_PACKED acx_template_nullframe_t;
2783+
2784+
2785+/*
2786+** JOIN command structure
2787+**
2788+** as opposed to acx100, acx111 dtim interval is AFTER rates_basic111.
2789+** NOTE: took me about an hour to get !@#$%^& packing right --> struct packing is eeeeevil... */
2790+typedef struct acx_joinbss {
2791+ u8 bssid[ETH_ALEN];
2792+ u16 beacon_interval;
2793+ union {
2794+ struct {
2795+ u8 dtim_interval;
2796+ u8 rates_basic;
2797+ u8 rates_supported;
2798+ /*
2799+ * ARM compiler doesn't pack correctly unless unions
2800+ * inside structures are multiples of 4 bytes. Ugh.
2801+ */
2802+ u8 genfrm_txrate; /* generated frame (bcn, proberesp, RTS, PSpoll) tx rate */
2803+ } ACX_PACKED acx100;
2804+ struct {
2805+ u16 rates_basic;
2806+ u8 dtim_interval;
2807+ u8 genfrm_txrate; /* generated frame (bcn, proberesp, RTS, PSpoll) tx rate */
2808+ } ACX_PACKED acx111;
2809+ /*
2810+ * ARM compiler doesn't pack correctly unles unions are aligned on
2811+ * 4 byte boundaries and are multiples of 4 bytes.
2812+ */
2813+ struct {
2814+ u8 d1;
2815+ u8 d2;
2816+ u8 d3;
2817+ u8 genfrm_txrate;
2818+ } ACX_PACKED txrate;
2819+ } ACX_PACKED u;
2820+ u8 genfrm_mod_pre; /* generated frame modulation/preamble:
2821+ ** bit7: PBCC, bit6: OFDM (else CCK/DQPSK/DBPSK)
2822+ ** bit5: short pre */
2823+ u8 macmode; /* BSS Type, must be one of ACX_MODE_xxx */
2824+ u8 channel;
2825+ u8 essid_len;
2826+ char essid[IW_ESSID_MAX_SIZE];
2827+} ACX_PACKED acx_joinbss_t;
2828+
2829+#define JOINBSS_RATES_1 0x01
2830+#define JOINBSS_RATES_2 0x02
2831+#define JOINBSS_RATES_5 0x04
2832+#define JOINBSS_RATES_11 0x08
2833+#define JOINBSS_RATES_22 0x10
2834+
2835+/* Looks like missing bits are used to indicate 11g rates!
2836+** (it follows from the fact that constants below match 1:1 to RATE111_nn)
2837+** This was actually seen! Look at that Assoc Request sent by acx111,
2838+** it _does_ contain 11g rates in basic set:
2839+01:30:20.070772 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1
2840+01:30:20.074425 Authentication (Open System)-1: Succesful
2841+01:30:20.076539 Authentication (Open System)-2:
2842+01:30:20.076620 Acknowledgment
2843+01:30:20.088546 Assoc Request (xxx) [1.0* 2.0* 5.5* 6.0* 9.0* 11.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit]
2844+01:30:20.122413 Assoc Response AID(1) :: Succesful
2845+01:30:20.122679 Acknowledgment
2846+01:30:20.173204 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1
2847+*/
2848+#define JOINBSS_RATES_BASIC111_1 0x0001
2849+#define JOINBSS_RATES_BASIC111_2 0x0002
2850+#define JOINBSS_RATES_BASIC111_5 0x0004
2851+#define JOINBSS_RATES_BASIC111_11 0x0020
2852+#define JOINBSS_RATES_BASIC111_22 0x0100
2853+
2854+
2855+/***********************************************************************
2856+*/
2857+typedef struct mem_read_write {
2858+ u16 addr;
2859+ u16 type; /* 0x0 int. RAM / 0xffff MAC reg. / 0x81 PHY RAM / 0x82 PHY reg.; or maybe it's actually 0x30 for MAC? Better verify it by writing and reading back and checking whether the value holds! */
2860+ u32 len;
2861+ u32 data;
2862+} ACX_PACKED mem_read_write_t;
2863+
2864+typedef struct firmware_image {
2865+ u32 chksum;
2866+ u32 size;
2867+ u8 data[1]; /* the byte array of the actual firmware... */
2868+} ACX_PACKED firmware_image_t;
2869+
2870+typedef struct acx_cmd_radioinit {
2871+ u32 offset;
2872+ u32 len;
2873+} ACX_PACKED acx_cmd_radioinit_t;
2874+
2875+typedef struct acx100_ie_wep_options {
2876+ u16 type;
2877+ u16 len;
2878+ u16 NumKeys; /* max # of keys */
2879+ u8 WEPOption; /* 0 == decrypt default key only, 1 == override decrypt */
2880+ u8 Pad; /* used only for acx111 */
2881+} ACX_PACKED acx100_ie_wep_options_t;
2882+
2883+typedef struct ie_dot11WEPDefaultKey {
2884+ u16 type;
2885+ u16 len;
2886+ u8 action;
2887+ u8 keySize;
2888+ u8 defaultKeyNum;
2889+ u8 key[29]; /* check this! was Key[19] */
2890+} ACX_PACKED ie_dot11WEPDefaultKey_t;
2891+
2892+typedef struct acx111WEPDefaultKey {
2893+ u8 MacAddr[ETH_ALEN];
2894+ u16 action; /* NOTE: this is a u16, NOT a u8!! */
2895+ u16 reserved;
2896+ u8 keySize;
2897+ u8 type;
2898+ u8 index;
2899+ u8 defaultKeyNum;
2900+ u8 counter[6];
2901+ u8 key[32]; /* up to 32 bytes (for TKIP!) */
2902+} ACX_PACKED acx111WEPDefaultKey_t;
2903+
2904+typedef struct ie_dot11WEPDefaultKeyID {
2905+ u16 type;
2906+ u16 len;
2907+ u8 KeyID;
2908+} ACX_PACKED ie_dot11WEPDefaultKeyID_t;
2909+
2910+typedef struct acx100_cmd_wep_mgmt {
2911+ u8 MacAddr[ETH_ALEN];
2912+ u16 Action;
2913+ u16 KeySize;
2914+ u8 Key[29]; /* 29*8 == 232bits == WEP256 */
2915+} ACX_PACKED acx100_cmd_wep_mgmt_t;
2916+
2917+typedef struct acx_ie_generic {
2918+ u16 type;
2919+ u16 len;
2920+ union {
2921+ /* Association ID IE: just a 16bit value: */
2922+ u16 aid;
2923+ /* generic member for quick implementation of commands */
2924+ u8 bytes[32];
2925+ } ACX_PACKED m;
2926+} ACX_PACKED acx_ie_generic_t;
2927+
2928+/***********************************************************************
2929+*/
2930+#define CHECK_SIZEOF(type,size) { \
2931+ extern void BUG_bad_size_for_##type(void); \
2932+ if (sizeof(type)!=(size)) BUG_bad_size_for_##type(); \
2933+}
2934+
2935+static inline void
2936+acx_struct_size_check(void)
2937+{
2938+ CHECK_SIZEOF(txdesc_t, 0x30);
2939+ CHECK_SIZEOF(acx100_ie_memconfigoption_t, 24);
2940+ CHECK_SIZEOF(acx100_ie_queueconfig_t, 0x20);
2941+ CHECK_SIZEOF(acx_joinbss_t, 0x30);
2942+ /* IEs need 4 bytes for (type,len) tuple */
2943+ CHECK_SIZEOF(acx111_ie_configoption_t, ACX111_IE_CONFIG_OPTIONS_LEN + 4);
2944+}
2945+
2946+
2947+/***********************************************************************
2948+** Global data
2949+*/
2950+extern const u8 acx_bitpos2ratebyte[];
2951+extern const u8 acx_bitpos2rate100[];
2952+
2953+extern const u8 acx_reg_domain_ids[];
2954+extern const char * const acx_reg_domain_strings[];
2955+enum {
2956+ acx_reg_domain_ids_len = 8
2957+};
2958+
2959+extern const struct iw_handler_def acx_ioctl_handler_def;
2960Index: linux-2.6.22/drivers/net/wireless/acx/common.c
2961===================================================================
2962--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2963+++ linux-2.6.22/drivers/net/wireless/acx/common.c 2007-08-23 18:34:19.000000000 +0200
2964@@ -0,0 +1,7388 @@
2965+/***********************************************************************
2966+** Copyright (C) 2003 ACX100 Open Source Project
2967+**
2968+** The contents of this file are subject to the Mozilla Public
2969+** License Version 1.1 (the "License"); you may not use this file
2970+** except in compliance with the License. You may obtain a copy of
2971+** the License at http://www.mozilla.org/MPL/
2972+**
2973+** Software distributed under the License is distributed on an "AS
2974+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
2975+** implied. See the License for the specific language governing
2976+** rights and limitations under the License.
2977+**
2978+** Alternatively, the contents of this file may be used under the
2979+** terms of the GNU Public License version 2 (the "GPL"), in which
2980+** case the provisions of the GPL are applicable instead of the
2981+** above. If you wish to allow the use of your version of this file
2982+** only under the terms of the GPL and not to allow others to use
2983+** your version of this file under the MPL, indicate your decision
2984+** by deleting the provisions above and replace them with the notice
2985+** and other provisions required by the GPL. If you do not delete
2986+** the provisions above, a recipient may use your version of this
2987+** file under either the MPL or the GPL.
2988+** ---------------------------------------------------------------------
2989+** Inquiries regarding the ACX100 Open Source Project can be
2990+** made directly to:
2991+**
2992+** acx100-users@lists.sf.net
2993+** http://acx100.sf.net
2994+** ---------------------------------------------------------------------
2995+*/
2996+
2997+#include <linux/version.h>
2998+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
2999+#include <linux/config.h>
3000+#endif
3001+#include <linux/module.h>
3002+#include <linux/kernel.h>
3003+#include <linux/sched.h>
3004+#include <linux/types.h>
3005+#include <linux/slab.h>
3006+#include <linux/delay.h>
3007+#include <linux/proc_fs.h>
3008+#include <linux/if_arp.h>
3009+#include <linux/rtnetlink.h>
3010+#include <linux/netdevice.h>
3011+#include <linux/etherdevice.h>
3012+#include <linux/wireless.h>
3013+#include <linux/pm.h>
3014+#include <linux/vmalloc.h>
3015+#include <net/iw_handler.h>
3016+
3017+#include "acx_hw.h"
3018+#include "acx.h"
3019+
3020+
3021+/***********************************************************************
3022+*/
3023+static client_t *acx_l_sta_list_alloc(acx_device_t *adev);
3024+static client_t *acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address);
3025+
3026+static int acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf);
3027+static int acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf);
3028+/* static int acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala); */
3029+static int acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf);
3030+static void acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req);
3031+static void acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req);
3032+static void acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req);
3033+static void acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req);
3034+static int acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, const rxbuffer_t *rxbuf);
3035+static int acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req);
3036+static int acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req);
3037+static int acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req);
3038+static int acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req);
3039+static int acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req);
3040+static int acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason);
3041+static int acx_l_transmit_authen1(acx_device_t *adev);
3042+static int acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, client_t *clt);
3043+static int acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req);
3044+static int acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req);
3045+static int acx_l_transmit_assoc_req(acx_device_t *adev);
3046+
3047+
3048+/***********************************************************************
3049+*/
3050+#if ACX_DEBUG
3051+unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG;
3052+/* parameter is 'debug', corresponding var is acx_debug */
3053+module_param_named(debug, acx_debug, uint, 0);
3054+MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)");
3055+#endif
3056+
3057+#ifdef MODULE_LICENSE
3058+MODULE_LICENSE("Dual MPL/GPL");
3059+#endif
3060+/* USB had this: MODULE_AUTHOR("Martin Wawro <martin.wawro AT uni-dortmund.de>"); */
3061+MODULE_AUTHOR("ACX100 Open Source Driver development team");
3062+MODULE_DESCRIPTION("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
3063+
3064+
3065+/***********************************************************************
3066+*/
3067+/* Probably a number of acx's intermediate buffers for USB transfers,
3068+** not to be confused with number of descriptors in tx/rx rings
3069+** (which are not directly accessible to host in USB devices) */
3070+#define USB_RX_CNT 10
3071+#define USB_TX_CNT 10
3072+
3073+
3074+/***********************************************************************
3075+*/
3076+
3077+/* minutes to wait until next radio recalibration: */
3078+#define RECALIB_PAUSE 5
3079+
3080+/* Please keep acx_reg_domain_ids_len in sync... */
3081+const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] =
3082+ { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 };
3083+static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] =
3084+#ifdef ACX_ALLOW_ALLCHANNELS
3085+ { 0x3fff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
3086+#else
3087+ { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc };
3088+#endif
3089+const char * const
3090+acx_reg_domain_strings[] = {
3091+ /* 0 */ " 1-11 FCC (USA)",
3092+ /* 1 */ " 1-11 DOC/IC (Canada)",
3093+/* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */
3094+ /* 2 */ " 1-13 ETSI (Europe)",
3095+ /* 3 */ "10-11 Spain",
3096+ /* 4 */ "10-13 France",
3097+ /* 5 */ " 14 MKK (Japan)",
3098+ /* 6 */ " 1-14 MKK1",
3099+ /* 7 */ " 3-9 Israel (not all firmware versions)",
3100+ NULL /* needs to remain as last entry */
3101+};
3102+
3103+
3104+
3105+/***********************************************************************
3106+** Debugging support
3107+*/
3108+#ifdef PARANOID_LOCKING
3109+static unsigned max_lock_time;
3110+static unsigned max_sem_time;
3111+
3112+void
3113+acx_lock_unhold() { max_lock_time = 0; }
3114+void
3115+acx_sem_unhold() { max_sem_time = 0; }
3116+
3117+static inline const char*
3118+sanitize_str(const char *s)
3119+{
3120+ const char* t = strrchr(s, '/');
3121+ if (t) return t + 1;
3122+ return s;
3123+}
3124+
3125+void
3126+acx_lock_debug(acx_device_t *adev, const char* where)
3127+{
3128+ unsigned int count = 100*1000*1000;
3129+ where = sanitize_str(where);
3130+ while (--count) {
3131+ if (!spin_is_locked(&adev->lock)) break;
3132+ cpu_relax();
3133+ }
3134+ if (!count) {
3135+ printk(KERN_EMERG "LOCKUP: already taken at %s!\n", adev->last_lock);
3136+ BUG();
3137+ }
3138+ adev->last_lock = where;
3139+ rdtscl(adev->lock_time);
3140+}
3141+void
3142+acx_unlock_debug(acx_device_t *adev, const char* where)
3143+{
3144+#ifdef SMP
3145+ if (!spin_is_locked(&adev->lock)) {
3146+ where = sanitize_str(where);
3147+ printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where);
3148+ BUG();
3149+ }
3150+#endif
3151+ if (acx_debug & L_LOCK) {
3152+ unsigned long diff;
3153+ rdtscl(diff);
3154+ diff -= adev->lock_time;
3155+ if (diff > max_lock_time) {
3156+ where = sanitize_str(where);
3157+ printk("max lock hold time %ld CPU ticks from %s "
3158+ "to %s\n", diff, adev->last_lock, where);
3159+ max_lock_time = diff;
3160+ }
3161+ }
3162+}
3163+void
3164+acx_down_debug(acx_device_t *adev, const char* where)
3165+{
3166+ int sem_count;
3167+ unsigned long timeout = jiffies + 5*HZ;
3168+
3169+ where = sanitize_str(where);
3170+
3171+ for (;;) {
3172+ sem_count = atomic_read(&adev->sem.count);
3173+ if (sem_count) break;
3174+ if (time_after(jiffies, timeout))
3175+ break;
3176+ msleep(5);
3177+ }
3178+ if (!sem_count) {
3179+ printk(KERN_EMERG "D STATE at %s! last sem at %s\n",
3180+ where, adev->last_sem);
3181+ dump_stack();
3182+ }
3183+ adev->last_sem = where;
3184+ adev->sem_time = jiffies;
3185+ down(&adev->sem);
3186+ if (acx_debug & L_LOCK) {
3187+ printk("%s: sem_down %d -> %d\n",
3188+ where, sem_count, atomic_read(&adev->sem.count));
3189+ }
3190+}
3191+void
3192+acx_up_debug(acx_device_t *adev, const char* where)
3193+{
3194+ int sem_count = atomic_read(&adev->sem.count);
3195+ if (sem_count) {
3196+ where = sanitize_str(where);
3197+ printk(KERN_EMERG "STRAY UP at %s! sem.count=%d\n", where, sem_count);
3198+ dump_stack();
3199+ }
3200+ if (acx_debug & L_LOCK) {
3201+ unsigned long diff = jiffies - adev->sem_time;
3202+ if (diff > max_sem_time) {
3203+ where = sanitize_str(where);
3204+ printk("max sem hold time %ld jiffies from %s "
3205+ "to %s\n", diff, adev->last_sem, where);
3206+ max_sem_time = diff;
3207+ }
3208+ }
3209+ up(&adev->sem);
3210+ if (acx_debug & L_LOCK) {
3211+ where = sanitize_str(where);
3212+ printk("%s: sem_up %d -> %d\n",
3213+ where, sem_count, atomic_read(&adev->sem.count));
3214+ }
3215+}
3216+#endif /* PARANOID_LOCKING */
3217+
3218+
3219+/***********************************************************************
3220+*/
3221+#if ACX_DEBUG > 1
3222+
3223+static int acx_debug_func_indent;
3224+#define DEBUG_TSC 0
3225+#define FUNC_INDENT_INCREMENT 2
3226+
3227+#if DEBUG_TSC
3228+#define TIMESTAMP(d) unsigned long d; rdtscl(d)
3229+#else
3230+#define TIMESTAMP(d) unsigned long d = jiffies
3231+#endif
3232+
3233+static const char
3234+spaces[] = " " " "; /* Nx10 spaces */
3235+
3236+void
3237+log_fn_enter(const char *funcname)
3238+{
3239+ int indent;
3240+ TIMESTAMP(d);
3241+
3242+ indent = acx_debug_func_indent;
3243+ if (indent >= sizeof(spaces))
3244+ indent = sizeof(spaces)-1;
3245+
3246+ printk("%08ld %s==> %s\n",
3247+ d % 100000000,
3248+ spaces + (sizeof(spaces)-1) - indent,
3249+ funcname
3250+ );
3251+
3252+ acx_debug_func_indent += FUNC_INDENT_INCREMENT;
3253+}
3254+void
3255+log_fn_exit(const char *funcname)
3256+{
3257+ int indent;
3258+ TIMESTAMP(d);
3259+
3260+ acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
3261+
3262+ indent = acx_debug_func_indent;
3263+ if (indent >= sizeof(spaces))
3264+ indent = sizeof(spaces)-1;
3265+
3266+ printk("%08ld %s<== %s\n",
3267+ d % 100000000,
3268+ spaces + (sizeof(spaces)-1) - indent,
3269+ funcname
3270+ );
3271+}
3272+void
3273+log_fn_exit_v(const char *funcname, int v)
3274+{
3275+ int indent;
3276+ TIMESTAMP(d);
3277+
3278+ acx_debug_func_indent -= FUNC_INDENT_INCREMENT;
3279+
3280+ indent = acx_debug_func_indent;
3281+ if (indent >= sizeof(spaces))
3282+ indent = sizeof(spaces)-1;
3283+
3284+ printk("%08ld %s<== %s: %08X\n",
3285+ d % 100000000,
3286+ spaces + (sizeof(spaces)-1) - indent,
3287+ funcname,
3288+ v
3289+ );
3290+}
3291+#endif /* ACX_DEBUG > 1 */
3292+
3293+
3294+/***********************************************************************
3295+** Basically a msleep with logging
3296+*/
3297+void
3298+acx_s_msleep(int ms)
3299+{
3300+ FN_ENTER;
3301+ msleep(ms);
3302+ FN_EXIT0;
3303+}
3304+
3305+
3306+/***********************************************************************
3307+** Not inlined: it's larger than it seems
3308+*/
3309+void
3310+acx_print_mac(const char *head, const u8 *mac, const char *tail)
3311+{
3312+ printk("%s"MACSTR"%s", head, MAC(mac), tail);
3313+}
3314+
3315+
3316+/***********************************************************************
3317+** acx_get_status_name
3318+*/
3319+static const char*
3320+acx_get_status_name(u16 status)
3321+{
3322+ static const char * const str[] = {
3323+ "STOPPED", "SCANNING", "WAIT_AUTH",
3324+ "AUTHENTICATED", "ASSOCIATED", "INVALID??"
3325+ };
3326+ if (status > VEC_SIZE(str)-1)
3327+ status = VEC_SIZE(str)-1;
3328+
3329+ return str[status];
3330+}
3331+
3332+
3333+/***********************************************************************
3334+** acx_get_packet_type_string
3335+*/
3336+#if ACX_DEBUG
3337+const char*
3338+acx_get_packet_type_string(u16 fc)
3339+{
3340+ static const char * const mgmt_arr[] = {
3341+ "MGMT/AssocReq", "MGMT/AssocResp", "MGMT/ReassocReq",
3342+ "MGMT/ReassocResp", "MGMT/ProbeReq", "MGMT/ProbeResp",
3343+ "MGMT/UNKNOWN", "MGMT/UNKNOWN", "MGMT/Beacon", "MGMT/ATIM",
3344+ "MGMT/Disassoc", "MGMT/Authen", "MGMT/Deauthen"
3345+ };
3346+ static const char * const ctl_arr[] = {
3347+ "CTL/PSPoll", "CTL/RTS", "CTL/CTS", "CTL/Ack", "CTL/CFEnd",
3348+ "CTL/CFEndCFAck"
3349+ };
3350+ static const char * const data_arr[] = {
3351+ "DATA/DataOnly", "DATA/Data CFAck", "DATA/Data CFPoll",
3352+ "DATA/Data CFAck/CFPoll", "DATA/Null", "DATA/CFAck",
3353+ "DATA/CFPoll", "DATA/CFAck/CFPoll"
3354+ };
3355+ const char *str;
3356+ u8 fstype = (WF_FC_FSTYPE & fc) >> 4;
3357+ u8 ctl;
3358+
3359+ switch (WF_FC_FTYPE & fc) {
3360+ case WF_FTYPE_MGMT:
3361+ if (fstype < VEC_SIZE(mgmt_arr))
3362+ str = mgmt_arr[fstype];
3363+ else
3364+ str = "MGMT/UNKNOWN";
3365+ break;
3366+ case WF_FTYPE_CTL:
3367+ ctl = fstype - 0x0a;
3368+ if (ctl < VEC_SIZE(ctl_arr))
3369+ str = ctl_arr[ctl];
3370+ else
3371+ str = "CTL/UNKNOWN";
3372+ break;
3373+ case WF_FTYPE_DATA:
3374+ if (fstype < VEC_SIZE(data_arr))
3375+ str = data_arr[fstype];
3376+ else
3377+ str = "DATA/UNKNOWN";
3378+ break;
3379+ default:
3380+ str = "UNKNOWN";
3381+ break;
3382+ }
3383+ return str;
3384+}
3385+#endif
3386+
3387+
3388+/***********************************************************************
3389+** acx_wlan_reason_str
3390+*/
3391+static inline const char*
3392+acx_wlan_reason_str(u16 reason)
3393+{
3394+ static const char* const reason_str[] = {
3395+ /* 0 */ "?",
3396+ /* 1 */ "unspecified",
3397+ /* 2 */ "prev auth is not valid",
3398+ /* 3 */ "leaving BBS",
3399+ /* 4 */ "due to inactivity",
3400+ /* 5 */ "AP is busy",
3401+ /* 6 */ "got class 2 frame from non-auth'ed STA",
3402+ /* 7 */ "got class 3 frame from non-assoc'ed STA",
3403+ /* 8 */ "STA has left BSS",
3404+ /* 9 */ "assoc without auth is not allowed",
3405+ /* 10 */ "bad power setting (802.11h)",
3406+ /* 11 */ "bad channel (802.11i)",
3407+ /* 12 */ "?",
3408+ /* 13 */ "invalid IE",
3409+ /* 14 */ "MIC failure",
3410+ /* 15 */ "four-way handshake timeout",
3411+ /* 16 */ "group key handshake timeout",
3412+ /* 17 */ "IE is different",
3413+ /* 18 */ "invalid group cipher",
3414+ /* 19 */ "invalid pairwise cipher",
3415+ /* 20 */ "invalid AKMP",
3416+ /* 21 */ "unsupported RSN version",
3417+ /* 22 */ "invalid RSN IE cap",
3418+ /* 23 */ "802.1x failed",
3419+ /* 24 */ "cipher suite rejected"
3420+ };
3421+ return reason < VEC_SIZE(reason_str) ? reason_str[reason] : "?";
3422+}
3423+
3424+
3425+/***********************************************************************
3426+** acx_cmd_status_str
3427+*/
3428+const char*
3429+acx_cmd_status_str(unsigned int state)
3430+{
3431+ static const char * const cmd_error_strings[] = {
3432+ "Idle",
3433+ "Success",
3434+ "Unknown Command",
3435+ "Invalid Information Element",
3436+ "Channel rejected",
3437+ "Channel invalid in current regulatory domain",
3438+ "MAC invalid",
3439+ "Command rejected (read-only information element)",
3440+ "Command rejected",
3441+ "Already asleep",
3442+ "TX in progress",
3443+ "Already awake",
3444+ "Write only",
3445+ "RX in progress",
3446+ "Invalid parameter",
3447+ "Scan in progress",
3448+ "Failed"
3449+ };
3450+ return state < VEC_SIZE(cmd_error_strings) ?
3451+ cmd_error_strings[state] : "?";
3452+}
3453+
3454+
3455+/***********************************************************************
3456+** get_status_string
3457+*/
3458+static inline const char*
3459+get_status_string(unsigned int status)
3460+{
3461+ /* A bit shortened, but hopefully still understandable */
3462+ static const char * const status_str[] = {
3463+ /* 0 */ "Successful",
3464+ /* 1 */ "Unspecified failure",
3465+ /* 2 */ "reserved",
3466+ /* 3 */ "reserved",
3467+ /* 4 */ "reserved",
3468+ /* 5 */ "reserved",
3469+ /* 6 */ "reserved",
3470+ /* 7 */ "reserved",
3471+ /* 8 */ "reserved",
3472+ /* 9 */ "reserved",
3473+ /*10 */ "Cannot support all requested capabilities in Capability Information field",
3474+ /*11 */ "Reassoc denied (reason outside of 802.11b scope)",
3475+ /*12 */ "Assoc denied (reason outside of 802.11b scope) -- maybe MAC filtering by peer?",
3476+ /*13 */ "Responding station doesnt support specified auth algorithm -- maybe WEP auth Open vs. Restricted?",
3477+ /*14 */ "Auth rejected: wrong transaction sequence number",
3478+ /*15 */ "Auth rejected: challenge failure",
3479+ /*16 */ "Auth rejected: timeout for next frame in sequence",
3480+ /*17 */ "Assoc denied: too many STAs on this AP",
3481+ /*18 */ "Assoc denied: requesting STA doesnt support all data rates in basic set",
3482+ /*19 */ "Assoc denied: requesting STA doesnt support Short Preamble",
3483+ /*20 */ "Assoc denied: requesting STA doesnt support PBCC Modulation",
3484+ /*21 */ "Assoc denied: requesting STA doesnt support Channel Agility"
3485+ /*22 */ "reserved",
3486+ /*23 */ "reserved",
3487+ /*24 */ "reserved",
3488+ /*25 */ "Assoc denied: requesting STA doesnt support Short Slot Time",
3489+ /*26 */ "Assoc denied: requesting STA doesnt support DSSS-OFDM"
3490+ };
3491+
3492+ return status_str[status < VEC_SIZE(status_str) ? status : 2];
3493+}
3494+
3495+
3496+/***********************************************************************
3497+*/
3498+void
3499+acx_log_bad_eid(wlan_hdr_t* hdr, int len, wlan_ie_t* ie_ptr)
3500+{
3501+ if (acx_debug & L_ASSOC) {
3502+ int offset = (u8*)ie_ptr - (u8*)hdr;
3503+ printk("acx: unknown EID %d in mgmt frame at offset %d. IE: ",
3504+ ie_ptr->eid, offset);
3505+ /* IE len can be bogus, IE can extend past packet end. Oh well... */
3506+ acx_dump_bytes(ie_ptr, ie_ptr->len + 2);
3507+ if (acx_debug & L_DATA) {
3508+ printk("frame (%s): ",
3509+ acx_get_packet_type_string(le16_to_cpu(hdr->fc)));
3510+ acx_dump_bytes(hdr, len);
3511+ }
3512+ }
3513+}
3514+
3515+
3516+/***********************************************************************
3517+*/
3518+#if ACX_DEBUG
3519+void
3520+acx_dump_bytes(const void *data, int num)
3521+{
3522+ const u8* ptr = (const u8*)data;
3523+
3524+ if (num <= 0) {
3525+ printk("\n");
3526+ return;
3527+ }
3528+
3529+ while (num >= 16) {
3530+ printk( "%02X %02X %02X %02X %02X %02X %02X %02X "
3531+ "%02X %02X %02X %02X %02X %02X %02X %02X\n",
3532+ ptr[0], ptr[1], ptr[2], ptr[3],
3533+ ptr[4], ptr[5], ptr[6], ptr[7],
3534+ ptr[8], ptr[9], ptr[10], ptr[11],
3535+ ptr[12], ptr[13], ptr[14], ptr[15]);
3536+ num -= 16;
3537+ ptr += 16;
3538+ }
3539+ if (num > 0) {
3540+ while (--num > 0)
3541+ printk("%02X ", *ptr++);
3542+ printk("%02X\n", *ptr);
3543+ }
3544+}
3545+#endif
3546+
3547+
3548+/***********************************************************************
3549+** acx_s_get_firmware_version
3550+*/
3551+void
3552+acx_s_get_firmware_version(acx_device_t *adev)
3553+{
3554+ fw_ver_t fw;
3555+ u8 hexarr[4] = { 0, 0, 0, 0 };
3556+ int hexidx = 0, val = 0;
3557+ const char *num;
3558+ char c;
3559+
3560+ FN_ENTER;
3561+
3562+ memset(fw.fw_id, 'E', FW_ID_SIZE);
3563+ acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV);
3564+ memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE);
3565+ adev->firmware_version[FW_ID_SIZE] = '\0';
3566+
3567+ log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n",
3568+ adev->firmware_version, fw.hw_id);
3569+
3570+ if (strncmp(fw.fw_id, "Rev ", 4) != 0) {
3571+ printk("acx: strange firmware version string "
3572+ "'%s', please report\n", adev->firmware_version);
3573+ adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */
3574+ } else {
3575+ num = &fw.fw_id[4];
3576+ while (1) {
3577+ c = *num++;
3578+ if ((c == '.') || (c == '\0')) {
3579+ hexarr[hexidx++] = val;
3580+ if ((hexidx > 3) || (c == '\0')) /* end? */
3581+ break;
3582+ val = 0;
3583+ continue;
3584+ }
3585+ if ((c >= '0') && (c <= '9'))
3586+ c -= '0';
3587+ else
3588+ c = c - 'a' + (char)10;
3589+ val = val*16 + c;
3590+ }
3591+
3592+ adev->firmware_numver = (u32)(
3593+ (hexarr[0] << 24) | (hexarr[1] << 16)
3594+ | (hexarr[2] << 8) | hexarr[3]);
3595+ log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver);
3596+ }
3597+ if (IS_ACX111(adev)) {
3598+ if (adev->firmware_numver == 0x00010011) {
3599+ /* This one does not survive floodpinging */
3600+ printk("acx: firmware '%s' is known to be buggy, "
3601+ "please upgrade\n", adev->firmware_version);
3602+ }
3603+ }
3604+
3605+ adev->firmware_id = le32_to_cpu(fw.hw_id);
3606+
3607+ /* we're able to find out more detailed chip names now */
3608+ switch (adev->firmware_id & 0xffff0000) {
3609+ case 0x01010000:
3610+ case 0x01020000:
3611+ adev->chip_name = "TNETW1100A";
3612+ break;
3613+ case 0x01030000:
3614+ adev->chip_name = "TNETW1100B";
3615+ break;
3616+ case 0x03000000:
3617+ case 0x03010000:
3618+ adev->chip_name = "TNETW1130";
3619+ break;
3620+ case 0x04030000: /* 0x04030101 is TNETW1450 */
3621+ adev->chip_name = "TNETW1450";
3622+ break;
3623+ default:
3624+ printk("acx: unknown chip ID 0x%08X, "
3625+ "please report\n", adev->firmware_id);
3626+ break;
3627+ }
3628+
3629+ FN_EXIT0;
3630+}
3631+
3632+
3633+/***********************************************************************
3634+** acx_display_hardware_details
3635+**
3636+** Displays hw/fw version, radio type etc...
3637+*/
3638+void
3639+acx_display_hardware_details(acx_device_t *adev)
3640+{
3641+ const char *radio_str, *form_str;
3642+
3643+ FN_ENTER;
3644+
3645+ switch (adev->radio_type) {
3646+ case RADIO_MAXIM_0D:
3647+ radio_str = "Maxim";
3648+ break;
3649+ case RADIO_RFMD_11:
3650+ radio_str = "RFMD";
3651+ break;
3652+ case RADIO_RALINK_15:
3653+ radio_str = "Ralink";
3654+ break;
3655+ case RADIO_RADIA_16:
3656+ radio_str = "Radia";
3657+ break;
3658+ case RADIO_UNKNOWN_17:
3659+ /* TI seems to have a radio which is
3660+ * additionally 802.11a capable, too */
3661+ radio_str = "802.11a/b/g radio?! Please report";
3662+ break;
3663+ case RADIO_UNKNOWN_19:
3664+ radio_str = "A radio used by Safecom cards?! Please report";
3665+ break;
3666+ case RADIO_UNKNOWN_1B:
3667+ radio_str = "An unknown radio used by TNETW1450 USB adapters";
3668+ break;
3669+ default:
3670+ radio_str = "UNKNOWN, please report radio type name!";
3671+ break;
3672+ }
3673+
3674+ switch (adev->form_factor) {
3675+ case 0x00:
3676+ form_str = "unspecified";
3677+ break;
3678+ case 0x01:
3679+ form_str = "(mini-)PCI / CardBus";
3680+ break;
3681+ case 0x02:
3682+ form_str = "USB";
3683+ break;
3684+ case 0x03:
3685+ form_str = "Compact Flash";
3686+ break;
3687+ default:
3688+ form_str = "UNKNOWN, please report";
3689+ break;
3690+ }
3691+
3692+ printk("acx: === chipset %s, radio type 0x%02X (%s), "
3693+ "form factor 0x%02X (%s), EEPROM version 0x%02X: "
3694+ "uploaded firmware '%s' ===\n",
3695+ adev->chip_name, adev->radio_type, radio_str,
3696+ adev->form_factor, form_str, adev->eeprom_version,
3697+ adev->firmware_version);
3698+
3699+ FN_EXIT0;
3700+}
3701+
3702+
3703+/***********************************************************************
3704+*/
3705+int
3706+acx_e_change_mtu(struct net_device *ndev, int mtu)
3707+{
3708+ enum {
3709+ MIN_MTU = 256,
3710+ MAX_MTU = WLAN_DATA_MAXLEN - (ETH_HLEN)
3711+ };
3712+
3713+ if (mtu < MIN_MTU || mtu > MAX_MTU)
3714+ return -EINVAL;
3715+
3716+ ndev->mtu = mtu;
3717+ return 0;
3718+}
3719+
3720+
3721+/***********************************************************************
3722+** acx_e_get_stats, acx_e_get_wireless_stats
3723+*/
3724+struct net_device_stats*
3725+acx_e_get_stats(struct net_device *ndev)
3726+{
3727+ acx_device_t *adev = ndev2adev(ndev);
3728+ return &adev->stats;
3729+}
3730+
3731+struct iw_statistics*
3732+acx_e_get_wireless_stats(struct net_device *ndev)
3733+{
3734+ acx_device_t *adev = ndev2adev(ndev);
3735+ return &adev->wstats;
3736+}
3737+
3738+
3739+/***********************************************************************
3740+** maps acx111 tx descr rate field to acx100 one
3741+*/
3742+const u8
3743+acx_bitpos2rate100[] = {
3744+ RATE100_1 ,/* 0 */
3745+ RATE100_2 ,/* 1 */
3746+ RATE100_5 ,/* 2 */
3747+ RATE100_2 ,/* 3, should not happen */
3748+ RATE100_2 ,/* 4, should not happen */
3749+ RATE100_11 ,/* 5 */
3750+ RATE100_2 ,/* 6, should not happen */
3751+ RATE100_2 ,/* 7, should not happen */
3752+ RATE100_22 ,/* 8 */
3753+ RATE100_2 ,/* 9, should not happen */
3754+ RATE100_2 ,/* 10, should not happen */
3755+ RATE100_2 ,/* 11, should not happen */
3756+ RATE100_2 ,/* 12, should not happen */
3757+ RATE100_2 ,/* 13, should not happen */
3758+ RATE100_2 ,/* 14, should not happen */
3759+ RATE100_2 ,/* 15, should not happen */
3760+};
3761+
3762+u8
3763+acx_rate111to100(u16 r) {
3764+ return acx_bitpos2rate100[highest_bit(r)];
3765+}
3766+
3767+
3768+/***********************************************************************
3769+** Calculate level like the feb 2003 windows driver seems to do
3770+*/
3771+static u8
3772+acx_signal_to_winlevel(u8 rawlevel)
3773+{
3774+ /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */
3775+ u8 winlevel = ((4 + (rawlevel * 5)) / 8);
3776+
3777+ if (winlevel > 100)
3778+ winlevel = 100;
3779+ return winlevel;
3780+}
3781+
3782+u8
3783+acx_signal_determine_quality(u8 signal, u8 noise)
3784+{
3785+ int qual;
3786+
3787+ qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2;
3788+
3789+ if (qual > 100)
3790+ return 100;
3791+ if (qual < 0)
3792+ return 0;
3793+ return qual;
3794+}
3795+
3796+
3797+/***********************************************************************
3798+** Interrogate/configure commands
3799+*/
3800+
3801+/* FIXME: the lengths given here probably aren't always correct.
3802+ * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4",
3803+ * unless the firmware actually expects a different length than the struct length */
3804+static const u16
3805+acx100_ie_len[] = {
3806+ 0,
3807+ ACX100_IE_ACX_TIMER_LEN,
3808+ sizeof(acx100_ie_powersave_t)-4, /* is that 6 or 8??? */
3809+ ACX1xx_IE_QUEUE_CONFIG_LEN,
3810+ ACX100_IE_BLOCK_SIZE_LEN,
3811+ ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
3812+ ACX1xx_IE_RATE_FALLBACK_LEN,
3813+ ACX100_IE_WEP_OPTIONS_LEN,
3814+ ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
3815+ 0,
3816+ ACX1xx_IE_ASSOC_ID_LEN,
3817+ 0,
3818+ ACX111_IE_CONFIG_OPTIONS_LEN,
3819+ ACX1xx_IE_FWREV_LEN,
3820+ ACX1xx_IE_FCS_ERROR_COUNT_LEN,
3821+ ACX1xx_IE_MEDIUM_USAGE_LEN,
3822+ ACX1xx_IE_RXCONFIG_LEN,
3823+ 0,
3824+ 0,
3825+ sizeof(fw_stats_t)-4,
3826+ 0,
3827+ ACX1xx_IE_FEATURE_CONFIG_LEN,
3828+ ACX111_IE_KEY_CHOOSE_LEN,
3829+ ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
3830+ ACX1FF_IE_WONE_CONFIG_LEN,
3831+ 0,
3832+ ACX1FF_IE_TID_CONFIG_LEN,
3833+ 0,
3834+ 0,
3835+ 0,
3836+ ACX1FF_IE_CALIB_ASSESSMENT_LEN,
3837+ ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
3838+ ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
3839+ ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
3840+ 0,
3841+ ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
3842+ ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
3843+ ACX1FF_IE_CCA_THRESHOLD_LEN,
3844+ ACX1FF_IE_EVENT_MASK_LEN,
3845+ ACX1FF_IE_DTIM_PERIOD_LEN,
3846+ 0,
3847+ ACX1FF_IE_ACI_CONFIG_SET_LEN,
3848+ 0,
3849+ 0,
3850+ 0,
3851+ 0,
3852+ 0,
3853+ 0,
3854+ ACX1FF_IE_EEPROM_VER_LEN,
3855+};
3856+
3857+static const u16
3858+acx100_ie_len_dot11[] = {
3859+ 0,
3860+ ACX1xx_IE_DOT11_STATION_ID_LEN,
3861+ 0,
3862+ ACX100_IE_DOT11_BEACON_PERIOD_LEN,
3863+ ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
3864+ ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
3865+ ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
3866+ ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
3867+ ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
3868+ 0,
3869+ ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
3870+ ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
3871+ 0,
3872+ ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
3873+ ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
3874+ ACX100_IE_DOT11_ED_THRESHOLD_LEN,
3875+ ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
3876+ 0,
3877+ 0,
3878+ 0,
3879+};
3880+
3881+static const u16
3882+acx111_ie_len[] = {
3883+ 0,
3884+ ACX100_IE_ACX_TIMER_LEN,
3885+ sizeof(acx111_ie_powersave_t)-4,
3886+ ACX1xx_IE_QUEUE_CONFIG_LEN,
3887+ ACX100_IE_BLOCK_SIZE_LEN,
3888+ ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN,
3889+ ACX1xx_IE_RATE_FALLBACK_LEN,
3890+ ACX100_IE_WEP_OPTIONS_LEN,
3891+ ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */
3892+ 0,
3893+ ACX1xx_IE_ASSOC_ID_LEN,
3894+ 0,
3895+ ACX111_IE_CONFIG_OPTIONS_LEN,
3896+ ACX1xx_IE_FWREV_LEN,
3897+ ACX1xx_IE_FCS_ERROR_COUNT_LEN,
3898+ ACX1xx_IE_MEDIUM_USAGE_LEN,
3899+ ACX1xx_IE_RXCONFIG_LEN,
3900+ 0,
3901+ 0,
3902+ sizeof(fw_stats_t)-4,
3903+ 0,
3904+ ACX1xx_IE_FEATURE_CONFIG_LEN,
3905+ ACX111_IE_KEY_CHOOSE_LEN,
3906+ ACX1FF_IE_MISC_CONFIG_TABLE_LEN,
3907+ ACX1FF_IE_WONE_CONFIG_LEN,
3908+ 0,
3909+ ACX1FF_IE_TID_CONFIG_LEN,
3910+ 0,
3911+ 0,
3912+ 0,
3913+ ACX1FF_IE_CALIB_ASSESSMENT_LEN,
3914+ ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN,
3915+ ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN,
3916+ ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN,
3917+ 0,
3918+ ACX1FF_IE_PACKET_DETECT_THRESH_LEN,
3919+ ACX1FF_IE_TX_CONFIG_OPTIONS_LEN,
3920+ ACX1FF_IE_CCA_THRESHOLD_LEN,
3921+ ACX1FF_IE_EVENT_MASK_LEN,
3922+ ACX1FF_IE_DTIM_PERIOD_LEN,
3923+ 0,
3924+ ACX1FF_IE_ACI_CONFIG_SET_LEN,
3925+ 0,
3926+ 0,
3927+ 0,
3928+ 0,
3929+ 0,
3930+ 0,
3931+ ACX1FF_IE_EEPROM_VER_LEN,
3932+};
3933+
3934+static const u16
3935+acx111_ie_len_dot11[] = {
3936+ 0,
3937+ ACX1xx_IE_DOT11_STATION_ID_LEN,
3938+ 0,
3939+ ACX100_IE_DOT11_BEACON_PERIOD_LEN,
3940+ ACX1xx_IE_DOT11_DTIM_PERIOD_LEN,
3941+ ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN,
3942+ ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN,
3943+ ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN,
3944+ ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
3945+ 0,
3946+ ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN,
3947+ ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN,
3948+ 0,
3949+ ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN,
3950+ ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN,
3951+ ACX100_IE_DOT11_ED_THRESHOLD_LEN,
3952+ ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN,
3953+ 0,
3954+ 0,
3955+ 0,
3956+};
3957+
3958+
3959+#undef FUNC
3960+#define FUNC "configure"
3961+#if !ACX_DEBUG
3962+int
3963+acx_s_configure(acx_device_t *adev, void *pdr, int type)
3964+{
3965+#else
3966+int
3967+acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* typestr)
3968+{
3969+#endif
3970+ u16 len;
3971+ int res;
3972+
3973+ if (type < 0x1000)
3974+ len = adev->ie_len[type];
3975+ else
3976+ len = adev->ie_len_dot11[type - 0x1000];
3977+
3978+ log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len);
3979+ if (unlikely(!len)) {
3980+ log(L_DEBUG, "zero-length type %s?!\n", typestr);
3981+ }
3982+
3983+ ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type);
3984+ ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len);
3985+ res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4);
3986+ if (unlikely(OK != res)) {
3987+#if ACX_DEBUG
3988+ printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr);
3989+#else
3990+ printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type);
3991+#endif
3992+ /* dump_stack() is already done in issue_cmd() */
3993+ }
3994+ return res;
3995+}
3996+
3997+#undef FUNC
3998+#define FUNC "interrogate"
3999+#if !ACX_DEBUG
4000+int
4001+acx_s_interrogate(acx_device_t *adev, void *pdr, int type)
4002+{
4003+#else
4004+int
4005+acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type,
4006+ const char* typestr)
4007+{
4008+#endif
4009+ u16 len;
4010+ int res;
4011+
4012+ /* FIXME: no check whether this exceeds the array yet.
4013+ * We should probably remember the number of entries... */
4014+ if (type < 0x1000)
4015+ len = adev->ie_len[type];
4016+ else
4017+ len = adev->ie_len_dot11[type-0x1000];
4018+
4019+ log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len);
4020+
4021+ ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type);
4022+ ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len);
4023+ res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4);
4024+ if (unlikely(OK != res)) {
4025+#if ACX_DEBUG
4026+ printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr);
4027+#else
4028+ printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type);
4029+#endif
4030+ /* dump_stack() is already done in issue_cmd() */
4031+ }
4032+ return res;
4033+}
4034+
4035+#if CMD_DISCOVERY
4036+void
4037+great_inquisitor(acx_device_t *adev)
4038+{
4039+ static struct {
4040+ u16 type;
4041+ u16 len;
4042+ /* 0x200 was too large here: */
4043+ u8 data[0x100 - 4];
4044+ } ACX_PACKED ie;
4045+ u16 type;
4046+
4047+ FN_ENTER;
4048+
4049+ /* 0..0x20, 0x1000..0x1020 */
4050+ for (type = 0; type <= 0x1020; type++) {
4051+ if (type == 0x21)
4052+ type = 0x1000;
4053+ ie.type = cpu_to_le16(type);
4054+ ie.len = cpu_to_le16(sizeof(ie) - 4);
4055+ acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie));
4056+ }
4057+ FN_EXIT0;
4058+}
4059+#endif
4060+
4061+
4062+#ifdef CONFIG_PROC_FS
4063+/***********************************************************************
4064+** /proc files
4065+*/
4066+/***********************************************************************
4067+** acx_l_proc_output
4068+** Generate content for our /proc entry
4069+**
4070+** Arguments:
4071+** buf is a pointer to write output to
4072+** adev is the usual pointer to our private struct acx_device
4073+** Returns:
4074+** number of bytes actually written to buf
4075+** Side effects:
4076+** none
4077+*/
4078+static int
4079+acx_l_proc_output(char *buf, acx_device_t *adev)
4080+{
4081+ char *p = buf;
4082+ int i;
4083+
4084+ FN_ENTER;
4085+
4086+ p += sprintf(p,
4087+ "acx driver version:\t\t" ACX_RELEASE "\n"
4088+ "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n"
4089+ "chip name:\t\t\t%s (0x%08X)\n"
4090+ "radio type:\t\t\t0x%02X\n"
4091+ "form factor:\t\t\t0x%02X\n"
4092+ "EEPROM version:\t\t\t0x%02X\n"
4093+ "firmware version:\t\t%s (0x%08X)\n",
4094+ adev->chip_name, adev->firmware_id,
4095+ adev->radio_type,
4096+ adev->form_factor,
4097+ adev->eeprom_version,
4098+ adev->firmware_version, adev->firmware_numver);
4099+
4100+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
4101+ struct client *bss = &adev->sta_list[i];
4102+ if (!bss->used) continue;
4103+ p += sprintf(p, "BSS %u BSSID "MACSTR" ESSID %s channel %u "
4104+ "Cap 0x%X SIR %u SNR %u\n",
4105+ i, MAC(bss->bssid), (char*)bss->essid, bss->channel,
4106+ bss->cap_info, bss->sir, bss->snr);
4107+ }
4108+ p += sprintf(p, "status:\t\t\t%u (%s)\n",
4109+ adev->status, acx_get_status_name(adev->status));
4110+
4111+ FN_EXIT1(p - buf);
4112+ return p - buf;
4113+}
4114+
4115+
4116+/***********************************************************************
4117+*/
4118+static int
4119+acx_s_proc_diag_output(char *buf, acx_device_t *adev)
4120+{
4121+ char *p = buf;
4122+ unsigned long flags;
4123+ unsigned int len = 0, partlen;
4124+ u32 temp1, temp2;
4125+ u8 *st, *st_end;
4126+#ifdef __BIG_ENDIAN
4127+ u8 *st2;
4128+#endif
4129+ fw_stats_t *fw_stats;
4130+ char *part_str = NULL;
4131+ fw_stats_tx_t *tx = NULL;
4132+ fw_stats_rx_t *rx = NULL;
4133+ fw_stats_dma_t *dma = NULL;
4134+ fw_stats_irq_t *irq = NULL;
4135+ fw_stats_wep_t *wep = NULL;
4136+ fw_stats_pwr_t *pwr = NULL;
4137+ fw_stats_mic_t *mic = NULL;
4138+ fw_stats_aes_t *aes = NULL;
4139+ fw_stats_event_t *evt = NULL;
4140+
4141+ FN_ENTER;
4142+
4143+ acx_lock(adev, flags);
4144+
4145+#if defined (ACX_MEM)
4146+ p = acxmem_s_proc_diag_output(p, adev);
4147+#else
4148+ if (IS_PCI(adev))
4149+ p = acxpci_s_proc_diag_output(p, adev);
4150+#endif
4151+
4152+ p += sprintf(p,
4153+ "\n"
4154+ "** network status **\n"
4155+ "dev_state_mask 0x%04X\n"
4156+ "status %u (%s), "
4157+ "mode %u, channel %u, "
4158+ "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ",
4159+ adev->dev_state_mask,
4160+ adev->status, acx_get_status_name(adev->status),
4161+ adev->mode, adev->channel,
4162+ adev->reg_dom_id, adev->reg_dom_chanmask
4163+ );
4164+ p += sprintf(p,
4165+ "ESSID \"%s\", essid_active %d, essid_len %d, "
4166+ "essid_for_assoc \"%s\", nick \"%s\"\n"
4167+ "WEP ena %d, restricted %d, idx %d\n",
4168+ adev->essid, adev->essid_active, (int)adev->essid_len,
4169+ adev->essid_for_assoc, adev->nick,
4170+ adev->wep_enabled, adev->wep_restricted,
4171+ adev->wep_current_index);
4172+ p += sprintf(p, "dev_addr "MACSTR"\n", MAC(adev->dev_addr));
4173+ p += sprintf(p, "bssid "MACSTR"\n", MAC(adev->bssid));
4174+ p += sprintf(p, "ap_filter "MACSTR"\n", MAC(adev->ap));
4175+
4176+ p += sprintf(p,
4177+ "\n"
4178+ "** PHY status **\n"
4179+ "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
4180+ "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
4181+ "rate_basic 0x%04X, rate_oper 0x%04X\n"
4182+ "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
4183+ "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
4184+ adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
4185+ adev->sensitivity, adev->antenna, adev->ed_threshold, adev->cca, adev->preamble_mode,
4186+ adev->rate_basic, adev->rate_oper,
4187+ adev->rts_threshold, adev->frag_threshold, adev->short_retry, adev->long_retry,
4188+ adev->msdu_lifetime, adev->listen_interval, adev->beacon_interval);
4189+
4190+ acx_unlock(adev, flags);
4191+
4192+ p += sprintf(p,
4193+ "\n"
4194+ "** Firmware **\n"
4195+ "NOTE: version dependent statistics layout, "
4196+ "please report if you suspect wrong parsing!\n"
4197+ "\n"
4198+ "version \"%s\"\n", adev->firmware_version);
4199+
4200+ /* TODO: may replace kmalloc/memset with kzalloc once
4201+ * Linux 2.6.14 is widespread */
4202+ fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL);
4203+ if (!fw_stats) {
4204+ FN_EXIT1(0);
4205+ return 0;
4206+ }
4207+ memset(fw_stats, 0, sizeof(*fw_stats));
4208+
4209+ st = (u8 *)fw_stats;
4210+
4211+ part_str = "statistics query command";
4212+
4213+ if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS))
4214+ goto fw_stats_end;
4215+
4216+ st += sizeof(u16);
4217+ len = *(u16 *)st;
4218+
4219+ if (len > sizeof(*fw_stats)) {
4220+ p += sprintf(p,
4221+ "firmware version with bigger fw_stats struct detected\n"
4222+ "(%u vs. %u), please report\n", len, sizeof(fw_stats_t));
4223+ if (len > sizeof(*fw_stats)) {
4224+ p += sprintf(p, "struct size exceeded allocation!\n");
4225+ len = sizeof(*fw_stats);
4226+ }
4227+ }
4228+ st += sizeof(u16);
4229+ st_end = st - 2*sizeof(u16) + len;
4230+
4231+#ifdef __BIG_ENDIAN
4232+ /* let's make one bold assumption here:
4233+ * (hopefully!) *all* statistics fields are u32 only,
4234+ * thus if we need to make endianness corrections
4235+ * we can simply do them in one go, in advance */
4236+ st2 = (u8 *)fw_stats;
4237+ for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4)
4238+ *(u32 *)st2 = le32_to_cpu(*(u32 *)st2);
4239+#endif
4240+
4241+ part_str = "Rx/Tx";
4242+
4243+ /* directly at end of a struct part? --> no error! */
4244+ if (st == st_end)
4245+ goto fw_stats_end;
4246+
4247+ tx = (fw_stats_tx_t *)st;
4248+ st += sizeof(fw_stats_tx_t);
4249+ rx = (fw_stats_rx_t *)st;
4250+ st += sizeof(fw_stats_rx_t);
4251+ partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t);
4252+
4253+ if (IS_ACX100(adev)) {
4254+ /* at least ACX100 PCI F/W 1.9.8.b
4255+ * and ACX100 USB F/W 1.0.7-USB
4256+ * don't have those two fields... */
4257+ st -= 2*sizeof(u32);
4258+
4259+ /* our parsing doesn't quite match this firmware yet,
4260+ * log failure */
4261+ if (st > st_end)
4262+ goto fw_stats_fail;
4263+ temp1 = temp2 = 999999999;
4264+ } else {
4265+ if (st > st_end)
4266+ goto fw_stats_fail;
4267+ temp1 = rx->rx_aci_events;
4268+ temp2 = rx->rx_aci_resets;
4269+ }
4270+
4271+ p += sprintf(p,
4272+ "%s:\n"
4273+ " tx_desc_overfl %u\n"
4274+ " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n"
4275+ " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n"
4276+ " rx_aci_events %u, rx_aci_resets %u\n",
4277+ part_str,
4278+ tx->tx_desc_of,
4279+ rx->rx_oom,
4280+ rx->rx_hdr_of,
4281+ rx->rx_hw_stuck,
4282+ rx->rx_dropped_frame,
4283+ rx->rx_frame_ptr_err,
4284+ rx->rx_xfr_hint_trig,
4285+ temp1,
4286+ temp2);
4287+
4288+ part_str = "DMA";
4289+
4290+ if (st == st_end)
4291+ goto fw_stats_end;
4292+
4293+ dma = (fw_stats_dma_t *)st;
4294+ partlen = sizeof(fw_stats_dma_t);
4295+ st += partlen;
4296+
4297+ if (st > st_end)
4298+ goto fw_stats_fail;
4299+
4300+ p += sprintf(p,
4301+ "%s:\n"
4302+ " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n",
4303+ part_str,
4304+ dma->rx_dma_req,
4305+ dma->rx_dma_err,
4306+ dma->tx_dma_req,
4307+ dma->tx_dma_err);
4308+
4309+ part_str = "IRQ";
4310+
4311+ if (st == st_end)
4312+ goto fw_stats_end;
4313+
4314+ irq = (fw_stats_irq_t *)st;
4315+ partlen = sizeof(fw_stats_irq_t);
4316+ st += partlen;
4317+
4318+ if (st > st_end)
4319+ goto fw_stats_fail;
4320+
4321+ p += sprintf(p,
4322+ "%s:\n"
4323+ " cmd_cplt %u, fiq %u\n"
4324+ " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n"
4325+ " irqs %u, tx_procs %u, decrypt_done %u\n"
4326+ " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n"
4327+ " commands %u, rx_procs %u, hw_pm_mode_changes %u\n"
4328+ " host_acks %u, pci_pm %u, acm_wakeups %u\n",
4329+ part_str,
4330+ irq->cmd_cplt,
4331+ irq->fiq,
4332+ irq->rx_hdrs,
4333+ irq->rx_cmplt,
4334+ irq->rx_mem_of,
4335+ irq->rx_rdys,
4336+ irq->irqs,
4337+ irq->tx_procs,
4338+ irq->decrypt_done,
4339+ irq->dma_0_done,
4340+ irq->dma_1_done,
4341+ irq->tx_exch_complet,
4342+ irq->commands,
4343+ irq->rx_procs,
4344+ irq->hw_pm_mode_changes,
4345+ irq->host_acks,
4346+ irq->pci_pm,
4347+ irq->acm_wakeups);
4348+
4349+ part_str = "WEP";
4350+
4351+ if (st == st_end)
4352+ goto fw_stats_end;
4353+
4354+ wep = (fw_stats_wep_t *)st;
4355+ partlen = sizeof(fw_stats_wep_t);
4356+ st += partlen;
4357+
4358+ if (
4359+ (IS_PCI(adev) && IS_ACX100(adev))
4360+ || (IS_USB(adev) && IS_ACX100(adev))
4361+ || (IS_MEM(adev) && IS_ACX100(adev))
4362+ ) {
4363+ /* at least ACX100 PCI F/W 1.9.8.b,
4364+ * ACX100 USB F/W 1.0.7-USB
4365+ * and ACX100 Generic Slave F/W 1.10.7.K
4366+ * don't have those two fields...
4367+ */
4368+ st -= 2*sizeof(u32);
4369+ if (st > st_end)
4370+ goto fw_stats_fail;
4371+ temp1 = temp2 = 999999999;
4372+ } else {
4373+ if (st > st_end)
4374+ goto fw_stats_fail;
4375+ temp1 = wep->wep_pkt_decrypt;
4376+ temp2 = wep->wep_decrypt_irqs;
4377+ }
4378+
4379+ p += sprintf(p,
4380+ "%s:\n"
4381+ " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n"
4382+ " wep_key_not_found %u, wep_decrypt_fail %u\n"
4383+ " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n",
4384+ part_str,
4385+ wep->wep_key_count,
4386+ wep->wep_default_key_count,
4387+ wep->dot11_def_key_mib,
4388+ wep->wep_key_not_found,
4389+ wep->wep_decrypt_fail,
4390+ temp1,
4391+ temp2);
4392+
4393+ part_str = "power";
4394+
4395+ if (st == st_end)
4396+ goto fw_stats_end;
4397+
4398+ pwr = (fw_stats_pwr_t *)st;
4399+ partlen = sizeof(fw_stats_pwr_t);
4400+ st += partlen;
4401+
4402+ if (st > st_end)
4403+ goto fw_stats_fail;
4404+
4405+ p += sprintf(p,
4406+ "%s:\n"
4407+ " tx_start_ctr %u, no_ps_tx_too_short %u\n"
4408+ " rx_start_ctr %u, no_ps_rx_too_short %u\n"
4409+ " lppd_started %u\n"
4410+ " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n",
4411+ part_str,
4412+ pwr->tx_start_ctr,
4413+ pwr->no_ps_tx_too_short,
4414+ pwr->rx_start_ctr,
4415+ pwr->no_ps_rx_too_short,
4416+ pwr->lppd_started,
4417+ pwr->no_lppd_too_noisy,
4418+ pwr->no_lppd_too_short,
4419+ pwr->no_lppd_matching_frame);
4420+
4421+ part_str = "MIC";
4422+
4423+ if (st == st_end)
4424+ goto fw_stats_end;
4425+
4426+ mic = (fw_stats_mic_t *)st;
4427+ partlen = sizeof(fw_stats_mic_t);
4428+ st += partlen;
4429+
4430+ if (st > st_end)
4431+ goto fw_stats_fail;
4432+
4433+ p += sprintf(p,
4434+ "%s:\n"
4435+ " mic_rx_pkts %u, mic_calc_fail %u\n",
4436+ part_str,
4437+ mic->mic_rx_pkts,
4438+ mic->mic_calc_fail);
4439+
4440+ part_str = "AES";
4441+
4442+ if (st == st_end)
4443+ goto fw_stats_end;
4444+
4445+ aes = (fw_stats_aes_t *)st;
4446+ partlen = sizeof(fw_stats_aes_t);
4447+ st += partlen;
4448+
4449+ if (st > st_end)
4450+ goto fw_stats_fail;
4451+
4452+ p += sprintf(p,
4453+ "%s:\n"
4454+ " aes_enc_fail %u, aes_dec_fail %u\n"
4455+ " aes_enc_pkts %u, aes_dec_pkts %u\n"
4456+ " aes_enc_irq %u, aes_dec_irq %u\n",
4457+ part_str,
4458+ aes->aes_enc_fail,
4459+ aes->aes_dec_fail,
4460+ aes->aes_enc_pkts,
4461+ aes->aes_dec_pkts,
4462+ aes->aes_enc_irq,
4463+ aes->aes_dec_irq);
4464+
4465+ part_str = "event";
4466+
4467+ if (st == st_end)
4468+ goto fw_stats_end;
4469+
4470+ evt = (fw_stats_event_t *)st;
4471+ partlen = sizeof(fw_stats_event_t);
4472+ st += partlen;
4473+
4474+ if (st > st_end)
4475+ goto fw_stats_fail;
4476+
4477+ p += sprintf(p,
4478+ "%s:\n"
4479+ " heartbeat %u, calibration %u\n"
4480+ " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n"
4481+ " oom_late %u\n"
4482+ " phy_tx_err %u, tx_stuck %u\n",
4483+ part_str,
4484+ evt->heartbeat,
4485+ evt->calibration,
4486+ evt->rx_mismatch,
4487+ evt->rx_mem_empty,
4488+ evt->rx_pool,
4489+ evt->oom_late,
4490+ evt->phy_tx_err,
4491+ evt->tx_stuck);
4492+
4493+ if (st < st_end)
4494+ goto fw_stats_bigger;
4495+
4496+ goto fw_stats_end;
4497+
4498+fw_stats_fail:
4499+ st -= partlen;
4500+ p += sprintf(p,
4501+ "failed at %s part (size %u), offset %u (struct size %u), "
4502+ "please report\n", part_str, partlen,
4503+ (int)st - (int)fw_stats, len);
4504+
4505+fw_stats_bigger:
4506+ for (; st < st_end; st += 4)
4507+ p += sprintf(p,
4508+ "UNKN%3d: %u\n", (int)st - (int)fw_stats, *(u32 *)st);
4509+
4510+fw_stats_end:
4511+ kfree(fw_stats);
4512+
4513+ FN_EXIT1(p - buf);
4514+ return p - buf;
4515+}
4516+
4517+
4518+/***********************************************************************
4519+*/
4520+static int
4521+acx_s_proc_phy_output(char *buf, acx_device_t *adev)
4522+{
4523+ char *p = buf;
4524+ int i;
4525+
4526+ FN_ENTER;
4527+
4528+ /*
4529+ if (RADIO_RFMD_11 != adev->radio_type) {
4530+ printk("sorry, not yet adapted for radio types "
4531+ "other than RFMD, please verify "
4532+ "PHY size etc. first!\n");
4533+ goto end;
4534+ }
4535+ */
4536+
4537+ /* The PHY area is only 0x80 bytes long; further pages after that
4538+ * only have some page number registers with altered value,
4539+ * all other registers remain the same. */
4540+ for (i = 0; i < 0x80; i++) {
4541+ acx_s_read_phy_reg(adev, i, p++);
4542+ }
4543+
4544+ FN_EXIT1(p - buf);
4545+ return p - buf;
4546+}
4547+
4548+
4549+/***********************************************************************
4550+** acx_e_read_proc_XXXX
4551+** Handle our /proc entry
4552+**
4553+** Arguments:
4554+** standard kernel read_proc interface
4555+** Returns:
4556+** number of bytes written to buf
4557+** Side effects:
4558+** none
4559+*/
4560+static int
4561+acx_e_read_proc(char *buf, char **start, off_t offset, int count,
4562+ int *eof, void *data)
4563+{
4564+ acx_device_t *adev = (acx_device_t*)data;
4565+ unsigned long flags;
4566+ int length;
4567+
4568+ FN_ENTER;
4569+
4570+ acx_sem_lock(adev);
4571+ acx_lock(adev, flags);
4572+ /* fill buf */
4573+ length = acx_l_proc_output(buf, adev);
4574+ acx_unlock(adev, flags);
4575+ acx_sem_unlock(adev);
4576+
4577+ /* housekeeping */
4578+ if (length <= offset + count)
4579+ *eof = 1;
4580+ *start = buf + offset;
4581+ length -= offset;
4582+ if (length > count)
4583+ length = count;
4584+ if (length < 0)
4585+ length = 0;
4586+ FN_EXIT1(length);
4587+ return length;
4588+}
4589+
4590+static char _buf[32768];
4591+static int
4592+acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count,
4593+ int *eof, void *data)
4594+{
4595+ acx_device_t *adev = (acx_device_t*)data;
4596+ int length;
4597+
4598+ FN_ENTER;
4599+
4600+ acx_sem_lock(adev);
4601+ /* fill buf */
4602+ length = acx_s_proc_diag_output(_buf, adev);
4603+ acx_sem_unlock(adev);
4604+
4605+ memcpy(buf, _buf + offset, count);
4606+
4607+ /* housekeeping */
4608+ if (length <= offset + count)
4609+ *eof = 1;
4610+ *start = count;
4611+ length -= offset;
4612+ if (length > count)
4613+ length = count;
4614+ if (length < 0)
4615+ length = 0;
4616+ FN_EXIT1(length);
4617+ return length;
4618+}
4619+
4620+static int
4621+acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count,
4622+ int *eof, void *data)
4623+{
4624+ acx_device_t *adev = (acx_device_t*)data;
4625+ int length;
4626+
4627+ FN_ENTER;
4628+
4629+ /* fill buf */
4630+ length = 0;
4631+#if defined (ACX_MEM)
4632+ acx_sem_lock(adev);
4633+ length = acxmem_proc_eeprom_output(buf, adev);
4634+ acx_sem_unlock(adev);
4635+#else
4636+ if (IS_PCI(adev)) {
4637+ acx_sem_lock(adev);
4638+ length = acxpci_proc_eeprom_output(buf, adev);
4639+ acx_sem_unlock(adev);
4640+ }
4641+#endif
4642+
4643+ /* housekeeping */
4644+ if (length <= offset + count)
4645+ *eof = 1;
4646+ *start = buf + offset;
4647+ length -= offset;
4648+ if (length > count)
4649+ length = count;
4650+ if (length < 0)
4651+ length = 0;
4652+ FN_EXIT1(length);
4653+ return length;
4654+}
4655+
4656+static int
4657+acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count,
4658+ int *eof, void *data)
4659+{
4660+ acx_device_t *adev = (acx_device_t*)data;
4661+ int length;
4662+
4663+ FN_ENTER;
4664+
4665+ acx_sem_lock(adev);
4666+ /* fill buf */
4667+ length = acx_s_proc_phy_output(buf, adev);
4668+ acx_sem_unlock(adev);
4669+
4670+ /* housekeeping */
4671+ if (length <= offset + count)
4672+ *eof = 1;
4673+ *start = buf + offset;
4674+ length -= offset;
4675+ if (length > count)
4676+ length = count;
4677+ if (length < 0)
4678+ length = 0;
4679+ FN_EXIT1(length);
4680+ return length;
4681+}
4682+
4683+
4684+/***********************************************************************
4685+** /proc files registration
4686+*/
4687+static const char * const
4688+proc_files[] = { "", "_diag", "_eeprom", "_phy" };
4689+
4690+static read_proc_t * const
4691+proc_funcs[] = {
4692+ acx_e_read_proc,
4693+ acx_e_read_proc_diag,
4694+ acx_e_read_proc_eeprom,
4695+ acx_e_read_proc_phy
4696+};
4697+
4698+static int
4699+manage_proc_entries(const struct net_device *ndev, int remove)
4700+{
4701+ acx_device_t *adev = ndev2adev((struct net_device *)ndev);
4702+ char procbuf[80];
4703+ int i;
4704+
4705+ for (i = 0; i < VEC_SIZE(proc_files); i++) {
4706+ snprintf(procbuf, sizeof(procbuf),
4707+ "driver/acx_%s%s", ndev->name, proc_files[i]);
4708+ log(L_INIT, "%sing /proc entry %s\n",
4709+ remove ? "remov" : "creat", procbuf);
4710+ if (!remove) {
4711+ if (!create_proc_read_entry(procbuf, 0, 0, proc_funcs[i], adev)) {
4712+ printk("acx: cannot register /proc entry %s\n", procbuf);
4713+ return NOT_OK;
4714+ }
4715+ } else {
4716+ remove_proc_entry(procbuf, NULL);
4717+ }
4718+ }
4719+ return OK;
4720+}
4721+
4722+int
4723+acx_proc_register_entries(const struct net_device *ndev)
4724+{
4725+ return manage_proc_entries(ndev, 0);
4726+}
4727+
4728+int
4729+acx_proc_unregister_entries(const struct net_device *ndev)
4730+{
4731+ return manage_proc_entries(ndev, 1);
4732+}
4733+#endif /* CONFIG_PROC_FS */
4734+
4735+
4736+/***********************************************************************
4737+** acx_cmd_join_bssid
4738+**
4739+** Common code for both acx100 and acx111.
4740+*/
4741+/* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */
4742+static const u8
4743+bitpos2genframe_txrate[] = {
4744+ 10, /* 0. 1 Mbit/s */
4745+ 20, /* 1. 2 Mbit/s */
4746+ 55, /* 2. 5.5 Mbit/s */
4747+ 0x0B, /* 3. 6 Mbit/s */
4748+ 0x0F, /* 4. 9 Mbit/s */
4749+ 110, /* 5. 11 Mbit/s */
4750+ 0x0A, /* 6. 12 Mbit/s */
4751+ 0x0E, /* 7. 18 Mbit/s */
4752+ 220, /* 8. 22 Mbit/s */
4753+ 0x09, /* 9. 24 Mbit/s */
4754+ 0x0D, /* 10. 36 Mbit/s */
4755+ 0x08, /* 11. 48 Mbit/s */
4756+ 0x0C, /* 12. 54 Mbit/s */
4757+ 10, /* 13. 1 Mbit/s, should never happen */
4758+ 10, /* 14. 1 Mbit/s, should never happen */
4759+ 10, /* 15. 1 Mbit/s, should never happen */
4760+};
4761+
4762+/* Looks scary, eh?
4763+** Actually, each one compiled into one AND and one SHIFT,
4764+** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */
4765+static inline unsigned int
4766+rate111to5bits(unsigned int rate)
4767+{
4768+ return (rate & 0x7)
4769+ | ( (rate & RATE111_11) / (RATE111_11/JOINBSS_RATES_11) )
4770+ | ( (rate & RATE111_22) / (RATE111_22/JOINBSS_RATES_22) )
4771+ ;
4772+}
4773+
4774+static void
4775+acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid)
4776+{
4777+ acx_joinbss_t tmp;
4778+ int dtim_interval;
4779+ int i;
4780+
4781+ if (mac_is_zero(bssid))
4782+ return;
4783+
4784+ FN_ENTER;
4785+
4786+ dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ?
4787+ 1 : adev->dtim_interval;
4788+
4789+ memset(&tmp, 0, sizeof(tmp));
4790+
4791+ for (i = 0; i < ETH_ALEN; i++) {
4792+ tmp.bssid[i] = bssid[ETH_ALEN-1 - i];
4793+ }
4794+
4795+ tmp.beacon_interval = cpu_to_le16(adev->beacon_interval);
4796+
4797+ /* Basic rate set. Control frame responses (such as ACK or CTS frames)
4798+ ** are sent with one of these rates */
4799+ if (IS_ACX111(adev)) {
4800+ /* It was experimentally determined that rates_basic
4801+ ** can take 11g rates as well, not only rates
4802+ ** defined with JOINBSS_RATES_BASIC111_nnn.
4803+ ** Just use RATE111_nnn constants... */
4804+ tmp.u.acx111.dtim_interval = dtim_interval;
4805+ tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic);
4806+ log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n",
4807+ adev->rate_basic, adev->rate_oper);
4808+ } else {
4809+ tmp.u.acx100.dtim_interval = dtim_interval;
4810+ tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic);
4811+ tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper);
4812+ log(L_ASSOC, "rates_basic:%04X->%02X, "
4813+ "rates_supported:%04X->%02X\n",
4814+ adev->rate_basic, tmp.u.acx100.rates_basic,
4815+ adev->rate_oper, tmp.u.acx100.rates_supported);
4816+ }
4817+
4818+ /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames
4819+ ** will be sent (rate/modulation/preamble) */
4820+ tmp.u.txrate.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)];
4821+ tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */
4822+ /* we can use short pre *if* all peers can understand it */
4823+ /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */
4824+
4825+ /* we switch fw to STA mode in MONITOR mode, it seems to be
4826+ ** the only mode where fw does not emit beacons by itself
4827+ ** but allows us to send anything (we really want to retain
4828+ ** ability to tx arbitrary frames in MONITOR mode)
4829+ */
4830+ tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA);
4831+ tmp.channel = adev->channel;
4832+ tmp.essid_len = adev->essid_len;
4833+ /* NOTE: the code memcpy'd essid_len + 1 before, which is WRONG! */
4834+ memcpy(tmp.essid, adev->essid, tmp.essid_len);
4835+ acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11);
4836+
4837+ log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode);
4838+ acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n");
4839+
4840+ acx_update_capabilities(adev);
4841+ FN_EXIT0;
4842+}
4843+
4844+
4845+/***********************************************************************
4846+** acx_s_cmd_start_scan
4847+**
4848+** Issue scan command to the hardware
4849+**
4850+** unified function for both ACX111 and ACX100
4851+*/
4852+static void
4853+acx_s_scan_chan(acx_device_t *adev)
4854+{
4855+ union {
4856+ acx111_scan_t acx111;
4857+ acx100_scan_t acx100;
4858+ } s;
4859+
4860+ FN_ENTER;
4861+
4862+ memset(&s, 0, sizeof(s));
4863+
4864+ /* first common positions... */
4865+
4866+ s.acx111.count = cpu_to_le16(adev->scan_count);
4867+ s.acx111.rate = adev->scan_rate;
4868+ s.acx111.options = adev->scan_mode;
4869+ s.acx111.chan_duration = cpu_to_le16(adev->scan_duration);
4870+ s.acx111.max_probe_delay = cpu_to_le16(adev->scan_probe_delay);
4871+
4872+ /* ...then differences */
4873+
4874+ if (IS_ACX111(adev)) {
4875+ s.acx111.channel_list_select = 0; /* scan every allowed channel */
4876+ /*s.acx111.channel_list_select = 1;*/ /* scan given channels */
4877+ /*s.acx111.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */
4878+ s.acx111.modulation = 0;
4879+ /*s.acx111.channel_list[0] = 6;
4880+ s.acx111.channel_list[1] = 4;*/
4881+ } else {
4882+ s.acx100.start_chan = cpu_to_le16(1);
4883+ s.acx100.flags = cpu_to_le16(0x8000);
4884+ }
4885+
4886+ acx_s_issue_cmd(adev, ACX1xx_CMD_SCAN, &s, sizeof(s));
4887+ FN_EXIT0;
4888+}
4889+
4890+
4891+void
4892+acx_s_cmd_start_scan(acx_device_t *adev)
4893+{
4894+ /* time_before check is 'just in case' thing */
4895+ if (!(adev->irq_status & HOST_INT_SCAN_COMPLETE)
4896+ && time_before(jiffies, adev->scan_start + 10*HZ)
4897+ ) {
4898+ log(L_INIT, "start_scan: seems like previous scan "
4899+ "is still running. Not starting anew. Please report\n");
4900+ return;
4901+ }
4902+
4903+ log(L_INIT, "starting radio scan\n");
4904+ /* remember that fw is commanded to do scan */
4905+ adev->scan_start = jiffies;
4906+ CLEAR_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
4907+ /* issue it */
4908+ acx_s_scan_chan(adev);
4909+}
4910+
4911+
4912+/***********************************************************************
4913+** acx111 feature config
4914+*/
4915+static int
4916+acx111_s_get_feature_config(acx_device_t *adev,
4917+ u32 *feature_options, u32 *data_flow_options)
4918+{
4919+ struct acx111_ie_feature_config feat;
4920+
4921+ if (!IS_ACX111(adev)) {
4922+ return NOT_OK;
4923+ }
4924+
4925+ memset(&feat, 0, sizeof(feat));
4926+
4927+ if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
4928+ return NOT_OK;
4929+ }
4930+ log(L_DEBUG,
4931+ "got Feature option:0x%X, DataFlow option: 0x%X\n",
4932+ feat.feature_options,
4933+ feat.data_flow_options);
4934+
4935+ if (feature_options)
4936+ *feature_options = le32_to_cpu(feat.feature_options);
4937+ if (data_flow_options)
4938+ *data_flow_options = le32_to_cpu(feat.data_flow_options);
4939+
4940+ return OK;
4941+}
4942+
4943+static int
4944+acx111_s_set_feature_config(acx_device_t *adev,
4945+ u32 feature_options, u32 data_flow_options,
4946+ unsigned int mode /* 0 == remove, 1 == add, 2 == set */)
4947+{
4948+ struct acx111_ie_feature_config feat;
4949+
4950+ if (!IS_ACX111(adev)) {
4951+ return NOT_OK;
4952+ }
4953+
4954+ if ((mode < 0) || (mode > 2))
4955+ return NOT_OK;
4956+
4957+ if (mode != 2)
4958+ /* need to modify old data */
4959+ acx111_s_get_feature_config(adev, &feat.feature_options, &feat.data_flow_options);
4960+ else {
4961+ /* need to set a completely new value */
4962+ feat.feature_options = 0;
4963+ feat.data_flow_options = 0;
4964+ }
4965+
4966+ if (mode == 0) { /* remove */
4967+ CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options));
4968+ CLEAR_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
4969+ } else { /* add or set */
4970+ SET_BIT(feat.feature_options, cpu_to_le32(feature_options));
4971+ SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options));
4972+ }
4973+
4974+ log(L_DEBUG,
4975+ "old: feature 0x%08X dataflow 0x%08X. mode: %u\n"
4976+ "new: feature 0x%08X dataflow 0x%08X\n",
4977+ feature_options, data_flow_options, mode,
4978+ le32_to_cpu(feat.feature_options),
4979+ le32_to_cpu(feat.data_flow_options));
4980+
4981+ if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) {
4982+ return NOT_OK;
4983+ }
4984+
4985+ return OK;
4986+}
4987+
4988+static inline int
4989+acx111_s_feature_off(acx_device_t *adev, u32 f, u32 d)
4990+{
4991+ return acx111_s_set_feature_config(adev, f, d, 0);
4992+}
4993+static inline int
4994+acx111_s_feature_on(acx_device_t *adev, u32 f, u32 d)
4995+{
4996+ return acx111_s_set_feature_config(adev, f, d, 1);
4997+}
4998+static inline int
4999+acx111_s_feature_set(acx_device_t *adev, u32 f, u32 d)
5000+{
5001+ return acx111_s_set_feature_config(adev, f, d, 2);
5002+}
5003+
5004+
5005+/***********************************************************************
5006+** acx100_s_init_memory_pools
5007+*/
5008+static int
5009+acx100_s_init_memory_pools(acx_device_t *adev, const acx_ie_memmap_t *mmt)
5010+{
5011+ acx100_ie_memblocksize_t MemoryBlockSize;
5012+ acx100_ie_memconfigoption_t MemoryConfigOption;
5013+ int TotalMemoryBlocks;
5014+ int RxBlockNum;
5015+ int TotalRxBlockSize;
5016+ int TxBlockNum;
5017+ int TotalTxBlockSize;
5018+
5019+ FN_ENTER;
5020+
5021+ /* Let's see if we can follow this:
5022+ first we select our memory block size (which I think is
5023+ completely arbitrary) */
5024+ MemoryBlockSize.size = cpu_to_le16(adev->memblocksize);
5025+
5026+ /* Then we alert the card to our decision of block size */
5027+ if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) {
5028+ goto bad;
5029+ }
5030+
5031+ /* We figure out how many total blocks we can create, using
5032+ the block size we chose, and the beginning and ending
5033+ memory pointers, i.e.: end-start/size */
5034+ TotalMemoryBlocks = (le32_to_cpu(mmt->PoolEnd) - le32_to_cpu(mmt->PoolStart)) / adev->memblocksize;
5035+
5036+ log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n",
5037+ TotalMemoryBlocks, TotalMemoryBlocks*adev->memblocksize);
5038+
5039+ /* MemoryConfigOption.DMA_config bitmask:
5040+ access to ACX memory is to be done:
5041+ 0x00080000 using PCI conf space?!
5042+ 0x00040000 using IO instructions?
5043+ 0x00000000 using memory access instructions
5044+ 0x00020000 using local memory block linked list (else what?)
5045+ 0x00010000 using host indirect descriptors (else host must access ACX memory?)
5046+ */
5047+#if defined (ACX_MEM)
5048+ /*
5049+ * ACX ignores DMA_config for generic slave mode.
5050+ */
5051+ MemoryConfigOption.DMA_config = 0;
5052+ /* Declare start of the Rx host pool */
5053+ MemoryConfigOption.pRxHostDesc = cpu2acx(0);
5054+ log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
5055+ acx2cpu(MemoryConfigOption.pRxHostDesc),
5056+ (long)adev->rxhostdesc_startphy);
5057+#else
5058+ if (IS_PCI(adev)) {
5059+ MemoryConfigOption.DMA_config = cpu_to_le32(0x30000);
5060+ /* Declare start of the Rx host pool */
5061+ MemoryConfigOption.pRxHostDesc = cpu2acx(adev->rxhostdesc_startphy);
5062+ log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n",
5063+ acx2cpu(MemoryConfigOption.pRxHostDesc),
5064+ (long)adev->rxhostdesc_startphy);
5065+ } else {
5066+ MemoryConfigOption.DMA_config = cpu_to_le32(0x20000);
5067+ }
5068+#endif
5069+
5070+ /* 50% of the allotment of memory blocks go to tx descriptors */
5071+ TxBlockNum = TotalMemoryBlocks / 2;
5072+ MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum);
5073+
5074+ /* and 50% go to the rx descriptors */
5075+ RxBlockNum = TotalMemoryBlocks - TxBlockNum;
5076+ MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum);
5077+
5078+ /* size of the tx and rx descriptor queues */
5079+ TotalTxBlockSize = TxBlockNum * adev->memblocksize;
5080+ TotalRxBlockSize = RxBlockNum * adev->memblocksize;
5081+ log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u "
5082+ "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum,
5083+ TotalTxBlockSize, TotalRxBlockSize);
5084+
5085+
5086+ /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */
5087+ MemoryConfigOption.rx_mem =
5088+ cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f);
5089+
5090+ /* align the rx descriptor queue to units of 0x20
5091+ * and offset it by the tx descriptor queue */
5092+ MemoryConfigOption.tx_mem =
5093+ cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize + 0x1f) & ~0x1f);
5094+ log(L_DEBUG, "rx_mem %08X rx_mem %08X\n",
5095+ MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem);
5096+
5097+ /* alert the device to our decision */
5098+ if (OK != acx_s_configure(adev, &MemoryConfigOption, ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) {
5099+ goto bad;
5100+ }
5101+
5102+ /* and tell the device to kick it into gear */
5103+ if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) {
5104+ goto bad;
5105+ }
5106+#ifdef ACX_MEM
5107+ /*
5108+ * slave memory interface has to manage the transmit pools for the ACX,
5109+ * so it needs to know what we chose here.
5110+ */
5111+ adev->acx_txbuf_start = MemoryConfigOption.tx_mem;
5112+ adev->acx_txbuf_numblocks = MemoryConfigOption.TxBlockNum;
5113+#endif
5114+
5115+ FN_EXIT1(OK);
5116+ return OK;
5117+bad:
5118+ FN_EXIT1(NOT_OK);
5119+ return NOT_OK;
5120+}
5121+
5122+
5123+/***********************************************************************
5124+** acx100_s_create_dma_regions
5125+**
5126+** Note that this fn messes up heavily with hardware, but we cannot
5127+** lock it (we need to sleep). Not a problem since IRQs can't happen
5128+*/
5129+static int
5130+acx100_s_create_dma_regions(acx_device_t *adev)
5131+{
5132+ acx100_ie_queueconfig_t queueconf;
5133+ acx_ie_memmap_t memmap;
5134+ int res = NOT_OK;
5135+ u32 tx_queue_start, rx_queue_start;
5136+
5137+ FN_ENTER;
5138+
5139+ /* read out the acx100 physical start address for the queues */
5140+ if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
5141+ goto fail;
5142+ }
5143+
5144+ tx_queue_start = le32_to_cpu(memmap.QueueStart);
5145+ rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t);
5146+
5147+ log(L_DEBUG, "initializing Queue Indicator\n");
5148+
5149+ memset(&queueconf, 0, sizeof(queueconf));
5150+
5151+ /* Not needed for PCI or slave memory, so we can avoid setting them altogether */
5152+ if (IS_USB(adev)) {
5153+ queueconf.NumTxDesc = USB_TX_CNT;
5154+ queueconf.NumRxDesc = USB_RX_CNT;
5155+ }
5156+
5157+ /* calculate size of queues */
5158+ queueconf.AreaSize = cpu_to_le32(
5159+ TX_CNT * sizeof(txdesc_t) +
5160+ RX_CNT * sizeof(rxdesc_t) + 8
5161+ );
5162+ queueconf.NumTxQueues = 1; /* number of tx queues */
5163+ /* sets the beginning of the tx descriptor queue */
5164+ queueconf.TxQueueStart = memmap.QueueStart;
5165+ /* done by memset: queueconf.TxQueuePri = 0; */
5166+ queueconf.RxQueueStart = cpu_to_le32(rx_queue_start);
5167+ queueconf.QueueOptions = 1; /* auto reset descriptor */
5168+ /* sets the end of the rx descriptor queue */
5169+ queueconf.QueueEnd = cpu_to_le32(
5170+ rx_queue_start + RX_CNT * sizeof(rxdesc_t)
5171+ );
5172+ /* sets the beginning of the next queue */
5173+ queueconf.HostQueueEnd = cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8);
5174+ if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) {
5175+ goto fail;
5176+ }
5177+
5178+#if defined (ACX_MEM)
5179+ /* sets the beginning of the rx descriptor queue, after the tx descrs */
5180+ adev->acx_queue_indicator =
5181+ (queueindicator_t *) le32_to_cpu (queueconf.QueueEnd);
5182+ if (OK != acxmem_s_create_hostdesc_queues(adev))
5183+ goto fail;
5184+
5185+ acxmem_create_desc_queues(adev, tx_queue_start, rx_queue_start);
5186+#else
5187+ if (IS_PCI(adev)) {
5188+ /* sets the beginning of the rx descriptor queue, after the tx descrs */
5189+ if (OK != acxpci_s_create_hostdesc_queues(adev))
5190+ goto fail;
5191+ acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
5192+ }
5193+#endif
5194+
5195+ if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
5196+ goto fail;
5197+ }
5198+
5199+ /*
5200+ * Have to make sure we skip past the Queue Indicator (QueueEnd) and Host Queue Indicator
5201+ * maps, each of which are 8 bytes and follow immediately after the transmit and
5202+ * receive queues.
5203+ */
5204+ memmap.PoolStart = cpu_to_le32(
5205+ (le32_to_cpu(memmap.QueueEnd) + 4 + 0x1f) & ~0x1f
5206+ );
5207+
5208+ if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) {
5209+ goto fail;
5210+ }
5211+
5212+ if (OK != acx100_s_init_memory_pools(adev, &memmap)) {
5213+ goto fail;
5214+ }
5215+
5216+ res = OK;
5217+ goto end;
5218+
5219+fail:
5220+ acx_s_msleep(1000); /* ? */
5221+#if defined (ACX_MEM)
5222+ acxmem_free_desc_queues(adev);
5223+#else
5224+ if (IS_PCI(adev))
5225+ acxpci_free_desc_queues(adev);
5226+#endif
5227+end:
5228+ FN_EXIT1(res);
5229+ return res;
5230+}
5231+
5232+
5233+/***********************************************************************
5234+** acx111_s_create_dma_regions
5235+**
5236+** Note that this fn messes heavily with hardware, but we cannot
5237+** lock it (we need to sleep). Not a problem since IRQs can't happen
5238+*/
5239+#define ACX111_PERCENT(percent) ((percent)/5)
5240+
5241+static int
5242+acx111_s_create_dma_regions(acx_device_t *adev)
5243+{
5244+ struct acx111_ie_memoryconfig memconf;
5245+ struct acx111_ie_queueconfig queueconf;
5246+ u32 tx_queue_start, rx_queue_start;
5247+
5248+ FN_ENTER;
5249+
5250+ /* Calculate memory positions and queue sizes */
5251+
5252+ /* Set up our host descriptor pool + data pool */
5253+#if defined (ACX_MEM)
5254+ if (OK != acxmem_s_create_hostdesc_queues(adev))
5255+ goto fail;
5256+#else
5257+ if (IS_PCI(adev)) {
5258+ if (OK != acxpci_s_create_hostdesc_queues(adev))
5259+ goto fail;
5260+ }
5261+#endif
5262+
5263+ memset(&memconf, 0, sizeof(memconf));
5264+ /* the number of STAs (STA contexts) to support
5265+ ** NB: was set to 1 and everything seemed to work nevertheless... */
5266+ memconf.no_of_stations = cpu_to_le16(VEC_SIZE(adev->sta_list));
5267+ /* specify the memory block size. Default is 256 */
5268+ memconf.memory_block_size = cpu_to_le16(adev->memblocksize);
5269+ /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */
5270+ memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50);
5271+ /* set the count of our queues
5272+ ** NB: struct acx111_ie_memoryconfig shall be modified
5273+ ** if we ever will switch to more than one rx and/or tx queue */
5274+ memconf.count_rx_queues = 1;
5275+ memconf.count_tx_queues = 1;
5276+ /* 0 == Busmaster Indirect Memory Organization, which is what we want
5277+ * (using linked host descs with their allocated mem).
5278+ * 2 == Generic Bus Slave */
5279+ /* done by memset: memconf.options = 0; */
5280+ /* let's use 25% for fragmentations and 75% for frame transfers
5281+ * (specified in units of 5%) */
5282+ memconf.fragmentation = ACX111_PERCENT(75);
5283+ /* Rx descriptor queue config */
5284+ memconf.rx_queue1_count_descs = RX_CNT;
5285+ memconf.rx_queue1_type = 7; /* must be set to 7 */
5286+ /* done by memset: memconf.rx_queue1_prio = 0; low prio */
5287+#if defined (ACX_MEM)
5288+ memconf.rx_queue1_host_rx_start = cpu2acx(adev->rxhostdesc_startphy);
5289+#else
5290+ if (IS_PCI(adev)) {
5291+ memconf.rx_queue1_host_rx_start = cpu2acx(adev->rxhostdesc_startphy);
5292+ }
5293+#endif
5294+ /* Tx descriptor queue config */
5295+ memconf.tx_queue1_count_descs = TX_CNT;
5296+ /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */
5297+
5298+ /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG),
5299+ ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh?
5300+ ** But it is actually correct wrt IE numbers.
5301+ ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG)
5302+ ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig
5303+ ** which is 4 bytes larger. what a mess. TODO: clean it up) */
5304+ if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) {
5305+ goto fail;
5306+ }
5307+
5308+ acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
5309+
5310+ tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address);
5311+ rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address);
5312+
5313+ log(L_INIT, "dump queue head (from card):\n"
5314+ "len: %u\n"
5315+ "tx_memory_block_address: %X\n"
5316+ "rx_memory_block_address: %X\n"
5317+ "tx1_queue address: %X\n"
5318+ "rx1_queue address: %X\n",
5319+ le16_to_cpu(queueconf.len),
5320+ le32_to_cpu(queueconf.tx_memory_block_address),
5321+ le32_to_cpu(queueconf.rx_memory_block_address),
5322+ tx_queue_start,
5323+ rx_queue_start);
5324+
5325+#if defined (ACX_MEM)
5326+ acxmem_create_desc_queues(adev, tx_queue_start, rx_queue_start);
5327+#else
5328+ if (IS_PCI(adev))
5329+ acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start);
5330+#endif
5331+
5332+ FN_EXIT1(OK);
5333+ return OK;
5334+fail:
5335+#if defined (ACX_MEM)
5336+ acxmem_free_desc_queues(adev);
5337+#else
5338+ if (IS_PCI(adev))
5339+ acxpci_free_desc_queues(adev);
5340+#endif
5341+
5342+ FN_EXIT1(NOT_OK);
5343+ return NOT_OK;
5344+}
5345+
5346+
5347+/***********************************************************************
5348+*/
5349+static void
5350+acx_s_initialize_rx_config(acx_device_t *adev)
5351+{
5352+ struct {
5353+ u16 id;
5354+ u16 len;
5355+ u16 rx_cfg1;
5356+ u16 rx_cfg2;
5357+ } ACX_PACKED cfg;
5358+
5359+ switch (adev->mode) {
5360+ case ACX_MODE_OFF:
5361+ adev->rx_config_1 = (u16) (0
5362+ /* | RX_CFG1_INCLUDE_RXBUF_HDR */
5363+ /* | RX_CFG1_FILTER_SSID */
5364+ /* | RX_CFG1_FILTER_BCAST */
5365+ /* | RX_CFG1_RCV_MC_ADDR1 */
5366+ /* | RX_CFG1_RCV_MC_ADDR0 */
5367+ /* | RX_CFG1_FILTER_ALL_MULTI */
5368+ /* | RX_CFG1_FILTER_BSSID */
5369+ /* | RX_CFG1_FILTER_MAC */
5370+ /* | RX_CFG1_RCV_PROMISCUOUS */
5371+ /* | RX_CFG1_INCLUDE_FCS */
5372+ /* | RX_CFG1_INCLUDE_PHY_HDR */
5373+ );
5374+ adev->rx_config_2 = (u16) (0
5375+ /*| RX_CFG2_RCV_ASSOC_REQ */
5376+ /*| RX_CFG2_RCV_AUTH_FRAMES */
5377+ /*| RX_CFG2_RCV_BEACON_FRAMES */
5378+ /*| RX_CFG2_RCV_CONTENTION_FREE */
5379+ /*| RX_CFG2_RCV_CTRL_FRAMES */
5380+ /*| RX_CFG2_RCV_DATA_FRAMES */
5381+ /*| RX_CFG2_RCV_BROKEN_FRAMES */
5382+ /*| RX_CFG2_RCV_MGMT_FRAMES */
5383+ /*| RX_CFG2_RCV_PROBE_REQ */
5384+ /*| RX_CFG2_RCV_PROBE_RESP */
5385+ /*| RX_CFG2_RCV_ACK_FRAMES */
5386+ /*| RX_CFG2_RCV_OTHER */
5387+ );
5388+ break;
5389+ case ACX_MODE_MONITOR:
5390+ adev->rx_config_1 = (u16) (0
5391+ /* | RX_CFG1_INCLUDE_RXBUF_HDR */
5392+ /* | RX_CFG1_FILTER_SSID */
5393+ /* | RX_CFG1_FILTER_BCAST */
5394+ /* | RX_CFG1_RCV_MC_ADDR1 */
5395+ /* | RX_CFG1_RCV_MC_ADDR0 */
5396+ /* | RX_CFG1_FILTER_ALL_MULTI */
5397+ /* | RX_CFG1_FILTER_BSSID */
5398+ /* | RX_CFG1_FILTER_MAC */
5399+ | RX_CFG1_RCV_PROMISCUOUS
5400+ /* | RX_CFG1_INCLUDE_FCS */
5401+ /* | RX_CFG1_INCLUDE_PHY_HDR */
5402+ );
5403+ adev->rx_config_2 = (u16) (0
5404+ | RX_CFG2_RCV_ASSOC_REQ
5405+ | RX_CFG2_RCV_AUTH_FRAMES
5406+ | RX_CFG2_RCV_BEACON_FRAMES
5407+ | RX_CFG2_RCV_CONTENTION_FREE
5408+ | RX_CFG2_RCV_CTRL_FRAMES
5409+ | RX_CFG2_RCV_DATA_FRAMES
5410+ | RX_CFG2_RCV_BROKEN_FRAMES
5411+ | RX_CFG2_RCV_MGMT_FRAMES
5412+ | RX_CFG2_RCV_PROBE_REQ
5413+ | RX_CFG2_RCV_PROBE_RESP
5414+ | RX_CFG2_RCV_ACK_FRAMES
5415+ | RX_CFG2_RCV_OTHER
5416+ );
5417+ break;
5418+ default:
5419+ adev->rx_config_1 = (u16) (0
5420+ /* | RX_CFG1_INCLUDE_RXBUF_HDR */
5421+ /* | RX_CFG1_FILTER_SSID */
5422+ /* | RX_CFG1_FILTER_BCAST */
5423+ /* | RX_CFG1_RCV_MC_ADDR1 */
5424+ /* | RX_CFG1_RCV_MC_ADDR0 */
5425+ /* | RX_CFG1_FILTER_ALL_MULTI */
5426+ /* | RX_CFG1_FILTER_BSSID */
5427+ | RX_CFG1_FILTER_MAC
5428+ /* | RX_CFG1_RCV_PROMISCUOUS */
5429+ /* | RX_CFG1_INCLUDE_FCS */
5430+ /* | RX_CFG1_INCLUDE_PHY_HDR */
5431+ );
5432+ adev->rx_config_2 = (u16) (0
5433+ | RX_CFG2_RCV_ASSOC_REQ
5434+ | RX_CFG2_RCV_AUTH_FRAMES
5435+ | RX_CFG2_RCV_BEACON_FRAMES
5436+ | RX_CFG2_RCV_CONTENTION_FREE
5437+ | RX_CFG2_RCV_CTRL_FRAMES
5438+ | RX_CFG2_RCV_DATA_FRAMES
5439+ /*| RX_CFG2_RCV_BROKEN_FRAMES */
5440+ | RX_CFG2_RCV_MGMT_FRAMES
5441+ | RX_CFG2_RCV_PROBE_REQ
5442+ | RX_CFG2_RCV_PROBE_RESP
5443+ /*| RX_CFG2_RCV_ACK_FRAMES */
5444+ | RX_CFG2_RCV_OTHER
5445+ );
5446+ break;
5447+ }
5448+ adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR;
5449+
5450+ if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)
5451+ || (adev->firmware_numver >= 0x02000000))
5452+ adev->phy_header_len = IS_ACX111(adev) ? 8 : 4;
5453+ else
5454+ adev->phy_header_len = 0;
5455+
5456+ log(L_INIT, "setting RXconfig to %04X:%04X\n",
5457+ adev->rx_config_1, adev->rx_config_2);
5458+ cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1);
5459+ cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2);
5460+ acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG);
5461+}
5462+
5463+
5464+/***********************************************************************
5465+** acx_s_set_defaults
5466+*/
5467+void
5468+acx_s_set_defaults(acx_device_t *adev)
5469+{
5470+ unsigned long flags;
5471+
5472+ FN_ENTER;
5473+
5474+ /* do it before getting settings, prevent bogus channel 0 warning */
5475+ adev->channel = 1;
5476+
5477+ /* query some settings from the card.
5478+ * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial
5479+ * query is REQUIRED, otherwise the card won't work correctly! */
5480+ adev->get_mask = GETSET_ANTENNA|GETSET_SENSITIVITY|GETSET_STATION_ID|GETSET_REG_DOMAIN;
5481+ /* Only ACX100 supports ED and CCA */
5482+ if (IS_ACX100(adev))
5483+ adev->get_mask |= GETSET_CCA|GETSET_ED_THRESH;
5484+
5485+ acx_s_update_card_settings(adev);
5486+
5487+ acx_lock(adev, flags);
5488+
5489+ /* set our global interrupt mask */
5490+#if defined (ACX_MEM)
5491+ acxmem_set_interrupt_mask(adev);
5492+#else
5493+ if (IS_PCI(adev))
5494+ acxpci_set_interrupt_mask(adev);
5495+#endif
5496+
5497+ adev->led_power = 1; /* LED is active on startup */
5498+ adev->brange_max_quality = 60; /* LED blink max quality is 60 */
5499+ adev->brange_time_last_state_change = jiffies;
5500+
5501+ /* copy the MAC address we just got from the card
5502+ * into our MAC address used during current 802.11 session */
5503+ MAC_COPY(adev->dev_addr, adev->ndev->dev_addr);
5504+ MAC_BCAST(adev->ap);
5505+
5506+ adev->essid_len =
5507+ snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X",
5508+ adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]);
5509+ adev->essid_active = 1;
5510+
5511+ /* we have a nick field to waste, so why not abuse it
5512+ * to announce the driver version? ;-) */
5513+ strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE);
5514+
5515+#if defined (ACX_MEM)
5516+ adev->reg_dom_id = adev->cfgopt_domains.list[0];
5517+#else
5518+ if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */
5519+ /* first regulatory domain entry in EEPROM == default reg. domain */
5520+ adev->reg_dom_id = adev->cfgopt_domains.list[0];
5521+ }
5522+#endif
5523+
5524+ /* 0xffff would be better, but then we won't get a "scan complete"
5525+ * interrupt, so our current infrastructure will fail: */
5526+ adev->scan_count = 1;
5527+ adev->scan_mode = ACX_SCAN_OPT_ACTIVE;
5528+ adev->scan_duration = 100;
5529+ adev->scan_probe_delay = 200;
5530+ /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
5531+ adev->scan_rate = ACX_SCAN_RATE_1;
5532+
5533+ adev->mode = ACX_MODE_2_STA;
5534+ adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
5535+ adev->listen_interval = 100;
5536+ adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
5537+ adev->dtim_interval = DEFAULT_DTIM_INTERVAL;
5538+
5539+ adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME;
5540+
5541+ adev->rts_threshold = DEFAULT_RTS_THRESHOLD;
5542+ adev->frag_threshold = 2346;
5543+
5544+ /* use standard default values for retry limits */
5545+ adev->short_retry = 7; /* max. retries for (short) non-RTS packets */
5546+ adev->long_retry = 4; /* max. retries for long (RTS) packets */
5547+
5548+ adev->preamble_mode = 2; /* auto */
5549+ adev->fallback_threshold = 3;
5550+ adev->stepup_threshold = 10;
5551+ adev->rate_bcast = RATE111_1;
5552+ adev->rate_bcast100 = RATE100_1;
5553+ adev->rate_basic = RATE111_1 | RATE111_2;
5554+ adev->rate_auto = 1;
5555+ if (IS_ACX111(adev)) {
5556+ adev->rate_oper = RATE111_ALL;
5557+ } else {
5558+ adev->rate_oper = RATE111_ACX100_COMPAT;
5559+ }
5560+
5561+ /* Supported Rates element - the rates here are given in units of
5562+ * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */
5563+ acx_l_update_ratevector(adev);
5564+
5565+ /* set some more defaults */
5566+ if (IS_ACX111(adev)) {
5567+ /* 30mW (15dBm) is default, at least in my acx111 card: */
5568+ adev->tx_level_dbm = 15;
5569+ } else {
5570+ /* don't use max. level, since it might be dangerous
5571+ * (e.g. WRT54G people experience
5572+ * excessive Tx power damage!) */
5573+ adev->tx_level_dbm = 18;
5574+ /*
5575+ * Lower power for the iPaq hx4700
5576+ */
5577+ if (IS_MEM(adev)) {
5578+ adev->tx_level_dbm = 14;
5579+ }
5580+ }
5581+ /* adev->tx_level_auto = 1; */
5582+ if (IS_ACX111(adev)) {
5583+ /* start with sensitivity level 1 out of 3: */
5584+ adev->sensitivity = 1;
5585+ }
5586+
5587+/* #define ENABLE_POWER_SAVE */
5588+#ifdef ENABLE_POWER_SAVE
5589+ adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC;
5590+ adev->ps_listen_interval = 1;
5591+ adev->ps_options = PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS;
5592+ adev->ps_hangover_period = 30;
5593+ adev->ps_enhanced_transition_time = 0;
5594+#else
5595+ adev->ps_wakeup_cfg = 0;
5596+ adev->ps_listen_interval = 0;
5597+ adev->ps_options = 0;
5598+ adev->ps_hangover_period = 0;
5599+ adev->ps_enhanced_transition_time = 0;
5600+#endif
5601+
5602+ /* These settings will be set in fw on ifup */
5603+ adev->set_mask = 0
5604+ | GETSET_RETRY
5605+ | SET_MSDU_LIFETIME
5606+ /* configure card to do rate fallback when in auto rate mode */
5607+ | SET_RATE_FALLBACK
5608+ | SET_RXCONFIG
5609+ | GETSET_TXPOWER
5610+ /* better re-init the antenna value we got above */
5611+ | GETSET_ANTENNA
5612+#if POWER_SAVE_80211
5613+ | GETSET_POWER_80211
5614+#endif
5615+ ;
5616+
5617+ acx_unlock(adev, flags);
5618+ acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */
5619+
5620+ acx_s_initialize_rx_config(adev);
5621+
5622+ FN_EXIT0;
5623+}
5624+
5625+
5626+/***********************************************************************
5627+** FIXME: this should be solved in a general way for all radio types
5628+** by decoding the radio firmware module,
5629+** since it probably has some standard structure describing how to
5630+** set the power level of the radio module which it controls.
5631+** Or maybe not, since the radio module probably has a function interface
5632+** instead which then manages Tx level programming :-\
5633+*/
5634+static int
5635+acx111_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
5636+{
5637+ struct acx111_ie_tx_level tx_level;
5638+
5639+ /* my acx111 card has two power levels in its configoptions (== EEPROM):
5640+ * 1 (30mW) [15dBm]
5641+ * 2 (10mW) [10dBm]
5642+ * For now, just assume all other acx111 cards have the same.
5643+ * FIXME: Ideally we would query it here, but we first need a
5644+ * standard way to query individual configoptions easily.
5645+ * Well, now we have proper cfgopt txpower variables, but this still
5646+ * hasn't been done yet, since it also requires dBm <-> mW conversion here... */
5647+ if (level_dbm <= 12) {
5648+ tx_level.level = 2; /* 10 dBm */
5649+ adev->tx_level_dbm = 10;
5650+ } else {
5651+ tx_level.level = 1; /* 15 dBm */
5652+ adev->tx_level_dbm = 15;
5653+ }
5654+ if (level_dbm != adev->tx_level_dbm)
5655+ log(L_INIT, "acx111 firmware has specific "
5656+ "power levels only: adjusted %d dBm to %d dBm!\n",
5657+ level_dbm, adev->tx_level_dbm);
5658+
5659+ return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
5660+}
5661+
5662+static int
5663+acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
5664+{
5665+ if (IS_ACX111(adev)) {
5666+ return acx111_s_set_tx_level(adev, level_dbm);
5667+ }
5668+#if defined (ACX_MEM)
5669+ return acx100mem_s_set_tx_level(adev, level_dbm);
5670+#else
5671+ if (IS_PCI(adev)) {
5672+ return acx100pci_s_set_tx_level(adev, level_dbm);
5673+ }
5674+#endif
5675+ return OK;
5676+}
5677+
5678+
5679+/***********************************************************************
5680+*/
5681+#ifdef UNUSED
5682+/* Returns the current tx level (ACX111) */
5683+static u8
5684+acx111_s_get_tx_level(acx_device_t *adev)
5685+{
5686+ struct acx111_ie_tx_level tx_level;
5687+
5688+ tx_level.level = 0;
5689+ acx_s_interrogate(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
5690+ return tx_level.level;
5691+}
5692+#endif
5693+
5694+
5695+/***********************************************************************
5696+** acx_l_rxmonitor
5697+** Called from IRQ context only
5698+*/
5699+static void
5700+acx_l_rxmonitor(acx_device_t *adev, const rxbuffer_t *rxbuf)
5701+{
5702+ wlansniffrm_t *msg;
5703+ struct sk_buff *skb;
5704+ void *datap;
5705+ unsigned int skb_len;
5706+ int payload_offset;
5707+
5708+ FN_ENTER;
5709+
5710+ /* we are in big luck: the acx100 doesn't modify any of the fields */
5711+ /* in the 802.11 frame. just pass this packet into the PF_PACKET */
5712+ /* subsystem. yeah. */
5713+ payload_offset = ((u8*)acx_get_wlan_hdr(adev, rxbuf) - (u8*)rxbuf);
5714+ skb_len = RXBUF_BYTES_USED(rxbuf) - payload_offset;
5715+
5716+ /* sanity check */
5717+ if (unlikely(skb_len > WLAN_A4FR_MAXLEN_WEP)) {
5718+ printk("%s: monitor mode panic: oversized frame!\n",
5719+ adev->ndev->name);
5720+ goto end;
5721+ }
5722+
5723+ if (adev->ndev->type == ARPHRD_IEEE80211_PRISM)
5724+ skb_len += sizeof(*msg);
5725+
5726+ /* allocate skb */
5727+ skb = dev_alloc_skb(skb_len);
5728+ if (unlikely(!skb)) {
5729+ printk("%s: no memory for skb (%u bytes)\n",
5730+ adev->ndev->name, skb_len);
5731+ goto end;
5732+ }
5733+
5734+ skb_put(skb, skb_len);
5735+
5736+ if (adev->ndev->type == ARPHRD_IEEE80211) {
5737+ /* when in raw 802.11 mode, just copy frame as-is */
5738+ datap = skb->data;
5739+ } else if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) {
5740+ /* emulate prism header */
5741+ msg = (wlansniffrm_t*)skb->data;
5742+ datap = msg + 1;
5743+
5744+ msg->msgcode = WLANSNIFFFRM;
5745+ msg->msglen = sizeof(*msg);
5746+ strncpy(msg->devname, adev->ndev->name, sizeof(msg->devname)-1);
5747+ msg->devname[sizeof(msg->devname)-1] = '\0';
5748+
5749+ msg->hosttime.did = WLANSNIFFFRM_hosttime;
5750+ msg->hosttime.status = WLANITEM_STATUS_data_ok;
5751+ msg->hosttime.len = 4;
5752+ msg->hosttime.data = jiffies;
5753+
5754+ msg->mactime.did = WLANSNIFFFRM_mactime;
5755+ msg->mactime.status = WLANITEM_STATUS_data_ok;
5756+ msg->mactime.len = 4;
5757+ msg->mactime.data = rxbuf->time;
5758+
5759+ msg->channel.did = WLANSNIFFFRM_channel;
5760+ msg->channel.status = WLANITEM_STATUS_data_ok;
5761+ msg->channel.len = 4;
5762+ msg->channel.data = adev->channel;
5763+
5764+ msg->rssi.did = WLANSNIFFFRM_rssi;
5765+ msg->rssi.status = WLANITEM_STATUS_no_value;
5766+ msg->rssi.len = 4;
5767+ msg->rssi.data = 0;
5768+
5769+ msg->sq.did = WLANSNIFFFRM_sq;
5770+ msg->sq.status = WLANITEM_STATUS_no_value;
5771+ msg->sq.len = 4;
5772+ msg->sq.data = 0;
5773+
5774+ msg->signal.did = WLANSNIFFFRM_signal;
5775+ msg->signal.status = WLANITEM_STATUS_data_ok;
5776+ msg->signal.len = 4;
5777+ msg->signal.data = rxbuf->phy_snr;
5778+
5779+ msg->noise.did = WLANSNIFFFRM_noise;
5780+ msg->noise.status = WLANITEM_STATUS_data_ok;
5781+ msg->noise.len = 4;
5782+ msg->noise.data = rxbuf->phy_level;
5783+
5784+ msg->rate.did = WLANSNIFFFRM_rate;
5785+ msg->rate.status = WLANITEM_STATUS_data_ok;
5786+ msg->rate.len = 4;
5787+ msg->rate.data = rxbuf->phy_plcp_signal / 5;
5788+
5789+ msg->istx.did = WLANSNIFFFRM_istx;
5790+ msg->istx.status = WLANITEM_STATUS_data_ok;
5791+ msg->istx.len = 4;
5792+ msg->istx.data = 0; /* tx=0: it's not a tx packet */
5793+
5794+ skb_len -= sizeof(*msg);
5795+
5796+ msg->frmlen.did = WLANSNIFFFRM_signal;
5797+ msg->frmlen.status = WLANITEM_STATUS_data_ok;
5798+ msg->frmlen.len = 4;
5799+ msg->frmlen.data = skb_len;
5800+ } else {
5801+ printk("acx: unsupported netdev type %d!\n", adev->ndev->type);
5802+ dev_kfree_skb(skb);
5803+ return;
5804+ }
5805+
5806+ /* sanity check (keep it here) */
5807+ if (unlikely((int)skb_len < 0)) {
5808+ printk("acx: skb_len=%d. Driver bug, please report\n", (int)skb_len);
5809+ dev_kfree_skb(skb);
5810+ return;
5811+ }
5812+ memcpy(datap, ((unsigned char*)rxbuf)+payload_offset, skb_len);
5813+
5814+ skb->dev = adev->ndev;
5815+ skb->dev->last_rx = jiffies;
5816+
5817+ skb_reset_mac_header(skb);
5818+ skb->ip_summed = CHECKSUM_NONE;
5819+ skb->pkt_type = PACKET_OTHERHOST;
5820+ skb->protocol = htons(ETH_P_80211_RAW);
5821+ netif_rx(skb);
5822+
5823+ adev->stats.rx_packets++;
5824+ adev->stats.rx_bytes += skb->len;
5825+
5826+end:
5827+ FN_EXIT0;
5828+}
5829+
5830+
5831+/***********************************************************************
5832+** acx_l_rx_ieee802_11_frame
5833+**
5834+** Called from IRQ context only
5835+*/
5836+
5837+/* All these contortions are for saner dup logging
5838+**
5839+** We want: (a) to know about excessive dups
5840+** (b) to not spam kernel log about occasional dups
5841+**
5842+** 1/64 threshold was chosen by running "ping -A"
5843+** It gave "rx: 59 DUPs in 2878 packets" only with 4 parallel
5844+** "ping -A" streams running. */
5845+/* 2005-10-11: bumped up to 1/8
5846+** subtract a $smallint from dup_count in order to
5847+** avoid "2 DUPs in 19 packets" messages */
5848+static inline int
5849+acx_l_handle_dup(acx_device_t *adev, u16 seq)
5850+{
5851+ if (adev->dup_count) {
5852+ adev->nondup_count++;
5853+ if (time_after(jiffies, adev->dup_msg_expiry)) {
5854+ /* Log only if more than 1 dup in 64 packets */
5855+ if (adev->nondup_count/8 < adev->dup_count-5) {
5856+ printk(KERN_INFO "%s: rx: %d DUPs in "
5857+ "%d packets received in 10 secs\n",
5858+ adev->ndev->name,
5859+ adev->dup_count,
5860+ adev->nondup_count);
5861+ }
5862+ adev->dup_count = 0;
5863+ adev->nondup_count = 0;
5864+ }
5865+ }
5866+ if (unlikely(seq == adev->last_seq_ctrl)) {
5867+ if (!adev->dup_count++)
5868+ adev->dup_msg_expiry = jiffies + 10*HZ;
5869+ adev->stats.rx_errors++;
5870+ return 1; /* a dup */
5871+ }
5872+ adev->last_seq_ctrl = seq;
5873+ return 0;
5874+}
5875+
5876+static int
5877+acx_l_rx_ieee802_11_frame(acx_device_t *adev, rxbuffer_t *rxbuf)
5878+{
5879+ unsigned int ftype, fstype;
5880+ const wlan_hdr_t *hdr;
5881+ int result = NOT_OK;
5882+
5883+ FN_ENTER;
5884+
5885+ hdr = acx_get_wlan_hdr(adev, rxbuf);
5886+
5887+ /* see IEEE 802.11-1999.pdf chapter 7 "MAC frame formats" */
5888+ if (unlikely((hdr->fc & WF_FC_PVERi) != 0)) {
5889+ printk_ratelimited(KERN_INFO "rx: unsupported 802.11 protocol\n");
5890+ goto end;
5891+ }
5892+
5893+ ftype = hdr->fc & WF_FC_FTYPEi;
5894+ fstype = hdr->fc & WF_FC_FSTYPEi;
5895+
5896+ switch (ftype) {
5897+ /* check data frames first, for speed */
5898+ case WF_FTYPE_DATAi:
5899+ switch (fstype) {
5900+ case WF_FSTYPE_DATAONLYi:
5901+ if (acx_l_handle_dup(adev, hdr->seq))
5902+ break; /* a dup, simply discard it */
5903+
5904+ /* TODO:
5905+ if (WF_FC_FROMTODSi == (hdr->fc & WF_FC_FROMTODSi)) {
5906+ result = acx_l_process_data_frame_wds(adev, rxbuf);
5907+ break;
5908+ }
5909+ */
5910+
5911+ switch (adev->mode) {
5912+ case ACX_MODE_3_AP:
5913+ result = acx_l_process_data_frame_master(adev, rxbuf);
5914+ break;
5915+ case ACX_MODE_0_ADHOC:
5916+ case ACX_MODE_2_STA:
5917+ result = acx_l_process_data_frame_client(adev, rxbuf);
5918+ break;
5919+ }
5920+ case WF_FSTYPE_DATA_CFACKi:
5921+ case WF_FSTYPE_DATA_CFPOLLi:
5922+ case WF_FSTYPE_DATA_CFACK_CFPOLLi:
5923+ case WF_FSTYPE_CFPOLLi:
5924+ case WF_FSTYPE_CFACK_CFPOLLi:
5925+ /* see above.
5926+ acx_process_class_frame(adev, rxbuf, 3); */
5927+ break;
5928+ case WF_FSTYPE_NULLi:
5929+ /* acx_l_process_NULL_frame(adev, rxbuf, 3); */
5930+ break;
5931+ /* FIXME: same here, see above */
5932+ case WF_FSTYPE_CFACKi:
5933+ default:
5934+ break;
5935+ }
5936+ break;
5937+ case WF_FTYPE_MGMTi:
5938+ result = acx_l_process_mgmt_frame(adev, rxbuf);
5939+ break;
5940+ case WF_FTYPE_CTLi:
5941+ if (fstype == WF_FSTYPE_PSPOLLi)
5942+ result = OK;
5943+ /* this call is irrelevant, since
5944+ * acx_process_class_frame is a stub, so return
5945+ * immediately instead.
5946+ * return acx_process_class_frame(adev, rxbuf, 3); */
5947+ break;
5948+ default:
5949+ break;
5950+ }
5951+end:
5952+ FN_EXIT1(result);
5953+ return result;
5954+}
5955+
5956+
5957+/***********************************************************************
5958+** acx_l_process_rxbuf
5959+**
5960+** NB: used by USB code also
5961+*/
5962+void
5963+acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf)
5964+{
5965+ struct wlan_hdr *hdr;
5966+ unsigned int qual;
5967+ int buf_len;
5968+ u16 fc;
5969+
5970+ hdr = acx_get_wlan_hdr(adev, rxbuf);
5971+ fc = le16_to_cpu(hdr->fc);
5972+ /* length of frame from control field to first byte of FCS */
5973+ buf_len = RXBUF_BYTES_RCVD(adev, rxbuf);
5974+
5975+ if ( ((WF_FC_FSTYPE & fc) != WF_FSTYPE_BEACON)
5976+ || (acx_debug & L_XFER_BEACON)
5977+ ) {
5978+ log(L_XFER|L_DATA, "rx: %s "
5979+ "time:%u len:%u signal:%u SNR:%u macstat:%02X "
5980+ "phystat:%02X phyrate:%u status:%u\n",
5981+ acx_get_packet_type_string(fc),
5982+ le32_to_cpu(rxbuf->time),
5983+ buf_len,
5984+ acx_signal_to_winlevel(rxbuf->phy_level),
5985+ acx_signal_to_winlevel(rxbuf->phy_snr),
5986+ rxbuf->mac_status,
5987+ rxbuf->phy_stat_baseband,
5988+ rxbuf->phy_plcp_signal,
5989+ adev->status);
5990+ }
5991+
5992+ if (unlikely(acx_debug & L_DATA)) {
5993+ printk("rx: 802.11 buf[%u]: ", buf_len);
5994+ acx_dump_bytes(hdr, buf_len);
5995+ }
5996+
5997+ /* FIXME: should check for Rx errors (rxbuf->mac_status?
5998+ * discard broken packets - but NOT for monitor!)
5999+ * and update Rx packet statistics here */
6000+
6001+ if (unlikely(adev->mode == ACX_MODE_MONITOR)) {
6002+ acx_l_rxmonitor(adev, rxbuf);
6003+ } else if (likely(buf_len >= WLAN_HDR_A3_LEN)) {
6004+ acx_l_rx_ieee802_11_frame(adev, rxbuf);
6005+ } else {
6006+ log(L_DEBUG|L_XFER|L_DATA,
6007+ "rx: NOT receiving packet (%s): "
6008+ "size too small (%u)\n",
6009+ acx_get_packet_type_string(fc),
6010+ buf_len);
6011+ }
6012+
6013+ /* Now check Rx quality level, AFTER processing packet.
6014+ * I tried to figure out how to map these levels to dBm
6015+ * values, but for the life of me I really didn't
6016+ * manage to get it. Either these values are not meant to
6017+ * be expressed in dBm, or it's some pretty complicated
6018+ * calculation. */
6019+
6020+#ifdef FROM_SCAN_SOURCE_ONLY
6021+ /* only consider packets originating from the MAC
6022+ * address of the device that's managing our BSSID.
6023+ * Disable it for now, since it removes information (levels
6024+ * from different peers) and slows the Rx path. */
6025+ if (adev->ap_client
6026+ && mac_is_equal(hdr->a2, adev->ap_client->address)) {
6027+#endif
6028+ adev->wstats.qual.level = acx_signal_to_winlevel(rxbuf->phy_level);
6029+ adev->wstats.qual.noise = acx_signal_to_winlevel(rxbuf->phy_snr);
6030+#ifndef OLD_QUALITY
6031+ qual = acx_signal_determine_quality(adev->wstats.qual.level,
6032+ adev->wstats.qual.noise);
6033+#else
6034+ qual = (adev->wstats.qual.noise <= 100) ?
6035+ 100 - adev->wstats.qual.noise : 0;
6036+#endif
6037+ adev->wstats.qual.qual = qual;
6038+ adev->wstats.qual.updated = 7; /* all 3 indicators updated */
6039+#ifdef FROM_SCAN_SOURCE_ONLY
6040+ }
6041+#endif
6042+}
6043+
6044+
6045+/***********************************************************************
6046+** acx_l_handle_txrate_auto
6047+**
6048+** Theory of operation:
6049+** client->rate_cap is a bitmask of rates client is capable of.
6050+** client->rate_cfg is a bitmask of allowed (configured) rates.
6051+** It is set as a result of iwconfig rate N [auto]
6052+** or iwpriv set_rates "N,N,N N,N,N" commands.
6053+** It can be fixed (e.g. 0x0080 == 18Mbit only),
6054+** auto (0x00ff == 18Mbit or any lower value),
6055+** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_).
6056+**
6057+** client->rate_cur is a value for rate111 field in tx descriptor.
6058+** It is always set to txrate_cfg sans zero or more most significant
6059+** bits. This routine handles selection of new rate_cur value depending on
6060+** outcome of last tx event.
6061+**
6062+** client->rate_100 is a precalculated rate value for acx100
6063+** (we can do without it, but will need to calculate it on each tx).
6064+**
6065+** You cannot configure mixed usage of 5.5 and/or 11Mbit rate
6066+** with PBCC and CCK modulation. Either both at CCK or both at PBCC.
6067+** In theory you can implement it, but so far it is considered not worth doing.
6068+**
6069+** 22Mbit, of course, is PBCC always. */
6070+
6071+/* maps acx100 tx descr rate field to acx111 one */
6072+static u16
6073+rate100to111(u8 r)
6074+{
6075+ switch (r) {
6076+ case RATE100_1: return RATE111_1;
6077+ case RATE100_2: return RATE111_2;
6078+ case RATE100_5:
6079+ case (RATE100_5 | RATE100_PBCC511): return RATE111_5;
6080+ case RATE100_11:
6081+ case (RATE100_11 | RATE100_PBCC511): return RATE111_11;
6082+ case RATE100_22: return RATE111_22;
6083+ default:
6084+ printk("acx: unexpected acx100 txrate: %u! "
6085+ "Please report\n", r);
6086+ return RATE111_1;
6087+ }
6088+}
6089+
6090+
6091+void
6092+acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc,
6093+ u16 cur, u8 rate100, u16 rate111,
6094+ u8 error, int pkts_to_ignore)
6095+{
6096+ u16 sent_rate;
6097+ int slower_rate_was_used;
6098+
6099+ /* vda: hmm. current code will do this:
6100+ ** 1. send packets at 11 Mbit, stepup++
6101+ ** 2. will try to send at 22Mbit. hardware will see no ACK,
6102+ ** retries at 11Mbit, success. code notes that used rate
6103+ ** is lower. stepup = 0, fallback++
6104+ ** 3. repeat step 2 fallback_count times. Fall back to
6105+ ** 11Mbit. go to step 1.
6106+ ** If stepup_count is large (say, 16) and fallback_count
6107+ ** is small (3), this wouldn't be too bad wrt throughput */
6108+
6109+ if (unlikely(!cur)) {
6110+ printk("acx: BUG! ratemask is empty\n");
6111+ return; /* or else we may lock up the box */
6112+ }
6113+
6114+ /* do some preparations, i.e. calculate the one rate that was
6115+ * used to send this packet */
6116+ if (IS_ACX111(adev)) {
6117+ sent_rate = 1 << highest_bit(rate111 & RATE111_ALL);
6118+ } else {
6119+ sent_rate = rate100to111(rate100);
6120+ }
6121+ /* sent_rate has only one bit set now, corresponding to tx rate
6122+ * which was used by hardware to tx this particular packet */
6123+
6124+ /* now do the actual auto rate management */
6125+ log(L_XFER, "tx: %sclient=%p/"MACSTR" used=%04X cur=%04X cfg=%04X "
6126+ "__=%u/%u ^^=%u/%u\n",
6127+ (txc->ignore_count > 0) ? "[IGN] " : "",
6128+ txc, MAC(txc->address), sent_rate, cur, txc->rate_cfg,
6129+ txc->fallback_count, adev->fallback_threshold,
6130+ txc->stepup_count, adev->stepup_threshold
6131+ );
6132+
6133+ /* we need to ignore old packets already in the tx queue since
6134+ * they use older rate bytes configured before our last rate change,
6135+ * otherwise our mechanism will get confused by interpreting old data.
6136+ * Do it after logging above */
6137+ if (txc->ignore_count) {
6138+ txc->ignore_count--;
6139+ return;
6140+ }
6141+
6142+ /* true only if the only nonzero bit in sent_rate is
6143+ ** less significant than highest nonzero bit in cur */
6144+ slower_rate_was_used = ( cur > ((sent_rate<<1)-1) );
6145+
6146+ if (slower_rate_was_used || error) {
6147+ txc->stepup_count = 0;
6148+ if (++txc->fallback_count <= adev->fallback_threshold)
6149+ return;
6150+ txc->fallback_count = 0;
6151+
6152+ /* clear highest 1 bit in cur */
6153+ sent_rate = RATE111_54;
6154+ while (!(cur & sent_rate)) sent_rate >>= 1;
6155+ CLEAR_BIT(cur, sent_rate);
6156+ if (!cur) /* we can't disable all rates! */
6157+ cur = sent_rate;
6158+ log(L_XFER, "tx: falling back to ratemask %04X\n", cur);
6159+
6160+ } else { /* there was neither lower rate nor error */
6161+ txc->fallback_count = 0;
6162+ if (++txc->stepup_count <= adev->stepup_threshold)
6163+ return;
6164+ txc->stepup_count = 0;
6165+
6166+ /* Sanitize. Sort of not needed, but I dont trust hw that much...
6167+ ** what if it can report bogus tx rates sometimes? */
6168+ while (!(cur & sent_rate)) sent_rate >>= 1;
6169+
6170+ /* try to find a higher sent_rate that isn't yet in our
6171+ * current set, but is an allowed cfg */
6172+ while (1) {
6173+ sent_rate <<= 1;
6174+ if (sent_rate > txc->rate_cfg)
6175+ /* no higher rates allowed by config */
6176+ return;
6177+ if (!(cur & sent_rate) && (txc->rate_cfg & sent_rate))
6178+ /* found */
6179+ break;
6180+ /* not found, try higher one */
6181+ }
6182+ SET_BIT(cur, sent_rate);
6183+ log(L_XFER, "tx: stepping up to ratemask %04X\n", cur);
6184+ }
6185+
6186+ txc->rate_cur = cur;
6187+ txc->ignore_count = pkts_to_ignore;
6188+ /* calculate acx100 style rate byte if needed */
6189+ if (IS_ACX100(adev)) {
6190+ txc->rate_100 = acx_bitpos2rate100[highest_bit(cur)];
6191+ }
6192+}
6193+
6194+
6195+/***********************************************************************
6196+** acx_i_start_xmit
6197+**
6198+** Called by network core. Can be called outside of process context.
6199+*/
6200+int
6201+acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev)
6202+{
6203+ acx_device_t *adev = ndev2adev(ndev);
6204+ tx_t *tx;
6205+ void *txbuf;
6206+ unsigned long flags;
6207+ int txresult = NOT_OK;
6208+ int len;
6209+
6210+ FN_ENTER;
6211+
6212+ if (unlikely(!skb)) {
6213+ /* indicate success */
6214+ txresult = OK;
6215+ goto end_no_unlock;
6216+ }
6217+ if (unlikely(!adev)) {
6218+ goto end_no_unlock;
6219+ }
6220+
6221+ acx_lock(adev, flags);
6222+
6223+ if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
6224+ goto end;
6225+ }
6226+ if (unlikely(adev->mode == ACX_MODE_OFF)) {
6227+ goto end;
6228+ }
6229+ if (unlikely(acx_queue_stopped(ndev))) {
6230+ log(L_DEBUG, "%s: called when queue stopped\n", __func__);
6231+ goto end;
6232+ }
6233+ if (unlikely(ACX_STATUS_4_ASSOCIATED != adev->status)) {
6234+ log(L_XFER, "trying to xmit, but not associated yet: "
6235+ "aborting...\n");
6236+ /* silently drop the packet, since we're not connected yet */
6237+ txresult = OK;
6238+ /* ...but indicate an error nevertheless */
6239+ adev->stats.tx_errors++;
6240+ goto end;
6241+ }
6242+
6243+ tx = acx_l_alloc_tx(adev);
6244+ if (unlikely(!tx)) {
6245+#ifndef ACX_MEM
6246+ /*
6247+ * generic slave interface has to make do with the tiny amount, around
6248+ * 7k, of transmit buffer space on the ACX itself. It is likely this will
6249+ * frequently be full.
6250+ */
6251+ printk_ratelimited("%s: start_xmit: txdesc ring is full, "
6252+ "dropping tx\n", ndev->name);
6253+#endif
6254+ txresult = NOT_OK;
6255+ goto end;
6256+ }
6257+
6258+ txbuf = acx_l_get_txbuf(adev, tx);
6259+ if (unlikely(!txbuf)) {
6260+ /* Card was removed */
6261+ txresult = NOT_OK;
6262+ acx_l_dealloc_tx(adev, tx);
6263+ goto end;
6264+ }
6265+ len = acx_ether_to_txbuf(adev, txbuf, skb);
6266+ if (unlikely(len < 0)) {
6267+ /* Error in packet conversion */
6268+ txresult = NOT_OK;
6269+ acx_l_dealloc_tx(adev, tx);
6270+ goto end;
6271+ }
6272+ acx_l_tx_data(adev, tx, len);
6273+ ndev->trans_start = jiffies;
6274+
6275+ txresult = OK;
6276+ adev->stats.tx_packets++;
6277+ adev->stats.tx_bytes += skb->len;
6278+
6279+end:
6280+ acx_unlock(adev, flags);
6281+
6282+end_no_unlock:
6283+ if ((txresult == OK) && skb)
6284+ dev_kfree_skb_any(skb);
6285+
6286+ FN_EXIT1(txresult);
6287+ return txresult;
6288+}
6289+
6290+
6291+/***********************************************************************
6292+** acx_l_update_ratevector
6293+**
6294+** Updates adev->rate_supported[_len] according to rate_{basic,oper}
6295+*/
6296+const u8
6297+acx_bitpos2ratebyte[] = {
6298+ DOT11RATEBYTE_1,
6299+ DOT11RATEBYTE_2,
6300+ DOT11RATEBYTE_5_5,
6301+ DOT11RATEBYTE_6_G,
6302+ DOT11RATEBYTE_9_G,
6303+ DOT11RATEBYTE_11,
6304+ DOT11RATEBYTE_12_G,
6305+ DOT11RATEBYTE_18_G,
6306+ DOT11RATEBYTE_22,
6307+ DOT11RATEBYTE_24_G,
6308+ DOT11RATEBYTE_36_G,
6309+ DOT11RATEBYTE_48_G,
6310+ DOT11RATEBYTE_54_G,
6311+};
6312+
6313+void
6314+acx_l_update_ratevector(acx_device_t *adev)
6315+{
6316+ u16 bcfg = adev->rate_basic;
6317+ u16 ocfg = adev->rate_oper;
6318+ u8 *supp = adev->rate_supported;
6319+ const u8 *dot11 = acx_bitpos2ratebyte;
6320+
6321+ FN_ENTER;
6322+
6323+ while (ocfg) {
6324+ if (ocfg & 1) {
6325+ *supp = *dot11;
6326+ if (bcfg & 1) {
6327+ *supp |= 0x80;
6328+ }
6329+ supp++;
6330+ }
6331+ dot11++;
6332+ ocfg >>= 1;
6333+ bcfg >>= 1;
6334+ }
6335+ adev->rate_supported_len = supp - adev->rate_supported;
6336+ if (acx_debug & L_ASSOC) {
6337+ printk("new ratevector: ");
6338+ acx_dump_bytes(adev->rate_supported, adev->rate_supported_len);
6339+ }
6340+ FN_EXIT0;
6341+}
6342+
6343+
6344+/***********************************************************************
6345+** acx_l_sta_list_init
6346+*/
6347+static void
6348+acx_l_sta_list_init(acx_device_t *adev)
6349+{
6350+ FN_ENTER;
6351+ memset(adev->sta_hash_tab, 0, sizeof(adev->sta_hash_tab));
6352+ memset(adev->sta_list, 0, sizeof(adev->sta_list));
6353+ FN_EXIT0;
6354+}
6355+
6356+
6357+/***********************************************************************
6358+** acx_l_sta_list_get_from_hash
6359+*/
6360+static inline client_t*
6361+acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address)
6362+{
6363+ return adev->sta_hash_tab[address[5] % VEC_SIZE(adev->sta_hash_tab)];
6364+}
6365+
6366+
6367+/***********************************************************************
6368+** acx_l_sta_list_get
6369+*/
6370+client_t*
6371+acx_l_sta_list_get(acx_device_t *adev, const u8 *address)
6372+{
6373+ client_t *client;
6374+ FN_ENTER;
6375+ client = acx_l_sta_list_get_from_hash(adev, address);
6376+ while (client) {
6377+ if (mac_is_equal(address, client->address)) {
6378+ client->mtime = jiffies;
6379+ break;
6380+ }
6381+ client = client->next;
6382+ }
6383+ FN_EXIT0;
6384+ return client;
6385+}
6386+
6387+
6388+/***********************************************************************
6389+** acx_l_sta_list_del
6390+*/
6391+void
6392+acx_l_sta_list_del(acx_device_t *adev, client_t *victim)
6393+{
6394+ client_t *client, *next;
6395+
6396+ client = acx_l_sta_list_get_from_hash(adev, victim->address);
6397+ next = client;
6398+ /* tricky. next = client on first iteration only,
6399+ ** on all other iters next = client->next */
6400+ while (next) {
6401+ if (next == victim) {
6402+ client->next = victim->next;
6403+ /* Overkill */
6404+ memset(victim, 0, sizeof(*victim));
6405+ break;
6406+ }
6407+ client = next;
6408+ next = client->next;
6409+ }
6410+}
6411+
6412+
6413+/***********************************************************************
6414+** acx_l_sta_list_alloc
6415+**
6416+** Never fails - will evict oldest client if needed
6417+*/
6418+static client_t*
6419+acx_l_sta_list_alloc(acx_device_t *adev)
6420+{
6421+ int i;
6422+ unsigned long age, oldest_age;
6423+ client_t *client, *oldest;
6424+
6425+ FN_ENTER;
6426+
6427+ oldest = &adev->sta_list[0];
6428+ oldest_age = 0;
6429+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
6430+ client = &adev->sta_list[i];
6431+
6432+ if (!client->used) {
6433+ goto found;
6434+ } else {
6435+ age = jiffies - client->mtime;
6436+ if (oldest_age < age) {
6437+ oldest_age = age;
6438+ oldest = client;
6439+ }
6440+ }
6441+ }
6442+ acx_l_sta_list_del(adev, oldest);
6443+ client = oldest;
6444+found:
6445+ memset(client, 0, sizeof(*client));
6446+ FN_EXIT0;
6447+ return client;
6448+}
6449+
6450+
6451+/***********************************************************************
6452+** acx_l_sta_list_add
6453+**
6454+** Never fails - will evict oldest client if needed
6455+*/
6456+/* In case we will reimplement it differently... */
6457+#define STA_LIST_ADD_CAN_FAIL 0
6458+
6459+static client_t*
6460+acx_l_sta_list_add(acx_device_t *adev, const u8 *address)
6461+{
6462+ client_t *client;
6463+ int index;
6464+
6465+ FN_ENTER;
6466+
6467+ client = acx_l_sta_list_alloc(adev);
6468+
6469+ client->mtime = jiffies;
6470+ MAC_COPY(client->address, address);
6471+ client->used = CLIENT_EXIST_1;
6472+ client->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
6473+ client->auth_step = 1;
6474+ /* give some tentative peer rate values
6475+ ** (needed because peer may do auth without probing us first,
6476+ ** thus we'll have no idea of peer's ratevector yet).
6477+ ** Will be overwritten by scanning or assoc code */
6478+ client->rate_cap = adev->rate_basic;
6479+ client->rate_cfg = adev->rate_basic;
6480+ client->rate_cur = 1 << lowest_bit(adev->rate_basic);
6481+
6482+ index = address[5] % VEC_SIZE(adev->sta_hash_tab);
6483+ client->next = adev->sta_hash_tab[index];
6484+ adev->sta_hash_tab[index] = client;
6485+
6486+ acxlog_mac(L_ASSOC, "sta_list_add: sta=", address, "\n");
6487+
6488+ FN_EXIT0;
6489+ return client;
6490+}
6491+
6492+
6493+/***********************************************************************
6494+** acx_l_sta_list_get_or_add
6495+**
6496+** Never fails - will evict oldest client if needed
6497+*/
6498+static client_t*
6499+acx_l_sta_list_get_or_add(acx_device_t *adev, const u8 *address)
6500+{
6501+ client_t *client = acx_l_sta_list_get(adev, address);
6502+ if (!client)
6503+ client = acx_l_sta_list_add(adev, address);
6504+ return client;
6505+}
6506+
6507+
6508+/***********************************************************************
6509+** acx_set_status
6510+**
6511+** This function is called in many atomic regions, must not sleep
6512+**
6513+** This function does not need locking UNLESS you call it
6514+** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can
6515+** wake queue. This can race with stop_queue elsewhere.
6516+** See acx_stop_queue comment. */
6517+void
6518+acx_set_status(acx_device_t *adev, u16 new_status)
6519+{
6520+#define QUEUE_OPEN_AFTER_ASSOC 1 /* this really seems to be needed now */
6521+ u16 old_status = adev->status;
6522+
6523+ FN_ENTER;
6524+
6525+ log(L_ASSOC, "%s(%d):%s\n",
6526+ __func__, new_status, acx_get_status_name(new_status));
6527+
6528+ /* wireless_send_event never sleeps */
6529+ if (ACX_STATUS_4_ASSOCIATED == new_status) {
6530+ union iwreq_data wrqu;
6531+
6532+ wrqu.data.length = 0;
6533+ wrqu.data.flags = 0;
6534+ wireless_send_event(adev->ndev, SIOCGIWSCAN, &wrqu, NULL);
6535+
6536+ wrqu.data.length = 0;
6537+ wrqu.data.flags = 0;
6538+ MAC_COPY(wrqu.ap_addr.sa_data, adev->bssid);
6539+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6540+ wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL);
6541+ } else {
6542+ union iwreq_data wrqu;
6543+
6544+ /* send event with empty BSSID to indicate we're not associated */
6545+ MAC_ZERO(wrqu.ap_addr.sa_data);
6546+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6547+ wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL);
6548+ }
6549+
6550+ adev->status = new_status;
6551+
6552+ switch (new_status) {
6553+ case ACX_STATUS_1_SCANNING:
6554+ adev->scan_retries = 0;
6555+ /* 1.0 s initial scan time */
6556+ acx_set_timer(adev, 1000000);
6557+ break;
6558+ case ACX_STATUS_2_WAIT_AUTH:
6559+ case ACX_STATUS_3_AUTHENTICATED:
6560+ adev->auth_or_assoc_retries = 0;
6561+ acx_set_timer(adev, 1500000); /* 1.5 s */
6562+ break;
6563+ }
6564+
6565+#if QUEUE_OPEN_AFTER_ASSOC
6566+ if (new_status == ACX_STATUS_4_ASSOCIATED) {
6567+ if (old_status < ACX_STATUS_4_ASSOCIATED) {
6568+ /* ah, we're newly associated now,
6569+ * so let's indicate carrier */
6570+ acx_carrier_on(adev->ndev, "after association");
6571+ acx_wake_queue(adev->ndev, "after association");
6572+ }
6573+ } else {
6574+ /* not associated any more, so let's kill carrier */
6575+ if (old_status >= ACX_STATUS_4_ASSOCIATED) {
6576+ acx_carrier_off(adev->ndev, "after losing association");
6577+ acx_stop_queue(adev->ndev, "after losing association");
6578+ }
6579+ }
6580+#endif
6581+ FN_EXIT0;
6582+}
6583+
6584+
6585+/***********************************************************************
6586+** acx_i_timer
6587+**
6588+** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong
6589+*/
6590+void
6591+acx_i_timer(unsigned long address)
6592+{
6593+ unsigned long flags;
6594+ acx_device_t *adev = (acx_device_t*)address;
6595+
6596+ FN_ENTER;
6597+
6598+ acx_lock(adev, flags);
6599+
6600+ log(L_DEBUG|L_ASSOC, "%s: adev->status=%d (%s)\n",
6601+ __func__, adev->status, acx_get_status_name(adev->status));
6602+
6603+ switch (adev->status) {
6604+ case ACX_STATUS_1_SCANNING:
6605+ /* was set to 0 by set_status() */
6606+ if (++adev->scan_retries < 7) {
6607+ acx_set_timer(adev, 1000000);
6608+ /* used to interrogate for scan status.
6609+ ** We rely on SCAN_COMPLETE IRQ instead */
6610+ log(L_ASSOC, "continuing scan (%d sec)\n",
6611+ adev->scan_retries);
6612+ } else {
6613+ log(L_ASSOC, "stopping scan\n");
6614+ /* send stop_scan cmd when we leave the interrupt context,
6615+ * and make a decision what to do next (COMPLETE_SCAN) */
6616+ acx_schedule_task(adev,
6617+ ACX_AFTER_IRQ_CMD_STOP_SCAN + ACX_AFTER_IRQ_COMPLETE_SCAN);
6618+ }
6619+ break;
6620+ case ACX_STATUS_2_WAIT_AUTH:
6621+ /* was set to 0 by set_status() */
6622+ if (++adev->auth_or_assoc_retries < 10) {
6623+ log(L_ASSOC, "resend authen1 request (attempt %d)\n",
6624+ adev->auth_or_assoc_retries + 1);
6625+ acx_l_transmit_authen1(adev);
6626+ } else {
6627+ /* time exceeded: fall back to scanning mode */
6628+ log(L_ASSOC,
6629+ "authen1 request reply timeout, giving up\n");
6630+ /* we are a STA, need to find AP anyhow */
6631+ acx_set_status(adev, ACX_STATUS_1_SCANNING);
6632+ acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN);
6633+ }
6634+ /* used to be 1500000, but some other driver uses 2.5s */
6635+ acx_set_timer(adev, 2500000);
6636+ break;
6637+ case ACX_STATUS_3_AUTHENTICATED:
6638+ /* was set to 0 by set_status() */
6639+ if (++adev->auth_or_assoc_retries < 10) {
6640+ log(L_ASSOC, "resend assoc request (attempt %d)\n",
6641+ adev->auth_or_assoc_retries + 1);
6642+ acx_l_transmit_assoc_req(adev);
6643+ } else {
6644+ /* time exceeded: give up */
6645+ log(L_ASSOC,
6646+ "association request reply timeout, giving up\n");
6647+ /* we are a STA, need to find AP anyhow */
6648+ acx_set_status(adev, ACX_STATUS_1_SCANNING);
6649+ acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN);
6650+ }
6651+ acx_set_timer(adev, 2500000); /* see above */
6652+ break;
6653+ case ACX_STATUS_4_ASSOCIATED:
6654+ default:
6655+ break;
6656+ }
6657+
6658+ acx_unlock(adev, flags);
6659+
6660+ FN_EXIT0;
6661+}
6662+
6663+
6664+/***********************************************************************
6665+** acx_set_timer
6666+**
6667+** Sets the 802.11 state management timer's timeout.
6668+*/
6669+void
6670+acx_set_timer(acx_device_t *adev, int timeout_us)
6671+{
6672+ FN_ENTER;
6673+
6674+ log(L_DEBUG|L_IRQ, "%s(%u ms)\n", __func__, timeout_us/1000);
6675+ if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
6676+ printk("attempt to set the timer "
6677+ "when the card interface is not up!\n");
6678+ goto end;
6679+ }
6680+
6681+ /* first check if the timer was already initialized, THEN modify it */
6682+ if (adev->mgmt_timer.function) {
6683+ mod_timer(&adev->mgmt_timer,
6684+ jiffies + (timeout_us * HZ / 1000000));
6685+ }
6686+end:
6687+ FN_EXIT0;
6688+}
6689+
6690+
6691+/***********************************************************************
6692+** acx_l_transmit_assocresp
6693+**
6694+** We are an AP here
6695+*/
6696+static const u8
6697+dot11ratebyte[] = {
6698+ DOT11RATEBYTE_1,
6699+ DOT11RATEBYTE_2,
6700+ DOT11RATEBYTE_5_5,
6701+ DOT11RATEBYTE_6_G,
6702+ DOT11RATEBYTE_9_G,
6703+ DOT11RATEBYTE_11,
6704+ DOT11RATEBYTE_12_G,
6705+ DOT11RATEBYTE_18_G,
6706+ DOT11RATEBYTE_22,
6707+ DOT11RATEBYTE_24_G,
6708+ DOT11RATEBYTE_36_G,
6709+ DOT11RATEBYTE_48_G,
6710+ DOT11RATEBYTE_54_G,
6711+};
6712+
6713+static inline int
6714+find_pos(const u8 *p, int size, u8 v)
6715+{
6716+ int i;
6717+ for (i = 0; i < size; i++)
6718+ if (p[i] == v)
6719+ return i;
6720+ /* printk a message about strange byte? */
6721+ return 0;
6722+}
6723+
6724+static void
6725+add_bits_to_ratemasks(u8* ratevec, int len, u16* brate, u16* orate)
6726+{
6727+ while (len--) {
6728+ int n = 1 << find_pos(dot11ratebyte,
6729+ sizeof(dot11ratebyte), *ratevec & 0x7f);
6730+ if (*ratevec & 0x80)
6731+ *brate |= n;
6732+ *orate |= n;
6733+ ratevec++;
6734+ }
6735+}
6736+
6737+static int
6738+acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req)
6739+{
6740+ struct tx *tx;
6741+ struct wlan_hdr_mgmt *head;
6742+ struct assocresp_frame_body *body;
6743+ u8 *p;
6744+ const u8 *da;
6745+ /* const u8 *sa; */
6746+ const u8 *bssid;
6747+ client_t *clt;
6748+
6749+ FN_ENTER;
6750+
6751+ /* sa = req->hdr->a1; */
6752+ da = req->hdr->a2;
6753+ bssid = req->hdr->a3;
6754+
6755+ clt = acx_l_sta_list_get(adev, da);
6756+ if (!clt)
6757+ goto ok;
6758+
6759+ /* Assoc without auth is a big no-no */
6760+ /* Let's be liberal: if already assoc'ed STA sends assoc req again,
6761+ ** we won't be rude */
6762+ if (clt->used != CLIENT_AUTHENTICATED_2
6763+ && clt->used != CLIENT_ASSOCIATED_3) {
6764+ acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH);
6765+ goto bad;
6766+ }
6767+
6768+ clt->used = CLIENT_ASSOCIATED_3;
6769+
6770+ if (clt->aid == 0)
6771+ clt->aid = ++adev->aid;
6772+ clt->cap_info = ieee2host16(*(req->cap_info));
6773+
6774+ /* We cheat here a bit. We don't really care which rates are flagged
6775+ ** as basic by the client, so we stuff them in single ratemask */
6776+ clt->rate_cap = 0;
6777+ if (req->supp_rates)
6778+ add_bits_to_ratemasks(req->supp_rates->rates,
6779+ req->supp_rates->len, &clt->rate_cap, &clt->rate_cap);
6780+ if (req->ext_rates)
6781+ add_bits_to_ratemasks(req->ext_rates->rates,
6782+ req->ext_rates->len, &clt->rate_cap, &clt->rate_cap);
6783+ /* We can check that client supports all basic rates,
6784+ ** and deny assoc if not. But let's be liberal, right? ;) */
6785+ clt->rate_cfg = clt->rate_cap & adev->rate_oper;
6786+ if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper);
6787+ clt->rate_cur = 1 << lowest_bit(clt->rate_cfg);
6788+ if (IS_ACX100(adev))
6789+ clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)];
6790+ clt->fallback_count = clt->stepup_count = 0;
6791+ clt->ignore_count = 16;
6792+
6793+ tx = acx_l_alloc_tx(adev);
6794+ if (!tx)
6795+ goto bad;
6796+ head = acx_l_get_txbuf(adev, tx);
6797+ if (!head) {
6798+ acx_l_dealloc_tx(adev, tx);
6799+ goto bad;
6800+ }
6801+ body = (void*)(head + 1);
6802+
6803+ head->fc = WF_FSTYPE_ASSOCRESPi;
6804+ head->dur = req->hdr->dur;
6805+ MAC_COPY(head->da, da);
6806+ MAC_COPY(head->sa, adev->dev_addr);
6807+ MAC_COPY(head->bssid, bssid);
6808+ head->seq = req->hdr->seq;
6809+
6810+ body->cap_info = host2ieee16(adev->capabilities);
6811+ body->status = host2ieee16(0);
6812+ body->aid = host2ieee16(clt->aid);
6813+ p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len,
6814+ adev->rate_supported);
6815+ p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len,
6816+ adev->rate_supported);
6817+
6818+ acx_l_tx_data(adev, tx, p - (u8*)head);
6819+ok:
6820+ FN_EXIT1(OK);
6821+ return OK;
6822+bad:
6823+ FN_EXIT1(NOT_OK);
6824+ return NOT_OK;
6825+}
6826+
6827+
6828+/***********************************************************************
6829+* acx_l_transmit_reassocresp
6830+
6831+You may be wondering, just like me, what the hell ReAuth is.
6832+In practice it was seen sent by STA when STA feels like losing connection.
6833+
6834+[802.11]
6835+
6836+5.4.2.3 Reassociation
6837+
6838+Association is sufficient for no-transition message delivery between
6839+IEEE 802.11 stations. Additional functionality is needed to support
6840+BSS-transition mobility. The additional required functionality
6841+is provided by the reassociation service. Reassociation is a DSS.
6842+The reassociation service is invoked to 'move' a current association
6843+from one AP to another. This keeps the DS informed of the current
6844+mapping between AP and STA as the station moves from BSS to BSS within
6845+an ESS. Reassociation also enables changing association attributes
6846+of an established association while the STA remains associated with
6847+the same AP. Reassociation is always initiated by the mobile STA.
6848+
6849+5.4.3.1 Authentication
6850+...
6851+A STA may be authenticated with many other STAs at any given instant.
6852+
6853+5.4.3.1.1 Preauthentication
6854+
6855+Because the authentication process could be time-consuming (depending
6856+on the authentication protocol in use), the authentication service can
6857+be invoked independently of the association service. Preauthentication
6858+is typically done by a STA while it is already associated with an AP
6859+(with which it previously authenticated). IEEE 802.11 does not require
6860+that STAs preauthenticate with APs. However, authentication is required
6861+before an association can be established. If the authentication is left
6862+until reassociation time, this may impact the speed with which a STA can
6863+reassociate between APs, limiting BSS-transition mobility performance.
6864+The use of preauthentication takes the authentication service overhead
6865+out of the time-critical reassociation process.
6866+
6867+5.7.3 Reassociation
6868+
6869+For a STA to reassociate, the reassociation service causes the following
6870+message to occur:
6871+
6872+ Reassociation request
6873+
6874+* Message type: Management
6875+* Message subtype: Reassociation request
6876+* Information items:
6877+ - IEEE address of the STA
6878+ - IEEE address of the AP with which the STA will reassociate
6879+ - IEEE address of the AP with which the STA is currently associated
6880+ - ESSID
6881+* Direction of message: From STA to 'new' AP
6882+
6883+The address of the current AP is included for efficiency. The inclusion
6884+of the current AP address facilitates MAC reassociation to be independent
6885+of the DS implementation.
6886+
6887+ Reassociation response
6888+* Message type: Management
6889+* Message subtype: Reassociation response
6890+* Information items:
6891+ - Result of the requested reassociation. (success/failure)
6892+ - If the reassociation is successful, the response shall include the AID.
6893+* Direction of message: From AP to STA
6894+
6895+7.2.3.6 Reassociation Request frame format
6896+
6897+The frame body of a management frame of subtype Reassociation Request
6898+contains the information shown in Table 9.
6899+
6900+Table 9 Reassociation Request frame body
6901+Order Information
6902+1 Capability information
6903+2 Listen interval
6904+3 Current AP address
6905+4 SSID
6906+5 Supported rates
6907+
6908+7.2.3.7 Reassociation Response frame format
6909+
6910+The frame body of a management frame of subtype Reassociation Response
6911+contains the information shown in Table 10.
6912+
6913+Table 10 Reassociation Response frame body
6914+Order Information
6915+1 Capability information
6916+2 Status code
6917+3 Association ID (AID)
6918+4 Supported rates
6919+
6920+*/
6921+static int
6922+acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req)
6923+{
6924+ struct tx *tx;
6925+ struct wlan_hdr_mgmt *head;
6926+ struct reassocresp_frame_body *body;
6927+ u8 *p;
6928+ const u8 *da;
6929+ /* const u8 *sa; */
6930+ const u8 *bssid;
6931+ client_t *clt;
6932+
6933+ FN_ENTER;
6934+
6935+ /* sa = req->hdr->a1; */
6936+ da = req->hdr->a2;
6937+ bssid = req->hdr->a3;
6938+
6939+ /* Must be already authenticated, so it must be in the list */
6940+ clt = acx_l_sta_list_get(adev, da);
6941+ if (!clt)
6942+ goto ok;
6943+
6944+ /* Assoc without auth is a big no-no */
6945+ /* Already assoc'ed STAs sending ReAssoc req are ok per 802.11 */
6946+ if (clt->used != CLIENT_AUTHENTICATED_2
6947+ && clt->used != CLIENT_ASSOCIATED_3) {
6948+ acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH);
6949+ goto bad;
6950+ }
6951+
6952+ clt->used = CLIENT_ASSOCIATED_3;
6953+ if (clt->aid == 0) {
6954+ clt->aid = ++adev->aid;
6955+ }
6956+ if (req->cap_info)
6957+ clt->cap_info = ieee2host16(*(req->cap_info));
6958+
6959+ /* We cheat here a bit. We don't really care which rates are flagged
6960+ ** as basic by the client, so we stuff them in single ratemask */
6961+ clt->rate_cap = 0;
6962+ if (req->supp_rates)
6963+ add_bits_to_ratemasks(req->supp_rates->rates,
6964+ req->supp_rates->len, &clt->rate_cap, &clt->rate_cap);
6965+ if (req->ext_rates)
6966+ add_bits_to_ratemasks(req->ext_rates->rates,
6967+ req->ext_rates->len, &clt->rate_cap, &clt->rate_cap);
6968+ /* We can check that client supports all basic rates,
6969+ ** and deny assoc if not. But let's be liberal, right? ;) */
6970+ clt->rate_cfg = clt->rate_cap & adev->rate_oper;
6971+ if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper);
6972+ clt->rate_cur = 1 << lowest_bit(clt->rate_cfg);
6973+ if (IS_ACX100(adev))
6974+ clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)];
6975+
6976+ clt->fallback_count = clt->stepup_count = 0;
6977+ clt->ignore_count = 16;
6978+
6979+ tx = acx_l_alloc_tx(adev);
6980+ if (!tx)
6981+ goto ok;
6982+ head = acx_l_get_txbuf(adev, tx);
6983+ if (!head) {
6984+ acx_l_dealloc_tx(adev, tx);
6985+ goto ok;
6986+ }
6987+ body = (void*)(head + 1);
6988+
6989+ head->fc = WF_FSTYPE_REASSOCRESPi;
6990+ head->dur = req->hdr->dur;
6991+ MAC_COPY(head->da, da);
6992+ MAC_COPY(head->sa, adev->dev_addr);
6993+ MAC_COPY(head->bssid, bssid);
6994+ head->seq = req->hdr->seq;
6995+
6996+ /* IEs: 1. caps */
6997+ body->cap_info = host2ieee16(adev->capabilities);
6998+ /* 2. status code */
6999+ body->status = host2ieee16(0);
7000+ /* 3. AID */
7001+ body->aid = host2ieee16(clt->aid);
7002+ /* 4. supp rates */
7003+ p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len,
7004+ adev->rate_supported);
7005+ /* 5. ext supp rates */
7006+ p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len,
7007+ adev->rate_supported);
7008+
7009+ acx_l_tx_data(adev, tx, p - (u8*)head);
7010+ok:
7011+ FN_EXIT1(OK);
7012+ return OK;
7013+bad:
7014+ FN_EXIT1(NOT_OK);
7015+ return NOT_OK;
7016+}
7017+
7018+
7019+/***********************************************************************
7020+** acx_l_process_disassoc_from_sta
7021+*/
7022+static void
7023+acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req)
7024+{
7025+ const u8 *ta;
7026+ client_t *clt;
7027+
7028+ FN_ENTER;
7029+
7030+ ta = req->hdr->a2;
7031+ clt = acx_l_sta_list_get(adev, ta);
7032+ if (!clt)
7033+ goto end;
7034+
7035+ if (clt->used != CLIENT_ASSOCIATED_3
7036+ && clt->used != CLIENT_AUTHENTICATED_2) {
7037+ /* it's disassociating, but it's
7038+ ** not even authenticated! Let it know that */
7039+ acxlog_mac(L_ASSOC|L_XFER, "peer ", ta, "has sent disassoc "
7040+ "req but it is not even auth'ed! sending deauth\n");
7041+ acx_l_transmit_deauthen(adev, ta,
7042+ WLAN_MGMT_REASON_CLASS2_NONAUTH);
7043+ clt->used = CLIENT_EXIST_1;
7044+ } else {
7045+ /* mark it as auth'ed only */
7046+ clt->used = CLIENT_AUTHENTICATED_2;
7047+ }
7048+end:
7049+ FN_EXIT0;
7050+}
7051+
7052+
7053+/***********************************************************************
7054+** acx_l_process_deauthen_from_sta
7055+*/
7056+static void
7057+acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req)
7058+{
7059+ const wlan_hdr_t *hdr;
7060+ client_t *client;
7061+
7062+ FN_ENTER;
7063+
7064+ hdr = req->hdr;
7065+
7066+ if (acx_debug & L_ASSOC) {
7067+ acx_print_mac("got deauth from sta:", hdr->a2, " ");
7068+ acx_print_mac("a1:", hdr->a1, " ");
7069+ acx_print_mac("a3:", hdr->a3, " ");
7070+ acx_print_mac("adev->addr:", adev->dev_addr, " ");
7071+ acx_print_mac("adev->bssid:", adev->bssid, "\n");
7072+ }
7073+
7074+ if (!mac_is_equal(adev->dev_addr, hdr->a1)) {
7075+ goto end;
7076+ }
7077+
7078+ client = acx_l_sta_list_get(adev, hdr->a2);
7079+ if (!client) {
7080+ goto end;
7081+ }
7082+ client->used = CLIENT_EXIST_1;
7083+end:
7084+ FN_EXIT0;
7085+}
7086+
7087+
7088+/***********************************************************************
7089+** acx_l_process_disassoc_from_ap
7090+*/
7091+static void
7092+acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req)
7093+{
7094+ FN_ENTER;
7095+
7096+ if (!adev->ap_client) {
7097+ /* Hrm, we aren't assoc'ed yet anyhow... */
7098+ goto end;
7099+ }
7100+
7101+ printk("%s: got disassoc frame with reason %d (%s)\n",
7102+ adev->ndev->name, *req->reason,
7103+ acx_wlan_reason_str(*req->reason));
7104+
7105+ if (mac_is_equal(adev->dev_addr, req->hdr->a1)) {
7106+ acx_l_transmit_deauthen(adev, adev->bssid,
7107+ WLAN_MGMT_REASON_DEAUTH_LEAVING);
7108+ SET_BIT(adev->set_mask, GETSET_RESCAN);
7109+ acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
7110+ }
7111+end:
7112+ FN_EXIT0;
7113+}
7114+
7115+
7116+/***********************************************************************
7117+** acx_l_process_deauth_from_ap
7118+*/
7119+static void
7120+acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req)
7121+{
7122+ FN_ENTER;
7123+
7124+ if (!adev->ap_client) {
7125+ /* Hrm, we aren't assoc'ed yet anyhow... */
7126+ goto end;
7127+ }
7128+
7129+ printk("%s: got deauth frame with reason %d (%s)\n",
7130+ adev->ndev->name, *req->reason,
7131+ acx_wlan_reason_str(*req->reason));
7132+
7133+ /* Chk: is ta verified to be from our AP? */
7134+ if (mac_is_equal(adev->dev_addr, req->hdr->a1)) {
7135+ log(L_DEBUG, "AP sent us deauth packet\n");
7136+ SET_BIT(adev->set_mask, GETSET_RESCAN);
7137+ acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
7138+ }
7139+end:
7140+ FN_EXIT0;
7141+}
7142+
7143+
7144+/***********************************************************************
7145+** acx_l_rx
7146+**
7147+** The end of the Rx path. Pulls data from a rxhostdesc into a socket
7148+** buffer and feeds it to the network stack via netif_rx().
7149+*/
7150+static void
7151+acx_l_rx(acx_device_t *adev, rxbuffer_t *rxbuf)
7152+{
7153+ FN_ENTER;
7154+ if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
7155+ struct sk_buff *skb;
7156+ skb = acx_rxbuf_to_ether(adev, rxbuf);
7157+ if (likely(skb)) {
7158+ netif_rx(skb);
7159+ adev->ndev->last_rx = jiffies;
7160+ adev->stats.rx_packets++;
7161+ adev->stats.rx_bytes += skb->len;
7162+ }
7163+ }
7164+ FN_EXIT0;
7165+}
7166+
7167+
7168+/***********************************************************************
7169+** acx_l_process_data_frame_master
7170+*/
7171+static int
7172+acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf)
7173+{
7174+ struct wlan_hdr *hdr;
7175+ struct tx *tx;
7176+ void *txbuf;
7177+ int len;
7178+ int result = NOT_OK;
7179+
7180+ FN_ENTER;
7181+
7182+ hdr = acx_get_wlan_hdr(adev, rxbuf);
7183+
7184+ switch (WF_FC_FROMTODSi & hdr->fc) {
7185+ case 0:
7186+ case WF_FC_FROMDSi:
7187+ log(L_DEBUG, "ap->sta or adhoc->adhoc data frame ignored\n");
7188+ goto done;
7189+ case WF_FC_TODSi:
7190+ break;
7191+ default: /* WF_FC_FROMTODSi */
7192+ log(L_DEBUG, "wds data frame ignored (TODO)\n");
7193+ goto done;
7194+ }
7195+
7196+ /* check if it is our BSSID, if not, leave */
7197+ if (!mac_is_equal(adev->bssid, hdr->a1)) {
7198+ goto done;
7199+ }
7200+
7201+ if (mac_is_equal(adev->dev_addr, hdr->a3)) {
7202+ /* this one is for us */
7203+ acx_l_rx(adev, rxbuf);
7204+ } else {
7205+ if (mac_is_bcast(hdr->a3)) {
7206+ /* this one is bcast, rx it too */
7207+ acx_l_rx(adev, rxbuf);
7208+ }
7209+ tx = acx_l_alloc_tx(adev);
7210+ if (!tx) {
7211+ goto fail;
7212+ }
7213+ /* repackage, tx, and hope it someday reaches its destination */
7214+ /* order is important, we do it in-place */
7215+ MAC_COPY(hdr->a1, hdr->a3);
7216+ MAC_COPY(hdr->a3, hdr->a2);
7217+ MAC_COPY(hdr->a2, adev->bssid);
7218+ /* To_DS = 0, From_DS = 1 */
7219+ hdr->fc = WF_FC_FROMDSi + WF_FTYPE_DATAi;
7220+
7221+ txbuf = acx_l_get_txbuf(adev, tx);
7222+ if (txbuf) {
7223+ len = RXBUF_BYTES_RCVD(adev, rxbuf);
7224+ memcpy(txbuf, hdr, len);
7225+ acx_l_tx_data(adev, tx, len);
7226+ } else {
7227+ acx_l_dealloc_tx(adev, tx);
7228+ }
7229+ }
7230+done:
7231+ result = OK;
7232+fail:
7233+ FN_EXIT1(result);
7234+ return result;
7235+}
7236+
7237+
7238+/***********************************************************************
7239+** acx_l_process_data_frame_client
7240+*/
7241+static int
7242+acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf)
7243+{
7244+ const u8 *da, *bssid;
7245+ const wlan_hdr_t *hdr;
7246+ struct net_device *ndev = adev->ndev;
7247+ int result = NOT_OK;
7248+
7249+ FN_ENTER;
7250+
7251+ if (ACX_STATUS_4_ASSOCIATED != adev->status)
7252+ goto drop;
7253+
7254+ hdr = acx_get_wlan_hdr(adev, rxbuf);
7255+
7256+ switch (WF_FC_FROMTODSi & hdr->fc) {
7257+ case 0:
7258+ if (adev->mode != ACX_MODE_0_ADHOC) {
7259+ log(L_DEBUG, "adhoc->adhoc data frame ignored\n");
7260+ goto drop;
7261+ }
7262+ bssid = hdr->a3;
7263+ break;
7264+ case WF_FC_FROMDSi:
7265+ if (adev->mode != ACX_MODE_2_STA) {
7266+ log(L_DEBUG, "ap->sta data frame ignored\n");
7267+ goto drop;
7268+ }
7269+ bssid = hdr->a2;
7270+ break;
7271+ case WF_FC_TODSi:
7272+ log(L_DEBUG, "sta->ap data frame ignored\n");
7273+ goto drop;
7274+ default: /* WF_FC_FROMTODSi: wds->wds */
7275+ log(L_DEBUG, "wds data frame ignored (todo)\n");
7276+ goto drop;
7277+ }
7278+
7279+ da = hdr->a1;
7280+
7281+ if (unlikely(acx_debug & L_DEBUG)) {
7282+ acx_print_mac("rx: da=", da, "");
7283+ acx_print_mac(" bssid=", bssid, "");
7284+ acx_print_mac(" adev->bssid=", adev->bssid, "");
7285+ acx_print_mac(" adev->addr=", adev->dev_addr, "\n");
7286+ }
7287+
7288+ /* promiscuous mode --> receive all packets */
7289+ if (unlikely(ndev->flags & IFF_PROMISC))
7290+ goto process;
7291+
7292+ /* FIRST, check if it is our BSSID */
7293+ if (!mac_is_equal(adev->bssid, bssid)) {
7294+ /* is not our BSSID, so bail out */
7295+ goto drop;
7296+ }
7297+
7298+ /* then, check if it is our address */
7299+ if (mac_is_equal(adev->dev_addr, da)) {
7300+ goto process;
7301+ }
7302+
7303+ /* then, check if it is broadcast */
7304+ if (mac_is_bcast(da)) {
7305+ goto process;
7306+ }
7307+
7308+ if (mac_is_mcast(da)) {
7309+ /* unconditionally receive all multicasts */
7310+ if (ndev->flags & IFF_ALLMULTI)
7311+ goto process;
7312+
7313+ /* FIXME: need to check against the list of
7314+ * multicast addresses that are configured
7315+ * for the interface (ifconfig) */
7316+ log(L_XFER, "FIXME: multicast packet, need to check "
7317+ "against a list of multicast addresses "
7318+ "(to be created!); accepting packet for now\n");
7319+ /* for now, just accept it here */
7320+ goto process;
7321+ }
7322+
7323+ log(L_DEBUG, "rx: foreign packet, dropping\n");
7324+ goto drop;
7325+process:
7326+ /* receive packet */
7327+ acx_l_rx(adev, rxbuf);
7328+
7329+ result = OK;
7330+drop:
7331+ FN_EXIT1(result);
7332+ return result;
7333+}
7334+
7335+
7336+/***********************************************************************
7337+** acx_l_process_mgmt_frame
7338+**
7339+** Theory of operation: mgmt packet gets parsed (to make it easy
7340+** to access variable-sized IEs), results stored in 'parsed'.
7341+** Then we react to the packet.
7342+*/
7343+typedef union parsed_mgmt_req {
7344+ wlan_fr_mgmt_t mgmt;
7345+ wlan_fr_assocreq_t assocreq;
7346+ wlan_fr_reassocreq_t reassocreq;
7347+ wlan_fr_assocresp_t assocresp;
7348+ wlan_fr_reassocresp_t reassocresp;
7349+ wlan_fr_beacon_t beacon;
7350+ wlan_fr_disassoc_t disassoc;
7351+ wlan_fr_authen_t authen;
7352+ wlan_fr_deauthen_t deauthen;
7353+ wlan_fr_proberesp_t proberesp;
7354+} parsed_mgmt_req_t;
7355+
7356+void BUG_excessive_stack_usage(void);
7357+
7358+static int
7359+acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf)
7360+{
7361+ parsed_mgmt_req_t parsed; /* takes ~100 bytes of stack */
7362+ wlan_hdr_t *hdr;
7363+ int adhoc, sta_scan, sta, ap;
7364+ int len;
7365+
7366+ if (sizeof(parsed) > 256)
7367+ BUG_excessive_stack_usage();
7368+
7369+ FN_ENTER;
7370+
7371+ hdr = acx_get_wlan_hdr(adev, rxbuf);
7372+
7373+ /* Management frames never have these set */
7374+ if (WF_FC_FROMTODSi & hdr->fc) {
7375+ FN_EXIT1(NOT_OK);
7376+ return NOT_OK;
7377+ }
7378+
7379+ len = RXBUF_BYTES_RCVD(adev, rxbuf);
7380+ if (WF_FC_ISWEPi & hdr->fc)
7381+ len -= 0x10;
7382+
7383+ adhoc = (adev->mode == ACX_MODE_0_ADHOC);
7384+ sta_scan = ((adev->mode == ACX_MODE_2_STA)
7385+ && (adev->status != ACX_STATUS_4_ASSOCIATED));
7386+ sta = ((adev->mode == ACX_MODE_2_STA)
7387+ && (adev->status == ACX_STATUS_4_ASSOCIATED));
7388+ ap = (adev->mode == ACX_MODE_3_AP);
7389+
7390+ switch (WF_FC_FSTYPEi & hdr->fc) {
7391+ /* beacons first, for speed */
7392+ case WF_FSTYPE_BEACONi:
7393+ memset(&parsed.beacon, 0, sizeof(parsed.beacon));
7394+ parsed.beacon.hdr = hdr;
7395+ parsed.beacon.len = len;
7396+ if (acx_debug & L_DATA) {
7397+ printk("beacon len:%d fc:%04X dur:%04X seq:%04X",
7398+ len, hdr->fc, hdr->dur, hdr->seq);
7399+ acx_print_mac(" a1:", hdr->a1, "");
7400+ acx_print_mac(" a2:", hdr->a2, "");
7401+ acx_print_mac(" a3:", hdr->a3, "\n");
7402+ }
7403+ wlan_mgmt_decode_beacon(&parsed.beacon);
7404+ /* beacon and probe response are very similar, so... */
7405+ acx_l_process_probe_response(adev, &parsed.beacon, rxbuf);
7406+ break;
7407+ case WF_FSTYPE_ASSOCREQi:
7408+ if (!ap)
7409+ break;
7410+ memset(&parsed.assocreq, 0, sizeof(parsed.assocreq));
7411+ parsed.assocreq.hdr = hdr;
7412+ parsed.assocreq.len = len;
7413+ wlan_mgmt_decode_assocreq(&parsed.assocreq);
7414+ if (mac_is_equal(hdr->a1, adev->bssid)
7415+ && mac_is_equal(hdr->a3, adev->bssid)) {
7416+ acx_l_transmit_assocresp(adev, &parsed.assocreq);
7417+ }
7418+ break;
7419+ case WF_FSTYPE_REASSOCREQi:
7420+ if (!ap)
7421+ break;
7422+ memset(&parsed.assocreq, 0, sizeof(parsed.assocreq));
7423+ parsed.assocreq.hdr = hdr;
7424+ parsed.assocreq.len = len;
7425+ wlan_mgmt_decode_assocreq(&parsed.assocreq);
7426+ /* reassocreq and assocreq are equivalent */
7427+ acx_l_transmit_reassocresp(adev, &parsed.reassocreq);
7428+ break;
7429+ case WF_FSTYPE_ASSOCRESPi:
7430+ if (!sta_scan)
7431+ break;
7432+ memset(&parsed.assocresp, 0, sizeof(parsed.assocresp));
7433+ parsed.assocresp.hdr = hdr;
7434+ parsed.assocresp.len = len;
7435+ wlan_mgmt_decode_assocresp(&parsed.assocresp);
7436+ acx_l_process_assocresp(adev, &parsed.assocresp);
7437+ break;
7438+ case WF_FSTYPE_REASSOCRESPi:
7439+ if (!sta_scan)
7440+ break;
7441+ memset(&parsed.assocresp, 0, sizeof(parsed.assocresp));
7442+ parsed.assocresp.hdr = hdr;
7443+ parsed.assocresp.len = len;
7444+ wlan_mgmt_decode_assocresp(&parsed.assocresp);
7445+ acx_l_process_reassocresp(adev, &parsed.reassocresp);
7446+ break;
7447+ case WF_FSTYPE_PROBEREQi:
7448+ if (ap || adhoc) {
7449+ /* FIXME: since we're supposed to be an AP,
7450+ ** we need to return a Probe Response packet.
7451+ ** Currently firmware is doing it for us,
7452+ ** but firmware is buggy! See comment elsewhere --vda */
7453+ }
7454+ break;
7455+ case WF_FSTYPE_PROBERESPi:
7456+ memset(&parsed.proberesp, 0, sizeof(parsed.proberesp));
7457+ parsed.proberesp.hdr = hdr;
7458+ parsed.proberesp.len = len;
7459+ wlan_mgmt_decode_proberesp(&parsed.proberesp);
7460+ acx_l_process_probe_response(adev, &parsed.proberesp, rxbuf);
7461+ break;
7462+ case 6:
7463+ case 7:
7464+ /* exit */
7465+ break;
7466+ case WF_FSTYPE_ATIMi:
7467+ /* exit */
7468+ break;
7469+ case WF_FSTYPE_DISASSOCi:
7470+ if (!sta && !ap)
7471+ break;
7472+ memset(&parsed.disassoc, 0, sizeof(parsed.disassoc));
7473+ parsed.disassoc.hdr = hdr;
7474+ parsed.disassoc.len = len;
7475+ wlan_mgmt_decode_disassoc(&parsed.disassoc);
7476+ if (sta)
7477+ acx_l_process_disassoc_from_ap(adev, &parsed.disassoc);
7478+ else
7479+ acx_l_process_disassoc_from_sta(adev, &parsed.disassoc);
7480+ break;
7481+ case WF_FSTYPE_AUTHENi:
7482+ if (!sta_scan && !ap)
7483+ break;
7484+ memset(&parsed.authen, 0, sizeof(parsed.authen));
7485+ parsed.authen.hdr = hdr;
7486+ parsed.authen.len = len;
7487+ wlan_mgmt_decode_authen(&parsed.authen);
7488+ acx_l_process_authen(adev, &parsed.authen);
7489+ break;
7490+ case WF_FSTYPE_DEAUTHENi:
7491+ if (!sta && !ap)
7492+ break;
7493+ memset(&parsed.deauthen, 0, sizeof(parsed.deauthen));
7494+ parsed.deauthen.hdr = hdr;
7495+ parsed.deauthen.len = len;
7496+ wlan_mgmt_decode_deauthen(&parsed.deauthen);
7497+ if (sta)
7498+ acx_l_process_deauth_from_ap(adev, &parsed.deauthen);
7499+ else
7500+ acx_l_process_deauth_from_sta(adev, &parsed.deauthen);
7501+ break;
7502+ }
7503+
7504+ FN_EXIT1(OK);
7505+ return OK;
7506+}
7507+
7508+
7509+#ifdef UNUSED
7510+/***********************************************************************
7511+** acx_process_class_frame
7512+**
7513+** Called from IRQ context only
7514+*/
7515+static int
7516+acx_process_class_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala)
7517+{
7518+ return OK;
7519+}
7520+#endif
7521+
7522+
7523+/***********************************************************************
7524+** acx_l_process_NULL_frame
7525+*/
7526+#ifdef BOGUS_ITS_NOT_A_NULL_FRAME_HANDLER_AT_ALL
7527+static int
7528+acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala)
7529+{
7530+ const signed char *esi;
7531+ const u8 *ebx;
7532+ const wlan_hdr_t *hdr;
7533+ const client_t *client;
7534+ int result = NOT_OK;
7535+
7536+ hdr = acx_get_wlan_hdr(adev, rxbuf);
7537+
7538+ switch (WF_FC_FROMTODSi & hdr->fc) {
7539+ case 0:
7540+ esi = hdr->a1;
7541+ ebx = hdr->a2;
7542+ break;
7543+ case WF_FC_FROMDSi:
7544+ esi = hdr->a1;
7545+ ebx = hdr->a3;
7546+ break;
7547+ case WF_FC_TODSi:
7548+ esi = hdr->a1;
7549+ ebx = hdr->a2;
7550+ break;
7551+ default: /* WF_FC_FROMTODSi */
7552+ esi = hdr->a1; /* added by me! --vda */
7553+ ebx = hdr->a2;
7554+ }
7555+
7556+ if (esi[0x0] < 0) {
7557+ result = OK;
7558+ goto done;
7559+ }
7560+
7561+ client = acx_l_sta_list_get(adev, ebx);
7562+ if (client)
7563+ result = NOT_OK;
7564+ else {
7565+#ifdef IS_IT_BROKEN
7566+ log(L_DEBUG|L_XFER, "<transmit_deauth 7>\n");
7567+ acx_l_transmit_deauthen(adev, ebx,
7568+ WLAN_MGMT_REASON_CLASS2_NONAUTH);
7569+#else
7570+ log(L_DEBUG, "received NULL frame from unknown client! "
7571+ "We really shouldn't send deauthen here, right?\n");
7572+#endif
7573+ result = OK;
7574+ }
7575+done:
7576+ return result;
7577+}
7578+#endif
7579+
7580+
7581+/***********************************************************************
7582+** acx_l_process_probe_response
7583+*/
7584+static int
7585+acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req,
7586+ const rxbuffer_t *rxbuf)
7587+{
7588+ struct client *bss;
7589+ wlan_hdr_t *hdr;
7590+
7591+ FN_ENTER;
7592+
7593+ hdr = req->hdr;
7594+
7595+ if (mac_is_equal(hdr->a3, adev->dev_addr)) {
7596+ log(L_ASSOC, "huh, scan found our own MAC!?\n");
7597+ goto ok; /* just skip this one silently */
7598+ }
7599+
7600+ bss = acx_l_sta_list_get_or_add(adev, hdr->a2);
7601+
7602+ /* NB: be careful modifying bss data! It may be one
7603+ ** of the already known clients (like our AP if we are a STA)
7604+ ** Thus do not blindly modify e.g. current ratemask! */
7605+
7606+ if (STA_LIST_ADD_CAN_FAIL && !bss) {
7607+ /* uh oh, we found more sites/stations than we can handle with
7608+ * our current setup: pull the emergency brake and stop scanning! */
7609+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_STOP_SCAN);
7610+ /* TODO: a nice comment what below call achieves --vda */
7611+ acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH);
7612+ goto ok;
7613+ }
7614+ /* NB: get_or_add already filled bss->address = hdr->a2 */
7615+ MAC_COPY(bss->bssid, hdr->a3);
7616+
7617+ /* copy the ESSID element */
7618+ if (req->ssid && req->ssid->len <= IW_ESSID_MAX_SIZE) {
7619+ bss->essid_len = req->ssid->len;
7620+ memcpy(bss->essid, req->ssid->ssid, req->ssid->len);
7621+ bss->essid[req->ssid->len] = '\0';
7622+ } else {
7623+ /* Either no ESSID IE or oversized one */
7624+ printk("%s: received packet has bogus ESSID\n",
7625+ adev->ndev->name);
7626+ }
7627+
7628+ if (req->ds_parms)
7629+ bss->channel = req->ds_parms->curr_ch;
7630+ if (req->cap_info)
7631+ bss->cap_info = ieee2host16(*req->cap_info);
7632+
7633+ bss->sir = acx_signal_to_winlevel(rxbuf->phy_level);
7634+ bss->snr = acx_signal_to_winlevel(rxbuf->phy_snr);
7635+
7636+ bss->rate_cap = 0; /* operational mask */
7637+ bss->rate_bas = 0; /* basic mask */
7638+ if (req->supp_rates)
7639+ add_bits_to_ratemasks(req->supp_rates->rates,
7640+ req->supp_rates->len, &bss->rate_bas, &bss->rate_cap);
7641+ if (req->ext_rates)
7642+ add_bits_to_ratemasks(req->ext_rates->rates,
7643+ req->ext_rates->len, &bss->rate_bas, &bss->rate_cap);
7644+ /* Fix up any possible bogosity - code elsewhere
7645+ * is not expecting empty masks */
7646+ if (!bss->rate_cap)
7647+ bss->rate_cap = adev->rate_basic;
7648+ if (!bss->rate_bas)
7649+ bss->rate_bas = 1 << lowest_bit(bss->rate_cap);
7650+ if (!bss->rate_cur)
7651+ bss->rate_cur = 1 << lowest_bit(bss->rate_bas);
7652+
7653+ /* People moan about this being too noisy at L_ASSOC */
7654+ log(L_DEBUG,
7655+ "found %s: ESSID=\"%s\" ch=%d "
7656+ "BSSID="MACSTR" caps=0x%04X SIR=%d SNR=%d\n",
7657+ (bss->cap_info & WF_MGMT_CAP_IBSS) ? "Ad-Hoc peer" : "AP",
7658+ bss->essid, bss->channel, MAC(bss->bssid), bss->cap_info,
7659+ bss->sir, bss->snr);
7660+ok:
7661+ FN_EXIT0;
7662+ return OK;
7663+}
7664+
7665+
7666+/***********************************************************************
7667+** acx_l_process_assocresp
7668+*/
7669+static int
7670+acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req)
7671+{
7672+ const wlan_hdr_t *hdr;
7673+ int res = OK;
7674+
7675+ FN_ENTER;
7676+
7677+ hdr = req->hdr;
7678+
7679+ if ((ACX_MODE_2_STA == adev->mode)
7680+ && mac_is_equal(adev->dev_addr, hdr->a1)) {
7681+ u16 st = ieee2host16(*(req->status));
7682+ if (WLAN_MGMT_STATUS_SUCCESS == st) {
7683+ adev->aid = ieee2host16(*(req->aid));
7684+ /* tell the card we are associated when
7685+ ** we are out of interrupt context */
7686+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_ASSOCIATE);
7687+ } else {
7688+
7689+ /* TODO: we shall delete peer from sta_list, and try
7690+ ** other candidates... */
7691+
7692+ printk("%s: association FAILED: peer sent "
7693+ "Status Code %d (%s)\n",
7694+ adev->ndev->name, st, get_status_string(st));
7695+ res = NOT_OK;
7696+ }
7697+ }
7698+
7699+ FN_EXIT1(res);
7700+ return res;
7701+}
7702+
7703+
7704+/***********************************************************************
7705+** acx_l_process_reassocresp
7706+*/
7707+static int
7708+acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req)
7709+{
7710+ const wlan_hdr_t *hdr;
7711+ int result = NOT_OK;
7712+ u16 st;
7713+
7714+ FN_ENTER;
7715+
7716+ hdr = req->hdr;
7717+
7718+ if (!mac_is_equal(adev->dev_addr, hdr->a1)) {
7719+ goto end;
7720+ }
7721+ st = ieee2host16(*(req->status));
7722+ if (st == WLAN_MGMT_STATUS_SUCCESS) {
7723+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED);
7724+ result = OK;
7725+ } else {
7726+ printk("%s: reassociation FAILED: peer sent "
7727+ "response code %d (%s)\n",
7728+ adev->ndev->name, st, get_status_string(st));
7729+ }
7730+end:
7731+ FN_EXIT1(result);
7732+ return result;
7733+}
7734+
7735+
7736+/***********************************************************************
7737+** acx_l_process_authen
7738+**
7739+** Called only in STA_SCAN or AP mode
7740+*/
7741+static int
7742+acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req)
7743+{
7744+ const wlan_hdr_t *hdr;
7745+ client_t *clt;
7746+ wlan_ie_challenge_t *chal;
7747+ u16 alg, seq, status;
7748+ int ap, result;
7749+
7750+ FN_ENTER;
7751+
7752+ hdr = req->hdr;
7753+
7754+ if (acx_debug & L_ASSOC) {
7755+ acx_print_mac("AUTHEN adev->addr=", adev->dev_addr, " ");
7756+ acx_print_mac("a1=", hdr->a1, " ");
7757+ acx_print_mac("a2=", hdr->a2, " ");
7758+ acx_print_mac("a3=", hdr->a3, " ");
7759+ acx_print_mac("adev->bssid=", adev->bssid, "\n");
7760+ }
7761+
7762+ if (!mac_is_equal(adev->dev_addr, hdr->a1)
7763+ || !mac_is_equal(adev->bssid, hdr->a3)) {
7764+ result = OK;
7765+ goto end;
7766+ }
7767+
7768+ alg = ieee2host16(*(req->auth_alg));
7769+ seq = ieee2host16(*(req->auth_seq));
7770+ status = ieee2host16(*(req->status));
7771+
7772+ log(L_ASSOC, "auth algorithm %d, auth sequence %d, status %d\n", alg, seq, status);
7773+
7774+ ap = (adev->mode == ACX_MODE_3_AP);
7775+
7776+ if (adev->auth_alg <= 1) {
7777+ if (adev->auth_alg != alg) {
7778+ log(L_ASSOC, "auth algorithm mismatch: "
7779+ "our:%d peer:%d\n", adev->auth_alg, alg);
7780+ result = NOT_OK;
7781+ goto end;
7782+ }
7783+ }
7784+ if (ap) {
7785+ clt = acx_l_sta_list_get_or_add(adev, hdr->a2);
7786+ if (STA_LIST_ADD_CAN_FAIL && !clt) {
7787+ log(L_ASSOC, "could not allocate room for client\n");
7788+ result = NOT_OK;
7789+ goto end;
7790+ }
7791+ } else {
7792+ clt = adev->ap_client;
7793+ if (!mac_is_equal(clt->address, hdr->a2)) {
7794+ printk("%s: malformed auth frame from AP?!\n",
7795+ adev->ndev->name);
7796+ result = NOT_OK;
7797+ goto end;
7798+ }
7799+ }
7800+
7801+ /* now check which step in the authentication sequence we are
7802+ * currently in, and act accordingly */
7803+ switch (seq) {
7804+ case 1:
7805+ if (!ap)
7806+ break;
7807+ acx_l_transmit_authen2(adev, req, clt);
7808+ break;
7809+ case 2:
7810+ if (ap)
7811+ break;
7812+ if (status == WLAN_MGMT_STATUS_SUCCESS) {
7813+ if (alg == WLAN_AUTH_ALG_OPENSYSTEM) {
7814+ acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED);
7815+ acx_l_transmit_assoc_req(adev);
7816+ } else
7817+ if (alg == WLAN_AUTH_ALG_SHAREDKEY) {
7818+ acx_l_transmit_authen3(adev, req);
7819+ }
7820+ } else {
7821+ printk("%s: auth FAILED: peer sent "
7822+ "response code %d (%s), "
7823+ "still waiting for authentication\n",
7824+ adev->ndev->name,
7825+ status, get_status_string(status));
7826+ acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH);
7827+ }
7828+ break;
7829+ case 3:
7830+ if (!ap)
7831+ break;
7832+ if ((clt->auth_alg != WLAN_AUTH_ALG_SHAREDKEY)
7833+ || (alg != WLAN_AUTH_ALG_SHAREDKEY)
7834+ || (clt->auth_step != 2))
7835+ break;
7836+ chal = req->challenge;
7837+ if (!chal
7838+ || memcmp(chal->challenge, clt->challenge_text, WLAN_CHALLENGE_LEN)
7839+ || (chal->eid != WLAN_EID_CHALLENGE)
7840+ || (chal->len != WLAN_CHALLENGE_LEN)
7841+ )
7842+ break;
7843+ acx_l_transmit_authen4(adev, req);
7844+ MAC_COPY(clt->address, hdr->a2);
7845+ clt->used = CLIENT_AUTHENTICATED_2;
7846+ clt->auth_step = 4;
7847+ clt->seq = ieee2host16(hdr->seq);
7848+ break;
7849+ case 4:
7850+ if (ap)
7851+ break;
7852+ /* ok, we're through: we're authenticated. Woohoo!! */
7853+ acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED);
7854+ log(L_ASSOC, "Authenticated!\n");
7855+ /* now that we're authenticated, request association */
7856+ acx_l_transmit_assoc_req(adev);
7857+ break;
7858+ }
7859+ result = OK;
7860+end:
7861+ FN_EXIT1(result);
7862+ return result;
7863+}
7864+
7865+
7866+/***********************************************************************
7867+** acx_gen_challenge
7868+*/
7869+static inline void
7870+acx_gen_challenge(wlan_ie_challenge_t* d)
7871+{
7872+ FN_ENTER;
7873+ d->eid = WLAN_EID_CHALLENGE;
7874+ d->len = WLAN_CHALLENGE_LEN;
7875+ get_random_bytes(d->challenge, WLAN_CHALLENGE_LEN);
7876+ FN_EXIT0;
7877+}
7878+
7879+
7880+/***********************************************************************
7881+** acx_l_transmit_deauthen
7882+*/
7883+static int
7884+acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason)
7885+{
7886+ struct tx *tx;
7887+ struct wlan_hdr_mgmt *head;
7888+ struct deauthen_frame_body *body;
7889+
7890+ FN_ENTER;
7891+
7892+ tx = acx_l_alloc_tx(adev);
7893+ if (!tx)
7894+ goto bad;
7895+ head = acx_l_get_txbuf(adev, tx);
7896+ if (!head) {
7897+ acx_l_dealloc_tx(adev, tx);
7898+ goto bad;
7899+ }
7900+ body = (void*)(head + 1);
7901+
7902+ head->fc = (WF_FTYPE_MGMTi | WF_FSTYPE_DEAUTHENi);
7903+ head->dur = 0;
7904+ MAC_COPY(head->da, addr);
7905+ MAC_COPY(head->sa, adev->dev_addr);
7906+ MAC_COPY(head->bssid, adev->bssid);
7907+ head->seq = 0;
7908+
7909+ log(L_DEBUG|L_ASSOC|L_XFER,
7910+ "sending deauthen to "MACSTR" for %d\n",
7911+ MAC(addr), reason);
7912+
7913+ body->reason = host2ieee16(reason);
7914+
7915+ /* body is fixed size here, but beware of cutting-and-pasting this -
7916+ ** do not use sizeof(*body) for variable sized mgmt packets! */
7917+ acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body));
7918+
7919+ FN_EXIT1(OK);
7920+ return OK;
7921+bad:
7922+ FN_EXIT1(NOT_OK);
7923+ return NOT_OK;
7924+}
7925+
7926+
7927+/***********************************************************************
7928+** acx_l_transmit_authen1
7929+*/
7930+static int
7931+acx_l_transmit_authen1(acx_device_t *adev)
7932+{
7933+ struct tx *tx;
7934+ struct wlan_hdr_mgmt *head;
7935+ struct auth_frame_body *body;
7936+
7937+ FN_ENTER;
7938+
7939+ log(L_ASSOC, "sending authentication1 request (auth algo %d), "
7940+ "awaiting response\n", adev->auth_alg);
7941+
7942+ tx = acx_l_alloc_tx(adev);
7943+ if (!tx)
7944+ goto bad;
7945+ head = acx_l_get_txbuf(adev, tx);
7946+ if (!head) {
7947+ acx_l_dealloc_tx(adev, tx);
7948+ goto bad;
7949+ }
7950+ body = (void*)(head + 1);
7951+
7952+ head->fc = WF_FSTYPE_AUTHENi;
7953+ /* duration should be 0 instead of 0x8000 to have
7954+ * the firmware calculate the value, right? */
7955+ head->dur = 0;
7956+ MAC_COPY(head->da, adev->bssid);
7957+ MAC_COPY(head->sa, adev->dev_addr);
7958+ MAC_COPY(head->bssid, adev->bssid);
7959+ head->seq = 0;
7960+
7961+ body->auth_alg = host2ieee16(adev->auth_alg);
7962+ body->auth_seq = host2ieee16(1);
7963+ body->status = host2ieee16(0);
7964+
7965+ acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2);
7966+
7967+ FN_EXIT1(OK);
7968+ return OK;
7969+bad:
7970+ FN_EXIT1(NOT_OK);
7971+ return NOT_OK;
7972+}
7973+
7974+
7975+/***********************************************************************
7976+** acx_l_transmit_authen2
7977+*/
7978+static int
7979+acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req,
7980+ client_t *clt)
7981+{
7982+ struct tx *tx;
7983+ struct wlan_hdr_mgmt *head;
7984+ struct auth_frame_body *body;
7985+ unsigned int packet_len;
7986+
7987+ FN_ENTER;
7988+
7989+ if (!clt)
7990+ goto ok;
7991+
7992+ MAC_COPY(clt->address, req->hdr->a2);
7993+#ifdef UNUSED
7994+ clt->ps = ((WF_FC_PWRMGTi & req->hdr->fc) != 0);
7995+#endif
7996+ clt->auth_alg = ieee2host16(*(req->auth_alg));
7997+ clt->auth_step = 2;
7998+ clt->seq = ieee2host16(req->hdr->seq);
7999+
8000+ tx = acx_l_alloc_tx(adev);
8001+ if (!tx)
8002+ goto bad;
8003+ head = acx_l_get_txbuf(adev, tx);
8004+ if (!head) {
8005+ acx_l_dealloc_tx(adev, tx);
8006+ goto bad;
8007+ }
8008+ body = (void*)(head + 1);
8009+
8010+ head->fc = WF_FSTYPE_AUTHENi;
8011+ head->dur = 0 /* req->hdr->dur */;
8012+ MAC_COPY(head->da, req->hdr->a2);
8013+ MAC_COPY(head->sa, adev->dev_addr);
8014+ MAC_COPY(head->bssid, req->hdr->a3);
8015+ head->seq = 0 /* req->hdr->seq */;
8016+
8017+ /* already in IEEE format, no endianness conversion */
8018+ body->auth_alg = *(req->auth_alg);
8019+ body->auth_seq = host2ieee16(2);
8020+ body->status = host2ieee16(0);
8021+
8022+ packet_len = WLAN_HDR_A3_LEN + 2 + 2 + 2;
8023+ if (ieee2host16(*(req->auth_alg)) == WLAN_AUTH_ALG_OPENSYSTEM) {
8024+ clt->used = CLIENT_AUTHENTICATED_2;
8025+ } else { /* shared key */
8026+ acx_gen_challenge(&body->challenge);
8027+ memcpy(&clt->challenge_text, body->challenge.challenge, WLAN_CHALLENGE_LEN);
8028+ packet_len += 2 + 2 + 2 + 1+1+WLAN_CHALLENGE_LEN;
8029+ }
8030+
8031+ acxlog_mac(L_ASSOC|L_XFER,
8032+ "transmit_auth2: BSSID=", head->bssid, "\n");
8033+
8034+ acx_l_tx_data(adev, tx, packet_len);
8035+ok:
8036+ FN_EXIT1(OK);
8037+ return OK;
8038+bad:
8039+ FN_EXIT1(NOT_OK);
8040+ return NOT_OK;
8041+}
8042+
8043+
8044+/***********************************************************************
8045+** acx_l_transmit_authen3
8046+*/
8047+static int
8048+acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req)
8049+{
8050+ struct tx *tx;
8051+ struct wlan_hdr_mgmt *head;
8052+ struct auth_frame_body *body;
8053+ unsigned int packet_len;
8054+
8055+ FN_ENTER;
8056+
8057+ tx = acx_l_alloc_tx(adev);
8058+ if (!tx)
8059+ goto ok;
8060+ head = acx_l_get_txbuf(adev, tx);
8061+ if (!head) {
8062+ acx_l_dealloc_tx(adev, tx);
8063+ goto ok;
8064+ }
8065+ body = (void*)(head + 1);
8066+
8067+ /* add WF_FC_ISWEPi: auth step 3 needs to be encrypted */
8068+ head->fc = WF_FC_ISWEPi + WF_FSTYPE_AUTHENi;
8069+ /* FIXME: is this needed?? authen4 does it...
8070+ * I think it's even wrong since we shouldn't re-use old
8071+ * values but instead let the firmware calculate proper ones
8072+ head->dur = req->hdr->dur;
8073+ head->seq = req->hdr->seq;
8074+ */
8075+ MAC_COPY(head->da, adev->bssid);
8076+ MAC_COPY(head->sa, adev->dev_addr);
8077+ MAC_COPY(head->bssid, adev->bssid);
8078+
8079+ /* already in IEEE format, no endianness conversion */
8080+ body->auth_alg = *(req->auth_alg);
8081+ body->auth_seq = host2ieee16(3);
8082+ body->status = host2ieee16(0);
8083+ memcpy(&body->challenge, req->challenge, req->challenge->len + 2);
8084+ packet_len = WLAN_HDR_A3_LEN + 8 + req->challenge->len;
8085+
8086+ log(L_ASSOC|L_XFER, "transmit_authen3!\n");
8087+
8088+ acx_l_tx_data(adev, tx, packet_len);
8089+ok:
8090+ FN_EXIT1(OK);
8091+ return OK;
8092+}
8093+
8094+
8095+/***********************************************************************
8096+** acx_l_transmit_authen4
8097+*/
8098+static int
8099+acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req)
8100+{
8101+ struct tx *tx;
8102+ struct wlan_hdr_mgmt *head;
8103+ struct auth_frame_body *body;
8104+
8105+ FN_ENTER;
8106+
8107+ tx = acx_l_alloc_tx(adev);
8108+ if (!tx)
8109+ goto ok;
8110+ head = acx_l_get_txbuf(adev, tx);
8111+ if (!head) {
8112+ acx_l_dealloc_tx(adev, tx);
8113+ goto ok;
8114+ }
8115+ body = (void*)(head + 1);
8116+
8117+ head->fc = WF_FSTYPE_AUTHENi; /* 0xb0 */
8118+ head->dur = 0 /* req->hdr->dur */;
8119+ MAC_COPY(head->da, req->hdr->a2);
8120+ MAC_COPY(head->sa, adev->dev_addr);
8121+ MAC_COPY(head->bssid, req->hdr->a3);
8122+ head->seq = 0 /* req->hdr->seq */;
8123+
8124+ /* already in IEEE format, no endianness conversion */
8125+ body->auth_alg = *(req->auth_alg);
8126+ body->auth_seq = host2ieee16(4);
8127+ body->status = host2ieee16(0);
8128+
8129+ acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2);
8130+ok:
8131+ FN_EXIT1(OK);
8132+ return OK;
8133+}
8134+
8135+
8136+/***********************************************************************
8137+** acx_l_transmit_assoc_req
8138+**
8139+** adev->ap_client is a current candidate AP here
8140+*/
8141+static int
8142+acx_l_transmit_assoc_req(acx_device_t *adev)
8143+{
8144+ struct tx *tx;
8145+ struct wlan_hdr_mgmt *head;
8146+ u8 *body, *p, *prate;
8147+ unsigned int packet_len;
8148+ u16 cap;
8149+
8150+ FN_ENTER;
8151+
8152+ log(L_ASSOC, "sending association request, "
8153+ "awaiting response. NOT ASSOCIATED YET\n");
8154+ tx = acx_l_alloc_tx(adev);
8155+ if (!tx)
8156+ goto bad;
8157+ head = acx_l_get_txbuf(adev, tx);
8158+ if (!head) {
8159+ acx_l_dealloc_tx(adev, tx);
8160+ goto bad;
8161+ }
8162+ body = (void*)(head + 1);
8163+
8164+ head->fc = WF_FSTYPE_ASSOCREQi;
8165+ head->dur = host2ieee16(0x8000);
8166+ MAC_COPY(head->da, adev->bssid);
8167+ MAC_COPY(head->sa, adev->dev_addr);
8168+ MAC_COPY(head->bssid, adev->bssid);
8169+ head->seq = 0;
8170+
8171+ p = body;
8172+ /* now start filling the AssocReq frame body */
8173+
8174+ /* since this assoc request will most likely only get
8175+ * sent in the STA to AP case (and not when Ad-Hoc IBSS),
8176+ * the cap combination indicated here will thus be
8177+ * WF_MGMT_CAP_ESSi *always* (no IBSS ever)
8178+ * The specs are more than non-obvious on all that:
8179+ *
8180+ * 802.11 7.3.1.4 Capability Information field
8181+ ** APs set the ESS subfield to 1 and the IBSS subfield to 0 within
8182+ ** Beacon or Probe Response management frames. STAs within an IBSS
8183+ ** set the ESS subfield to 0 and the IBSS subfield to 1 in transmitted
8184+ ** Beacon or Probe Response management frames
8185+ **
8186+ ** APs set the Privacy subfield to 1 within transmitted Beacon,
8187+ ** Probe Response, Association Response, and Reassociation Response
8188+ ** if WEP is required for all data type frames within the BSS.
8189+ ** STAs within an IBSS set the Privacy subfield to 1 in Beacon
8190+ ** or Probe Response management frames if WEP is required
8191+ ** for all data type frames within the IBSS */
8192+
8193+ /* note that returning 0 will be refused by several APs...
8194+ * (so this indicates that you're probably supposed to
8195+ * "confirm" the ESS mode) */
8196+ cap = WF_MGMT_CAP_ESSi;
8197+
8198+ /* this one used to be a check on wep_restricted,
8199+ * but more likely it's wep_enabled instead */
8200+ if (adev->wep_enabled)
8201+ SET_BIT(cap, WF_MGMT_CAP_PRIVACYi);
8202+
8203+ /* Probably we can just set these always, because our hw is
8204+ ** capable of shortpre and PBCC --vda */
8205+ /* only ask for short preamble if the peer station supports it */
8206+ if (adev->ap_client->cap_info & WF_MGMT_CAP_SHORT)
8207+ SET_BIT(cap, WF_MGMT_CAP_SHORTi);
8208+ /* only ask for PBCC support if the peer station supports it */
8209+ if (adev->ap_client->cap_info & WF_MGMT_CAP_PBCC)
8210+ SET_BIT(cap, WF_MGMT_CAP_PBCCi);
8211+
8212+ /* IEs: 1. caps */
8213+ *(u16*)p = cap; p += 2;
8214+ /* 2. listen interval */
8215+ *(u16*)p = host2ieee16(adev->listen_interval); p += 2;
8216+ /* 3. ESSID */
8217+ p = wlan_fill_ie_ssid(p,
8218+ strlen(adev->essid_for_assoc), adev->essid_for_assoc);
8219+ /* 4. supp rates */
8220+ prate = p;
8221+ p = wlan_fill_ie_rates(p,
8222+ adev->rate_supported_len, adev->rate_supported);
8223+ /* 5. ext supp rates */
8224+ p = wlan_fill_ie_rates_ext(p,
8225+ adev->rate_supported_len, adev->rate_supported);
8226+
8227+ if (acx_debug & L_DEBUG) {
8228+ printk("association: rates element\n");
8229+ acx_dump_bytes(prate, p - prate);
8230+ }
8231+
8232+ /* calculate lengths */
8233+ packet_len = WLAN_HDR_A3_LEN + (p - body);
8234+
8235+ log(L_ASSOC, "association: requesting caps 0x%04X, ESSID \"%s\"\n",
8236+ cap, adev->essid_for_assoc);
8237+
8238+ acx_l_tx_data(adev, tx, packet_len);
8239+ FN_EXIT1(OK);
8240+ return OK;
8241+bad:
8242+ FN_EXIT1(NOT_OK);
8243+ return NOT_OK;
8244+}
8245+
8246+
8247+/***********************************************************************
8248+** acx_l_transmit_disassoc
8249+**
8250+** FIXME: looks like incomplete implementation of a helper:
8251+** acx_l_transmit_disassoc(adev, clt) - kick this client (we're an AP)
8252+** acx_l_transmit_disassoc(adev, NULL) - leave BSSID (we're a STA)
8253+*/
8254+#ifdef BROKEN
8255+int
8256+acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt)
8257+{
8258+ struct tx *tx;
8259+ struct wlan_hdr_mgmt *head;
8260+ struct disassoc_frame_body *body;
8261+
8262+ FN_ENTER;
8263+/* if (clt != NULL) { */
8264+ tx = acx_l_alloc_tx(adev);
8265+ if (!tx)
8266+ goto bad;
8267+ head = acx_l_get_txbuf(adev, tx);
8268+ if (!head) {
8269+ acx_l_dealloc_tx(adev, tx);
8270+ goto bad;
8271+ }
8272+ body = (void*)(head + 1);
8273+
8274+/* clt->used = CLIENT_AUTHENTICATED_2; - not (yet?) associated */
8275+
8276+ head->fc = WF_FSTYPE_DISASSOCi;
8277+ head->dur = 0;
8278+ /* huh? It muchly depends on whether we're STA or AP...
8279+ ** sta->ap: da=bssid, sa=own, bssid=bssid
8280+ ** ap->sta: da=sta, sa=bssid, bssid=bssid. FIXME! */
8281+ MAC_COPY(head->da, adev->bssid);
8282+ MAC_COPY(head->sa, adev->dev_addr);
8283+ MAC_COPY(head->bssid, adev->dev_addr);
8284+ head->seq = 0;
8285+
8286+ /* "Class 3 frame received from nonassociated station." */
8287+ body->reason = host2ieee16(7);
8288+
8289+ /* fixed size struct, ok to sizeof */
8290+ acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body));
8291+/* } */
8292+ FN_EXIT1(OK);
8293+ return OK;
8294+bad:
8295+ FN_EXIT1(NOT_OK);
8296+ return NOT_OK;
8297+}
8298+#endif
8299+
8300+
8301+/***********************************************************************
8302+** acx_s_complete_scan
8303+**
8304+** Called either from after_interrupt_task() if:
8305+** 1) there was Scan_Complete IRQ, or
8306+** 2) scanning expired in timer()
8307+** We need to decide which ESS or IBSS to join.
8308+** Iterates thru adev->sta_list:
8309+** if adev->ap is not bcast, will join only specified
8310+** ESS or IBSS with this bssid
8311+** checks peers' caps for ESS/IBSS bit
8312+** checks peers' SSID, allows exact match or hidden SSID
8313+** If station to join is chosen:
8314+** points adev->ap_client to the chosen struct client
8315+** sets adev->essid_for_assoc for future assoc attempt
8316+** Auth/assoc is not yet performed
8317+** Returns OK if there is no need to restart scan
8318+*/
8319+int
8320+acx_s_complete_scan(acx_device_t *adev)
8321+{
8322+ struct client *bss;
8323+ unsigned long flags;
8324+ u16 needed_cap;
8325+ int i;
8326+ int idx_found = -1;
8327+ int result = OK;
8328+
8329+ FN_ENTER;
8330+
8331+ switch (adev->mode) {
8332+ case ACX_MODE_0_ADHOC:
8333+ needed_cap = WF_MGMT_CAP_IBSS; /* 2, we require Ad-Hoc */
8334+ break;
8335+ case ACX_MODE_2_STA:
8336+ needed_cap = WF_MGMT_CAP_ESS; /* 1, we require Managed */
8337+ break;
8338+ default:
8339+ printk("acx: driver bug: mode=%d in complete_scan()\n", adev->mode);
8340+ dump_stack();
8341+ goto end;
8342+ }
8343+
8344+ acx_lock(adev, flags);
8345+
8346+ /* TODO: sta_iterator hiding implementation would be nice here... */
8347+
8348+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
8349+ bss = &adev->sta_list[i];
8350+ if (!bss->used) continue;
8351+
8352+
8353+ log(L_ASSOC, "scan table: SSID=\"%s\" CH=%d SIR=%d SNR=%d\n",
8354+ bss->essid, bss->channel, bss->sir, bss->snr);
8355+
8356+ if (!mac_is_bcast(adev->ap))
8357+ if (!mac_is_equal(bss->bssid, adev->ap))
8358+ continue; /* keep looking */
8359+
8360+ /* broken peer with no mode flags set? */
8361+ if (unlikely(!(bss->cap_info & (WF_MGMT_CAP_ESS | WF_MGMT_CAP_IBSS)))) {
8362+ printk("%s: strange peer "MACSTR" found with "
8363+ "neither ESS (AP) nor IBSS (Ad-Hoc) "
8364+ "capability - skipped\n",
8365+ adev->ndev->name, MAC(bss->address));
8366+ continue;
8367+ }
8368+ log(L_ASSOC, "peer_cap 0x%04X, needed_cap 0x%04X\n",
8369+ bss->cap_info, needed_cap);
8370+
8371+ /* does peer station support what we need? */
8372+ if ((bss->cap_info & needed_cap) != needed_cap)
8373+ continue; /* keep looking */
8374+
8375+ /* strange peer with NO basic rates?! */
8376+ if (unlikely(!bss->rate_bas)) {
8377+ printk("%s: strange peer "MACSTR" with empty rate set "
8378+ "- skipped\n",
8379+ adev->ndev->name, MAC(bss->address));
8380+ continue;
8381+ }
8382+
8383+ /* do we support all basic rates of this peer? */
8384+ if ((bss->rate_bas & adev->rate_oper) != bss->rate_bas) {
8385+/* we probably need to have all rates as operational rates,
8386+ even in case of an 11M-only configuration */
8387+#ifdef THIS_IS_TROUBLESOME
8388+ printk("%s: peer "MACSTR": incompatible basic rates "
8389+ "(AP requests 0x%04X, we have 0x%04X) "
8390+ "- skipped\n",
8391+ adev->ndev->name, MAC(bss->address),
8392+ bss->rate_bas, adev->rate_oper);
8393+ continue;
8394+#else
8395+ printk("%s: peer "MACSTR": incompatible basic rates "
8396+ "(AP requests 0x%04X, we have 0x%04X). "
8397+ "Considering anyway...\n",
8398+ adev->ndev->name, MAC(bss->address),
8399+ bss->rate_bas, adev->rate_oper);
8400+#endif
8401+ }
8402+
8403+ if ( !(adev->reg_dom_chanmask & (1<<(bss->channel-1))) ) {
8404+ printk("%s: warning: peer "MACSTR" is on channel %d "
8405+ "outside of channel range of current "
8406+ "regulatory domain - couldn't join "
8407+ "even if other settings match. "
8408+ "You might want to adapt your config\n",
8409+ adev->ndev->name, MAC(bss->address),
8410+ bss->channel);
8411+ continue; /* keep looking */
8412+ }
8413+
8414+ if (!adev->essid_active || !strcmp(bss->essid, adev->essid)) {
8415+ log(L_ASSOC,
8416+ "found station with matching ESSID! ('%s' "
8417+ "station, '%s' config)\n",
8418+ bss->essid,
8419+ (adev->essid_active) ? adev->essid : "[any]");
8420+ /* TODO: continue looking for peer with better SNR */
8421+ bss->used = CLIENT_JOIN_CANDIDATE;
8422+ idx_found = i;
8423+
8424+ /* stop searching if this station is
8425+ * on the current channel, otherwise
8426+ * keep looking for an even better match */
8427+ if (bss->channel == adev->channel)
8428+ break;
8429+ } else
8430+ if (is_hidden_essid(bss->essid)) {
8431+ /* hmm, station with empty or single-space SSID:
8432+ * using hidden SSID broadcast?
8433+ */
8434+ /* This behaviour is broken: which AP from zillion
8435+ ** of APs with hidden SSID you'd try?
8436+ ** We should use Probe requests to get Probe responses
8437+ ** and check for real SSID (are those never hidden?) */
8438+ bss->used = CLIENT_JOIN_CANDIDATE;
8439+ if (idx_found == -1)
8440+ idx_found = i;
8441+ log(L_ASSOC, "found station with empty or "
8442+ "single-space (hidden) SSID, considering "
8443+ "for assoc attempt\n");
8444+ /* ...and keep looking for better matches */
8445+ } else {
8446+ log(L_ASSOC, "ESSID doesn't match! ('%s' "
8447+ "station, '%s' config)\n",
8448+ bss->essid,
8449+ (adev->essid_active) ? adev->essid : "[any]");
8450+ }
8451+ }
8452+
8453+ /* TODO: iterate thru join candidates instead */
8454+ /* TODO: rescan if not associated within some timeout */
8455+ if (idx_found != -1) {
8456+ char *essid_src;
8457+ size_t essid_len;
8458+
8459+ bss = &adev->sta_list[idx_found];
8460+ adev->ap_client = bss;
8461+
8462+ if (is_hidden_essid(bss->essid)) {
8463+ /* if the ESSID of the station we found is empty
8464+ * (no broadcast), then use user-configured ESSID
8465+ * instead */
8466+ essid_src = adev->essid;
8467+ essid_len = adev->essid_len;
8468+ } else {
8469+ essid_src = bss->essid;
8470+ essid_len = strlen(bss->essid);
8471+ }
8472+
8473+ acx_update_capabilities(adev);
8474+
8475+ memcpy(adev->essid_for_assoc, essid_src, essid_len);
8476+ adev->essid_for_assoc[essid_len] = '\0';
8477+ adev->channel = bss->channel;
8478+ MAC_COPY(adev->bssid, bss->bssid);
8479+
8480+ bss->rate_cfg = (bss->rate_cap & adev->rate_oper);
8481+ bss->rate_cur = 1 << lowest_bit(bss->rate_cfg);
8482+ bss->rate_100 = acx_rate111to100(bss->rate_cur);
8483+
8484+ acxlog_mac(L_ASSOC,
8485+ "matching station found: ", adev->bssid, ", joining\n");
8486+
8487+ /* TODO: do we need to switch to the peer's channel first? */
8488+
8489+ if (ACX_MODE_0_ADHOC == adev->mode) {
8490+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED);
8491+ } else {
8492+ acx_l_transmit_authen1(adev);
8493+ acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH);
8494+ }
8495+ } else { /* idx_found == -1 */
8496+ /* uh oh, no station found in range */
8497+ if (ACX_MODE_0_ADHOC == adev->mode) {
8498+ printk("%s: no matching station found in range, "
8499+ "generating our own IBSS instead\n",
8500+ adev->ndev->name);
8501+ /* we do it the HostAP way: */
8502+ MAC_COPY(adev->bssid, adev->dev_addr);
8503+ adev->bssid[0] |= 0x02; /* 'local assigned addr' bit */
8504+ /* add IBSS bit to our caps... */
8505+ acx_update_capabilities(adev);
8506+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED);
8507+ /* In order to cmd_join be called below */
8508+ idx_found = 0;
8509+ } else {
8510+ /* we shall scan again, AP can be
8511+ ** just temporarily powered off */
8512+ log(L_ASSOC,
8513+ "no matching station found in range yet\n");
8514+ acx_set_status(adev, ACX_STATUS_1_SCANNING);
8515+ result = NOT_OK;
8516+ }
8517+ }
8518+
8519+ acx_unlock(adev, flags);
8520+
8521+ if (idx_found != -1) {
8522+ if (ACX_MODE_0_ADHOC == adev->mode) {
8523+ /* need to update channel in beacon template */
8524+ SET_BIT(adev->set_mask, SET_TEMPLATES);
8525+ if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
8526+ acx_s_update_card_settings(adev);
8527+ }
8528+ /* Inform firmware on our decision to start or join BSS */
8529+ acx_s_cmd_join_bssid(adev, adev->bssid);
8530+ }
8531+
8532+end:
8533+ FN_EXIT1(result);
8534+ return result;
8535+}
8536+
8537+
8538+/***********************************************************************
8539+** acx_s_read_fw
8540+**
8541+** Loads a firmware image
8542+**
8543+** Returns:
8544+** 0 unable to load file
8545+** pointer to firmware success
8546+*/
8547+firmware_image_t*
8548+acx_s_read_fw(struct device *dev, const char *file, u32 *size)
8549+{
8550+ firmware_image_t *res;
8551+ const struct firmware *fw_entry;
8552+
8553+ res = NULL;
8554+ log(L_INIT, "requesting firmware image '%s'\n", file);
8555+ if (!request_firmware(&fw_entry, file, dev)) {
8556+ *size = 8;
8557+ if (fw_entry->size >= 8)
8558+ *size = 8 + le32_to_cpu(*(u32 *)(fw_entry->data + 4));
8559+ if (fw_entry->size != *size) {
8560+ printk("acx: firmware size does not match "
8561+ "firmware header: %d != %d, "
8562+ "aborting fw upload\n",
8563+ (int) fw_entry->size, (int) *size);
8564+ goto release_ret;
8565+ }
8566+ res = vmalloc(*size);
8567+ if (!res) {
8568+ printk("acx: no memory for firmware "
8569+ "(%u bytes)\n", *size);
8570+ goto release_ret;
8571+ }
8572+ memcpy(res, fw_entry->data, fw_entry->size);
8573+release_ret:
8574+ release_firmware(fw_entry);
8575+ return res;
8576+ }
8577+ printk("acx: firmware image '%s' was not provided. "
8578+ "Check your hotplug scripts\n", file);
8579+
8580+ /* checksum will be verified in write_fw, so don't bother here */
8581+ return res;
8582+}
8583+
8584+
8585+/***********************************************************************
8586+** acx_s_set_wepkey
8587+*/
8588+static void
8589+acx100_s_set_wepkey(acx_device_t *adev)
8590+{
8591+ ie_dot11WEPDefaultKey_t dk;
8592+ int i;
8593+
8594+ for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
8595+ if (adev->wep_keys[i].size != 0) {
8596+ log(L_INIT, "setting WEP key: %d with "
8597+ "total size: %d\n", i, (int) adev->wep_keys[i].size);
8598+ dk.action = 1;
8599+ dk.keySize = adev->wep_keys[i].size;
8600+ dk.defaultKeyNum = i;
8601+ memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
8602+ acx_s_configure(adev, &dk, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
8603+ }
8604+ }
8605+}
8606+
8607+static void
8608+acx111_s_set_wepkey(acx_device_t *adev)
8609+{
8610+ acx111WEPDefaultKey_t dk;
8611+ int i;
8612+
8613+ for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
8614+ if (adev->wep_keys[i].size != 0) {
8615+ log(L_INIT, "setting WEP key: %d with "
8616+ "total size: %d\n", i, (int) adev->wep_keys[i].size);
8617+ memset(&dk, 0, sizeof(dk));
8618+ dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
8619+ dk.keySize = adev->wep_keys[i].size;
8620+
8621+ /* are these two lines necessary? */
8622+ dk.type = 0; /* default WEP key */
8623+ dk.index = 0; /* ignored when setting default key */
8624+
8625+ dk.defaultKeyNum = i;
8626+ memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
8627+ acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk, sizeof(dk));
8628+ }
8629+ }
8630+}
8631+
8632+static void
8633+acx_s_set_wepkey(acx_device_t *adev)
8634+{
8635+ if (IS_ACX111(adev))
8636+ acx111_s_set_wepkey(adev);
8637+ else
8638+ acx100_s_set_wepkey(adev);
8639+}
8640+
8641+
8642+/***********************************************************************
8643+** acx100_s_init_wep
8644+**
8645+** FIXME: this should probably be moved into the new card settings
8646+** management, but since we're also modifying the memory map layout here
8647+** due to the WEP key space we want, we should take care...
8648+*/
8649+static int
8650+acx100_s_init_wep(acx_device_t *adev)
8651+{
8652+ acx100_ie_wep_options_t options;
8653+ ie_dot11WEPDefaultKeyID_t dk;
8654+ acx_ie_memmap_t pt;
8655+ int res = NOT_OK;
8656+
8657+ FN_ENTER;
8658+
8659+ if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
8660+ goto fail;
8661+ }
8662+
8663+ log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd);
8664+
8665+ pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
8666+ pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4);
8667+
8668+ if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
8669+ goto fail;
8670+ }
8671+
8672+ /* let's choose maximum setting: 4 default keys, plus 10 other keys: */
8673+ options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
8674+ options.WEPOption = 0x00;
8675+
8676+ log(L_ASSOC, "%s: writing WEP options\n", __func__);
8677+ acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
8678+
8679+ acx100_s_set_wepkey(adev);
8680+
8681+ if (adev->wep_keys[adev->wep_current_index].size != 0) {
8682+ log(L_ASSOC, "setting active default WEP key number: %d\n",
8683+ adev->wep_current_index);
8684+ dk.KeyID = adev->wep_current_index;
8685+ acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
8686+ }
8687+ /* FIXME!!! wep_key_struct is filled nowhere! But adev
8688+ * is initialized to 0, and we don't REALLY need those keys either */
8689+/* for (i = 0; i < 10; i++) {
8690+ if (adev->wep_key_struct[i].len != 0) {
8691+ MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr);
8692+ wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len);
8693+ memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize));
8694+ wep_mgmt.Action = cpu_to_le16(1);
8695+ log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize));
8696+ if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) {
8697+ adev->wep_key_struct[i].index = i;
8698+ }
8699+ }
8700+ }
8701+*/
8702+
8703+ /* now retrieve the updated WEPCacheEnd pointer... */
8704+ if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
8705+ printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n",
8706+ adev->ndev->name);
8707+ goto fail;
8708+ }
8709+ /* ...and tell it to start allocating templates at that location */
8710+ /* (no endianness conversion needed) */
8711+ pt.PacketTemplateStart = pt.WEPCacheEnd;
8712+
8713+ if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) {
8714+ printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n",
8715+ adev->ndev->name);
8716+ goto fail;
8717+ }
8718+ res = OK;
8719+
8720+fail:
8721+ FN_EXIT1(res);
8722+ return res;
8723+}
8724+
8725+
8726+static int
8727+acx_s_init_max_template_generic(acx_device_t *adev, unsigned int len, unsigned int cmd)
8728+{
8729+ int res;
8730+ union {
8731+ acx_template_nullframe_t null;
8732+ acx_template_beacon_t b;
8733+ acx_template_tim_t tim;
8734+ acx_template_probereq_t preq;
8735+ acx_template_proberesp_t presp;
8736+ } templ;
8737+
8738+ memset(&templ, 0, len);
8739+ templ.null.size = cpu_to_le16(len - 2);
8740+ res = acx_s_issue_cmd(adev, cmd, &templ, len);
8741+ return res;
8742+}
8743+
8744+static inline int
8745+acx_s_init_max_null_data_template(acx_device_t *adev)
8746+{
8747+ return acx_s_init_max_template_generic(
8748+ adev, sizeof(acx_template_nullframe_t), ACX1xx_CMD_CONFIG_NULL_DATA
8749+ );
8750+}
8751+
8752+static inline int
8753+acx_s_init_max_beacon_template(acx_device_t *adev)
8754+{
8755+ return acx_s_init_max_template_generic(
8756+ adev, sizeof(acx_template_beacon_t), ACX1xx_CMD_CONFIG_BEACON
8757+ );
8758+}
8759+
8760+static inline int
8761+acx_s_init_max_tim_template(acx_device_t *adev)
8762+{
8763+ return acx_s_init_max_template_generic(
8764+ adev, sizeof(acx_template_tim_t), ACX1xx_CMD_CONFIG_TIM
8765+ );
8766+}
8767+
8768+static inline int
8769+acx_s_init_max_probe_response_template(acx_device_t *adev)
8770+{
8771+ return acx_s_init_max_template_generic(
8772+ adev, sizeof(acx_template_proberesp_t), ACX1xx_CMD_CONFIG_PROBE_RESPONSE
8773+ );
8774+}
8775+
8776+static inline int
8777+acx_s_init_max_probe_request_template(acx_device_t *adev)
8778+{
8779+ return acx_s_init_max_template_generic(
8780+ adev, sizeof(acx_template_probereq_t), ACX1xx_CMD_CONFIG_PROBE_REQUEST
8781+ );
8782+}
8783+
8784+/***********************************************************************
8785+** acx_s_set_tim_template
8786+**
8787+** FIXME: In full blown driver we will regularly update partial virtual bitmap
8788+** by calling this function
8789+** (it can be done by irq handler on each DTIM irq or by timer...)
8790+
8791+[802.11 7.3.2.6] TIM information element:
8792+- 1 EID
8793+- 1 Length
8794+1 1 DTIM Count
8795+ indicates how many beacons (including this) appear before next DTIM
8796+ (0=this one is a DTIM)
8797+2 1 DTIM Period
8798+ number of beacons between successive DTIMs
8799+ (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc)
8800+3 1 Bitmap Control
8801+ bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?)
8802+ set to 1 in TIM elements with a value of 0 in the DTIM Count field
8803+ when one or more broadcast or multicast frames are buffered at the AP.
8804+ bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE).
8805+4 n Partial Virtual Bitmap
8806+ Visible part of traffic-indication bitmap.
8807+ Full bitmap consists of 2008 bits (251 octets) such that bit number N
8808+ (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8)
8809+ in octet number N/8 where the low-order bit of each octet is bit0,
8810+ and the high order bit is bit7.
8811+ Each set bit in virtual bitmap corresponds to traffic buffered by AP
8812+ for a specific station (with corresponding AID?).
8813+ Partial Virtual Bitmap shows a part of bitmap which has non-zero.
8814+ Bitmap Offset is a number of skipped zero octets (see above).
8815+ 'Missing' octets at the tail are also assumed to be zero.
8816+ Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55
8817+ This means that traffic-indication bitmap is:
8818+ 00000000 00000000 01010101 01010101 01010101 00000000 00000000...
8819+ (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?)
8820+*/
8821+static int
8822+acx_s_set_tim_template(acx_device_t *adev)
8823+{
8824+/* For now, configure smallish test bitmap, all zero ("no pending data") */
8825+ enum { bitmap_size = 5 };
8826+
8827+ acx_template_tim_t t;
8828+ int result;
8829+
8830+ FN_ENTER;
8831+
8832+ memset(&t, 0, sizeof(t));
8833+ t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */
8834+ t.tim_eid = WLAN_EID_TIM;
8835+ t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */
8836+ result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t));
8837+ FN_EXIT1(result);
8838+ return result;
8839+}
8840+
8841+
8842+/***********************************************************************
8843+** acx_fill_beacon_or_proberesp_template
8844+**
8845+** For frame format info, please see 802.11-1999.pdf item 7.2.3.9 and below!!
8846+**
8847+** NB: we use the fact that
8848+** struct acx_template_proberesp and struct acx_template_beacon are the same
8849+** (well, almost...)
8850+**
8851+** [802.11] Beacon's body consist of these IEs:
8852+** 1 Timestamp
8853+** 2 Beacon interval
8854+** 3 Capability information
8855+** 4 SSID
8856+** 5 Supported rates (up to 8 rates)
8857+** 6 FH Parameter Set (frequency-hopping PHYs only)
8858+** 7 DS Parameter Set (direct sequence PHYs only)
8859+** 8 CF Parameter Set (only if PCF is supported)
8860+** 9 IBSS Parameter Set (ad-hoc only)
8861+**
8862+** Beacon only:
8863+** 10 TIM (AP only) (see 802.11 7.3.2.6)
8864+** 11 Country Information (802.11d)
8865+** 12 FH Parameters (802.11d)
8866+** 13 FH Pattern Table (802.11d)
8867+** ... (?!! did not yet find relevant PDF file... --vda)
8868+** 19 ERP Information (extended rate PHYs)
8869+** 20 Extended Supported Rates (if more than 8 rates)
8870+**
8871+** Proberesp only:
8872+** 10 Country information (802.11d)
8873+** 11 FH Parameters (802.11d)
8874+** 12 FH Pattern Table (802.11d)
8875+** 13-n Requested information elements (802.11d)
8876+** ????
8877+** 18 ERP Information (extended rate PHYs)
8878+** 19 Extended Supported Rates (if more than 8 rates)
8879+*/
8880+static int
8881+acx_fill_beacon_or_proberesp_template(acx_device_t *adev,
8882+ struct acx_template_beacon *templ,
8883+ u16 fc /* in host order! */)
8884+{
8885+ int len;
8886+ u8 *p;
8887+
8888+ FN_ENTER;
8889+
8890+ memset(templ, 0, sizeof(*templ));
8891+ MAC_BCAST(templ->da);
8892+ MAC_COPY(templ->sa, adev->dev_addr);
8893+ MAC_COPY(templ->bssid, adev->bssid);
8894+
8895+ templ->beacon_interval = cpu_to_le16(adev->beacon_interval);
8896+ acx_update_capabilities(adev);
8897+ templ->cap = cpu_to_le16(adev->capabilities);
8898+
8899+ p = templ->variable;
8900+ p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid);
8901+ p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported);
8902+ p = wlan_fill_ie_ds_parms(p, adev->channel);
8903+ /* NB: should go AFTER tim, but acx seem to keep tim last always */
8904+ p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported);
8905+
8906+ switch (adev->mode) {
8907+ case ACX_MODE_0_ADHOC:
8908+ /* ATIM window */
8909+ p = wlan_fill_ie_ibss_parms(p, 0); break;
8910+ case ACX_MODE_3_AP:
8911+ /* TIM IE is set up as separate template */
8912+ break;
8913+ }
8914+
8915+ len = p - (u8*)templ;
8916+ templ->fc = cpu_to_le16(WF_FTYPE_MGMT | fc);
8917+ /* - 2: do not count 'u16 size' field */
8918+ templ->size = cpu_to_le16(len - 2);
8919+
8920+ FN_EXIT1(len);
8921+ return len;
8922+}
8923+
8924+
8925+#if POWER_SAVE_80211
8926+/***********************************************************************
8927+** acx_s_set_null_data_template
8928+*/
8929+static int
8930+acx_s_set_null_data_template(acx_device_t *adev)
8931+{
8932+ struct acx_template_nullframe b;
8933+ int result;
8934+
8935+ FN_ENTER;
8936+
8937+ /* memset(&b, 0, sizeof(b)); not needed, setting all members */
8938+
8939+ b.size = cpu_to_le16(sizeof(b) - 2);
8940+ b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi;
8941+ b.hdr.dur = 0;
8942+ MAC_BCAST(b.hdr.a1);
8943+ MAC_COPY(b.hdr.a2, adev->dev_addr);
8944+ MAC_COPY(b.hdr.a3, adev->bssid);
8945+ b.hdr.seq = 0;
8946+
8947+ result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b));
8948+
8949+ FN_EXIT1(result);
8950+ return result;
8951+}
8952+#endif
8953+
8954+
8955+/***********************************************************************
8956+** acx_s_set_beacon_template
8957+*/
8958+static int
8959+acx_s_set_beacon_template(acx_device_t *adev)
8960+{
8961+ struct acx_template_beacon bcn;
8962+ int len, result;
8963+
8964+ FN_ENTER;
8965+
8966+ len = acx_fill_beacon_or_proberesp_template(adev, &bcn, WF_FSTYPE_BEACON);
8967+ result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len);
8968+
8969+ FN_EXIT1(result);
8970+ return result;
8971+}
8972+
8973+
8974+/***********************************************************************
8975+** acx_s_set_probe_response_template
8976+*/
8977+static int
8978+acx_s_set_probe_response_template(acx_device_t *adev)
8979+{
8980+ struct acx_template_proberesp pr;
8981+ int len, result;
8982+
8983+ FN_ENTER;
8984+
8985+ len = acx_fill_beacon_or_proberesp_template(adev, &pr, WF_FSTYPE_PROBERESP);
8986+ result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_RESPONSE, &pr, len);
8987+
8988+ FN_EXIT1(result);
8989+ return result;
8990+}
8991+
8992+
8993+/***********************************************************************
8994+** acx_s_init_packet_templates()
8995+**
8996+** NOTE: order is very important here, to have a correct memory layout!
8997+** init templates: max Probe Request (station mode), max NULL data,
8998+** max Beacon, max TIM, max Probe Response.
8999+*/
9000+static int
9001+acx_s_init_packet_templates(acx_device_t *adev)
9002+{
9003+ acx_ie_memmap_t mm; /* ACX100 only */
9004+ int result = NOT_OK;
9005+
9006+ FN_ENTER;
9007+
9008+ log(L_DEBUG|L_INIT, "initializing max packet templates\n");
9009+
9010+ if (OK != acx_s_init_max_probe_request_template(adev))
9011+ goto failed;
9012+
9013+ if (OK != acx_s_init_max_null_data_template(adev))
9014+ goto failed;
9015+
9016+ if (OK != acx_s_init_max_beacon_template(adev))
9017+ goto failed;
9018+
9019+ if (OK != acx_s_init_max_tim_template(adev))
9020+ goto failed;
9021+
9022+ if (OK != acx_s_init_max_probe_response_template(adev))
9023+ goto failed;
9024+
9025+ if (IS_ACX111(adev)) {
9026+ /* ACX111 doesn't need the memory map magic below,
9027+ * and the other templates will be set later (acx_start) */
9028+ result = OK;
9029+ goto success;
9030+ }
9031+
9032+ /* ACX100 will have its TIM template set,
9033+ * and we also need to update the memory map */
9034+
9035+ if (OK != acx_s_set_tim_template(adev))
9036+ goto failed_acx100;
9037+
9038+ log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm));
9039+
9040+ if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP))
9041+ goto failed_acx100;
9042+
9043+ mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4);
9044+ if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP))
9045+ goto failed_acx100;
9046+
9047+ result = OK;
9048+ goto success;
9049+
9050+failed_acx100:
9051+ log(L_DEBUG|L_INIT,
9052+ /* "cb=0x%X\n" */
9053+ "ACXMemoryMap:\n"
9054+ ".CodeStart=0x%X\n"
9055+ ".CodeEnd=0x%X\n"
9056+ ".WEPCacheStart=0x%X\n"
9057+ ".WEPCacheEnd=0x%X\n"
9058+ ".PacketTemplateStart=0x%X\n"
9059+ ".PacketTemplateEnd=0x%X\n",
9060+ /* len, */
9061+ le32_to_cpu(mm.CodeStart),
9062+ le32_to_cpu(mm.CodeEnd),
9063+ le32_to_cpu(mm.WEPCacheStart),
9064+ le32_to_cpu(mm.WEPCacheEnd),
9065+ le32_to_cpu(mm.PacketTemplateStart),
9066+ le32_to_cpu(mm.PacketTemplateEnd));
9067+
9068+failed:
9069+ printk("%s: %s() FAILED\n", adev->ndev->name, __func__);
9070+
9071+success:
9072+ FN_EXIT1(result);
9073+ return result;
9074+}
9075+
9076+
9077+/***********************************************************************
9078+*/
9079+static int
9080+acx_s_set_probe_request_template(acx_device_t *adev)
9081+{
9082+ struct acx_template_probereq probereq;
9083+ char *p;
9084+ int res;
9085+ int frame_len;
9086+
9087+ FN_ENTER;
9088+
9089+ memset(&probereq, 0, sizeof(probereq));
9090+
9091+ probereq.fc = WF_FTYPE_MGMTi | WF_FSTYPE_PROBEREQi;
9092+ MAC_BCAST(probereq.da);
9093+ MAC_COPY(probereq.sa, adev->dev_addr);
9094+ MAC_BCAST(probereq.bssid);
9095+
9096+ p = probereq.variable;
9097+ p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid);
9098+ p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported);
9099+ p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported);
9100+ frame_len = p - (char*)&probereq;
9101+ probereq.size = cpu_to_le16(frame_len - 2);
9102+
9103+ res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_REQUEST, &probereq, frame_len);
9104+ FN_EXIT0;
9105+ return res;
9106+}
9107+
9108+
9109+/***********************************************************************
9110+** acx_s_init_mac
9111+*/
9112+int
9113+acx_s_init_mac(acx_device_t *adev)
9114+{
9115+ int result = NOT_OK;
9116+
9117+ FN_ENTER;
9118+
9119+ if (IS_ACX111(adev)) {
9120+ adev->ie_len = acx111_ie_len;
9121+ adev->ie_len_dot11 = acx111_ie_len_dot11;
9122+ } else {
9123+ adev->ie_len = acx100_ie_len;
9124+ adev->ie_len_dot11 = acx100_ie_len_dot11;
9125+ }
9126+
9127+#if defined (ACX_MEM)
9128+ adev->memblocksize = 256; /* 256 is default */
9129+ /* try to load radio for both ACX100 and ACX111, since both
9130+ * chips have at least some firmware versions making use of an
9131+ * external radio module */
9132+ acxmem_s_upload_radio(adev);
9133+#else
9134+ if (IS_PCI(adev)) {
9135+ adev->memblocksize = 256; /* 256 is default */
9136+ /* try to load radio for both ACX100 and ACX111, since both
9137+ * chips have at least some firmware versions making use of an
9138+ * external radio module */
9139+ acxpci_s_upload_radio(adev);
9140+ } else {
9141+ adev->memblocksize = 128;
9142+ }
9143+#endif
9144+
9145+ if (IS_ACX111(adev)) {
9146+ /* for ACX111, the order is different from ACX100
9147+ 1. init packet templates
9148+ 2. create station context and create dma regions
9149+ 3. init wep default keys
9150+ */
9151+ if (OK != acx_s_init_packet_templates(adev))
9152+ goto fail;
9153+ if (OK != acx111_s_create_dma_regions(adev)) {
9154+ printk("%s: acx111_create_dma_regions FAILED\n",
9155+ adev->ndev->name);
9156+ goto fail;
9157+ }
9158+ } else {
9159+ if (OK != acx100_s_init_wep(adev))
9160+ goto fail;
9161+ if (OK != acx_s_init_packet_templates(adev))
9162+ goto fail;
9163+ if (OK != acx100_s_create_dma_regions(adev)) {
9164+ printk("%s: acx100_create_dma_regions FAILED\n",
9165+ adev->ndev->name);
9166+ goto fail;
9167+ }
9168+ }
9169+
9170+ MAC_COPY(adev->ndev->dev_addr, adev->dev_addr);
9171+ result = OK;
9172+
9173+fail:
9174+ if (result)
9175+ printk("acx: init_mac() FAILED\n");
9176+ FN_EXIT1(result);
9177+ return result;
9178+}
9179+
9180+
9181+void
9182+acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set)
9183+{
9184+ unsigned mask;
9185+
9186+ unsigned int i;
9187+
9188+ for (i = 0; i < sizeof(acx_reg_domain_ids); i++)
9189+ if (acx_reg_domain_ids[i] == adev->reg_dom_id)
9190+ break;
9191+
9192+ if (sizeof(acx_reg_domain_ids) == i) {
9193+ log(L_INIT, "Invalid or unsupported regulatory domain"
9194+ " 0x%02X specified, falling back to FCC (USA)!"
9195+ " Please report if this sounds fishy!\n",
9196+ adev->reg_dom_id);
9197+ i = 0;
9198+ adev->reg_dom_id = acx_reg_domain_ids[i];
9199+
9200+ /* since there was a mismatch, we need to force updating */
9201+ do_set = 1;
9202+ }
9203+
9204+ if (do_set) {
9205+ acx_ie_generic_t dom;
9206+ dom.m.bytes[0] = adev->reg_dom_id;
9207+ acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
9208+ }
9209+
9210+ adev->reg_dom_chanmask = reg_domain_channel_masks[i];
9211+
9212+ mask = (1 << (adev->channel - 1));
9213+ if (!(adev->reg_dom_chanmask & mask)) {
9214+ /* hmm, need to adjust our channel to reside within domain */
9215+ mask = 1;
9216+ for (i = 1; i <= 14; i++) {
9217+ if (adev->reg_dom_chanmask & mask) {
9218+ printk("%s: adjusting selected channel from %d "
9219+ "to %d due to new regulatory domain\n",
9220+ adev->ndev->name, adev->channel, i);
9221+ adev->channel = i;
9222+ break;
9223+ }
9224+ mask <<= 1;
9225+ }
9226+ }
9227+}
9228+
9229+
9230+#if POWER_SAVE_80211
9231+static void
9232+acx_s_update_80211_powersave_mode(acx_device_t *adev)
9233+{
9234+ /* merge both structs in a union to be able to have common code */
9235+ union {
9236+ acx111_ie_powersave_t acx111;
9237+ acx100_ie_powersave_t acx100;
9238+ } pm;
9239+
9240+ /* change 802.11 power save mode settings */
9241+ log(L_INIT, "updating 802.11 power save mode settings: "
9242+ "wakeup_cfg 0x%02X, listen interval %u, "
9243+ "options 0x%02X, hangover period %u, "
9244+ "enhanced_ps_transition_time %u\n",
9245+ adev->ps_wakeup_cfg, adev->ps_listen_interval,
9246+ adev->ps_options, adev->ps_hangover_period,
9247+ adev->ps_enhanced_transition_time);
9248+ acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
9249+ log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, "
9250+ "listen interval %u, options 0x%02X, "
9251+ "hangover period %u, "
9252+ "enhanced_ps_transition_time %u, beacon_rx_time %u\n",
9253+ pm.acx111.wakeup_cfg,
9254+ pm.acx111.listen_interval,
9255+ pm.acx111.options,
9256+ pm.acx111.hangover_period,
9257+ IS_ACX111(adev) ?
9258+ pm.acx111.enhanced_ps_transition_time
9259+ : pm.acx100.enhanced_ps_transition_time,
9260+ IS_ACX111(adev) ?
9261+ pm.acx111.beacon_rx_time
9262+ : (u32)-1
9263+ );
9264+ pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg;
9265+ pm.acx111.listen_interval = adev->ps_listen_interval;
9266+ pm.acx111.options = adev->ps_options;
9267+ pm.acx111.hangover_period = adev->ps_hangover_period;
9268+ if (IS_ACX111(adev)) {
9269+ pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time);
9270+ pm.acx111.enhanced_ps_transition_time = cpu_to_le32(adev->ps_enhanced_transition_time);
9271+ } else {
9272+ pm.acx100.enhanced_ps_transition_time = cpu_to_le16(adev->ps_enhanced_transition_time);
9273+ }
9274+ acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT);
9275+ acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
9276+ log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
9277+ acx_s_msleep(40);
9278+ acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT);
9279+ log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg);
9280+ log(L_INIT, "power save mode change %s\n",
9281+ (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful");
9282+ /* FIXME: maybe verify via PS_CFG_PENDING bit here
9283+ * that power save mode change was successful. */
9284+ /* FIXME: we shouldn't trigger a scan immediately after
9285+ * fiddling with power save mode (since the firmware is sending
9286+ * a NULL frame then). */
9287+}
9288+#endif
9289+
9290+
9291+/***********************************************************************
9292+** acx_s_update_card_settings
9293+**
9294+** Applies accumulated changes in various adev->xxxx members
9295+** Called by ioctl commit handler, acx_start, acx_set_defaults,
9296+** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG),
9297+*/
9298+static void
9299+acx111_s_sens_radio_16_17(acx_device_t *adev)
9300+{
9301+ u32 feature1, feature2;
9302+
9303+ if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) {
9304+ printk("%s: invalid sensitivity setting (1..3), "
9305+ "setting to 1\n", adev->ndev->name);
9306+ adev->sensitivity = 1;
9307+ }
9308+ acx111_s_get_feature_config(adev, &feature1, &feature2);
9309+ CLEAR_BIT(feature1, FEATURE1_LOW_RX|FEATURE1_EXTRA_LOW_RX);
9310+ if (adev->sensitivity > 1)
9311+ SET_BIT(feature1, FEATURE1_LOW_RX);
9312+ if (adev->sensitivity > 2)
9313+ SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX);
9314+ acx111_s_feature_set(adev, feature1, feature2);
9315+}
9316+
9317+
9318+void
9319+acx_s_update_card_settings(acx_device_t *adev)
9320+{
9321+ unsigned long flags;
9322+ unsigned int start_scan = 0;
9323+ int i;
9324+
9325+ FN_ENTER;
9326+
9327+ log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n",
9328+ adev->get_mask, adev->set_mask);
9329+
9330+ /* Track dependencies betweed various settings */
9331+
9332+ if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_WEP)) {
9333+ log(L_INIT, "important setting has been changed. "
9334+ "Need to update packet templates, too\n");
9335+ SET_BIT(adev->set_mask, SET_TEMPLATES);
9336+ }
9337+ if (adev->set_mask & GETSET_CHANNEL) {
9338+ /* This will actually tune RX/TX to the channel */
9339+ SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX);
9340+ switch (adev->mode) {
9341+ case ACX_MODE_0_ADHOC:
9342+ case ACX_MODE_3_AP:
9343+ /* Beacons contain channel# - update them */
9344+ SET_BIT(adev->set_mask, SET_TEMPLATES);
9345+ }
9346+ switch (adev->mode) {
9347+ case ACX_MODE_0_ADHOC:
9348+ case ACX_MODE_2_STA:
9349+ start_scan = 1;
9350+ }
9351+ }
9352+
9353+ /* Apply settings */
9354+
9355+#ifdef WHY_SHOULD_WE_BOTHER /* imagine we were just powered off */
9356+ /* send a disassoc request in case it's required */
9357+ if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_CHANNEL|GETSET_WEP)) {
9358+ if (ACX_MODE_2_STA == adev->mode) {
9359+ if (ACX_STATUS_4_ASSOCIATED == adev->status) {
9360+ log(L_ASSOC, "we were ASSOCIATED - "
9361+ "sending disassoc request\n");
9362+ acx_lock(adev, flags);
9363+ acx_l_transmit_disassoc(adev, NULL);
9364+ /* FIXME: deauth? */
9365+ acx_unlock(adev, flags);
9366+ }
9367+ /* need to reset some other stuff as well */
9368+ log(L_DEBUG, "resetting bssid\n");
9369+ MAC_ZERO(adev->bssid);
9370+ SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST);
9371+ start_scan = 1;
9372+ }
9373+ }
9374+#endif
9375+
9376+ if (adev->get_mask & GETSET_STATION_ID) {
9377+ u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
9378+ const u8 *paddr;
9379+
9380+ acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
9381+ paddr = &stationID[4];
9382+ for (i = 0; i < ETH_ALEN; i++) {
9383+ /* we copy the MAC address (reversed in
9384+ * the card) to the netdevice's MAC
9385+ * address, and on ifup it will be
9386+ * copied into iwadev->dev_addr */
9387+ adev->ndev->dev_addr[ETH_ALEN - 1 - i] = paddr[i];
9388+ }
9389+ CLEAR_BIT(adev->get_mask, GETSET_STATION_ID);
9390+ }
9391+
9392+ if (adev->get_mask & GETSET_SENSITIVITY) {
9393+ if ((RADIO_RFMD_11 == adev->radio_type)
9394+ || (RADIO_MAXIM_0D == adev->radio_type)
9395+ || (RADIO_RALINK_15 == adev->radio_type)) {
9396+ acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity);
9397+ } else {
9398+ log(L_INIT, "don't know how to get sensitivity "
9399+ "for radio type 0x%02X\n", adev->radio_type);
9400+ adev->sensitivity = 0;
9401+ }
9402+ log(L_INIT, "got sensitivity value %u\n", adev->sensitivity);
9403+
9404+ CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY);
9405+ }
9406+
9407+ if (adev->get_mask & GETSET_ANTENNA) {
9408+ u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
9409+
9410+ memset(antenna, 0, sizeof(antenna));
9411+ acx_s_interrogate(adev, antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA);
9412+ adev->antenna = antenna[4];
9413+ log(L_INIT, "got antenna value 0x%02X\n", adev->antenna);
9414+ CLEAR_BIT(adev->get_mask, GETSET_ANTENNA);
9415+ }
9416+
9417+ if (adev->get_mask & GETSET_ED_THRESH) {
9418+ if (IS_ACX100(adev)) {
9419+ u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
9420+
9421+ memset(ed_threshold, 0, sizeof(ed_threshold));
9422+ acx_s_interrogate(adev, ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD);
9423+ adev->ed_threshold = ed_threshold[4];
9424+ } else {
9425+ log(L_INIT, "acx111 doesn't support ED\n");
9426+ adev->ed_threshold = 0;
9427+ }
9428+ log(L_INIT, "got Energy Detect (ED) threshold %u\n", adev->ed_threshold);
9429+ CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH);
9430+ }
9431+
9432+ if (adev->get_mask & GETSET_CCA) {
9433+ if (IS_ACX100(adev)) {
9434+ u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
9435+
9436+ memset(cca, 0, sizeof(adev->cca));
9437+ acx_s_interrogate(adev, cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
9438+ adev->cca = cca[4];
9439+ } else {
9440+ log(L_INIT, "acx111 doesn't support CCA\n");
9441+ adev->cca = 0;
9442+ }
9443+ log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n", adev->cca);
9444+ CLEAR_BIT(adev->get_mask, GETSET_CCA);
9445+ }
9446+
9447+ if (adev->get_mask & GETSET_REG_DOMAIN) {
9448+ acx_ie_generic_t dom;
9449+
9450+ acx_s_interrogate(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN);
9451+ adev->reg_dom_id = dom.m.bytes[0];
9452+ acx_s_set_sane_reg_domain(adev, 0);
9453+ log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id);
9454+ CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN);
9455+ }
9456+
9457+ if (adev->set_mask & GETSET_STATION_ID) {
9458+ u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN];
9459+ u8 *paddr;
9460+
9461+ paddr = &stationID[4];
9462+ memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
9463+ for (i = 0; i < ETH_ALEN; i++) {
9464+ /* copy the MAC address we obtained when we noticed
9465+ * that the ethernet iface's MAC changed
9466+ * to the card (reversed in
9467+ * the card!) */
9468+ paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i];
9469+ }
9470+ acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID);
9471+ CLEAR_BIT(adev->set_mask, GETSET_STATION_ID);
9472+ }
9473+
9474+ if (adev->set_mask & SET_TEMPLATES) {
9475+ log(L_INIT, "updating packet templates\n");
9476+ switch (adev->mode) {
9477+ case ACX_MODE_2_STA:
9478+ acx_s_set_probe_request_template(adev);
9479+#if POWER_SAVE_80211
9480+ acx_s_set_null_data_template(adev);
9481+#endif
9482+ break;
9483+ case ACX_MODE_0_ADHOC:
9484+ acx_s_set_probe_request_template(adev);
9485+#if POWER_SAVE_80211
9486+ /* maybe power save functionality is somehow possible
9487+ * for Ad-Hoc mode, too... FIXME: verify it somehow? firmware debug fields? */
9488+ acx_s_set_null_data_template(adev);
9489+#endif
9490+ /* fall through */
9491+ case ACX_MODE_3_AP:
9492+ acx_s_set_beacon_template(adev);
9493+ acx_s_set_tim_template(adev);
9494+ /* BTW acx111 firmware would not send probe responses
9495+ ** if probe request does not have all basic rates flagged
9496+ ** by 0x80! Thus firmware does not conform to 802.11,
9497+ ** it should ignore 0x80 bit in ratevector from STA.
9498+ ** We can 'fix' it by not using this template and
9499+ ** sending probe responses by hand. TODO --vda */
9500+ acx_s_set_probe_response_template(adev);
9501+ }
9502+ /* Needed if generated frames are to be emitted at different tx rate now */
9503+ log(L_IRQ, "redoing cmd_join_bssid() after template cfg\n");
9504+ acx_s_cmd_join_bssid(adev, adev->bssid);
9505+ CLEAR_BIT(adev->set_mask, SET_TEMPLATES);
9506+ }
9507+ if (adev->set_mask & SET_STA_LIST) {
9508+ acx_lock(adev, flags);
9509+ acx_l_sta_list_init(adev);
9510+ CLEAR_BIT(adev->set_mask, SET_STA_LIST);
9511+ acx_unlock(adev, flags);
9512+ }
9513+ if (adev->set_mask & SET_RATE_FALLBACK) {
9514+ u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN];
9515+
9516+ /* configure to not do fallbacks when not in auto rate mode */
9517+ rate[4] = (adev->rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0;
9518+ log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]);
9519+ acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK);
9520+ CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK);
9521+ }
9522+ if (adev->set_mask & GETSET_TXPOWER) {
9523+ log(L_INIT, "updating transmit power: %u dBm\n",
9524+ adev->tx_level_dbm);
9525+ acx_s_set_tx_level(adev, adev->tx_level_dbm);
9526+ CLEAR_BIT(adev->set_mask, GETSET_TXPOWER);
9527+ }
9528+
9529+ if (adev->set_mask & GETSET_SENSITIVITY) {
9530+ log(L_INIT, "updating sensitivity value: %u\n",
9531+ adev->sensitivity);
9532+ switch (adev->radio_type) {
9533+ case RADIO_RFMD_11:
9534+ case RADIO_MAXIM_0D:
9535+ case RADIO_RALINK_15:
9536+ acx_s_write_phy_reg(adev, 0x30, adev->sensitivity);
9537+ break;
9538+ case RADIO_RADIA_16:
9539+ case RADIO_UNKNOWN_17:
9540+ acx111_s_sens_radio_16_17(adev);
9541+ break;
9542+ default:
9543+ log(L_INIT, "don't know how to modify sensitivity "
9544+ "for radio type 0x%02X\n", adev->radio_type);
9545+ }
9546+ CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY);
9547+ }
9548+
9549+ if (adev->set_mask & GETSET_ANTENNA) {
9550+ /* antenna */
9551+ u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN];
9552+
9553+ memset(antenna, 0, sizeof(antenna));
9554+ antenna[4] = adev->antenna;
9555+ log(L_INIT, "updating antenna value: 0x%02X\n",
9556+ adev->antenna);
9557+ acx_s_configure(adev, &antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA);
9558+ CLEAR_BIT(adev->set_mask, GETSET_ANTENNA);
9559+ }
9560+
9561+ if (adev->set_mask & GETSET_ED_THRESH) {
9562+ /* ed_threshold */
9563+ log(L_INIT, "updating Energy Detect (ED) threshold: %u\n",
9564+ adev->ed_threshold);
9565+ if (IS_ACX100(adev)) {
9566+ u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN];
9567+
9568+ memset(ed_threshold, 0, sizeof(ed_threshold));
9569+ ed_threshold[4] = adev->ed_threshold;
9570+ acx_s_configure(adev, &ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD);
9571+ }
9572+ else
9573+ log(L_INIT, "acx111 doesn't support ED!\n");
9574+ CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH);
9575+ }
9576+
9577+ if (adev->set_mask & GETSET_CCA) {
9578+ /* CCA value */
9579+ log(L_INIT, "updating Channel Clear Assessment "
9580+ "(CCA) value: 0x%02X\n", adev->cca);
9581+ if (IS_ACX100(adev)) {
9582+ u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN];
9583+
9584+ memset(cca, 0, sizeof(cca));
9585+ cca[4] = adev->cca;
9586+ acx_s_configure(adev, &cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE);
9587+ }
9588+ else
9589+ log(L_INIT, "acx111 doesn't support CCA!\n");
9590+ CLEAR_BIT(adev->set_mask, GETSET_CCA);
9591+ }
9592+
9593+ if (adev->set_mask & GETSET_LED_POWER) {
9594+ /* Enable Tx */
9595+ log(L_INIT, "updating power LED status: %u\n", adev->led_power);
9596+
9597+ acx_lock(adev, flags);
9598+#if defined (ACX_MEM)
9599+ acxmem_l_power_led(adev, adev->led_power);
9600+#else
9601+ if (IS_PCI(adev))
9602+ acxpci_l_power_led(adev, adev->led_power);
9603+#endif
9604+ CLEAR_BIT(adev->set_mask, GETSET_LED_POWER);
9605+ acx_unlock(adev, flags);
9606+ }
9607+
9608+ if (adev->set_mask & GETSET_POWER_80211) {
9609+#if POWER_SAVE_80211
9610+ acx_s_update_80211_powersave_mode(adev);
9611+#endif
9612+ CLEAR_BIT(adev->set_mask, GETSET_POWER_80211);
9613+ }
9614+
9615+ if (adev->set_mask & GETSET_CHANNEL) {
9616+ /* channel */
9617+ log(L_INIT, "updating channel to: %u\n", adev->channel);
9618+ CLEAR_BIT(adev->set_mask, GETSET_CHANNEL);
9619+ }
9620+
9621+ if (adev->set_mask & GETSET_TX) {
9622+ /* set Tx */
9623+ log(L_INIT, "updating: %s Tx\n",
9624+ adev->tx_disabled ? "disable" : "enable");
9625+ if (adev->tx_disabled)
9626+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
9627+ else
9628+ acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1);
9629+ CLEAR_BIT(adev->set_mask, GETSET_TX);
9630+ }
9631+
9632+ if (adev->set_mask & GETSET_RX) {
9633+ /* Enable Rx */
9634+ log(L_INIT, "updating: enable Rx on channel: %u\n",
9635+ adev->channel);
9636+ acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1);
9637+ CLEAR_BIT(adev->set_mask, GETSET_RX);
9638+ }
9639+
9640+ if (adev->set_mask & GETSET_RETRY) {
9641+ u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN];
9642+ u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN];
9643+
9644+ log(L_INIT, "updating short retry limit: %u, long retry limit: %u\n",
9645+ adev->short_retry, adev->long_retry);
9646+ short_retry[0x4] = adev->short_retry;
9647+ long_retry[0x4] = adev->long_retry;
9648+ acx_s_configure(adev, &short_retry, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT);
9649+ acx_s_configure(adev, &long_retry, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT);
9650+ CLEAR_BIT(adev->set_mask, GETSET_RETRY);
9651+ }
9652+
9653+ if (adev->set_mask & SET_MSDU_LIFETIME) {
9654+ u8 xmt_msdu_lifetime[4 + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN];
9655+
9656+ log(L_INIT, "updating tx MSDU lifetime: %u\n",
9657+ adev->msdu_lifetime);
9658+ *(u32 *)&xmt_msdu_lifetime[4] = cpu_to_le32((u32)adev->msdu_lifetime);
9659+ acx_s_configure(adev, &xmt_msdu_lifetime, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME);
9660+ CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME);
9661+ }
9662+
9663+ if (adev->set_mask & GETSET_REG_DOMAIN) {
9664+ log(L_INIT, "updating regulatory domain: 0x%02X\n",
9665+ adev->reg_dom_id);
9666+ acx_s_set_sane_reg_domain(adev, 1);
9667+ CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN);
9668+ }
9669+
9670+ if (adev->set_mask & GETSET_MODE) {
9671+ adev->ndev->type = (adev->mode == ACX_MODE_MONITOR) ?
9672+ adev->monitor_type : ARPHRD_ETHER;
9673+
9674+ switch (adev->mode) {
9675+ case ACX_MODE_3_AP:
9676+
9677+ acx_lock(adev, flags);
9678+ acx_l_sta_list_init(adev);
9679+ adev->aid = 0;
9680+ adev->ap_client = NULL;
9681+ MAC_COPY(adev->bssid, adev->dev_addr);
9682+ /* this basically says "we're connected" */
9683+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED);
9684+ acx_unlock(adev, flags);
9685+
9686+ acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER);
9687+ /* start sending beacons */
9688+ acx_s_cmd_join_bssid(adev, adev->bssid);
9689+ break;
9690+ case ACX_MODE_MONITOR:
9691+ acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER);
9692+ /* this stops beacons */
9693+ acx_s_cmd_join_bssid(adev, adev->bssid);
9694+ /* this basically says "we're connected" */
9695+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED);
9696+ SET_BIT(adev->set_mask, SET_RXCONFIG|SET_WEP_OPTIONS);
9697+ break;
9698+ case ACX_MODE_0_ADHOC:
9699+ case ACX_MODE_2_STA:
9700+ acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER);
9701+
9702+ acx_lock(adev, flags);
9703+ adev->aid = 0;
9704+ adev->ap_client = NULL;
9705+ acx_unlock(adev, flags);
9706+
9707+ /* we want to start looking for peer or AP */
9708+ start_scan = 1;
9709+ break;
9710+ case ACX_MODE_OFF:
9711+ /* TODO: disable RX/TX, stop any scanning activity etc: */
9712+ /* adev->tx_disabled = 1; */
9713+ /* SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); */
9714+
9715+ /* This stops beacons (invalid macmode...) */
9716+ acx_s_cmd_join_bssid(adev, adev->bssid);
9717+ acx_set_status(adev, ACX_STATUS_0_STOPPED);
9718+ break;
9719+ }
9720+ CLEAR_BIT(adev->set_mask, GETSET_MODE);
9721+ }
9722+
9723+ if (adev->set_mask & SET_RXCONFIG) {
9724+ acx_s_initialize_rx_config(adev);
9725+ CLEAR_BIT(adev->set_mask, SET_RXCONFIG);
9726+ }
9727+
9728+ if (adev->set_mask & GETSET_RESCAN) {
9729+ switch (adev->mode) {
9730+ case ACX_MODE_0_ADHOC:
9731+ case ACX_MODE_2_STA:
9732+ start_scan = 1;
9733+ break;
9734+ }
9735+ CLEAR_BIT(adev->set_mask, GETSET_RESCAN);
9736+ }
9737+
9738+ if (adev->set_mask & GETSET_WEP) {
9739+ /* encode */
9740+
9741+ ie_dot11WEPDefaultKeyID_t dkey;
9742+#ifdef DEBUG_WEP
9743+ struct {
9744+ u16 type;
9745+ u16 len;
9746+ u8 val;
9747+ } ACX_PACKED keyindic;
9748+#endif
9749+ log(L_INIT, "updating WEP key settings\n");
9750+
9751+ acx_s_set_wepkey(adev);
9752+
9753+ dkey.KeyID = adev->wep_current_index;
9754+ log(L_INIT, "setting WEP key %u as default\n", dkey.KeyID);
9755+ acx_s_configure(adev, &dkey, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
9756+#ifdef DEBUG_WEP
9757+ keyindic.val = 3;
9758+ acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE);
9759+#endif
9760+ start_scan = 1;
9761+ CLEAR_BIT(adev->set_mask, GETSET_WEP);
9762+ }
9763+
9764+ if (adev->set_mask & SET_WEP_OPTIONS) {
9765+ acx100_ie_wep_options_t options;
9766+ if (IS_ACX111(adev)) {
9767+ log(L_DEBUG, "setting WEP Options for acx111 is not supported\n");
9768+ } else {
9769+ log(L_INIT, "setting WEP Options\n");
9770+ acx100_s_init_wep(adev);
9771+#if 0
9772+ /* let's choose maximum setting: 4 default keys,
9773+ * plus 10 other keys: */
9774+ options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
9775+ /* don't decrypt default key only,
9776+ * don't override decryption: */
9777+ options.WEPOption = 0;
9778+ if (adev->mode == ACX_MODE_MONITOR) {
9779+ /* don't decrypt default key only,
9780+ * override decryption mechanism: */
9781+ options.WEPOption = 2;
9782+ }
9783+
9784+ acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS);
9785+#endif
9786+ }
9787+ CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS);
9788+ }
9789+
9790+ /* Rescan was requested */
9791+ if (start_scan) {
9792+ switch (adev->mode) {
9793+ case ACX_MODE_0_ADHOC:
9794+ case ACX_MODE_2_STA:
9795+ /* We can avoid clearing list if join code
9796+ ** will be a bit more clever about not picking
9797+ ** 'bad' AP over and over again */
9798+ acx_lock(adev, flags);
9799+ adev->ap_client = NULL;
9800+ acx_l_sta_list_init(adev);
9801+ acx_set_status(adev, ACX_STATUS_1_SCANNING);
9802+ acx_unlock(adev, flags);
9803+
9804+ acx_s_cmd_start_scan(adev);
9805+ }
9806+ }
9807+
9808+ /* debug, rate, and nick don't need any handling */
9809+ /* what about sniffing mode?? */
9810+
9811+ log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n",
9812+ adev->get_mask, adev->set_mask);
9813+
9814+/* end: */
9815+ FN_EXIT0;
9816+}
9817+
9818+
9819+/***********************************************************************
9820+** acx_e_after_interrupt_task
9821+*/
9822+static int
9823+acx_s_recalib_radio(acx_device_t *adev)
9824+{
9825+ if (IS_ACX111(adev)) {
9826+ acx111_cmd_radiocalib_t cal;
9827+
9828+ printk("%s: recalibrating radio\n", adev->ndev->name);
9829+ /* automatic recalibration, choose all methods: */
9830+ cal.methods = cpu_to_le32(0x8000000f);
9831+ /* automatic recalibration every 60 seconds (value in TUs)
9832+ * I wonder what the firmware default here is? */
9833+ cal.interval = cpu_to_le32(58594);
9834+ return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB,
9835+ &cal, sizeof(cal), CMD_TIMEOUT_MS(100));
9836+ } else {
9837+ /* On ACX100, we need to recalibrate the radio
9838+ * by issuing a GETSET_TX|GETSET_RX */
9839+ if (/* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) &&
9840+ (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */
9841+ (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1)) &&
9842+ (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1)) )
9843+ return OK;
9844+ return NOT_OK;
9845+ }
9846+}
9847+
9848+static void
9849+acx_s_after_interrupt_recalib(acx_device_t *adev)
9850+{
9851+ int res;
9852+
9853+ /* this helps with ACX100 at least;
9854+ * hopefully ACX111 also does a
9855+ * recalibration here */
9856+
9857+ /* clear flag beforehand, since we want to make sure
9858+ * it's cleared; then only set it again on specific circumstances */
9859+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
9860+
9861+ /* better wait a bit between recalibrations to
9862+ * prevent overheating due to torturing the card
9863+ * into working too long despite high temperature
9864+ * (just a safety measure) */
9865+ if (adev->recalib_time_last_success
9866+ && time_before(jiffies, adev->recalib_time_last_success
9867+ + RECALIB_PAUSE * 60 * HZ)) {
9868+ if (adev->recalib_msg_ratelimit <= 4) {
9869+ printk("%s: less than " STRING(RECALIB_PAUSE)
9870+ " minutes since last radio recalibration, "
9871+ "not recalibrating (maybe card is too hot?)\n",
9872+ adev->ndev->name);
9873+ adev->recalib_msg_ratelimit++;
9874+ if (adev->recalib_msg_ratelimit == 5)
9875+ printk("disabling above message until next recalib\n");
9876+ }
9877+ return;
9878+ }
9879+
9880+ adev->recalib_msg_ratelimit = 0;
9881+
9882+ /* note that commands sometimes fail (card busy),
9883+ * so only clear flag if we were fully successful */
9884+ res = acx_s_recalib_radio(adev);
9885+ if (res == OK) {
9886+ printk("%s: successfully recalibrated radio\n",
9887+ adev->ndev->name);
9888+ adev->recalib_time_last_success = jiffies;
9889+ adev->recalib_failure_count = 0;
9890+ } else {
9891+ /* failed: resubmit, but only limited
9892+ * amount of times within some time range
9893+ * to prevent endless loop */
9894+
9895+ adev->recalib_time_last_success = 0; /* we failed */
9896+
9897+ /* if some time passed between last
9898+ * attempts, then reset failure retry counter
9899+ * to be able to do next recalib attempt */
9900+ if (time_after(jiffies, adev->recalib_time_last_attempt + 5*HZ))
9901+ adev->recalib_failure_count = 0;
9902+
9903+ if (adev->recalib_failure_count < 5) {
9904+ /* increment inside only, for speedup of outside path */
9905+ adev->recalib_failure_count++;
9906+ adev->recalib_time_last_attempt = jiffies;
9907+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
9908+ }
9909+ }
9910+}
9911+
9912+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
9913+static void
9914+acx_e_after_interrupt_task(struct work_struct *work)
9915+{
9916+ acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
9917+#else
9918+ static void
9919+ acx_e_after_interrupt_task(void *data)
9920+ {
9921+ struct net_device *ndev = (struct net_device*)data;
9922+ acx_device_t *adev = ndev2adev(ndev);
9923+#endif
9924+ FN_ENTER;
9925+
9926+ acx_sem_lock(adev);
9927+
9928+ if (!adev->after_interrupt_jobs)
9929+ goto end; /* no jobs to do */
9930+
9931+#if TX_CLEANUP_IN_SOFTIRQ
9932+ /* can happen only on PCI */
9933+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_TX_CLEANUP) {
9934+ acx_lock(adev, flags);
9935+ acxpci_l_clean_txdesc(adev);
9936+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_TX_CLEANUP);
9937+ acx_unlock(adev, flags);
9938+ }
9939+#endif
9940+ /* we see lotsa tx errors */
9941+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) {
9942+ acx_s_after_interrupt_recalib(adev);
9943+ }
9944+
9945+ /* a poor interrupt code wanted to do update_card_settings() */
9946+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) {
9947+ if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
9948+ acx_s_update_card_settings(adev);
9949+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
9950+ }
9951+
9952+ /* 1) we detected that no Scan_Complete IRQ came from fw, or
9953+ ** 2) we found too many STAs */
9954+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) {
9955+ log(L_IRQ, "sending a stop scan cmd...\n");
9956+ acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0);
9957+ /* HACK: set the IRQ bit, since we won't get a
9958+ * scan complete IRQ any more on ACX111 (works on ACX100!),
9959+ * since _we_, not a fw, have stopped the scan */
9960+ SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
9961+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_STOP_SCAN);
9962+ }
9963+
9964+ /* either fw sent Scan_Complete or we detected that
9965+ ** no Scan_Complete IRQ came from fw. Finish scanning,
9966+ ** pick join partner if any */
9967+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) {
9968+ if (adev->status == ACX_STATUS_1_SCANNING) {
9969+ if (OK != acx_s_complete_scan(adev)) {
9970+ SET_BIT(adev->after_interrupt_jobs,
9971+ ACX_AFTER_IRQ_RESTART_SCAN);
9972+ }
9973+ } else {
9974+ /* + scan kills current join status - restore it
9975+ ** (do we need it for STA?) */
9976+ /* + does it happen only with active scans?
9977+ ** active and passive scans? ALL scans including
9978+ ** background one? */
9979+ /* + was not verified that everything is restored
9980+ ** (but at least we start to emit beacons again) */
9981+ switch (adev->mode) {
9982+ case ACX_MODE_0_ADHOC:
9983+ case ACX_MODE_3_AP:
9984+ log(L_IRQ, "redoing cmd_join_bssid() after scan\n");
9985+ acx_s_cmd_join_bssid(adev, adev->bssid);
9986+ }
9987+ }
9988+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_COMPLETE_SCAN);
9989+ }
9990+
9991+ /* STA auth or assoc timed out, start over again */
9992+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) {
9993+ log(L_IRQ, "sending a start_scan cmd...\n");
9994+ acx_s_cmd_start_scan(adev);
9995+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_RESTART_SCAN);
9996+ }
9997+
9998+ /* whee, we got positive assoc response! 8) */
9999+ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) {
10000+ acx_ie_generic_t pdr;
10001+ /* tiny race window exists, checking that we still a STA */
10002+ switch (adev->mode) {
10003+ case ACX_MODE_2_STA:
10004+ pdr.m.aid = cpu_to_le16(adev->aid);
10005+ acx_s_configure(adev, &pdr, ACX1xx_IE_ASSOC_ID);
10006+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED);
10007+ log(L_ASSOC|L_DEBUG, "ASSOCIATED!\n");
10008+ CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_ASSOCIATE);
10009+ }
10010+ }
10011+end:
10012+ acx_sem_unlock(adev);
10013+ FN_EXIT0;
10014+}
10015+
10016+
10017+/***********************************************************************
10018+** acx_schedule_task
10019+**
10020+** Schedule the call of the after_interrupt method after leaving
10021+** the interrupt context.
10022+*/
10023+void
10024+acx_schedule_task(acx_device_t *adev, unsigned int set_flag)
10025+{
10026+ SET_BIT(adev->after_interrupt_jobs, set_flag);
10027+ SCHEDULE_WORK(&adev->after_interrupt_task);
10028+}
10029+
10030+
10031+/***********************************************************************
10032+*/
10033+void
10034+acx_init_task_scheduler(acx_device_t *adev)
10035+{
10036+ /* configure task scheduler */
10037+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
10038+ INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task);
10039+#else
10040+ INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task,
10041+ adev->ndev);
10042+#endif
10043+}
10044+
10045+
10046+/***********************************************************************
10047+** acx_s_start
10048+*/
10049+void
10050+acx_s_start(acx_device_t *adev)
10051+{
10052+ FN_ENTER;
10053+
10054+ /*
10055+ * Ok, now we do everything that can possibly be done with ioctl
10056+ * calls to make sure that when it was called before the card
10057+ * was up we get the changes asked for
10058+ */
10059+
10060+ SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP
10061+ |GETSET_TXPOWER|GETSET_ANTENNA|GETSET_ED_THRESH|GETSET_CCA
10062+ |GETSET_REG_DOMAIN|GETSET_MODE|GETSET_CHANNEL
10063+ |GETSET_TX|GETSET_RX|GETSET_STATION_ID);
10064+
10065+ log(L_INIT, "updating initial settings on iface activation\n");
10066+ acx_s_update_card_settings(adev);
10067+
10068+ FN_EXIT0;
10069+}
10070+
10071+
10072+/***********************************************************************
10073+** acx_update_capabilities
10074+*/
10075+void
10076+acx_update_capabilities(acx_device_t *adev)
10077+{
10078+ u16 cap = 0;
10079+
10080+ switch (adev->mode) {
10081+ case ACX_MODE_3_AP:
10082+ SET_BIT(cap, WF_MGMT_CAP_ESS); break;
10083+ case ACX_MODE_0_ADHOC:
10084+ SET_BIT(cap, WF_MGMT_CAP_IBSS); break;
10085+ /* other types of stations do not emit beacons */
10086+ }
10087+
10088+ if (adev->wep_restricted) {
10089+ SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
10090+ }
10091+ if (adev->cfgopt_dot11ShortPreambleOption) {
10092+ SET_BIT(cap, WF_MGMT_CAP_SHORT);
10093+ }
10094+ if (adev->cfgopt_dot11PBCCOption) {
10095+ SET_BIT(cap, WF_MGMT_CAP_PBCC);
10096+ }
10097+ if (adev->cfgopt_dot11ChannelAgility) {
10098+ SET_BIT(cap, WF_MGMT_CAP_AGILITY);
10099+ }
10100+ log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n",
10101+ adev->capabilities, cap);
10102+ adev->capabilities = cap;
10103+}
10104+
10105+/***********************************************************************
10106+** Common function to parse ALL configoption struct formats
10107+** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?).
10108+** FIXME: logging should be removed here and added to a /proc file instead
10109+*/
10110+void
10111+acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg)
10112+{
10113+ const u8 *pEle;
10114+ int i;
10115+ int is_acx111 = IS_ACX111(adev);
10116+
10117+ if (acx_debug & L_DEBUG) {
10118+ printk("configoption struct content:\n");
10119+ acx_dump_bytes(pcfg, sizeof(*pcfg));
10120+ }
10121+
10122+ if (( is_acx111 && (adev->eeprom_version == 5))
10123+ || (!is_acx111 && (adev->eeprom_version == 4))
10124+ || (!is_acx111 && (adev->eeprom_version == 5))) {
10125+ /* these versions are known to be supported */
10126+ } else {
10127+ printk("unknown chip and EEPROM version combination (%s, v%d), "
10128+ "don't know how to parse config options yet. "
10129+ "Please report\n", is_acx111 ? "ACX111" : "ACX100",
10130+ adev->eeprom_version);
10131+ return;
10132+ }
10133+
10134+ /* first custom-parse the first part which has chip-specific layout */
10135+
10136+ pEle = (const u8 *) pcfg;
10137+
10138+ pEle += 4; /* skip (type,len) header */
10139+
10140+ memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv));
10141+ pEle += sizeof(adev->cfgopt_NVSv);
10142+
10143+ if (is_acx111) {
10144+ adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *)pEle);
10145+ pEle += sizeof(adev->cfgopt_NVS_vendor_offs);
10146+
10147+ adev->cfgopt_probe_delay = 200; /* good default value? */
10148+ pEle += 2; /* FIXME: unknown, value 0x0001 */
10149+ } else {
10150+ memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC));
10151+ pEle += sizeof(adev->cfgopt_MAC);
10152+
10153+ adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *)pEle);
10154+ pEle += sizeof(adev->cfgopt_probe_delay);
10155+ if ((adev->cfgopt_probe_delay < 100) || (adev->cfgopt_probe_delay > 500)) {
10156+ printk("strange probe_delay value %d, "
10157+ "tweaking to 200\n", adev->cfgopt_probe_delay);
10158+ adev->cfgopt_probe_delay = 200;
10159+ }
10160+ }
10161+
10162+ adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *)pEle);
10163+ pEle += sizeof(adev->cfgopt_eof_memory);
10164+
10165+ printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n",
10166+ adev->cfgopt_NVS_vendor_offs,
10167+ adev->cfgopt_probe_delay,
10168+ adev->cfgopt_eof_memory);
10169+
10170+ adev->cfgopt_dot11CCAModes = *pEle++;
10171+ adev->cfgopt_dot11Diversity = *pEle++;
10172+ adev->cfgopt_dot11ShortPreambleOption = *pEle++;
10173+ adev->cfgopt_dot11PBCCOption = *pEle++;
10174+ adev->cfgopt_dot11ChannelAgility = *pEle++;
10175+ adev->cfgopt_dot11PhyType = *pEle++;
10176+ adev->cfgopt_dot11TempType = *pEle++;
10177+ printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X "
10178+ "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n",
10179+ adev->cfgopt_dot11CCAModes,
10180+ adev->cfgopt_dot11Diversity,
10181+ adev->cfgopt_dot11ShortPreambleOption,
10182+ adev->cfgopt_dot11PBCCOption,
10183+ adev->cfgopt_dot11ChannelAgility,
10184+ adev->cfgopt_dot11PhyType,
10185+ adev->cfgopt_dot11TempType);
10186+
10187+ /* then use common parsing for next part which has common layout */
10188+
10189+ pEle++; /* skip table_count (6) */
10190+
10191+ if (IS_MEM(adev) && IS_ACX100(adev))
10192+ {
10193+ /*
10194+ * For iPaq hx4700 Generic Slave F/W 1.10.7.K. I'm not sure if these
10195+ * 4 extra bytes are before the dot11 things above or after, so I'm just
10196+ * going to guess after. If someone sees these aren't reasonable numbers,
10197+ * please fix this.
10198+ * The area from which the dot11 values above are read contains:
10199+ * 04 01 01 01 00 05 01 06 00 02 01 02
10200+ * the 8 dot11 reads above take care of 8 of them, but which 8...
10201+ */
10202+ pEle += 4;
10203+ }
10204+
10205+ adev->cfgopt_antennas.type = pEle[0];
10206+ adev->cfgopt_antennas.len = pEle[1];
10207+ printk("AntennaID:%02X Len:%02X Data:",
10208+ adev->cfgopt_antennas.type, adev->cfgopt_antennas.len);
10209+ for (i = 0; i < pEle[1]; i++) {
10210+ adev->cfgopt_antennas.list[i] = pEle[i+2];
10211+ printk("%02X ", pEle[i+2]);
10212+ }
10213+ printk("\n");
10214+
10215+ pEle += pEle[1] + 2;
10216+ adev->cfgopt_power_levels.type = pEle[0];
10217+ adev->cfgopt_power_levels.len = pEle[1];
10218+ printk("PowerLevelID:%02X Len:%02X Data:",
10219+ adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len);
10220+ for (i = 0; i < pEle[1]; i++) {
10221+ adev->cfgopt_power_levels.list[i] = le16_to_cpu(*(u16 *)&pEle[i*2+2]);
10222+ printk("%04X ", adev->cfgopt_power_levels.list[i]);
10223+ }
10224+ printk("\n");
10225+
10226+ pEle += pEle[1]*2 + 2;
10227+ adev->cfgopt_data_rates.type = pEle[0];
10228+ adev->cfgopt_data_rates.len = pEle[1];
10229+ printk("DataRatesID:%02X Len:%02X Data:",
10230+ adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len);
10231+ for (i = 0; i < pEle[1]; i++) {
10232+ adev->cfgopt_data_rates.list[i] = pEle[i+2];
10233+ printk("%02X ", pEle[i+2]);
10234+ }
10235+ printk("\n");
10236+
10237+ pEle += pEle[1] + 2;
10238+ adev->cfgopt_domains.type = pEle[0];
10239+ adev->cfgopt_domains.len = pEle[1];
10240+ if (IS_MEM(adev) && IS_ACX100(adev))
10241+ {
10242+ /*
10243+ * For iPaq hx4700 Generic Slave F/W 1.10.7.K.
10244+ * There's an extra byte between this structure and the next
10245+ * that is not accounted for with this structure's length. It's
10246+ * most likely a bug in the firmware, but we can fix it here
10247+ * by bumping the length of this field by 1.
10248+ */
10249+ adev->cfgopt_domains.len++;
10250+ }
10251+ printk("DomainID:%02X Len:%02X Data:",
10252+ adev->cfgopt_domains.type, adev->cfgopt_domains.len);
10253+ for (i = 0; i < adev->cfgopt_domains.len; i++) {
10254+ adev->cfgopt_domains.list[i] = pEle[i+2];
10255+ printk("%02X ", pEle[i+2]);
10256+ }
10257+ printk("\n");
10258+
10259+ pEle += adev->cfgopt_domains.len + 2;
10260+
10261+ adev->cfgopt_product_id.type = pEle[0];
10262+ adev->cfgopt_product_id.len = pEle[1];
10263+ for (i = 0; i < pEle[1]; i++) {
10264+ adev->cfgopt_product_id.list[i] = pEle[i+2];
10265+ }
10266+ printk("ProductID:%02X Len:%02X Data:%.*s\n",
10267+ adev->cfgopt_product_id.type, adev->cfgopt_product_id.len,
10268+ adev->cfgopt_product_id.len, (char *)adev->cfgopt_product_id.list);
10269+
10270+ pEle += pEle[1] + 2;
10271+ adev->cfgopt_manufacturer.type = pEle[0];
10272+ adev->cfgopt_manufacturer.len = pEle[1];
10273+ for (i = 0; i < pEle[1]; i++) {
10274+ adev->cfgopt_manufacturer.list[i] = pEle[i+2];
10275+ }
10276+ printk("ManufacturerID:%02X Len:%02X Data:%.*s\n",
10277+ adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len,
10278+ adev->cfgopt_manufacturer.len, (char *)adev->cfgopt_manufacturer.list);
10279+/*
10280+ printk("EEPROM part:\n");
10281+ for (i=0; i<58; i++) {
10282+ printk("%02X =======> 0x%02X\n",
10283+ i, (u8 *)adev->cfgopt_NVSv[i-2]);
10284+ }
10285+*/
10286+}
10287+
10288+
10289+/***********************************************************************
10290+*/
10291+static int __init
10292+acx_e_init_module(void)
10293+{
10294+ int r1,r2,r3,r4;
10295+
10296+ acx_struct_size_check();
10297+
10298+ printk("acx: this driver is still EXPERIMENTAL\n"
10299+ "acx: reading README file and/or Craig's HOWTO is "
10300+ "recommended, visit http://acx100.sf.net in case "
10301+ "of further questions/discussion\n");
10302+
10303+#if defined(CONFIG_ACX_PCI)
10304+ r1 = acxpci_e_init_module();
10305+#else
10306+ r1 = -EINVAL;
10307+#endif
10308+#if defined(CONFIG_ACX_MEM)
10309+ r2 = acxmem_e_init_module();
10310+#else
10311+ r2 = -EINVAL;
10312+#endif
10313+#if defined(CONFIG_ACX_USB)
10314+ r3 = acxusb_e_init_module();
10315+#else
10316+ r3 = -EINVAL;
10317+#endif
10318+#if defined(CONFIG_ACX_CS)
10319+ r4 = acx_cs_init();
10320+#else
10321+ r4 = -EINVAL;
10322+#endif
10323+ if (r2 && r1 && r3 && r4) { /* all failed! */
10324+ if (r3 || r1)
10325+ return r3 ? r3 : r1;
10326+ else
10327+ return r2;
10328+ }
10329+ /* return success if at least one succeeded */
10330+ return 0;
10331+
10332+}
10333+
10334+static void __exit
10335+acx_e_cleanup_module(void)
10336+{
10337+#if defined(CONFIG_ACX_PCI)
10338+ acxpci_e_cleanup_module();
10339+#endif
10340+#if defined(CONFIG_ACX_MEM)
10341+ acxmem_e_cleanup_module();
10342+#endif
10343+#if defined(CONFIG_ACX_USB)
10344+ acxusb_e_cleanup_module();
10345+#endif
10346+#if defined(CONFIG_ACX_CS)
10347+ acx_cs_cleanup();
10348+#endif
10349+}
10350+
10351+module_init(acx_e_init_module)
10352+module_exit(acx_e_cleanup_module)
10353Index: linux-2.6.22/drivers/net/wireless/acx/conv.c
10354===================================================================
10355--- /dev/null 1970-01-01 00:00:00.000000000 +0000
10356+++ linux-2.6.22/drivers/net/wireless/acx/conv.c 2007-08-23 18:34:19.000000000 +0200
10357@@ -0,0 +1,504 @@
10358+/***********************************************************************
10359+** Copyright (C) 2003 ACX100 Open Source Project
10360+**
10361+** The contents of this file are subject to the Mozilla Public
10362+** License Version 1.1 (the "License"); you may not use this file
10363+** except in compliance with the License. You may obtain a copy of
10364+** the License at http://www.mozilla.org/MPL/
10365+**
10366+** Software distributed under the License is distributed on an "AS
10367+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10368+** implied. See the License for the specific language governing
10369+** rights and limitations under the License.
10370+**
10371+** Alternatively, the contents of this file may be used under the
10372+** terms of the GNU Public License version 2 (the "GPL"), in which
10373+** case the provisions of the GPL are applicable instead of the
10374+** above. If you wish to allow the use of your version of this file
10375+** only under the terms of the GPL and not to allow others to use
10376+** your version of this file under the MPL, indicate your decision
10377+** by deleting the provisions above and replace them with the notice
10378+** and other provisions required by the GPL. If you do not delete
10379+** the provisions above, a recipient may use your version of this
10380+** file under either the MPL or the GPL.
10381+** ---------------------------------------------------------------------
10382+** Inquiries regarding the ACX100 Open Source Project can be
10383+** made directly to:
10384+**
10385+** acx100-users@lists.sf.net
10386+** http://acx100.sf.net
10387+** ---------------------------------------------------------------------
10388+*/
10389+
10390+#include <linux/version.h>
10391+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
10392+#include <linux/config.h>
10393+#endif
10394+#include <linux/skbuff.h>
10395+#include <linux/if_arp.h>
10396+#include <linux/etherdevice.h>
10397+#include <linux/wireless.h>
10398+#include <net/iw_handler.h>
10399+
10400+#include "acx.h"
10401+
10402+
10403+/***********************************************************************
10404+** proto_is_stt
10405+**
10406+** Searches the 802.1h Selective Translation Table for a given
10407+** protocol.
10408+**
10409+** prottype - protocol number (in host order) to search for.
10410+**
10411+** Returns:
10412+** 1 - if the table is empty or a match is found.
10413+** 0 - if the table is non-empty and a match is not found.
10414+**
10415+** Based largely on p80211conv.c of the linux-wlan-ng project
10416+*/
10417+static inline int
10418+proto_is_stt(unsigned int proto)
10419+{
10420+ /* Always return found for now. This is the behavior used by the */
10421+ /* Zoom Win95 driver when 802.1h mode is selected */
10422+ /* TODO: If necessary, add an actual search we'll probably
10423+ need this to match the CMAC's way of doing things.
10424+ Need to do some testing to confirm.
10425+ */
10426+
10427+ if (proto == 0x80f3) /* APPLETALK */
10428+ return 1;
10429+
10430+ return 0;
10431+/* return ((prottype == ETH_P_AARP) || (prottype == ETH_P_IPX)); */
10432+}
10433+
10434+/* Helpers */
10435+
10436+static inline void
10437+store_llc_snap(struct wlan_llc *llc)
10438+{
10439+ llc->dsap = 0xaa; /* SNAP, see IEEE 802 */
10440+ llc->ssap = 0xaa;
10441+ llc->ctl = 0x03;
10442+}
10443+static inline int
10444+llc_is_snap(const struct wlan_llc *llc)
10445+{
10446+ return (llc->dsap == 0xaa)
10447+ && (llc->ssap == 0xaa)
10448+ && (llc->ctl == 0x03);
10449+}
10450+static inline void
10451+store_oui_rfc1042(struct wlan_snap *snap)
10452+{
10453+ snap->oui[0] = 0;
10454+ snap->oui[1] = 0;
10455+ snap->oui[2] = 0;
10456+}
10457+static inline int
10458+oui_is_rfc1042(const struct wlan_snap *snap)
10459+{
10460+ return (snap->oui[0] == 0)
10461+ && (snap->oui[1] == 0)
10462+ && (snap->oui[2] == 0);
10463+}
10464+static inline void
10465+store_oui_8021h(struct wlan_snap *snap)
10466+{
10467+ snap->oui[0] = 0;
10468+ snap->oui[1] = 0;
10469+ snap->oui[2] = 0xf8;
10470+}
10471+static inline int
10472+oui_is_8021h(const struct wlan_snap *snap)
10473+{
10474+ return (snap->oui[0] == 0)
10475+ && (snap->oui[1] == 0)
10476+ && (snap->oui[2] == 0xf8);
10477+}
10478+
10479+
10480+/***********************************************************************
10481+** acx_ether_to_txbuf
10482+**
10483+** Uses the contents of the ether frame to build the elements of
10484+** the 802.11 frame.
10485+**
10486+** We don't actually set up the frame header here. That's the
10487+** MAC's job. We're only handling conversion of DIXII or 802.3+LLC
10488+** frames to something that works with 802.11.
10489+**
10490+** Based largely on p80211conv.c of the linux-wlan-ng project
10491+*/
10492+int
10493+acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb)
10494+{
10495+ struct wlan_hdr_a3 *w_hdr;
10496+ struct wlan_ethhdr *e_hdr;
10497+ struct wlan_llc *e_llc;
10498+ struct wlan_snap *e_snap;
10499+ const u8 *a1, *a3;
10500+ int header_len, payload_len = -1;
10501+ /* protocol type or data length, depending on whether
10502+ * DIX or 802.3 ethernet format */
10503+ u16 proto;
10504+ u16 fc;
10505+
10506+ FN_ENTER;
10507+
10508+ if (unlikely(!skb->len)) {
10509+ log(L_DEBUG, "zero-length skb!\n");
10510+ goto end;
10511+ }
10512+
10513+ w_hdr = (struct wlan_hdr_a3*)txbuf;
10514+
10515+ switch (adev->mode) {
10516+ case ACX_MODE_MONITOR:
10517+ /* NB: one day we might want to play with DESC_CTL2_FCS
10518+ ** Will need to stop doing "- WLAN_FCS_LEN" here then */
10519+ if (unlikely(skb->len >= WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_FCS_LEN)) {
10520+ printk("%s: can't tx oversized frame (%d bytes)\n",
10521+ adev->ndev->name, skb->len);
10522+ goto end;
10523+ }
10524+ memcpy(w_hdr, skb->data, skb->len);
10525+ payload_len = skb->len;
10526+ goto end;
10527+ }
10528+
10529+ /* step 1: classify ether frame, DIX or 802.3? */
10530+ e_hdr = (wlan_ethhdr_t *)skb->data;
10531+ proto = ntohs(e_hdr->type);
10532+ if (proto <= 1500) {
10533+ log(L_DEBUG, "tx: 802.3 len: %d\n", skb->len);
10534+ /* codes <= 1500 reserved for 802.3 lengths */
10535+ /* it's 802.3, pass ether payload unchanged, */
10536+ /* trim off ethernet header and copy payload to txdesc */
10537+ header_len = WLAN_HDR_A3_LEN;
10538+ } else {
10539+ /* it's DIXII, time for some conversion */
10540+ /* Create 802.11 packet. Header also contains llc and snap. */
10541+
10542+ log(L_DEBUG, "tx: DIXII len: %d\n", skb->len);
10543+
10544+ /* size of header is 802.11 header + llc + snap */
10545+ header_len = WLAN_HDR_A3_LEN + sizeof(wlan_llc_t) + sizeof(wlan_snap_t);
10546+ /* llc is located behind the 802.11 header */
10547+ e_llc = (wlan_llc_t*)(w_hdr + 1);
10548+ /* snap is located behind the llc */
10549+ e_snap = (wlan_snap_t*)(e_llc + 1);
10550+
10551+ /* setup the LLC header */
10552+ store_llc_snap(e_llc);
10553+
10554+ /* setup the SNAP header */
10555+ e_snap->type = htons(proto);
10556+ if (proto_is_stt(proto)) {
10557+ store_oui_8021h(e_snap);
10558+ } else {
10559+ store_oui_rfc1042(e_snap);
10560+ }
10561+ }
10562+ /* trim off ethernet header and copy payload to txbuf */
10563+ payload_len = skb->len - sizeof(wlan_ethhdr_t);
10564+ /* TODO: can we just let acx DMA payload from skb instead? */
10565+ memcpy((u8*)txbuf + header_len, skb->data + sizeof(wlan_ethhdr_t), payload_len);
10566+ payload_len += header_len;
10567+
10568+ /* Set up the 802.11 header */
10569+ switch (adev->mode) {
10570+ case ACX_MODE_0_ADHOC:
10571+ fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi);
10572+ a1 = e_hdr->daddr;
10573+ a3 = adev->bssid;
10574+ break;
10575+ case ACX_MODE_2_STA:
10576+ fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_TODSi);
10577+ a1 = adev->bssid;
10578+ a3 = e_hdr->daddr;
10579+ break;
10580+ case ACX_MODE_3_AP:
10581+ fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_FROMDSi);
10582+ a1 = e_hdr->daddr;
10583+ a3 = e_hdr->saddr;
10584+ break;
10585+ default:
10586+ printk("%s: error - converting eth to wlan in unknown mode\n",
10587+ adev->ndev->name);
10588+ payload_len = -1;
10589+ goto end;
10590+ }
10591+ if (adev->wep_enabled)
10592+ SET_BIT(fc, WF_FC_ISWEPi);
10593+
10594+ w_hdr->fc = fc;
10595+ w_hdr->dur = 0;
10596+ MAC_COPY(w_hdr->a1, a1);
10597+ MAC_COPY(w_hdr->a2, adev->dev_addr);
10598+ MAC_COPY(w_hdr->a3, a3);
10599+ w_hdr->seq = 0;
10600+
10601+#ifdef DEBUG_CONVERT
10602+ if (acx_debug & L_DATA) {
10603+ printk("original eth frame [%d]: ", skb->len);
10604+ acx_dump_bytes(skb->data, skb->len);
10605+ printk("802.11 frame [%d]: ", payload_len);
10606+ acx_dump_bytes(w_hdr, payload_len);
10607+ }
10608+#endif
10609+
10610+end:
10611+ FN_EXIT1(payload_len);
10612+ return payload_len;
10613+}
10614+
10615+
10616+/***********************************************************************
10617+** acx_rxbuf_to_ether
10618+**
10619+** Uses the contents of a received 802.11 frame to build an ether
10620+** frame.
10621+**
10622+** This function extracts the src and dest address from the 802.11
10623+** frame to use in the construction of the eth frame.
10624+**
10625+** Based largely on p80211conv.c of the linux-wlan-ng project
10626+*/
10627+struct sk_buff*
10628+acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf)
10629+{
10630+ struct wlan_hdr *w_hdr;
10631+ struct wlan_ethhdr *e_hdr;
10632+ struct wlan_llc *e_llc;
10633+ struct wlan_snap *e_snap;
10634+ struct sk_buff *skb;
10635+ const u8 *daddr;
10636+ const u8 *saddr;
10637+ const u8 *e_payload;
10638+ int buflen, payload_length;
10639+ unsigned int payload_offset, mtu;
10640+ u16 fc;
10641+
10642+ FN_ENTER;
10643+
10644+ /* This looks complex because it must handle possible
10645+ ** phy header in rxbuff */
10646+ w_hdr = acx_get_wlan_hdr(adev, rxbuf);
10647+ payload_offset = WLAN_HDR_A3_LEN; /* it is relative to w_hdr */
10648+ payload_length = RXBUF_BYTES_USED(rxbuf) /* entire rxbuff... */
10649+ - ((u8*)w_hdr - (u8*)rxbuf) /* minus space before 802.11 frame */
10650+ - WLAN_HDR_A3_LEN; /* minus 802.11 header */
10651+
10652+ /* setup some vars for convenience */
10653+ fc = w_hdr->fc;
10654+ switch (WF_FC_FROMTODSi & fc) {
10655+ case 0:
10656+ daddr = w_hdr->a1;
10657+ saddr = w_hdr->a2;
10658+ break;
10659+ case WF_FC_FROMDSi:
10660+ daddr = w_hdr->a1;
10661+ saddr = w_hdr->a3;
10662+ break;
10663+ case WF_FC_TODSi:
10664+ daddr = w_hdr->a3;
10665+ saddr = w_hdr->a2;
10666+ break;
10667+ default: /* WF_FC_FROMTODSi */
10668+ payload_offset += (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
10669+ payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
10670+ daddr = w_hdr->a3;
10671+ saddr = w_hdr->a4;
10672+ }
10673+
10674+ if ((WF_FC_ISWEPi & fc) && IS_ACX100(adev)) {
10675+ /* chop off the IV+ICV WEP header and footer */
10676+ log(L_DATA|L_DEBUG, "rx: WEP packet, "
10677+ "chopping off IV and ICV\n");
10678+ payload_offset += WLAN_WEP_IV_LEN;
10679+ payload_length -= WLAN_WEP_IV_LEN + WLAN_WEP_ICV_LEN;
10680+ }
10681+
10682+ if (unlikely(payload_length < 0)) {
10683+ printk("%s: rx frame too short, ignored\n", adev->ndev->name);
10684+ goto ret_null;
10685+ }
10686+
10687+ e_hdr = (wlan_ethhdr_t*) ((u8*) w_hdr + payload_offset);
10688+ e_llc = (wlan_llc_t*) e_hdr;
10689+ e_snap = (wlan_snap_t*) (e_llc + 1);
10690+ mtu = adev->ndev->mtu;
10691+ e_payload = (u8*) (e_snap + 1);
10692+
10693+ log(L_DATA, "rx: payload_offset %d, payload_length %d\n",
10694+ payload_offset, payload_length);
10695+ log(L_XFER|L_DATA,
10696+ "rx: frame info: llc=%02X%02X%02X "
10697+ "snap.oui=%02X%02X%02X snap.type=%04X\n",
10698+ e_llc->dsap, e_llc->ssap, e_llc->ctl,
10699+ e_snap->oui[0], e_snap->oui[1], e_snap->oui[2],
10700+ ntohs(e_snap->type));
10701+
10702+ /* Test for the various encodings */
10703+ if ((payload_length >= sizeof(wlan_ethhdr_t))
10704+ && ((e_llc->dsap != 0xaa) || (e_llc->ssap != 0xaa))
10705+ && ( (mac_is_equal(daddr, e_hdr->daddr))
10706+ || (mac_is_equal(saddr, e_hdr->saddr))
10707+ )
10708+ ) {
10709+ /* 802.3 Encapsulated: */
10710+ /* wlan frame body contains complete eth frame (header+body) */
10711+ log(L_DEBUG|L_DATA, "rx: 802.3 ENCAP len=%d\n", payload_length);
10712+
10713+ if (unlikely(payload_length > (mtu + ETH_HLEN))) {
10714+ printk("%s: rx: ENCAP frame too large (%d > %d)\n",
10715+ adev->ndev->name,
10716+ payload_length, mtu + ETH_HLEN);
10717+ goto ret_null;
10718+ }
10719+
10720+ /* allocate space and setup host buffer */
10721+ buflen = payload_length;
10722+ /* Attempt to align IP header (14 bytes eth header + 2 = 16) */
10723+ skb = dev_alloc_skb(buflen + 2);
10724+ if (unlikely(!skb))
10725+ goto no_skb;
10726+ skb_reserve(skb, 2);
10727+ skb_put(skb, buflen); /* make room */
10728+
10729+ /* now copy the data from the 80211 frame */
10730+ memcpy(skb->data, e_hdr, payload_length);
10731+
10732+ } else if ( (payload_length >= sizeof(wlan_llc_t)+sizeof(wlan_snap_t))
10733+ && llc_is_snap(e_llc) ) {
10734+ /* wlan frame body contains: AA AA 03 ... (it's a SNAP) */
10735+
10736+ if ( !oui_is_rfc1042(e_snap)
10737+ || (proto_is_stt(ieee2host16(e_snap->type)) /* && (ethconv == WLAN_ETHCONV_8021h) */)) {
10738+ log(L_DEBUG|L_DATA, "rx: SNAP+RFC1042 len=%d\n", payload_length);
10739+ /* wlan frame body contains: AA AA 03 !(00 00 00) ... -or- */
10740+ /* wlan frame body contains: AA AA 03 00 00 00 0x80f3 ... */
10741+ /* build eth hdr, type = len, copy AA AA 03... as eth body */
10742+ /* it's a SNAP + RFC1042 frame && protocol is in STT */
10743+
10744+ if (unlikely(payload_length > mtu)) {
10745+ printk("%s: rx: SNAP frame too large (%d > %d)\n",
10746+ adev->ndev->name,
10747+ payload_length, mtu);
10748+ goto ret_null;
10749+ }
10750+
10751+ /* allocate space and setup host buffer */
10752+ buflen = payload_length + ETH_HLEN;
10753+ skb = dev_alloc_skb(buflen + 2);
10754+ if (unlikely(!skb))
10755+ goto no_skb;
10756+ skb_reserve(skb, 2);
10757+ skb_put(skb, buflen); /* make room */
10758+
10759+ /* create 802.3 header */
10760+ e_hdr = (wlan_ethhdr_t*) skb->data;
10761+ MAC_COPY(e_hdr->daddr, daddr);
10762+ MAC_COPY(e_hdr->saddr, saddr);
10763+ e_hdr->type = htons(payload_length);
10764+
10765+ /* Now copy the data from the 80211 frame.
10766+ Make room in front for the eth header, and keep the
10767+ llc and snap from the 802.11 payload */
10768+ memcpy(skb->data + ETH_HLEN,
10769+ e_llc, payload_length);
10770+
10771+ } else {
10772+ /* wlan frame body contains: AA AA 03 00 00 00 [type] [tail] */
10773+ /* build eth hdr, type=[type], copy [tail] as eth body */
10774+ log(L_DEBUG|L_DATA, "rx: 802.1h/RFC1042 len=%d\n",
10775+ payload_length);
10776+ /* it's an 802.1h frame (an RFC1042 && protocol is not in STT) */
10777+ /* build a DIXII + RFC894 */
10778+
10779+ payload_length -= sizeof(wlan_llc_t) + sizeof(wlan_snap_t);
10780+ if (unlikely(payload_length > mtu)) {
10781+ printk("%s: rx: DIXII frame too large (%d > %d)\n",
10782+ adev->ndev->name,
10783+ payload_length, mtu);
10784+ goto ret_null;
10785+ }
10786+
10787+ /* allocate space and setup host buffer */
10788+ buflen = payload_length + ETH_HLEN;
10789+ skb = dev_alloc_skb(buflen + 2);
10790+ if (unlikely(!skb))
10791+ goto no_skb;
10792+ skb_reserve(skb, 2);
10793+ skb_put(skb, buflen); /* make room */
10794+
10795+ /* create 802.3 header */
10796+ e_hdr = (wlan_ethhdr_t *) skb->data;
10797+ MAC_COPY(e_hdr->daddr, daddr);
10798+ MAC_COPY(e_hdr->saddr, saddr);
10799+ e_hdr->type = e_snap->type;
10800+
10801+ /* Now copy the data from the 80211 frame.
10802+ Make room in front for the eth header, and cut off the
10803+ llc and snap from the 802.11 payload */
10804+ memcpy(skb->data + ETH_HLEN,
10805+ e_payload, payload_length);
10806+ }
10807+
10808+ } else {
10809+ log(L_DEBUG|L_DATA, "rx: NON-ENCAP len=%d\n", payload_length);
10810+ /* build eth hdr, type=len, copy wlan body as eth body */
10811+ /* any NON-ENCAP */
10812+ /* it's a generic 80211+LLC or IPX 'Raw 802.3' */
10813+ /* build an 802.3 frame */
10814+
10815+ if (unlikely(payload_length > mtu)) {
10816+ printk("%s: rx: OTHER frame too large (%d > %d)\n",
10817+ adev->ndev->name, payload_length, mtu);
10818+ goto ret_null;
10819+ }
10820+
10821+ /* allocate space and setup host buffer */
10822+ buflen = payload_length + ETH_HLEN;
10823+ skb = dev_alloc_skb(buflen + 2);
10824+ if (unlikely(!skb))
10825+ goto no_skb;
10826+ skb_reserve(skb, 2);
10827+ skb_put(skb, buflen); /* make room */
10828+
10829+ /* set up the 802.3 header */
10830+ e_hdr = (wlan_ethhdr_t *) skb->data;
10831+ MAC_COPY(e_hdr->daddr, daddr);
10832+ MAC_COPY(e_hdr->saddr, saddr);
10833+ e_hdr->type = htons(payload_length);
10834+
10835+ /* now copy the data from the 80211 frame */
10836+ memcpy(skb->data + ETH_HLEN, e_llc, payload_length);
10837+ }
10838+
10839+ skb->dev = adev->ndev;
10840+ skb->protocol = eth_type_trans(skb, adev->ndev);
10841+
10842+#ifdef DEBUG_CONVERT
10843+ if (acx_debug & L_DATA) {
10844+ int len = RXBUF_BYTES_RCVD(adev, rxbuf);
10845+ printk("p802.11 frame [%d]: ", len);
10846+ acx_dump_bytes(w_hdr, len);
10847+ printk("eth frame [%d]: ", skb->len);
10848+ acx_dump_bytes(skb->data, skb->len);
10849+ }
10850+#endif
10851+
10852+ FN_EXIT0;
10853+ return skb;
10854+
10855+no_skb:
10856+ printk("%s: rx: no memory for skb (%d bytes)\n",
10857+ adev->ndev->name, buflen + 2);
10858+ret_null:
10859+ FN_EXIT1((int)NULL);
10860+ return NULL;
10861+}
10862Index: linux-2.6.22/drivers/net/wireless/acx/cs.c
10863===================================================================
10864--- /dev/null 1970-01-01 00:00:00.000000000 +0000
10865+++ linux-2.6.22/drivers/net/wireless/acx/cs.c 2007-08-23 18:34:19.000000000 +0200
10866@@ -0,0 +1,5703 @@
10867+/***********************************************************************
10868+** Copyright (C) 2003 ACX100 Open Source Project
10869+**
10870+** The contents of this file are subject to the Mozilla Public
10871+** License Version 1.1 (the "License"); you may not use this file
10872+** except in compliance with the License. You may obtain a copy of
10873+** the License at http://www.mozilla.org/MPL/
10874+**
10875+** Software distributed under the License is distributed on an "AS
10876+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10877+** implied. See the License for the specific language governing
10878+** rights and limitations under the License.
10879+**
10880+** Alternatively, the contents of this file may be used under the
10881+** terms of the GNU Public License version 2 (the "GPL"), in which
10882+** case the provisions of the GPL are applicable instead of the
10883+** above. If you wish to allow the use of your version of this file
10884+** only under the terms of the GPL and not to allow others to use
10885+** your version of this file under the MPL, indicate your decision
10886+** by deleting the provisions above and replace them with the notice
10887+** and other provisions required by the GPL. If you do not delete
10888+** the provisions above, a recipient may use your version of this
10889+** file under either the MPL or the GPL.
10890+** ---------------------------------------------------------------------
10891+** Inquiries regarding the ACX100 Open Source Project can be
10892+** made directly to:
10893+**
10894+** acx100-users@lists.sf.net
10895+** http://acx100.sf.net
10896+** ---------------------------------------------------------------------
10897+**
10898+** Slave memory interface support:
10899+**
10900+** Todd Blumer - SDG Systems
10901+** Bill Reese - HP
10902+** Eric McCorkle - Shadowsun
10903+**
10904+** CF support, (c) Fabrice Crohas, Paul Sokolovsky
10905+*/
10906+#define ACX_MEM 1
10907+
10908+/*
10909+ * non-zero makes it dump the ACX memory to the console then
10910+ * panic when you cat /proc/driver/acx_wlan0_diag
10911+ */
10912+#define DUMP_MEM_DEFINED 1
10913+
10914+#define DUMP_MEM_DURING_DIAG 0
10915+#define DUMP_IF_SLOW 0
10916+
10917+#define PATCH_AROUND_BAD_SPOTS 1
10918+#define HX4700_FIRMWARE_CHECKSUM 0x0036862e
10919+#define HX4700_ALTERNATE_FIRMWARE_CHECKSUM 0x00368a75
10920+
10921+#include <linux/version.h>
10922+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
10923+#include <linux/config.h>
10924+#endif
10925+
10926+/* Linux 2.6.18+ uses <linux/utsrelease.h> */
10927+#ifndef UTS_RELEASE
10928+#include <linux/utsrelease.h>
10929+#endif
10930+
10931+#include <linux/compiler.h> /* required for Lx 2.6.8 ?? */
10932+#include <linux/kernel.h>
10933+#include <linux/module.h>
10934+#include <linux/moduleparam.h>
10935+#include <linux/sched.h>
10936+#include <linux/types.h>
10937+#include <linux/skbuff.h>
10938+#include <linux/slab.h>
10939+#include <linux/if_arp.h>
10940+#include <linux/irq.h>
10941+#include <linux/rtnetlink.h>
10942+#include <linux/wireless.h>
10943+#include <net/iw_handler.h>
10944+#include <linux/netdevice.h>
10945+#include <linux/ioport.h>
10946+#include <linux/pci.h>
10947+#include <linux/platform_device.h>
10948+#include <linux/pm.h>
10949+#include <linux/vmalloc.h>
10950+#include <linux/delay.h>
10951+#include <linux/workqueue.h>
10952+#include <linux/inetdevice.h>
10953+
10954+#define PCMCIA_DEBUG 1
10955+
10956+/*
10957+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
10958+ you do not define PCMCIA_DEBUG at all, all the debug code will be
10959+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
10960+ be present but disabled -- but it can then be enabled for specific
10961+ modules at load time with a 'pc_debug=#' option to insmod.
10962+
10963+*/
10964+#include <pcmcia/cs_types.h>
10965+#include <pcmcia/cs.h>
10966+#include <pcmcia/cistpl.h>
10967+#include <pcmcia/cisreg.h>
10968+#include <pcmcia/ds.h>
10969+#include "acx.h"
10970+#include "acx_hw.h"
10971+
10972+#ifdef PCMCIA_DEBUG
10973+static int pc_debug = PCMCIA_DEBUG;
10974+module_param(pc_debug, int, 0);
10975+static char *version = "$Revision: 1.10 $";
10976+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
10977+#else
10978+#define DEBUG(n, args...)
10979+#endif
10980+
10981+
10982+static win_req_t memwin;
10983+
10984+typedef struct local_info_t {
10985+ dev_node_t node;
10986+ struct net_device *ndev;
10987+} local_info_t;
10988+
10989+static struct net_device *resume_ndev;
10990+
10991+
10992+/***********************************************************************
10993+*/
10994+
10995+#define CARD_EEPROM_ID_SIZE 6
10996+
10997+#include <asm/io.h>
10998+
10999+#define REG_ACX_VENDOR_ID 0x900
11000+/*
11001+ * This is the vendor id on the HX4700, anyway
11002+ */
11003+#define ACX_VENDOR_ID 0x8400104c
11004+
11005+typedef enum {
11006+ ACX_SOFT_RESET = 0,
11007+
11008+ ACX_SLV_REG_ADDR,
11009+ ACX_SLV_REG_DATA,
11010+ ACX_SLV_REG_ADATA,
11011+
11012+ ACX_SLV_MEM_CP,
11013+ ACX_SLV_MEM_ADDR,
11014+ ACX_SLV_MEM_DATA,
11015+ ACX_SLV_MEM_CTL,
11016+} acxreg_t;
11017+
11018+/***********************************************************************
11019+*/
11020+static void acxmem_i_tx_timeout(struct net_device *ndev);
11021+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
11022+static irqreturn_t acxmem_i_interrupt(int irq, void *dev_id);
11023+#else
11024+static irqreturn_t acxmem_i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
11025+#endif
11026+static void acxmem_i_set_multicast_list(struct net_device *ndev);
11027+
11028+static int acxmem_e_open(struct net_device *ndev);
11029+static int acxmem_e_close(struct net_device *ndev);
11030+static void acxmem_s_up(struct net_device *ndev);
11031+static void acxmem_s_down(struct net_device *ndev);
11032+
11033+static void dump_acxmem (acx_device_t *adev, u32 start, int length);
11034+static int acxmem_complete_hw_reset (acx_device_t *adev);
11035+static void acxmem_s_delete_dma_regions(acx_device_t *adev);
11036+
11037+static int
11038+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
11039+acxmem_e_suspend( struct net_device *ndev, pm_message_t state);
11040+#else
11041+acxmem_e_suspend( struct net_device *ndev, u32 state);
11042+#endif
11043+static void
11044+fw_resumer(struct work_struct *notused);
11045+//fw_resumer( void *data );
11046+
11047+static int acx_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
11048+{
11049+ struct net_device *ndev = ptr;
11050+ acx_device_t *adev = ndev2adev(ndev);
11051+
11052+ /*
11053+ * Upper level ioctl() handlers send a NETDEV_CHANGEADDR if the MAC address changes.
11054+ */
11055+
11056+ if (NETDEV_CHANGEADDR == event) {
11057+ /*
11058+ * the upper layers put the new MAC address in ndev->dev_addr; we just copy
11059+ * it over and update the ACX with it.
11060+ */
11061+ MAC_COPY(adev->dev_addr, adev->ndev->dev_addr);
11062+ adev->set_mask |= GETSET_STATION_ID;
11063+ acx_s_update_card_settings (adev);
11064+ }
11065+
11066+ return 0;
11067+}
11068+
11069+static struct notifier_block acx_netdev_notifier = {
11070+ .notifier_call = acx_netdev_event,
11071+};
11072+
11073+/***********************************************************************
11074+** Register access
11075+*/
11076+
11077+/* Pick one */
11078+/* #define INLINE_IO static */
11079+#define INLINE_IO static inline
11080+
11081+INLINE_IO u32
11082+read_id_register (acx_device_t *adev)
11083+{
11084+ writel (0x24, &adev->iobase[ACX_SLV_REG_ADDR]);
11085+ return readl (&adev->iobase[ACX_SLV_REG_DATA]);
11086+}
11087+
11088+INLINE_IO u32
11089+read_reg32(acx_device_t *adev, unsigned int offset)
11090+{
11091+ u32 val;
11092+ u32 addr;
11093+
11094+ if (offset > IO_ACX_ECPU_CTRL)
11095+ addr = offset;
11096+ else
11097+ addr = adev->io[offset];
11098+
11099+ if (addr < 0x20) {
11100+ return readl(((u8*)adev->iobase) + addr);
11101+ }
11102+
11103+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
11104+ val = readl( &adev->iobase[ACX_SLV_REG_DATA] );
11105+
11106+ return val;
11107+}
11108+
11109+INLINE_IO u16
11110+read_reg16(acx_device_t *adev, unsigned int offset)
11111+{
11112+ u16 lo;
11113+ u32 addr;
11114+
11115+ if (offset > IO_ACX_ECPU_CTRL)
11116+ addr = offset;
11117+ else
11118+ addr = adev->io[offset];
11119+
11120+ if (addr < 0x20) {
11121+ return readw(((u8 *) adev->iobase) + addr);
11122+ }
11123+
11124+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
11125+ lo = readw( (u16 *)&adev->iobase[ACX_SLV_REG_DATA] );
11126+
11127+ return lo;
11128+}
11129+
11130+INLINE_IO u8
11131+read_reg8(acx_device_t *adev, unsigned int offset)
11132+{
11133+ u8 lo;
11134+ u32 addr;
11135+
11136+ if (offset > IO_ACX_ECPU_CTRL)
11137+ addr = offset;
11138+ else
11139+ addr = adev->io[offset];
11140+
11141+ if (addr < 0x20)
11142+ return readb(((u8 *)adev->iobase) + addr);
11143+
11144+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
11145+ lo = readw( (u8 *)&adev->iobase[ACX_SLV_REG_DATA] );
11146+
11147+ return (u8)lo;
11148+}
11149+
11150+INLINE_IO void
11151+write_reg32(acx_device_t *adev, unsigned int offset, u32 val)
11152+{
11153+ u32 addr;
11154+
11155+ if (offset > IO_ACX_ECPU_CTRL)
11156+ addr = offset;
11157+ else
11158+ addr = adev->io[offset];
11159+
11160+ if (addr < 0x20) {
11161+ writel(val, ((u8*)adev->iobase) + addr);
11162+ return;
11163+ }
11164+
11165+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
11166+ writel( val, &adev->iobase[ACX_SLV_REG_DATA] );
11167+}
11168+
11169+INLINE_IO void
11170+write_reg16(acx_device_t *adev, unsigned int offset, u16 val)
11171+{
11172+ u32 addr;
11173+
11174+ if (offset > IO_ACX_ECPU_CTRL)
11175+ addr = offset;
11176+ else
11177+ addr = adev->io[offset];
11178+
11179+ if (addr < 0x20) {
11180+ writew(val, ((u8 *)adev->iobase) + addr);
11181+ return;
11182+ }
11183+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
11184+ writew( val, (u16 *) &adev->iobase[ACX_SLV_REG_DATA] );
11185+}
11186+
11187+INLINE_IO void
11188+write_reg8(acx_device_t *adev, unsigned int offset, u8 val)
11189+{
11190+ u32 addr;
11191+
11192+ if (offset > IO_ACX_ECPU_CTRL)
11193+ addr = offset;
11194+ else
11195+ addr = adev->io[offset];
11196+
11197+ if (addr < 0x20) {
11198+ writeb(val, ((u8 *) adev->iobase) + addr);
11199+ return;
11200+ }
11201+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
11202+ writeb( val, (u8 *)&adev->iobase[ACX_SLV_REG_DATA] );
11203+}
11204+
11205+/* Handle PCI posting properly:
11206+ * Make sure that writes reach the adapter in case they require to be executed
11207+ * *before* the next write, by reading a random (and safely accessible) register.
11208+ * This call has to be made if there is no read following (which would flush the data
11209+ * to the adapter), yet the written data has to reach the adapter immediately. */
11210+INLINE_IO void
11211+write_flush(acx_device_t *adev)
11212+{
11213+ /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */
11214+ /* faster version (accesses the first register, IO_ACX_SOFT_RESET,
11215+ * which should also be safe): */
11216+ (void) readl(adev->iobase);
11217+}
11218+
11219+INLINE_IO void
11220+set_regbits (acx_device_t *adev, unsigned int offset, u32 bits) {
11221+ u32 tmp;
11222+
11223+ tmp = read_reg32 (adev, offset);
11224+ tmp = tmp | bits;
11225+ write_reg32 (adev, offset, tmp);
11226+ write_flush (adev);
11227+}
11228+
11229+INLINE_IO void
11230+clear_regbits (acx_device_t *adev, unsigned int offset, u32 bits) {
11231+ u32 tmp;
11232+
11233+ tmp = read_reg32 (adev, offset);
11234+ tmp = tmp & ~bits;
11235+ write_reg32 (adev, offset, tmp);
11236+ write_flush (adev);
11237+}
11238+
11239+/*
11240+ * Copy from PXA memory to the ACX memory. This assumes both the PXA and ACX
11241+ * addresses are 32 bit aligned. Count is in bytes.
11242+ */
11243+INLINE_IO void
11244+write_slavemem32 (acx_device_t *adev, u32 slave_address, u32 val)
11245+{
11246+ write_reg32 (adev, IO_ACX_SLV_MEM_CTL, 0x0);
11247+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, slave_address);
11248+ udelay (10);
11249+ write_reg32 (adev, IO_ACX_SLV_MEM_DATA, val);
11250+}
11251+
11252+INLINE_IO u32
11253+read_slavemem32 (acx_device_t *adev, u32 slave_address)
11254+{
11255+ u32 val;
11256+
11257+ write_reg32 (adev, IO_ACX_SLV_MEM_CTL, 0x0);
11258+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, slave_address);
11259+ udelay (10);
11260+ val = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
11261+
11262+ return val;
11263+}
11264+
11265+INLINE_IO void
11266+write_slavemem8 (acx_device_t *adev, u32 slave_address, u8 val)
11267+{
11268+ u32 data;
11269+ u32 base;
11270+ int offset;
11271+
11272+ /*
11273+ * Get the word containing the target address and the byte offset in that word.
11274+ */
11275+ base = slave_address & ~3;
11276+ offset = (slave_address & 3) * 8;
11277+
11278+ data = read_slavemem32 (adev, base);
11279+ data &= ~(0xff << offset);
11280+ data |= val << offset;
11281+ write_slavemem32 (adev, base, data);
11282+}
11283+
11284+INLINE_IO u8
11285+read_slavemem8 (acx_device_t *adev, u32 slave_address)
11286+{
11287+ u8 val;
11288+ u32 base;
11289+ u32 data;
11290+ int offset;
11291+
11292+ base = slave_address & ~3;
11293+ offset = (slave_address & 3) * 8;
11294+
11295+ data = read_slavemem32 (adev, base);
11296+
11297+ val = (data >> offset) & 0xff;
11298+
11299+ return val;
11300+}
11301+
11302+/*
11303+ * doesn't split across word boundaries
11304+ */
11305+INLINE_IO void
11306+write_slavemem16 (acx_device_t *adev, u32 slave_address, u16 val)
11307+{
11308+ u32 data;
11309+ u32 base;
11310+ int offset;
11311+
11312+ /*
11313+ * Get the word containing the target address and the byte offset in that word.
11314+ */
11315+ base = slave_address & ~3;
11316+ offset = (slave_address & 3) * 8;
11317+
11318+ data = read_slavemem32 (adev, base);
11319+ data &= ~(0xffff << offset);
11320+ data |= val << offset;
11321+ write_slavemem32 (adev, base, data);
11322+}
11323+
11324+/*
11325+ * doesn't split across word boundaries
11326+ */
11327+INLINE_IO u16
11328+read_slavemem16 (acx_device_t *adev, u32 slave_address)
11329+{
11330+ u16 val;
11331+ u32 base;
11332+ u32 data;
11333+ int offset;
11334+
11335+ base = slave_address & ~3;
11336+ offset = (slave_address & 3) * 8;
11337+
11338+ data = read_slavemem32 (adev, base);
11339+
11340+ val = (data >> offset) & 0xffff;
11341+
11342+ return val;
11343+}
11344+
11345+/*
11346+ * Copy from slave memory
11347+ *
11348+ * TODO - rewrite using address autoincrement, handle partial words
11349+ */
11350+void
11351+copy_from_slavemem (acx_device_t *adev, u8 *destination, u32 source, int count) {
11352+ u32 tmp = 0;
11353+ u8 *ptmp = (u8 *) &tmp;
11354+
11355+ /*
11356+ * Right now I'm making the assumption that the destination is aligned, but
11357+ * I'd better check.
11358+ */
11359+ if ((u32) destination & 3) {
11360+ printk ("acx copy_from_slavemem: warning! destination not word-aligned!\n");
11361+ }
11362+
11363+ while (count >= 4) {
11364+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, source);
11365+ udelay (10);
11366+ *((u32 *) destination) = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
11367+ count -= 4;
11368+ source += 4;
11369+ destination += 4;
11370+ }
11371+
11372+ /*
11373+ * If the word reads above didn't satisfy the count, read one more word
11374+ * and transfer a byte at a time until the request is satisfied.
11375+ */
11376+ if (count) {
11377+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, source);
11378+ udelay (10);
11379+ tmp = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
11380+ while (count--) {
11381+ *destination++ = *ptmp++;
11382+ }
11383+ }
11384+}
11385+
11386+/*
11387+ * Copy to slave memory
11388+ *
11389+ * TODO - rewrite using autoincrement, handle partial words
11390+ */
11391+void
11392+copy_to_slavemem (acx_device_t *adev, u32 destination, u8 *source, int count)
11393+{
11394+ u32 tmp = 0;
11395+ u8* ptmp = (u8 *) &tmp;
11396+ static u8 src[512]; /* make static to avoid huge stack objects */
11397+
11398+ /*
11399+ * For now, make sure the source is word-aligned by copying it to a word-aligned
11400+ * buffer. Someday rewrite to avoid the extra copy.
11401+ */
11402+ if (count > sizeof (src)) {
11403+ printk ("acx copy_to_slavemem: Warning! buffer overflow!\n");
11404+ count = sizeof (src);
11405+ }
11406+ memcpy (src, source, count);
11407+ source = src;
11408+
11409+ while (count >= 4) {
11410+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, destination);
11411+ udelay (10);
11412+ write_reg32 (adev, IO_ACX_SLV_MEM_DATA, *((u32 *) source));
11413+ count -= 4;
11414+ source += 4;
11415+ destination += 4;
11416+ }
11417+
11418+ /*
11419+ * If there are leftovers read the next word from the acx and merge in
11420+ * what they want to write.
11421+ */
11422+ if (count) {
11423+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, destination);
11424+ udelay (10);
11425+ tmp = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
11426+ while (count--) {
11427+ *ptmp++ = *source++;
11428+ }
11429+ /*
11430+ * reset address in case we're currently in auto-increment mode
11431+ */
11432+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, destination);
11433+ udelay (10);
11434+ write_reg32 (adev, IO_ACX_SLV_MEM_DATA, tmp);
11435+ udelay (10);
11436+ }
11437+
11438+}
11439+
11440+/*
11441+ * Block copy to slave buffers using memory block chain mode. Copies to the ACX
11442+ * transmit buffer structure with minimal intervention on our part.
11443+ * Interrupts should be disabled when calling this.
11444+ */
11445+void
11446+chaincopy_to_slavemem (acx_device_t *adev, u32 destination, u8 *source, int count)
11447+{
11448+ u32 val;
11449+ u32 *data = (u32 *) source;
11450+ static u8 aligned_source[WLAN_A4FR_MAXLEN_WEP_FCS];
11451+
11452+ /*
11453+ * Warn if the pointers don't look right. Destination must fit in [23:5] with
11454+ * zero elsewhere and source should be 32 bit aligned.
11455+ * This should never happen since we're in control of both, but I want to know about
11456+ * it if it does.
11457+ */
11458+ if ((destination & 0x00ffffe0) != destination) {
11459+ printk ("acx chaincopy: destination block 0x%04x not aligned!\n", destination);
11460+ }
11461+ if (count > sizeof aligned_source) {
11462+ printk( KERN_ERR "chaincopy_to_slavemem overflow!\n" );
11463+ count = sizeof aligned_source;
11464+ }
11465+ if ((u32) source & 3) {
11466+ memcpy (aligned_source, source, count);
11467+ data = (u32 *) aligned_source;
11468+ }
11469+
11470+ /*
11471+ * SLV_MEM_CTL[17:16] = memory block chain mode with auto-increment
11472+ * SLV_MEM_CTL[5:2] = offset to data portion = 1 word
11473+ */
11474+ val = 2 << 16 | 1 << 2;
11475+ writel (val, &adev->iobase[ACX_SLV_MEM_CTL]);
11476+
11477+ /*
11478+ * SLV_MEM_CP[23:5] = start of 1st block
11479+ * SLV_MEM_CP[3:2] = offset to memblkptr = 0
11480+ */
11481+ val = destination & 0x00ffffe0;
11482+ writel (val, &adev->iobase[ACX_SLV_MEM_CP]);
11483+
11484+ /*
11485+ * SLV_MEM_ADDR[23:2] = SLV_MEM_CTL[5:2] + SLV_MEM_CP[23:5]
11486+ */
11487+ val = (destination & 0x00ffffe0) + (1<<2);
11488+ writel (val, &adev->iobase[ACX_SLV_MEM_ADDR]);
11489+
11490+ /*
11491+ * Write the data to the slave data register, rounding up to the end
11492+ * of the word containing the last byte (hence the > 0)
11493+ */
11494+ while (count > 0) {
11495+ writel (*data++, &adev->iobase[ACX_SLV_MEM_DATA]);
11496+ count -= 4;
11497+ }
11498+}
11499+
11500+
11501+/*
11502+ * Block copy from slave buffers using memory block chain mode. Copies from the ACX
11503+ * receive buffer structures with minimal intervention on our part.
11504+ * Interrupts should be disabled when calling this.
11505+ */
11506+void
11507+chaincopy_from_slavemem (acx_device_t *adev, u8 *destination, u32 source, int count)
11508+{
11509+ u32 val;
11510+ u32 *data = (u32 *) destination;
11511+ static u8 aligned_destination[WLAN_A4FR_MAXLEN_WEP_FCS];
11512+ int saved_count = count;
11513+
11514+ /*
11515+ * Warn if the pointers don't look right. Destination must fit in [23:5] with
11516+ * zero elsewhere and source should be 32 bit aligned.
11517+ * Turns out the network stack sends unaligned things, so fix them before
11518+ * copying to the ACX.
11519+ */
11520+ if ((source & 0x00ffffe0) != source) {
11521+ printk ("acx chaincopy: source block 0x%04x not aligned!\n", source);
11522+ dump_acxmem (adev, 0, 0x10000);
11523+ }
11524+ if ((u32) destination & 3) {
11525+ //printk ("acx chaincopy: data destination not word aligned!\n");
11526+ data = (u32 *) aligned_destination;
11527+ if (count > sizeof aligned_destination) {
11528+ printk( KERN_ERR "chaincopy_from_slavemem overflow!\n" );
11529+ count = sizeof aligned_destination;
11530+ }
11531+ }
11532+
11533+ /*
11534+ * SLV_MEM_CTL[17:16] = memory block chain mode with auto-increment
11535+ * SLV_MEM_CTL[5:2] = offset to data portion = 1 word
11536+ */
11537+ val = (2 << 16) | (1 << 2);
11538+ writel (val, &adev->iobase[ACX_SLV_MEM_CTL]);
11539+
11540+ /*
11541+ * SLV_MEM_CP[23:5] = start of 1st block
11542+ * SLV_MEM_CP[3:2] = offset to memblkptr = 0
11543+ */
11544+ val = source & 0x00ffffe0;
11545+ writel (val, &adev->iobase[ACX_SLV_MEM_CP]);
11546+
11547+ /*
11548+ * SLV_MEM_ADDR[23:2] = SLV_MEM_CTL[5:2] + SLV_MEM_CP[23:5]
11549+ */
11550+ val = (source & 0x00ffffe0) + (1<<2);
11551+ writel (val, &adev->iobase[ACX_SLV_MEM_ADDR]);
11552+
11553+ /*
11554+ * Read the data from the slave data register, rounding up to the end
11555+ * of the word containing the last byte (hence the > 0)
11556+ */
11557+ while (count > 0) {
11558+ *data++ = readl (&adev->iobase[ACX_SLV_MEM_DATA]);
11559+ count -= 4;
11560+ }
11561+
11562+ /*
11563+ * If the destination wasn't aligned, we would have saved it in
11564+ * the aligned buffer, so copy it where it should go.
11565+ */
11566+ if ((u32) destination & 3) {
11567+ memcpy (destination, aligned_destination, saved_count);
11568+ }
11569+}
11570+
11571+char
11572+printable (char c)
11573+{
11574+ return ((c >= 20) && (c < 127)) ? c : '.';
11575+}
11576+
11577+#if DUMP_MEM_DEFINED > 0
11578+static void
11579+dump_acxmem (acx_device_t *adev, u32 start, int length)
11580+{
11581+ int i;
11582+ u8 buf[16];
11583+
11584+ while (length > 0) {
11585+ printk ("%04x ", start);
11586+ copy_from_slavemem (adev, buf, start, 16);
11587+ for (i = 0; (i < 16) && (i < length); i++) {
11588+ printk ("%02x ", buf[i]);
11589+ }
11590+ for (i = 0; (i < 16) && (i < length); i++) {
11591+ printk ("%c", printable (buf[i]));
11592+ }
11593+ printk ("\n");
11594+ start += 16;
11595+ length -= 16;
11596+ }
11597+}
11598+#endif
11599+
11600+static void
11601+enable_acx_irq(acx_device_t *adev);
11602+static void
11603+disable_acx_irq(acx_device_t *adev);
11604+
11605+/*
11606+ * Return an acx pointer to the next transmit data block.
11607+ */
11608+u32
11609+allocate_acx_txbuf_space (acx_device_t *adev, int count) {
11610+ u32 block, next, last_block;
11611+ int blocks_needed;
11612+ unsigned long flags;
11613+
11614+ spin_lock_irqsave(&adev->txbuf_lock, flags);
11615+ /*
11616+ * Take 4 off the memory block size to account for the reserved word at the start of
11617+ * the block.
11618+ */
11619+ blocks_needed = count / (adev->memblocksize - 4);
11620+ if (count % (adev->memblocksize - 4))
11621+ blocks_needed++;
11622+
11623+ if (blocks_needed <= adev->acx_txbuf_blocks_free) {
11624+ /*
11625+ * Take blocks at the head of the free list.
11626+ */
11627+ last_block = block = adev->acx_txbuf_free;
11628+
11629+ /*
11630+ * Follow block pointers through the requested number of blocks both to
11631+ * find the new head of the free list and to set the flags for the blocks
11632+ * appropriately.
11633+ */
11634+ while (blocks_needed--) {
11635+ /*
11636+ * Keep track of the last block of the allocation
11637+ */
11638+ last_block = adev->acx_txbuf_free;
11639+
11640+ /*
11641+ * Make sure the end control flag is not set.
11642+ */
11643+ next = read_slavemem32 (adev, adev->acx_txbuf_free) & 0x7ffff;
11644+ write_slavemem32 (adev, adev->acx_txbuf_free, next);
11645+
11646+ /*
11647+ * Update the new head of the free list
11648+ */
11649+ adev->acx_txbuf_free = next << 5;
11650+ adev->acx_txbuf_blocks_free--;
11651+
11652+ }
11653+
11654+ /*
11655+ * Flag the last block both by clearing out the next pointer
11656+ * and marking the control field.
11657+ */
11658+ write_slavemem32 (adev, last_block, 0x02000000);
11659+
11660+ /*
11661+ * If we're out of buffers make sure the free list pointer is NULL
11662+ */
11663+ if (!adev->acx_txbuf_blocks_free) {
11664+ adev->acx_txbuf_free = 0;
11665+ }
11666+ }
11667+ else {
11668+ block = 0;
11669+ }
11670+ spin_unlock_irqrestore (&adev->txbuf_lock, flags);
11671+ return block;
11672+}
11673+
11674+/*
11675+ * Return buffer space back to the pool by following the next pointers until we find
11676+ * the block marked as the end. Point the last block to the head of the free list,
11677+ * then update the head of the free list to point to the newly freed memory.
11678+ * This routine gets called in interrupt context, so it shouldn't block to protect
11679+ * the integrity of the linked list. The ISR already holds the lock.
11680+ */
11681+void
11682+reclaim_acx_txbuf_space (acx_device_t *adev, u32 blockptr) {
11683+ u32 cur, last, next;
11684+ unsigned long flags;
11685+
11686+ spin_lock_irqsave (&adev->txbuf_lock, flags);
11687+ if ((blockptr >= adev->acx_txbuf_start) &&
11688+ (blockptr <= adev->acx_txbuf_start +
11689+ (adev->acx_txbuf_numblocks - 1) * adev->memblocksize)) {
11690+ cur = blockptr;
11691+ do {
11692+ last = cur;
11693+ next = read_slavemem32 (adev, cur);
11694+
11695+ /*
11696+ * Advance to the next block in this allocation
11697+ */
11698+ cur = (next & 0x7ffff) << 5;
11699+
11700+ /*
11701+ * This block now counts as free.
11702+ */
11703+ adev->acx_txbuf_blocks_free++;
11704+ } while (!(next & 0x02000000));
11705+
11706+ /*
11707+ * last now points to the last block of that allocation. Update the pointer
11708+ * in that block to point to the free list and reset the free list to the
11709+ * first block of the free call. If there were no free blocks, make sure
11710+ * the new end of the list marks itself as truly the end.
11711+ */
11712+ if (adev->acx_txbuf_free) {
11713+ write_slavemem32 (adev, last, adev->acx_txbuf_free >> 5);
11714+ }
11715+ else {
11716+ write_slavemem32 (adev, last, 0x02000000);
11717+ }
11718+ adev->acx_txbuf_free = blockptr;
11719+ }
11720+ spin_unlock_irqrestore(&adev->txbuf_lock, flags);
11721+}
11722+
11723+/*
11724+ * Initialize the pieces managing the transmit buffer pool on the ACX. The transmit
11725+ * buffer is a circular queue with one 32 bit word reserved at the beginning of each
11726+ * block. The upper 13 bits are a control field, of which only 0x02000000 has any
11727+ * meaning. The lower 19 bits are the address of the next block divided by 32.
11728+ */
11729+void
11730+init_acx_txbuf (acx_device_t *adev) {
11731+
11732+ /*
11733+ * acx100_s_init_memory_pools set up txbuf_start and txbuf_numblocks for us.
11734+ * All we need to do is reset the rest of the bookeeping.
11735+ */
11736+
11737+ adev->acx_txbuf_free = adev->acx_txbuf_start;
11738+ adev->acx_txbuf_blocks_free = adev->acx_txbuf_numblocks;
11739+
11740+ /*
11741+ * Initialization leaves the last transmit pool block without a pointer back to
11742+ * the head of the list, but marked as the end of the list. That's how we want
11743+ * to see it, too, so leave it alone. This is only ever called after a firmware
11744+ * reset, so the ACX memory is in the state we want.
11745+ */
11746+
11747+}
11748+
11749+INLINE_IO int
11750+adev_present(acx_device_t *adev)
11751+{
11752+ /* fast version (accesses the first register, IO_ACX_SOFT_RESET,
11753+ * which should be safe): */
11754+ return readl(adev->iobase) != 0xffffffff;
11755+}
11756+
11757+/***********************************************************************
11758+*/
11759+static inline txdesc_t*
11760+get_txdesc(acx_device_t *adev, int index)
11761+{
11762+ return (txdesc_t*) (((u8*)adev->txdesc_start) + index * adev->txdesc_size);
11763+}
11764+
11765+static inline txdesc_t*
11766+advance_txdesc(acx_device_t *adev, txdesc_t* txdesc, int inc)
11767+{
11768+ return (txdesc_t*) (((u8*)txdesc) + inc * adev->txdesc_size);
11769+}
11770+
11771+static txhostdesc_t*
11772+get_txhostdesc(acx_device_t *adev, txdesc_t* txdesc)
11773+{
11774+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
11775+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
11776+ printk("bad txdesc ptr %p\n", txdesc);
11777+ return NULL;
11778+ }
11779+ index /= adev->txdesc_size;
11780+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
11781+ printk("bad txdesc ptr %p\n", txdesc);
11782+ return NULL;
11783+ }
11784+ return &adev->txhostdesc_start[index*2];
11785+}
11786+
11787+static inline client_t*
11788+get_txc(acx_device_t *adev, txdesc_t* txdesc)
11789+{
11790+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
11791+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
11792+ printk("bad txdesc ptr %p\n", txdesc);
11793+ return NULL;
11794+ }
11795+ index /= adev->txdesc_size;
11796+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
11797+ printk("bad txdesc ptr %p\n", txdesc);
11798+ return NULL;
11799+ }
11800+ return adev->txc[index];
11801+}
11802+
11803+static inline u16
11804+get_txr(acx_device_t *adev, txdesc_t* txdesc)
11805+{
11806+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
11807+ index /= adev->txdesc_size;
11808+ return adev->txr[index];
11809+}
11810+
11811+static inline void
11812+put_txcr(acx_device_t *adev, txdesc_t* txdesc, client_t* c, u16 r111)
11813+{
11814+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
11815+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
11816+ printk("bad txdesc ptr %p\n", txdesc);
11817+ return;
11818+ }
11819+ index /= adev->txdesc_size;
11820+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
11821+ printk("bad txdesc ptr %p\n", txdesc);
11822+ return;
11823+ }
11824+ adev->txc[index] = c;
11825+ adev->txr[index] = r111;
11826+}
11827+
11828+
11829+/***********************************************************************
11830+** EEPROM and PHY read/write helpers
11831+*/
11832+/***********************************************************************
11833+** acxmem_read_eeprom_byte
11834+**
11835+** Function called to read an octet in the EEPROM.
11836+**
11837+** This function is used by acxmem_e_probe to check if the
11838+** connected card is a legal one or not.
11839+**
11840+** Arguments:
11841+** adev ptr to acx_device structure
11842+** addr address to read in the EEPROM
11843+** charbuf ptr to a char. This is where the read octet
11844+** will be stored
11845+*/
11846+int
11847+acxmem_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf)
11848+{
11849+ int result;
11850+ int count;
11851+
11852+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
11853+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr);
11854+ write_flush(adev);
11855+ write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
11856+
11857+ count = 0xffff;
11858+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
11859+ /* scheduling away instead of CPU burning loop
11860+ * doesn't seem to work here at all:
11861+ * awful delay, sometimes also failure.
11862+ * Doesn't matter anyway (only small delay). */
11863+ if (unlikely(!--count)) {
11864+ printk("%s: timeout waiting for EEPROM read\n",
11865+ adev->ndev->name);
11866+ result = NOT_OK;
11867+ goto fail;
11868+ }
11869+ cpu_relax();
11870+ }
11871+
11872+ *charbuf = read_reg8(adev, IO_ACX_EEPROM_DATA);
11873+ log(L_DEBUG, "EEPROM at 0x%04X = 0x%02X\n", addr, *charbuf);
11874+ result = OK;
11875+
11876+fail:
11877+ return result;
11878+}
11879+
11880+
11881+/***********************************************************************
11882+** We don't lock hw accesses here since we never r/w eeprom in IRQ
11883+** Note: this function sleeps only because of GFP_KERNEL alloc
11884+*/
11885+#ifdef UNUSED
11886+int
11887+acxmem_s_write_eeprom(acx_device_t *adev, u32 addr, u32 len, const u8 *charbuf)
11888+{
11889+ u8 *data_verify = NULL;
11890+ unsigned long flags;
11891+ int count, i;
11892+ int result = NOT_OK;
11893+ u16 gpio_orig;
11894+
11895+ printk("acx: WARNING! I would write to EEPROM now. "
11896+ "Since I really DON'T want to unless you know "
11897+ "what you're doing (THIS CODE WILL PROBABLY "
11898+ "NOT WORK YET!), I will abort that now. And "
11899+ "definitely make sure to make a "
11900+ "/proc/driver/acx_wlan0_eeprom backup copy first!!! "
11901+ "(the EEPROM content includes the PCI config header!! "
11902+ "If you kill important stuff, then you WILL "
11903+ "get in trouble and people DID get in trouble already)\n");
11904+ return OK;
11905+
11906+ FN_ENTER;
11907+
11908+ data_verify = kmalloc(len, GFP_KERNEL);
11909+ if (!data_verify) {
11910+ goto end;
11911+ }
11912+
11913+ /* first we need to enable the OE (EEPROM Output Enable) GPIO line
11914+ * to be able to write to the EEPROM.
11915+ * NOTE: an EEPROM writing success has been reported,
11916+ * but you probably have to modify GPIO_OUT, too,
11917+ * and you probably need to activate a different GPIO
11918+ * line instead! */
11919+ gpio_orig = read_reg16(adev, IO_ACX_GPIO_OE);
11920+ write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig & ~1);
11921+ write_flush(adev);
11922+
11923+ /* ok, now start writing the data out */
11924+ for (i = 0; i < len; i++) {
11925+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
11926+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
11927+ write_reg32(adev, IO_ACX_EEPROM_DATA, *(charbuf + i));
11928+ write_flush(adev);
11929+ write_reg32(adev, IO_ACX_EEPROM_CTL, 1);
11930+
11931+ count = 0xffff;
11932+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
11933+ if (unlikely(!--count)) {
11934+ printk("WARNING, DANGER!!! "
11935+ "Timeout waiting for EEPROM write\n");
11936+ goto end;
11937+ }
11938+ cpu_relax();
11939+ }
11940+ }
11941+
11942+ /* disable EEPROM writing */
11943+ write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig);
11944+ write_flush(adev);
11945+
11946+ /* now start a verification run */
11947+ for (i = 0; i < len; i++) {
11948+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
11949+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
11950+ write_flush(adev);
11951+ write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
11952+
11953+ count = 0xffff;
11954+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
11955+ if (unlikely(!--count)) {
11956+ printk("timeout waiting for EEPROM read\n");
11957+ goto end;
11958+ }
11959+ cpu_relax();
11960+ }
11961+
11962+ data_verify[i] = read_reg16(adev, IO_ACX_EEPROM_DATA);
11963+ }
11964+
11965+ if (0 == memcmp(charbuf, data_verify, len))
11966+ result = OK; /* read data matches, success */
11967+
11968+end:
11969+ kfree(data_verify);
11970+ FN_EXIT1(result);
11971+ return result;
11972+}
11973+#endif /* UNUSED */
11974+
11975+
11976+/***********************************************************************
11977+** acxmem_s_read_phy_reg
11978+**
11979+** Messing with rx/tx disabling and enabling here
11980+** (write_reg32(adev, IO_ACX_ENABLE, 0b000000xx)) kills traffic
11981+*/
11982+int
11983+acxmem_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf)
11984+{
11985+ int result = NOT_OK;
11986+ int count;
11987+
11988+ FN_ENTER;
11989+
11990+ write_reg32(adev, IO_ACX_PHY_ADDR, reg);
11991+ write_flush(adev);
11992+ write_reg32(adev, IO_ACX_PHY_CTL, 2);
11993+
11994+ count = 0xffff;
11995+ while (read_reg32(adev, IO_ACX_PHY_CTL)) {
11996+ /* scheduling away instead of CPU burning loop
11997+ * doesn't seem to work here at all:
11998+ * awful delay, sometimes also failure.
11999+ * Doesn't matter anyway (only small delay). */
12000+ if (unlikely(!--count)) {
12001+ printk("%s: timeout waiting for phy read\n",
12002+ adev->ndev->name);
12003+ *charbuf = 0;
12004+ goto fail;
12005+ }
12006+ cpu_relax();
12007+ }
12008+
12009+ log(L_DEBUG, "count was %u\n", count);
12010+ *charbuf = read_reg8(adev, IO_ACX_PHY_DATA);
12011+
12012+ log(L_DEBUG, "radio PHY at 0x%04X = 0x%02X\n", *charbuf, reg);
12013+ result = OK;
12014+ goto fail; /* silence compiler warning */
12015+fail:
12016+ FN_EXIT1(result);
12017+ return result;
12018+}
12019+
12020+
12021+/***********************************************************************
12022+*/
12023+int
12024+acxmem_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value)
12025+{
12026+ int count;
12027+ FN_ENTER;
12028+
12029+ /* mprusko said that 32bit accesses result in distorted sensitivity
12030+ * on his card. Unconfirmed, looks like it's not true (most likely since we
12031+ * now properly flush writes). */
12032+ write_reg32(adev, IO_ACX_PHY_DATA, value);
12033+ write_reg32(adev, IO_ACX_PHY_ADDR, reg);
12034+ write_flush(adev);
12035+ write_reg32(adev, IO_ACX_PHY_CTL, 1);
12036+ write_flush(adev);
12037+
12038+ count = 0xffff;
12039+ while (read_reg32(adev, IO_ACX_PHY_CTL)) {
12040+ /* scheduling away instead of CPU burning loop
12041+ * doesn't seem to work here at all:
12042+ * awful delay, sometimes also failure.
12043+ * Doesn't matter anyway (only small delay). */
12044+ if (unlikely(!--count)) {
12045+ printk("%s: timeout waiting for phy read\n",
12046+ adev->ndev->name);
12047+ goto fail;
12048+ }
12049+ cpu_relax();
12050+ }
12051+
12052+ log(L_DEBUG, "radio PHY write 0x%02X at 0x%04X\n", value, reg);
12053+ fail:
12054+ FN_EXIT1(OK);
12055+ return OK;
12056+}
12057+
12058+
12059+#define NO_AUTO_INCREMENT 1
12060+
12061+/***********************************************************************
12062+** acxmem_s_write_fw
12063+**
12064+** Write the firmware image into the card.
12065+**
12066+** Arguments:
12067+** adev wlan device structure
12068+** fw_image firmware image.
12069+**
12070+** Returns:
12071+** 1 firmware image corrupted
12072+** 0 success
12073+*/
12074+static int
12075+acxmem_s_write_fw(acx_device_t *adev, const firmware_image_t *fw_image, u32 offset)
12076+{
12077+ int len, size, checkMismatch = -1;
12078+ u32 sum, v32, tmp, id;
12079+ /* we skip the first four bytes which contain the control sum */
12080+ const u8 *p = (u8*)fw_image + 4;
12081+
12082+ /* start the image checksum by adding the image size value */
12083+ sum = p[0]+p[1]+p[2]+p[3];
12084+ p += 4;
12085+
12086+#ifdef NOPE
12087+#if NO_AUTO_INCREMENT
12088+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */
12089+#else
12090+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */
12091+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */
12092+ write_flush(adev);
12093+#endif
12094+#endif
12095+ len = 0;
12096+ size = le32_to_cpu(fw_image->size) & (~3);
12097+
12098+ while (likely(len < size)) {
12099+ v32 = be32_to_cpu(*(u32*)p);
12100+ sum += p[0]+p[1]+p[2]+p[3];
12101+ p += 4;
12102+ len += 4;
12103+
12104+#ifdef NOPE
12105+#if NO_AUTO_INCREMENT
12106+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4);
12107+ write_flush(adev);
12108+#endif
12109+ write_reg32(adev, IO_ACX_SLV_MEM_DATA, v32);
12110+ write_flush(adev);
12111+#endif
12112+ write_slavemem32 (adev, offset + len - 4, v32);
12113+
12114+ id = read_id_register (adev);
12115+
12116+ /*
12117+ * check the data written
12118+ */
12119+ tmp = read_slavemem32 (adev, offset + len - 4);
12120+ if (checkMismatch && (tmp != v32)) {
12121+ printk ("first data mismatch at 0x%08x good 0x%08x bad 0x%08x id 0x%08x\n",
12122+ offset + len - 4, v32, tmp, id);
12123+ checkMismatch = 0;
12124+ }
12125+ }
12126+ log(L_DEBUG, "firmware written, size:%d sum1:%x sum2:%x\n",
12127+ size, sum, le32_to_cpu(fw_image->chksum));
12128+
12129+ /* compare our checksum with the stored image checksum */
12130+ return (sum != le32_to_cpu(fw_image->chksum));
12131+}
12132+
12133+
12134+/***********************************************************************
12135+** acxmem_s_validate_fw
12136+**
12137+** Compare the firmware image given with
12138+** the firmware image written into the card.
12139+**
12140+** Arguments:
12141+** adev wlan device structure
12142+** fw_image firmware image.
12143+**
12144+** Returns:
12145+** NOT_OK firmware image corrupted or not correctly written
12146+** OK success
12147+*/
12148+static int
12149+acxmem_s_validate_fw(acx_device_t *adev, const firmware_image_t *fw_image,
12150+ u32 offset)
12151+{
12152+ u32 sum, v32, w32;
12153+ int len, size;
12154+ int result = OK;
12155+ /* we skip the first four bytes which contain the control sum */
12156+ const u8 *p = (u8*)fw_image + 4;
12157+
12158+ /* start the image checksum by adding the image size value */
12159+ sum = p[0]+p[1]+p[2]+p[3];
12160+ p += 4;
12161+
12162+ write_reg32(adev, IO_ACX_SLV_END_CTL, 0);
12163+
12164+#if NO_AUTO_INCREMENT
12165+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */
12166+#else
12167+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */
12168+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */
12169+#endif
12170+
12171+ len = 0;
12172+ size = le32_to_cpu(fw_image->size) & (~3);
12173+
12174+ while (likely(len < size)) {
12175+ v32 = be32_to_cpu(*(u32*)p);
12176+ p += 4;
12177+ len += 4;
12178+
12179+#ifdef NOPE
12180+#if NO_AUTO_INCREMENT
12181+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4);
12182+#endif
12183+ udelay(10);
12184+ w32 = read_reg32(adev, IO_ACX_SLV_MEM_DATA);
12185+#endif
12186+ w32 = read_slavemem32 (adev, offset + len - 4);
12187+
12188+ if (unlikely(w32 != v32)) {
12189+ printk("acx: FATAL: firmware upload: "
12190+ "data parts at offset %d don't match\n(0x%08X vs. 0x%08X)!\n"
12191+ "I/O timing issues or defective memory, with DWL-xx0+? "
12192+ "ACX_IO_WIDTH=16 may help. Please report\n",
12193+ len, v32, w32);
12194+ result = NOT_OK;
12195+ break;
12196+ }
12197+
12198+ sum += (u8)w32 + (u8)(w32>>8) + (u8)(w32>>16) + (u8)(w32>>24);
12199+ }
12200+
12201+ /* sum control verification */
12202+ if (result != NOT_OK) {
12203+ if (sum != le32_to_cpu(fw_image->chksum)) {
12204+ printk("acx: FATAL: firmware upload: "
12205+ "checksums don't match!\n");
12206+ result = NOT_OK;
12207+ }
12208+ }
12209+
12210+ return result;
12211+}
12212+
12213+
12214+/***********************************************************************
12215+** acxmem_s_upload_fw
12216+**
12217+** Called from acx_reset_dev
12218+*/
12219+static int
12220+acxmem_s_upload_fw(acx_device_t *adev)
12221+{
12222+ firmware_image_t *fw_image = NULL;
12223+ int res = NOT_OK;
12224+ int try;
12225+ u32 file_size;
12226+ char *filename = "WLANGEN.BIN";
12227+#ifdef PATCH_AROUND_BAD_SPOTS
12228+ u32 offset;
12229+ int i;
12230+ /*
12231+ * arm-linux-objdump -d patch.bin, or
12232+ * od -Ax -t x4 patch.bin after finding the bounds
12233+ * of the .text section with arm-linux-objdump -s patch.bin
12234+ */
12235+ u32 patch[] = {
12236+ 0xe584c030, 0xe59fc008,
12237+ 0xe92d1000, 0xe59fc004, 0xe8bd8000, 0x0000080c,
12238+ 0x0000aa68, 0x605a2200, 0x2c0a689c, 0x2414d80a,
12239+ 0x2f00689f, 0x1c27d007, 0x06241e7c, 0x2f000e24,
12240+ 0xe000d1f6, 0x602e6018, 0x23036468, 0x480203db,
12241+ 0x60ca6003, 0xbdf0750a, 0xffff0808
12242+ };
12243+#endif
12244+
12245+ FN_ENTER;
12246+ /* No combined image; tell common we need the radio firmware, too */
12247+ adev->need_radio_fw = 1;
12248+
12249+ fw_image = acx_s_read_fw(adev->dev, filename, &file_size);
12250+ if (!fw_image) {
12251+ FN_EXIT1(NOT_OK);
12252+ return NOT_OK;
12253+ }
12254+
12255+ for (try = 1; try <= 5; try++) {
12256+ res = acxmem_s_write_fw(adev, fw_image, 0);
12257+ log(L_DEBUG|L_INIT, "acx_write_fw (main): %d\n", res);
12258+ if (OK == res) {
12259+ res = acxmem_s_validate_fw(adev, fw_image, 0);
12260+ log(L_DEBUG|L_INIT, "acx_validate_fw "
12261+ "(main): %d\n", res);
12262+ }
12263+
12264+ if (OK == res) {
12265+ SET_BIT(adev->dev_state_mask, ACX_STATE_FW_LOADED);
12266+ break;
12267+ }
12268+ printk("acx: firmware upload attempt #%d FAILED, "
12269+ "retrying...\n", try);
12270+ acx_s_msleep(1000); /* better wait for a while... */
12271+ }
12272+
12273+#ifdef PATCH_AROUND_BAD_SPOTS
12274+ /*
12275+ * Only want to do this if the firmware is exactly what we expect for an
12276+ * iPaq 4700; otherwise, bad things would ensue.
12277+ */
12278+ if ((HX4700_FIRMWARE_CHECKSUM == fw_image->chksum) ||
12279+ (HX4700_ALTERNATE_FIRMWARE_CHECKSUM == fw_image->chksum)) {
12280+ /*
12281+ * Put the patch after the main firmware image. 0x950c contains
12282+ * the ACX's idea of the end of the firmware. Use that location to
12283+ * load ours (which depends on that location being 0xab58) then
12284+ * update that location to point to after ours.
12285+ */
12286+
12287+ offset = read_slavemem32 (adev, 0x950c);
12288+
12289+ log (L_DEBUG, "acx: patching in at 0x%04x\n", offset);
12290+
12291+ for (i = 0; i < sizeof(patch) / sizeof(patch[0]); i++) {
12292+ write_slavemem32 (adev, offset, patch[i]);
12293+ offset += sizeof(u32);
12294+ }
12295+
12296+ /*
12297+ * Patch the instruction at 0x0804 to branch to our ARM patch at 0xab58
12298+ */
12299+ write_slavemem32 (adev, 0x0804, 0xea000000 + (0xab58-0x0804-8)/4);
12300+
12301+ /*
12302+ * Patch the instructions at 0x1f40 to branch to our Thumb patch at 0xab74
12303+ *
12304+ * 4a00 ldr r2, [pc, #0]
12305+ * 4710 bx r2
12306+ * .data 0xab74+1
12307+ */
12308+ write_slavemem32 (adev, 0x1f40, 0x47104a00);
12309+ write_slavemem32 (adev, 0x1f44, 0x0000ab74+1);
12310+
12311+ /*
12312+ * Bump the end of the firmware up to beyond our patch.
12313+ */
12314+ write_slavemem32 (adev, 0x950c, offset);
12315+
12316+ }
12317+#endif
12318+
12319+ vfree(fw_image);
12320+
12321+ FN_EXIT1(res);
12322+ return res;
12323+}
12324+
12325+
12326+/***********************************************************************
12327+** acxmem_s_upload_radio
12328+**
12329+** Uploads the appropriate radio module firmware into the card.
12330+*/
12331+int
12332+acxmem_s_upload_radio(acx_device_t *adev)
12333+{
12334+ acx_ie_memmap_t mm;
12335+ firmware_image_t *radio_image;
12336+ acx_cmd_radioinit_t radioinit;
12337+ int res = NOT_OK;
12338+ int try;
12339+ u32 offset;
12340+ u32 size;
12341+ char filename[sizeof("RADIONN.BIN")];
12342+
12343+ if (!adev->need_radio_fw) return OK;
12344+
12345+ FN_ENTER;
12346+
12347+ acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP);
12348+ offset = le32_to_cpu(mm.CodeEnd);
12349+
12350+ snprintf(filename, sizeof(filename), "RADIO%02x.BIN",
12351+ adev->radio_type);
12352+ radio_image = acx_s_read_fw(adev->dev, filename, &size);
12353+ if (!radio_image) {
12354+ printk("acx: can't load radio module '%s'\n", filename);
12355+ goto fail;
12356+ }
12357+
12358+ acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0);
12359+
12360+ for (try = 1; try <= 5; try++) {
12361+ res = acxmem_s_write_fw(adev, radio_image, offset);
12362+ log(L_DEBUG|L_INIT, "acx_write_fw (radio): %d\n", res);
12363+ if (OK == res) {
12364+ res = acxmem_s_validate_fw(adev, radio_image, offset);
12365+ log(L_DEBUG|L_INIT, "acx_validate_fw (radio): %d\n", res);
12366+ }
12367+
12368+ if (OK == res)
12369+ break;
12370+ printk("acx: radio firmware upload attempt #%d FAILED, "
12371+ "retrying...\n", try);
12372+ acx_s_msleep(1000); /* better wait for a while... */
12373+ }
12374+
12375+ acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0);
12376+ radioinit.offset = cpu_to_le32(offset);
12377+
12378+ /* no endian conversion needed, remains in card CPU area: */
12379+ radioinit.len = radio_image->size;
12380+
12381+ vfree(radio_image);
12382+
12383+ if (OK != res)
12384+ goto fail;
12385+
12386+ /* will take a moment so let's have a big timeout */
12387+ acx_s_issue_cmd_timeo(adev, ACX1xx_CMD_RADIOINIT,
12388+ &radioinit, sizeof(radioinit), CMD_TIMEOUT_MS(1000));
12389+
12390+ res = acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP);
12391+
12392+fail:
12393+ FN_EXIT1(res);
12394+ return res;
12395+}
12396+
12397+/***********************************************************************
12398+** acxmem_l_reset_mac
12399+**
12400+** MAC will be reset
12401+** Call context: reset_dev
12402+*/
12403+static void
12404+acxmem_l_reset_mac(acx_device_t *adev)
12405+{
12406+ int count;
12407+ FN_ENTER;
12408+
12409+ /* halt eCPU */
12410+ set_regbits (adev, IO_ACX_ECPU_CTRL, 0x1);
12411+
12412+ /* now do soft reset of eCPU, set bit */
12413+ set_regbits (adev, IO_ACX_SOFT_RESET, 0x1);
12414+ log(L_DEBUG, "%s: enable soft reset...\n", __func__);
12415+
12416+ /* Windows driver sleeps here for a while with this sequence */
12417+ for (count = 0; count < 200; count++) {
12418+ udelay (50);
12419+ }
12420+
12421+ /* now clear bit again: deassert eCPU reset */
12422+ log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__);
12423+ clear_regbits (adev, IO_ACX_SOFT_RESET, 0x1);
12424+
12425+ /* now start a burst read from initial EEPROM */
12426+ set_regbits (adev, IO_ACX_EE_START, 0x1);
12427+
12428+ /*
12429+ * Windows driver sleeps here for a while with this sequence
12430+ */
12431+ for (count = 0; count < 200; count++) {
12432+ udelay (50);
12433+ }
12434+
12435+ /* Windows driver writes 0x10000 to register 0x808 here */
12436+
12437+ write_reg32 (adev, 0x808, 0x10000);
12438+
12439+ FN_EXIT0;
12440+}
12441+
12442+
12443+/***********************************************************************
12444+** acxmem_s_verify_init
12445+*/
12446+static int
12447+acxmem_s_verify_init(acx_device_t *adev)
12448+{
12449+ int result = NOT_OK;
12450+ unsigned long timeout;
12451+
12452+ FN_ENTER;
12453+
12454+ timeout = jiffies + 2*HZ;
12455+ for (;;) {
12456+ u32 irqstat = read_reg32(adev, IO_ACX_IRQ_STATUS_NON_DES);
12457+ if ((irqstat != 0xFFFFFFFF) && (irqstat & HOST_INT_FCS_THRESHOLD)) {
12458+ result = OK;
12459+ write_reg32(adev, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD);
12460+ break;
12461+ }
12462+ if (time_after(jiffies, timeout))
12463+ break;
12464+ /* Init may take up to ~0.5 sec total */
12465+ acx_s_msleep(50);
12466+ }
12467+
12468+ FN_EXIT1(result);
12469+ return result;
12470+}
12471+
12472+
12473+/***********************************************************************
12474+** A few low-level helpers
12475+**
12476+** Note: these functions are not protected by lock
12477+** and thus are never allowed to be called from IRQ.
12478+** Also they must not race with fw upload which uses same hw regs
12479+*/
12480+
12481+/***********************************************************************
12482+** acxmem_write_cmd_type_status
12483+*/
12484+
12485+static inline void
12486+acxmem_write_cmd_type_status(acx_device_t *adev, u16 type, u16 status)
12487+{
12488+ write_slavemem32 (adev, (u32) adev->cmd_area, type | (status << 16));
12489+ write_flush(adev);
12490+}
12491+
12492+
12493+/***********************************************************************
12494+** acxmem_read_cmd_type_status
12495+*/
12496+static u32
12497+acxmem_read_cmd_type_status(acx_device_t *adev)
12498+{
12499+ u32 cmd_type, cmd_status;
12500+
12501+ cmd_type = read_slavemem32 (adev, (u32) adev->cmd_area);
12502+
12503+ cmd_status = (cmd_type >> 16);
12504+ cmd_type = (u16)cmd_type;
12505+
12506+ log(L_CTL, "cmd_type:%04X cmd_status:%04X [%s]\n",
12507+ cmd_type, cmd_status,
12508+ acx_cmd_status_str(cmd_status));
12509+
12510+ return cmd_status;
12511+}
12512+
12513+
12514+/***********************************************************************
12515+** acxmem_s_reset_dev
12516+**
12517+** Arguments:
12518+** netdevice that contains the adev variable
12519+** Returns:
12520+** NOT_OK on fail
12521+** OK on success
12522+** Side effects:
12523+** device is hard reset
12524+** Call context:
12525+** acxmem_e_probe
12526+** Comment:
12527+** This resets the device using low level hardware calls
12528+** as well as uploads and verifies the firmware to the card
12529+*/
12530+
12531+static inline void
12532+init_mboxes(acx_device_t *adev)
12533+{
12534+ u32 cmd_offs, info_offs;
12535+
12536+ cmd_offs = read_reg32(adev, IO_ACX_CMD_MAILBOX_OFFS);
12537+ info_offs = read_reg32(adev, IO_ACX_INFO_MAILBOX_OFFS);
12538+ adev->cmd_area = (u8*) cmd_offs;
12539+ adev->info_area = (u8*) info_offs;
12540+ /*
12541+ log(L_DEBUG, "iobase2=%p\n"
12542+ */
12543+ log( L_DEBUG, "cmd_mbox_offset=%X cmd_area=%p\n"
12544+ "info_mbox_offset=%X info_area=%p\n",
12545+ cmd_offs, adev->cmd_area,
12546+ info_offs, adev->info_area);
12547+}
12548+
12549+
12550+static inline void
12551+read_eeprom_area(acx_device_t *adev)
12552+{
12553+#if ACX_DEBUG > 1
12554+ int offs;
12555+ u8 tmp;
12556+
12557+ for (offs = 0x8c; offs < 0xb9; offs++)
12558+ acxmem_read_eeprom_byte(adev, offs, &tmp);
12559+#endif
12560+}
12561+
12562+static int
12563+acxmem_s_reset_dev(acx_device_t *adev)
12564+{
12565+ const char* msg = "";
12566+ unsigned long flags;
12567+ int result = NOT_OK;
12568+ u16 hardware_info;
12569+ u16 ecpu_ctrl;
12570+ int count;
12571+ u32 tmp;
12572+
12573+ FN_ENTER;
12574+ /*
12575+ write_reg32 (adev, IO_ACX_SLV_MEM_CP, 0);
12576+ */
12577+ /* reset the device to make sure the eCPU is stopped
12578+ * to upload the firmware correctly */
12579+
12580+ acx_lock(adev, flags);
12581+
12582+ /* Windows driver does some funny things here */
12583+ /*
12584+ * clear bit 0x200 in register 0x2A0
12585+ */
12586+ clear_regbits (adev, 0x2A0, 0x200);
12587+
12588+ /*
12589+ * Set bit 0x200 in ACX_GPIO_OUT
12590+ */
12591+ set_regbits (adev, IO_ACX_GPIO_OUT, 0x200);
12592+
12593+ /*
12594+ * read register 0x900 until its value is 0x8400104C, sleeping
12595+ * in between reads if it's not immediate
12596+ */
12597+ tmp = read_reg32 (adev, REG_ACX_VENDOR_ID);
12598+ count = 500;
12599+ while (count-- && (tmp != ACX_VENDOR_ID)) {
12600+ mdelay (10);
12601+ tmp = read_reg32 (adev, REG_ACX_VENDOR_ID);
12602+ }
12603+
12604+ /* end what Windows driver does */
12605+
12606+ acxmem_l_reset_mac(adev);
12607+
12608+ ecpu_ctrl = read_reg32(adev, IO_ACX_ECPU_CTRL) & 1;
12609+ if (!ecpu_ctrl) {
12610+ msg = "eCPU is already running. ";
12611+ goto end_unlock;
12612+ }
12613+
12614+#ifdef WE_DONT_NEED_THAT_DO_WE
12615+ if (read_reg16(adev, IO_ACX_SOR_CFG) & 2) {
12616+ /* eCPU most likely means "embedded CPU" */
12617+ msg = "eCPU did not start after boot from flash. ";
12618+ goto end_unlock;
12619+ }
12620+
12621+ /* check sense on reset flags */
12622+ if (read_reg16(adev, IO_ACX_SOR_CFG) & 0x10) {
12623+ printk("%s: eCPU did not start after boot (SOR), "
12624+ "is this fatal?\n", adev->ndev->name);
12625+ }
12626+#endif
12627+ /* scan, if any, is stopped now, setting corresponding IRQ bit */
12628+ adev->irq_status |= HOST_INT_SCAN_COMPLETE;
12629+
12630+ acx_unlock(adev, flags);
12631+
12632+ /* need to know radio type before fw load */
12633+ /* Need to wait for arrival of this information in a loop,
12634+ * most probably since eCPU runs some init code from EEPROM
12635+ * (started burst read in reset_mac()) which also
12636+ * sets the radio type ID */
12637+
12638+ count = 0xffff;
12639+ do {
12640+ hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION);
12641+ if (!--count) {
12642+ msg = "eCPU didn't indicate radio type";
12643+ goto end_fail;
12644+ }
12645+ cpu_relax();
12646+ } while (!(hardware_info & 0xff00)); /* radio type still zero? */
12647+ printk("ACX radio type 0x%02x\n", (hardware_info >> 8) & 0xff);
12648+ /* printk("DEBUG: count %d\n", count); */
12649+ adev->form_factor = hardware_info & 0xff;
12650+ adev->radio_type = hardware_info >> 8;
12651+
12652+ /* load the firmware */
12653+ if (OK != acxmem_s_upload_fw(adev))
12654+ goto end_fail;
12655+
12656+ /* acx_s_msleep(10); this one really shouldn't be required */
12657+
12658+ /* now start eCPU by clearing bit */
12659+ clear_regbits (adev, IO_ACX_ECPU_CTRL, 0x1);
12660+ log(L_DEBUG, "booted eCPU up and waiting for completion...\n");
12661+
12662+ /* Windows driver clears bit 0x200 in register 0x2A0 here */
12663+ clear_regbits (adev, 0x2A0, 0x200);
12664+
12665+ /* Windows driver sets bit 0x200 in ACX_GPIO_OUT here */
12666+ set_regbits (adev, IO_ACX_GPIO_OUT, 0x200);
12667+ /* wait for eCPU bootup */
12668+ if (OK != acxmem_s_verify_init(adev)) {
12669+ msg = "timeout waiting for eCPU. ";
12670+ goto end_fail;
12671+ }
12672+ log(L_DEBUG, "eCPU has woken up, card is ready to be configured\n");
12673+ init_mboxes(adev);
12674+ acxmem_write_cmd_type_status(adev, ACX1xx_CMD_RESET, 0);
12675+
12676+ /* test that EEPROM is readable */
12677+ read_eeprom_area(adev);
12678+
12679+ result = OK;
12680+ goto end;
12681+
12682+/* Finish error message. Indicate which function failed */
12683+end_unlock:
12684+ acx_unlock(adev, flags);
12685+end_fail:
12686+ printk("acx: %sreset_dev() FAILED\n", msg);
12687+end:
12688+ FN_EXIT1(result);
12689+ return result;
12690+}
12691+
12692+
12693+/***********************************************************************
12694+** acxmem_s_issue_cmd_timeo
12695+**
12696+** Sends command to fw, extract result
12697+**
12698+** NB: we do _not_ take lock inside, so be sure to not touch anything
12699+** which may interfere with IRQ handler operation
12700+**
12701+** TODO: busy wait is a bit silly, so:
12702+** 1) stop doing many iters - go to sleep after first
12703+** 2) go to waitqueue based approach: wait, not poll!
12704+*/
12705+#undef FUNC
12706+#define FUNC "issue_cmd"
12707+
12708+#if !ACX_DEBUG
12709+int
12710+acxmem_s_issue_cmd_timeo(
12711+ acx_device_t *adev,
12712+ unsigned int cmd,
12713+ void *buffer,
12714+ unsigned buflen,
12715+ unsigned cmd_timeout)
12716+{
12717+#else
12718+int
12719+acxmem_s_issue_cmd_timeo_debug(
12720+ acx_device_t *adev,
12721+ unsigned cmd,
12722+ void *buffer,
12723+ unsigned buflen,
12724+ unsigned cmd_timeout,
12725+ const char* cmdstr)
12726+{
12727+ unsigned long start = jiffies;
12728+#endif
12729+ const char *devname;
12730+ unsigned counter;
12731+ u16 irqtype;
12732+ int i, j;
12733+ u8 *p;
12734+ u16 cmd_status;
12735+ unsigned long timeout;
12736+
12737+ FN_ENTER;
12738+
12739+ devname = adev->ndev->name;
12740+ if (!devname || !devname[0] || devname[4]=='%')
12741+ devname = "acx";
12742+
12743+ log(L_CTL, FUNC"(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n",
12744+ cmdstr, buflen, cmd_timeout,
12745+ buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1);
12746+
12747+ if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) {
12748+ printk("%s: "FUNC"(): firmware is not loaded yet, "
12749+ "cannot execute commands!\n", devname);
12750+ goto bad;
12751+ }
12752+
12753+ if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) {
12754+ printk("input buffer (len=%u):\n", buflen);
12755+ acx_dump_bytes(buffer, buflen);
12756+ }
12757+
12758+ /* wait for firmware to become idle for our command submission */
12759+ timeout = HZ/5;
12760+ counter = (timeout * 1000 / HZ) - 1; /* in ms */
12761+ timeout += jiffies;
12762+ do {
12763+ cmd_status = acxmem_read_cmd_type_status(adev);
12764+ /* Test for IDLE state */
12765+ if (!cmd_status)
12766+ break;
12767+ if (counter % 8 == 0) {
12768+ if (time_after(jiffies, timeout)) {
12769+ counter = 0;
12770+ break;
12771+ }
12772+ /* we waited 8 iterations, no luck. Sleep 8 ms */
12773+ acx_s_msleep(8);
12774+ }
12775+ } while (likely(--counter));
12776+
12777+ if (!counter) {
12778+ /* the card doesn't get idle, we're in trouble */
12779+ printk("%s: "FUNC"(): cmd_status is not IDLE: 0x%04X!=0\n",
12780+ devname, cmd_status);
12781+#if DUMP_IF_SLOW > 0
12782+ dump_acxmem (adev, 0, 0x10000);
12783+ panic ("not idle");
12784+#endif
12785+ goto bad;
12786+ } else if (counter < 190) { /* if waited >10ms... */
12787+ log(L_CTL|L_DEBUG, FUNC"(): waited for IDLE %dms. "
12788+ "Please report\n", 199 - counter);
12789+ }
12790+
12791+ /* now write the parameters of the command if needed */
12792+ if (buffer && buflen) {
12793+ /* if it's an INTERROGATE command, just pass the length
12794+ * of parameters to read, as data */
12795+#if CMD_DISCOVERY
12796+ if (cmd == ACX1xx_CMD_INTERROGATE)
12797+ memset_io(adev->cmd_area + 4, 0xAA, buflen);
12798+#endif
12799+ /*
12800+ * slave memory version
12801+ */
12802+ copy_to_slavemem (adev, (u32) (adev->cmd_area + 4), buffer,
12803+ (cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen);
12804+ }
12805+ /* now write the actual command type */
12806+ acxmem_write_cmd_type_status(adev, cmd, 0);
12807+
12808+ /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */
12809+ adev->irq_status &= ~HOST_INT_CMD_COMPLETE;
12810+
12811+ /* execute command */
12812+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD);
12813+ write_flush(adev);
12814+
12815+ /* wait for firmware to process command */
12816+
12817+ /* Ensure nonzero and not too large timeout.
12818+ ** Also converts e.g. 100->99, 200->199
12819+ ** which is nice but not essential */
12820+ cmd_timeout = (cmd_timeout-1) | 1;
12821+ if (unlikely(cmd_timeout > 1199))
12822+ cmd_timeout = 1199;
12823+
12824+ /* we schedule away sometimes (timeout can be large) */
12825+ counter = cmd_timeout;
12826+ timeout = jiffies + cmd_timeout * HZ / 1000;
12827+ do {
12828+ if (!adev->irqs_active) { /* IRQ disabled: poll */
12829+ irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES);
12830+ if (irqtype & HOST_INT_CMD_COMPLETE) {
12831+ write_reg16(adev, IO_ACX_IRQ_ACK,
12832+ HOST_INT_CMD_COMPLETE);
12833+ break;
12834+ }
12835+ } else { /* Wait when IRQ will set the bit */
12836+ irqtype = adev->irq_status;
12837+ if (irqtype & HOST_INT_CMD_COMPLETE)
12838+ break;
12839+ }
12840+
12841+ if (counter % 8 == 0) {
12842+ if (time_after(jiffies, timeout)) {
12843+ counter = 0;
12844+ break;
12845+ }
12846+ /* we waited 8 iterations, no luck. Sleep 8 ms */
12847+ acx_s_msleep(8);
12848+ }
12849+ } while (likely(--counter));
12850+
12851+ /* save state for debugging */
12852+ cmd_status = acxmem_read_cmd_type_status(adev);
12853+
12854+ /* put the card in IDLE state */
12855+ acxmem_write_cmd_type_status(adev, ACX1xx_CMD_RESET, 0);
12856+
12857+ if (!counter) { /* timed out! */
12858+ printk("%s: "FUNC"(): timed out %s for CMD_COMPLETE. "
12859+ "irq bits:0x%04X irq_status:0x%04X timeout:%dms "
12860+ "cmd_status:%d (%s)\n",
12861+ devname, (adev->irqs_active) ? "waiting" : "polling",
12862+ irqtype, adev->irq_status, cmd_timeout,
12863+ cmd_status, acx_cmd_status_str(cmd_status));
12864+ printk("%s: "FUNC"(): device irq status 0x%04x\n",
12865+ devname, read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES));
12866+ printk("%s: "FUNC"(): IO_ACX_IRQ_MASK 0x%04x IO_ACX_FEMR 0x%04x\n",
12867+ devname,
12868+ read_reg16 (adev, IO_ACX_IRQ_MASK),
12869+ read_reg16 (adev, IO_ACX_FEMR));
12870+ if (read_reg16 (adev, IO_ACX_IRQ_MASK) == 0xffff) {
12871+ printk ("acxmem: firmware probably hosed - reloading\n");
12872+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
12873+ {
12874+ pm_message_t state;
12875+ /* acxmem_e_suspend (resume_pdev, state); */
12876+ acxmem_e_suspend (adev->ndev , state);
12877+ }
12878+#else
12879+ acxmem_e_suspend (adev, 0);
12880+#endif
12881+ {
12882+ resume_ndev = adev->ndev;
12883+ fw_resumer (NULL);
12884+ }
12885+ }
12886+
12887+ goto bad;
12888+ } else if (cmd_timeout - counter > 30) { /* if waited >30ms... */
12889+ log(L_CTL|L_DEBUG, FUNC"(): %s for CMD_COMPLETE %dms. "
12890+ "count:%d. Please report\n",
12891+ (adev->irqs_active) ? "waited" : "polled",
12892+ cmd_timeout - counter, counter);
12893+ }
12894+
12895+ if (1 != cmd_status) { /* it is not a 'Success' */
12896+ printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s). "
12897+ "Took %dms of %d\n",
12898+ devname, cmd_status, acx_cmd_status_str(cmd_status),
12899+ cmd_timeout - counter, cmd_timeout);
12900+ /* zero out result buffer
12901+ * WARNING: this will trash stack in case of illegally large input
12902+ * length! */
12903+ if (buflen > 388) {
12904+ /*
12905+ * 388 is maximum command length
12906+ */
12907+ printk ("invalid length 0x%08x\n", buflen);
12908+ buflen = 388;
12909+ }
12910+ p = (u8 *) buffer;
12911+ for (i = 0; i < buflen; i+= 16) {
12912+ printk ("%04x:", i);
12913+ for (j = 0; (j < 16) && (i+j < buflen); j++) {
12914+ printk (" %02x", *p++);
12915+ }
12916+ printk ("\n");
12917+ }
12918+ if (buffer && buflen)
12919+ memset(buffer, 0, buflen);
12920+ goto bad;
12921+ }
12922+
12923+ /* read in result parameters if needed */
12924+ if (buffer && buflen && (cmd == ACX1xx_CMD_INTERROGATE)) {
12925+ copy_from_slavemem (adev, buffer, (u32) (adev->cmd_area + 4), buflen);
12926+ if (acx_debug & L_DEBUG) {
12927+ printk("output buffer (len=%u): ", buflen);
12928+ acx_dump_bytes(buffer, buflen);
12929+ }
12930+ }
12931+
12932+/* ok: */
12933+ log(L_CTL, FUNC"(%s): took %ld jiffies to complete\n",
12934+ cmdstr, jiffies - start);
12935+ FN_EXIT1(OK);
12936+ return OK;
12937+
12938+bad:
12939+ /* Give enough info so that callers can avoid
12940+ ** printing their own diagnostic messages */
12941+#if ACX_DEBUG
12942+ printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr);
12943+#else
12944+ printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd);
12945+#endif
12946+ dump_stack();
12947+ FN_EXIT1(NOT_OK);
12948+ return NOT_OK;
12949+}
12950+
12951+
12952+/***********************************************************************
12953+*/
12954+#if defined(NONESSENTIAL_FEATURES)
12955+typedef struct device_id {
12956+ unsigned char id[6];
12957+ char *descr;
12958+ char *type;
12959+} device_id_t;
12960+
12961+static const device_id_t
12962+device_ids[] =
12963+{
12964+ {
12965+ {'G', 'l', 'o', 'b', 'a', 'l'},
12966+ NULL,
12967+ NULL,
12968+ },
12969+ {
12970+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
12971+ "uninitialized",
12972+ "SpeedStream SS1021 or Gigafast WF721-AEX"
12973+ },
12974+ {
12975+ {0x80, 0x81, 0x82, 0x83, 0x84, 0x85},
12976+ "non-standard",
12977+ "DrayTek Vigor 520"
12978+ },
12979+ {
12980+ {'?', '?', '?', '?', '?', '?'},
12981+ "non-standard",
12982+ "Level One WPC-0200"
12983+ },
12984+ {
12985+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
12986+ "empty",
12987+ "DWL-650+ variant"
12988+ }
12989+};
12990+
12991+static void
12992+acx_show_card_eeprom_id(acx_device_t *adev)
12993+{
12994+ unsigned char buffer[CARD_EEPROM_ID_SIZE];
12995+ int i;
12996+
12997+ memset(&buffer, 0, CARD_EEPROM_ID_SIZE);
12998+ /* use direct EEPROM access */
12999+ for (i = 0; i < CARD_EEPROM_ID_SIZE; i++) {
13000+ if (OK != acxmem_read_eeprom_byte(adev,
13001+ ACX100_EEPROM_ID_OFFSET + i,
13002+ &buffer[i])) {
13003+ printk("acx: reading EEPROM FAILED\n");
13004+ break;
13005+ }
13006+ }
13007+
13008+ for (i = 0; i < VEC_SIZE(device_ids); i++) {
13009+ if (!memcmp(&buffer, device_ids[i].id, CARD_EEPROM_ID_SIZE)) {
13010+ if (device_ids[i].descr) {
13011+ printk("acx: EEPROM card ID string check "
13012+ "found %s card ID: is this %s?\n",
13013+ device_ids[i].descr, device_ids[i].type);
13014+ }
13015+ break;
13016+ }
13017+ }
13018+ if (i == VEC_SIZE(device_ids)) {
13019+ printk("acx: EEPROM card ID string check found "
13020+ "unknown card: expected 'Global', got '%.*s\'. "
13021+ "Please report\n", CARD_EEPROM_ID_SIZE, buffer);
13022+ }
13023+}
13024+#endif /* NONESSENTIAL_FEATURES */
13025+
13026+/***********************************************************************
13027+** acxmem_free_desc_queues
13028+**
13029+** Releases the queues that have been allocated, the
13030+** others have been initialised to NULL so this
13031+** function can be used if only part of the queues were allocated.
13032+*/
13033+
13034+void
13035+acxmem_free_desc_queues(acx_device_t *adev)
13036+{
13037+#define ACX_FREE_QUEUE(size, ptr, phyaddr) \
13038+ if (ptr) { \
13039+ kfree(ptr); \
13040+ ptr = NULL; \
13041+ size = 0; \
13042+ }
13043+
13044+ FN_ENTER;
13045+
13046+ ACX_FREE_QUEUE(adev->txhostdesc_area_size, adev->txhostdesc_start, adev->txhostdesc_startphy);
13047+ ACX_FREE_QUEUE(adev->txbuf_area_size, adev->txbuf_start, adev->txbuf_startphy);
13048+
13049+ adev->txdesc_start = NULL;
13050+
13051+ ACX_FREE_QUEUE(adev->rxhostdesc_area_size, adev->rxhostdesc_start, adev->rxhostdesc_startphy);
13052+ ACX_FREE_QUEUE(adev->rxbuf_area_size, adev->rxbuf_start, adev->rxbuf_startphy);
13053+
13054+ adev->rxdesc_start = NULL;
13055+
13056+ FN_EXIT0;
13057+}
13058+
13059+
13060+/***********************************************************************
13061+** acxmem_s_delete_dma_regions
13062+*/
13063+static void
13064+acxmem_s_delete_dma_regions(acx_device_t *adev)
13065+{
13066+ unsigned long flags;
13067+
13068+ FN_ENTER;
13069+ /* disable radio Tx/Rx. Shouldn't we use the firmware commands
13070+ * here instead? Or are we that much down the road that it's no
13071+ * longer possible here? */
13072+ /*
13073+ * slave memory interface really doesn't like this.
13074+ */
13075+ /*
13076+ write_reg16(adev, IO_ACX_ENABLE, 0);
13077+ */
13078+
13079+ acx_s_msleep(100);
13080+
13081+ acx_lock(adev, flags);
13082+ acxmem_free_desc_queues(adev);
13083+ acx_unlock(adev, flags);
13084+
13085+ FN_EXIT0;
13086+}
13087+
13088+
13089+/***********************************************************************
13090+** acxmem_e_probe
13091+**
13092+** Probe routine called when a PCI device w/ matching ID is found.
13093+** Here's the sequence:
13094+** - Allocate the PCI resources.
13095+** - Read the PCMCIA attribute memory to make sure we have a WLAN card
13096+** - Reset the MAC
13097+** - Initialize the dev and wlan data
13098+** - Initialize the MAC
13099+**
13100+** pdev - ptr to pci device structure containing info about pci configuration
13101+** id - ptr to the device id entry that matched this device
13102+*/
13103+static const u16
13104+IO_ACX100[] =
13105+{
13106+ 0x0000, /* IO_ACX_SOFT_RESET */
13107+
13108+ 0x0014, /* IO_ACX_SLV_MEM_ADDR */
13109+ 0x0018, /* IO_ACX_SLV_MEM_DATA */
13110+ 0x001c, /* IO_ACX_SLV_MEM_CTL */
13111+ 0x0020, /* IO_ACX_SLV_END_CTL */
13112+
13113+ 0x0034, /* IO_ACX_FEMR */
13114+
13115+ 0x007c, /* IO_ACX_INT_TRIG */
13116+ 0x0098, /* IO_ACX_IRQ_MASK */
13117+ 0x00a4, /* IO_ACX_IRQ_STATUS_NON_DES */
13118+ 0x00a8, /* IO_ACX_IRQ_STATUS_CLEAR */
13119+ 0x00ac, /* IO_ACX_IRQ_ACK */
13120+ 0x00b0, /* IO_ACX_HINT_TRIG */
13121+
13122+ 0x0104, /* IO_ACX_ENABLE */
13123+
13124+ 0x0250, /* IO_ACX_EEPROM_CTL */
13125+ 0x0254, /* IO_ACX_EEPROM_ADDR */
13126+ 0x0258, /* IO_ACX_EEPROM_DATA */
13127+ 0x025c, /* IO_ACX_EEPROM_CFG */
13128+
13129+ 0x0268, /* IO_ACX_PHY_ADDR */
13130+ 0x026c, /* IO_ACX_PHY_DATA */
13131+ 0x0270, /* IO_ACX_PHY_CTL */
13132+
13133+ 0x0290, /* IO_ACX_GPIO_OE */
13134+
13135+ 0x0298, /* IO_ACX_GPIO_OUT */
13136+
13137+ 0x02a4, /* IO_ACX_CMD_MAILBOX_OFFS */
13138+ 0x02a8, /* IO_ACX_INFO_MAILBOX_OFFS */
13139+ 0x02ac, /* IO_ACX_EEPROM_INFORMATION */
13140+
13141+ 0x02d0, /* IO_ACX_EE_START */
13142+ 0x02d4, /* IO_ACX_SOR_CFG */
13143+ 0x02d8 /* IO_ACX_ECPU_CTRL */
13144+};
13145+
13146+static const u16
13147+IO_ACX111[] =
13148+{
13149+ 0x0000, /* IO_ACX_SOFT_RESET */
13150+
13151+ 0x0014, /* IO_ACX_SLV_MEM_ADDR */
13152+ 0x0018, /* IO_ACX_SLV_MEM_DATA */
13153+ 0x001c, /* IO_ACX_SLV_MEM_CTL */
13154+ 0x0020, /* IO_ACX_SLV_MEM_CP */
13155+
13156+ 0x0034, /* IO_ACX_FEMR */
13157+
13158+ 0x00b4, /* IO_ACX_INT_TRIG */
13159+ 0x00d4, /* IO_ACX_IRQ_MASK */
13160+ /* we do mean NON_DES (0xf0), not NON_DES_MASK which is at 0xe0: */
13161+ 0x00f0, /* IO_ACX_IRQ_STATUS_NON_DES */
13162+ 0x00e4, /* IO_ACX_IRQ_STATUS_CLEAR */
13163+ 0x00e8, /* IO_ACX_IRQ_ACK */
13164+ 0x00ec, /* IO_ACX_HINT_TRIG */
13165+
13166+ 0x01d0, /* IO_ACX_ENABLE */
13167+
13168+ 0x0338, /* IO_ACX_EEPROM_CTL */
13169+ 0x033c, /* IO_ACX_EEPROM_ADDR */
13170+ 0x0340, /* IO_ACX_EEPROM_DATA */
13171+ 0x0344, /* IO_ACX_EEPROM_CFG */
13172+
13173+ 0x0350, /* IO_ACX_PHY_ADDR */
13174+ 0x0354, /* IO_ACX_PHY_DATA */
13175+ 0x0358, /* IO_ACX_PHY_CTL */
13176+
13177+ 0x0374, /* IO_ACX_GPIO_OE */
13178+
13179+ 0x037c, /* IO_ACX_GPIO_OUT */
13180+
13181+ 0x0388, /* IO_ACX_CMD_MAILBOX_OFFS */
13182+ 0x038c, /* IO_ACX_INFO_MAILBOX_OFFS */
13183+ 0x0390, /* IO_ACX_EEPROM_INFORMATION */
13184+
13185+ 0x0100, /* IO_ACX_EE_START */
13186+ 0x0104, /* IO_ACX_SOR_CFG */
13187+ 0x0108, /* IO_ACX_ECPU_CTRL */
13188+};
13189+
13190+static void
13191+dummy_netdev_init(struct net_device *ndev) {}
13192+
13193+/*
13194+ * Most of the acx specific pieces of hardware reset.
13195+ */
13196+static int
13197+acxmem_complete_hw_reset (acx_device_t *adev)
13198+{
13199+ acx111_ie_configoption_t co;
13200+
13201+ /* NB: read_reg() reads may return bogus data before reset_dev(),
13202+ * since the firmware which directly controls large parts of the I/O
13203+ * registers isn't initialized yet.
13204+ * acx100 seems to be more affected than acx111 */
13205+ if (OK != acxmem_s_reset_dev (adev))
13206+ return -1;
13207+
13208+ if (IS_ACX100(adev)) {
13209+ /* ACX100: configopt struct in cmd mailbox - directly after reset */
13210+ copy_from_slavemem (adev, (u8*) &co, (u32) adev->cmd_area, sizeof (co));
13211+ }
13212+
13213+ if (OK != acx_s_init_mac(adev))
13214+ return -3;
13215+
13216+ if (IS_ACX111(adev)) {
13217+ /* ACX111: configopt struct needs to be queried after full init */
13218+ acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS);
13219+ }
13220+
13221+ /*
13222+ * Set up transmit buffer administration
13223+ */
13224+ init_acx_txbuf (adev);
13225+
13226+ /*
13227+ * Windows driver writes 0x01000000 to register 0x288, RADIO_CTL, if the form factor
13228+ * is 3. It also write protects the EEPROM by writing 1<<9 to GPIO_OUT
13229+ */
13230+ if (adev->form_factor == 3) {
13231+ set_regbits (adev, 0x288, 0x01000000);
13232+ set_regbits (adev, 0x298, 1<<9);
13233+ }
13234+
13235+/* TODO: merge them into one function, they are called just once and are the same for pci & usb */
13236+ if (OK != acxmem_read_eeprom_byte(adev, 0x05, &adev->eeprom_version))
13237+ return -2;
13238+
13239+ acx_s_parse_configoption(adev, &co);
13240+ acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */
13241+ acx_display_hardware_details(adev);
13242+
13243+ return 0;
13244+}
13245+
13246+static int acx_init_netdev(struct net_device *ndev, struct device *dev, int base_addr, int addr_size, int irq)
13247+{
13248+ const char *chip_name;
13249+ int result = -EIO;
13250+ int err;
13251+ u8 chip_type;
13252+ acx_device_t *adev = NULL;
13253+
13254+ FN_ENTER;
13255+
13256+ /* FIXME: prism54 calls pci_set_mwi() here,
13257+ * should we do/support the same? */
13258+
13259+ /* chiptype is u8 but id->driver_data is ulong
13260+ ** Works for now (possible values are 1 and 2) */
13261+ chip_type = CHIPTYPE_ACX100;
13262+ /* acx100 and acx111 have different PCI memory regions */
13263+ if (chip_type == CHIPTYPE_ACX100) {
13264+ chip_name = "ACX100";
13265+ } else if (chip_type == CHIPTYPE_ACX111) {
13266+ chip_name = "ACX111";
13267+ } else {
13268+ printk("acx: unknown chip type 0x%04X\n", chip_type);
13269+ goto fail_unknown_chiptype;
13270+ }
13271+
13272+ printk("acx: found %s-based wireless network card\n", chip_name);
13273+ log(L_ANY, "initial debug setting is 0x%04X\n", acx_debug);
13274+
13275+
13276+ dev_set_drvdata(dev, ndev);
13277+
13278+ ether_setup(ndev);
13279+
13280+ ndev->irq = irq;
13281+
13282+ ndev->base_addr = base_addr;
13283+printk (KERN_INFO "memwinbase=%lx memwinsize=%u\n",memwin.Base,memwin.Size);
13284+ if (addr_size == 0 || ndev->irq == 0)
13285+ goto fail_hw_params;
13286+ ndev->open = &acxmem_e_open;
13287+ ndev->stop = &acxmem_e_close;
13288+ //pdev->dev.release = &acxmem_e_release;
13289+ ndev->hard_start_xmit = &acx_i_start_xmit;
13290+ ndev->get_stats = &acx_e_get_stats;
13291+#if IW_HANDLER_VERSION <= 5
13292+ ndev->get_wireless_stats = &acx_e_get_wireless_stats;
13293+#endif
13294+ ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def;
13295+ ndev->set_multicast_list = &acxmem_i_set_multicast_list;
13296+ ndev->tx_timeout = &acxmem_i_tx_timeout;
13297+ ndev->change_mtu = &acx_e_change_mtu;
13298+ ndev->watchdog_timeo = 4 * HZ;
13299+
13300+ adev = ndev2adev(ndev);
13301+ spin_lock_init(&adev->lock); /* initial state: unlocked */
13302+ spin_lock_init(&adev->txbuf_lock);
13303+ /* We do not start with downed sem: we want PARANOID_LOCKING to work */
13304+ sema_init(&adev->sem, 1); /* initial state: 1 (upped) */
13305+ /* since nobody can see new netdev yet, we can as well
13306+ ** just _presume_ that we're under sem (instead of actually taking it): */
13307+ /* acx_sem_lock(adev); */
13308+ adev->dev = dev;
13309+ adev->ndev = ndev;
13310+ adev->dev_type = DEVTYPE_MEM;
13311+ adev->chip_type = chip_type;
13312+ adev->chip_name = chip_name;
13313+ adev->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111;
13314+ adev->membase = (volatile u32 *) ndev->base_addr;
13315+ adev->iobase = (volatile u32 *) ioremap_nocache (ndev->base_addr, addr_size);
13316+ /* to find crashes due to weird driver access
13317+ * to unconfigured interface (ifup) */
13318+ adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead;
13319+
13320+#if defined(NONESSENTIAL_FEATURES)
13321+ acx_show_card_eeprom_id(adev);
13322+#endif /* NONESSENTIAL_FEATURES */
13323+
13324+#ifdef SET_MODULE_OWNER
13325+ SET_MODULE_OWNER(ndev);
13326+#endif
13327+ // need to fix that @@
13328+ SET_NETDEV_DEV(ndev, dev);
13329+
13330+ log(L_IRQ|L_INIT, "using IRQ %d\n", ndev->irq);
13331+
13332+ /* ok, pci setup is finished, now start initializing the card */
13333+
13334+ if (OK != acxmem_complete_hw_reset (adev))
13335+ goto fail_reset;
13336+
13337+ /*
13338+ * Set up default things for most of the card settings.
13339+ */
13340+ acx_s_set_defaults(adev);
13341+
13342+ /* Register the card, AFTER everything else has been set up,
13343+ * since otherwise an ioctl could step on our feet due to
13344+ * firmware operations happening in parallel or uninitialized data */
13345+ err = register_netdev(ndev);
13346+ if (OK != err) {
13347+ printk("acx: register_netdev() FAILED: %d\n", err);
13348+ goto fail_register_netdev;
13349+ }
13350+
13351+ acx_proc_register_entries(ndev);
13352+
13353+ /* Now we have our device, so make sure the kernel doesn't try
13354+ * to send packets even though we're not associated to a network yet */
13355+ acx_stop_queue(ndev, "on probe");
13356+ acx_carrier_off(ndev, "on probe");
13357+
13358+ /*
13359+ * Set up a default monitor type so that poor combinations of initialization
13360+ * sequences in monitor mode don't end up destroying the hardware type.
13361+ */
13362+ adev->monitor_type = ARPHRD_ETHER;
13363+
13364+ /*
13365+ * Register to receive inetaddr notifier changes. This will allow us to
13366+ * catch if the user changes the MAC address of the interface.
13367+ */
13368+ register_netdevice_notifier(&acx_netdev_notifier);
13369+
13370+ /* after register_netdev() userspace may start working with dev
13371+ * (in particular, on other CPUs), we only need to up the sem */
13372+ /* acx_sem_unlock(adev); */
13373+
13374+ printk("acx "ACX_RELEASE": net device %s, driver compiled "
13375+ "against wireless extensions %d and Linux %s\n",
13376+ ndev->name, WIRELESS_EXT, UTS_RELEASE);
13377+
13378+#if CMD_DISCOVERY
13379+ great_inquisitor(adev);
13380+#endif
13381+
13382+ result = OK;
13383+ goto done;
13384+
13385+ /* error paths: undo everything in reverse order... */
13386+
13387+fail_register_netdev:
13388+
13389+ acxmem_s_delete_dma_regions(adev);
13390+
13391+fail_reset:
13392+fail_hw_params:
13393+ free_netdev(ndev);
13394+fail_unknown_chiptype:
13395+
13396+
13397+done:
13398+ FN_EXIT1(result);
13399+ return result;
13400+}
13401+
13402+
13403+/***********************************************************************
13404+** acxmem_e_remove
13405+**
13406+** Shut device down (if not hot unplugged)
13407+** and deallocate PCI resources for the acx chip.
13408+**
13409+** pdev - ptr to PCI device structure containing info about pci configuration
13410+*/
13411+static int __devexit
13412+acxmem_e_remove(struct pcmcia_device *link)
13413+{
13414+ struct net_device *ndev;
13415+ acx_device_t *adev;
13416+ unsigned long flags;
13417+
13418+ FN_ENTER;
13419+
13420+ ndev = ((local_info_t*)link->priv)->ndev;
13421+ if (!ndev) {
13422+ log(L_DEBUG, "%s: card is unused. Skipping any release code\n",
13423+ __func__);
13424+ goto end;
13425+ }
13426+
13427+ adev = ndev2adev(ndev);
13428+
13429+ /* If device wasn't hot unplugged... */
13430+ if (adev_present(adev)) {
13431+
13432+ acx_sem_lock(adev);
13433+
13434+ /* disable both Tx and Rx to shut radio down properly */
13435+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
13436+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0);
13437+
13438+#ifdef REDUNDANT
13439+ /* put the eCPU to sleep to save power
13440+ * Halting is not possible currently,
13441+ * since not supported by all firmware versions */
13442+ acx_s_issue_cmd(adev, ACX100_CMD_SLEEP, NULL, 0);
13443+#endif
13444+ acx_lock(adev, flags);
13445+
13446+ /* disable power LED to save power :-) */
13447+ log(L_INIT, "switching off power LED to save power\n");
13448+ acxmem_l_power_led(adev, 0);
13449+
13450+ /* stop our eCPU */
13451+ if (IS_ACX111(adev)) {
13452+ /* FIXME: does this actually keep halting the eCPU?
13453+ * I don't think so...
13454+ */
13455+ acxmem_l_reset_mac(adev);
13456+ } else {
13457+ u16 temp;
13458+
13459+ /* halt eCPU */
13460+ temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1;
13461+ write_reg16(adev, IO_ACX_ECPU_CTRL, temp);
13462+ write_flush(adev);
13463+ }
13464+
13465+ acx_unlock(adev, flags);
13466+
13467+ acx_sem_unlock(adev);
13468+ }
13469+
13470+
13471+ /*
13472+ * Unregister the notifier chain
13473+ */
13474+ unregister_netdevice_notifier(&acx_netdev_notifier);
13475+
13476+ /* unregister the device to not let the kernel
13477+ * (e.g. ioctls) access a half-deconfigured device
13478+ * NB: this will cause acxmem_e_close() to be called,
13479+ * thus we shouldn't call it under sem! */
13480+ log(L_INIT, "removing device %s\n", ndev->name);
13481+ unregister_netdev(ndev);
13482+
13483+ /* unregister_netdev ensures that no references to us left.
13484+ * For paranoid reasons we continue to follow the rules */
13485+ acx_sem_lock(adev);
13486+
13487+ if (adev->dev_state_mask & ACX_STATE_IFACE_UP) {
13488+ acxmem_s_down(ndev);
13489+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
13490+ }
13491+
13492+ acx_proc_unregister_entries(ndev);
13493+
13494+ acxmem_s_delete_dma_regions(adev);
13495+
13496+ /* finally, clean up PCI bus state */
13497+ if (adev->iobase) iounmap((void *)adev->iobase);
13498+
13499+ acx_sem_unlock(adev);
13500+
13501+ /* Free netdev (quite late,
13502+ * since otherwise we might get caught off-guard
13503+ * by a netdev timeout handler execution
13504+ * expecting to see a working dev...) */
13505+ free_netdev(ndev);
13506+
13507+ printk ("e_remove done\n");
13508+end:
13509+ FN_EXIT0;
13510+
13511+ return 0;
13512+}
13513+
13514+
13515+/***********************************************************************
13516+** TODO: PM code needs to be fixed / debugged / tested.
13517+*/
13518+#ifdef CONFIG_PM
13519+static int
13520+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
13521+acxmem_e_suspend( struct net_device *ndev, pm_message_t state)
13522+#else
13523+acxmem_e_suspend( struct net_device *ndev, u32 state)
13524+#endif
13525+{
13526+ FN_ENTER;
13527+ acx_device_t *adev;
13528+ printk("acx: suspend handler is experimental!\n");
13529+ printk("sus: dev %p\n", ndev);
13530+
13531+ if (!netif_running(ndev))
13532+ goto end;
13533+ // @@ need to get it from link or something like that
13534+ adev = ndev2adev(ndev);
13535+ printk("sus: adev %p\n", adev);
13536+
13537+ acx_sem_lock(adev);
13538+
13539+ netif_device_detach(adev->ndev); /* this one cannot sleep */
13540+ acxmem_s_down(adev->ndev);
13541+ /* down() does not set it to 0xffff, but here we really want that */
13542+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
13543+ write_reg16(adev, IO_ACX_FEMR, 0x0);
13544+ acxmem_s_delete_dma_regions(adev);
13545+
13546+ /*
13547+ * Turn the ACX chip off.
13548+ */
13549+
13550+ acx_sem_unlock(adev);
13551+end:
13552+ FN_EXIT0;
13553+ return OK;
13554+}
13555+
13556+
13557+static void
13558+fw_resumer(struct work_struct *notused)
13559+{
13560+ acx_device_t *adev;
13561+ struct net_device *ndev = resume_ndev;
13562+
13563+ printk("acx: resume handler is experimental!\n");
13564+ printk("rsm: got dev %p\n", ndev);
13565+
13566+ if (!netif_running(ndev))
13567+ return;
13568+
13569+ adev = ndev2adev(ndev);
13570+ printk("rsm: got adev %p\n", adev);
13571+
13572+ acx_sem_lock(adev);
13573+
13574+ /*
13575+ * Turn on the ACX.
13576+ */
13577+
13578+ acxmem_complete_hw_reset (adev);
13579+
13580+ /*
13581+ * done by acx_s_set_defaults for initial startup
13582+ */
13583+ acxmem_set_interrupt_mask(adev);
13584+
13585+ printk ("rsm: bringing up interface\n");
13586+ SET_BIT (adev->set_mask, GETSET_ALL);
13587+ acxmem_s_up(ndev);
13588+ printk("rsm: acx up done\n");
13589+
13590+ /* now even reload all card parameters as they were before suspend,
13591+ * and possibly be back in the network again already :-)
13592+ */
13593+ /* - most settings updated in acxmem_s_up()
13594+ if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
13595+ adev->set_mask = GETSET_ALL;
13596+ acx_s_update_card_settings(adev);
13597+ printk("rsm: settings updated\n");
13598+ }
13599+ */
13600+ netif_device_attach(ndev);
13601+ printk("rsm: device attached\n");
13602+
13603+ acx_sem_unlock(adev);
13604+}
13605+
13606+DECLARE_WORK( fw_resume_work, fw_resumer );
13607+
13608+static int
13609+acxmem_e_resume(struct pcmcia_device *link)
13610+{
13611+ FN_ENTER;
13612+
13613+ //resume_pdev = pdev;
13614+ schedule_work( &fw_resume_work );
13615+
13616+ FN_EXIT0;
13617+ return OK;
13618+}
13619+#endif /* CONFIG_PM */
13620+
13621+
13622+/***********************************************************************
13623+** acxmem_s_up
13624+**
13625+** This function is called by acxmem_e_open (when ifconfig sets the device as up)
13626+**
13627+** Side effects:
13628+** - Enables on-card interrupt requests
13629+** - calls acx_s_start
13630+*/
13631+
13632+static void
13633+enable_acx_irq(acx_device_t *adev)
13634+{
13635+ FN_ENTER;
13636+ write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask);
13637+ write_reg16(adev, IO_ACX_FEMR, 0x8000);
13638+ adev->irqs_active = 1;
13639+ FN_EXIT0;
13640+}
13641+
13642+static void
13643+acxmem_s_up(struct net_device *ndev)
13644+{
13645+ acx_device_t *adev = ndev2adev(ndev);
13646+ unsigned long flags;
13647+
13648+ FN_ENTER;
13649+
13650+ acx_lock(adev, flags);
13651+ enable_acx_irq(adev);
13652+ acx_unlock(adev, flags);
13653+
13654+ /* acx fw < 1.9.3.e has a hardware timer, and older drivers
13655+ ** used to use it. But we don't do that anymore, our OS
13656+ ** has reliable software timers */
13657+ init_timer(&adev->mgmt_timer);
13658+ adev->mgmt_timer.function = acx_i_timer;
13659+ adev->mgmt_timer.data = (unsigned long)adev;
13660+
13661+ /* Need to set ACX_STATE_IFACE_UP first, or else
13662+ ** timer won't be started by acx_set_status() */
13663+ SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
13664+ switch (adev->mode) {
13665+ case ACX_MODE_0_ADHOC:
13666+ case ACX_MODE_2_STA:
13667+ /* actual scan cmd will happen in start() */
13668+ acx_set_status(adev, ACX_STATUS_1_SCANNING); break;
13669+ case ACX_MODE_3_AP:
13670+ case ACX_MODE_MONITOR:
13671+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); break;
13672+ }
13673+
13674+ acx_s_start(adev);
13675+
13676+ FN_EXIT0;
13677+}
13678+
13679+
13680+/***********************************************************************
13681+** acxmem_s_down
13682+**
13683+** This disables the netdevice
13684+**
13685+** Side effects:
13686+** - disables on-card interrupt request
13687+*/
13688+
13689+static void
13690+disable_acx_irq(acx_device_t *adev)
13691+{
13692+ FN_ENTER;
13693+
13694+ /* I guess mask is not 0xffff because acx100 won't signal
13695+ ** cmd completion then (needed for ifup).
13696+ ** Someone with acx100 please confirm */
13697+ write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask_off);
13698+ write_reg16(adev, IO_ACX_FEMR, 0x0);
13699+ adev->irqs_active = 0;
13700+ FN_EXIT0;
13701+}
13702+
13703+static void
13704+acxmem_s_down(struct net_device *ndev)
13705+{
13706+ acx_device_t *adev = ndev2adev(ndev);
13707+ unsigned long flags;
13708+
13709+ FN_ENTER;
13710+
13711+ /* Disable IRQs first, so that IRQs cannot race with us */
13712+ /* then wait until interrupts have finished executing on other CPUs */
13713+ acx_lock(adev, flags);
13714+ disable_acx_irq(adev);
13715+ synchronize_irq(adev->pdev->irq);
13716+ acx_unlock(adev, flags);
13717+
13718+ /* we really don't want to have an asynchronous tasklet disturb us
13719+ ** after something vital for its job has been shut down, so
13720+ ** end all remaining work now.
13721+ **
13722+ ** NB: carrier_off (done by set_status below) would lead to
13723+ ** not yet fully understood deadlock in FLUSH_SCHEDULED_WORK().
13724+ ** That's why we do FLUSH first.
13725+ **
13726+ ** NB2: we have a bad locking bug here: FLUSH_SCHEDULED_WORK()
13727+ ** waits for acx_e_after_interrupt_task to complete if it is running
13728+ ** on another CPU, but acx_e_after_interrupt_task
13729+ ** will sleep on sem forever, because it is taken by us!
13730+ ** Work around that by temporary sem unlock.
13731+ ** This will fail miserably if we'll be hit by concurrent
13732+ ** iwconfig or something in between. TODO! */
13733+ acx_sem_unlock(adev);
13734+ FLUSH_SCHEDULED_WORK();
13735+ acx_sem_lock(adev);
13736+
13737+ /* This is possible:
13738+ ** FLUSH_SCHEDULED_WORK -> acx_e_after_interrupt_task ->
13739+ ** -> set_status(ASSOCIATED) -> wake_queue()
13740+ ** That's why we stop queue _after_ FLUSH_SCHEDULED_WORK
13741+ ** lock/unlock is just paranoia, maybe not needed */
13742+ acx_lock(adev, flags);
13743+ acx_stop_queue(ndev, "on ifdown");
13744+ acx_set_status(adev, ACX_STATUS_0_STOPPED);
13745+ acx_unlock(adev, flags);
13746+
13747+ /* kernel/timer.c says it's illegal to del_timer_sync()
13748+ ** a timer which restarts itself. We guarantee this cannot
13749+ ** ever happen because acx_i_timer() never does this if
13750+ ** status is ACX_STATUS_0_STOPPED */
13751+ del_timer_sync(&adev->mgmt_timer);
13752+
13753+ FN_EXIT0;
13754+}
13755+
13756+
13757+/***********************************************************************
13758+** acxmem_e_open
13759+**
13760+** Called as a result of SIOCSIFFLAGS ioctl changing the flags bit IFF_UP
13761+** from clear to set. In other words: ifconfig up.
13762+**
13763+** Returns:
13764+** 0 success
13765+** >0 f/w reported error
13766+** <0 driver reported error
13767+*/
13768+static int
13769+acxmem_e_open(struct net_device *ndev)
13770+{
13771+ acx_device_t *adev = ndev2adev(ndev);
13772+ int result = OK;
13773+
13774+ FN_ENTER;
13775+
13776+ acx_sem_lock(adev);
13777+
13778+ acx_init_task_scheduler(adev);
13779+
13780+/* TODO: pci_set_power_state(pdev, PCI_D0); ? */
13781+
13782+#if 0
13783+ /* request shared IRQ handler */
13784+ if (request_irq(ndev->irq, acxmem_i_interrupt, SA_INTERRUPT, ndev->name, ndev)) {
13785+ printk("%s: request_irq FAILED\n", ndev->name);
13786+ result = -EAGAIN;
13787+ goto done;
13788+ }
13789+ set_irq_type (ndev->irq, IRQT_FALLING);
13790+ log(L_DEBUG|L_IRQ, "request_irq %d successful\n", ndev->irq);
13791+#endif
13792+
13793+ /* ifup device */
13794+ acxmem_s_up(ndev);
13795+
13796+ /* We don't currently have to do anything else.
13797+ * The setup of the MAC should be subsequently completed via
13798+ * the mlme commands.
13799+ * Higher layers know we're ready from dev->start==1 and
13800+ * dev->tbusy==0. Our rx path knows to pass up received/
13801+ * frames because of dev->flags&IFF_UP is true.
13802+ */
13803+done:
13804+ acx_sem_unlock(adev);
13805+
13806+ FN_EXIT1(result);
13807+ return result;
13808+}
13809+
13810+
13811+/***********************************************************************
13812+** acxmem_e_close
13813+**
13814+** Called as a result of SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
13815+** from set to clear. I.e. called by "ifconfig DEV down"
13816+**
13817+** Returns:
13818+** 0 success
13819+** >0 f/w reported error
13820+** <0 driver reported error
13821+*/
13822+static int
13823+acxmem_e_close(struct net_device *ndev)
13824+{
13825+ acx_device_t *adev = ndev2adev(ndev);
13826+
13827+ FN_ENTER;
13828+
13829+ acx_sem_lock(adev);
13830+
13831+ /* ifdown device */
13832+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
13833+ if (netif_device_present(ndev)) {
13834+ acxmem_s_down(ndev);
13835+ }
13836+
13837+ /* disable all IRQs, release shared IRQ handler */
13838+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
13839+ write_reg16(adev, IO_ACX_FEMR, 0x0);
13840+ free_irq(ndev->irq, ndev);
13841+
13842+/* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */
13843+
13844+ /* We currently don't have to do anything else.
13845+ * Higher layers know we're not ready from dev->start==0 and
13846+ * dev->tbusy==1. Our rx path knows to not pass up received
13847+ * frames because of dev->flags&IFF_UP is false.
13848+ */
13849+ acx_sem_unlock(adev);
13850+
13851+ log(L_INIT, "closed device\n");
13852+ FN_EXIT0;
13853+ return OK;
13854+}
13855+
13856+
13857+/***********************************************************************
13858+** acxmem_i_tx_timeout
13859+**
13860+** Called from network core. Must not sleep!
13861+*/
13862+static void
13863+acxmem_i_tx_timeout(struct net_device *ndev)
13864+{
13865+ acx_device_t *adev = ndev2adev(ndev);
13866+ unsigned long flags;
13867+ unsigned int tx_num_cleaned;
13868+
13869+ FN_ENTER;
13870+
13871+ acx_lock(adev, flags);
13872+
13873+ /* clean processed tx descs, they may have been completely full */
13874+ tx_num_cleaned = acxmem_l_clean_txdesc(adev);
13875+
13876+ /* nothing cleaned, yet (almost) no free buffers available?
13877+ * --> clean all tx descs, no matter which status!!
13878+ * Note that I strongly suspect that doing emergency cleaning
13879+ * may confuse the firmware. This is a last ditch effort to get
13880+ * ANYTHING to work again...
13881+ *
13882+ * TODO: it's best to simply reset & reinit hw from scratch...
13883+ */
13884+ if ((adev->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) {
13885+ printk("%s: FAILED to free any of the many full tx buffers. "
13886+ "Switching to emergency freeing. "
13887+ "Please report!\n", ndev->name);
13888+ acxmem_l_clean_txdesc_emergency(adev);
13889+ }
13890+
13891+ if (acx_queue_stopped(ndev) && (ACX_STATUS_4_ASSOCIATED == adev->status))
13892+ acx_wake_queue(ndev, "after tx timeout");
13893+
13894+ /* stall may have happened due to radio drift, so recalib radio */
13895+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
13896+
13897+ /* do unimportant work last */
13898+ printk("%s: tx timeout!\n", ndev->name);
13899+ adev->stats.tx_errors++;
13900+
13901+ acx_unlock(adev, flags);
13902+
13903+ FN_EXIT0;
13904+}
13905+
13906+
13907+/***********************************************************************
13908+** acxmem_i_set_multicast_list
13909+** FIXME: most likely needs refinement
13910+*/
13911+static void
13912+acxmem_i_set_multicast_list(struct net_device *ndev)
13913+{
13914+ acx_device_t *adev = ndev2adev(ndev);
13915+ unsigned long flags;
13916+
13917+ FN_ENTER;
13918+
13919+ acx_lock(adev, flags);
13920+
13921+ /* firmwares don't have allmulti capability,
13922+ * so just use promiscuous mode instead in this case. */
13923+ if (ndev->flags & (IFF_PROMISC|IFF_ALLMULTI)) {
13924+ SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
13925+ CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
13926+ SET_BIT(adev->set_mask, SET_RXCONFIG);
13927+ /* let kernel know in case *we* needed to set promiscuous */
13928+ ndev->flags |= (IFF_PROMISC|IFF_ALLMULTI);
13929+ } else {
13930+ CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
13931+ SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
13932+ SET_BIT(adev->set_mask, SET_RXCONFIG);
13933+ ndev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI);
13934+ }
13935+
13936+ /* cannot update card settings directly here, atomic context */
13937+ acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
13938+
13939+ acx_unlock(adev, flags);
13940+
13941+ FN_EXIT0;
13942+}
13943+
13944+
13945+/***************************************************************
13946+** acxmem_l_process_rxdesc
13947+**
13948+** Called directly and only from the IRQ handler
13949+*/
13950+
13951+#if !ACX_DEBUG
13952+static inline void log_rxbuffer(const acx_device_t *adev) {}
13953+#else
13954+static void
13955+log_rxbuffer(const acx_device_t *adev)
13956+{
13957+ register const struct rxhostdesc *rxhostdesc;
13958+ int i;
13959+ /* no FN_ENTER here, we don't want that */
13960+
13961+ rxhostdesc = adev->rxhostdesc_start;
13962+ if (unlikely(!rxhostdesc)) return;
13963+ for (i = 0; i < RX_CNT; i++) {
13964+ if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
13965+ && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
13966+ printk("rx: buf %d full\n", i);
13967+ rxhostdesc++;
13968+ }
13969+}
13970+#endif
13971+
13972+static void
13973+acxmem_l_process_rxdesc(acx_device_t *adev)
13974+{
13975+ register rxhostdesc_t *hostdesc;
13976+ register rxdesc_t *rxdesc;
13977+ unsigned count, tail;
13978+ u32 addr;
13979+ u8 Ctl_8;
13980+
13981+ FN_ENTER;
13982+
13983+ if (unlikely(acx_debug & L_BUFR))
13984+ log_rxbuffer(adev);
13985+
13986+ /* First, have a loop to determine the first descriptor that's
13987+ * full, just in case there's a mismatch between our current
13988+ * rx_tail and the full descriptor we're supposed to handle. */
13989+ tail = adev->rx_tail;
13990+ count = RX_CNT;
13991+ while (1) {
13992+ hostdesc = &adev->rxhostdesc_start[tail];
13993+ rxdesc = &adev->rxdesc_start[tail];
13994+ /* advance tail regardless of outcome of the below test */
13995+ tail = (tail + 1) % RX_CNT;
13996+
13997+ /*
13998+ * Unlike the PCI interface, where the ACX can write directly to
13999+ * the host descriptors, on the slave memory interface we have to
14000+ * pull these. All we really need to do is check the Ctl_8 field
14001+ * in the rx descriptor on the ACX, which should be 0x11000000 if
14002+ * we should process it.
14003+ */
14004+ Ctl_8 = hostdesc->Ctl_16 = read_slavemem8 (adev, (u32) &(rxdesc->Ctl_8));
14005+ if ((Ctl_8 & DESC_CTL_HOSTOWN) &&
14006+ (Ctl_8 & DESC_CTL_ACXDONE))
14007+ break; /* found it! */
14008+
14009+ if (unlikely(!--count)) /* hmm, no luck: all descs empty, bail out */
14010+ goto end;
14011+ }
14012+
14013+ /* now process descriptors, starting with the first we figured out */
14014+ while (1) {
14015+ log(L_BUFR, "rx: tail=%u Ctl_8=%02X\n", tail, Ctl_8);
14016+ /*
14017+ * If the ACX has CTL_RECLAIM set on this descriptor there
14018+ * is no buffer associated; it just wants us to tell it to
14019+ * reclaim the memory.
14020+ */
14021+ if (!(Ctl_8 & DESC_CTL_RECLAIM)) {
14022+
14023+ /*
14024+ * slave interface - pull data now
14025+ */
14026+ hostdesc->length = read_slavemem16 (adev, (u32) &(rxdesc->total_length));
14027+
14028+ /*
14029+ * hostdesc->data is an rxbuffer_t, which includes header information,
14030+ * but the length in the data packet doesn't. The header information
14031+ * takes up an additional 12 bytes, so add that to the length we copy.
14032+ */
14033+ addr = read_slavemem32 (adev, (u32) &(rxdesc->ACXMemPtr));
14034+ if (addr) {
14035+ /*
14036+ * How can &(rxdesc->ACXMemPtr) above ever be zero? Looks like we
14037+ * get that now and then - try to trap it for debug.
14038+ */
14039+ if (addr & 0xffff0000) {
14040+ printk("rxdesc 0x%08x\n", (u32) rxdesc);
14041+ dump_acxmem (adev, 0, 0x10000);
14042+ panic ("Bad access!");
14043+ }
14044+ chaincopy_from_slavemem (adev, (u8 *) hostdesc->data, addr,
14045+ hostdesc->length +
14046+ (u32) &((rxbuffer_t *)0)->hdr_a3);
14047+ acx_l_process_rxbuf(adev, hostdesc->data);
14048+ }
14049+ }
14050+ else {
14051+ printk ("rx reclaim only!\n");
14052+ }
14053+
14054+ hostdesc->Status = 0;
14055+
14056+ /*
14057+ * Let the ACX know we're done.
14058+ */
14059+ CLEAR_BIT (Ctl_8, DESC_CTL_HOSTOWN);
14060+ SET_BIT (Ctl_8, DESC_CTL_HOSTDONE);
14061+ SET_BIT (Ctl_8, DESC_CTL_RECLAIM);
14062+ write_slavemem8 (adev, (u32) &rxdesc->Ctl_8, Ctl_8);
14063+
14064+ /*
14065+ * Now tell the ACX we've finished with the receive buffer so
14066+ * it can finish the reclaim.
14067+ */
14068+ write_reg16 (adev, IO_ACX_INT_TRIG, INT_TRIG_RXPRC);
14069+
14070+ /* ok, descriptor is handled, now check the next descriptor */
14071+ hostdesc = &adev->rxhostdesc_start[tail];
14072+ rxdesc = &adev->rxdesc_start[tail];
14073+
14074+ Ctl_8 = hostdesc->Ctl_16 = read_slavemem8 (adev, (u32) &(rxdesc->Ctl_8));
14075+
14076+ /* if next descriptor is empty, then bail out */
14077+ if (!(Ctl_8 & DESC_CTL_HOSTOWN) || !(Ctl_8 & DESC_CTL_ACXDONE))
14078+ break;
14079+
14080+ tail = (tail + 1) % RX_CNT;
14081+ }
14082+end:
14083+ adev->rx_tail = tail;
14084+ FN_EXIT0;
14085+}
14086+
14087+
14088+/***********************************************************************
14089+** acxmem_i_interrupt
14090+**
14091+** IRQ handler (atomic context, must not sleep, blah, blah)
14092+*/
14093+
14094+/* scan is complete. all frames now on the receive queue are valid */
14095+#define INFO_SCAN_COMPLETE 0x0001
14096+#define INFO_WEP_KEY_NOT_FOUND 0x0002
14097+/* hw has been reset as the result of a watchdog timer timeout */
14098+#define INFO_WATCH_DOG_RESET 0x0003
14099+/* failed to send out NULL frame from PS mode notification to AP */
14100+/* recommended action: try entering 802.11 PS mode again */
14101+#define INFO_PS_FAIL 0x0004
14102+/* encryption/decryption process on a packet failed */
14103+#define INFO_IV_ICV_FAILURE 0x0005
14104+
14105+/* Info mailbox format:
14106+2 bytes: type
14107+2 bytes: status
14108+more bytes may follow
14109+ rumors say about status:
14110+ 0x0000 info available (set by hw)
14111+ 0x0001 information received (must be set by host)
14112+ 0x1000 info available, mailbox overflowed (messages lost) (set by hw)
14113+ but in practice we've seen:
14114+ 0x9000 when we did not set status to 0x0001 on prev message
14115+ 0x1001 when we did set it
14116+ 0x0000 was never seen
14117+ conclusion: this is really a bitfield:
14118+ 0x1000 is 'info available' bit
14119+ 'mailbox overflowed' bit is 0x8000, not 0x1000
14120+ value of 0x0000 probably means that there are no messages at all
14121+ P.S. I dunno how in hell hw is supposed to notice that messages are lost -
14122+ it does NOT clear bit 0x0001, and this bit will probably stay forever set
14123+ after we set it once. Let's hope this will be fixed in firmware someday
14124+*/
14125+
14126+static void
14127+handle_info_irq(acx_device_t *adev)
14128+{
14129+#if ACX_DEBUG
14130+ static const char * const info_type_msg[] = {
14131+ "(unknown)",
14132+ "scan complete",
14133+ "WEP key not found",
14134+ "internal watchdog reset was done",
14135+ "failed to send powersave (NULL frame) notification to AP",
14136+ "encrypt/decrypt on a packet has failed",
14137+ "TKIP tx keys disabled",
14138+ "TKIP rx keys disabled",
14139+ "TKIP rx: key ID not found",
14140+ "???",
14141+ "???",
14142+ "???",
14143+ "???",
14144+ "???",
14145+ "???",
14146+ "???",
14147+ "TKIP IV value exceeds thresh"
14148+ };
14149+#endif
14150+ u32 info_type, info_status;
14151+
14152+ info_type = read_slavemem32 (adev, (u32) adev->info_area);
14153+
14154+ info_status = (info_type >> 16);
14155+ info_type = (u16)info_type;
14156+
14157+ /* inform fw that we have read this info message */
14158+ write_slavemem32(adev, (u32) adev->info_area, info_type | 0x00010000);
14159+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_INFOACK);
14160+ write_flush(adev);
14161+
14162+ log(L_CTL, "info_type:%04X info_status:%04X\n",
14163+ info_type, info_status);
14164+
14165+ log(L_IRQ, "got Info IRQ: status %04X type %04X: %s\n",
14166+ info_status, info_type,
14167+ info_type_msg[(info_type >= VEC_SIZE(info_type_msg)) ?
14168+ 0 : info_type]
14169+ );
14170+}
14171+
14172+
14173+static void
14174+log_unusual_irq(u16 irqtype) {
14175+ /*
14176+ if (!printk_ratelimit())
14177+ return;
14178+ */
14179+
14180+ printk("acx: got");
14181+ if (irqtype & HOST_INT_TX_XFER) {
14182+ printk(" Tx_Xfer");
14183+ }
14184+ if (irqtype & HOST_INT_RX_COMPLETE) {
14185+ printk(" Rx_Complete");
14186+ }
14187+ if (irqtype & HOST_INT_DTIM) {
14188+ printk(" DTIM");
14189+ }
14190+ if (irqtype & HOST_INT_BEACON) {
14191+ printk(" Beacon");
14192+ }
14193+ if (irqtype & HOST_INT_TIMER) {
14194+ log(L_IRQ, " Timer");
14195+ }
14196+ if (irqtype & HOST_INT_KEY_NOT_FOUND) {
14197+ printk(" Key_Not_Found");
14198+ }
14199+ if (irqtype & HOST_INT_IV_ICV_FAILURE) {
14200+ printk(" IV_ICV_Failure (crypto)");
14201+ }
14202+ /* HOST_INT_CMD_COMPLETE */
14203+ /* HOST_INT_INFO */
14204+ if (irqtype & HOST_INT_OVERFLOW) {
14205+ printk(" Overflow");
14206+ }
14207+ if (irqtype & HOST_INT_PROCESS_ERROR) {
14208+ printk(" Process_Error");
14209+ }
14210+ /* HOST_INT_SCAN_COMPLETE */
14211+ if (irqtype & HOST_INT_FCS_THRESHOLD) {
14212+ printk(" FCS_Threshold");
14213+ }
14214+ if (irqtype & HOST_INT_UNKNOWN) {
14215+ printk(" Unknown");
14216+ }
14217+ printk(" IRQ(s)\n");
14218+}
14219+
14220+
14221+static void
14222+update_link_quality_led(acx_device_t *adev)
14223+{
14224+ int qual;
14225+
14226+ qual = acx_signal_determine_quality(adev->wstats.qual.level, adev->wstats.qual.noise);
14227+ if (qual > adev->brange_max_quality)
14228+ qual = adev->brange_max_quality;
14229+
14230+ if (time_after(jiffies, adev->brange_time_last_state_change +
14231+ (HZ/2 - HZ/2 * (unsigned long)qual / adev->brange_max_quality ) )) {
14232+ acxmem_l_power_led(adev, (adev->brange_last_state == 0));
14233+ adev->brange_last_state ^= 1; /* toggle */
14234+ adev->brange_time_last_state_change = jiffies;
14235+ }
14236+}
14237+
14238+
14239+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */
14240+
14241+static irqreturn_t
14242+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
14243+acxmem_i_interrupt(int irq, void *dev_id)
14244+#else
14245+acxmwm_i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
14246+#endif
14247+{
14248+ acx_device_t *adev;
14249+ unsigned long flags;
14250+ unsigned int irqcount = MAX_IRQLOOPS_PER_JIFFY;
14251+ register u16 irqtype;
14252+ u16 unmasked;
14253+
14254+ adev = ndev2adev((struct net_device*)dev_id);
14255+
14256+ /* LOCKING: can just spin_lock() since IRQs are disabled anyway.
14257+ * I am paranoid */
14258+ acx_lock(adev, flags);
14259+
14260+ unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR);
14261+ if (unlikely(0xffff == unmasked)) {
14262+ /* 0xffff value hints at missing hardware,
14263+ * so don't do anything.
14264+ * Not very clean, but other drivers do the same... */
14265+ log(L_IRQ, "IRQ type:FFFF - device removed? IRQ_NONE\n");
14266+ goto none;
14267+ }
14268+
14269+ /* We will check only "interesting" IRQ types */
14270+ irqtype = unmasked & ~adev->irq_mask;
14271+ if (!irqtype) {
14272+ /* We are on a shared IRQ line and it wasn't our IRQ */
14273+ log(L_IRQ, "IRQ type:%04X, mask:%04X - all are masked, IRQ_NONE\n",
14274+ unmasked, adev->irq_mask);
14275+ goto none;
14276+ }
14277+
14278+ /* Done here because IRQ_NONEs taking three lines of log
14279+ ** drive me crazy */
14280+ FN_ENTER;
14281+
14282+#define IRQ_ITERATE 1
14283+#if IRQ_ITERATE
14284+if (jiffies != adev->irq_last_jiffies) {
14285+ adev->irq_loops_this_jiffy = 0;
14286+ adev->irq_last_jiffies = jiffies;
14287+}
14288+
14289+/* safety condition; we'll normally abort loop below
14290+ * in case no IRQ type occurred */
14291+while (likely(--irqcount)) {
14292+#endif
14293+ /* ACK all IRQs ASAP */
14294+ write_reg16(adev, IO_ACX_IRQ_ACK, 0xffff);
14295+
14296+ log(L_IRQ, "IRQ type:%04X, mask:%04X, type & ~mask:%04X\n",
14297+ unmasked, adev->irq_mask, irqtype);
14298+
14299+ /* Handle most important IRQ types first */
14300+ if (irqtype & HOST_INT_RX_DATA) {
14301+ log(L_IRQ, "got Rx_Data IRQ\n");
14302+ acxmem_l_process_rxdesc(adev);
14303+ }
14304+ if (irqtype & HOST_INT_TX_COMPLETE) {
14305+ log(L_IRQ, "got Tx_Complete IRQ\n");
14306+ /* don't clean up on each Tx complete, wait a bit
14307+ * unless we're going towards full, in which case
14308+ * we do it immediately, too (otherwise we might lockup
14309+ * with a full Tx buffer if we go into
14310+ * acxmem_l_clean_txdesc() at a time when we won't wakeup
14311+ * the net queue in there for some reason...) */
14312+ if (adev->tx_free <= TX_START_CLEAN) {
14313+#if TX_CLEANUP_IN_SOFTIRQ
14314+ acx_schedule_task(adev, ACX_AFTER_IRQ_TX_CLEANUP);
14315+#else
14316+ acxmem_l_clean_txdesc(adev);
14317+#endif
14318+ }
14319+ }
14320+
14321+ /* Less frequent ones */
14322+ if (irqtype & (0
14323+ | HOST_INT_CMD_COMPLETE
14324+ | HOST_INT_INFO
14325+ | HOST_INT_SCAN_COMPLETE
14326+ )) {
14327+ if (irqtype & HOST_INT_CMD_COMPLETE) {
14328+ log(L_IRQ, "got Command_Complete IRQ\n");
14329+ /* save the state for the running issue_cmd() */
14330+ SET_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE);
14331+ }
14332+ if (irqtype & HOST_INT_INFO) {
14333+ handle_info_irq(adev);
14334+ }
14335+ if (irqtype & HOST_INT_SCAN_COMPLETE) {
14336+ log(L_IRQ, "got Scan_Complete IRQ\n");
14337+ /* need to do that in process context */
14338+ acx_schedule_task(adev, ACX_AFTER_IRQ_COMPLETE_SCAN);
14339+ /* remember that fw is not scanning anymore */
14340+ SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
14341+ }
14342+ }
14343+
14344+ /* These we just log, but either they happen rarely
14345+ * or we keep them masked out */
14346+ if (irqtype & (0
14347+ /* | HOST_INT_RX_DATA */
14348+ /* | HOST_INT_TX_COMPLETE */
14349+ | HOST_INT_TX_XFER
14350+ | HOST_INT_RX_COMPLETE
14351+ | HOST_INT_DTIM
14352+ | HOST_INT_BEACON
14353+ | HOST_INT_TIMER
14354+ | HOST_INT_KEY_NOT_FOUND
14355+ | HOST_INT_IV_ICV_FAILURE
14356+ /* | HOST_INT_CMD_COMPLETE */
14357+ /* | HOST_INT_INFO */
14358+ | HOST_INT_OVERFLOW
14359+ | HOST_INT_PROCESS_ERROR
14360+ /* | HOST_INT_SCAN_COMPLETE */
14361+ | HOST_INT_FCS_THRESHOLD
14362+ | HOST_INT_UNKNOWN
14363+ )) {
14364+ log_unusual_irq(irqtype);
14365+ }
14366+
14367+#if IRQ_ITERATE
14368+ unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR);
14369+ irqtype = unmasked & ~adev->irq_mask;
14370+ /* Bail out if no new IRQ bits or if all are masked out */
14371+ if (!irqtype)
14372+ break;
14373+
14374+ if (unlikely(++adev->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) {
14375+ printk(KERN_ERR "acx: too many interrupts per jiffy!\n");
14376+ /* Looks like card floods us with IRQs! Try to stop that */
14377+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
14378+ /* This will short-circuit all future attempts to handle IRQ.
14379+ * We cant do much more... */
14380+ adev->irq_mask = 0;
14381+ break;
14382+ }
14383+}
14384+#endif
14385+ /* Routine to perform blink with range */
14386+ if (unlikely(adev->led_power == 2))
14387+ update_link_quality_led(adev);
14388+
14389+/* handled: */
14390+ /* write_flush(adev); - not needed, last op was read anyway */
14391+ acx_unlock(adev, flags);
14392+ FN_EXIT0;
14393+ return IRQ_HANDLED;
14394+
14395+none:
14396+ acx_unlock(adev, flags);
14397+ return IRQ_NONE;
14398+}
14399+
14400+
14401+/***********************************************************************
14402+** acxmem_l_power_led
14403+*/
14404+void
14405+acxmem_l_power_led(acx_device_t *adev, int enable)
14406+{
14407+ u16 gpio_pled = IS_ACX111(adev) ? 0x0040 : 0x0800;
14408+
14409+ /* A hack. Not moving message rate limiting to adev->xxx
14410+ * (it's only a debug message after all) */
14411+ static int rate_limit = 0;
14412+
14413+ if (rate_limit++ < 3)
14414+ log(L_IOCTL, "Please report in case toggling the power "
14415+ "LED doesn't work for your card!\n");
14416+ if (enable)
14417+ write_reg16(adev, IO_ACX_GPIO_OUT,
14418+ read_reg16(adev, IO_ACX_GPIO_OUT) & ~gpio_pled);
14419+ else
14420+ write_reg16(adev, IO_ACX_GPIO_OUT,
14421+ read_reg16(adev, IO_ACX_GPIO_OUT) | gpio_pled);
14422+}
14423+
14424+
14425+/***********************************************************************
14426+** Ioctls
14427+*/
14428+
14429+/***********************************************************************
14430+*/
14431+int
14432+acx111pci_ioctl_info(
14433+ struct net_device *ndev,
14434+ struct iw_request_info *info,
14435+ struct iw_param *vwrq,
14436+ char *extra)
14437+{
14438+#if ACX_DEBUG > 1
14439+ acx_device_t *adev = ndev2adev(ndev);
14440+ rxdesc_t *rxdesc;
14441+ txdesc_t *txdesc;
14442+ rxhostdesc_t *rxhostdesc;
14443+ txhostdesc_t *txhostdesc;
14444+ struct acx111_ie_memoryconfig memconf;
14445+ struct acx111_ie_queueconfig queueconf;
14446+ unsigned long flags;
14447+ int i;
14448+ char memmap[0x34];
14449+ char rxconfig[0x8];
14450+ char fcserror[0x8];
14451+ char ratefallback[0x5];
14452+
14453+ if ( !(acx_debug & (L_IOCTL|L_DEBUG)) )
14454+ return OK;
14455+ /* using printk() since we checked debug flag already */
14456+
14457+ acx_sem_lock(adev);
14458+
14459+ if (!IS_ACX111(adev)) {
14460+ printk("acx111-specific function called "
14461+ "with non-acx111 chip, aborting\n");
14462+ goto end_ok;
14463+ }
14464+
14465+ /* get Acx111 Memory Configuration */
14466+ memset(&memconf, 0, sizeof(memconf));
14467+ /* BTW, fails with 12 (Write only) error code.
14468+ ** Retained for easy testing of issue_cmd error handling :) */
14469+ printk ("Interrogating queue config\n");
14470+ acx_s_interrogate(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG);
14471+ printk ("done with queue config\n");
14472+
14473+ /* get Acx111 Queue Configuration */
14474+ memset(&queueconf, 0, sizeof(queueconf));
14475+ printk ("Interrogating mem config options\n");
14476+ acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
14477+ printk ("done with mem config options\n");
14478+
14479+ /* get Acx111 Memory Map */
14480+ memset(memmap, 0, sizeof(memmap));
14481+ printk ("Interrogating mem map\n");
14482+ acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP);
14483+ printk ("done with mem map\n");
14484+
14485+ /* get Acx111 Rx Config */
14486+ memset(rxconfig, 0, sizeof(rxconfig));
14487+ printk ("Interrogating rxconfig\n");
14488+ acx_s_interrogate(adev, &rxconfig, ACX1xx_IE_RXCONFIG);
14489+ printk ("done with queue rxconfig\n");
14490+
14491+ /* get Acx111 fcs error count */
14492+ memset(fcserror, 0, sizeof(fcserror));
14493+ printk ("Interrogating fcs err count\n");
14494+ acx_s_interrogate(adev, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT);
14495+ printk ("done with err count\n");
14496+
14497+ /* get Acx111 rate fallback */
14498+ memset(ratefallback, 0, sizeof(ratefallback));
14499+ printk ("Interrogating rate fallback\n");
14500+ acx_s_interrogate(adev, &ratefallback, ACX1xx_IE_RATE_FALLBACK);
14501+ printk ("done with rate fallback\n");
14502+
14503+ /* force occurrence of a beacon interrupt */
14504+ /* TODO: comment why is this necessary */
14505+ write_reg16(adev, IO_ACX_HINT_TRIG, HOST_INT_BEACON);
14506+
14507+ /* dump Acx111 Mem Configuration */
14508+ printk("dump mem config:\n"
14509+ "data read: %d, struct size: %d\n"
14510+ "Number of stations: %1X\n"
14511+ "Memory block size: %1X\n"
14512+ "tx/rx memory block allocation: %1X\n"
14513+ "count rx: %X / tx: %X queues\n"
14514+ "options %1X\n"
14515+ "fragmentation %1X\n"
14516+ "Rx Queue 1 Count Descriptors: %X\n"
14517+ "Rx Queue 1 Host Memory Start: %X\n"
14518+ "Tx Queue 1 Count Descriptors: %X\n"
14519+ "Tx Queue 1 Attributes: %X\n",
14520+ memconf.len, (int) sizeof(memconf),
14521+ memconf.no_of_stations,
14522+ memconf.memory_block_size,
14523+ memconf.tx_rx_memory_block_allocation,
14524+ memconf.count_rx_queues, memconf.count_tx_queues,
14525+ memconf.options,
14526+ memconf.fragmentation,
14527+ memconf.rx_queue1_count_descs,
14528+ acx2cpu(memconf.rx_queue1_host_rx_start),
14529+ memconf.tx_queue1_count_descs,
14530+ memconf.tx_queue1_attributes);
14531+
14532+ /* dump Acx111 Queue Configuration */
14533+ printk("dump queue head:\n"
14534+ "data read: %d, struct size: %d\n"
14535+ "tx_memory_block_address (from card): %X\n"
14536+ "rx_memory_block_address (from card): %X\n"
14537+ "rx1_queue address (from card): %X\n"
14538+ "tx1_queue address (from card): %X\n"
14539+ "tx1_queue attributes (from card): %X\n",
14540+ queueconf.len, (int) sizeof(queueconf),
14541+ queueconf.tx_memory_block_address,
14542+ queueconf.rx_memory_block_address,
14543+ queueconf.rx1_queue_address,
14544+ queueconf.tx1_queue_address,
14545+ queueconf.tx1_attributes);
14546+
14547+ /* dump Acx111 Mem Map */
14548+ printk("dump mem map:\n"
14549+ "data read: %d, struct size: %d\n"
14550+ "Code start: %X\n"
14551+ "Code end: %X\n"
14552+ "WEP default key start: %X\n"
14553+ "WEP default key end: %X\n"
14554+ "STA table start: %X\n"
14555+ "STA table end: %X\n"
14556+ "Packet template start: %X\n"
14557+ "Packet template end: %X\n"
14558+ "Queue memory start: %X\n"
14559+ "Queue memory end: %X\n"
14560+ "Packet memory pool start: %X\n"
14561+ "Packet memory pool end: %X\n"
14562+ "iobase: %p\n"
14563+ "iobase2: %p\n",
14564+ *((u16 *)&memmap[0x02]), (int) sizeof(memmap),
14565+ *((u32 *)&memmap[0x04]),
14566+ *((u32 *)&memmap[0x08]),
14567+ *((u32 *)&memmap[0x0C]),
14568+ *((u32 *)&memmap[0x10]),
14569+ *((u32 *)&memmap[0x14]),
14570+ *((u32 *)&memmap[0x18]),
14571+ *((u32 *)&memmap[0x1C]),
14572+ *((u32 *)&memmap[0x20]),
14573+ *((u32 *)&memmap[0x24]),
14574+ *((u32 *)&memmap[0x28]),
14575+ *((u32 *)&memmap[0x2C]),
14576+ *((u32 *)&memmap[0x30]),
14577+ adev->iobase,
14578+ adev->iobase2);
14579+
14580+ /* dump Acx111 Rx Config */
14581+ printk("dump rx config:\n"
14582+ "data read: %d, struct size: %d\n"
14583+ "rx config: %X\n"
14584+ "rx filter config: %X\n",
14585+ *((u16 *)&rxconfig[0x02]), (int) sizeof(rxconfig),
14586+ *((u16 *)&rxconfig[0x04]),
14587+ *((u16 *)&rxconfig[0x06]));
14588+
14589+ /* dump Acx111 fcs error */
14590+ printk("dump fcserror:\n"
14591+ "data read: %d, struct size: %d\n"
14592+ "fcserrors: %X\n",
14593+ *((u16 *)&fcserror[0x02]), (int) sizeof(fcserror),
14594+ *((u32 *)&fcserror[0x04]));
14595+
14596+ /* dump Acx111 rate fallback */
14597+ printk("dump rate fallback:\n"
14598+ "data read: %d, struct size: %d\n"
14599+ "ratefallback: %X\n",
14600+ *((u16 *)&ratefallback[0x02]), (int) sizeof(ratefallback),
14601+ *((u8 *)&ratefallback[0x04]));
14602+
14603+ /* protect against IRQ */
14604+ acx_lock(adev, flags);
14605+
14606+ /* dump acx111 internal rx descriptor ring buffer */
14607+ rxdesc = adev->rxdesc_start;
14608+
14609+ /* loop over complete receive pool */
14610+ if (rxdesc) for (i = 0; i < RX_CNT; i++) {
14611+ printk("\ndump internal rxdesc %d:\n"
14612+ "mem pos %p\n"
14613+ "next 0x%X\n"
14614+ "acx mem pointer (dynamic) 0x%X\n"
14615+ "CTL (dynamic) 0x%X\n"
14616+ "Rate (dynamic) 0x%X\n"
14617+ "RxStatus (dynamic) 0x%X\n"
14618+ "Mod/Pre (dynamic) 0x%X\n",
14619+ i,
14620+ rxdesc,
14621+ acx2cpu(rxdesc->pNextDesc),
14622+ acx2cpu(rxdesc->ACXMemPtr),
14623+ rxdesc->Ctl_8,
14624+ rxdesc->rate,
14625+ rxdesc->error,
14626+ rxdesc->SNR);
14627+ rxdesc++;
14628+ }
14629+
14630+ /* dump host rx descriptor ring buffer */
14631+
14632+ rxhostdesc = adev->rxhostdesc_start;
14633+
14634+ /* loop over complete receive pool */
14635+ if (rxhostdesc) for (i = 0; i < RX_CNT; i++) {
14636+ printk("\ndump host rxdesc %d:\n"
14637+ "mem pos %p\n"
14638+ "buffer mem pos 0x%X\n"
14639+ "buffer mem offset 0x%X\n"
14640+ "CTL 0x%X\n"
14641+ "Length 0x%X\n"
14642+ "next 0x%X\n"
14643+ "Status 0x%X\n",
14644+ i,
14645+ rxhostdesc,
14646+ acx2cpu(rxhostdesc->data_phy),
14647+ rxhostdesc->data_offset,
14648+ le16_to_cpu(rxhostdesc->Ctl_16),
14649+ le16_to_cpu(rxhostdesc->length),
14650+ acx2cpu(rxhostdesc->desc_phy_next),
14651+ rxhostdesc->Status);
14652+ rxhostdesc++;
14653+ }
14654+
14655+ /* dump acx111 internal tx descriptor ring buffer */
14656+ txdesc = adev->txdesc_start;
14657+
14658+ /* loop over complete transmit pool */
14659+ if (txdesc) for (i = 0; i < TX_CNT; i++) {
14660+ printk("\ndump internal txdesc %d:\n"
14661+ "size 0x%X\n"
14662+ "mem pos %p\n"
14663+ "next 0x%X\n"
14664+ "acx mem pointer (dynamic) 0x%X\n"
14665+ "host mem pointer (dynamic) 0x%X\n"
14666+ "length (dynamic) 0x%X\n"
14667+ "CTL (dynamic) 0x%X\n"
14668+ "CTL2 (dynamic) 0x%X\n"
14669+ "Status (dynamic) 0x%X\n"
14670+ "Rate (dynamic) 0x%X\n",
14671+ i,
14672+ (int) sizeof(struct txdesc),
14673+ txdesc,
14674+ acx2cpu(txdesc->pNextDesc),
14675+ acx2cpu(txdesc->AcxMemPtr),
14676+ acx2cpu(txdesc->HostMemPtr),
14677+ le16_to_cpu(txdesc->total_length),
14678+ txdesc->Ctl_8,
14679+ txdesc->Ctl2_8, txdesc->error,
14680+ txdesc->u.r1.rate);
14681+ txdesc = advance_txdesc(adev, txdesc, 1);
14682+ }
14683+
14684+ /* dump host tx descriptor ring buffer */
14685+
14686+ txhostdesc = adev->txhostdesc_start;
14687+
14688+ /* loop over complete host send pool */
14689+ if (txhostdesc) for (i = 0; i < TX_CNT * 2; i++) {
14690+ printk("\ndump host txdesc %d:\n"
14691+ "mem pos %p\n"
14692+ "buffer mem pos 0x%X\n"
14693+ "buffer mem offset 0x%X\n"
14694+ "CTL 0x%X\n"
14695+ "Length 0x%X\n"
14696+ "next 0x%X\n"
14697+ "Status 0x%X\n",
14698+ i,
14699+ txhostdesc,
14700+ acx2cpu(txhostdesc->data_phy),
14701+ txhostdesc->data_offset,
14702+ le16_to_cpu(txhostdesc->Ctl_16),
14703+ le16_to_cpu(txhostdesc->length),
14704+ acx2cpu(txhostdesc->desc_phy_next),
14705+ le32_to_cpu(txhostdesc->Status));
14706+ txhostdesc++;
14707+ }
14708+
14709+ /* write_reg16(adev, 0xb4, 0x4); */
14710+
14711+ acx_unlock(adev, flags);
14712+end_ok:
14713+
14714+ acx_sem_unlock(adev);
14715+#endif /* ACX_DEBUG */
14716+ return OK;
14717+}
14718+
14719+
14720+/***********************************************************************
14721+*/
14722+int
14723+acx100mem_ioctl_set_phy_amp_bias(
14724+ struct net_device *ndev,
14725+ struct iw_request_info *info,
14726+ struct iw_param *vwrq,
14727+ char *extra)
14728+{
14729+ acx_device_t *adev = ndev2adev(ndev);
14730+ unsigned long flags;
14731+ u16 gpio_old;
14732+
14733+ if (!IS_ACX100(adev)) {
14734+ /* WARNING!!!
14735+ * Removing this check *might* damage
14736+ * hardware, since we're tweaking GPIOs here after all!!!
14737+ * You've been warned...
14738+ * WARNING!!! */
14739+ printk("acx: sorry, setting bias level for non-acx100 "
14740+ "is not supported yet\n");
14741+ return OK;
14742+ }
14743+
14744+ if (*extra > 7) {
14745+ printk("acx: invalid bias parameter, range is 0-7\n");
14746+ return -EINVAL;
14747+ }
14748+
14749+ acx_sem_lock(adev);
14750+
14751+ /* Need to lock accesses to [IO_ACX_GPIO_OUT]:
14752+ * IRQ handler uses it to update LED */
14753+ acx_lock(adev, flags);
14754+ gpio_old = read_reg16(adev, IO_ACX_GPIO_OUT);
14755+ write_reg16(adev, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8));
14756+ acx_unlock(adev, flags);
14757+
14758+ log(L_DEBUG, "gpio_old: 0x%04X\n", gpio_old);
14759+ printk("%s: PHY power amplifier bias: old:%d, new:%d\n",
14760+ ndev->name,
14761+ (gpio_old & 0x0700) >> 8, (unsigned char)*extra);
14762+
14763+ acx_sem_unlock(adev);
14764+
14765+ return OK;
14766+}
14767+
14768+/***************************************************************
14769+** acxmem_l_alloc_tx
14770+** Actually returns a txdesc_t* ptr
14771+**
14772+** FIXME: in case of fragments, should allocate multiple descrs
14773+** after figuring out how many we need and whether we still have
14774+** sufficiently many.
14775+*/
14776+tx_t*
14777+acxmem_l_alloc_tx(acx_device_t *adev)
14778+{
14779+ struct txdesc *txdesc;
14780+ unsigned head;
14781+ u8 ctl8;
14782+ static int txattempts = 0;
14783+
14784+ FN_ENTER;
14785+
14786+ if (unlikely(!adev->tx_free)) {
14787+ printk("acx: BUG: no free txdesc left\n");
14788+ /*
14789+ * Probably the ACX ignored a transmit attempt and now there's a packet
14790+ * sitting in the queue we think should be transmitting but the ACX doesn't
14791+ * know about.
14792+ * On the first pass, send the ACX a TxProc interrupt to try moving
14793+ * things along, and if that doesn't work (ie, we get called again) completely
14794+ * flush the transmit queue.
14795+ */
14796+ if (txattempts < 10) {
14797+ txattempts++;
14798+ printk ("acx: trying to wake up ACX\n");
14799+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC);
14800+ write_flush(adev); }
14801+ else {
14802+ txattempts = 0;
14803+ printk ("acx: flushing transmit queue.\n");
14804+ acxmem_l_clean_txdesc_emergency (adev);
14805+ }
14806+ txdesc = NULL;
14807+ goto end;
14808+ }
14809+
14810+ /*
14811+ * Make a quick check to see if there is transmit buffer space on
14812+ * the ACX. This can't guarantee there is enough space for the packet
14813+ * since we don't yet know how big it is, but it will prevent at least some
14814+ * annoyances.
14815+ */
14816+ if (!adev->acx_txbuf_blocks_free) {
14817+ txdesc = NULL;
14818+ goto end;
14819+ }
14820+
14821+ head = adev->tx_head;
14822+ /*
14823+ * txdesc points to ACX memory
14824+ */
14825+ txdesc = get_txdesc(adev, head);
14826+ ctl8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
14827+
14828+ /*
14829+ * If we don't own the buffer (HOSTOWN) it is certainly not free; however,
14830+ * we may have previously thought we had enough memory to send
14831+ * a packet, allocated the buffer then gave up when we found not enough
14832+ * transmit buffer space on the ACX. In that case, HOSTOWN and
14833+ * ACXDONE will both be set.
14834+ */
14835+ if (unlikely(DESC_CTL_HOSTOWN != (ctl8 & DESC_CTL_HOSTOWN))) {
14836+ /* whoops, descr at current index is not free, so probably
14837+ * ring buffer already full */
14838+ printk("acx: BUG: tx_head:%d Ctl8:0x%02X - failed to find "
14839+ "free txdesc\n", head, ctl8);
14840+ txdesc = NULL;
14841+ goto end;
14842+ }
14843+
14844+ /* Needed in case txdesc won't be eventually submitted for tx */
14845+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), DESC_CTL_ACXDONE_HOSTOWN);
14846+
14847+ adev->tx_free--;
14848+ log(L_BUFT, "tx: got desc %u, %u remain\n",
14849+ head, adev->tx_free);
14850+ /* Keep a few free descs between head and tail of tx ring.
14851+ ** It is not absolutely needed, just feels safer */
14852+ if (adev->tx_free < TX_STOP_QUEUE) {
14853+ log(L_BUF, "stop queue (%u tx desc left)\n",
14854+ adev->tx_free);
14855+ acx_stop_queue(adev->ndev, NULL);
14856+ }
14857+
14858+ /* returning current descriptor, so advance to next free one */
14859+ adev->tx_head = (head + 1) % TX_CNT;
14860+end:
14861+ FN_EXIT0;
14862+
14863+ return (tx_t*)txdesc;
14864+}
14865+
14866+
14867+/***************************************************************
14868+** acxmem_l_dealloc_tx
14869+** Clears out a previously allocatedvoid acxmem_l_dealloc_tx(tx_t *tx_opaque);
14870+ transmit descriptor. The ACX
14871+** can get confused if we skip transmit descriptors in the queue,
14872+** so when we don't need a descriptor return it to its original
14873+** state and move the queue head pointer back.
14874+**
14875+*/
14876+void
14877+acxmem_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque)
14878+{
14879+ /*
14880+ * txdesc is the address of the descriptor on the ACX.
14881+ */
14882+ txdesc_t *txdesc = (txdesc_t*)tx_opaque;
14883+ txdesc_t tmptxdesc;
14884+ int index;
14885+
14886+ memset (&tmptxdesc, 0, sizeof(tmptxdesc));
14887+ tmptxdesc.Ctl_8 = DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG;
14888+ tmptxdesc.u.r1.rate = 0x0a;
14889+
14890+ /*
14891+ * Clear out all of the transmit descriptor except for the next pointer
14892+ */
14893+ copy_to_slavemem (adev, (u32) &(txdesc->HostMemPtr),
14894+ (u8 *) &(tmptxdesc.HostMemPtr),
14895+ sizeof (tmptxdesc) - sizeof(tmptxdesc.pNextDesc));
14896+
14897+ /*
14898+ * This is only called immediately after we've allocated, so we should
14899+ * be able to set the head back to this descriptor.
14900+ */
14901+ index = ((u8*) txdesc - (u8*)adev->txdesc_start) / adev->txdesc_size;
14902+ printk ("acx_dealloc: moving head from %d to %d\n", adev->tx_head, index);
14903+ adev->tx_head = index;
14904+}
14905+
14906+
14907+/***********************************************************************
14908+*/
14909+void*
14910+acxmem_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque)
14911+{
14912+ return get_txhostdesc(adev, (txdesc_t*)tx_opaque)->data;
14913+}
14914+
14915+
14916+/***********************************************************************
14917+** acxmem_l_tx_data
14918+**
14919+** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx).
14920+** Can be called from acx_i_start_xmit (data frames from net core).
14921+**
14922+** FIXME: in case of fragments, should loop over the number of
14923+** pre-allocated tx descrs, properly setting up transfer data and
14924+** CTL_xxx flags according to fragment number.
14925+*/
14926+void
14927+acxmem_update_queue_indicator (acx_device_t *adev, int txqueue)
14928+{
14929+#ifdef USING_MORE_THAN_ONE_TRANSMIT_QUEUE
14930+ u32 indicator;
14931+ unsigned long flags;
14932+ int count;
14933+
14934+ /*
14935+ * Can't handle an interrupt while we're fiddling with the ACX's lock,
14936+ * according to TI. The ACX is supposed to hold fw_lock for at most
14937+ * 500ns.
14938+ */
14939+ local_irq_save (flags);
14940+
14941+ /*
14942+ * Wait for ACX to release the lock (at most 500ns).
14943+ */
14944+ count = 0;
14945+ while (read_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->fw_lock))
14946+ && (count++ < 50)) {
14947+ ndelay (10);
14948+ }
14949+ if (count < 50) {
14950+
14951+ /*
14952+ * Take out the host lock - anything non-zero will work, so don't worry about
14953+ * be/le
14954+ */
14955+ write_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->host_lock), 1);
14956+
14957+ /*
14958+ * Avoid a race condition
14959+ */
14960+ count = 0;
14961+ while (read_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->fw_lock))
14962+ && (count++ < 50)) {
14963+ ndelay (10);
14964+ }
14965+
14966+ if (count < 50) {
14967+ /*
14968+ * Mark the queue active
14969+ */
14970+ indicator = read_slavemem32 (adev, (u32) &(adev->acx_queue_indicator->indicator));
14971+ indicator |= cpu_to_le32 (1 << txqueue);
14972+ write_slavemem32 (adev, (u32) &(adev->acx_queue_indicator->indicator), indicator);
14973+ }
14974+
14975+ /*
14976+ * Release the host lock
14977+ */
14978+ write_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->host_lock), 0);
14979+
14980+ }
14981+
14982+ /*
14983+ * Restore interrupts
14984+ */
14985+ local_irq_restore (flags);
14986+#endif
14987+}
14988+
14989+void
14990+acxmem_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int len)
14991+{
14992+ /*
14993+ * txdesc is the address on the ACX
14994+ */
14995+ txdesc_t *txdesc = (txdesc_t*)tx_opaque;
14996+ txhostdesc_t *hostdesc1, *hostdesc2;
14997+ client_t *clt;
14998+ u16 rate_cur;
14999+ u8 Ctl_8, Ctl2_8;
15000+ u32 addr;
15001+
15002+ FN_ENTER;
15003+ /* fw doesn't tx such packets anyhow */
15004+ if (unlikely(len < WLAN_HDR_A3_LEN))
15005+ goto end;
15006+
15007+ hostdesc1 = get_txhostdesc(adev, txdesc);
15008+ /* modify flag status in separate variable to be able to write it back
15009+ * in one big swoop later (also in order to have less device memory
15010+ * accesses) */
15011+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
15012+ Ctl2_8 = 0; /* really need to init it to 0, not txdesc->Ctl2_8, it seems */
15013+
15014+ hostdesc2 = hostdesc1 + 1;
15015+
15016+ /* DON'T simply set Ctl field to 0 here globally,
15017+ * it needs to maintain a consistent flag status (those are state flags!!),
15018+ * otherwise it may lead to severe disruption. Only set or reset particular
15019+ * flags at the exact moment this is needed... */
15020+
15021+ /* let chip do RTS/CTS handshaking before sending
15022+ * in case packet size exceeds threshold */
15023+ if (len > adev->rts_threshold)
15024+ SET_BIT(Ctl2_8, DESC_CTL2_RTS);
15025+ else
15026+ CLEAR_BIT(Ctl2_8, DESC_CTL2_RTS);
15027+
15028+ switch (adev->mode) {
15029+ case ACX_MODE_0_ADHOC:
15030+ case ACX_MODE_3_AP:
15031+ clt = acx_l_sta_list_get(adev, ((wlan_hdr_t*)hostdesc1->data)->a1);
15032+ break;
15033+ case ACX_MODE_2_STA:
15034+ clt = adev->ap_client;
15035+ break;
15036+#if 0
15037+/* testing was done on acx111: */
15038+ case ACX_MODE_MONITOR:
15039+ SET_BIT(Ctl2_8, 0
15040+/* sends CTS to self before packet */
15041+ + DESC_CTL2_SEQ /* don't increase sequence field */
15042+/* not working (looks like good fcs is still added) */
15043+ + DESC_CTL2_FCS /* don't add the FCS */
15044+/* not tested */
15045+ + DESC_CTL2_MORE_FRAG
15046+/* not tested */
15047+ + DESC_CTL2_RETRY /* don't increase retry field */
15048+/* not tested */
15049+ + DESC_CTL2_POWER /* don't increase power mgmt. field */
15050+/* no effect */
15051+ + DESC_CTL2_WEP /* encrypt this frame */
15052+/* not tested */
15053+ + DESC_CTL2_DUR /* don't increase duration field */
15054+ );
15055+ /* fallthrough */
15056+#endif
15057+ default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */
15058+ clt = NULL;
15059+ break;
15060+ }
15061+
15062+ rate_cur = clt ? clt->rate_cur : adev->rate_bcast;
15063+ if (unlikely(!rate_cur)) {
15064+ printk("acx: driver bug! bad ratemask\n");
15065+ goto end;
15066+ }
15067+
15068+ /* used in tx cleanup routine for auto rate and accounting: */
15069+ put_txcr(adev, txdesc, clt, rate_cur);
15070+
15071+ write_slavemem16 (adev, (u32) &(txdesc->total_length), cpu_to_le16(len));
15072+ hostdesc2->length = cpu_to_le16(len - WLAN_HDR_A3_LEN);
15073+ if (IS_ACX111(adev)) {
15074+ /* note that if !txdesc->do_auto, txrate->cur
15075+ ** has only one nonzero bit */
15076+ txdesc->u.r2.rate111 = cpu_to_le16(
15077+ rate_cur
15078+ /* WARNING: I was never able to make it work with prism54 AP.
15079+ ** It was falling down to 1Mbit where shortpre is not applicable,
15080+ ** and not working at all at "5,11 basic rates only" setting.
15081+ ** I even didn't see tx packets in radio packet capture.
15082+ ** Disabled for now --vda */
15083+ /*| ((clt->shortpre && clt->cur!=RATE111_1) ? RATE111_SHORTPRE : 0) */
15084+ );
15085+#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS
15086+ /* should add this to rate111 above as necessary */
15087+ | (clt->pbcc511 ? RATE111_PBCC511 : 0)
15088+#endif
15089+ hostdesc1->length = cpu_to_le16(len);
15090+ } else { /* ACX100 */
15091+ u8 rate_100 = clt ? clt->rate_100 : adev->rate_bcast100;
15092+ write_slavemem8 (adev, (u32) &(txdesc->u.r1.rate), rate_100);
15093+#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS
15094+ if (clt->pbcc511) {
15095+ if (n == RATE100_5 || n == RATE100_11)
15096+ n |= RATE100_PBCC511;
15097+ }
15098+
15099+ if (clt->shortpre && (clt->cur != RATE111_1))
15100+ SET_BIT(Ctl_8, DESC_CTL_SHORT_PREAMBLE); /* set Short Preamble */
15101+#endif
15102+ /* set autodma and reclaim and 1st mpdu */
15103+ SET_BIT(Ctl_8, DESC_CTL_FIRSTFRAG);
15104+
15105+#if ACX_FRAGMENTATION
15106+ /* SET_BIT(Ctl2_8, DESC_CTL2_MORE_FRAG); cannot set it unconditionally, needs to be set for all non-last fragments */
15107+#endif
15108+ hostdesc1->length = cpu_to_le16(WLAN_HDR_A3_LEN);
15109+
15110+ /*
15111+ * Since we're not using autodma copy the packet data to the acx now.
15112+ * Even host descriptors point to the packet header, and the odd indexed
15113+ * descriptor following points to the packet data.
15114+ *
15115+ * The first step is to find free memory in the ACX transmit buffers.
15116+ * They don't necessarily map one to one with the transmit queue entries,
15117+ * so search through them starting just after the last one used.
15118+ */
15119+ addr = allocate_acx_txbuf_space (adev, len);
15120+ if (addr) {
15121+ chaincopy_to_slavemem (adev, addr, hostdesc1->data, len);
15122+ }
15123+ else {
15124+ /*
15125+ * Bummer. We thought we might have enough room in the transmit
15126+ * buffers to send this packet, but it turns out we don't. alloc_tx
15127+ * has already marked this transmit descriptor as HOSTOWN and ACXDONE,
15128+ * which means the ACX will hang when it gets to this descriptor unless
15129+ * we do something about it. Having a bubble in the transmit queue just
15130+ * doesn't seem to work, so we have to reset this transmit queue entry's
15131+ * state to its original value and back up our head pointer to point
15132+ * back to this entry.
15133+ */
15134+ hostdesc1->length = 0;
15135+ hostdesc2->length = 0;
15136+ write_slavemem16 (adev, (u32) &(txdesc->total_length), 0);
15137+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG);
15138+ adev->tx_head = ((u8*) txdesc - (u8*) adev->txdesc_start) / adev->txdesc_size;
15139+ goto end;
15140+ }
15141+ /*
15142+ * Tell the ACX where the packet is.
15143+ */
15144+ write_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr), addr);
15145+
15146+ }
15147+ /* don't need to clean ack/rts statistics here, already
15148+ * done on descr cleanup */
15149+
15150+ /* clears HOSTOWN and ACXDONE bits, thus telling that the descriptors
15151+ * are now owned by the acx100; do this as LAST operation */
15152+ CLEAR_BIT(Ctl_8, DESC_CTL_ACXDONE_HOSTOWN);
15153+ /* flush writes before we release hostdesc to the adapter here */
15154+ //wmb();
15155+
15156+ /* write back modified flags */
15157+ /*
15158+ * At this point Ctl_8 should just be FIRSTFRAG
15159+ */
15160+ write_slavemem8 (adev, (u32) &(txdesc->Ctl2_8),Ctl2_8);
15161+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), Ctl_8);
15162+ /* unused: txdesc->tx_time = cpu_to_le32(jiffies); */
15163+
15164+ /*
15165+ * Update the queue indicator to say there's data on the first queue.
15166+ */
15167+ acxmem_update_queue_indicator (adev, 0);
15168+
15169+ /* flush writes before we tell the adapter that it's its turn now */
15170+ mmiowb();
15171+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC);
15172+ write_flush(adev);
15173+
15174+ /* log the packet content AFTER sending it,
15175+ * in order to not delay sending any further than absolutely needed
15176+ * Do separate logs for acx100/111 to have human-readable rates */
15177+ if (unlikely(acx_debug & (L_XFER|L_DATA))) {
15178+ u16 fc = ((wlan_hdr_t*)hostdesc1->data)->fc;
15179+ if (IS_ACX111(adev))
15180+ printk("tx: pkt (%s): len %d "
15181+ "rate %04X%s status %u\n",
15182+ acx_get_packet_type_string(le16_to_cpu(fc)), len,
15183+ le16_to_cpu(txdesc->u.r2.rate111),
15184+ (le16_to_cpu(txdesc->u.r2.rate111) & RATE111_SHORTPRE) ? "(SPr)" : "",
15185+ adev->status);
15186+ else
15187+ printk("tx: pkt (%s): len %d rate %03u%s status %u\n",
15188+ acx_get_packet_type_string(fc), len,
15189+ read_slavemem8 (adev, (u32) &(txdesc->u.r1.rate)),
15190+ (Ctl_8 & DESC_CTL_SHORT_PREAMBLE) ? "(SPr)" : "",
15191+ adev->status);
15192+
15193+ if (acx_debug & L_DATA) {
15194+ printk("tx: 802.11 [%d]: ", len);
15195+ acx_dump_bytes(hostdesc1->data, len);
15196+ }
15197+ }
15198+end:
15199+ FN_EXIT0;
15200+}
15201+
15202+
15203+/***********************************************************************
15204+** acxmem_l_clean_txdesc
15205+**
15206+** This function resets the txdescs' status when the ACX100
15207+** signals the TX done IRQ (txdescs have been processed), starting with
15208+** the pool index of the descriptor which we would use next,
15209+** in order to make sure that we can be as fast as possible
15210+** in filling new txdescs.
15211+** Everytime we get called we know where the next packet to be cleaned is.
15212+*/
15213+
15214+#if !ACX_DEBUG
15215+static inline void log_txbuffer(const acx_device_t *adev) {}
15216+#else
15217+static void
15218+log_txbuffer(acx_device_t *adev)
15219+{
15220+ txdesc_t *txdesc;
15221+ int i;
15222+ u8 Ctl_8;
15223+
15224+ /* no FN_ENTER here, we don't want that */
15225+ /* no locks here, since it's entirely non-critical code */
15226+ txdesc = adev->txdesc_start;
15227+ if (unlikely(!txdesc)) return;
15228+ printk("tx: desc->Ctl8's:");
15229+ for (i = 0; i < TX_CNT; i++) {
15230+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
15231+ printk(" %02X", Ctl_8);
15232+ txdesc = advance_txdesc(adev, txdesc, 1);
15233+ }
15234+ printk("\n");
15235+}
15236+#endif
15237+
15238+
15239+static void
15240+handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger)
15241+{
15242+ const char *err = "unknown error";
15243+
15244+ /* hmm, should we handle this as a mask
15245+ * of *several* bits?
15246+ * For now I think only caring about
15247+ * individual bits is ok... */
15248+ switch (error) {
15249+ case 0x01:
15250+ err = "no Tx due to error in other fragment";
15251+ adev->wstats.discard.fragment++;
15252+ break;
15253+ case 0x02:
15254+ err = "Tx aborted";
15255+ adev->stats.tx_aborted_errors++;
15256+ break;
15257+ case 0x04:
15258+ err = "Tx desc wrong parameters";
15259+ adev->wstats.discard.misc++;
15260+ break;
15261+ case 0x08:
15262+ err = "WEP key not found";
15263+ adev->wstats.discard.misc++;
15264+ break;
15265+ case 0x10:
15266+ err = "MSDU lifetime timeout? - try changing "
15267+ "'iwconfig retry lifetime XXX'";
15268+ adev->wstats.discard.misc++;
15269+ break;
15270+ case 0x20:
15271+ err = "excessive Tx retries due to either distance "
15272+ "too high or unable to Tx or Tx frame error - "
15273+ "try changing 'iwconfig txpower XXX' or "
15274+ "'sens'itivity or 'retry'";
15275+ adev->wstats.discard.retries++;
15276+ /* Tx error 0x20 also seems to occur on
15277+ * overheating, so I'm not sure whether we
15278+ * actually want to do aggressive radio recalibration,
15279+ * since people maybe won't notice then that their hardware
15280+ * is slowly getting cooked...
15281+ * Or is it still a safe long distance from utter
15282+ * radio non-functionality despite many radio recalibs
15283+ * to final destructive overheating of the hardware?
15284+ * In this case we really should do recalib here...
15285+ * I guess the only way to find out is to do a
15286+ * potentially fatal self-experiment :-\
15287+ * Or maybe only recalib in case we're using Tx
15288+ * rate auto (on errors switching to lower speed
15289+ * --> less heat?) or 802.11 power save mode?
15290+ *
15291+ * ok, just do it. */
15292+ if (++adev->retry_errors_msg_ratelimit % 4 == 0) {
15293+ if (adev->retry_errors_msg_ratelimit <= 20) {
15294+ printk("%s: several excessive Tx "
15295+ "retry errors occurred, attempting "
15296+ "to recalibrate radio. Radio "
15297+ "drift might be caused by increasing "
15298+ "card temperature, please check the card "
15299+ "before it's too late!\n",
15300+ adev->ndev->name);
15301+ if (adev->retry_errors_msg_ratelimit == 20)
15302+ printk("disabling above message\n");
15303+ }
15304+
15305+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
15306+ }
15307+ break;
15308+ case 0x40:
15309+ err = "Tx buffer overflow";
15310+ adev->stats.tx_fifo_errors++;
15311+ break;
15312+ case 0x80:
15313+ err = "DMA error";
15314+ adev->wstats.discard.misc++;
15315+ break;
15316+ }
15317+ adev->stats.tx_errors++;
15318+ if (adev->stats.tx_errors <= 20)
15319+ printk("%s: tx error 0x%02X, buf %02u! (%s)\n",
15320+ adev->ndev->name, error, finger, err);
15321+ else
15322+ printk("%s: tx error 0x%02X, buf %02u!\n",
15323+ adev->ndev->name, error, finger);
15324+}
15325+
15326+
15327+unsigned int
15328+acxmem_l_clean_txdesc(acx_device_t *adev)
15329+{
15330+ txdesc_t *txdesc;
15331+ unsigned finger;
15332+ int num_cleaned;
15333+ u16 r111;
15334+ u8 error, ack_failures, rts_failures, rts_ok, r100, Ctl_8;
15335+ u32 acxmem;
15336+ txdesc_t tmptxdesc;
15337+
15338+ FN_ENTER;
15339+
15340+ /*
15341+ * Set up a template descriptor for re-initialization. The only
15342+ * things that get set are Ctl_8 and the rate, and the rate defaults
15343+ * to 1Mbps.
15344+ */
15345+ memset (&tmptxdesc, 0, sizeof (tmptxdesc));
15346+ tmptxdesc.Ctl_8 = DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG;
15347+ tmptxdesc.u.r1.rate = 0x0a;
15348+
15349+ if (unlikely(acx_debug & L_DEBUG))
15350+ log_txbuffer(adev);
15351+
15352+ log(L_BUFT, "tx: cleaning up bufs from %u\n", adev->tx_tail);
15353+
15354+ /* We know first descr which is not free yet. We advance it as far
15355+ ** as we see correct bits set in following descs (if next desc
15356+ ** is NOT free, we shouldn't advance at all). We know that in
15357+ ** front of tx_tail may be "holes" with isolated free descs.
15358+ ** We will catch up when all intermediate descs will be freed also */
15359+
15360+ finger = adev->tx_tail;
15361+ num_cleaned = 0;
15362+ while (likely(finger != adev->tx_head)) {
15363+ txdesc = get_txdesc(adev, finger);
15364+
15365+ /* If we allocated txdesc on tx path but then decided
15366+ ** to NOT use it, then it will be left as a free "bubble"
15367+ ** in the "allocated for tx" part of the ring.
15368+ ** We may meet it on the next ring pass here. */
15369+
15370+ /* stop if not marked as "tx finished" and "host owned" */
15371+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
15372+ if ((Ctl_8 & DESC_CTL_ACXDONE_HOSTOWN)
15373+ != DESC_CTL_ACXDONE_HOSTOWN) {
15374+ if (unlikely(!num_cleaned)) { /* maybe remove completely */
15375+ log(L_BUFT, "clean_txdesc: tail isn't free. "
15376+ "tail:%d head:%d\n",
15377+ adev->tx_tail, adev->tx_head);
15378+ }
15379+ break;
15380+ }
15381+
15382+ /* remember desc values... */
15383+ error = read_slavemem8 (adev, (u32) &(txdesc->error));
15384+ ack_failures = read_slavemem8 (adev, (u32) &(txdesc->ack_failures));
15385+ rts_failures = read_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_failures));
15386+ rts_ok = read_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_ok));
15387+ r100 = read_slavemem8 (adev, (u32) &(txdesc->u.r1.rate));
15388+ r111 = le16_to_cpu(read_slavemem16 (adev, (u32) &(txdesc->u.r2.rate111)));
15389+
15390+ /* need to check for certain error conditions before we
15391+ * clean the descriptor: we still need valid descr data here */
15392+ if (unlikely(0x30 & error)) {
15393+ /* only send IWEVTXDROP in case of retry or lifetime exceeded;
15394+ * all other errors mean we screwed up locally */
15395+ union iwreq_data wrqu;
15396+ wlan_hdr_t *hdr;
15397+ txhostdesc_t *hostdesc;
15398+
15399+ hostdesc = get_txhostdesc(adev, txdesc);
15400+ hdr = (wlan_hdr_t *)hostdesc->data;
15401+ MAC_COPY(wrqu.addr.sa_data, hdr->a1);
15402+ wireless_send_event(adev->ndev, IWEVTXDROP, &wrqu, NULL);
15403+ }
15404+
15405+ /*
15406+ * Free up the transmit data buffers
15407+ */
15408+ acxmem = read_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr));
15409+ if (acxmem) {
15410+ reclaim_acx_txbuf_space (adev, acxmem);
15411+ }
15412+
15413+ /* ...and free the desc by clearing all the fields
15414+ except the next pointer */
15415+ copy_to_slavemem (adev,
15416+ (u32) &(txdesc->HostMemPtr),
15417+ (u8 *) &(tmptxdesc.HostMemPtr),
15418+ sizeof (tmptxdesc) - sizeof(tmptxdesc.pNextDesc)
15419+ );
15420+
15421+ adev->tx_free++;
15422+ num_cleaned++;
15423+
15424+ if ((adev->tx_free >= TX_START_QUEUE)
15425+ && (adev->status == ACX_STATUS_4_ASSOCIATED)
15426+ && (acx_queue_stopped(adev->ndev))
15427+ ) {
15428+ log(L_BUF, "tx: wake queue (avail. Tx desc %u)\n",
15429+ adev->tx_free);
15430+ acx_wake_queue(adev->ndev, NULL);
15431+ }
15432+
15433+ /* do error checking, rate handling and logging
15434+ * AFTER having done the work, it's faster */
15435+
15436+ /* do rate handling */
15437+ if (adev->rate_auto) {
15438+ struct client *clt = get_txc(adev, txdesc);
15439+ if (clt) {
15440+ u16 cur = get_txr(adev, txdesc);
15441+ if (clt->rate_cur == cur) {
15442+ acx_l_handle_txrate_auto(adev, clt,
15443+ cur, /* intended rate */
15444+ r100, r111, /* actually used rate */
15445+ (error & 0x30), /* was there an error? */
15446+ TX_CNT + TX_CLEAN_BACKLOG - adev->tx_free);
15447+ }
15448+ }
15449+ }
15450+
15451+ if (unlikely(error))
15452+ handle_tx_error(adev, error, finger);
15453+
15454+ if (IS_ACX111(adev))
15455+ log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u r111=%04X\n",
15456+ finger, ack_failures, rts_failures, rts_ok, r111);
15457+ else
15458+ log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u rate=%u\n",
15459+ finger, ack_failures, rts_failures, rts_ok, r100);
15460+
15461+ /* update pointer for descr to be cleaned next */
15462+ finger = (finger + 1) % TX_CNT;
15463+ }
15464+
15465+ /* remember last position */
15466+ adev->tx_tail = finger;
15467+/* end: */
15468+ FN_EXIT1(num_cleaned);
15469+ return num_cleaned;
15470+}
15471+
15472+/* clean *all* Tx descriptors, and regardless of their previous state.
15473+ * Used for brute-force reset handling. */
15474+void
15475+acxmem_l_clean_txdesc_emergency(acx_device_t *adev)
15476+{
15477+ txdesc_t *txdesc;
15478+ int i;
15479+ u32 acxmem;
15480+
15481+ FN_ENTER;
15482+
15483+ for (i = 0; i < TX_CNT; i++) {
15484+ txdesc = get_txdesc(adev, i);
15485+
15486+ /* free it */
15487+ write_slavemem8 (adev, (u32) &(txdesc->ack_failures), 0);
15488+ write_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_failures), 0);
15489+ write_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_ok), 0);
15490+ write_slavemem8 (adev, (u32) &(txdesc->error), 0);
15491+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), DESC_CTL_HOSTOWN);
15492+
15493+ /*
15494+ * Clean up the memory allocated on the ACX for this transmit descriptor.
15495+ */
15496+ acxmem = read_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr));
15497+ if (acxmem) {
15498+ reclaim_acx_txbuf_space (adev, acxmem);
15499+ }
15500+
15501+ write_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr), 0);
15502+ }
15503+
15504+ adev->tx_free = TX_CNT;
15505+
15506+ FN_EXIT0;
15507+}
15508+
15509+
15510+/***********************************************************************
15511+** acxmem_s_create_tx_host_desc_queue
15512+*/
15513+
15514+static void*
15515+allocate(acx_device_t *adev, size_t size, dma_addr_t *phy, const char *msg)
15516+{
15517+ void *ptr;
15518+ ptr = kmalloc (size, GFP_KERNEL);
15519+ /*
15520+ * The ACX can't use the physical address, so we'll have to fake it
15521+ * later and it might be handy to have the virtual address.
15522+ */
15523+ *phy = (dma_addr_t) NULL;
15524+
15525+ if (ptr) {
15526+ log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n",
15527+ msg, (int)size, ptr, (unsigned long long)*phy);
15528+ memset(ptr, 0, size);
15529+ return ptr;
15530+ }
15531+ printk(KERN_ERR "acx: %s allocation FAILED (%d bytes)\n",
15532+ msg, (int)size);
15533+ return NULL;
15534+}
15535+
15536+
15537+/*
15538+ * In the generic slave memory access mode, most of the stuff in
15539+ * the txhostdesc_t is unused. It's only here because the rest of
15540+ * the ACX driver expects it to be since the PCI version uses indirect
15541+ * host memory organization with DMA. Since we're not using DMA the
15542+ * only use we have for the host descriptors is to store the packets
15543+ * on the way out.
15544+ */
15545+static int
15546+acxmem_s_create_tx_host_desc_queue(acx_device_t *adev)
15547+{
15548+ txhostdesc_t *hostdesc;
15549+ u8 *txbuf;
15550+ int i;
15551+
15552+ FN_ENTER;
15553+
15554+ /* allocate TX buffer */
15555+ adev->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS;
15556+
15557+ adev->txbuf_start = allocate(adev, adev->txbuf_area_size,
15558+ &adev->txbuf_startphy, "txbuf_start");
15559+ if (!adev->txbuf_start)
15560+ goto fail;
15561+
15562+ /* allocate the TX host descriptor queue pool */
15563+ adev->txhostdesc_area_size = TX_CNT * 2*sizeof(*hostdesc);
15564+
15565+ adev->txhostdesc_start = allocate(adev, adev->txhostdesc_area_size,
15566+ &adev->txhostdesc_startphy, "txhostdesc_start");
15567+ if (!adev->txhostdesc_start)
15568+ goto fail;
15569+
15570+ /* check for proper alignment of TX host descriptor pool */
15571+ if ((long) adev->txhostdesc_start & 3) {
15572+ printk("acx: driver bug: dma alloc returns unaligned address\n");
15573+ goto fail;
15574+ }
15575+
15576+ hostdesc = adev->txhostdesc_start;
15577+ txbuf = adev->txbuf_start;
15578+
15579+#if 0
15580+/* Each tx buffer is accessed by hardware via
15581+** txdesc -> txhostdesc(s) -> txbuffer(s).
15582+** We use only one txhostdesc per txdesc, but it looks like
15583+** acx111 is buggy: it accesses second txhostdesc
15584+** (via hostdesc.desc_phy_next field) even if
15585+** txdesc->length == hostdesc->length and thus
15586+** entire packet was placed into first txhostdesc.
15587+** Due to this bug acx111 hangs unless second txhostdesc
15588+** has le16_to_cpu(hostdesc.length) = 3 (or larger)
15589+** Storing NULL into hostdesc.desc_phy_next
15590+** doesn't seem to help.
15591+**
15592+** Update: although it worked on Xterasys XN-2522g
15593+** with len=3 trick, WG311v2 is even more bogus, doesn't work.
15594+** Keeping this code (#ifdef'ed out) for documentational purposes.
15595+*/
15596+ for (i = 0; i < TX_CNT*2; i++) {
15597+ hostdesc_phy += sizeof(*hostdesc);
15598+ if (!(i & 1)) {
15599+ hostdesc->data_phy = cpu2acx(txbuf_phy);
15600+ /* hostdesc->data_offset = ... */
15601+ /* hostdesc->reserved = ... */
15602+ hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN);
15603+ /* hostdesc->length = ... */
15604+ hostdesc->desc_phy_next = cpu2acx(hostdesc_phy);
15605+ hostdesc->pNext = ptr2acx(NULL);
15606+ /* hostdesc->Status = ... */
15607+ /* below: non-hardware fields */
15608+ hostdesc->data = txbuf;
15609+
15610+ txbuf += WLAN_A4FR_MAXLEN_WEP_FCS;
15611+ txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS;
15612+ } else {
15613+ /* hostdesc->data_phy = ... */
15614+ /* hostdesc->data_offset = ... */
15615+ /* hostdesc->reserved = ... */
15616+ /* hostdesc->Ctl_16 = ... */
15617+ hostdesc->length = cpu_to_le16(3); /* bug workaround */
15618+ /* hostdesc->desc_phy_next = ... */
15619+ /* hostdesc->pNext = ... */
15620+ /* hostdesc->Status = ... */
15621+ /* below: non-hardware fields */
15622+ /* hostdesc->data = ... */
15623+ }
15624+ hostdesc++;
15625+ }
15626+#endif
15627+/* We initialize two hostdescs so that they point to adjacent
15628+** memory areas. Thus txbuf is really just a contiguous memory area */
15629+ for (i = 0; i < TX_CNT*2; i++) {
15630+ /* ->data is a non-hardware field: */
15631+ hostdesc->data = txbuf;
15632+
15633+ if (!(i & 1)) {
15634+ txbuf += WLAN_HDR_A3_LEN;
15635+ } else {
15636+ txbuf += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN;
15637+ }
15638+ hostdesc++;
15639+ }
15640+ hostdesc--;
15641+
15642+ FN_EXIT1(OK);
15643+ return OK;
15644+fail:
15645+ printk("acx: create_tx_host_desc_queue FAILED\n");
15646+ /* dealloc will be done by free function on error case */
15647+ FN_EXIT1(NOT_OK);
15648+ return NOT_OK;
15649+}
15650+
15651+
15652+/***************************************************************
15653+** acxmem_s_create_rx_host_desc_queue
15654+*/
15655+/* the whole size of a data buffer (header plus data body)
15656+ * plus 32 bytes safety offset at the end */
15657+#define RX_BUFFER_SIZE (sizeof(rxbuffer_t) + 32)
15658+
15659+static int
15660+acxmem_s_create_rx_host_desc_queue(acx_device_t *adev)
15661+{
15662+ rxhostdesc_t *hostdesc;
15663+ rxbuffer_t *rxbuf;
15664+ int i;
15665+
15666+ FN_ENTER;
15667+
15668+ /* allocate the RX host descriptor queue pool */
15669+ adev->rxhostdesc_area_size = RX_CNT * sizeof(*hostdesc);
15670+
15671+ adev->rxhostdesc_start = allocate(adev, adev->rxhostdesc_area_size,
15672+ &adev->rxhostdesc_startphy, "rxhostdesc_start");
15673+ if (!adev->rxhostdesc_start)
15674+ goto fail;
15675+
15676+ /* check for proper alignment of RX host descriptor pool */
15677+ if ((long) adev->rxhostdesc_start & 3) {
15678+ printk("acx: driver bug: dma alloc returns unaligned address\n");
15679+ goto fail;
15680+ }
15681+
15682+ /* allocate Rx buffer pool which will be used by the acx
15683+ * to store the whole content of the received frames in it */
15684+ adev->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE;
15685+
15686+ adev->rxbuf_start = allocate(adev, adev->rxbuf_area_size,
15687+ &adev->rxbuf_startphy, "rxbuf_start");
15688+ if (!adev->rxbuf_start)
15689+ goto fail;
15690+
15691+ rxbuf = adev->rxbuf_start;
15692+ hostdesc = adev->rxhostdesc_start;
15693+
15694+ /* don't make any popular C programming pointer arithmetic mistakes
15695+ * here, otherwise I'll kill you...
15696+ * (and don't dare asking me why I'm warning you about that...) */
15697+ for (i = 0; i < RX_CNT; i++) {
15698+ hostdesc->data = rxbuf;
15699+ hostdesc->length = cpu_to_le16(RX_BUFFER_SIZE);
15700+ rxbuf++;
15701+ hostdesc++;
15702+ }
15703+ hostdesc--;
15704+ FN_EXIT1(OK);
15705+ return OK;
15706+fail:
15707+ printk("acx: create_rx_host_desc_queue FAILED\n");
15708+ /* dealloc will be done by free function on error case */
15709+ FN_EXIT1(NOT_OK);
15710+ return NOT_OK;
15711+}
15712+
15713+
15714+/***************************************************************
15715+** acxmem_s_create_hostdesc_queues
15716+*/
15717+int
15718+acxmem_s_create_hostdesc_queues(acx_device_t *adev)
15719+{
15720+ int result;
15721+ result = acxmem_s_create_tx_host_desc_queue(adev);
15722+ if (OK != result) return result;
15723+ result = acxmem_s_create_rx_host_desc_queue(adev);
15724+ return result;
15725+}
15726+
15727+
15728+/***************************************************************
15729+** acxmem_create_tx_desc_queue
15730+*/
15731+static void
15732+acxmem_create_tx_desc_queue(acx_device_t *adev, u32 tx_queue_start)
15733+{
15734+ txdesc_t *txdesc;
15735+ u32 clr;
15736+ int i;
15737+
15738+ FN_ENTER;
15739+
15740+ if (IS_ACX100(adev))
15741+ adev->txdesc_size = sizeof(*txdesc);
15742+ else
15743+ /* the acx111 txdesc is 4 bytes larger */
15744+ adev->txdesc_size = sizeof(*txdesc) + 4;
15745+
15746+ /*
15747+ * This refers to an ACX address, not one of ours
15748+ */
15749+ adev->txdesc_start = (txdesc_t *) tx_queue_start;
15750+
15751+ log(L_DEBUG, "adev->txdesc_start=%p\n",
15752+ adev->txdesc_start);
15753+
15754+ adev->tx_free = TX_CNT;
15755+ /* done by memset: adev->tx_head = 0; */
15756+ /* done by memset: adev->tx_tail = 0; */
15757+ txdesc = adev->txdesc_start;
15758+
15759+ if (IS_ACX111(adev)) {
15760+ /* ACX111 has a preinitialized Tx buffer! */
15761+ /* loop over whole send pool */
15762+ /* FIXME: do we have to do the hostmemptr stuff here?? */
15763+ for (i = 0; i < TX_CNT; i++) {
15764+ txdesc->Ctl_8 = DESC_CTL_HOSTOWN;
15765+ /* reserve two (hdr desc and payload desc) */
15766+ txdesc = advance_txdesc(adev, txdesc, 1);
15767+ }
15768+ } else {
15769+ /* ACX100 Tx buffer needs to be initialized by us */
15770+ /* clear whole send pool. sizeof is safe here (we are acx100) */
15771+
15772+ /*
15773+ * adev->txdesc_start refers to device memory, so we can't write
15774+ * directly to it.
15775+ */
15776+ clr = (u32) adev->txdesc_start;
15777+ while (clr < (u32) adev->txdesc_start + (TX_CNT * sizeof(*txdesc))) {
15778+ write_slavemem32 (adev, clr, 0);
15779+ clr += 4;
15780+ }
15781+
15782+ /* loop over whole send pool */
15783+ for (i = 0; i < TX_CNT; i++) {
15784+ log(L_DEBUG, "configure card tx descriptor: 0x%p, "
15785+ "size: 0x%X\n", txdesc, adev->txdesc_size);
15786+
15787+ /* initialise ctl */
15788+ /*
15789+ * No auto DMA here
15790+ */
15791+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8),
15792+ (u8) (DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG));
15793+ /* done by memset(0): txdesc->Ctl2_8 = 0; */
15794+
15795+ /* point to next txdesc */
15796+ write_slavemem32 (adev, (u32) &(txdesc->pNextDesc),
15797+ (u32) cpu_to_le32 ((u8 *) txdesc + adev->txdesc_size));
15798+
15799+ /* go to the next one */
15800+ /* ++ is safe here (we are acx100) */
15801+ txdesc++;
15802+ }
15803+ /* go back to the last one */
15804+ txdesc--;
15805+ /* and point to the first making it a ring buffer */
15806+ write_slavemem32 (adev, (u32) &(txdesc->pNextDesc),
15807+ (u32) cpu_to_le32 (tx_queue_start));
15808+ }
15809+ FN_EXIT0;
15810+}
15811+
15812+
15813+/***************************************************************
15814+** acxmem_create_rx_desc_queue
15815+*/
15816+static void
15817+acxmem_create_rx_desc_queue(acx_device_t *adev, u32 rx_queue_start)
15818+{
15819+ rxdesc_t *rxdesc;
15820+ u32 mem_offs;
15821+ int i;
15822+
15823+ FN_ENTER;
15824+
15825+ /* done by memset: adev->rx_tail = 0; */
15826+
15827+ /* ACX111 doesn't need any further config: preconfigures itself.
15828+ * Simply print ring buffer for debugging */
15829+ if (IS_ACX111(adev)) {
15830+ /* rxdesc_start already set here */
15831+
15832+ adev->rxdesc_start = (rxdesc_t *) rx_queue_start;
15833+
15834+ rxdesc = adev->rxdesc_start;
15835+ for (i = 0; i < RX_CNT; i++) {
15836+ log(L_DEBUG, "rx descriptor %d @ 0x%p\n", i, rxdesc);
15837+ rxdesc = adev->rxdesc_start = (rxdesc_t *)
15838+ acx2cpu(rxdesc->pNextDesc);
15839+ }
15840+ } else {
15841+ /* we didn't pre-calculate rxdesc_start in case of ACX100 */
15842+ /* rxdesc_start should be right AFTER Tx pool */
15843+ adev->rxdesc_start = (rxdesc_t *)
15844+ ((u8 *) adev->txdesc_start + (TX_CNT * sizeof(txdesc_t)));
15845+ /* NB: sizeof(txdesc_t) above is valid because we know
15846+ ** we are in if (acx100) block. Beware of cut-n-pasting elsewhere!
15847+ ** acx111's txdesc is larger! */
15848+
15849+ mem_offs = (u32) adev->rxdesc_start;
15850+ while (mem_offs < (u32) adev->rxdesc_start + (RX_CNT * sizeof (*rxdesc))) {
15851+ write_slavemem32 (adev, mem_offs, 0);
15852+ mem_offs += 4;
15853+ }
15854+
15855+ /* loop over whole receive pool */
15856+ rxdesc = adev->rxdesc_start;
15857+ for (i = 0; i < RX_CNT; i++) {
15858+ log(L_DEBUG, "rx descriptor @ 0x%p\n", rxdesc);
15859+ /* point to next rxdesc */
15860+ write_slavemem32 (adev, (u32) &(rxdesc->pNextDesc),
15861+ (u32) cpu_to_le32 ((u8 *) rxdesc + sizeof(*rxdesc)));
15862+ /* go to the next one */
15863+ rxdesc++;
15864+ }
15865+ /* go to the last one */
15866+ rxdesc--;
15867+
15868+ /* and point to the first making it a ring buffer */
15869+ write_slavemem32 (adev, (u32) &(rxdesc->pNextDesc),
15870+ (u32) cpu_to_le32 (rx_queue_start));
15871+ }
15872+ FN_EXIT0;
15873+}
15874+
15875+
15876+/***************************************************************
15877+** acxmem_create_desc_queues
15878+*/
15879+void
15880+acxmem_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start)
15881+{
15882+ u32 *p;
15883+ int i;
15884+
15885+ acxmem_create_tx_desc_queue(adev, tx_queue_start);
15886+ acxmem_create_rx_desc_queue(adev, rx_queue_start);
15887+ p = (u32 *) adev->acx_queue_indicator;
15888+ for (i = 0; i < 4; i++) {
15889+ write_slavemem32 (adev, (u32) p, 0);
15890+ p++;
15891+ }
15892+}
15893+
15894+
15895+/***************************************************************
15896+** acxmem_s_proc_diag_output
15897+*/
15898+char*
15899+acxmem_s_proc_diag_output(char *p, acx_device_t *adev)
15900+{
15901+ const char *rtl, *thd, *ttl;
15902+ txdesc_t *txdesc;
15903+ u8 Ctl_8;
15904+ rxdesc_t *rxdesc;
15905+ int i;
15906+ u32 tmp;
15907+ txdesc_t txd;
15908+ u8 buf[0x200];
15909+ int j, k;
15910+
15911+ FN_ENTER;
15912+
15913+#if DUMP_MEM_DURING_DIAG > 0
15914+ dump_acxmem (adev, 0, 0x10000);
15915+ panic ("dump finished");
15916+#endif
15917+
15918+ p += sprintf(p, "** Rx buf **\n");
15919+ rxdesc = adev->rxdesc_start;
15920+ if (rxdesc) for (i = 0; i < RX_CNT; i++) {
15921+ rtl = (i == adev->rx_tail) ? " [tail]" : "";
15922+ Ctl_8 = read_slavemem8 (adev, (u32) &(rxdesc->Ctl_8));
15923+ if (Ctl_8 & DESC_CTL_HOSTOWN)
15924+ p += sprintf(p, "%02u (%02x) FULL%s\n", i, Ctl_8, rtl);
15925+ else
15926+ p += sprintf(p, "%02u (%02x) empty%s\n", i, Ctl_8, rtl);
15927+ rxdesc++;
15928+ }
15929+ p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", adev->tx_free,
15930+ acx_queue_stopped(adev->ndev) ? "STOPPED" : "running");
15931+
15932+ p += sprintf(p, "** Tx buf %d blocks total, %d available, free list head %04x\n",
15933+ adev->acx_txbuf_numblocks, adev->acx_txbuf_blocks_free, adev->acx_txbuf_free);
15934+ txdesc = adev->txdesc_start;
15935+ if (txdesc) {
15936+ for (i = 0; i < TX_CNT; i++) {
15937+ thd = (i == adev->tx_head) ? " [head]" : "";
15938+ ttl = (i == adev->tx_tail) ? " [tail]" : "";
15939+ copy_from_slavemem (adev, (u8 *) &txd, (u32) txdesc, sizeof (txd));
15940+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
15941+ if (Ctl_8 & DESC_CTL_ACXDONE)
15942+ p += sprintf(p, "%02u ready to free (%02X)%s%s", i, Ctl_8, thd, ttl);
15943+ else if (Ctl_8 & DESC_CTL_HOSTOWN)
15944+ p += sprintf(p, "%02u available (%02X)%s%s", i, Ctl_8, thd, ttl);
15945+ else
15946+ p += sprintf(p, "%02u busy (%02X)%s%s", i, Ctl_8, thd, ttl);
15947+ tmp = read_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr));
15948+ if (tmp) {
15949+ p += sprintf (p, " %04x", tmp);
15950+ while ((tmp = read_slavemem32 (adev, (u32) tmp)) != 0x02000000) {
15951+ tmp <<= 5;
15952+ p += sprintf (p, " %04x", tmp);
15953+ }
15954+ }
15955+ p += sprintf (p, "\n");
15956+ p += sprintf (p, " %04x: %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %02x %02x %02x %02x\n"
15957+ "%02x %02x %02x %02x %04x\n",
15958+ (u32) txdesc,
15959+ txd.pNextDesc.v, txd.HostMemPtr.v, txd.AcxMemPtr.v, txd.tx_time,
15960+ txd.total_length, txd.Reserved,
15961+ txd.dummy[0], txd.dummy[1], txd.dummy[2], txd.dummy[3],
15962+ txd.Ctl_8, txd.Ctl2_8, txd.error, txd.ack_failures,
15963+ txd.u.rts.rts_failures, txd.u.rts.rts_ok, txd.u.r1.rate, txd.u.r1.queue_ctrl,
15964+ txd.queue_info
15965+ );
15966+ if (txd.AcxMemPtr.v) {
15967+ copy_from_slavemem (adev, buf, txd.AcxMemPtr.v, sizeof (buf));
15968+ for (j = 0; (j < txd.total_length) && (j<(sizeof(buf)-4)); j+=16) {
15969+ p += sprintf (p, " ");
15970+ for (k = 0; (k < 16) && (j+k < txd.total_length); k++) {
15971+ p += sprintf (p, " %02x", buf[j+k+4]);
15972+ }
15973+ p += sprintf (p, "\n");
15974+ }
15975+ }
15976+ txdesc = advance_txdesc(adev, txdesc, 1);
15977+ }
15978+ }
15979+
15980+ p += sprintf(p,
15981+ "\n"
15982+ "** Generic slave data **\n"
15983+ "irq_mask 0x%04x irq_status 0x%04x irq on acx 0x%04x\n"
15984+ "txbuf_start 0x%p, txbuf_area_size %u\n"
15985+ "txdesc_size %u, txdesc_start 0x%p\n"
15986+ "txhostdesc_start 0x%p, txhostdesc_area_size %u\n"
15987+ "txbuf start 0x%04x, txbuf size %d\n"
15988+ "rxdesc_start 0x%p\n"
15989+ "rxhostdesc_start 0x%p, rxhostdesc_area_size %u\n"
15990+ "rxbuf_start 0x%p, rxbuf_area_size %u\n",
15991+ adev->irq_mask, adev->irq_status, read_reg32(adev, IO_ACX_IRQ_STATUS_NON_DES),
15992+ adev->txbuf_start, adev->txbuf_area_size,
15993+ adev->txdesc_size, adev->txdesc_start,
15994+ adev->txhostdesc_start, adev->txhostdesc_area_size,
15995+ adev->acx_txbuf_start, adev->acx_txbuf_numblocks * adev->memblocksize,
15996+ adev->rxdesc_start,
15997+ adev->rxhostdesc_start, adev->rxhostdesc_area_size,
15998+ adev->rxbuf_start, adev->rxbuf_area_size);
15999+ FN_EXIT0;
16000+ return p;
16001+}
16002+
16003+
16004+/***********************************************************************
16005+*/
16006+int
16007+acxmem_proc_eeprom_output(char *buf, acx_device_t *adev)
16008+{
16009+ char *p = buf;
16010+ int i;
16011+
16012+ FN_ENTER;
16013+
16014+ for (i = 0; i < 0x400; i++) {
16015+ acxmem_read_eeprom_byte(adev, i, p++);
16016+ }
16017+
16018+ FN_EXIT1(p - buf);
16019+ return p - buf;
16020+}
16021+
16022+
16023+/***********************************************************************
16024+*/
16025+void
16026+acxmem_set_interrupt_mask(acx_device_t *adev)
16027+{
16028+ if (IS_ACX111(adev)) {
16029+ adev->irq_mask = (u16) ~(0
16030+ | HOST_INT_RX_DATA
16031+ | HOST_INT_TX_COMPLETE
16032+ /* | HOST_INT_TX_XFER */
16033+ /* | HOST_INT_RX_COMPLETE */
16034+ /* | HOST_INT_DTIM */
16035+ /* | HOST_INT_BEACON */
16036+ /* | HOST_INT_TIMER */
16037+ /* | HOST_INT_KEY_NOT_FOUND */
16038+ | HOST_INT_IV_ICV_FAILURE
16039+ | HOST_INT_CMD_COMPLETE
16040+ | HOST_INT_INFO
16041+ | HOST_INT_OVERFLOW
16042+ /* | HOST_INT_PROCESS_ERROR */
16043+ | HOST_INT_SCAN_COMPLETE
16044+ | HOST_INT_FCS_THRESHOLD
16045+ | HOST_INT_UNKNOWN
16046+ );
16047+ /* Or else acx100 won't signal cmd completion, right? */
16048+ adev->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */
16049+ } else {
16050+ adev->irq_mask = (u16) ~(0
16051+ | HOST_INT_RX_DATA
16052+ | HOST_INT_TX_COMPLETE
16053+ /* | HOST_INT_TX_XFER */
16054+ /* | HOST_INT_RX_COMPLETE */
16055+ /* | HOST_INT_DTIM */
16056+ /* | HOST_INT_BEACON */
16057+ /* | HOST_INT_TIMER */
16058+ /* | HOST_INT_KEY_NOT_FOUND */
16059+ /* | HOST_INT_IV_ICV_FAILURE */
16060+ | HOST_INT_CMD_COMPLETE
16061+ | HOST_INT_INFO
16062+ /* | HOST_INT_OVERFLOW */
16063+ /* | HOST_INT_PROCESS_ERROR */
16064+ | HOST_INT_SCAN_COMPLETE
16065+ /* | HOST_INT_FCS_THRESHOLD */
16066+ /* | HOST_INT_BEACON_MISSED */
16067+ );
16068+ adev->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */
16069+ }
16070+}
16071+
16072+
16073+/***********************************************************************
16074+*/
16075+int
16076+acx100mem_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
16077+{
16078+ struct acx111_ie_tx_level tx_level;
16079+
16080+ /* since it can be assumed that at least the Maxim radio has a
16081+ * maximum power output of 20dBm and since it also can be
16082+ * assumed that these values drive the DAC responsible for
16083+ * setting the linear Tx level, I'd guess that these values
16084+ * should be the corresponding linear values for a dBm value,
16085+ * in other words: calculate the values from that formula:
16086+ * Y [dBm] = 10 * log (X [mW])
16087+ * then scale the 0..63 value range onto the 1..100mW range (0..20 dBm)
16088+ * and you're done...
16089+ * Hopefully that's ok, but you never know if we're actually
16090+ * right... (especially since Windows XP doesn't seem to show
16091+ * actual Tx dBm values :-P) */
16092+
16093+ /* NOTE: on Maxim, value 30 IS 30mW, and value 10 IS 10mW - so the
16094+ * values are EXACTLY mW!!! Not sure about RFMD and others,
16095+ * though... */
16096+ static const u8 dbm2val_maxim[21] = {
16097+ 63, 63, 63, 62,
16098+ 61, 61, 60, 60,
16099+ 59, 58, 57, 55,
16100+ 53, 50, 47, 43,
16101+ 38, 31, 23, 13,
16102+ 0
16103+ };
16104+ static const u8 dbm2val_rfmd[21] = {
16105+ 0, 0, 0, 1,
16106+ 2, 2, 3, 3,
16107+ 4, 5, 6, 8,
16108+ 10, 13, 16, 20,
16109+ 25, 32, 41, 50,
16110+ 63
16111+ };
16112+ const u8 *table;
16113+
16114+ switch (adev->radio_type) {
16115+ case RADIO_MAXIM_0D:
16116+ table = &dbm2val_maxim[0];
16117+ break;
16118+ case RADIO_RFMD_11:
16119+ case RADIO_RALINK_15:
16120+ table = &dbm2val_rfmd[0];
16121+ break;
16122+ default:
16123+ printk("%s: unknown/unsupported radio type, "
16124+ "cannot modify tx power level yet!\n",
16125+ adev->ndev->name);
16126+ return NOT_OK;
16127+ }
16128+ /*
16129+ * The hx4700 EEPROM, at least, only supports 1 power setting. The configure
16130+ * routine matches the PA bias with the gain, so just use its default value.
16131+ * The values are: 0x2b for the gain and 0x03 for the PA bias. The firmware
16132+ * writes the gain level to the Tx gain control DAC and the PA bias to the Maxim
16133+ * radio's PA bias register. The firmware limits itself to 0 - 64 when writing to the
16134+ * gain control DAC.
16135+ *
16136+ * Physically between the ACX and the radio, higher Tx gain control DAC values result
16137+ * in less power output; 0 volts to the Maxim radio results in the highest output power
16138+ * level, which I'm assuming matches up with 0 in the Tx Gain DAC register.
16139+ *
16140+ * Although there is only the 1 power setting, one of the radio firmware functions adjusts
16141+ * the transmit power level up and down. That function is called by the ACX FIQ handler
16142+ * under certain conditions.
16143+ */
16144+ tx_level.level = 1;
16145+ //return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
16146+
16147+ printk("%s: changing radio power level to %u dBm (%u)\n",
16148+ adev->ndev->name, level_dbm, table[level_dbm]);
16149+ acxmem_s_write_phy_reg(adev, 0x11, table[level_dbm]);
16150+
16151+ return 0;
16152+}
16153+
16154+void acxmem_e_release(struct device *dev) {
16155+}
16156+
16157+/***********************************************************************
16158+** acx_cs part
16159+**
16160+** called by pcmcia card service
16161+*/
16162+
16163+/*
16164+ The event() function is this driver's Card Services event handler.
16165+ It will be called by Card Services when an appropriate card status
16166+ event is received. The config() and release() entry points are
16167+ used to configure or release a socket, in response to card
16168+ insertion and ejection events. They are invoked from the acx_cs
16169+ event handler.
16170+*/
16171+
16172+static int acx_cs_config(struct pcmcia_device *link);
16173+static void acx_cs_release(struct pcmcia_device *link);
16174+
16175+/*
16176+ The attach() and detach() entry points are used to create and destroy
16177+ "instances" of the driver, where each instance represents everything
16178+ needed to manage one actual PCMCIA card.
16179+*/
16180+
16181+static void acx_cs_detach(struct pcmcia_device *p_dev);
16182+
16183+/*
16184+ You'll also need to prototype all the functions that will actually
16185+ be used to talk to your device. See 'pcmem_cs' for a good example
16186+ of a fully self-sufficient driver; the other drivers rely more or
16187+ less on other parts of the kernel.
16188+*/
16189+
16190+/*
16191+ A linked list of "instances" of the acxnet device. Each actual
16192+ PCMCIA card corresponds to one device instance, and is described
16193+ by one struct pcmcia_device structure (defined in ds.h).
16194+
16195+ You may not want to use a linked list for this -- for example, the
16196+ memory card driver uses an array of struct pcmcia_device pointers, where minor
16197+ device numbers are used to derive the corresponding array index.
16198+*/
16199+
16200+/*
16201+ A driver needs to provide a dev_node_t structure for each device
16202+ on a card. In some cases, there is only one device per card (for
16203+ example, ethernet cards, modems). In other cases, there may be
16204+ many actual or logical devices (SCSI adapters, memory cards with
16205+ multiple partitions). The dev_node_t structures need to be kept
16206+ in a linked list starting at the 'dev' field of a struct pcmcia_device
16207+ structure. We allocate them in the card's private data structure,
16208+ because they generally shouldn't be allocated dynamically.
16209+
16210+ In this case, we also provide a flag to indicate if a device is
16211+ "stopped" due to a power management event, or card ejection. The
16212+ device IO routines can use a flag like this to throttle IO to a
16213+ card that is not ready to accept it.
16214+*/
16215+
16216+
16217+/*======================================================================
16218+
16219+ acx_attach() creates an "instance" of the driver, allocating
16220+ local data structures for one device. The device is registered
16221+ with Card Services.
16222+
16223+ The dev_link structure is initialized, but we don't actually
16224+ configure the card at this point -- we wait until we receive a
16225+ card insertion event.
16226+
16227+ ======================================================================*/
16228+
16229+static int acx_cs_probe(struct pcmcia_device *link)
16230+{
16231+ local_info_t *local;
16232+ struct net_device *ndev;
16233+
16234+ DEBUG(0, "acx_attach()\n");
16235+
16236+ ndev = alloc_netdev(sizeof(acx_device_t), "wlan%d", dummy_netdev_init);
16237+ if (!ndev) {
16238+ printk("acx: no memory for netdevice struct\n");
16239+ return -ENOMEM;
16240+ }
16241+
16242+ /* Interrupt setup */
16243+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
16244+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
16245+ link->irq.Handler = acxmem_i_interrupt;
16246+ link->irq.Instance = ndev;
16247+
16248+ /*
16249+ General socket configuration defaults can go here. In this
16250+ client, we assume very little, and rely on the CIS for almost
16251+ everything. In most clients, many details (i.e., number, sizes,
16252+ and attributes of IO windows) are fixed by the nature of the
16253+ device, and can be hard-wired here.
16254+ */
16255+ link->conf.Attributes = CONF_ENABLE_IRQ;
16256+ link->conf.IntType = INT_MEMORY_AND_IO;
16257+ link->conf.Present = PRESENT_OPTION | PRESENT_COPY;
16258+
16259+ /* Allocate space for private device-specific data */
16260+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
16261+ if (!local) {
16262+ printk(KERN_ERR "acx_cs: no memory for new device\n");
16263+ return -ENOMEM;
16264+ }
16265+ local->ndev = ndev;
16266+
16267+ link->priv = local;
16268+
16269+ return acx_cs_config(link);
16270+} /* acx_attach */
16271+
16272+/*======================================================================
16273+
16274+ This deletes a driver "instance". The device is de-registered
16275+ with Card Services. If it has been released, all local data
16276+ structures are freed. Otherwise, the structures will be freed
16277+ when the device is released.
16278+
16279+ ======================================================================*/
16280+
16281+static void acx_cs_detach(struct pcmcia_device *link)
16282+{
16283+ DEBUG(0, "acx_detach(0x%p)\n", link);
16284+
16285+
16286+ if ( ((local_info_t*)link->priv)->ndev ) {
16287+ acxmem_e_close( ((local_info_t*)link->priv)->ndev );
16288+ }
16289+
16290+ acx_cs_release(link);
16291+
16292+ ((local_info_t*)link->priv)->ndev = NULL;
16293+
16294+ kfree(link->priv);
16295+} /* acx_detach */
16296+
16297+/*======================================================================
16298+
16299+ acx_config() is scheduled to run after a CARD_INSERTION event
16300+ is received, to configure the PCMCIA socket, and to make the
16301+ device available to the system.
16302+
16303+ ======================================================================*/
16304+
16305+#define CS_CHECK(fn, ret) \
16306+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
16307+
16308+static int acx_cs_config(struct pcmcia_device *link)
16309+{
16310+ tuple_t tuple;
16311+ cisparse_t parse;
16312+ local_info_t *local = link->priv;
16313+ int last_fn, last_ret;
16314+ u_char buf[64];
16315+ win_req_t req;
16316+ memreq_t map;
16317+// int i;
16318+// acx_device_t *adev;
16319+
16320+// adev = (acx_device_t *)link->priv;
16321+
16322+ DEBUG(0, "acx_cs_config(0x%p)\n", link);
16323+
16324+ /*
16325+ In this loop, we scan the CIS for configuration table entries,
16326+ each of which describes a valid card configuration, including
16327+ voltage, IO window, memory window, and interrupt settings.
16328+
16329+ We make no assumptions about the card to be configured: we use
16330+ just the information available in the CIS. In an ideal world,
16331+ this would work for any PCMCIA card, but it requires a complete
16332+ and accurate CIS. In practice, a driver usually "knows" most of
16333+ these things without consulting the CIS, and most client drivers
16334+ will only use the CIS to fill in implementation-defined details.
16335+ */
16336+ tuple.Attributes = 0;
16337+ tuple.TupleData = (cisdata_t *)buf;
16338+ tuple.TupleDataMax = sizeof(buf);
16339+ tuple.TupleOffset = 0;
16340+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
16341+
16342+ /* don't trust the CIS on this; Linksys got it wrong */
16343+ //link->conf.Present = 0x63;
16344+
16345+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
16346+ while (1) {
16347+ cistpl_cftable_entry_t dflt = { 0 };
16348+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
16349+ if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
16350+ pcmcia_parse_tuple(link, &tuple, &parse) != 0)
16351+ goto next_entry;
16352+
16353+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
16354+ if (cfg->index == 0) goto next_entry;
16355+ link->conf.ConfigIndex = cfg->index;
16356+
16357+ /* Does this card need audio output? */
16358+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
16359+ link->conf.Attributes |= CONF_ENABLE_SPKR;
16360+ link->conf.Status = CCSR_AUDIO_ENA;
16361+ }
16362+
16363+ /* Use power settings for Vcc and Vpp if present */
16364+ /* Note that the CIS values need to be rescaled */
16365+ if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
16366+ link->conf.Vpp =
16367+ cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
16368+ else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
16369+ link->conf.Vpp =
16370+ dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
16371+
16372+ /* Do we need to allocate an interrupt? */
16373+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
16374+ link->conf.Attributes |= CONF_ENABLE_IRQ;
16375+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
16376+ cistpl_mem_t *mem =
16377+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
16378+// req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_AM|WIN_ENABLE|WIN_USE_WAIT;
16379+ req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE|WIN_USE_WAIT;
16380+ req.Base = mem->win[0].host_addr;
16381+ req.Size = mem->win[0].len;
16382+ req.Size=0x1000;
16383+ req.AccessSpeed = 0;
16384+ if (pcmcia_request_window(&link, &req, &link->win) != 0)
16385+ goto next_entry;
16386+ map.Page = 0; map.CardOffset = mem->win[0].card_addr;
16387+ if (pcmcia_map_mem_page(link->win, &map) != 0)
16388+ goto next_entry;
16389+ else
16390+ printk(KERN_INFO "MEMORY WINDOW FOUND!!!\n");
16391+ }
16392+ /* If we got this far, we're cool! */
16393+ break;
16394+
16395+ next_entry:
16396+ CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
16397+ }
16398+
16399+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
16400+ printk(KERN_INFO "requesting Irq...\n");
16401+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
16402+ }
16403+
16404+ /*
16405+ This actually configures the PCMCIA socket -- setting up
16406+ the I/O windows and the interrupt mapping, and putting the
16407+ card and host interface into "Memory and IO" mode.
16408+ */
16409+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
16410+ DEBUG(0,"RequestConfiguration OK\n");
16411+
16412+
16413+ memwin.Base=req.Base;
16414+ memwin.Size=req.Size;
16415+
16416+ acx_init_netdev(local->ndev, &link->dev, memwin.Base, memwin.Size, link->irq.AssignedIRQ);
16417+
16418+#if 1
16419+ /*
16420+ At this point, the dev_node_t structure(s) need to be
16421+ initialized and arranged in a linked list at link->dev_node.
16422+ */
16423+ strcpy(local->node.dev_name, local->ndev->name );
16424+ local->node.major = local->node.minor = 0;
16425+ link->dev_node = &local->node;
16426+
16427+ /* Finally, report what we've done */
16428+ printk(KERN_INFO "%s: index 0x%02x: ",
16429+ local->ndev->name, link->conf.ConfigIndex);
16430+#endif
16431+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
16432+ printk("irq %d", link->irq.AssignedIRQ);
16433+ if (link->io.NumPorts1)
16434+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
16435+ link->io.BasePort1+link->io.NumPorts1-1);
16436+ if (link->io.NumPorts2)
16437+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
16438+ link->io.BasePort2+link->io.NumPorts2-1);
16439+ if (link->win)
16440+ printk(", mem 0x%06lx-0x%06lx\n", req.Base,
16441+ req.Base+req.Size-1);
16442+ return 0;
16443+
16444+ cs_failed:
16445+ cs_error(link, last_fn, last_ret);
16446+ acx_cs_release(link);
16447+ return -ENODEV;
16448+} /* acx_config */
16449+
16450+/*======================================================================
16451+
16452+ After a card is removed, acx_release() will unregister the
16453+ device, and release the PCMCIA configuration. If the device is
16454+ still open, this will be postponed until it is closed.
16455+
16456+ ======================================================================*/
16457+
16458+static void acx_cs_release(struct pcmcia_device *link)
16459+{
16460+ DEBUG(0, "acx_release(0x%p)\n", link);
16461+ acxmem_e_remove(link);
16462+ pcmcia_disable_device(link);
16463+}
16464+
16465+static int acx_cs_suspend(struct pcmcia_device *link)
16466+{
16467+ local_info_t *local = link->priv;
16468+
16469+ pm_message_t state;
16470+ acxmem_e_suspend ( local->ndev, state);
16471+ /* Already done in suspend
16472+ * netif_device_detach(local->ndev); */
16473+
16474+ return 0;
16475+}
16476+
16477+static int acx_cs_resume(struct pcmcia_device *link)
16478+{
16479+ local_info_t *local = link->priv;
16480+
16481+ FN_ENTER;
16482+ resume_ndev = local->ndev;
16483+
16484+ schedule_work( &fw_resume_work );
16485+
16486+ /* Already done in suspend
16487+ if (link->open) {
16488+ // do we need reset for ACX, if so what function nane is ?
16489+ //reset_acx_card(local->eth_dev);
16490+ netif_device_attach(local->ndev);
16491+ } */
16492+
16493+ FN_EXIT0;
16494+ return 0;
16495+}
16496+
16497+static struct pcmcia_device_id acx_ids[] = {
16498+ PCMCIA_DEVICE_MANF_CARD(0x0097, 0x8402),
16499+ PCMCIA_DEVICE_MANF_CARD(0x0250, 0xb001),
16500+ PCMCIA_DEVICE_NULL,
16501+};
16502+MODULE_DEVICE_TABLE(pcmcia, acx_ids);
16503+
16504+static struct pcmcia_driver acx_driver = {
16505+ .owner = THIS_MODULE,
16506+ .drv = {
16507+ .name = "acx_cs",
16508+ },
16509+ .probe = acx_cs_probe,
16510+ .remove = acx_cs_detach,
16511+ .id_table = acx_ids,
16512+ .suspend = acx_cs_suspend,
16513+ .resume = acx_cs_resume,
16514+};
16515+
16516+int acx_cs_init(void)
16517+{
16518+ /* return success if at least one succeeded */
16519+ DEBUG(0, "acxcs_init()\n");
16520+ return pcmcia_register_driver(&acx_driver);
16521+}
16522+
16523+void acx_cs_cleanup(void)
16524+{
16525+ pcmcia_unregister_driver(&acx_driver);
16526+}
16527+
16528+/*
16529+ This program is free software; you can redistribute it and/or
16530+ modify it under the terms of the GNU General Public License
16531+ as published by the Free Software Foundation; either version 2
16532+ of the License, or (at your option) any later version.
16533+
16534+ This program is distributed in the hope that it will be useful,
16535+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16536+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16537+ GNU General Public License for more details.
16538+
16539+ In addition:
16540+
16541+ Redistribution and use in source and binary forms, with or without
16542+ modification, are permitted provided that the following conditions
16543+ are met:
16544+
16545+ 1. Redistributions of source code must retain the above copyright
16546+ notice, this list of conditions and the following disclaimer.
16547+ 2. Redistributions in binary form must reproduce the above copyright
16548+ notice, this list of conditions and the following disclaimer in the
16549+ documentation and/or other materials provided with the distribution.
16550+ 3. The name of the author may not be used to endorse or promote
16551+ products derived from this software without specific prior written
16552+ permission.
16553+
16554+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16555+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16556+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16557+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
16558+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16559+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16560+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16561+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16562+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
16563+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
16564+ POSSIBILITY OF SUCH DAMAGE.
16565+*/
16566+
16567+MODULE_DESCRIPTION( "ACX Cardbus Driver" );
16568+MODULE_LICENSE( "GPL" );
16569+
16570Index: linux-2.6.22/drivers/net/wireless/acx/htcsable_acx.c
16571===================================================================
16572--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16573+++ linux-2.6.22/drivers/net/wireless/acx/htcsable_acx.c 2007-08-23 18:34:19.000000000 +0200
16574@@ -0,0 +1,118 @@
16575+/*
16576+ * WLAN (TI TNETW1100B) support in the HTC Sable
16577+ *
16578+ * Copyright (c) 2006 SDG Systems, LLC
16579+ *
16580+ * This file is subject to the terms and conditions of the GNU General Public
16581+ * License. See the file COPYING in the main directory of this archive for
16582+ * more details.
16583+ *
16584+ * 28-March-2006 Todd Blumer <todd@sdgsystems.com>
16585+ */
16586+
16587+
16588+#include <linux/kernel.h>
16589+#include <linux/platform_device.h>
16590+#include <linux/delay.h>
16591+
16592+#include <asm/hardware.h>
16593+
16594+#include <asm/arch/pxa-regs.h>
16595+#include <linux/mfd/asic3_base.h>
16596+#include <asm/arch/htcsable-gpio.h>
16597+#include <asm/arch/htcsable-asic.h>
16598+#include <asm/io.h>
16599+
16600+#include "acx_hw.h"
16601+
16602+#define WLAN_BASE PXA_CS2_PHYS
16603+
16604+/*
16605+off: b15 c8 d3
16606+on: d3 c8 b5 b5-
16607+*/
16608+
16609+#define GPIO_NR_HTCSABLE_ACX111 111
16610+
16611+static int
16612+htcsable_wlan_stop( void );
16613+
16614+static int
16615+htcsable_wlan_start( void )
16616+{
16617+ printk( "htcsable_wlan_start\n" );
16618+
16619+ /*asic3_set_gpio_out_c(&htcsable_asic3.dev, 1<<GPIOC_ACX_RESET, 0);*/
16620+ asic3_set_gpio_out_c(&htcsable_asic3.dev, 1<<GPIOC_ACX_PWR_3, 1<<GPIOC_ACX_PWR_3); /* related to acx */
16621+ SET_HTCSABLE_GPIO(ACX111, 1);
16622+ asic3_set_gpio_out_b(&htcsable_asic3.dev, 1<<GPIOB_ACX_PWR_1, 1<<GPIOB_ACX_PWR_1);
16623+ asic3_set_gpio_out_d(&htcsable_asic3.dev, 1<<GPIOD_ACX_PWR_2, 1<<GPIOD_ACX_PWR_2);
16624+ mdelay(260);
16625+ asic3_set_gpio_out_c(&htcsable_asic3.dev, 1<<GPIOC_ACX_RESET, 1<<GPIOC_ACX_RESET);
16626+
16627+ return 0;
16628+}
16629+
16630+static int
16631+htcsable_wlan_stop( void )
16632+{
16633+ printk( "htcsable_wlan_stop\n" );
16634+ asic3_set_gpio_out_b(&htcsable_asic3.dev, 1<<GPIOB_ACX_PWR_1, 0);
16635+ asic3_set_gpio_out_c(&htcsable_asic3.dev, 1<<GPIOC_ACX_RESET, 0);
16636+ asic3_set_gpio_out_d(&htcsable_asic3.dev, 1<<GPIOD_ACX_PWR_2, 0);
16637+ SET_HTCSABLE_GPIO(ACX111, 0); /* not necessary to power down this one? */
16638+ asic3_set_gpio_out_c(&htcsable_asic3.dev, 1<<GPIOC_ACX_PWR_3, 0); /* not necessary to power down this one? */
16639+
16640+ return 0;
16641+}
16642+
16643+static struct resource acx_resources[] = {
16644+ [0] = {
16645+ .start = WLAN_BASE,
16646+ .end = WLAN_BASE + 0x20,
16647+ .flags = IORESOURCE_MEM,
16648+ },
16649+ [1] = {
16650+// .start = asic3_irq_base(&htcsable_asic3.dev) + ASIC3_GPIOC_IRQ_BASE+GPIOC_WIFI_IRQ_N,
16651+// .end = asic3_irq_base(&htcsable_asic3.dev) + ASIC3_GPIOC_IRQ_BASE+GPIOC_WIFI_IRQ_N,
16652+ .flags = IORESOURCE_IRQ,
16653+ },
16654+};
16655+
16656+static struct acx_hardware_data acx_data = {
16657+ .start_hw = htcsable_wlan_start,
16658+ .stop_hw = htcsable_wlan_stop,
16659+};
16660+
16661+static struct platform_device acx_device = {
16662+ .name = "acx-mem",
16663+ .dev = {
16664+ .platform_data = &acx_data,
16665+ },
16666+ .num_resources = ARRAY_SIZE( acx_resources ),
16667+ .resource = acx_resources,
16668+};
16669+
16670+static int __init
16671+htcsable_wlan_init( void )
16672+{
16673+ printk( "htcsable_wlan_init: acx-mem platform_device_register\n" );
16674+ acx_device.resource[1].start = asic3_irq_base(&htcsable_asic3.dev) + ASIC3_GPIOB_IRQ_BASE+GPIOB_ACX_IRQ_N;
16675+ acx_device.resource[1].end = asic3_irq_base(&htcsable_asic3.dev) + ASIC3_GPIOB_IRQ_BASE+GPIOB_ACX_IRQ_N;
16676+ return platform_device_register( &acx_device );
16677+}
16678+
16679+
16680+static void __exit
16681+htcsable_wlan_exit( void )
16682+{
16683+ platform_device_unregister( &acx_device );
16684+}
16685+
16686+module_init( htcsable_wlan_init );
16687+module_exit( htcsable_wlan_exit );
16688+
16689+MODULE_AUTHOR( "Todd Blumer <todd@sdgsystems.com>" );
16690+MODULE_DESCRIPTION( "WLAN driver for HTC Sable" );
16691+MODULE_LICENSE( "GPL" );
16692+
16693Index: linux-2.6.22/drivers/net/wireless/acx/htcuniversal_acx.c
16694===================================================================
16695--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16696+++ linux-2.6.22/drivers/net/wireless/acx/htcuniversal_acx.c 2007-08-23 18:34:19.000000000 +0200
16697@@ -0,0 +1,108 @@
16698+/*
16699+ * WLAN (TI TNETW1100B) support in the HTC Universal
16700+ *
16701+ * Copyright (c) 2006 SDG Systems, LLC
16702+ *
16703+ * This file is subject to the terms and conditions of the GNU General Public
16704+ * License. See the file COPYING in the main directory of this archive for
16705+ * more details.
16706+ *
16707+ * 28-March-2006 Todd Blumer <todd@sdgsystems.com>
16708+ */
16709+
16710+
16711+#include <linux/kernel.h>
16712+#include <linux/platform_device.h>
16713+#include <linux/delay.h>
16714+
16715+#include <asm/hardware.h>
16716+
16717+#include <asm/arch/pxa-regs.h>
16718+#include <linux/soc/asic3_base.h>
16719+#include <asm/arch/htcuniversal-gpio.h>
16720+#include <asm/arch/htcuniversal-asic.h>
16721+#include <asm/io.h>
16722+
16723+#include "acx_hw.h"
16724+
16725+#define WLAN_BASE PXA_CS2_PHYS
16726+
16727+
16728+static int
16729+htcuniversal_wlan_start( void )
16730+{
16731+ htcuniversal_egpio_enable(1<<EGPIO6_WIFI_ON);
16732+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_WIFI_PWR1_ON, 1<<GPIOC_WIFI_PWR1_ON);
16733+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_WIFI_PWR3_ON, 1<<GPIOD_WIFI_PWR3_ON);
16734+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_WIFI_PWR2_ON, 1<<GPIOD_WIFI_PWR2_ON);
16735+ mdelay(100);
16736+
16737+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_WIFI_RESET, 0);
16738+ mdelay(100);
16739+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_WIFI_RESET, 1<<GPIOC_WIFI_RESET);
16740+ mdelay(100);
16741+ return 0;
16742+}
16743+
16744+static int
16745+htcuniversal_wlan_stop( void )
16746+{
16747+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_WIFI_RESET, 0);
16748+
16749+ htcuniversal_egpio_disable(1<<EGPIO6_WIFI_ON);
16750+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_WIFI_PWR1_ON, 0);
16751+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_WIFI_PWR2_ON, 0);
16752+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_WIFI_PWR3_ON, 0);
16753+ return 0;
16754+}
16755+
16756+static struct resource acx_resources[] = {
16757+ [0] = {
16758+ .start = WLAN_BASE,
16759+ .end = WLAN_BASE + 0x20,
16760+ .flags = IORESOURCE_MEM,
16761+ },
16762+ [1] = {
16763+// .start = asic3_irq_base(&htcuniversal_asic3.dev) + ASIC3_GPIOC_IRQ_BASE+GPIOC_WIFI_IRQ_N,
16764+// .end = asic3_irq_base(&htcuniversal_asic3.dev) + ASIC3_GPIOC_IRQ_BASE+GPIOC_WIFI_IRQ_N,
16765+ .flags = IORESOURCE_IRQ,
16766+ },
16767+};
16768+
16769+static struct acx_hardware_data acx_data = {
16770+ .start_hw = htcuniversal_wlan_start,
16771+ .stop_hw = htcuniversal_wlan_stop,
16772+};
16773+
16774+static struct platform_device acx_device = {
16775+ .name = "acx-mem",
16776+ .dev = {
16777+ .platform_data = &acx_data,
16778+ },
16779+ .num_resources = ARRAY_SIZE( acx_resources ),
16780+ .resource = acx_resources,
16781+};
16782+
16783+static int __init
16784+htcuniversal_wlan_init( void )
16785+{
16786+ printk( "htcuniversal_wlan_init: acx-mem platform_device_register\n" );
16787+ acx_device.resource[1].start = asic3_irq_base(&htcuniversal_asic3.dev) + ASIC3_GPIOC_IRQ_BASE+GPIOC_WIFI_IRQ_N;
16788+ acx_device.resource[1].end = asic3_irq_base(&htcuniversal_asic3.dev) + ASIC3_GPIOC_IRQ_BASE+GPIOC_WIFI_IRQ_N;
16789+ return platform_device_register( &acx_device );
16790+}
16791+
16792+
16793+static void __exit
16794+htcuniversal_wlan_exit( void )
16795+{
16796+ platform_device_unregister( &acx_device );
16797+}
16798+
16799+module_init( htcuniversal_wlan_init );
16800+module_exit( htcuniversal_wlan_exit );
16801+
16802+MODULE_AUTHOR( "Todd Blumer <todd@sdgsystems.com>" );
16803+MODULE_DESCRIPTION( "WLAN driver for HTC Universal" );
16804+MODULE_LICENSE( "GPL" );
16805+
16806Index: linux-2.6.22/drivers/net/wireless/acx/hx4700_acx.c
16807===================================================================
16808--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16809+++ linux-2.6.22/drivers/net/wireless/acx/hx4700_acx.c 2007-08-23 18:34:19.000000000 +0200
16810@@ -0,0 +1,108 @@
16811+/*
16812+ * WLAN (TI TNETW1100B) support in the hx470x.
16813+ *
16814+ * Copyright (c) 2006 SDG Systems, LLC
16815+ *
16816+ * This file is subject to the terms and conditions of the GNU General Public
16817+ * License. See the file COPYING in the main directory of this archive for
16818+ * more details.
16819+ *
16820+ * 28-March-2006 Todd Blumer <todd@sdgsystems.com>
16821+ */
16822+
16823+
16824+#include <linux/kernel.h>
16825+#include <linux/platform_device.h>
16826+#include <linux/delay.h>
16827+#include <linux/leds.h>
16828+
16829+#include <asm/hardware.h>
16830+
16831+#include <asm/arch/pxa-regs.h>
16832+#include <asm/arch/hx4700-gpio.h>
16833+#include <asm/arch/hx4700-core.h>
16834+#include <asm/io.h>
16835+
16836+#include "acx_hw.h"
16837+
16838+#define WLAN_OFFSET 0x1000000
16839+#define WLAN_BASE (PXA_CS5_PHYS+WLAN_OFFSET)
16840+
16841+
16842+static int
16843+hx4700_wlan_start( void )
16844+{
16845+ SET_HX4700_GPIO( WLAN_RESET_N, 0 );
16846+ mdelay(5);
16847+ hx4700_egpio_enable( EGPIO0_VCC_3V3_EN );
16848+ mdelay(100);
16849+ hx4700_egpio_enable( EGPIO7_VCC_3V3_WL_EN );
16850+ mdelay(150);
16851+ hx4700_egpio_enable( EGPIO1_WL_VREG_EN | EGPIO2_VCC_2V1_WL_EN |
16852+ EGPIO6_WL1V8_EN );
16853+ mdelay(10);
16854+ SET_HX4700_GPIO( WLAN_RESET_N, 1 );
16855+ mdelay(50);
16856+ led_trigger_event_shared(hx4700_radio_trig, LED_FULL);
16857+ return 0;
16858+}
16859+
16860+static int
16861+hx4700_wlan_stop( void )
16862+{
16863+ hx4700_egpio_disable( EGPIO0_VCC_3V3_EN | EGPIO1_WL_VREG_EN |
16864+ EGPIO7_VCC_3V3_WL_EN | EGPIO2_VCC_2V1_WL_EN |
16865+ EGPIO6_WL1V8_EN );
16866+ SET_HX4700_GPIO( WLAN_RESET_N, 0 );
16867+ led_trigger_event_shared(hx4700_radio_trig, LED_OFF);
16868+ return 0;
16869+}
16870+
16871+static struct resource acx_resources[] = {
16872+ [0] = {
16873+ .start = WLAN_BASE,
16874+ .end = WLAN_BASE + 0x20,
16875+ .flags = IORESOURCE_MEM,
16876+ },
16877+ [1] = {
16878+ .start = HX4700_IRQ(WLAN_IRQ_N),
16879+ .end = HX4700_IRQ(WLAN_IRQ_N),
16880+ .flags = IORESOURCE_IRQ,
16881+ },
16882+};
16883+
16884+static struct acx_hardware_data acx_data = {
16885+ .start_hw = hx4700_wlan_start,
16886+ .stop_hw = hx4700_wlan_stop,
16887+};
16888+
16889+static struct platform_device acx_device = {
16890+ .name = "acx-mem",
16891+ .dev = {
16892+ .platform_data = &acx_data,
16893+ },
16894+ .num_resources = ARRAY_SIZE( acx_resources ),
16895+ .resource = acx_resources,
16896+};
16897+
16898+static int __init
16899+hx4700_wlan_init( void )
16900+{
16901+ printk( "hx4700_wlan_init: acx-mem platform_device_register\n" );
16902+ return platform_device_register( &acx_device );
16903+}
16904+
16905+
16906+static void __exit
16907+hx4700_wlan_exit( void )
16908+{
16909+ platform_device_unregister( &acx_device );
16910+}
16911+
16912+module_init( hx4700_wlan_init );
16913+module_exit( hx4700_wlan_exit );
16914+
16915+MODULE_AUTHOR( "Todd Blumer <todd@sdgsystems.com>" );
16916+MODULE_DESCRIPTION( "WLAN driver for iPAQ hx4700" );
16917+MODULE_LICENSE( "GPL" );
16918+
16919Index: linux-2.6.22/drivers/net/wireless/acx/ioctl.c
16920===================================================================
16921--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16922+++ linux-2.6.22/drivers/net/wireless/acx/ioctl.c 2007-08-23 18:34:19.000000000 +0200
16923@@ -0,0 +1,2748 @@
16924+/***********************************************************************
16925+** Copyright (C) 2003 ACX100 Open Source Project
16926+**
16927+** The contents of this file are subject to the Mozilla Public
16928+** License Version 1.1 (the "License"); you may not use this file
16929+** except in compliance with the License. You may obtain a copy of
16930+** the License at http://www.mozilla.org/MPL/
16931+**
16932+** Software distributed under the License is distributed on an "AS
16933+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16934+** implied. See the License for the specific language governing
16935+** rights and limitations under the License.
16936+**
16937+** Alternatively, the contents of this file may be used under the
16938+** terms of the GNU Public License version 2 (the "GPL"), in which
16939+** case the provisions of the GPL are applicable instead of the
16940+** above. If you wish to allow the use of your version of this file
16941+** only under the terms of the GPL and not to allow others to use
16942+** your version of this file under the MPL, indicate your decision
16943+** by deleting the provisions above and replace them with the notice
16944+** and other provisions required by the GPL. If you do not delete
16945+** the provisions above, a recipient may use your version of this
16946+** file under either the MPL or the GPL.
16947+** ---------------------------------------------------------------------
16948+** Inquiries regarding the ACX100 Open Source Project can be
16949+** made directly to:
16950+**
16951+** acx100-users@lists.sf.net
16952+** http://acx100.sf.net
16953+** ---------------------------------------------------------------------
16954+*/
16955+
16956+#include <linux/version.h>
16957+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
16958+#include <linux/config.h>
16959+#endif
16960+#include <linux/kernel.h>
16961+#include <linux/types.h>
16962+#include <asm/io.h>
16963+/* #include <asm/uaccess.h> */ /* required for 2.4.x kernels; verify_write() */
16964+#include <linux/if_arp.h>
16965+#include <linux/wireless.h>
16966+#include <net/iw_handler.h>
16967+
16968+#include "acx.h"
16969+
16970+
16971+/***********************************************************************
16972+*/
16973+
16974+/* channel frequencies
16975+ * TODO: Currently, every other 802.11 driver keeps its own copy of this. In
16976+ * the long run this should be integrated into ieee802_11.h or wireless.h or
16977+ * whatever IEEE802.11x framework evolves */
16978+static const u16 acx_channel_freq[] = {
16979+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
16980+ 2447, 2452, 2457, 2462, 2467, 2472, 2484,
16981+};
16982+
16983+
16984+/***********************************************************************
16985+** acx_ioctl_commit
16986+*/
16987+static int
16988+acx_ioctl_commit(struct net_device *ndev,
16989+ struct iw_request_info *info,
16990+ union iwreq_data *wrqu,
16991+ char *extra)
16992+{
16993+ acx_device_t *adev = ndev2adev(ndev);
16994+
16995+ FN_ENTER;
16996+
16997+ acx_sem_lock(adev);
16998+ if (ACX_STATE_IFACE_UP & adev->dev_state_mask)
16999+ acx_s_update_card_settings(adev);
17000+ acx_sem_unlock(adev);
17001+
17002+ FN_EXIT0;
17003+ return OK;
17004+}
17005+
17006+
17007+/***********************************************************************
17008+*/
17009+static int
17010+acx_ioctl_get_name(
17011+ struct net_device *ndev,
17012+ struct iw_request_info *info,
17013+ union iwreq_data *wrqu,
17014+ char *extra)
17015+{
17016+ acx_device_t *adev = ndev2adev(ndev);
17017+ static const char * const names[] = { "IEEE 802.11b+/g+", "IEEE 802.11b+" };
17018+
17019+ strcpy(wrqu->name, names[IS_ACX111(adev) ? 0 : 1]);
17020+
17021+ return OK;
17022+}
17023+
17024+
17025+/***********************************************************************
17026+** acx_ioctl_set_freq
17027+*/
17028+static int
17029+acx_ioctl_set_freq(
17030+ struct net_device *ndev,
17031+ struct iw_request_info *info,
17032+ union iwreq_data *wrqu,
17033+ char *extra)
17034+{
17035+ acx_device_t *adev = ndev2adev(ndev);
17036+ int channel = -1;
17037+ unsigned int mult = 1;
17038+ int result;
17039+
17040+ FN_ENTER;
17041+
17042+ if (wrqu->freq.e == 0 && wrqu->freq.m <= 1000) {
17043+ /* Setting by channel number */
17044+ channel = wrqu->freq.m;
17045+ } else {
17046+ /* If setting by frequency, convert to a channel */
17047+ int i;
17048+
17049+ for (i = 0; i < (6 - wrqu->freq.e); i++)
17050+ mult *= 10;
17051+
17052+ for (i = 1; i <= 14; i++)
17053+ if (wrqu->freq.m == acx_channel_freq[i - 1] * mult)
17054+ channel = i;
17055+ }
17056+
17057+ if (channel > 14) {
17058+ result = -EINVAL;
17059+ goto end;
17060+ }
17061+
17062+ acx_sem_lock(adev);
17063+
17064+ adev->channel = channel;
17065+ /* hmm, the following code part is strange, but this is how
17066+ * it was being done before... */
17067+ log(L_IOCTL, "Changing to channel %d\n", channel);
17068+ SET_BIT(adev->set_mask, GETSET_CHANNEL);
17069+
17070+ result = -EINPROGRESS; /* need to call commit handler */
17071+
17072+ acx_sem_unlock(adev);
17073+end:
17074+ FN_EXIT1(result);
17075+ return result;
17076+}
17077+
17078+
17079+/***********************************************************************
17080+*/
17081+static inline int
17082+acx_ioctl_get_freq(
17083+ struct net_device *ndev,
17084+ struct iw_request_info *info,
17085+ union iwreq_data *wrqu,
17086+ char *extra)
17087+{
17088+ acx_device_t *adev = ndev2adev(ndev);
17089+ wrqu->freq.e = 0;
17090+ wrqu->freq.m = adev->channel;
17091+ return OK;
17092+}
17093+
17094+
17095+/***********************************************************************
17096+** acx_ioctl_set_mode
17097+*/
17098+static int
17099+acx_ioctl_set_mode(
17100+ struct net_device *ndev,
17101+ struct iw_request_info *info,
17102+ union iwreq_data *wrqu,
17103+ char *extra)
17104+{
17105+ acx_device_t *adev = ndev2adev(ndev);
17106+ int result;
17107+
17108+ FN_ENTER;
17109+
17110+ acx_sem_lock(adev);
17111+
17112+ switch (wrqu->mode) {
17113+ case IW_MODE_AUTO:
17114+ adev->mode = ACX_MODE_OFF;
17115+ break;
17116+ case IW_MODE_MONITOR:
17117+ adev->mode = ACX_MODE_MONITOR;
17118+ break;
17119+ case IW_MODE_ADHOC:
17120+ adev->mode = ACX_MODE_0_ADHOC;
17121+ break;
17122+ case IW_MODE_INFRA:
17123+ adev->mode = ACX_MODE_2_STA;
17124+ break;
17125+ case IW_MODE_MASTER:
17126+ printk("acx: master mode (HostAP) is very, very "
17127+ "experimental! It might work partially, but "
17128+ "better get prepared for nasty surprises "
17129+ "at any time\n");
17130+ adev->mode = ACX_MODE_3_AP;
17131+ break;
17132+ case IW_MODE_REPEAT:
17133+ case IW_MODE_SECOND:
17134+ default:
17135+ result = -EOPNOTSUPP;
17136+ goto end_unlock;
17137+ }
17138+
17139+ log(L_ASSOC, "new adev->mode=%d\n", adev->mode);
17140+ SET_BIT(adev->set_mask, GETSET_MODE);
17141+ result = -EINPROGRESS;
17142+
17143+end_unlock:
17144+ acx_sem_unlock(adev);
17145+
17146+ FN_EXIT1(result);
17147+ return result;
17148+}
17149+
17150+
17151+/***********************************************************************
17152+*/
17153+static int
17154+acx_ioctl_get_mode(
17155+ struct net_device *ndev,
17156+ struct iw_request_info *info,
17157+ union iwreq_data *wrqu,
17158+ char *extra)
17159+{
17160+ acx_device_t *adev = ndev2adev(ndev);
17161+ int result = 0;
17162+
17163+ switch (adev->mode) {
17164+ case ACX_MODE_OFF:
17165+ wrqu->mode = IW_MODE_AUTO; break;
17166+ case ACX_MODE_MONITOR:
17167+ wrqu->mode = IW_MODE_MONITOR; break;
17168+ case ACX_MODE_0_ADHOC:
17169+ wrqu->mode = IW_MODE_ADHOC; break;
17170+ case ACX_MODE_2_STA:
17171+ wrqu->mode = IW_MODE_INFRA; break;
17172+ case ACX_MODE_3_AP:
17173+ wrqu->mode = IW_MODE_MASTER; break;
17174+ default:
17175+ result = -EOPNOTSUPP;
17176+ }
17177+ return result;
17178+}
17179+
17180+
17181+/***********************************************************************
17182+*/
17183+static int
17184+acx_ioctl_set_sens(
17185+ struct net_device *ndev,
17186+ struct iw_request_info *info,
17187+ union iwreq_data *wrqu,
17188+ char *extra)
17189+{
17190+ struct iw_param *vwrq = &wrqu->sens;
17191+ acx_device_t *adev = ndev2adev(ndev);
17192+
17193+ acx_sem_lock(adev);
17194+
17195+ adev->sensitivity = (1 == vwrq->disabled) ? 0 : vwrq->value;
17196+ SET_BIT(adev->set_mask, GETSET_SENSITIVITY);
17197+
17198+ acx_sem_unlock(adev);
17199+
17200+ return -EINPROGRESS;
17201+}
17202+
17203+
17204+/***********************************************************************
17205+*/
17206+static int
17207+acx_ioctl_get_sens(
17208+ struct net_device *ndev,
17209+ struct iw_request_info *info,
17210+ union iwreq_data *wrqu,
17211+ char *extra)
17212+{
17213+ struct iw_param *vwrq = &wrqu->sens;
17214+ acx_device_t *adev = ndev2adev(ndev);
17215+
17216+ if (IS_USB(adev))
17217+ /* setting the PHY reg via fw cmd doesn't work yet */
17218+ return -EOPNOTSUPP;
17219+
17220+ /* acx_sem_lock(adev); */
17221+
17222+ vwrq->value = adev->sensitivity;
17223+ vwrq->disabled = (vwrq->value == 0);
17224+ vwrq->fixed = 1;
17225+
17226+ /* acx_sem_unlock(adev); */
17227+
17228+ return OK;
17229+}
17230+
17231+
17232+/***********************************************************************
17233+** acx_ioctl_set_ap
17234+**
17235+** Sets the MAC address of the AP to associate with
17236+*/
17237+static int
17238+acx_ioctl_set_ap(
17239+ struct net_device *ndev,
17240+ struct iw_request_info *info,
17241+ union iwreq_data *wrqu,
17242+ char *extra)
17243+{
17244+ struct sockaddr *awrq = &wrqu->ap_addr;
17245+ acx_device_t *adev = ndev2adev(ndev);
17246+ int result = 0;
17247+ const u8 *ap;
17248+
17249+ FN_ENTER;
17250+ if (NULL == awrq) {
17251+ result = -EFAULT;
17252+ goto end;
17253+ }
17254+ if (ARPHRD_ETHER != awrq->sa_family) {
17255+ result = -EINVAL;
17256+ goto end;
17257+ }
17258+
17259+ ap = awrq->sa_data;
17260+ acxlog_mac(L_IOCTL, "set AP=", ap, "\n");
17261+
17262+ MAC_COPY(adev->ap, ap);
17263+
17264+ /* We want to start rescan in managed or ad-hoc mode,
17265+ ** otherwise just set adev->ap.
17266+ ** "iwconfig <if> ap <mac> mode managed": we must be able
17267+ ** to set ap _first_ and _then_ set mode */
17268+ switch (adev->mode) {
17269+ case ACX_MODE_0_ADHOC:
17270+ case ACX_MODE_2_STA:
17271+ /* FIXME: if there is a convention on what zero AP means,
17272+ ** please add a comment about that. I don't know of any --vda */
17273+ if (mac_is_zero(ap)) {
17274+ /* "off" == 00:00:00:00:00:00 */
17275+ MAC_BCAST(adev->ap);
17276+ log(L_IOCTL, "Not reassociating\n");
17277+ } else {
17278+ log(L_IOCTL, "Forcing reassociation\n");
17279+ SET_BIT(adev->set_mask, GETSET_RESCAN);
17280+ }
17281+ break;
17282+ }
17283+ result = -EINPROGRESS;
17284+end:
17285+ FN_EXIT1(result);
17286+ return result;
17287+}
17288+
17289+
17290+/***********************************************************************
17291+*/
17292+static int
17293+acx_ioctl_get_ap(
17294+ struct net_device *ndev,
17295+ struct iw_request_info *info,
17296+ union iwreq_data *wrqu,
17297+ char *extra)
17298+{
17299+ struct sockaddr *awrq = &wrqu->ap_addr;
17300+ acx_device_t *adev = ndev2adev(ndev);
17301+
17302+ if (ACX_STATUS_4_ASSOCIATED == adev->status) {
17303+ /* as seen in Aironet driver, airo.c */
17304+ MAC_COPY(awrq->sa_data, adev->bssid);
17305+ } else {
17306+ MAC_ZERO(awrq->sa_data);
17307+ }
17308+ awrq->sa_family = ARPHRD_ETHER;
17309+ return OK;
17310+}
17311+
17312+
17313+/***********************************************************************
17314+** acx_ioctl_get_aplist
17315+**
17316+** Deprecated in favor of iwscan.
17317+** We simply return the list of currently available stations in range,
17318+** don't do a new scan.
17319+*/
17320+static int
17321+acx_ioctl_get_aplist(
17322+ struct net_device *ndev,
17323+ struct iw_request_info *info,
17324+ union iwreq_data *wrqu,
17325+ char *extra)
17326+{
17327+ struct iw_point *dwrq = &wrqu->data;
17328+ acx_device_t *adev = ndev2adev(ndev);
17329+ struct sockaddr *address = (struct sockaddr *) extra;
17330+ struct iw_quality qual[IW_MAX_AP];
17331+ int i, cur;
17332+ int result = OK;
17333+
17334+ FN_ENTER;
17335+
17336+ /* we have AP list only in STA mode */
17337+ if (ACX_MODE_2_STA != adev->mode) {
17338+ result = -EOPNOTSUPP;
17339+ goto end;
17340+ }
17341+
17342+ cur = 0;
17343+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
17344+ struct client *bss = &adev->sta_list[i];
17345+ if (!bss->used) continue;
17346+ MAC_COPY(address[cur].sa_data, bss->bssid);
17347+ address[cur].sa_family = ARPHRD_ETHER;
17348+ qual[cur].level = bss->sir;
17349+ qual[cur].noise = bss->snr;
17350+#ifndef OLD_QUALITY
17351+ qual[cur].qual = acx_signal_determine_quality(qual[cur].level,
17352+ qual[cur].noise);
17353+#else
17354+ qual[cur].qual = (qual[cur].noise <= 100) ?
17355+ 100 - qual[cur].noise : 0;
17356+#endif
17357+ /* no scan: level/noise/qual not updated: */
17358+ qual[cur].updated = 0;
17359+ cur++;
17360+ }
17361+ if (cur) {
17362+ dwrq->flags = 1;
17363+ memcpy(extra + sizeof(struct sockaddr)*cur, &qual,
17364+ sizeof(struct iw_quality)*cur);
17365+ }
17366+ dwrq->length = cur;
17367+end:
17368+ FN_EXIT1(result);
17369+ return result;
17370+}
17371+
17372+
17373+/***********************************************************************
17374+*/
17375+static int
17376+acx_ioctl_set_scan(
17377+ struct net_device *ndev,
17378+ struct iw_request_info *info,
17379+ union iwreq_data *wrqu,
17380+ char *extra)
17381+{
17382+ acx_device_t *adev = ndev2adev(ndev);
17383+ int result;
17384+
17385+ FN_ENTER;
17386+
17387+ acx_sem_lock(adev);
17388+
17389+ /* don't start scan if device is not up yet */
17390+ if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
17391+ result = -EAGAIN;
17392+ goto end_unlock;
17393+ }
17394+
17395+ /* This is NOT a rescan for new AP!
17396+ ** Do not use SET_BIT(GETSET_RESCAN); */
17397+ acx_s_cmd_start_scan(adev);
17398+ result = OK;
17399+
17400+end_unlock:
17401+ acx_sem_unlock(adev);
17402+/* end: */
17403+ FN_EXIT1(result);
17404+ return result;
17405+}
17406+
17407+
17408+/***********************************************************************
17409+** acx_s_scan_add_station
17410+*/
17411+/* helper. not sure whether it's really a _s_leeping fn */
17412+static char*
17413+acx_s_scan_add_station(
17414+ acx_device_t *adev,
17415+ char *ptr,
17416+ char *end_buf,
17417+ struct client *bss)
17418+{
17419+ struct iw_event iwe;
17420+ char *ptr_rate;
17421+
17422+ FN_ENTER;
17423+
17424+ /* MAC address has to be added first */
17425+ iwe.cmd = SIOCGIWAP;
17426+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
17427+ MAC_COPY(iwe.u.ap_addr.sa_data, bss->bssid);
17428+ acxlog_mac(L_IOCTL, "scan, station address: ", bss->bssid, "\n");
17429+ ptr = iwe_stream_add_event(ptr, end_buf, &iwe, IW_EV_ADDR_LEN);
17430+
17431+ /* Add ESSID */
17432+ iwe.cmd = SIOCGIWESSID;
17433+ iwe.u.data.length = bss->essid_len;
17434+ iwe.u.data.flags = 1;
17435+ log(L_IOCTL, "scan, essid: %s\n", bss->essid);
17436+ ptr = iwe_stream_add_point(ptr, end_buf, &iwe, bss->essid);
17437+
17438+ /* Add mode */
17439+ iwe.cmd = SIOCGIWMODE;
17440+ if (bss->cap_info & (WF_MGMT_CAP_ESS | WF_MGMT_CAP_IBSS)) {
17441+ if (bss->cap_info & WF_MGMT_CAP_ESS)
17442+ iwe.u.mode = IW_MODE_MASTER;
17443+ else
17444+ iwe.u.mode = IW_MODE_ADHOC;
17445+ log(L_IOCTL, "scan, mode: %d\n", iwe.u.mode);
17446+ ptr = iwe_stream_add_event(ptr, end_buf, &iwe, IW_EV_UINT_LEN);
17447+ }
17448+
17449+ /* Add frequency */
17450+ iwe.cmd = SIOCGIWFREQ;
17451+ iwe.u.freq.m = acx_channel_freq[bss->channel - 1] * 100000;
17452+ iwe.u.freq.e = 1;
17453+ log(L_IOCTL, "scan, frequency: %d\n", iwe.u.freq.m);
17454+ ptr = iwe_stream_add_event(ptr, end_buf, &iwe, IW_EV_FREQ_LEN);
17455+
17456+ /* Add link quality */
17457+ iwe.cmd = IWEVQUAL;
17458+ /* FIXME: these values should be expressed in dBm, but we don't know
17459+ * how to calibrate it yet */
17460+ iwe.u.qual.level = bss->sir;
17461+ iwe.u.qual.noise = bss->snr;
17462+#ifndef OLD_QUALITY
17463+ iwe.u.qual.qual = acx_signal_determine_quality(iwe.u.qual.level,
17464+ iwe.u.qual.noise);
17465+#else
17466+ iwe.u.qual.qual = (iwe.u.qual.noise <= 100) ?
17467+ 100 - iwe.u.qual.noise : 0;
17468+#endif
17469+ iwe.u.qual.updated = 7;
17470+ log(L_IOCTL, "scan, link quality: %d/%d/%d\n",
17471+ iwe.u.qual.level, iwe.u.qual.noise, iwe.u.qual.qual);
17472+ ptr = iwe_stream_add_event(ptr, end_buf, &iwe, IW_EV_QUAL_LEN);
17473+
17474+ /* Add encryption */
17475+ iwe.cmd = SIOCGIWENCODE;
17476+ if (bss->cap_info & WF_MGMT_CAP_PRIVACY)
17477+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
17478+ else
17479+ iwe.u.data.flags = IW_ENCODE_DISABLED;
17480+ iwe.u.data.length = 0;
17481+ log(L_IOCTL, "scan, encryption flags: %X\n", iwe.u.data.flags);
17482+ ptr = iwe_stream_add_point(ptr, end_buf, &iwe, bss->essid);
17483+
17484+ /* add rates */
17485+ iwe.cmd = SIOCGIWRATE;
17486+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
17487+ ptr_rate = ptr + IW_EV_LCP_LEN;
17488+
17489+ {
17490+ u16 rate = bss->rate_cap;
17491+ const u8* p = acx_bitpos2ratebyte;
17492+ while (rate) {
17493+ if (rate & 1) {
17494+ iwe.u.bitrate.value = *p * 500000; /* units of 500kb/s */
17495+ log(L_IOCTL, "scan, rate: %d\n", iwe.u.bitrate.value);
17496+ ptr_rate = iwe_stream_add_value(ptr, ptr_rate, end_buf,
17497+ &iwe, IW_EV_PARAM_LEN);
17498+ }
17499+ rate >>= 1;
17500+ p++;
17501+ }}
17502+
17503+ if ((ptr_rate - ptr) > (ptrdiff_t)IW_EV_LCP_LEN)
17504+ ptr = ptr_rate;
17505+
17506+ /* drop remaining station data items for now */
17507+
17508+ FN_EXIT0;
17509+ return ptr;
17510+}
17511+
17512+
17513+/***********************************************************************
17514+ * acx_ioctl_get_scan
17515+ */
17516+static int
17517+acx_ioctl_get_scan(
17518+ struct net_device *ndev,
17519+ struct iw_request_info *info,
17520+ union iwreq_data *wrqu,
17521+ char *extra)
17522+{
17523+ struct iw_point *dwrq = &wrqu->data;
17524+ acx_device_t *adev = ndev2adev(ndev);
17525+ char *ptr = extra;
17526+ int i;
17527+ int result = OK;
17528+
17529+ FN_ENTER;
17530+
17531+ acx_sem_lock(adev);
17532+
17533+ /* no scan available if device is not up yet */
17534+ if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) {
17535+ log(L_IOCTL, "iface not up yet\n");
17536+ result = -EAGAIN;
17537+ goto end_unlock;
17538+ }
17539+
17540+#ifdef ENODATA_TO_BE_USED_AFTER_SCAN_ERROR_ONLY
17541+ if (adev->bss_table_count == 0) {
17542+ /* no stations found */
17543+ result = -ENODATA;
17544+ goto end_unlock;
17545+ }
17546+#endif
17547+
17548+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
17549+ struct client *bss = &adev->sta_list[i];
17550+ if (!bss->used) continue;
17551+ ptr = acx_s_scan_add_station(adev, ptr,
17552+ extra + IW_SCAN_MAX_DATA, bss);
17553+ }
17554+ dwrq->length = ptr - extra;
17555+ dwrq->flags = 0;
17556+
17557+end_unlock:
17558+ acx_sem_unlock(adev);
17559+/* end: */
17560+ FN_EXIT1(result);
17561+ return result;
17562+}
17563+
17564+
17565+/***********************************************************************
17566+** acx_ioctl_set_essid
17567+*/
17568+static int
17569+acx_ioctl_set_essid(
17570+ struct net_device *ndev,
17571+ struct iw_request_info *info,
17572+ union iwreq_data *wrqu,
17573+ char *extra)
17574+{
17575+ struct iw_point *dwrq = &wrqu->essid;
17576+ acx_device_t *adev = ndev2adev(ndev);
17577+ int len = dwrq->length;
17578+ int result;
17579+
17580+ FN_ENTER;
17581+
17582+ if (len < 0) {
17583+ result = -EINVAL;
17584+ goto end;
17585+ }
17586+
17587+ log(L_IOCTL, "set ESSID '%*s', length %d, flags 0x%04X\n",
17588+ len, extra, len, dwrq->flags);
17589+
17590+#if WIRELESS_EXT >= 21
17591+ /* WE 21 gives real ESSID strlen, not +1 (trailing zero):
17592+ * see LKML "[patch] drivers/net/wireless: correct reported ssid lengths" */
17593+ len += 1;
17594+#endif
17595+
17596+ acx_sem_lock(adev);
17597+
17598+ /* ESSID disabled? */
17599+ if (0 == dwrq->flags) {
17600+ adev->essid_active = 0;
17601+
17602+ } else {
17603+ if (len > IW_ESSID_MAX_SIZE) {
17604+ result = -E2BIG;
17605+ goto end_unlock;
17606+ }
17607+
17608+ if (len >= sizeof(adev->essid))
17609+ len = sizeof(adev->essid) - 1;
17610+ memcpy(adev->essid, extra, len);
17611+ adev->essid[len] = '\0';
17612+ /* Paranoia: just in case there is a '\0'... */
17613+ adev->essid_len = strlen(adev->essid);
17614+ adev->essid_active = 1;
17615+ }
17616+
17617+ SET_BIT(adev->set_mask, GETSET_RESCAN);
17618+
17619+ result = -EINPROGRESS;
17620+
17621+end_unlock:
17622+ acx_sem_unlock(adev);
17623+end:
17624+ FN_EXIT1(result);
17625+ return result;
17626+}
17627+
17628+
17629+/***********************************************************************
17630+*/
17631+static int
17632+acx_ioctl_get_essid(
17633+ struct net_device *ndev,
17634+ struct iw_request_info *info,
17635+ union iwreq_data *wrqu,
17636+ char *extra)
17637+{
17638+ struct iw_point *dwrq = &wrqu->essid;
17639+ acx_device_t *adev = ndev2adev(ndev);
17640+
17641+ dwrq->flags = adev->essid_active;
17642+ if (adev->essid_active) {
17643+ memcpy(extra, adev->essid, adev->essid_len);
17644+ extra[adev->essid_len] = '\0';
17645+ dwrq->length = adev->essid_len + 1;
17646+ dwrq->flags = 1;
17647+ }
17648+ return OK;
17649+}
17650+
17651+
17652+/***********************************************************************
17653+** acx_l_update_client_rates
17654+*/
17655+static void
17656+acx_l_update_client_rates(acx_device_t *adev, u16 rate)
17657+{
17658+ int i;
17659+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
17660+ client_t *clt = &adev->sta_list[i];
17661+ if (!clt->used) continue;
17662+ clt->rate_cfg = (clt->rate_cap & rate);
17663+ if (!clt->rate_cfg) {
17664+ /* no compatible rates left: kick client */
17665+ acxlog_mac(L_ASSOC, "client ",clt->address," kicked: "
17666+ "rates are not compatible anymore\n");
17667+ acx_l_sta_list_del(adev, clt);
17668+ continue;
17669+ }
17670+ clt->rate_cur &= clt->rate_cfg;
17671+ if (!clt->rate_cur) {
17672+ /* current rate become invalid, choose a valid one */
17673+ clt->rate_cur = 1 << lowest_bit(clt->rate_cfg);
17674+ }
17675+ if (IS_ACX100(adev))
17676+ clt->rate_100 = acx_bitpos2rate100[highest_bit(clt->rate_cur)];
17677+ clt->fallback_count = clt->stepup_count = 0;
17678+ clt->ignore_count = 16;
17679+ }
17680+ switch (adev->mode) {
17681+ case ACX_MODE_2_STA:
17682+ if (adev->ap_client && !adev->ap_client->used) {
17683+ /* Owwww... we kicked our AP!! :) */
17684+ SET_BIT(adev->set_mask, GETSET_RESCAN);
17685+ }
17686+ }
17687+}
17688+
17689+
17690+/***********************************************************************
17691+*/
17692+/* maps bits from acx111 rate to rate in Mbits */
17693+static const unsigned int
17694+acx111_rate_tbl[] = {
17695+ 1000000, /* 0 */
17696+ 2000000, /* 1 */
17697+ 5500000, /* 2 */
17698+ 6000000, /* 3 */
17699+ 9000000, /* 4 */
17700+ 11000000, /* 5 */
17701+ 12000000, /* 6 */
17702+ 18000000, /* 7 */
17703+ 22000000, /* 8 */
17704+ 24000000, /* 9 */
17705+ 36000000, /* 10 */
17706+ 48000000, /* 11 */
17707+ 54000000, /* 12 */
17708+ 500000, /* 13, should not happen */
17709+ 500000, /* 14, should not happen */
17710+ 500000, /* 15, should not happen */
17711+};
17712+
17713+/***********************************************************************
17714+ * acx_ioctl_set_rate
17715+ */
17716+static int
17717+acx_ioctl_set_rate(
17718+ struct net_device *ndev,
17719+ struct iw_request_info *info,
17720+ union iwreq_data *wrqu,
17721+ char *extra)
17722+{
17723+ struct iw_param *vwrq = &wrqu->param;
17724+ acx_device_t *adev = ndev2adev(ndev);
17725+ u16 txrate_cfg = 1;
17726+ unsigned long flags;
17727+ int autorate;
17728+ int result = -EINVAL;
17729+
17730+ FN_ENTER;
17731+ log(L_IOCTL, "rate %d fixed 0x%X disabled 0x%X flags 0x%X\n",
17732+ vwrq->value, vwrq->fixed, vwrq->disabled, vwrq->flags);
17733+
17734+ if ((0 == vwrq->fixed) || (1 == vwrq->fixed)) {
17735+ int i = VEC_SIZE(acx111_rate_tbl)-1;
17736+ if (vwrq->value == -1)
17737+ /* "iwconfig rate auto" --> choose highest */
17738+ vwrq->value = IS_ACX100(adev) ? 22000000 : 54000000;
17739+ while (i >= 0) {
17740+ if (vwrq->value == acx111_rate_tbl[i]) {
17741+ txrate_cfg <<= i;
17742+ i = 0;
17743+ break;
17744+ }
17745+ i--;
17746+ }
17747+ if (i == -1) { /* no matching rate */
17748+ result = -EINVAL;
17749+ goto end;
17750+ }
17751+ } else { /* rate N, N<1000 (driver specific): we don't use this */
17752+ result = -EOPNOTSUPP;
17753+ goto end;
17754+ }
17755+ /* now: only one bit is set in txrate_cfg, corresponding to
17756+ ** indicated rate */
17757+
17758+ autorate = (vwrq->fixed == 0) && (RATE111_1 != txrate_cfg);
17759+ if (autorate) {
17760+ /* convert 00100000 -> 00111111 */
17761+ txrate_cfg = (txrate_cfg<<1)-1;
17762+ }
17763+
17764+ if (IS_ACX100(adev)) {
17765+ txrate_cfg &= RATE111_ACX100_COMPAT;
17766+ if (!txrate_cfg) {
17767+ result = -ENOTSUPP; /* rate is not supported by acx100 */
17768+ goto end;
17769+ }
17770+ }
17771+
17772+ acx_sem_lock(adev);
17773+ acx_lock(adev, flags);
17774+
17775+ adev->rate_auto = autorate;
17776+ adev->rate_oper = txrate_cfg;
17777+ adev->rate_basic = txrate_cfg;
17778+ /* only do that in auto mode, non-auto will be able to use
17779+ * one specific Tx rate only anyway */
17780+ if (autorate) {
17781+ /* only use 802.11b base rates, for standard 802.11b H/W
17782+ * compatibility */
17783+ adev->rate_basic &= RATE111_80211B_COMPAT;
17784+ }
17785+ adev->rate_bcast = 1 << lowest_bit(txrate_cfg);
17786+ if (IS_ACX100(adev))
17787+ adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast);
17788+ acx_l_update_ratevector(adev);
17789+ acx_l_update_client_rates(adev, txrate_cfg);
17790+
17791+ /* Do/don't do tx rate fallback; beacon contents and rate */
17792+ SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES);
17793+ result = -EINPROGRESS;
17794+
17795+ acx_unlock(adev, flags);
17796+ acx_sem_unlock(adev);
17797+end:
17798+ FN_EXIT1(result);
17799+ return result;
17800+}
17801+
17802+
17803+/***********************************************************************
17804+** acx_ioctl_get_rate
17805+*/
17806+static int
17807+acx_ioctl_get_rate(
17808+ struct net_device *ndev,
17809+ struct iw_request_info *info,
17810+ union iwreq_data *wrqu,
17811+ char *extra)
17812+{
17813+ struct iw_param *vwrq = &wrqu->param;
17814+ acx_device_t *adev = ndev2adev(ndev);
17815+ unsigned long flags;
17816+ u16 rate;
17817+
17818+ acx_lock(adev, flags);
17819+ rate = adev->rate_oper;
17820+ if (adev->ap_client)
17821+ rate = adev->ap_client->rate_cur;
17822+ vwrq->value = acx111_rate_tbl[highest_bit(rate)];
17823+ vwrq->fixed = !adev->rate_auto;
17824+ vwrq->disabled = 0;
17825+ acx_unlock(adev, flags);
17826+
17827+ return OK;
17828+}
17829+
17830+static int
17831+acx_ioctl_set_rts(
17832+ struct net_device *ndev,
17833+ struct iw_request_info *info,
17834+ union iwreq_data *wrqu,
17835+ char *extra)
17836+{
17837+ struct iw_param *vwrq = &wrqu->rts;
17838+ acx_device_t *adev = ndev2adev(ndev);
17839+ int val = vwrq->value;
17840+
17841+ if (vwrq->disabled)
17842+ val = 2312;
17843+ if ((val < 0) || (val > 2312))
17844+ return -EINVAL;
17845+
17846+ adev->rts_threshold = val;
17847+ return OK;
17848+}
17849+
17850+static inline int
17851+acx_ioctl_get_rts(
17852+ struct net_device *ndev,
17853+ struct iw_request_info *info,
17854+ union iwreq_data *wrqu,
17855+ char *extra)
17856+{
17857+ struct iw_param *vwrq = &wrqu->rts;
17858+ acx_device_t *adev = ndev2adev(ndev);
17859+
17860+ vwrq->value = adev->rts_threshold;
17861+ vwrq->disabled = (vwrq->value >= 2312);
17862+ vwrq->fixed = 1;
17863+ return OK;
17864+}
17865+
17866+
17867+#if ACX_FRAGMENTATION
17868+static int
17869+acx_ioctl_set_frag(
17870+ struct net_device *ndev,
17871+ struct iw_request_info *info,
17872+ struct iw_param *vwrq,
17873+ char *extra)
17874+{
17875+ acx_device_t *adev = ndev2adev(ndev);
17876+ int val = vwrq->value;
17877+
17878+ if (vwrq->disabled)
17879+ val = 32767;
17880+ else
17881+ if ((val < 256) || (val > 2347))
17882+ return -EINVAL;
17883+
17884+ adev->frag_threshold = val;
17885+ return OK;
17886+}
17887+
17888+static inline int
17889+acx_ioctl_get_frag(
17890+ struct net_device *ndev,
17891+ struct iw_request_info *info,
17892+ union iwreq_data *wrqu,
17893+ char *extra)
17894+{
17895+ struct iw_param *vwrq = &wrqu->frag;
17896+ acx_device_t *adev = ndev2adev(ndev);
17897+
17898+ vwrq->value = adev->frag_threshold;
17899+ vwrq->disabled = (vwrq->value >= 2347);
17900+ vwrq->fixed = 1;
17901+ return OK;
17902+}
17903+#endif
17904+
17905+
17906+/***********************************************************************
17907+** acx_ioctl_set_encode
17908+*/
17909+static int
17910+acx_ioctl_set_encode(
17911+ struct net_device *ndev,
17912+ struct iw_request_info *info,
17913+ union iwreq_data *wrqu,
17914+ char *extra)
17915+{
17916+ struct iw_point *dwrq = &wrqu->encoding;
17917+ acx_device_t *adev = ndev2adev(ndev);
17918+ int index;
17919+ int result;
17920+
17921+ FN_ENTER;
17922+
17923+ log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n",
17924+ dwrq->flags, dwrq->length, extra ? "set" : "No key");
17925+
17926+ acx_sem_lock(adev);
17927+
17928+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
17929+
17930+ if (dwrq->length > 0) {
17931+ /* if index is 0 or invalid, use default key */
17932+ if ((index < 0) || (index > 3))
17933+ index = (int)adev->wep_current_index;
17934+
17935+ if (0 == (dwrq->flags & IW_ENCODE_NOKEY)) {
17936+ if (dwrq->length > 29)
17937+ dwrq->length = 29; /* restrict it */
17938+
17939+ if (dwrq->length > 13) {
17940+ /* 29*8 == 232, WEP256 */
17941+ adev->wep_keys[index].size = 29;
17942+ } else if (dwrq->length > 5) {
17943+ /* 13*8 == 104bit, WEP128 */
17944+ adev->wep_keys[index].size = 13;
17945+ } else if (dwrq->length > 0) {
17946+ /* 5*8 == 40bit, WEP64 */
17947+ adev->wep_keys[index].size = 5;
17948+ } else {
17949+ /* disable key */
17950+ adev->wep_keys[index].size = 0;
17951+ }
17952+
17953+ memset(adev->wep_keys[index].key, 0,
17954+ sizeof(adev->wep_keys[index].key));
17955+ memcpy(adev->wep_keys[index].key, extra, dwrq->length);
17956+ }
17957+ } else {
17958+ /* set transmit key */
17959+ if ((index >= 0) && (index <= 3))
17960+ adev->wep_current_index = index;
17961+ else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
17962+ /* complain if we were not just setting
17963+ * the key mode */
17964+ result = -EINVAL;
17965+ goto end_unlock;
17966+ }
17967+ }
17968+
17969+ adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
17970+
17971+ if (dwrq->flags & IW_ENCODE_OPEN) {
17972+ adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
17973+ adev->wep_restricted = 0;
17974+
17975+ } else if (dwrq->flags & IW_ENCODE_RESTRICTED) {
17976+ adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
17977+ adev->wep_restricted = 1;
17978+ }
17979+
17980+ /* set flag to make sure the card WEP settings get updated */
17981+ SET_BIT(adev->set_mask, GETSET_WEP);
17982+
17983+ log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n",
17984+ dwrq->length, extra, dwrq->flags);
17985+
17986+ for (index = 0; index <= 3; index++) {
17987+ if (adev->wep_keys[index].size) {
17988+ log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n",
17989+ adev->wep_keys[index].index,
17990+ (int) adev->wep_keys[index].size,
17991+ adev->wep_keys[index].key);
17992+ }
17993+ }
17994+ result = -EINPROGRESS;
17995+
17996+end_unlock:
17997+ acx_sem_unlock(adev);
17998+
17999+ FN_EXIT1(result);
18000+ return result;
18001+}
18002+
18003+
18004+/***********************************************************************
18005+** acx_ioctl_get_encode
18006+*/
18007+static int
18008+acx_ioctl_get_encode(
18009+ struct net_device *ndev,
18010+ struct iw_request_info *info,
18011+ union iwreq_data *wrqu,
18012+ char *extra)
18013+{
18014+ struct iw_point *dwrq = &wrqu->encoding;
18015+ acx_device_t *adev = ndev2adev(ndev);
18016+ int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
18017+
18018+ FN_ENTER;
18019+
18020+ if (adev->wep_enabled == 0) {
18021+ dwrq->flags = IW_ENCODE_DISABLED;
18022+ } else {
18023+ if ((index < 0) || (index > 3))
18024+ index = (int)adev->wep_current_index;
18025+
18026+ dwrq->flags = (adev->wep_restricted == 1) ?
18027+ IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
18028+ dwrq->length = adev->wep_keys[index].size;
18029+
18030+ memcpy(extra, adev->wep_keys[index].key,
18031+ adev->wep_keys[index].size);
18032+ }
18033+
18034+ /* set the current index */
18035+ SET_BIT(dwrq->flags, index + 1);
18036+
18037+ log(L_IOCTL, "len=%d, key=%p, flags=0x%X\n",
18038+ dwrq->length, dwrq->pointer,
18039+ dwrq->flags);
18040+
18041+ FN_EXIT1(OK);
18042+ return OK;
18043+}
18044+
18045+
18046+/***********************************************************************
18047+*/
18048+static int
18049+acx_ioctl_set_power(
18050+ struct net_device *ndev,
18051+ struct iw_request_info *info,
18052+ union iwreq_data *wrqu,
18053+ char *extra)
18054+{
18055+ struct iw_param *vwrq = &wrqu->power;
18056+ acx_device_t *adev = ndev2adev(ndev);
18057+ int result = -EINPROGRESS;
18058+
18059+ FN_ENTER;
18060+
18061+ log(L_IOCTL, "set 802.11 powersave flags=0x%04X\n", vwrq->flags);
18062+
18063+ acx_sem_lock(adev);
18064+
18065+ if (vwrq->disabled) {
18066+ CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE);
18067+ SET_BIT(adev->set_mask, GETSET_POWER_80211);
18068+ goto end;
18069+ }
18070+ if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
18071+ u16 ps_timeout = (vwrq->value * 1024) / 1000;
18072+
18073+ if (ps_timeout > 255)
18074+ ps_timeout = 255;
18075+ log(L_IOCTL, "setting PS timeout value to %d time units "
18076+ "due to %dus\n", ps_timeout, vwrq->value);
18077+ adev->ps_hangover_period = ps_timeout;
18078+ } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
18079+ u16 ps_periods = vwrq->value / 1000000;
18080+
18081+ if (ps_periods > 255)
18082+ ps_periods = 255;
18083+ log(L_IOCTL, "setting PS period value to %d periods "
18084+ "due to %dus\n", ps_periods, vwrq->value);
18085+ adev->ps_listen_interval = ps_periods;
18086+ CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_MODE_MASK);
18087+ SET_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_EACH_ITVL);
18088+ }
18089+
18090+ switch (vwrq->flags & IW_POWER_MODE) {
18091+ /* FIXME: are we doing the right thing here? */
18092+ case IW_POWER_UNICAST_R:
18093+ CLEAR_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS);
18094+ break;
18095+ case IW_POWER_MULTICAST_R:
18096+ SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS);
18097+ break;
18098+ case IW_POWER_ALL_R:
18099+ SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS);
18100+ break;
18101+ case IW_POWER_ON:
18102+ break;
18103+ default:
18104+ log(L_IOCTL, "unknown PS mode\n");
18105+ result = -EINVAL;
18106+ goto end;
18107+ }
18108+
18109+ SET_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE);
18110+ SET_BIT(adev->set_mask, GETSET_POWER_80211);
18111+end:
18112+ acx_sem_unlock(adev);
18113+
18114+ FN_EXIT1(result);
18115+ return result;
18116+}
18117+
18118+
18119+/***********************************************************************
18120+*/
18121+static int
18122+acx_ioctl_get_power(
18123+ struct net_device *ndev,
18124+ struct iw_request_info *info,
18125+ union iwreq_data *wrqu,
18126+ char *extra)
18127+{
18128+ struct iw_param *vwrq = &wrqu->power;
18129+ acx_device_t *adev = ndev2adev(ndev);
18130+
18131+ FN_ENTER;
18132+
18133+ log(L_IOCTL, "Get 802.11 Power Save flags = 0x%04X\n", vwrq->flags);
18134+ vwrq->disabled = ((adev->ps_wakeup_cfg & PS_CFG_ENABLE) == 0);
18135+ if (vwrq->disabled)
18136+ goto end;
18137+
18138+ if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
18139+ vwrq->value = adev->ps_hangover_period * 1000 / 1024;
18140+ vwrq->flags = IW_POWER_TIMEOUT;
18141+ } else {
18142+ vwrq->value = adev->ps_listen_interval * 1000000;
18143+ vwrq->flags = IW_POWER_PERIOD|IW_POWER_RELATIVE;
18144+ }
18145+ if (adev->ps_options & PS_OPT_STILL_RCV_BCASTS)
18146+ SET_BIT(vwrq->flags, IW_POWER_ALL_R);
18147+ else
18148+ SET_BIT(vwrq->flags, IW_POWER_UNICAST_R);
18149+end:
18150+ FN_EXIT1(OK);
18151+ return OK;
18152+}
18153+
18154+
18155+/***********************************************************************
18156+** acx_ioctl_get_txpow
18157+*/
18158+static inline int
18159+acx_ioctl_get_txpow(
18160+ struct net_device *ndev,
18161+ struct iw_request_info *info,
18162+ union iwreq_data *wrqu,
18163+ char *extra)
18164+{
18165+ struct iw_param *vwrq = &wrqu->power;
18166+ acx_device_t *adev = ndev2adev(ndev);
18167+
18168+ FN_ENTER;
18169+
18170+ vwrq->flags = IW_TXPOW_DBM;
18171+ vwrq->disabled = 0;
18172+ vwrq->fixed = 1;
18173+ vwrq->value = adev->tx_level_dbm;
18174+
18175+ log(L_IOCTL, "get txpower:%d dBm\n", adev->tx_level_dbm);
18176+
18177+ FN_EXIT1(OK);
18178+ return OK;
18179+}
18180+
18181+
18182+/***********************************************************************
18183+** acx_ioctl_set_txpow
18184+*/
18185+static int
18186+acx_ioctl_set_txpow(
18187+ struct net_device *ndev,
18188+ struct iw_request_info *info,
18189+ union iwreq_data *wrqu,
18190+ char *extra)
18191+{
18192+ struct iw_param *vwrq = &wrqu->power;
18193+ acx_device_t *adev = ndev2adev(ndev);
18194+ int result;
18195+
18196+ FN_ENTER;
18197+
18198+ log(L_IOCTL, "set txpower:%d, disabled:%d, flags:0x%04X\n",
18199+ vwrq->value, vwrq->disabled, vwrq->flags);
18200+
18201+ acx_sem_lock(adev);
18202+
18203+ if (vwrq->disabled != adev->tx_disabled) {
18204+ SET_BIT(adev->set_mask, GETSET_TX);
18205+ }
18206+
18207+ adev->tx_disabled = vwrq->disabled;
18208+ if (vwrq->value == -1) {
18209+ if (vwrq->disabled) {
18210+ adev->tx_level_dbm = 0;
18211+ log(L_IOCTL, "disable radio tx\n");
18212+ } else {
18213+ /* adev->tx_level_auto = 1; */
18214+ log(L_IOCTL, "set tx power auto (NIY)\n");
18215+ }
18216+ } else {
18217+ adev->tx_level_dbm = vwrq->value <= 20 ? vwrq->value : 20;
18218+ /* adev->tx_level_auto = 0; */
18219+ log(L_IOCTL, "set txpower=%d dBm\n", adev->tx_level_dbm);
18220+ }
18221+ SET_BIT(adev->set_mask, GETSET_TXPOWER);
18222+
18223+ result = -EINPROGRESS;
18224+
18225+ acx_sem_unlock(adev);
18226+
18227+ FN_EXIT1(result);
18228+ return result;
18229+}
18230+
18231+
18232+/***********************************************************************
18233+** acx_ioctl_get_range
18234+*/
18235+static int
18236+acx_ioctl_get_range(
18237+ struct net_device *ndev,
18238+ struct iw_request_info *info,
18239+ union iwreq_data *wrqu,
18240+ char *extra)
18241+{
18242+ struct iw_point *dwrq = &wrqu->data;
18243+ struct iw_range *range = (struct iw_range *)extra;
18244+ acx_device_t *adev = ndev2adev(ndev);
18245+ int i,n;
18246+
18247+ FN_ENTER;
18248+
18249+ if (!dwrq->pointer)
18250+ goto end;
18251+
18252+ dwrq->length = sizeof(struct iw_range);
18253+ memset(range, 0, sizeof(struct iw_range));
18254+ n = 0;
18255+ for (i = 1; i <= 14; i++) {
18256+ if (adev->reg_dom_chanmask & (1 << (i - 1))) {
18257+ range->freq[n].i = i;
18258+ range->freq[n].m = acx_channel_freq[i - 1] * 100000;
18259+ range->freq[n].e = 1; /* units are MHz */
18260+ n++;
18261+ }
18262+ }
18263+ range->num_channels = n;
18264+ range->num_frequency = n;
18265+
18266+ range->min_rts = 0;
18267+ range->max_rts = 2312;
18268+
18269+#if ACX_FRAGMENTATION
18270+ range->min_frag = 256;
18271+ range->max_frag = 2312;
18272+#endif
18273+
18274+ range->encoding_size[0] = 5;
18275+ range->encoding_size[1] = 13;
18276+ range->encoding_size[2] = 29;
18277+ range->num_encoding_sizes = 3;
18278+ range->max_encoding_tokens = 4;
18279+
18280+ range->min_pmp = 0;
18281+ range->max_pmp = 5000000;
18282+ range->min_pmt = 0;
18283+ range->max_pmt = 65535 * 1000;
18284+ range->pmp_flags = IW_POWER_PERIOD;
18285+ range->pmt_flags = IW_POWER_TIMEOUT;
18286+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
18287+
18288+ if (IS_ACX100(adev)) { /* ACX100 has direct radio programming - arbitrary levels, so offer a lot */
18289+ for (i = 0; i <= IW_MAX_TXPOWER - 1; i++)
18290+ range->txpower[i] = 20 * i / (IW_MAX_TXPOWER - 1);
18291+ range->num_txpower = IW_MAX_TXPOWER;
18292+ range->txpower_capa = IW_TXPOW_DBM;
18293+ }
18294+ else {
18295+ int count = min(IW_MAX_TXPOWER, (int)adev->cfgopt_power_levels.len);
18296+ for (i = 0; i <= count; i++)
18297+ range->txpower[i] = adev->cfgopt_power_levels.list[i];
18298+ range->num_txpower = count;
18299+ /* this list is given in mW */
18300+ range->txpower_capa = IW_TXPOW_MWATT;
18301+ }
18302+
18303+ range->we_version_compiled = WIRELESS_EXT;
18304+ range->we_version_source = 0x9;
18305+
18306+ range->retry_capa = IW_RETRY_LIMIT;
18307+ range->retry_flags = IW_RETRY_LIMIT;
18308+ range->min_retry = 1;
18309+ range->max_retry = 255;
18310+
18311+ range->r_time_flags = IW_RETRY_LIFETIME;
18312+ range->min_r_time = 0;
18313+ /* FIXME: lifetime ranges and orders of magnitude are strange?? */
18314+ range->max_r_time = 65535;
18315+
18316+ if (IS_USB(adev))
18317+ range->sensitivity = 0;
18318+ else if (IS_ACX111(adev))
18319+ range->sensitivity = 3;
18320+ else
18321+ range->sensitivity = 255;
18322+
18323+ for (i=0; i < adev->rate_supported_len; i++) {
18324+ range->bitrate[i] = (adev->rate_supported[i] & ~0x80) * 500000;
18325+ /* never happens, but keep it, to be safe: */
18326+ if (range->bitrate[i] == 0)
18327+ break;
18328+ }
18329+ range->num_bitrates = i;
18330+
18331+ range->max_qual.qual = 100;
18332+ range->max_qual.level = 100;
18333+ range->max_qual.noise = 100;
18334+ /* TODO: better values */
18335+ range->avg_qual.qual = 90;
18336+ range->avg_qual.level = 80;
18337+ range->avg_qual.noise = 2;
18338+
18339+end:
18340+ FN_EXIT1(OK);
18341+ return OK;
18342+}
18343+
18344+
18345+/***********************************************************************
18346+** Private functions
18347+*/
18348+
18349+/***********************************************************************
18350+** acx_ioctl_get_nick
18351+*/
18352+static inline int
18353+acx_ioctl_get_nick(
18354+ struct net_device *ndev,
18355+ struct iw_request_info *info,
18356+ union iwreq_data *wrqu,
18357+ char *extra)
18358+{
18359+ struct iw_point *dwrq = &wrqu->data;
18360+ acx_device_t *adev = ndev2adev(ndev);
18361+
18362+ strcpy(extra, adev->nick);
18363+ dwrq->length = strlen(extra) + 1;
18364+
18365+ return OK;
18366+}
18367+
18368+
18369+/***********************************************************************
18370+** acx_ioctl_set_nick
18371+*/
18372+static int
18373+acx_ioctl_set_nick(
18374+ struct net_device *ndev,
18375+ struct iw_request_info *info,
18376+ union iwreq_data *wrqu,
18377+ char *extra)
18378+{
18379+ struct iw_point *dwrq = &wrqu->data;
18380+ acx_device_t *adev = ndev2adev(ndev);
18381+ int result;
18382+
18383+ FN_ENTER;
18384+
18385+ acx_sem_lock(adev);
18386+
18387+ if (dwrq->length > IW_ESSID_MAX_SIZE + 1) {
18388+ result = -E2BIG;
18389+ goto end_unlock;
18390+ }
18391+
18392+ /* extra includes trailing \0, so it's ok */
18393+ strcpy(adev->nick, extra);
18394+ result = OK;
18395+
18396+end_unlock:
18397+ acx_sem_unlock(adev);
18398+
18399+ FN_EXIT1(result);
18400+ return result;
18401+}
18402+
18403+
18404+/***********************************************************************
18405+** acx_ioctl_get_retry
18406+*/
18407+static int
18408+acx_ioctl_get_retry(
18409+ struct net_device *ndev,
18410+ struct iw_request_info *info,
18411+ union iwreq_data *wrqu,
18412+ char *extra)
18413+{
18414+ struct iw_param *vwrq = &wrqu->retry;
18415+ acx_device_t *adev = ndev2adev(ndev);
18416+ unsigned int type = vwrq->flags & IW_RETRY_TYPE;
18417+ unsigned int modifier = vwrq->flags & IW_RETRY_MODIFIER;
18418+ int result;
18419+
18420+ FN_ENTER;
18421+
18422+ acx_sem_lock(adev);
18423+
18424+ /* return the short retry number by default */
18425+ if (type == IW_RETRY_LIFETIME) {
18426+ vwrq->flags = IW_RETRY_LIFETIME;
18427+ vwrq->value = adev->msdu_lifetime;
18428+ } else if (modifier == IW_RETRY_MAX) {
18429+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
18430+ vwrq->value = adev->long_retry;
18431+ } else {
18432+ vwrq->flags = IW_RETRY_LIMIT;
18433+ if (adev->long_retry != adev->short_retry)
18434+ SET_BIT(vwrq->flags, IW_RETRY_MIN);
18435+ vwrq->value = adev->short_retry;
18436+ }
18437+
18438+ /* can't be disabled */
18439+ vwrq->disabled = (u8)0;
18440+ result = OK;
18441+
18442+ acx_sem_unlock(adev);
18443+
18444+ FN_EXIT1(result);
18445+ return result;
18446+}
18447+
18448+
18449+/***********************************************************************
18450+** acx_ioctl_set_retry
18451+*/
18452+static int
18453+acx_ioctl_set_retry(
18454+ struct net_device *ndev,
18455+ struct iw_request_info *info,
18456+ union iwreq_data *wrqu,
18457+ char *extra)
18458+{
18459+ struct iw_param *vwrq = &wrqu->retry;
18460+ acx_device_t *adev = ndev2adev(ndev);
18461+ int result;
18462+
18463+ FN_ENTER;
18464+
18465+ if (!vwrq) {
18466+ result = -EFAULT;
18467+ goto end;
18468+ }
18469+ if (vwrq->disabled) {
18470+ result = -EINVAL;
18471+ goto end;
18472+ }
18473+
18474+ acx_sem_lock(adev);
18475+
18476+ result = -EINVAL;
18477+ if (IW_RETRY_LIMIT == (vwrq->flags & IW_RETRY_TYPE)) {
18478+ printk("old retry limits: short %d long %d\n",
18479+ adev->short_retry, adev->long_retry);
18480+ if (vwrq->flags & IW_RETRY_MAX) {
18481+ adev->long_retry = vwrq->value;
18482+ } else if (vwrq->flags & IW_RETRY_MIN) {
18483+ adev->short_retry = vwrq->value;
18484+ } else {
18485+ /* no modifier: set both */
18486+ adev->long_retry = vwrq->value;
18487+ adev->short_retry = vwrq->value;
18488+ }
18489+ printk("new retry limits: short %d long %d\n",
18490+ adev->short_retry, adev->long_retry);
18491+ SET_BIT(adev->set_mask, GETSET_RETRY);
18492+ result = -EINPROGRESS;
18493+ }
18494+ else if (vwrq->flags & IW_RETRY_LIFETIME) {
18495+ adev->msdu_lifetime = vwrq->value;
18496+ printk("new MSDU lifetime: %d\n", adev->msdu_lifetime);
18497+ SET_BIT(adev->set_mask, SET_MSDU_LIFETIME);
18498+ result = -EINPROGRESS;
18499+ }
18500+
18501+ acx_sem_unlock(adev);
18502+end:
18503+ FN_EXIT1(result);
18504+ return result;
18505+}
18506+
18507+
18508+/************************ private ioctls ******************************/
18509+
18510+
18511+/***********************************************************************
18512+** acx_ioctl_set_debug
18513+*/
18514+#if ACX_DEBUG
18515+static int
18516+acx_ioctl_set_debug(
18517+ struct net_device *ndev,
18518+ struct iw_request_info *info,
18519+ union iwreq_data *wrqu,
18520+ char *extra)
18521+{
18522+ unsigned int debug_new = *((unsigned int *)extra);
18523+ int result = -EINVAL;
18524+
18525+ log(L_ANY, "setting debug from %04X to %04X\n", acx_debug, debug_new);
18526+ acx_debug = debug_new;
18527+
18528+ result = OK;
18529+ return result;
18530+
18531+}
18532+#endif
18533+
18534+
18535+/***********************************************************************
18536+** acx_ioctl_list_reg_domain
18537+*/
18538+static int
18539+acx_ioctl_list_reg_domain(
18540+ struct net_device *ndev,
18541+ struct iw_request_info *info,
18542+ union iwreq_data *wrqu,
18543+ char *extra)
18544+{
18545+ int i = 1;
18546+ const char * const *entry = acx_reg_domain_strings;
18547+
18548+ printk("dom# chan# domain/country\n");
18549+ while (*entry)
18550+ printk("%4d %s\n", i++, *entry++);
18551+ return OK;
18552+}
18553+
18554+
18555+/***********************************************************************
18556+** acx_ioctl_set_reg_domain
18557+*/
18558+static int
18559+acx_ioctl_set_reg_domain(
18560+ struct net_device *ndev,
18561+ struct iw_request_info *info,
18562+ union iwreq_data *wrqu,
18563+ char *extra)
18564+{
18565+ acx_device_t *adev = ndev2adev(ndev);
18566+ int result;
18567+
18568+ FN_ENTER;
18569+
18570+ if ((*extra < 1) || ((size_t)*extra > acx_reg_domain_ids_len)) {
18571+ result = -EINVAL;
18572+ goto end;
18573+ }
18574+
18575+ acx_sem_lock(adev);
18576+
18577+ adev->reg_dom_id = acx_reg_domain_ids[*extra - 1];
18578+ SET_BIT(adev->set_mask, GETSET_REG_DOMAIN);
18579+
18580+ result = -EINPROGRESS;
18581+
18582+ acx_sem_unlock(adev);
18583+end:
18584+ FN_EXIT1(result);
18585+ return result;
18586+}
18587+
18588+
18589+/***********************************************************************
18590+** acx_ioctl_get_reg_domain
18591+*/
18592+static int
18593+acx_ioctl_get_reg_domain(
18594+ struct net_device *ndev,
18595+ struct iw_request_info *info,
18596+ union iwreq_data *wrqu,
18597+ char *extra)
18598+{
18599+ acx_device_t *adev = ndev2adev(ndev);
18600+ int dom,i;
18601+
18602+ /* no locking */
18603+ dom = adev->reg_dom_id;
18604+
18605+ for (i = 1; i <= acx_reg_domain_ids_len; i++) {
18606+ if (acx_reg_domain_ids[i-1] == dom) {
18607+ log(L_IOCTL, "regulatory domain is currently set "
18608+ "to %d (0x%X): %s\n", i, dom,
18609+ acx_reg_domain_strings[i-1]);
18610+ *extra = i;
18611+ break;
18612+ }
18613+ }
18614+
18615+ return OK;
18616+}
18617+
18618+
18619+/***********************************************************************
18620+** acx_ioctl_set_short_preamble
18621+*/
18622+static const char * const
18623+preamble_modes[] = {
18624+ "off",
18625+ "on",
18626+ "auto (peer capability dependent)",
18627+ "unknown mode, error"
18628+};
18629+
18630+static int
18631+acx_ioctl_set_short_preamble(
18632+ struct net_device *ndev,
18633+ struct iw_request_info *info,
18634+ union iwreq_data *wrqu,
18635+ char *extra)
18636+{
18637+ acx_device_t *adev = ndev2adev(ndev);
18638+ int i;
18639+ int result;
18640+
18641+ FN_ENTER;
18642+
18643+ if ((unsigned char)*extra > 2) {
18644+ result = -EINVAL;
18645+ goto end;
18646+ }
18647+
18648+ acx_sem_lock(adev);
18649+
18650+ adev->preamble_mode = (u8)*extra;
18651+ switch (adev->preamble_mode) {
18652+ case 0: /* long */
18653+ adev->preamble_cur = 0;
18654+ break;
18655+ case 1:
18656+ /* short, kick incapable peers */
18657+ adev->preamble_cur = 1;
18658+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
18659+ client_t *clt = &adev->sta_list[i];
18660+ if (!clt->used) continue;
18661+ if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) {
18662+ clt->used = CLIENT_EMPTY_SLOT_0;
18663+ }
18664+ }
18665+ switch (adev->mode) {
18666+ case ACX_MODE_2_STA:
18667+ if (adev->ap_client && !adev->ap_client->used) {
18668+ /* We kicked our AP :) */
18669+ SET_BIT(adev->set_mask, GETSET_RESCAN);
18670+ }
18671+ }
18672+ break;
18673+ case 2: /* auto. short only if all peers are short-capable */
18674+ adev->preamble_cur = 1;
18675+ for (i = 0; i < VEC_SIZE(adev->sta_list); i++) {
18676+ client_t *clt = &adev->sta_list[i];
18677+ if (!clt->used) continue;
18678+ if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) {
18679+ adev->preamble_cur = 0;
18680+ break;
18681+ }
18682+ }
18683+ break;
18684+ }
18685+ printk("new short preamble setting: configured %s, active %s\n",
18686+ preamble_modes[adev->preamble_mode],
18687+ preamble_modes[adev->preamble_cur]);
18688+ result = OK;
18689+
18690+ acx_sem_unlock(adev);
18691+end:
18692+ FN_EXIT1(result);
18693+ return result;
18694+}
18695+
18696+
18697+/***********************************************************************
18698+** acx_ioctl_get_short_preamble
18699+*/
18700+static int
18701+acx_ioctl_get_short_preamble(
18702+ struct net_device *ndev,
18703+ struct iw_request_info *info,
18704+ union iwreq_data *wrqu,
18705+ char *extra)
18706+{
18707+ acx_device_t *adev = ndev2adev(ndev);
18708+
18709+ acx_sem_lock(adev);
18710+
18711+ printk("current short preamble setting: configured %s, active %s\n",
18712+ preamble_modes[adev->preamble_mode],
18713+ preamble_modes[adev->preamble_cur]);
18714+
18715+ *extra = (char)adev->preamble_mode;
18716+
18717+ acx_sem_unlock(adev);
18718+
18719+ return OK;
18720+}
18721+
18722+
18723+/***********************************************************************
18724+** acx_ioctl_set_antenna
18725+**
18726+** TX and RX antenna can be set separately but this function good
18727+** for testing 0-4 bits
18728+*/
18729+static int
18730+acx_ioctl_set_antenna(
18731+ struct net_device *ndev,
18732+ struct iw_request_info *info,
18733+ union iwreq_data *wrqu,
18734+ char *extra)
18735+{
18736+ acx_device_t *adev = ndev2adev(ndev);
18737+
18738+ acx_sem_lock(adev);
18739+
18740+ printk("old antenna value: 0x%02X (COMBINED bit mask)\n"
18741+ "Rx antenna selection:\n"
18742+ "0x00 ant. 1\n"
18743+ "0x40 ant. 2\n"
18744+ "0x80 full diversity\n"
18745+ "0xc0 partial diversity\n"
18746+ "0x0f dwell time mask (in units of us)\n"
18747+ "Tx antenna selection:\n"
18748+ "0x00 ant. 2\n" /* yep, those ARE reversed! */
18749+ "0x20 ant. 1\n"
18750+ "new antenna value: 0x%02X\n",
18751+ adev->antenna, (u8)*extra);
18752+
18753+ adev->antenna = (u8)*extra;
18754+ SET_BIT(adev->set_mask, GETSET_ANTENNA);
18755+
18756+ acx_sem_unlock(adev);
18757+
18758+ return -EINPROGRESS;
18759+}
18760+
18761+
18762+/***********************************************************************
18763+** acx_ioctl_get_antenna
18764+*/
18765+static int
18766+acx_ioctl_get_antenna(
18767+ struct net_device *ndev,
18768+ struct iw_request_info *info,
18769+ union iwreq_data *wrqu,
18770+ char *extra)
18771+{
18772+ acx_device_t *adev = ndev2adev(ndev);
18773+
18774+ /* no locking. it's pointless to lock a single load */
18775+ printk("current antenna value: 0x%02X (COMBINED bit mask)\n"
18776+ "Rx antenna selection:\n"
18777+ "0x00 ant. 1\n"
18778+ "0x40 ant. 2\n"
18779+ "0x80 full diversity\n"
18780+ "0xc0 partial diversity\n"
18781+ "Tx antenna selection:\n"
18782+ "0x00 ant. 2\n" /* yep, those ARE reversed! */
18783+ "0x20 ant. 1\n", adev->antenna);
18784+
18785+ return 0;
18786+}
18787+
18788+
18789+/***********************************************************************
18790+** acx_ioctl_set_rx_antenna
18791+**
18792+** 0 = antenna1; 1 = antenna2; 2 = full diversity; 3 = partial diversity
18793+** Could anybody test which antenna is the external one?
18794+*/
18795+static int
18796+acx_ioctl_set_rx_antenna(
18797+ struct net_device *ndev,
18798+ struct iw_request_info *info,
18799+ union iwreq_data *wrqu,
18800+ char *extra)
18801+{
18802+ acx_device_t *adev = ndev2adev(ndev);
18803+ int result;
18804+
18805+ FN_ENTER;
18806+
18807+ if (*extra > 3) {
18808+ result = -EINVAL;
18809+ goto end;
18810+ }
18811+
18812+ printk("old antenna value: 0x%02X\n", adev->antenna);
18813+
18814+ acx_sem_lock(adev);
18815+
18816+ adev->antenna &= 0x3f;
18817+ SET_BIT(adev->antenna, (*extra << 6));
18818+ SET_BIT(adev->set_mask, GETSET_ANTENNA);
18819+ printk("new antenna value: 0x%02X\n", adev->antenna);
18820+ result = -EINPROGRESS;
18821+
18822+ acx_sem_unlock(adev);
18823+end:
18824+ FN_EXIT1(result);
18825+ return result;
18826+}
18827+
18828+
18829+/***********************************************************************
18830+** acx_ioctl_set_tx_antenna
18831+**
18832+** Arguments: 0 == antenna2; 1 == antenna1;
18833+** Could anybody test which antenna is the external one?
18834+*/
18835+static int
18836+acx_ioctl_set_tx_antenna(
18837+ struct net_device *ndev,
18838+ struct iw_request_info *info,
18839+ union iwreq_data *wrqu,
18840+ char *extra)
18841+{
18842+ acx_device_t *adev = ndev2adev(ndev);
18843+ int result;
18844+
18845+ FN_ENTER;
18846+
18847+ if (*extra > 1) {
18848+ result = -EINVAL;
18849+ goto end;
18850+ }
18851+
18852+ printk("old antenna value: 0x%02X\n", adev->antenna);
18853+
18854+ acx_sem_lock(adev);
18855+
18856+ adev->antenna &= ~0x30;
18857+ SET_BIT(adev->antenna, ((*extra & 0x01) << 5));
18858+ SET_BIT(adev->set_mask, GETSET_ANTENNA);
18859+ printk("new antenna value: 0x%02X\n", adev->antenna);
18860+ result = -EINPROGRESS;
18861+
18862+ acx_sem_unlock(adev);
18863+end:
18864+ FN_EXIT1(result);
18865+ return result;
18866+}
18867+
18868+
18869+/***********************************************************************
18870+** acx_ioctl_wlansniff
18871+**
18872+** can we just remove this in favor of monitor mode? --vda
18873+*/
18874+static int
18875+acx_ioctl_wlansniff(
18876+ struct net_device *ndev,
18877+ struct iw_request_info *info,
18878+ union iwreq_data *wrqu,
18879+ char *extra)
18880+{
18881+ acx_device_t *adev = ndev2adev(ndev);
18882+ unsigned int *params = (unsigned int*)extra;
18883+ unsigned int enable = (unsigned int)(params[0] > 0);
18884+ int result;
18885+
18886+ FN_ENTER;
18887+
18888+ acx_sem_lock(adev);
18889+
18890+ /* not using printk() here, since it distorts kismet display
18891+ * when printk messages activated */
18892+ log(L_IOCTL, "setting monitor to: 0x%02X\n", params[0]);
18893+
18894+ switch (params[0]) {
18895+ case 0:
18896+ /* no monitor mode. hmm, should we simply ignore it
18897+ * or go back to enabling adev->netdev->type ARPHRD_ETHER? */
18898+ break;
18899+ case 1:
18900+ adev->monitor_type = ARPHRD_IEEE80211_PRISM;
18901+ break;
18902+ case 2:
18903+ adev->monitor_type = ARPHRD_IEEE80211;
18904+ break;
18905+ }
18906+
18907+ if (params[0]) {
18908+ adev->mode = ACX_MODE_MONITOR;
18909+ SET_BIT(adev->set_mask, GETSET_MODE);
18910+ }
18911+
18912+ if (enable) {
18913+ adev->channel = params[1];
18914+ SET_BIT(adev->set_mask, GETSET_RX);
18915+ }
18916+ result = -EINPROGRESS;
18917+
18918+ acx_sem_unlock(adev);
18919+
18920+ FN_EXIT1(result);
18921+ return result;
18922+}
18923+
18924+
18925+/***********************************************************************
18926+** acx_ioctl_unknown11
18927+** FIXME: looks like some sort of "iwpriv kick_sta MAC" but it's broken
18928+*/
18929+static int
18930+acx_ioctl_unknown11(
18931+ struct net_device *ndev,
18932+ struct iw_request_info *info,
18933+ union iwreq_data *wrqu,
18934+ char *extra)
18935+{
18936+#ifdef BROKEN
18937+ struct iw_param *vwrq = &wrqu->param;
18938+ acx_device_t *adev = ndev2adev(ndev);
18939+ unsigned long flags;
18940+ client_t client;
18941+ int result;
18942+
18943+ acx_sem_lock(adev);
18944+ acx_lock(adev, flags);
18945+
18946+ acx_l_transmit_disassoc(adev, &client);
18947+ result = OK;
18948+
18949+ acx_unlock(adev, flags);
18950+ acx_sem_unlock(adev);
18951+
18952+ return result;
18953+#endif
18954+ return -EINVAL;
18955+}
18956+
18957+
18958+/***********************************************************************
18959+** debug helper function to be able to debug various issues relatively easily
18960+*/
18961+static int
18962+acx_ioctl_dbg_set_masks(
18963+ struct net_device *ndev,
18964+ struct iw_request_info *info,
18965+ union iwreq_data *wrqu,
18966+ char *extra)
18967+{
18968+ acx_device_t *adev = ndev2adev(ndev);
18969+ const unsigned int *params = (unsigned int*)extra;
18970+ int result;
18971+
18972+ acx_sem_lock(adev);
18973+
18974+ log(L_IOCTL, "setting flags in settings mask: "
18975+ "get_mask %08X set_mask %08X\n"
18976+ "before: get_mask %08X set_mask %08X\n",
18977+ params[0], params[1],
18978+ adev->get_mask, adev->set_mask);
18979+ SET_BIT(adev->get_mask, params[0]);
18980+ SET_BIT(adev->set_mask, params[1]);
18981+ log(L_IOCTL, "after: get_mask %08X set_mask %08X\n",
18982+ adev->get_mask, adev->set_mask);
18983+ result = -EINPROGRESS; /* immediately call commit handler */
18984+
18985+ acx_sem_unlock(adev);
18986+
18987+ return result;
18988+}
18989+
18990+
18991+/***********************************************************************
18992+* acx_ioctl_set_rates
18993+*
18994+* This ioctl takes string parameter. Examples:
18995+* iwpriv wlan0 SetRates "1,2"
18996+* use 1 and 2 Mbit rates, both are in basic rate set
18997+* iwpriv wlan0 SetRates "1,2 5,11"
18998+* use 1,2,5.5,11 Mbit rates. 1 and 2 are basic
18999+* iwpriv wlan0 SetRates "1,2 5c,11c"
19000+* same ('c' means 'CCK modulation' and it is a default for 5 and 11)
19001+* iwpriv wlan0 SetRates "1,2 5p,11p"
19002+* use 1,2,5.5,11 Mbit, 1,2 are basic. 5 and 11 are using PBCC
19003+* iwpriv wlan0 SetRates "1,2,5,11 22p"
19004+* use 1,2,5.5,11,22 Mbit. 1,2,5.5 and 11 are basic. 22 is using PBCC
19005+* (this is the maximum acx100 can do (modulo x4 mode))
19006+* iwpriv wlan0 SetRates "1,2,5,11 22"
19007+* same. 802.11 defines only PBCC modulation
19008+* for 22 and 33 Mbit rates, so there is no ambiguity
19009+* iwpriv wlan0 SetRates "1,2,5,11 6o,9o,12o,18o,24o,36o,48o,54o"
19010+* 1,2,5.5 and 11 are basic. 11g OFDM rates are enabled but
19011+* they are not in basic rate set. 22 Mbit is disabled.
19012+* iwpriv wlan0 SetRates "1,2,5,11 6,9,12,18,24,36,48,54"
19013+* same. OFDM is default for 11g rates except 22 and 33 Mbit,
19014+* thus 'o' is optional
19015+* iwpriv wlan0 SetRates "1,2,5,11 6d,9d,12d,18d,24d,36d,48d,54d"
19016+* 1,2,5.5 and 11 are basic. 11g CCK-OFDM rates are enabled
19017+* (acx111 does not support CCK-OFDM, driver will reject this cmd)
19018+* iwpriv wlan0 SetRates "6,9,12 18,24,36,48,54"
19019+* 6,9,12 are basic, rest of 11g rates is enabled. Using OFDM
19020+*/
19021+#include "setrate.c"
19022+
19023+/* disallow: 33Mbit (unsupported by hw) */
19024+/* disallow: CCKOFDM (unsupported by hw) */
19025+static int
19026+acx111_supported(int mbit, int modulation, void *opaque)
19027+{
19028+ if (mbit==33) return -ENOTSUPP;
19029+ if (modulation==DOT11_MOD_CCKOFDM) return -ENOTSUPP;
19030+ return OK;
19031+}
19032+
19033+static const u16
19034+acx111mask[] = {
19035+ [DOT11_RATE_1 ] = RATE111_1 ,
19036+ [DOT11_RATE_2 ] = RATE111_2 ,
19037+ [DOT11_RATE_5 ] = RATE111_5 ,
19038+ [DOT11_RATE_11] = RATE111_11,
19039+ [DOT11_RATE_22] = RATE111_22,
19040+ /* [DOT11_RATE_33] = */
19041+ [DOT11_RATE_6 ] = RATE111_6 ,
19042+ [DOT11_RATE_9 ] = RATE111_9 ,
19043+ [DOT11_RATE_12] = RATE111_12,
19044+ [DOT11_RATE_18] = RATE111_18,
19045+ [DOT11_RATE_24] = RATE111_24,
19046+ [DOT11_RATE_36] = RATE111_36,
19047+ [DOT11_RATE_48] = RATE111_48,
19048+ [DOT11_RATE_54] = RATE111_54,
19049+};
19050+
19051+static u32
19052+acx111_gen_mask(int mbit, int modulation, void *opaque)
19053+{
19054+ /* lower 16 bits show selected 1, 2, CCK and OFDM rates */
19055+ /* upper 16 bits show selected PBCC rates */
19056+ u32 m = acx111mask[rate_mbit2enum(mbit)];
19057+ if (modulation==DOT11_MOD_PBCC)
19058+ return m<<16;
19059+ return m;
19060+}
19061+
19062+static int
19063+verify_rate(u32 rate, int chip_type)
19064+{
19065+ /* never happens. be paranoid */
19066+ if (!rate) return -EINVAL;
19067+
19068+ /* disallow: mixing PBCC and CCK at 5 and 11Mbit
19069+ ** (can be supported, but needs complicated handling in tx code) */
19070+ if (( rate & ((RATE111_11+RATE111_5)<<16) )
19071+ && ( rate & (RATE111_11+RATE111_5) )
19072+ ) {
19073+ return -ENOTSUPP;
19074+ }
19075+ if (CHIPTYPE_ACX100 == chip_type) {
19076+ if ( rate & ~(RATE111_ACX100_COMPAT+(RATE111_ACX100_COMPAT<<16)) )
19077+ return -ENOTSUPP;
19078+ }
19079+ return 0;
19080+}
19081+
19082+static int
19083+acx_ioctl_set_rates(struct net_device *ndev,
19084+ struct iw_request_info *info,
19085+ union iwreq_data *wrqu,
19086+ char *extra)
19087+{
19088+ acx_device_t *adev = ndev2adev(ndev);
19089+ unsigned long flags;
19090+ int result;
19091+ u32 brate = 0, orate = 0; /* basic, operational rate set */
19092+
19093+ FN_ENTER;
19094+
19095+ log(L_IOCTL, "set_rates %s\n", extra);
19096+ result = fill_ratemasks(extra, &brate, &orate,
19097+ acx111_supported, acx111_gen_mask, 0);
19098+ if (result) goto end;
19099+ SET_BIT(orate, brate);
19100+ log(L_IOCTL, "brate %08X orate %08X\n", brate, orate);
19101+
19102+ result = verify_rate(brate, adev->chip_type);
19103+ if (result) goto end;
19104+ result = verify_rate(orate, adev->chip_type);
19105+ if (result) goto end;
19106+
19107+ acx_sem_lock(adev);
19108+ acx_lock(adev, flags);
19109+
19110+ adev->rate_basic = brate;
19111+ adev->rate_oper = orate;
19112+ /* TODO: ideally, we shall monitor highest basic rate
19113+ ** which was successfully sent to every peer
19114+ ** (say, last we checked, everybody could hear 5.5 Mbits)
19115+ ** and use that for bcasts when we want to reach all peers.
19116+ ** For beacons, we probably shall use lowest basic rate
19117+ ** because we want to reach all *potential* new peers too */
19118+ adev->rate_bcast = 1 << lowest_bit(brate);
19119+ if (IS_ACX100(adev))
19120+ adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast);
19121+ adev->rate_auto = !has_only_one_bit(orate);
19122+ acx_l_update_client_rates(adev, orate);
19123+ /* TODO: get rid of ratevector, build it only when needed */
19124+ acx_l_update_ratevector(adev);
19125+
19126+ /* Do/don't do tx rate fallback; beacon contents and rate */
19127+ SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES);
19128+ result = -EINPROGRESS;
19129+
19130+ acx_unlock(adev, flags);
19131+ acx_sem_unlock(adev);
19132+end:
19133+ FN_EXIT1(result);
19134+ return result;
19135+}
19136+
19137+
19138+/***********************************************************************
19139+** acx_ioctl_get_phy_chan_busy_percentage
19140+*/
19141+static int
19142+acx_ioctl_get_phy_chan_busy_percentage(
19143+ struct net_device *ndev,
19144+ struct iw_request_info *info,
19145+ union iwreq_data *wrqu,
19146+ char *extra)
19147+{
19148+ acx_device_t *adev = ndev2adev(ndev);
19149+ struct {
19150+ u16 type;
19151+ u16 len;
19152+ u32 busytime;
19153+ u32 totaltime;
19154+ } ACX_PACKED usage;
19155+ int result;
19156+
19157+ acx_sem_lock(adev);
19158+
19159+ if (OK != acx_s_interrogate(adev, &usage, ACX1xx_IE_MEDIUM_USAGE)) {
19160+ result = NOT_OK;
19161+ goto end_unlock;
19162+ }
19163+
19164+ usage.busytime = le32_to_cpu(usage.busytime);
19165+ usage.totaltime = le32_to_cpu(usage.totaltime);
19166+
19167+ /* yes, this is supposed to be "Medium" (singular of media),
19168+ not "average"! OK, reword the message to make it obvious... */
19169+ printk("%s: busy percentage of medium (since last invocation): %d%% "
19170+ "(%u of %u microseconds)\n",
19171+ ndev->name,
19172+ usage.busytime / ((usage.totaltime / 100) + 1),
19173+ usage.busytime, usage.totaltime);
19174+
19175+ result = OK;
19176+
19177+end_unlock:
19178+ acx_sem_unlock(adev);
19179+
19180+ return result;
19181+}
19182+
19183+
19184+/***********************************************************************
19185+** acx_ioctl_set_ed_threshold
19186+*/
19187+static inline int
19188+acx_ioctl_set_ed_threshold(
19189+ struct net_device *ndev,
19190+ struct iw_request_info *info,
19191+ union iwreq_data *wrqu,
19192+ char *extra)
19193+{
19194+ acx_device_t *adev = ndev2adev(ndev);
19195+
19196+ acx_sem_lock(adev);
19197+
19198+ printk("old ED threshold value: %d\n", adev->ed_threshold);
19199+ adev->ed_threshold = (unsigned char)*extra;
19200+ printk("new ED threshold value: %d\n", (unsigned char)*extra);
19201+ SET_BIT(adev->set_mask, GETSET_ED_THRESH);
19202+
19203+ acx_sem_unlock(adev);
19204+
19205+ return -EINPROGRESS;
19206+}
19207+
19208+
19209+/***********************************************************************
19210+** acx_ioctl_set_cca
19211+*/
19212+static inline int
19213+acx_ioctl_set_cca(
19214+ struct net_device *ndev,
19215+ struct iw_request_info *info,
19216+ union iwreq_data *wrqu,
19217+ char *extra)
19218+{
19219+ acx_device_t *adev = ndev2adev(ndev);
19220+ int result;
19221+
19222+ acx_sem_lock(adev);
19223+
19224+ printk("old CCA value: 0x%02X\n", adev->cca);
19225+ adev->cca = (unsigned char)*extra;
19226+ printk("new CCA value: 0x%02X\n", (unsigned char)*extra);
19227+ SET_BIT(adev->set_mask, GETSET_CCA);
19228+ result = -EINPROGRESS;
19229+
19230+ acx_sem_unlock(adev);
19231+
19232+ return result;
19233+}
19234+
19235+
19236+/***********************************************************************
19237+*/
19238+static const char * const
19239+scan_modes[] = { "active", "passive", "background" };
19240+
19241+static void
19242+acx_print_scan_params(acx_device_t *adev, const char* head)
19243+{
19244+ printk("%s: %smode %d (%s), min chan time %dTU, "
19245+ "max chan time %dTU, max scan rate byte: %d\n",
19246+ adev->ndev->name, head,
19247+ adev->scan_mode, scan_modes[adev->scan_mode],
19248+ adev->scan_probe_delay, adev->scan_duration, adev->scan_rate);
19249+}
19250+
19251+static int
19252+acx_ioctl_set_scan_params(
19253+ struct net_device *ndev,
19254+ struct iw_request_info *info,
19255+ union iwreq_data *wrqu,
19256+ char *extra)
19257+{
19258+ acx_device_t *adev = ndev2adev(ndev);
19259+ int result;
19260+ const int *params = (int *)extra;
19261+
19262+ acx_sem_lock(adev);
19263+
19264+ acx_print_scan_params(adev, "old scan parameters: ");
19265+ if ((params[0] != -1) && (params[0] >= 0) && (params[0] <= 2))
19266+ adev->scan_mode = params[0];
19267+ if (params[1] != -1)
19268+ adev->scan_probe_delay = params[1];
19269+ if (params[2] != -1)
19270+ adev->scan_duration = params[2];
19271+ if ((params[3] != -1) && (params[3] <= 255))
19272+ adev->scan_rate = params[3];
19273+ acx_print_scan_params(adev, "new scan parameters: ");
19274+ SET_BIT(adev->set_mask, GETSET_RESCAN);
19275+ result = -EINPROGRESS;
19276+
19277+ acx_sem_unlock(adev);
19278+
19279+ return result;
19280+}
19281+
19282+static int
19283+acx_ioctl_get_scan_params(
19284+ struct net_device *ndev,
19285+ struct iw_request_info *info,
19286+ union iwreq_data *wrqu,
19287+ char *extra)
19288+{
19289+ acx_device_t *adev = ndev2adev(ndev);
19290+ int result;
19291+ int *params = (int *)extra;
19292+
19293+ acx_sem_lock(adev);
19294+
19295+ acx_print_scan_params(adev, "current scan parameters: ");
19296+ params[0] = adev->scan_mode;
19297+ params[1] = adev->scan_probe_delay;
19298+ params[2] = adev->scan_duration;
19299+ params[3] = adev->scan_rate;
19300+ result = OK;
19301+
19302+ acx_sem_unlock(adev);
19303+
19304+ return result;
19305+}
19306+
19307+
19308+/***********************************************************************
19309+*/
19310+static int
19311+acx100_ioctl_set_led_power(
19312+ struct net_device *ndev,
19313+ struct iw_request_info *info,
19314+ union iwreq_data *wrqu,
19315+ char *extra)
19316+{
19317+ static const char * const led_modes[] = { "off", "on", "LinkQuality" };
19318+
19319+ acx_device_t *adev = ndev2adev(ndev);
19320+ int result;
19321+
19322+ acx_sem_lock(adev);
19323+
19324+ printk("%s: power LED status: old %d (%s), ",
19325+ ndev->name,
19326+ adev->led_power,
19327+ led_modes[adev->led_power]);
19328+ adev->led_power = extra[0];
19329+ if (adev->led_power > 2) adev->led_power = 2;
19330+ printk("new %d (%s)\n",
19331+ adev->led_power,
19332+ led_modes[adev->led_power]);
19333+
19334+ if (adev->led_power == 2) {
19335+ printk("%s: max link quality setting: old %d, ",
19336+ ndev->name, adev->brange_max_quality);
19337+ if (extra[1])
19338+ adev->brange_max_quality = extra[1];
19339+ printk("new %d\n", adev->brange_max_quality);
19340+ }
19341+
19342+ SET_BIT(adev->set_mask, GETSET_LED_POWER);
19343+
19344+ result = -EINPROGRESS;
19345+
19346+ acx_sem_unlock(adev);
19347+
19348+ return result;
19349+}
19350+
19351+
19352+/***********************************************************************
19353+*/
19354+static inline int
19355+acx100_ioctl_get_led_power(
19356+ struct net_device *ndev,
19357+ struct iw_request_info *info,
19358+ union iwreq_data *wrqu,
19359+ char *extra)
19360+{
19361+ acx_device_t *adev = ndev2adev(ndev);
19362+
19363+ acx_sem_lock(adev);
19364+
19365+ extra[0] = adev->led_power;
19366+ if (adev->led_power == 2)
19367+ extra[1] = adev->brange_max_quality;
19368+ else
19369+ extra[1] = -1;
19370+
19371+ acx_sem_unlock(adev);
19372+
19373+ return OK;
19374+}
19375+
19376+
19377+/***********************************************************************
19378+*/
19379+static int
19380+acx111_ioctl_info(
19381+ struct net_device *ndev,
19382+ struct iw_request_info *info,
19383+ union iwreq_data *wrqu,
19384+ char *extra)
19385+{
19386+ struct iw_param *vwrq = &wrqu->param;
19387+ if (!IS_PCI(ndev2adev(ndev)))
19388+ return OK;
19389+ return acx111pci_ioctl_info(ndev, info, vwrq, extra);
19390+}
19391+
19392+
19393+/***********************************************************************
19394+*/
19395+static int
19396+acx100_ioctl_set_phy_amp_bias(
19397+ struct net_device *ndev,
19398+ struct iw_request_info *info,
19399+ union iwreq_data *wrqu,
19400+ char *extra)
19401+{
19402+ struct iw_param *vwrq = &wrqu->param;
19403+ if (IS_USB(ndev2adev(ndev))) {
19404+ printk("acx: set_phy_amp_bias() is not supported on USB\n");
19405+ return OK;
19406+ }
19407+#ifdef ACX_MEM
19408+ return acx100mem_ioctl_set_phy_amp_bias(ndev, info, vwrq, extra);
19409+#else
19410+ return acx100pci_ioctl_set_phy_amp_bias(ndev, info, vwrq, extra);
19411+#endif
19412+}
19413+
19414+
19415+/***********************************************************************
19416+*/
19417+static const iw_handler acx_ioctl_handler[] =
19418+{
19419+ acx_ioctl_commit, /* SIOCSIWCOMMIT */
19420+ acx_ioctl_get_name, /* SIOCGIWNAME */
19421+ NULL, /* SIOCSIWNWID */
19422+ NULL, /* SIOCGIWNWID */
19423+ acx_ioctl_set_freq, /* SIOCSIWFREQ */
19424+ acx_ioctl_get_freq, /* SIOCGIWFREQ */
19425+ acx_ioctl_set_mode, /* SIOCSIWMODE */
19426+ acx_ioctl_get_mode, /* SIOCGIWMODE */
19427+ acx_ioctl_set_sens, /* SIOCSIWSENS */
19428+ acx_ioctl_get_sens, /* SIOCGIWSENS */
19429+ NULL, /* SIOCSIWRANGE */
19430+ acx_ioctl_get_range, /* SIOCGIWRANGE */
19431+ NULL, /* SIOCSIWPRIV */
19432+ NULL, /* SIOCGIWPRIV */
19433+ NULL, /* SIOCSIWSTATS */
19434+ NULL, /* SIOCGIWSTATS */
19435+#if IW_HANDLER_VERSION > 4
19436+ iw_handler_set_spy, /* SIOCSIWSPY */
19437+ iw_handler_get_spy, /* SIOCGIWSPY */
19438+ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
19439+ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
19440+#else /* IW_HANDLER_VERSION > 4 */
19441+#ifdef WIRELESS_SPY
19442+ NULL /* acx_ioctl_set_spy FIXME */, /* SIOCSIWSPY */
19443+ NULL /* acx_ioctl_get_spy */, /* SIOCGIWSPY */
19444+#else /* WSPY */
19445+ NULL, /* SIOCSIWSPY */
19446+ NULL, /* SIOCGIWSPY */
19447+#endif /* WSPY */
19448+ NULL, /* [nothing] */
19449+ NULL, /* [nothing] */
19450+#endif /* IW_HANDLER_VERSION > 4 */
19451+ acx_ioctl_set_ap, /* SIOCSIWAP */
19452+ acx_ioctl_get_ap, /* SIOCGIWAP */
19453+ NULL, /* [nothing] */
19454+ acx_ioctl_get_aplist, /* SIOCGIWAPLIST */
19455+ acx_ioctl_set_scan, /* SIOCSIWSCAN */
19456+ acx_ioctl_get_scan, /* SIOCGIWSCAN */
19457+ acx_ioctl_set_essid, /* SIOCSIWESSID */
19458+ acx_ioctl_get_essid, /* SIOCGIWESSID */
19459+ acx_ioctl_set_nick, /* SIOCSIWNICKN */
19460+ acx_ioctl_get_nick, /* SIOCGIWNICKN */
19461+ NULL, /* [nothing] */
19462+ NULL, /* [nothing] */
19463+ acx_ioctl_set_rate, /* SIOCSIWRATE */
19464+ acx_ioctl_get_rate, /* SIOCGIWRATE */
19465+ acx_ioctl_set_rts, /* SIOCSIWRTS */
19466+ acx_ioctl_get_rts, /* SIOCGIWRTS */
19467+#if ACX_FRAGMENTATION
19468+ acx_ioctl_set_frag, /* SIOCSIWFRAG */
19469+ acx_ioctl_get_frag, /* SIOCGIWFRAG */
19470+#else
19471+ NULL, /* SIOCSIWFRAG */
19472+ NULL, /* SIOCGIWFRAG */
19473+#endif
19474+ acx_ioctl_set_txpow, /* SIOCSIWTXPOW */
19475+ acx_ioctl_get_txpow, /* SIOCGIWTXPOW */
19476+ acx_ioctl_set_retry, /* SIOCSIWRETRY */
19477+ acx_ioctl_get_retry, /* SIOCGIWRETRY */
19478+ acx_ioctl_set_encode, /* SIOCSIWENCODE */
19479+ acx_ioctl_get_encode, /* SIOCGIWENCODE */
19480+ acx_ioctl_set_power, /* SIOCSIWPOWER */
19481+ acx_ioctl_get_power, /* SIOCGIWPOWER */
19482+};
19483+
19484+
19485+/***********************************************************************
19486+*/
19487+
19488+/* if you plan to reorder something, make sure to reorder all other places
19489+ * accordingly! */
19490+/* SET/GET convention: SETs must have even position, GETs odd */
19491+#define ACX100_IOCTL SIOCIWFIRSTPRIV
19492+enum {
19493+ ACX100_IOCTL_DEBUG = ACX100_IOCTL,
19494+ ACX100_IOCTL_GET__________UNUSED1,
19495+ ACX100_IOCTL_SET_PLED,
19496+ ACX100_IOCTL_GET_PLED,
19497+ ACX100_IOCTL_SET_RATES,
19498+ ACX100_IOCTL_LIST_DOM,
19499+ ACX100_IOCTL_SET_DOM,
19500+ ACX100_IOCTL_GET_DOM,
19501+ ACX100_IOCTL_SET_SCAN_PARAMS,
19502+ ACX100_IOCTL_GET_SCAN_PARAMS,
19503+ ACX100_IOCTL_SET_PREAMB,
19504+ ACX100_IOCTL_GET_PREAMB,
19505+ ACX100_IOCTL_SET_ANT,
19506+ ACX100_IOCTL_GET_ANT,
19507+ ACX100_IOCTL_RX_ANT,
19508+ ACX100_IOCTL_TX_ANT,
19509+ ACX100_IOCTL_SET_PHY_AMP_BIAS,
19510+ ACX100_IOCTL_GET_PHY_CHAN_BUSY,
19511+ ACX100_IOCTL_SET_ED,
19512+ ACX100_IOCTL_GET__________UNUSED3,
19513+ ACX100_IOCTL_SET_CCA,
19514+ ACX100_IOCTL_GET__________UNUSED4,
19515+ ACX100_IOCTL_MONITOR,
19516+ ACX100_IOCTL_TEST,
19517+ ACX100_IOCTL_DBG_SET_MASKS,
19518+ ACX111_IOCTL_INFO,
19519+ ACX100_IOCTL_DBG_SET_IO,
19520+ ACX100_IOCTL_DBG_GET_IO
19521+};
19522+
19523+
19524+static const iw_handler acx_ioctl_private_handler[] =
19525+{
19526+#if ACX_DEBUG
19527+[ACX100_IOCTL_DEBUG - ACX100_IOCTL] = acx_ioctl_set_debug,
19528+#endif
19529+[ACX100_IOCTL_SET_PLED - ACX100_IOCTL] = acx100_ioctl_set_led_power,
19530+[ACX100_IOCTL_GET_PLED - ACX100_IOCTL] = acx100_ioctl_get_led_power,
19531+[ACX100_IOCTL_SET_RATES - ACX100_IOCTL] = acx_ioctl_set_rates,
19532+[ACX100_IOCTL_LIST_DOM - ACX100_IOCTL] = acx_ioctl_list_reg_domain,
19533+[ACX100_IOCTL_SET_DOM - ACX100_IOCTL] = acx_ioctl_set_reg_domain,
19534+[ACX100_IOCTL_GET_DOM - ACX100_IOCTL] = acx_ioctl_get_reg_domain,
19535+[ACX100_IOCTL_SET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_set_scan_params,
19536+[ACX100_IOCTL_GET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_get_scan_params,
19537+[ACX100_IOCTL_SET_PREAMB - ACX100_IOCTL] = acx_ioctl_set_short_preamble,
19538+[ACX100_IOCTL_GET_PREAMB - ACX100_IOCTL] = acx_ioctl_get_short_preamble,
19539+[ACX100_IOCTL_SET_ANT - ACX100_IOCTL] = acx_ioctl_set_antenna,
19540+[ACX100_IOCTL_GET_ANT - ACX100_IOCTL] = acx_ioctl_get_antenna,
19541+[ACX100_IOCTL_RX_ANT - ACX100_IOCTL] = acx_ioctl_set_rx_antenna,
19542+[ACX100_IOCTL_TX_ANT - ACX100_IOCTL] = acx_ioctl_set_tx_antenna,
19543+[ACX100_IOCTL_SET_PHY_AMP_BIAS - ACX100_IOCTL] = acx100_ioctl_set_phy_amp_bias,
19544+[ACX100_IOCTL_GET_PHY_CHAN_BUSY - ACX100_IOCTL] = acx_ioctl_get_phy_chan_busy_percentage,
19545+[ACX100_IOCTL_SET_ED - ACX100_IOCTL] = acx_ioctl_set_ed_threshold,
19546+[ACX100_IOCTL_SET_CCA - ACX100_IOCTL] = acx_ioctl_set_cca,
19547+[ACX100_IOCTL_MONITOR - ACX100_IOCTL] = acx_ioctl_wlansniff,
19548+[ACX100_IOCTL_TEST - ACX100_IOCTL] = acx_ioctl_unknown11,
19549+[ACX100_IOCTL_DBG_SET_MASKS - ACX100_IOCTL] = acx_ioctl_dbg_set_masks,
19550+[ACX111_IOCTL_INFO - ACX100_IOCTL] = acx111_ioctl_info,
19551+};
19552+
19553+
19554+static const struct iw_priv_args acx_ioctl_private_args[] = {
19555+#if ACX_DEBUG
19556+{ cmd : ACX100_IOCTL_DEBUG,
19557+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
19558+ get_args : 0,
19559+ name : "SetDebug" },
19560+#endif
19561+{ cmd : ACX100_IOCTL_SET_PLED,
19562+ set_args : IW_PRIV_TYPE_BYTE | 2,
19563+ get_args : 0,
19564+ name : "SetLEDPower" },
19565+{ cmd : ACX100_IOCTL_GET_PLED,
19566+ set_args : 0,
19567+ get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2,
19568+ name : "GetLEDPower" },
19569+{ cmd : ACX100_IOCTL_SET_RATES,
19570+ set_args : IW_PRIV_TYPE_CHAR | 256,
19571+ get_args : 0,
19572+ name : "SetRates" },
19573+{ cmd : ACX100_IOCTL_LIST_DOM,
19574+ set_args : 0,
19575+ get_args : 0,
19576+ name : "ListRegDomain" },
19577+{ cmd : ACX100_IOCTL_SET_DOM,
19578+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19579+ get_args : 0,
19580+ name : "SetRegDomain" },
19581+{ cmd : ACX100_IOCTL_GET_DOM,
19582+ set_args : 0,
19583+ get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19584+ name : "GetRegDomain" },
19585+{ cmd : ACX100_IOCTL_SET_SCAN_PARAMS,
19586+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4,
19587+ get_args : 0,
19588+ name : "SetScanParams" },
19589+{ cmd : ACX100_IOCTL_GET_SCAN_PARAMS,
19590+ set_args : 0,
19591+ get_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4,
19592+ name : "GetScanParams" },
19593+{ cmd : ACX100_IOCTL_SET_PREAMB,
19594+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19595+ get_args : 0,
19596+ name : "SetSPreamble" },
19597+{ cmd : ACX100_IOCTL_GET_PREAMB,
19598+ set_args : 0,
19599+ get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19600+ name : "GetSPreamble" },
19601+{ cmd : ACX100_IOCTL_SET_ANT,
19602+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19603+ get_args : 0,
19604+ name : "SetAntenna" },
19605+{ cmd : ACX100_IOCTL_GET_ANT,
19606+ set_args : 0,
19607+ get_args : 0,
19608+ name : "GetAntenna" },
19609+{ cmd : ACX100_IOCTL_RX_ANT,
19610+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19611+ get_args : 0,
19612+ name : "SetRxAnt" },
19613+{ cmd : ACX100_IOCTL_TX_ANT,
19614+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19615+ get_args : 0,
19616+ name : "SetTxAnt" },
19617+{ cmd : ACX100_IOCTL_SET_PHY_AMP_BIAS,
19618+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19619+ get_args : 0,
19620+ name : "SetPhyAmpBias"},
19621+{ cmd : ACX100_IOCTL_GET_PHY_CHAN_BUSY,
19622+ set_args : 0,
19623+ get_args : 0,
19624+ name : "GetPhyChanBusy" },
19625+{ cmd : ACX100_IOCTL_SET_ED,
19626+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
19627+ get_args : 0,
19628+ name : "SetED" },
19629+{ cmd : ACX100_IOCTL_SET_CCA,
19630+ set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
19631+ get_args : 0,
19632+ name : "SetCCA" },
19633+{ cmd : ACX100_IOCTL_MONITOR,
19634+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
19635+ get_args : 0,
19636+ name : "monitor" },
19637+{ cmd : ACX100_IOCTL_TEST,
19638+ set_args : 0,
19639+ get_args : 0,
19640+ name : "Test" },
19641+{ cmd : ACX100_IOCTL_DBG_SET_MASKS,
19642+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
19643+ get_args : 0,
19644+ name : "DbgSetMasks" },
19645+{ cmd : ACX111_IOCTL_INFO,
19646+ set_args : 0,
19647+ get_args : 0,
19648+ name : "GetAcx111Info" },
19649+{ cmd : ACX100_IOCTL_DBG_SET_IO,
19650+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4,
19651+ get_args : 0,
19652+ name : "DbgSetIO" },
19653+{ cmd : ACX100_IOCTL_DBG_GET_IO,
19654+ set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
19655+ get_args : 0,
19656+ name : "DbgGetIO" },
19657+};
19658+
19659+
19660+const struct iw_handler_def acx_ioctl_handler_def =
19661+{
19662+ .num_standard = VEC_SIZE(acx_ioctl_handler),
19663+ .num_private = VEC_SIZE(acx_ioctl_private_handler),
19664+ .num_private_args = VEC_SIZE(acx_ioctl_private_args),
19665+ .standard = (iw_handler *) acx_ioctl_handler,
19666+ .private = (iw_handler *) acx_ioctl_private_handler,
19667+ .private_args = (struct iw_priv_args *) acx_ioctl_private_args,
19668+#if IW_HANDLER_VERSION > 5
19669+ .get_wireless_stats = acx_e_get_wireless_stats
19670+#endif /* IW > 5 */
19671+};
19672Index: linux-2.6.22/drivers/net/wireless/acx/Kconfig
19673===================================================================
19674--- /dev/null 1970-01-01 00:00:00.000000000 +0000
19675+++ linux-2.6.22/drivers/net/wireless/acx/Kconfig 2007-08-23 18:34:19.000000000 +0200
19676@@ -0,0 +1,113 @@
19677+config ACX
19678+ tristate "TI acx100/acx111 802.11b/g wireless chipsets"
19679+ depends on NET_RADIO && EXPERIMENTAL
19680+ select FW_LOADER
19681+ ---help---
19682+ A driver for 802.11b/g wireless cards based on
19683+ Texas Instruments acx100 and acx111 chipsets.
19684+
19685+ This driver supports Host AP mode that allows
19686+ your computer to act as an IEEE 802.11 access point.
19687+ This driver is new and experimental.
19688+
19689+ Texas Instruments did not take part in development of this driver
19690+ in any way, shape or form.
19691+
19692+ The driver can be compiled as a module and will be named "acx".
19693+
19694+config ACX_PCI
19695+ bool "TI acx100/acx111 802.11b/g PCI"
19696+ depends on ACX && PCI
19697+ ---help---
19698+ Include PCI and CardBus support in acx.
19699+
19700+ acx chipsets need their firmware loaded at startup.
19701+ You will need to provide a firmware image via hotplug.
19702+
19703+ Firmware may be in a form of single image 40-100kb in size
19704+ (a 'combined' firmware) or two images - main image
19705+ (again 40-100kb) and radio image (~10kb or less).
19706+
19707+ Firmware images are requested from hotplug using following names:
19708+
19709+ tiacx100 - main firmware image for acx100 chipset
19710+ tiacx100rNN - radio acx100 firmware for radio type NN
19711+ tiacx100cNN - combined acx100 firmware for radio type NN
19712+ tiacx111 - main acx111 firmware
19713+ tiacx111rNN - radio acx111 firmware for radio type NN
19714+ tiacx111cNN - combined acx111 firmware for radio type NN
19715+
19716+ Driver will attempt to load combined image first.
19717+ If no such image is found, it will try to load main image
19718+ and radio image instead.
19719+
19720+ Firmware files are not covered by GPL and are not distributed
19721+ with this driver for legal reasons.
19722+
19723+config ACX_USB
19724+ bool "TI acx100/acx111 802.11b/g USB"
19725+ depends on ACX && (USB=y || USB=ACX)
19726+ ---help---
19727+ Include USB support in acx.
19728+
19729+ There is only one currently known device in this category,
19730+ D-Link DWL-120+, but newer devices seem to be on the horizon.
19731+
19732+ acx chipsets need their firmware loaded at startup.
19733+ You will need to provide a firmware image via hotplug.
19734+
19735+ Firmware for USB device is requested from hotplug
19736+ by the 'tiacx100usb' name.
19737+
19738+ Firmware files are not covered by GPL and are not distributed
19739+ with this driver for legal reasons.
19740+
19741+config ACX_MEM
19742+ bool "TI acx100/acx111 802.11b/g memory mapped slave 16 interface"
19743+ depends on ACX
19744+ ---help---
19745+ acx chipsets need their firmware loaded at startup.
19746+ You will need to provide a firmware image via hotplug.
19747+
19748+ Firmware for USB device is requested from hotplug
19749+ by the 'tiacx100usb' name.
19750+
19751+ Firmware files are not covered by GPL and are not distributed
19752+ with this driver for legal reasons.
19753+
19754+config ACX_CS
19755+ bool "TI acx100/acx111 802.11b/g cardbus interface"
19756+ depends on ACX
19757+ ---help---
19758+ acx chipsets need their firmware loaded at startup.
19759+ You will need to provide a firmware image via hotplug.
19760+
19761+ This driver is based on memory mapped driver.
19762+
19763+ Firmware files are not covered by GPL and are not distributed
19764+ with this driver for legal reasons.
19765+
19766+config ACX_HX4700
19767+ tristate "ACX support for the iPAQ hx4700 using ACX_MEM"
19768+ depends on HX4700_CORE && ACX_MEM
19769+ ---help---
19770+ Include memory interface support in acx for the iPAQ hx4700.
19771+
19772+config ACX_HTCUNIVERSAL
19773+ tristate "ACX support for the HTC Universal using ACX_MEM"
19774+ depends on HTCUNIVERSAL_CORE && HTC_ASIC3 && ACX_MEM
19775+ ---help---
19776+ Include memory interface support in acx for the HTC Universal.
19777+
19778+config ACX_HTCSABLE
19779+ tristate "ACX support for the HTC Sable (IPAQ hw6915) using ACX_MEM"
19780+ depends on MACH_HW6900 && HTC_ASIC3 && ACX_MEM
19781+ ---help---
19782+ Include memory interface support in acx for the HTC Sable (IPAQ hw6915).
19783+
19784+config ACX_RX3000
19785+ tristate "ACX support for the iPAQ RX3000 using ACX_MEM"
19786+ depends on MACH_RX3715 && ACX_MEM && LEDS_ASIC3
19787+ ---help---
19788+ Include memory interface support in acx for the IPAQ RX3000.
19789+
19790Index: linux-2.6.22/drivers/net/wireless/acx/Makefile
19791===================================================================
19792--- /dev/null 1970-01-01 00:00:00.000000000 +0000
19793+++ linux-2.6.22/drivers/net/wireless/acx/Makefile 2007-08-23 18:34:19.000000000 +0200
19794@@ -0,0 +1,21 @@
19795+#obj-m += acx.o
19796+
19797+#acx-obj-y += pci.o
19798+#acx-obj-y += usb.o
19799+
19800+#acx-objs := wlan.o conv.o ioctl.o common.o $(acx-obj-y)
19801+
19802+# Use this if you have proper Kconfig integration:
19803+
19804+obj-$(CONFIG_ACX) += acx.o
19805+obj-$(CONFIG_ACX_HX4700) += hx4700_acx.o
19806+obj-$(CONFIG_ACX_HTCUNIVERSAL) += htcuniversal_acx.o
19807+obj-$(CONFIG_ACX_HTCSABLE) += htcsable_acx.o
19808+obj-$(CONFIG_ACX_RX3000) += rx3000_acx.o
19809+#
19810+acx-obj-$(CONFIG_ACX_PCI) += pci.o
19811+acx-obj-$(CONFIG_ACX_USB) += usb.o
19812+acx-obj-$(CONFIG_ACX_MEM) += mem.o
19813+acx-obj-$(CONFIG_ACX_CS) += cs.o
19814+#
19815+acx-objs := wlan.o conv.o ioctl.o common.o $(acx-obj-y)
19816Index: linux-2.6.22/drivers/net/wireless/acx/mem.c
19817===================================================================
19818--- /dev/null 1970-01-01 00:00:00.000000000 +0000
19819+++ linux-2.6.22/drivers/net/wireless/acx/mem.c 2007-08-23 18:34:19.000000000 +0200
19820@@ -0,0 +1,5363 @@
19821+/***********************************************************************
19822+** Copyright (C) 2003 ACX100 Open Source Project
19823+**
19824+** The contents of this file are subject to the Mozilla Public
19825+** License Version 1.1 (the "License"); you may not use this file
19826+** except in compliance with the License. You may obtain a copy of
19827+** the License at http://www.mozilla.org/MPL/
19828+**
19829+** Software distributed under the License is distributed on an "AS
19830+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
19831+** implied. See the License for the specific language governing
19832+** rights and limitations under the License.
19833+**
19834+** Alternatively, the contents of this file may be used under the
19835+** terms of the GNU Public License version 2 (the "GPL"), in which
19836+** case the provisions of the GPL are applicable instead of the
19837+** above. If you wish to allow the use of your version of this file
19838+** only under the terms of the GPL and not to allow others to use
19839+** your version of this file under the MPL, indicate your decision
19840+** by deleting the provisions above and replace them with the notice
19841+** and other provisions required by the GPL. If you do not delete
19842+** the provisions above, a recipient may use your version of this
19843+** file under either the MPL or the GPL.
19844+** ---------------------------------------------------------------------
19845+** Inquiries regarding the ACX100 Open Source Project can be
19846+** made directly to:
19847+**
19848+** acx100-users@lists.sf.net
19849+** http://acx100.sf.net
19850+** ---------------------------------------------------------------------
19851+**
19852+** Slave memory interface support:
19853+**
19854+** Todd Blumer - SDG Systems
19855+** Bill Reese - HP
19856+** Eric McCorkle - Shadowsun
19857+*/
19858+#define ACX_MEM 1
19859+
19860+/*
19861+ * non-zero makes it dump the ACX memory to the console then
19862+ * panic when you cat /proc/driver/acx_wlan0_diag
19863+ */
19864+#define DUMP_MEM_DEFINED 1
19865+
19866+#define DUMP_MEM_DURING_DIAG 0
19867+#define DUMP_IF_SLOW 0
19868+
19869+#define PATCH_AROUND_BAD_SPOTS 1
19870+#define HX4700_FIRMWARE_CHECKSUM 0x0036862e
19871+#define HX4700_ALTERNATE_FIRMWARE_CHECKSUM 0x00368a75
19872+
19873+#include <linux/version.h>
19874+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
19875+#include <linux/config.h>
19876+#endif
19877+
19878+/* Linux 2.6.18+ uses <linux/utsrelease.h> */
19879+#ifndef UTS_RELEASE
19880+#include <linux/utsrelease.h>
19881+#endif
19882+
19883+#include <linux/compiler.h> /* required for Lx 2.6.8 ?? */
19884+#include <linux/kernel.h>
19885+#include <linux/module.h>
19886+#include <linux/moduleparam.h>
19887+#include <linux/sched.h>
19888+#include <linux/types.h>
19889+#include <linux/skbuff.h>
19890+#include <linux/slab.h>
19891+#include <linux/if_arp.h>
19892+#include <linux/irq.h>
19893+#include <linux/rtnetlink.h>
19894+#include <linux/wireless.h>
19895+#include <net/iw_handler.h>
19896+#include <linux/netdevice.h>
19897+#include <linux/ioport.h>
19898+#include <linux/pci.h>
19899+#include <linux/platform_device.h>
19900+#include <linux/pm.h>
19901+#include <linux/vmalloc.h>
19902+#include <linux/delay.h>
19903+#include <linux/workqueue.h>
19904+#include <linux/inetdevice.h>
19905+
19906+#include "acx.h"
19907+#include "acx_hw.h"
19908+
19909+/***********************************************************************
19910+*/
19911+
19912+#define CARD_EEPROM_ID_SIZE 6
19913+
19914+#include <asm/io.h>
19915+
19916+#define REG_ACX_VENDOR_ID 0x900
19917+/*
19918+ * This is the vendor id on the HX4700, anyway
19919+ */
19920+#define ACX_VENDOR_ID 0x8400104c
19921+
19922+typedef enum {
19923+ ACX_SOFT_RESET = 0,
19924+
19925+ ACX_SLV_REG_ADDR,
19926+ ACX_SLV_REG_DATA,
19927+ ACX_SLV_REG_ADATA,
19928+
19929+ ACX_SLV_MEM_CP,
19930+ ACX_SLV_MEM_ADDR,
19931+ ACX_SLV_MEM_DATA,
19932+ ACX_SLV_MEM_CTL,
19933+} acxreg_t;
19934+
19935+/***********************************************************************
19936+*/
19937+static void acxmem_i_tx_timeout(struct net_device *ndev);
19938+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
19939+static irqreturn_t acxmem_i_interrupt(int irq, void *dev_id);
19940+#else
19941+static irqreturn_t acxmem_i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
19942+#endif
19943+static void acxmem_i_set_multicast_list(struct net_device *ndev);
19944+
19945+static int acxmem_e_open(struct net_device *ndev);
19946+static int acxmem_e_close(struct net_device *ndev);
19947+static void acxmem_s_up(struct net_device *ndev);
19948+static void acxmem_s_down(struct net_device *ndev);
19949+
19950+static void dump_acxmem (acx_device_t *adev, u32 start, int length);
19951+static int acxmem_complete_hw_reset (acx_device_t *adev);
19952+static void acxmem_s_delete_dma_regions(acx_device_t *adev);
19953+
19954+static struct platform_device *resume_pdev;
19955+
19956+static int
19957+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
19958+acxmem_e_suspend(struct platform_device *pdev, pm_message_t state);
19959+#else
19960+acxmem_e_suspend(struct device *pdev, u32 state);
19961+#endif
19962+static void
19963+fw_resumer(struct work_struct *notused);
19964+//fw_resumer( void *data );
19965+
19966+static int acx_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
19967+{
19968+ struct net_device *ndev = ptr;
19969+ acx_device_t *adev = ndev2adev(ndev);
19970+
19971+ /*
19972+ * Upper level ioctl() handlers send a NETDEV_CHANGEADDR if the MAC address changes.
19973+ */
19974+
19975+ if (NETDEV_CHANGEADDR == event) {
19976+ /*
19977+ * the upper layers put the new MAC address in ndev->dev_addr; we just copy
19978+ * it over and update the ACX with it.
19979+ */
19980+ MAC_COPY(adev->dev_addr, adev->ndev->dev_addr);
19981+ adev->set_mask |= GETSET_STATION_ID;
19982+ acx_s_update_card_settings (adev);
19983+ }
19984+
19985+ return 0;
19986+}
19987+
19988+static struct notifier_block acx_netdev_notifier = {
19989+ .notifier_call = acx_netdev_event,
19990+};
19991+
19992+/***********************************************************************
19993+** Register access
19994+*/
19995+
19996+/* Pick one */
19997+/* #define INLINE_IO static */
19998+#define INLINE_IO static inline
19999+
20000+INLINE_IO u32
20001+read_id_register (acx_device_t *adev)
20002+{
20003+ writel (0x24, &adev->iobase[ACX_SLV_REG_ADDR]);
20004+ return readl (&adev->iobase[ACX_SLV_REG_DATA]);
20005+}
20006+
20007+INLINE_IO u32
20008+read_reg32(acx_device_t *adev, unsigned int offset)
20009+{
20010+ u32 val;
20011+ u32 addr;
20012+
20013+ if (offset > IO_ACX_ECPU_CTRL)
20014+ addr = offset;
20015+ else
20016+ addr = adev->io[offset];
20017+
20018+ if (addr < 0x20) {
20019+ return readl(((u8*)adev->iobase) + addr);
20020+ }
20021+
20022+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
20023+ val = readl( &adev->iobase[ACX_SLV_REG_DATA] );
20024+
20025+ return val;
20026+}
20027+
20028+INLINE_IO u16
20029+read_reg16(acx_device_t *adev, unsigned int offset)
20030+{
20031+ u16 lo;
20032+ u32 addr;
20033+
20034+ if (offset > IO_ACX_ECPU_CTRL)
20035+ addr = offset;
20036+ else
20037+ addr = adev->io[offset];
20038+
20039+ if (addr < 0x20) {
20040+ return readw(((u8 *) adev->iobase) + addr);
20041+ }
20042+
20043+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
20044+ lo = readw( (u16 *)&adev->iobase[ACX_SLV_REG_DATA] );
20045+
20046+ return lo;
20047+}
20048+
20049+INLINE_IO u8
20050+read_reg8(acx_device_t *adev, unsigned int offset)
20051+{
20052+ u8 lo;
20053+ u32 addr;
20054+
20055+ if (offset > IO_ACX_ECPU_CTRL)
20056+ addr = offset;
20057+ else
20058+ addr = adev->io[offset];
20059+
20060+ if (addr < 0x20)
20061+ return readb(((u8 *)adev->iobase) + addr);
20062+
20063+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
20064+ lo = readw( (u8 *)&adev->iobase[ACX_SLV_REG_DATA] );
20065+
20066+ return (u8)lo;
20067+}
20068+
20069+INLINE_IO void
20070+write_reg32(acx_device_t *adev, unsigned int offset, u32 val)
20071+{
20072+ u32 addr;
20073+
20074+ if (offset > IO_ACX_ECPU_CTRL)
20075+ addr = offset;
20076+ else
20077+ addr = adev->io[offset];
20078+
20079+ if (addr < 0x20) {
20080+ writel(val, ((u8*)adev->iobase) + addr);
20081+ return;
20082+ }
20083+
20084+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
20085+ writel( val, &adev->iobase[ACX_SLV_REG_DATA] );
20086+}
20087+
20088+INLINE_IO void
20089+write_reg16(acx_device_t *adev, unsigned int offset, u16 val)
20090+{
20091+ u32 addr;
20092+
20093+ if (offset > IO_ACX_ECPU_CTRL)
20094+ addr = offset;
20095+ else
20096+ addr = adev->io[offset];
20097+
20098+ if (addr < 0x20) {
20099+ writew(val, ((u8 *)adev->iobase) + addr);
20100+ return;
20101+ }
20102+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
20103+ writew( val, (u16 *) &adev->iobase[ACX_SLV_REG_DATA] );
20104+}
20105+
20106+INLINE_IO void
20107+write_reg8(acx_device_t *adev, unsigned int offset, u8 val)
20108+{
20109+ u32 addr;
20110+
20111+ if (offset > IO_ACX_ECPU_CTRL)
20112+ addr = offset;
20113+ else
20114+ addr = adev->io[offset];
20115+
20116+ if (addr < 0x20) {
20117+ writeb(val, ((u8 *) adev->iobase) + addr);
20118+ return;
20119+ }
20120+ writel( addr, &adev->iobase[ACX_SLV_REG_ADDR] );
20121+ writeb( val, (u8 *)&adev->iobase[ACX_SLV_REG_DATA] );
20122+}
20123+
20124+/* Handle PCI posting properly:
20125+ * Make sure that writes reach the adapter in case they require to be executed
20126+ * *before* the next write, by reading a random (and safely accessible) register.
20127+ * This call has to be made if there is no read following (which would flush the data
20128+ * to the adapter), yet the written data has to reach the adapter immediately. */
20129+INLINE_IO void
20130+write_flush(acx_device_t *adev)
20131+{
20132+ /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */
20133+ /* faster version (accesses the first register, IO_ACX_SOFT_RESET,
20134+ * which should also be safe): */
20135+ (void) readl(adev->iobase);
20136+}
20137+
20138+INLINE_IO void
20139+set_regbits (acx_device_t *adev, unsigned int offset, u32 bits) {
20140+ u32 tmp;
20141+
20142+ tmp = read_reg32 (adev, offset);
20143+ tmp = tmp | bits;
20144+ write_reg32 (adev, offset, tmp);
20145+ write_flush (adev);
20146+}
20147+
20148+INLINE_IO void
20149+clear_regbits (acx_device_t *adev, unsigned int offset, u32 bits) {
20150+ u32 tmp;
20151+
20152+ tmp = read_reg32 (adev, offset);
20153+ tmp = tmp & ~bits;
20154+ write_reg32 (adev, offset, tmp);
20155+ write_flush (adev);
20156+}
20157+
20158+/*
20159+ * Copy from PXA memory to the ACX memory. This assumes both the PXA and ACX
20160+ * addresses are 32 bit aligned. Count is in bytes.
20161+ */
20162+INLINE_IO void
20163+write_slavemem32 (acx_device_t *adev, u32 slave_address, u32 val)
20164+{
20165+ write_reg32 (adev, IO_ACX_SLV_MEM_CTL, 0x0);
20166+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, slave_address);
20167+ udelay (10);
20168+ write_reg32 (adev, IO_ACX_SLV_MEM_DATA, val);
20169+}
20170+
20171+INLINE_IO u32
20172+read_slavemem32 (acx_device_t *adev, u32 slave_address)
20173+{
20174+ u32 val;
20175+
20176+ write_reg32 (adev, IO_ACX_SLV_MEM_CTL, 0x0);
20177+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, slave_address);
20178+ udelay (10);
20179+ val = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
20180+
20181+ return val;
20182+}
20183+
20184+INLINE_IO void
20185+write_slavemem8 (acx_device_t *adev, u32 slave_address, u8 val)
20186+{
20187+ u32 data;
20188+ u32 base;
20189+ int offset;
20190+
20191+ /*
20192+ * Get the word containing the target address and the byte offset in that word.
20193+ */
20194+ base = slave_address & ~3;
20195+ offset = (slave_address & 3) * 8;
20196+
20197+ data = read_slavemem32 (adev, base);
20198+ data &= ~(0xff << offset);
20199+ data |= val << offset;
20200+ write_slavemem32 (adev, base, data);
20201+}
20202+
20203+INLINE_IO u8
20204+read_slavemem8 (acx_device_t *adev, u32 slave_address)
20205+{
20206+ u8 val;
20207+ u32 base;
20208+ u32 data;
20209+ int offset;
20210+
20211+ base = slave_address & ~3;
20212+ offset = (slave_address & 3) * 8;
20213+
20214+ data = read_slavemem32 (adev, base);
20215+
20216+ val = (data >> offset) & 0xff;
20217+
20218+ return val;
20219+}
20220+
20221+/*
20222+ * doesn't split across word boundaries
20223+ */
20224+INLINE_IO void
20225+write_slavemem16 (acx_device_t *adev, u32 slave_address, u16 val)
20226+{
20227+ u32 data;
20228+ u32 base;
20229+ int offset;
20230+
20231+ /*
20232+ * Get the word containing the target address and the byte offset in that word.
20233+ */
20234+ base = slave_address & ~3;
20235+ offset = (slave_address & 3) * 8;
20236+
20237+ data = read_slavemem32 (adev, base);
20238+ data &= ~(0xffff << offset);
20239+ data |= val << offset;
20240+ write_slavemem32 (adev, base, data);
20241+}
20242+
20243+/*
20244+ * doesn't split across word boundaries
20245+ */
20246+INLINE_IO u16
20247+read_slavemem16 (acx_device_t *adev, u32 slave_address)
20248+{
20249+ u16 val;
20250+ u32 base;
20251+ u32 data;
20252+ int offset;
20253+
20254+ base = slave_address & ~3;
20255+ offset = (slave_address & 3) * 8;
20256+
20257+ data = read_slavemem32 (adev, base);
20258+
20259+ val = (data >> offset) & 0xffff;
20260+
20261+ return val;
20262+}
20263+
20264+/*
20265+ * Copy from slave memory
20266+ *
20267+ * TODO - rewrite using address autoincrement, handle partial words
20268+ */
20269+void
20270+copy_from_slavemem (acx_device_t *adev, u8 *destination, u32 source, int count) {
20271+ u32 tmp = 0;
20272+ u8 *ptmp = (u8 *) &tmp;
20273+
20274+ /*
20275+ * Right now I'm making the assumption that the destination is aligned, but
20276+ * I'd better check.
20277+ */
20278+ if ((u32) destination & 3) {
20279+ printk ("acx copy_from_slavemem: warning! destination not word-aligned!\n");
20280+ }
20281+
20282+ while (count >= 4) {
20283+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, source);
20284+ udelay (10);
20285+ *((u32 *) destination) = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
20286+ count -= 4;
20287+ source += 4;
20288+ destination += 4;
20289+ }
20290+
20291+ /*
20292+ * If the word reads above didn't satisfy the count, read one more word
20293+ * and transfer a byte at a time until the request is satisfied.
20294+ */
20295+ if (count) {
20296+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, source);
20297+ udelay (10);
20298+ tmp = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
20299+ while (count--) {
20300+ *destination++ = *ptmp++;
20301+ }
20302+ }
20303+}
20304+
20305+/*
20306+ * Copy to slave memory
20307+ *
20308+ * TODO - rewrite using autoincrement, handle partial words
20309+ */
20310+void
20311+copy_to_slavemem (acx_device_t *adev, u32 destination, u8 *source, int count)
20312+{
20313+ u32 tmp = 0;
20314+ u8* ptmp = (u8 *) &tmp;
20315+ static u8 src[512]; /* make static to avoid huge stack objects */
20316+
20317+ /*
20318+ * For now, make sure the source is word-aligned by copying it to a word-aligned
20319+ * buffer. Someday rewrite to avoid the extra copy.
20320+ */
20321+ if (count > sizeof (src)) {
20322+ printk ("acx copy_to_slavemem: Warning! buffer overflow!\n");
20323+ count = sizeof (src);
20324+ }
20325+ memcpy (src, source, count);
20326+ source = src;
20327+
20328+ while (count >= 4) {
20329+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, destination);
20330+ udelay (10);
20331+ write_reg32 (adev, IO_ACX_SLV_MEM_DATA, *((u32 *) source));
20332+ count -= 4;
20333+ source += 4;
20334+ destination += 4;
20335+ }
20336+
20337+ /*
20338+ * If there are leftovers read the next word from the acx and merge in
20339+ * what they want to write.
20340+ */
20341+ if (count) {
20342+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, destination);
20343+ udelay (10);
20344+ tmp = read_reg32 (adev, IO_ACX_SLV_MEM_DATA);
20345+ while (count--) {
20346+ *ptmp++ = *source++;
20347+ }
20348+ /*
20349+ * reset address in case we're currently in auto-increment mode
20350+ */
20351+ write_reg32 (adev, IO_ACX_SLV_MEM_ADDR, destination);
20352+ udelay (10);
20353+ write_reg32 (adev, IO_ACX_SLV_MEM_DATA, tmp);
20354+ udelay (10);
20355+ }
20356+
20357+}
20358+
20359+/*
20360+ * Block copy to slave buffers using memory block chain mode. Copies to the ACX
20361+ * transmit buffer structure with minimal intervention on our part.
20362+ * Interrupts should be disabled when calling this.
20363+ */
20364+void
20365+chaincopy_to_slavemem (acx_device_t *adev, u32 destination, u8 *source, int count)
20366+{
20367+ u32 val;
20368+ u32 *data = (u32 *) source;
20369+ static u8 aligned_source[WLAN_A4FR_MAXLEN_WEP_FCS];
20370+
20371+ /*
20372+ * Warn if the pointers don't look right. Destination must fit in [23:5] with
20373+ * zero elsewhere and source should be 32 bit aligned.
20374+ * This should never happen since we're in control of both, but I want to know about
20375+ * it if it does.
20376+ */
20377+ if ((destination & 0x00ffffe0) != destination) {
20378+ printk ("acx chaincopy: destination block 0x%04x not aligned!\n", destination);
20379+ }
20380+ if (count > sizeof aligned_source) {
20381+ printk( KERN_ERR "chaincopy_to_slavemem overflow!\n" );
20382+ count = sizeof aligned_source;
20383+ }
20384+ if ((u32) source & 3) {
20385+ memcpy (aligned_source, source, count);
20386+ data = (u32 *) aligned_source;
20387+ }
20388+
20389+ /*
20390+ * SLV_MEM_CTL[17:16] = memory block chain mode with auto-increment
20391+ * SLV_MEM_CTL[5:2] = offset to data portion = 1 word
20392+ */
20393+ val = 2 << 16 | 1 << 2;
20394+ writel (val, &adev->iobase[ACX_SLV_MEM_CTL]);
20395+
20396+ /*
20397+ * SLV_MEM_CP[23:5] = start of 1st block
20398+ * SLV_MEM_CP[3:2] = offset to memblkptr = 0
20399+ */
20400+ val = destination & 0x00ffffe0;
20401+ writel (val, &adev->iobase[ACX_SLV_MEM_CP]);
20402+
20403+ /*
20404+ * SLV_MEM_ADDR[23:2] = SLV_MEM_CTL[5:2] + SLV_MEM_CP[23:5]
20405+ */
20406+ val = (destination & 0x00ffffe0) + (1<<2);
20407+ writel (val, &adev->iobase[ACX_SLV_MEM_ADDR]);
20408+
20409+ /*
20410+ * Write the data to the slave data register, rounding up to the end
20411+ * of the word containing the last byte (hence the > 0)
20412+ */
20413+ while (count > 0) {
20414+ writel (*data++, &adev->iobase[ACX_SLV_MEM_DATA]);
20415+ count -= 4;
20416+ }
20417+}
20418+
20419+
20420+/*
20421+ * Block copy from slave buffers using memory block chain mode. Copies from the ACX
20422+ * receive buffer structures with minimal intervention on our part.
20423+ * Interrupts should be disabled when calling this.
20424+ */
20425+void
20426+chaincopy_from_slavemem (acx_device_t *adev, u8 *destination, u32 source, int count)
20427+{
20428+ u32 val;
20429+ u32 *data = (u32 *) destination;
20430+ static u8 aligned_destination[WLAN_A4FR_MAXLEN_WEP_FCS];
20431+ int saved_count = count;
20432+
20433+ /*
20434+ * Warn if the pointers don't look right. Destination must fit in [23:5] with
20435+ * zero elsewhere and source should be 32 bit aligned.
20436+ * Turns out the network stack sends unaligned things, so fix them before
20437+ * copying to the ACX.
20438+ */
20439+ if ((source & 0x00ffffe0) != source) {
20440+ printk ("acx chaincopy: source block 0x%04x not aligned!\n", source);
20441+ dump_acxmem (adev, 0, 0x10000);
20442+ }
20443+ if ((u32) destination & 3) {
20444+ //printk ("acx chaincopy: data destination not word aligned!\n");
20445+ data = (u32 *) aligned_destination;
20446+ if (count > sizeof aligned_destination) {
20447+ printk( KERN_ERR "chaincopy_from_slavemem overflow!\n" );
20448+ count = sizeof aligned_destination;
20449+ }
20450+ }
20451+
20452+ /*
20453+ * SLV_MEM_CTL[17:16] = memory block chain mode with auto-increment
20454+ * SLV_MEM_CTL[5:2] = offset to data portion = 1 word
20455+ */
20456+ val = (2 << 16) | (1 << 2);
20457+ writel (val, &adev->iobase[ACX_SLV_MEM_CTL]);
20458+
20459+ /*
20460+ * SLV_MEM_CP[23:5] = start of 1st block
20461+ * SLV_MEM_CP[3:2] = offset to memblkptr = 0
20462+ */
20463+ val = source & 0x00ffffe0;
20464+ writel (val, &adev->iobase[ACX_SLV_MEM_CP]);
20465+
20466+ /*
20467+ * SLV_MEM_ADDR[23:2] = SLV_MEM_CTL[5:2] + SLV_MEM_CP[23:5]
20468+ */
20469+ val = (source & 0x00ffffe0) + (1<<2);
20470+ writel (val, &adev->iobase[ACX_SLV_MEM_ADDR]);
20471+
20472+ /*
20473+ * Read the data from the slave data register, rounding up to the end
20474+ * of the word containing the last byte (hence the > 0)
20475+ */
20476+ while (count > 0) {
20477+ *data++ = readl (&adev->iobase[ACX_SLV_MEM_DATA]);
20478+ count -= 4;
20479+ }
20480+
20481+ /*
20482+ * If the destination wasn't aligned, we would have saved it in
20483+ * the aligned buffer, so copy it where it should go.
20484+ */
20485+ if ((u32) destination & 3) {
20486+ memcpy (destination, aligned_destination, saved_count);
20487+ }
20488+}
20489+
20490+char
20491+printable (char c)
20492+{
20493+ return ((c >= 20) && (c < 127)) ? c : '.';
20494+}
20495+
20496+#if DUMP_MEM_DEFINED > 0
20497+static void
20498+dump_acxmem (acx_device_t *adev, u32 start, int length)
20499+{
20500+ int i;
20501+ u8 buf[16];
20502+
20503+ while (length > 0) {
20504+ printk ("%04x ", start);
20505+ copy_from_slavemem (adev, buf, start, 16);
20506+ for (i = 0; (i < 16) && (i < length); i++) {
20507+ printk ("%02x ", buf[i]);
20508+ }
20509+ for (i = 0; (i < 16) && (i < length); i++) {
20510+ printk ("%c", printable (buf[i]));
20511+ }
20512+ printk ("\n");
20513+ start += 16;
20514+ length -= 16;
20515+ }
20516+}
20517+#endif
20518+
20519+static void
20520+enable_acx_irq(acx_device_t *adev);
20521+static void
20522+disable_acx_irq(acx_device_t *adev);
20523+
20524+/*
20525+ * Return an acx pointer to the next transmit data block.
20526+ */
20527+u32
20528+allocate_acx_txbuf_space (acx_device_t *adev, int count) {
20529+ u32 block, next, last_block;
20530+ int blocks_needed;
20531+ unsigned long flags;
20532+
20533+ spin_lock_irqsave(&adev->txbuf_lock, flags);
20534+ /*
20535+ * Take 4 off the memory block size to account for the reserved word at the start of
20536+ * the block.
20537+ */
20538+ blocks_needed = count / (adev->memblocksize - 4);
20539+ if (count % (adev->memblocksize - 4))
20540+ blocks_needed++;
20541+
20542+ if (blocks_needed <= adev->acx_txbuf_blocks_free) {
20543+ /*
20544+ * Take blocks at the head of the free list.
20545+ */
20546+ last_block = block = adev->acx_txbuf_free;
20547+
20548+ /*
20549+ * Follow block pointers through the requested number of blocks both to
20550+ * find the new head of the free list and to set the flags for the blocks
20551+ * appropriately.
20552+ */
20553+ while (blocks_needed--) {
20554+ /*
20555+ * Keep track of the last block of the allocation
20556+ */
20557+ last_block = adev->acx_txbuf_free;
20558+
20559+ /*
20560+ * Make sure the end control flag is not set.
20561+ */
20562+ next = read_slavemem32 (adev, adev->acx_txbuf_free) & 0x7ffff;
20563+ write_slavemem32 (adev, adev->acx_txbuf_free, next);
20564+
20565+ /*
20566+ * Update the new head of the free list
20567+ */
20568+ adev->acx_txbuf_free = next << 5;
20569+ adev->acx_txbuf_blocks_free--;
20570+
20571+ }
20572+
20573+ /*
20574+ * Flag the last block both by clearing out the next pointer
20575+ * and marking the control field.
20576+ */
20577+ write_slavemem32 (adev, last_block, 0x02000000);
20578+
20579+ /*
20580+ * If we're out of buffers make sure the free list pointer is NULL
20581+ */
20582+ if (!adev->acx_txbuf_blocks_free) {
20583+ adev->acx_txbuf_free = 0;
20584+ }
20585+ }
20586+ else {
20587+ block = 0;
20588+ }
20589+ spin_unlock_irqrestore (&adev->txbuf_lock, flags);
20590+ return block;
20591+}
20592+
20593+/*
20594+ * Return buffer space back to the pool by following the next pointers until we find
20595+ * the block marked as the end. Point the last block to the head of the free list,
20596+ * then update the head of the free list to point to the newly freed memory.
20597+ * This routine gets called in interrupt context, so it shouldn't block to protect
20598+ * the integrity of the linked list. The ISR already holds the lock.
20599+ */
20600+void
20601+reclaim_acx_txbuf_space (acx_device_t *adev, u32 blockptr) {
20602+ u32 cur, last, next;
20603+ unsigned long flags;
20604+
20605+ spin_lock_irqsave (&adev->txbuf_lock, flags);
20606+ if ((blockptr >= adev->acx_txbuf_start) &&
20607+ (blockptr <= adev->acx_txbuf_start +
20608+ (adev->acx_txbuf_numblocks - 1) * adev->memblocksize)) {
20609+ cur = blockptr;
20610+ do {
20611+ last = cur;
20612+ next = read_slavemem32 (adev, cur);
20613+
20614+ /*
20615+ * Advance to the next block in this allocation
20616+ */
20617+ cur = (next & 0x7ffff) << 5;
20618+
20619+ /*
20620+ * This block now counts as free.
20621+ */
20622+ adev->acx_txbuf_blocks_free++;
20623+ } while (!(next & 0x02000000));
20624+
20625+ /*
20626+ * last now points to the last block of that allocation. Update the pointer
20627+ * in that block to point to the free list and reset the free list to the
20628+ * first block of the free call. If there were no free blocks, make sure
20629+ * the new end of the list marks itself as truly the end.
20630+ */
20631+ if (adev->acx_txbuf_free) {
20632+ write_slavemem32 (adev, last, adev->acx_txbuf_free >> 5);
20633+ }
20634+ else {
20635+ write_slavemem32 (adev, last, 0x02000000);
20636+ }
20637+ adev->acx_txbuf_free = blockptr;
20638+ }
20639+ spin_unlock_irqrestore(&adev->txbuf_lock, flags);
20640+}
20641+
20642+/*
20643+ * Initialize the pieces managing the transmit buffer pool on the ACX. The transmit
20644+ * buffer is a circular queue with one 32 bit word reserved at the beginning of each
20645+ * block. The upper 13 bits are a control field, of which only 0x02000000 has any
20646+ * meaning. The lower 19 bits are the address of the next block divided by 32.
20647+ */
20648+void
20649+init_acx_txbuf (acx_device_t *adev) {
20650+
20651+ /*
20652+ * acx100_s_init_memory_pools set up txbuf_start and txbuf_numblocks for us.
20653+ * All we need to do is reset the rest of the bookeeping.
20654+ */
20655+
20656+ adev->acx_txbuf_free = adev->acx_txbuf_start;
20657+ adev->acx_txbuf_blocks_free = adev->acx_txbuf_numblocks;
20658+
20659+ /*
20660+ * Initialization leaves the last transmit pool block without a pointer back to
20661+ * the head of the list, but marked as the end of the list. That's how we want
20662+ * to see it, too, so leave it alone. This is only ever called after a firmware
20663+ * reset, so the ACX memory is in the state we want.
20664+ */
20665+
20666+}
20667+
20668+INLINE_IO int
20669+adev_present(acx_device_t *adev)
20670+{
20671+ /* fast version (accesses the first register, IO_ACX_SOFT_RESET,
20672+ * which should be safe): */
20673+ return readl(adev->iobase) != 0xffffffff;
20674+}
20675+
20676+/***********************************************************************
20677+*/
20678+static inline txdesc_t*
20679+get_txdesc(acx_device_t *adev, int index)
20680+{
20681+ return (txdesc_t*) (((u8*)adev->txdesc_start) + index * adev->txdesc_size);
20682+}
20683+
20684+static inline txdesc_t*
20685+advance_txdesc(acx_device_t *adev, txdesc_t* txdesc, int inc)
20686+{
20687+ return (txdesc_t*) (((u8*)txdesc) + inc * adev->txdesc_size);
20688+}
20689+
20690+static txhostdesc_t*
20691+get_txhostdesc(acx_device_t *adev, txdesc_t* txdesc)
20692+{
20693+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
20694+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
20695+ printk("bad txdesc ptr %p\n", txdesc);
20696+ return NULL;
20697+ }
20698+ index /= adev->txdesc_size;
20699+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
20700+ printk("bad txdesc ptr %p\n", txdesc);
20701+ return NULL;
20702+ }
20703+ return &adev->txhostdesc_start[index*2];
20704+}
20705+
20706+static inline client_t*
20707+get_txc(acx_device_t *adev, txdesc_t* txdesc)
20708+{
20709+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
20710+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
20711+ printk("bad txdesc ptr %p\n", txdesc);
20712+ return NULL;
20713+ }
20714+ index /= adev->txdesc_size;
20715+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
20716+ printk("bad txdesc ptr %p\n", txdesc);
20717+ return NULL;
20718+ }
20719+ return adev->txc[index];
20720+}
20721+
20722+static inline u16
20723+get_txr(acx_device_t *adev, txdesc_t* txdesc)
20724+{
20725+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
20726+ index /= adev->txdesc_size;
20727+ return adev->txr[index];
20728+}
20729+
20730+static inline void
20731+put_txcr(acx_device_t *adev, txdesc_t* txdesc, client_t* c, u16 r111)
20732+{
20733+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
20734+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
20735+ printk("bad txdesc ptr %p\n", txdesc);
20736+ return;
20737+ }
20738+ index /= adev->txdesc_size;
20739+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
20740+ printk("bad txdesc ptr %p\n", txdesc);
20741+ return;
20742+ }
20743+ adev->txc[index] = c;
20744+ adev->txr[index] = r111;
20745+}
20746+
20747+
20748+/***********************************************************************
20749+** EEPROM and PHY read/write helpers
20750+*/
20751+/***********************************************************************
20752+** acxmem_read_eeprom_byte
20753+**
20754+** Function called to read an octet in the EEPROM.
20755+**
20756+** This function is used by acxmem_e_probe to check if the
20757+** connected card is a legal one or not.
20758+**
20759+** Arguments:
20760+** adev ptr to acx_device structure
20761+** addr address to read in the EEPROM
20762+** charbuf ptr to a char. This is where the read octet
20763+** will be stored
20764+*/
20765+int
20766+acxmem_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf)
20767+{
20768+ int result;
20769+ int count;
20770+
20771+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
20772+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr);
20773+ write_flush(adev);
20774+ write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
20775+
20776+ count = 0xffff;
20777+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
20778+ /* scheduling away instead of CPU burning loop
20779+ * doesn't seem to work here at all:
20780+ * awful delay, sometimes also failure.
20781+ * Doesn't matter anyway (only small delay). */
20782+ if (unlikely(!--count)) {
20783+ printk("%s: timeout waiting for EEPROM read\n",
20784+ adev->ndev->name);
20785+ result = NOT_OK;
20786+ goto fail;
20787+ }
20788+ cpu_relax();
20789+ }
20790+
20791+ *charbuf = read_reg8(adev, IO_ACX_EEPROM_DATA);
20792+ log(L_DEBUG, "EEPROM at 0x%04X = 0x%02X\n", addr, *charbuf);
20793+ result = OK;
20794+
20795+fail:
20796+ return result;
20797+}
20798+
20799+
20800+/***********************************************************************
20801+** We don't lock hw accesses here since we never r/w eeprom in IRQ
20802+** Note: this function sleeps only because of GFP_KERNEL alloc
20803+*/
20804+#ifdef UNUSED
20805+int
20806+acxmem_s_write_eeprom(acx_device_t *adev, u32 addr, u32 len, const u8 *charbuf)
20807+{
20808+ u8 *data_verify = NULL;
20809+ unsigned long flags;
20810+ int count, i;
20811+ int result = NOT_OK;
20812+ u16 gpio_orig;
20813+
20814+ printk("acx: WARNING! I would write to EEPROM now. "
20815+ "Since I really DON'T want to unless you know "
20816+ "what you're doing (THIS CODE WILL PROBABLY "
20817+ "NOT WORK YET!), I will abort that now. And "
20818+ "definitely make sure to make a "
20819+ "/proc/driver/acx_wlan0_eeprom backup copy first!!! "
20820+ "(the EEPROM content includes the PCI config header!! "
20821+ "If you kill important stuff, then you WILL "
20822+ "get in trouble and people DID get in trouble already)\n");
20823+ return OK;
20824+
20825+ FN_ENTER;
20826+
20827+ data_verify = kmalloc(len, GFP_KERNEL);
20828+ if (!data_verify) {
20829+ goto end;
20830+ }
20831+
20832+ /* first we need to enable the OE (EEPROM Output Enable) GPIO line
20833+ * to be able to write to the EEPROM.
20834+ * NOTE: an EEPROM writing success has been reported,
20835+ * but you probably have to modify GPIO_OUT, too,
20836+ * and you probably need to activate a different GPIO
20837+ * line instead! */
20838+ gpio_orig = read_reg16(adev, IO_ACX_GPIO_OE);
20839+ write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig & ~1);
20840+ write_flush(adev);
20841+
20842+ /* ok, now start writing the data out */
20843+ for (i = 0; i < len; i++) {
20844+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
20845+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
20846+ write_reg32(adev, IO_ACX_EEPROM_DATA, *(charbuf + i));
20847+ write_flush(adev);
20848+ write_reg32(adev, IO_ACX_EEPROM_CTL, 1);
20849+
20850+ count = 0xffff;
20851+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
20852+ if (unlikely(!--count)) {
20853+ printk("WARNING, DANGER!!! "
20854+ "Timeout waiting for EEPROM write\n");
20855+ goto end;
20856+ }
20857+ cpu_relax();
20858+ }
20859+ }
20860+
20861+ /* disable EEPROM writing */
20862+ write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig);
20863+ write_flush(adev);
20864+
20865+ /* now start a verification run */
20866+ for (i = 0; i < len; i++) {
20867+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
20868+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
20869+ write_flush(adev);
20870+ write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
20871+
20872+ count = 0xffff;
20873+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
20874+ if (unlikely(!--count)) {
20875+ printk("timeout waiting for EEPROM read\n");
20876+ goto end;
20877+ }
20878+ cpu_relax();
20879+ }
20880+
20881+ data_verify[i] = read_reg16(adev, IO_ACX_EEPROM_DATA);
20882+ }
20883+
20884+ if (0 == memcmp(charbuf, data_verify, len))
20885+ result = OK; /* read data matches, success */
20886+
20887+end:
20888+ kfree(data_verify);
20889+ FN_EXIT1(result);
20890+ return result;
20891+}
20892+#endif /* UNUSED */
20893+
20894+
20895+/***********************************************************************
20896+** acxmem_s_read_phy_reg
20897+**
20898+** Messing with rx/tx disabling and enabling here
20899+** (write_reg32(adev, IO_ACX_ENABLE, 0b000000xx)) kills traffic
20900+*/
20901+int
20902+acxmem_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf)
20903+{
20904+ int result = NOT_OK;
20905+ int count;
20906+
20907+ FN_ENTER;
20908+
20909+ write_reg32(adev, IO_ACX_PHY_ADDR, reg);
20910+ write_flush(adev);
20911+ write_reg32(adev, IO_ACX_PHY_CTL, 2);
20912+
20913+ count = 0xffff;
20914+ while (read_reg32(adev, IO_ACX_PHY_CTL)) {
20915+ /* scheduling away instead of CPU burning loop
20916+ * doesn't seem to work here at all:
20917+ * awful delay, sometimes also failure.
20918+ * Doesn't matter anyway (only small delay). */
20919+ if (unlikely(!--count)) {
20920+ printk("%s: timeout waiting for phy read\n",
20921+ adev->ndev->name);
20922+ *charbuf = 0;
20923+ goto fail;
20924+ }
20925+ cpu_relax();
20926+ }
20927+
20928+ log(L_DEBUG, "count was %u\n", count);
20929+ *charbuf = read_reg8(adev, IO_ACX_PHY_DATA);
20930+
20931+ log(L_DEBUG, "radio PHY at 0x%04X = 0x%02X\n", *charbuf, reg);
20932+ result = OK;
20933+ goto fail; /* silence compiler warning */
20934+fail:
20935+ FN_EXIT1(result);
20936+ return result;
20937+}
20938+
20939+
20940+/***********************************************************************
20941+*/
20942+int
20943+acxmem_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value)
20944+{
20945+ int count;
20946+ FN_ENTER;
20947+
20948+ /* mprusko said that 32bit accesses result in distorted sensitivity
20949+ * on his card. Unconfirmed, looks like it's not true (most likely since we
20950+ * now properly flush writes). */
20951+ write_reg32(adev, IO_ACX_PHY_DATA, value);
20952+ write_reg32(adev, IO_ACX_PHY_ADDR, reg);
20953+ write_flush(adev);
20954+ write_reg32(adev, IO_ACX_PHY_CTL, 1);
20955+ write_flush(adev);
20956+
20957+ count = 0xffff;
20958+ while (read_reg32(adev, IO_ACX_PHY_CTL)) {
20959+ /* scheduling away instead of CPU burning loop
20960+ * doesn't seem to work here at all:
20961+ * awful delay, sometimes also failure.
20962+ * Doesn't matter anyway (only small delay). */
20963+ if (unlikely(!--count)) {
20964+ printk("%s: timeout waiting for phy read\n",
20965+ adev->ndev->name);
20966+ goto fail;
20967+ }
20968+ cpu_relax();
20969+ }
20970+
20971+ log(L_DEBUG, "radio PHY write 0x%02X at 0x%04X\n", value, reg);
20972+ fail:
20973+ FN_EXIT1(OK);
20974+ return OK;
20975+}
20976+
20977+
20978+#define NO_AUTO_INCREMENT 1
20979+
20980+/***********************************************************************
20981+** acxmem_s_write_fw
20982+**
20983+** Write the firmware image into the card.
20984+**
20985+** Arguments:
20986+** adev wlan device structure
20987+** fw_image firmware image.
20988+**
20989+** Returns:
20990+** 1 firmware image corrupted
20991+** 0 success
20992+*/
20993+static int
20994+acxmem_s_write_fw(acx_device_t *adev, const firmware_image_t *fw_image, u32 offset)
20995+{
20996+ int len, size, checkMismatch = -1;
20997+ u32 sum, v32, tmp, id;
20998+ /* we skip the first four bytes which contain the control sum */
20999+ const u8 *p = (u8*)fw_image + 4;
21000+
21001+ /* start the image checksum by adding the image size value */
21002+ sum = p[0]+p[1]+p[2]+p[3];
21003+ p += 4;
21004+
21005+#ifdef NOPE
21006+#if NO_AUTO_INCREMENT
21007+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */
21008+#else
21009+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */
21010+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */
21011+ write_flush(adev);
21012+#endif
21013+#endif
21014+ len = 0;
21015+ size = le32_to_cpu(fw_image->size) & (~3);
21016+
21017+ while (likely(len < size)) {
21018+ v32 = be32_to_cpu(*(u32*)p);
21019+ sum += p[0]+p[1]+p[2]+p[3];
21020+ p += 4;
21021+ len += 4;
21022+
21023+#ifdef NOPE
21024+#if NO_AUTO_INCREMENT
21025+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4);
21026+ write_flush(adev);
21027+#endif
21028+ write_reg32(adev, IO_ACX_SLV_MEM_DATA, v32);
21029+ write_flush(adev);
21030+#endif
21031+ write_slavemem32 (adev, offset + len - 4, v32);
21032+
21033+ id = read_id_register (adev);
21034+
21035+ /*
21036+ * check the data written
21037+ */
21038+ tmp = read_slavemem32 (adev, offset + len - 4);
21039+ if (checkMismatch && (tmp != v32)) {
21040+ printk ("first data mismatch at 0x%08x good 0x%08x bad 0x%08x id 0x%08x\n",
21041+ offset + len - 4, v32, tmp, id);
21042+ checkMismatch = 0;
21043+ }
21044+ }
21045+ log(L_DEBUG, "firmware written, size:%d sum1:%x sum2:%x\n",
21046+ size, sum, le32_to_cpu(fw_image->chksum));
21047+
21048+ /* compare our checksum with the stored image checksum */
21049+ return (sum != le32_to_cpu(fw_image->chksum));
21050+}
21051+
21052+
21053+/***********************************************************************
21054+** acxmem_s_validate_fw
21055+**
21056+** Compare the firmware image given with
21057+** the firmware image written into the card.
21058+**
21059+** Arguments:
21060+** adev wlan device structure
21061+** fw_image firmware image.
21062+**
21063+** Returns:
21064+** NOT_OK firmware image corrupted or not correctly written
21065+** OK success
21066+*/
21067+static int
21068+acxmem_s_validate_fw(acx_device_t *adev, const firmware_image_t *fw_image,
21069+ u32 offset)
21070+{
21071+ u32 sum, v32, w32;
21072+ int len, size;
21073+ int result = OK;
21074+ /* we skip the first four bytes which contain the control sum */
21075+ const u8 *p = (u8*)fw_image + 4;
21076+
21077+ /* start the image checksum by adding the image size value */
21078+ sum = p[0]+p[1]+p[2]+p[3];
21079+ p += 4;
21080+
21081+ write_reg32(adev, IO_ACX_SLV_END_CTL, 0);
21082+
21083+#if NO_AUTO_INCREMENT
21084+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */
21085+#else
21086+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */
21087+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */
21088+#endif
21089+
21090+ len = 0;
21091+ size = le32_to_cpu(fw_image->size) & (~3);
21092+
21093+ while (likely(len < size)) {
21094+ v32 = be32_to_cpu(*(u32*)p);
21095+ p += 4;
21096+ len += 4;
21097+
21098+#ifdef NOPE
21099+#if NO_AUTO_INCREMENT
21100+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4);
21101+#endif
21102+ udelay(10);
21103+ w32 = read_reg32(adev, IO_ACX_SLV_MEM_DATA);
21104+#endif
21105+ w32 = read_slavemem32 (adev, offset + len - 4);
21106+
21107+ if (unlikely(w32 != v32)) {
21108+ printk("acx: FATAL: firmware upload: "
21109+ "data parts at offset %d don't match\n(0x%08X vs. 0x%08X)!\n"
21110+ "I/O timing issues or defective memory, with DWL-xx0+? "
21111+ "ACX_IO_WIDTH=16 may help. Please report\n",
21112+ len, v32, w32);
21113+ result = NOT_OK;
21114+ break;
21115+ }
21116+
21117+ sum += (u8)w32 + (u8)(w32>>8) + (u8)(w32>>16) + (u8)(w32>>24);
21118+ }
21119+
21120+ /* sum control verification */
21121+ if (result != NOT_OK) {
21122+ if (sum != le32_to_cpu(fw_image->chksum)) {
21123+ printk("acx: FATAL: firmware upload: "
21124+ "checksums don't match!\n");
21125+ result = NOT_OK;
21126+ }
21127+ }
21128+
21129+ return result;
21130+}
21131+
21132+
21133+/***********************************************************************
21134+** acxmem_s_upload_fw
21135+**
21136+** Called from acx_reset_dev
21137+*/
21138+static int
21139+acxmem_s_upload_fw(acx_device_t *adev)
21140+{
21141+ firmware_image_t *fw_image = NULL;
21142+ int res = NOT_OK;
21143+ int try;
21144+ u32 file_size;
21145+ char *filename = "WLANGEN.BIN";
21146+#ifdef PATCH_AROUND_BAD_SPOTS
21147+ u32 offset;
21148+ int i;
21149+ /*
21150+ * arm-linux-objdump -d patch.bin, or
21151+ * od -Ax -t x4 patch.bin after finding the bounds
21152+ * of the .text section with arm-linux-objdump -s patch.bin
21153+ */
21154+ u32 patch[] = {
21155+ 0xe584c030, 0xe59fc008,
21156+ 0xe92d1000, 0xe59fc004, 0xe8bd8000, 0x0000080c,
21157+ 0x0000aa68, 0x605a2200, 0x2c0a689c, 0x2414d80a,
21158+ 0x2f00689f, 0x1c27d007, 0x06241e7c, 0x2f000e24,
21159+ 0xe000d1f6, 0x602e6018, 0x23036468, 0x480203db,
21160+ 0x60ca6003, 0xbdf0750a, 0xffff0808
21161+ };
21162+#endif
21163+
21164+ FN_ENTER;
21165+ /* No combined image; tell common we need the radio firmware, too */
21166+ adev->need_radio_fw = 1;
21167+
21168+ fw_image = acx_s_read_fw(adev->dev, filename, &file_size);
21169+ if (!fw_image) {
21170+ FN_EXIT1(NOT_OK);
21171+ return NOT_OK;
21172+ }
21173+
21174+ for (try = 1; try <= 5; try++) {
21175+ res = acxmem_s_write_fw(adev, fw_image, 0);
21176+ log(L_DEBUG|L_INIT, "acx_write_fw (main): %d\n", res);
21177+ if (OK == res) {
21178+ res = acxmem_s_validate_fw(adev, fw_image, 0);
21179+ log(L_DEBUG|L_INIT, "acx_validate_fw "
21180+ "(main): %d\n", res);
21181+ }
21182+
21183+ if (OK == res) {
21184+ SET_BIT(adev->dev_state_mask, ACX_STATE_FW_LOADED);
21185+ break;
21186+ }
21187+ printk("acx: firmware upload attempt #%d FAILED, "
21188+ "retrying...\n", try);
21189+ acx_s_msleep(1000); /* better wait for a while... */
21190+ }
21191+
21192+#ifdef PATCH_AROUND_BAD_SPOTS
21193+ /*
21194+ * Only want to do this if the firmware is exactly what we expect for an
21195+ * iPaq 4700; otherwise, bad things would ensue.
21196+ */
21197+ if ((HX4700_FIRMWARE_CHECKSUM == fw_image->chksum) ||
21198+ (HX4700_ALTERNATE_FIRMWARE_CHECKSUM == fw_image->chksum)) {
21199+ /*
21200+ * Put the patch after the main firmware image. 0x950c contains
21201+ * the ACX's idea of the end of the firmware. Use that location to
21202+ * load ours (which depends on that location being 0xab58) then
21203+ * update that location to point to after ours.
21204+ */
21205+
21206+ offset = read_slavemem32 (adev, 0x950c);
21207+
21208+ log (L_DEBUG, "acx: patching in at 0x%04x\n", offset);
21209+
21210+ for (i = 0; i < sizeof(patch) / sizeof(patch[0]); i++) {
21211+ write_slavemem32 (adev, offset, patch[i]);
21212+ offset += sizeof(u32);
21213+ }
21214+
21215+ /*
21216+ * Patch the instruction at 0x0804 to branch to our ARM patch at 0xab58
21217+ */
21218+ write_slavemem32 (adev, 0x0804, 0xea000000 + (0xab58-0x0804-8)/4);
21219+
21220+ /*
21221+ * Patch the instructions at 0x1f40 to branch to our Thumb patch at 0xab74
21222+ *
21223+ * 4a00 ldr r2, [pc, #0]
21224+ * 4710 bx r2
21225+ * .data 0xab74+1
21226+ */
21227+ write_slavemem32 (adev, 0x1f40, 0x47104a00);
21228+ write_slavemem32 (adev, 0x1f44, 0x0000ab74+1);
21229+
21230+ /*
21231+ * Bump the end of the firmware up to beyond our patch.
21232+ */
21233+ write_slavemem32 (adev, 0x950c, offset);
21234+
21235+ }
21236+#endif
21237+
21238+ vfree(fw_image);
21239+
21240+ FN_EXIT1(res);
21241+ return res;
21242+}
21243+
21244+
21245+/***********************************************************************
21246+** acxmem_s_upload_radio
21247+**
21248+** Uploads the appropriate radio module firmware into the card.
21249+*/
21250+int
21251+acxmem_s_upload_radio(acx_device_t *adev)
21252+{
21253+ acx_ie_memmap_t mm;
21254+ firmware_image_t *radio_image;
21255+ acx_cmd_radioinit_t radioinit;
21256+ int res = NOT_OK;
21257+ int try;
21258+ u32 offset;
21259+ u32 size;
21260+ char filename[sizeof("RADIONN.BIN")];
21261+
21262+ if (!adev->need_radio_fw) return OK;
21263+
21264+ FN_ENTER;
21265+
21266+ acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP);
21267+ offset = le32_to_cpu(mm.CodeEnd);
21268+
21269+ snprintf(filename, sizeof(filename), "RADIO%02x.BIN",
21270+ adev->radio_type);
21271+ radio_image = acx_s_read_fw(adev->dev, filename, &size);
21272+ if (!radio_image) {
21273+ printk("acx: can't load radio module '%s'\n", filename);
21274+ goto fail;
21275+ }
21276+
21277+ acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0);
21278+
21279+ for (try = 1; try <= 5; try++) {
21280+ res = acxmem_s_write_fw(adev, radio_image, offset);
21281+ log(L_DEBUG|L_INIT, "acx_write_fw (radio): %d\n", res);
21282+ if (OK == res) {
21283+ res = acxmem_s_validate_fw(adev, radio_image, offset);
21284+ log(L_DEBUG|L_INIT, "acx_validate_fw (radio): %d\n", res);
21285+ }
21286+
21287+ if (OK == res)
21288+ break;
21289+ printk("acx: radio firmware upload attempt #%d FAILED, "
21290+ "retrying...\n", try);
21291+ acx_s_msleep(1000); /* better wait for a while... */
21292+ }
21293+
21294+ acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0);
21295+ radioinit.offset = cpu_to_le32(offset);
21296+
21297+ /* no endian conversion needed, remains in card CPU area: */
21298+ radioinit.len = radio_image->size;
21299+
21300+ vfree(radio_image);
21301+
21302+ if (OK != res)
21303+ goto fail;
21304+
21305+ /* will take a moment so let's have a big timeout */
21306+ acx_s_issue_cmd_timeo(adev, ACX1xx_CMD_RADIOINIT,
21307+ &radioinit, sizeof(radioinit), CMD_TIMEOUT_MS(1000));
21308+
21309+ res = acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP);
21310+
21311+fail:
21312+ FN_EXIT1(res);
21313+ return res;
21314+}
21315+
21316+/***********************************************************************
21317+** acxmem_l_reset_mac
21318+**
21319+** MAC will be reset
21320+** Call context: reset_dev
21321+*/
21322+static void
21323+acxmem_l_reset_mac(acx_device_t *adev)
21324+{
21325+ int count;
21326+ FN_ENTER;
21327+
21328+ /* halt eCPU */
21329+ set_regbits (adev, IO_ACX_ECPU_CTRL, 0x1);
21330+
21331+ /* now do soft reset of eCPU, set bit */
21332+ set_regbits (adev, IO_ACX_SOFT_RESET, 0x1);
21333+ log(L_DEBUG, "%s: enable soft reset...\n", __func__);
21334+
21335+ /* Windows driver sleeps here for a while with this sequence */
21336+ for (count = 0; count < 200; count++) {
21337+ udelay (50);
21338+ }
21339+
21340+ /* now clear bit again: deassert eCPU reset */
21341+ log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__);
21342+ clear_regbits (adev, IO_ACX_SOFT_RESET, 0x1);
21343+
21344+ /* now start a burst read from initial EEPROM */
21345+ set_regbits (adev, IO_ACX_EE_START, 0x1);
21346+
21347+ /*
21348+ * Windows driver sleeps here for a while with this sequence
21349+ */
21350+ for (count = 0; count < 200; count++) {
21351+ udelay (50);
21352+ }
21353+
21354+ /* Windows driver writes 0x10000 to register 0x808 here */
21355+
21356+ write_reg32 (adev, 0x808, 0x10000);
21357+
21358+ FN_EXIT0;
21359+}
21360+
21361+
21362+/***********************************************************************
21363+** acxmem_s_verify_init
21364+*/
21365+static int
21366+acxmem_s_verify_init(acx_device_t *adev)
21367+{
21368+ int result = NOT_OK;
21369+ unsigned long timeout;
21370+
21371+ FN_ENTER;
21372+
21373+ timeout = jiffies + 2*HZ;
21374+ for (;;) {
21375+ u32 irqstat = read_reg32(adev, IO_ACX_IRQ_STATUS_NON_DES);
21376+ if ((irqstat != 0xFFFFFFFF) && (irqstat & HOST_INT_FCS_THRESHOLD)) {
21377+ result = OK;
21378+ write_reg32(adev, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD);
21379+ break;
21380+ }
21381+ if (time_after(jiffies, timeout))
21382+ break;
21383+ /* Init may take up to ~0.5 sec total */
21384+ acx_s_msleep(50);
21385+ }
21386+
21387+ FN_EXIT1(result);
21388+ return result;
21389+}
21390+
21391+
21392+/***********************************************************************
21393+** A few low-level helpers
21394+**
21395+** Note: these functions are not protected by lock
21396+** and thus are never allowed to be called from IRQ.
21397+** Also they must not race with fw upload which uses same hw regs
21398+*/
21399+
21400+/***********************************************************************
21401+** acxmem_write_cmd_type_status
21402+*/
21403+
21404+static inline void
21405+acxmem_write_cmd_type_status(acx_device_t *adev, u16 type, u16 status)
21406+{
21407+ write_slavemem32 (adev, (u32) adev->cmd_area, type | (status << 16));
21408+ write_flush(adev);
21409+}
21410+
21411+
21412+/***********************************************************************
21413+** acxmem_read_cmd_type_status
21414+*/
21415+static u32
21416+acxmem_read_cmd_type_status(acx_device_t *adev)
21417+{
21418+ u32 cmd_type, cmd_status;
21419+
21420+ cmd_type = read_slavemem32 (adev, (u32) adev->cmd_area);
21421+
21422+ cmd_status = (cmd_type >> 16);
21423+ cmd_type = (u16)cmd_type;
21424+
21425+ log(L_CTL, "cmd_type:%04X cmd_status:%04X [%s]\n",
21426+ cmd_type, cmd_status,
21427+ acx_cmd_status_str(cmd_status));
21428+
21429+ return cmd_status;
21430+}
21431+
21432+
21433+/***********************************************************************
21434+** acxmem_s_reset_dev
21435+**
21436+** Arguments:
21437+** netdevice that contains the adev variable
21438+** Returns:
21439+** NOT_OK on fail
21440+** OK on success
21441+** Side effects:
21442+** device is hard reset
21443+** Call context:
21444+** acxmem_e_probe
21445+** Comment:
21446+** This resets the device using low level hardware calls
21447+** as well as uploads and verifies the firmware to the card
21448+*/
21449+
21450+static inline void
21451+init_mboxes(acx_device_t *adev)
21452+{
21453+ u32 cmd_offs, info_offs;
21454+
21455+ cmd_offs = read_reg32(adev, IO_ACX_CMD_MAILBOX_OFFS);
21456+ info_offs = read_reg32(adev, IO_ACX_INFO_MAILBOX_OFFS);
21457+ adev->cmd_area = (u8*) cmd_offs;
21458+ adev->info_area = (u8*) info_offs;
21459+ /*
21460+ log(L_DEBUG, "iobase2=%p\n"
21461+ */
21462+ log( L_DEBUG, "cmd_mbox_offset=%X cmd_area=%p\n"
21463+ "info_mbox_offset=%X info_area=%p\n",
21464+ cmd_offs, adev->cmd_area,
21465+ info_offs, adev->info_area);
21466+}
21467+
21468+
21469+static inline void
21470+read_eeprom_area(acx_device_t *adev)
21471+{
21472+#if ACX_DEBUG > 1
21473+ int offs;
21474+ u8 tmp;
21475+
21476+ for (offs = 0x8c; offs < 0xb9; offs++)
21477+ acxmem_read_eeprom_byte(adev, offs, &tmp);
21478+#endif
21479+}
21480+
21481+static int
21482+acxmem_s_reset_dev(acx_device_t *adev)
21483+{
21484+ const char* msg = "";
21485+ unsigned long flags;
21486+ int result = NOT_OK;
21487+ u16 hardware_info;
21488+ u16 ecpu_ctrl;
21489+ int count;
21490+ u32 tmp;
21491+
21492+ FN_ENTER;
21493+ /*
21494+ write_reg32 (adev, IO_ACX_SLV_MEM_CP, 0);
21495+ */
21496+ /* reset the device to make sure the eCPU is stopped
21497+ * to upload the firmware correctly */
21498+
21499+ acx_lock(adev, flags);
21500+
21501+ /* Windows driver does some funny things here */
21502+ /*
21503+ * clear bit 0x200 in register 0x2A0
21504+ */
21505+ clear_regbits (adev, 0x2A0, 0x200);
21506+
21507+ /*
21508+ * Set bit 0x200 in ACX_GPIO_OUT
21509+ */
21510+ set_regbits (adev, IO_ACX_GPIO_OUT, 0x200);
21511+
21512+ /*
21513+ * read register 0x900 until its value is 0x8400104C, sleeping
21514+ * in between reads if it's not immediate
21515+ */
21516+ tmp = read_reg32 (adev, REG_ACX_VENDOR_ID);
21517+ count = 500;
21518+ while (count-- && (tmp != ACX_VENDOR_ID)) {
21519+ mdelay (10);
21520+ tmp = read_reg32 (adev, REG_ACX_VENDOR_ID);
21521+ }
21522+
21523+ /* end what Windows driver does */
21524+
21525+ acxmem_l_reset_mac(adev);
21526+
21527+ ecpu_ctrl = read_reg32(adev, IO_ACX_ECPU_CTRL) & 1;
21528+ if (!ecpu_ctrl) {
21529+ msg = "eCPU is already running. ";
21530+ goto end_unlock;
21531+ }
21532+
21533+#ifdef WE_DONT_NEED_THAT_DO_WE
21534+ if (read_reg16(adev, IO_ACX_SOR_CFG) & 2) {
21535+ /* eCPU most likely means "embedded CPU" */
21536+ msg = "eCPU did not start after boot from flash. ";
21537+ goto end_unlock;
21538+ }
21539+
21540+ /* check sense on reset flags */
21541+ if (read_reg16(adev, IO_ACX_SOR_CFG) & 0x10) {
21542+ printk("%s: eCPU did not start after boot (SOR), "
21543+ "is this fatal?\n", adev->ndev->name);
21544+ }
21545+#endif
21546+ /* scan, if any, is stopped now, setting corresponding IRQ bit */
21547+ adev->irq_status |= HOST_INT_SCAN_COMPLETE;
21548+
21549+ acx_unlock(adev, flags);
21550+
21551+ /* need to know radio type before fw load */
21552+ /* Need to wait for arrival of this information in a loop,
21553+ * most probably since eCPU runs some init code from EEPROM
21554+ * (started burst read in reset_mac()) which also
21555+ * sets the radio type ID */
21556+
21557+ count = 0xffff;
21558+ do {
21559+ hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION);
21560+ if (!--count) {
21561+ msg = "eCPU didn't indicate radio type";
21562+ goto end_fail;
21563+ }
21564+ cpu_relax();
21565+ } while (!(hardware_info & 0xff00)); /* radio type still zero? */
21566+ printk("ACX radio type 0x%02x\n", (hardware_info >> 8) & 0xff);
21567+ /* printk("DEBUG: count %d\n", count); */
21568+ adev->form_factor = hardware_info & 0xff;
21569+ adev->radio_type = hardware_info >> 8;
21570+
21571+ /* load the firmware */
21572+ if (OK != acxmem_s_upload_fw(adev))
21573+ goto end_fail;
21574+
21575+ /* acx_s_msleep(10); this one really shouldn't be required */
21576+
21577+ /* now start eCPU by clearing bit */
21578+ clear_regbits (adev, IO_ACX_ECPU_CTRL, 0x1);
21579+ log(L_DEBUG, "booted eCPU up and waiting for completion...\n");
21580+
21581+ /* Windows driver clears bit 0x200 in register 0x2A0 here */
21582+ clear_regbits (adev, 0x2A0, 0x200);
21583+
21584+ /* Windows driver sets bit 0x200 in ACX_GPIO_OUT here */
21585+ set_regbits (adev, IO_ACX_GPIO_OUT, 0x200);
21586+ /* wait for eCPU bootup */
21587+ if (OK != acxmem_s_verify_init(adev)) {
21588+ msg = "timeout waiting for eCPU. ";
21589+ goto end_fail;
21590+ }
21591+ log(L_DEBUG, "eCPU has woken up, card is ready to be configured\n");
21592+ init_mboxes(adev);
21593+ acxmem_write_cmd_type_status(adev, ACX1xx_CMD_RESET, 0);
21594+
21595+ /* test that EEPROM is readable */
21596+ read_eeprom_area(adev);
21597+
21598+ result = OK;
21599+ goto end;
21600+
21601+/* Finish error message. Indicate which function failed */
21602+end_unlock:
21603+ acx_unlock(adev, flags);
21604+end_fail:
21605+ printk("acx: %sreset_dev() FAILED\n", msg);
21606+end:
21607+ FN_EXIT1(result);
21608+ return result;
21609+}
21610+
21611+
21612+/***********************************************************************
21613+** acxmem_s_issue_cmd_timeo
21614+**
21615+** Sends command to fw, extract result
21616+**
21617+** NB: we do _not_ take lock inside, so be sure to not touch anything
21618+** which may interfere with IRQ handler operation
21619+**
21620+** TODO: busy wait is a bit silly, so:
21621+** 1) stop doing many iters - go to sleep after first
21622+** 2) go to waitqueue based approach: wait, not poll!
21623+*/
21624+#undef FUNC
21625+#define FUNC "issue_cmd"
21626+
21627+#if !ACX_DEBUG
21628+int
21629+acxmem_s_issue_cmd_timeo(
21630+ acx_device_t *adev,
21631+ unsigned int cmd,
21632+ void *buffer,
21633+ unsigned buflen,
21634+ unsigned cmd_timeout)
21635+{
21636+#else
21637+int
21638+acxmem_s_issue_cmd_timeo_debug(
21639+ acx_device_t *adev,
21640+ unsigned cmd,
21641+ void *buffer,
21642+ unsigned buflen,
21643+ unsigned cmd_timeout,
21644+ const char* cmdstr)
21645+{
21646+ unsigned long start = jiffies;
21647+#endif
21648+ const char *devname;
21649+ unsigned counter;
21650+ u16 irqtype;
21651+ int i, j;
21652+ u8 *p;
21653+ u16 cmd_status;
21654+ unsigned long timeout;
21655+
21656+ FN_ENTER;
21657+
21658+ devname = adev->ndev->name;
21659+ if (!devname || !devname[0] || devname[4]=='%')
21660+ devname = "acx";
21661+
21662+ log(L_CTL, FUNC"(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n",
21663+ cmdstr, buflen, cmd_timeout,
21664+ buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1);
21665+
21666+ if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) {
21667+ printk("%s: "FUNC"(): firmware is not loaded yet, "
21668+ "cannot execute commands!\n", devname);
21669+ goto bad;
21670+ }
21671+
21672+ if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) {
21673+ printk("input buffer (len=%u):\n", buflen);
21674+ acx_dump_bytes(buffer, buflen);
21675+ }
21676+
21677+ /* wait for firmware to become idle for our command submission */
21678+ timeout = HZ/5;
21679+ counter = (timeout * 1000 / HZ) - 1; /* in ms */
21680+ timeout += jiffies;
21681+ do {
21682+ cmd_status = acxmem_read_cmd_type_status(adev);
21683+ /* Test for IDLE state */
21684+ if (!cmd_status)
21685+ break;
21686+ if (counter % 8 == 0) {
21687+ if (time_after(jiffies, timeout)) {
21688+ counter = 0;
21689+ break;
21690+ }
21691+ /* we waited 8 iterations, no luck. Sleep 8 ms */
21692+ acx_s_msleep(8);
21693+ }
21694+ } while (likely(--counter));
21695+
21696+ if (!counter) {
21697+ /* the card doesn't get idle, we're in trouble */
21698+ printk("%s: "FUNC"(): cmd_status is not IDLE: 0x%04X!=0\n",
21699+ devname, cmd_status);
21700+#if DUMP_IF_SLOW > 0
21701+ dump_acxmem (adev, 0, 0x10000);
21702+ panic ("not idle");
21703+#endif
21704+ goto bad;
21705+ } else if (counter < 190) { /* if waited >10ms... */
21706+ log(L_CTL|L_DEBUG, FUNC"(): waited for IDLE %dms. "
21707+ "Please report\n", 199 - counter);
21708+ }
21709+
21710+ /* now write the parameters of the command if needed */
21711+ if (buffer && buflen) {
21712+ /* if it's an INTERROGATE command, just pass the length
21713+ * of parameters to read, as data */
21714+#if CMD_DISCOVERY
21715+ if (cmd == ACX1xx_CMD_INTERROGATE)
21716+ memset_io(adev->cmd_area + 4, 0xAA, buflen);
21717+#endif
21718+ /*
21719+ * slave memory version
21720+ */
21721+ copy_to_slavemem (adev, (u32) (adev->cmd_area + 4), buffer,
21722+ (cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen);
21723+ }
21724+ /* now write the actual command type */
21725+ acxmem_write_cmd_type_status(adev, cmd, 0);
21726+
21727+ /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */
21728+ adev->irq_status &= ~HOST_INT_CMD_COMPLETE;
21729+
21730+ /* execute command */
21731+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD);
21732+ write_flush(adev);
21733+
21734+ /* wait for firmware to process command */
21735+
21736+ /* Ensure nonzero and not too large timeout.
21737+ ** Also converts e.g. 100->99, 200->199
21738+ ** which is nice but not essential */
21739+ cmd_timeout = (cmd_timeout-1) | 1;
21740+ if (unlikely(cmd_timeout > 1199))
21741+ cmd_timeout = 1199;
21742+
21743+ /* we schedule away sometimes (timeout can be large) */
21744+ counter = cmd_timeout;
21745+ timeout = jiffies + cmd_timeout * HZ / 1000;
21746+ do {
21747+ if (!adev->irqs_active) { /* IRQ disabled: poll */
21748+ irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES);
21749+ if (irqtype & HOST_INT_CMD_COMPLETE) {
21750+ write_reg16(adev, IO_ACX_IRQ_ACK,
21751+ HOST_INT_CMD_COMPLETE);
21752+ break;
21753+ }
21754+ } else { /* Wait when IRQ will set the bit */
21755+ irqtype = adev->irq_status;
21756+ if (irqtype & HOST_INT_CMD_COMPLETE)
21757+ break;
21758+ }
21759+
21760+ if (counter % 8 == 0) {
21761+ if (time_after(jiffies, timeout)) {
21762+ counter = 0;
21763+ break;
21764+ }
21765+ /* we waited 8 iterations, no luck. Sleep 8 ms */
21766+ acx_s_msleep(8);
21767+ }
21768+ } while (likely(--counter));
21769+
21770+ /* save state for debugging */
21771+ cmd_status = acxmem_read_cmd_type_status(adev);
21772+
21773+ /* put the card in IDLE state */
21774+ acxmem_write_cmd_type_status(adev, ACX1xx_CMD_RESET, 0);
21775+
21776+ if (!counter) { /* timed out! */
21777+ printk("%s: "FUNC"(): timed out %s for CMD_COMPLETE. "
21778+ "irq bits:0x%04X irq_status:0x%04X timeout:%dms "
21779+ "cmd_status:%d (%s)\n",
21780+ devname, (adev->irqs_active) ? "waiting" : "polling",
21781+ irqtype, adev->irq_status, cmd_timeout,
21782+ cmd_status, acx_cmd_status_str(cmd_status));
21783+ printk("%s: "FUNC"(): device irq status 0x%04x\n",
21784+ devname, read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES));
21785+ printk("%s: "FUNC"(): IO_ACX_IRQ_MASK 0x%04x IO_ACX_FEMR 0x%04x\n",
21786+ devname,
21787+ read_reg16 (adev, IO_ACX_IRQ_MASK),
21788+ read_reg16 (adev, IO_ACX_FEMR));
21789+ if (read_reg16 (adev, IO_ACX_IRQ_MASK) == 0xffff) {
21790+ printk ("acxmem: firmware probably hosed - reloading\n");
21791+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
21792+ {
21793+ pm_message_t state;
21794+ acxmem_e_suspend (resume_pdev, state);
21795+ }
21796+#else
21797+ acxmem_e_suspend (adev->dev, 0);
21798+#endif
21799+ {
21800+ struct work_struct *notused;
21801+ fw_resumer (notused);
21802+ }
21803+ }
21804+
21805+ goto bad;
21806+ } else if (cmd_timeout - counter > 30) { /* if waited >30ms... */
21807+ log(L_CTL|L_DEBUG, FUNC"(): %s for CMD_COMPLETE %dms. "
21808+ "count:%d. Please report\n",
21809+ (adev->irqs_active) ? "waited" : "polled",
21810+ cmd_timeout - counter, counter);
21811+ }
21812+
21813+ if (1 != cmd_status) { /* it is not a 'Success' */
21814+ printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s). "
21815+ "Took %dms of %d\n",
21816+ devname, cmd_status, acx_cmd_status_str(cmd_status),
21817+ cmd_timeout - counter, cmd_timeout);
21818+ /* zero out result buffer
21819+ * WARNING: this will trash stack in case of illegally large input
21820+ * length! */
21821+ if (buflen > 388) {
21822+ /*
21823+ * 388 is maximum command length
21824+ */
21825+ printk ("invalid length 0x%08x\n", buflen);
21826+ buflen = 388;
21827+ }
21828+ p = (u8 *) buffer;
21829+ for (i = 0; i < buflen; i+= 16) {
21830+ printk ("%04x:", i);
21831+ for (j = 0; (j < 16) && (i+j < buflen); j++) {
21832+ printk (" %02x", *p++);
21833+ }
21834+ printk ("\n");
21835+ }
21836+
21837+ if (buffer && buflen)
21838+ memset(buffer, 0, buflen);
21839+ goto bad;
21840+ }
21841+
21842+ /* read in result parameters if needed */
21843+ if (buffer && buflen && (cmd == ACX1xx_CMD_INTERROGATE)) {
21844+ copy_from_slavemem (adev, buffer, (u32) (adev->cmd_area + 4), buflen);
21845+ if (acx_debug & L_DEBUG) {
21846+ printk("output buffer (len=%u): ", buflen);
21847+ acx_dump_bytes(buffer, buflen);
21848+ }
21849+ }
21850+
21851+/* ok: */
21852+ log(L_CTL, FUNC"(%s): took %ld jiffies to complete\n",
21853+ cmdstr, jiffies - start);
21854+ FN_EXIT1(OK);
21855+ return OK;
21856+
21857+bad:
21858+ /* Give enough info so that callers can avoid
21859+ ** printing their own diagnostic messages */
21860+#if ACX_DEBUG
21861+ printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr);
21862+#else
21863+ printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd);
21864+#endif
21865+ dump_stack();
21866+ FN_EXIT1(NOT_OK);
21867+ return NOT_OK;
21868+}
21869+
21870+
21871+/***********************************************************************
21872+*/
21873+#if defined(NONESSENTIAL_FEATURES)
21874+typedef struct device_id {
21875+ unsigned char id[6];
21876+ char *descr;
21877+ char *type;
21878+} device_id_t;
21879+
21880+static const device_id_t
21881+device_ids[] =
21882+{
21883+ {
21884+ {'G', 'l', 'o', 'b', 'a', 'l'},
21885+ NULL,
21886+ NULL,
21887+ },
21888+ {
21889+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
21890+ "uninitialized",
21891+ "SpeedStream SS1021 or Gigafast WF721-AEX"
21892+ },
21893+ {
21894+ {0x80, 0x81, 0x82, 0x83, 0x84, 0x85},
21895+ "non-standard",
21896+ "DrayTek Vigor 520"
21897+ },
21898+ {
21899+ {'?', '?', '?', '?', '?', '?'},
21900+ "non-standard",
21901+ "Level One WPC-0200"
21902+ },
21903+ {
21904+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
21905+ "empty",
21906+ "DWL-650+ variant"
21907+ }
21908+};
21909+
21910+static void
21911+acx_show_card_eeprom_id(acx_device_t *adev)
21912+{
21913+ unsigned char buffer[CARD_EEPROM_ID_SIZE];
21914+ int i;
21915+
21916+ memset(&buffer, 0, CARD_EEPROM_ID_SIZE);
21917+ /* use direct EEPROM access */
21918+ for (i = 0; i < CARD_EEPROM_ID_SIZE; i++) {
21919+ if (OK != acxmem_read_eeprom_byte(adev,
21920+ ACX100_EEPROM_ID_OFFSET + i,
21921+ &buffer[i])) {
21922+ printk("acx: reading EEPROM FAILED\n");
21923+ break;
21924+ }
21925+ }
21926+
21927+ for (i = 0; i < VEC_SIZE(device_ids); i++) {
21928+ if (!memcmp(&buffer, device_ids[i].id, CARD_EEPROM_ID_SIZE)) {
21929+ if (device_ids[i].descr) {
21930+ printk("acx: EEPROM card ID string check "
21931+ "found %s card ID: is this %s?\n",
21932+ device_ids[i].descr, device_ids[i].type);
21933+ }
21934+ break;
21935+ }
21936+ }
21937+ if (i == VEC_SIZE(device_ids)) {
21938+ printk("acx: EEPROM card ID string check found "
21939+ "unknown card: expected 'Global', got '%.*s\'. "
21940+ "Please report\n", CARD_EEPROM_ID_SIZE, buffer);
21941+ }
21942+}
21943+#endif /* NONESSENTIAL_FEATURES */
21944+
21945+/***********************************************************************
21946+** acxmem_free_desc_queues
21947+**
21948+** Releases the queues that have been allocated, the
21949+** others have been initialised to NULL so this
21950+** function can be used if only part of the queues were allocated.
21951+*/
21952+
21953+void
21954+acxmem_free_desc_queues(acx_device_t *adev)
21955+{
21956+#define ACX_FREE_QUEUE(size, ptr, phyaddr) \
21957+ if (ptr) { \
21958+ kfree(ptr); \
21959+ ptr = NULL; \
21960+ size = 0; \
21961+ }
21962+
21963+ FN_ENTER;
21964+
21965+ ACX_FREE_QUEUE(adev->txhostdesc_area_size, adev->txhostdesc_start, adev->txhostdesc_startphy);
21966+ ACX_FREE_QUEUE(adev->txbuf_area_size, adev->txbuf_start, adev->txbuf_startphy);
21967+
21968+ adev->txdesc_start = NULL;
21969+
21970+ ACX_FREE_QUEUE(adev->rxhostdesc_area_size, adev->rxhostdesc_start, adev->rxhostdesc_startphy);
21971+ ACX_FREE_QUEUE(adev->rxbuf_area_size, adev->rxbuf_start, adev->rxbuf_startphy);
21972+
21973+ adev->rxdesc_start = NULL;
21974+
21975+ FN_EXIT0;
21976+}
21977+
21978+
21979+/***********************************************************************
21980+** acxmem_s_delete_dma_regions
21981+*/
21982+static void
21983+acxmem_s_delete_dma_regions(acx_device_t *adev)
21984+{
21985+ unsigned long flags;
21986+
21987+ FN_ENTER;
21988+ /* disable radio Tx/Rx. Shouldn't we use the firmware commands
21989+ * here instead? Or are we that much down the road that it's no
21990+ * longer possible here? */
21991+ /*
21992+ * slave memory interface really doesn't like this.
21993+ */
21994+ /*
21995+ write_reg16(adev, IO_ACX_ENABLE, 0);
21996+ */
21997+
21998+ acx_s_msleep(100);
21999+
22000+ acx_lock(adev, flags);
22001+ acxmem_free_desc_queues(adev);
22002+ acx_unlock(adev, flags);
22003+
22004+ FN_EXIT0;
22005+}
22006+
22007+
22008+/***********************************************************************
22009+** acxmem_e_probe
22010+**
22011+** Probe routine called when a PCI device w/ matching ID is found.
22012+** Here's the sequence:
22013+** - Allocate the PCI resources.
22014+** - Read the PCMCIA attribute memory to make sure we have a WLAN card
22015+** - Reset the MAC
22016+** - Initialize the dev and wlan data
22017+** - Initialize the MAC
22018+**
22019+** pdev - ptr to pci device structure containing info about pci configuration
22020+** id - ptr to the device id entry that matched this device
22021+*/
22022+static const u16
22023+IO_ACX100[] =
22024+{
22025+ 0x0000, /* IO_ACX_SOFT_RESET */
22026+
22027+ 0x0014, /* IO_ACX_SLV_MEM_ADDR */
22028+ 0x0018, /* IO_ACX_SLV_MEM_DATA */
22029+ 0x001c, /* IO_ACX_SLV_MEM_CTL */
22030+ 0x0020, /* IO_ACX_SLV_END_CTL */
22031+
22032+ 0x0034, /* IO_ACX_FEMR */
22033+
22034+ 0x007c, /* IO_ACX_INT_TRIG */
22035+ 0x0098, /* IO_ACX_IRQ_MASK */
22036+ 0x00a4, /* IO_ACX_IRQ_STATUS_NON_DES */
22037+ 0x00a8, /* IO_ACX_IRQ_STATUS_CLEAR */
22038+ 0x00ac, /* IO_ACX_IRQ_ACK */
22039+ 0x00b0, /* IO_ACX_HINT_TRIG */
22040+
22041+ 0x0104, /* IO_ACX_ENABLE */
22042+
22043+ 0x0250, /* IO_ACX_EEPROM_CTL */
22044+ 0x0254, /* IO_ACX_EEPROM_ADDR */
22045+ 0x0258, /* IO_ACX_EEPROM_DATA */
22046+ 0x025c, /* IO_ACX_EEPROM_CFG */
22047+
22048+ 0x0268, /* IO_ACX_PHY_ADDR */
22049+ 0x026c, /* IO_ACX_PHY_DATA */
22050+ 0x0270, /* IO_ACX_PHY_CTL */
22051+
22052+ 0x0290, /* IO_ACX_GPIO_OE */
22053+
22054+ 0x0298, /* IO_ACX_GPIO_OUT */
22055+
22056+ 0x02a4, /* IO_ACX_CMD_MAILBOX_OFFS */
22057+ 0x02a8, /* IO_ACX_INFO_MAILBOX_OFFS */
22058+ 0x02ac, /* IO_ACX_EEPROM_INFORMATION */
22059+
22060+ 0x02d0, /* IO_ACX_EE_START */
22061+ 0x02d4, /* IO_ACX_SOR_CFG */
22062+ 0x02d8 /* IO_ACX_ECPU_CTRL */
22063+};
22064+
22065+static const u16
22066+IO_ACX111[] =
22067+{
22068+ 0x0000, /* IO_ACX_SOFT_RESET */
22069+
22070+ 0x0014, /* IO_ACX_SLV_MEM_ADDR */
22071+ 0x0018, /* IO_ACX_SLV_MEM_DATA */
22072+ 0x001c, /* IO_ACX_SLV_MEM_CTL */
22073+ 0x0020, /* IO_ACX_SLV_MEM_CP */
22074+
22075+ 0x0034, /* IO_ACX_FEMR */
22076+
22077+ 0x00b4, /* IO_ACX_INT_TRIG */
22078+ 0x00d4, /* IO_ACX_IRQ_MASK */
22079+ /* we do mean NON_DES (0xf0), not NON_DES_MASK which is at 0xe0: */
22080+ 0x00f0, /* IO_ACX_IRQ_STATUS_NON_DES */
22081+ 0x00e4, /* IO_ACX_IRQ_STATUS_CLEAR */
22082+ 0x00e8, /* IO_ACX_IRQ_ACK */
22083+ 0x00ec, /* IO_ACX_HINT_TRIG */
22084+
22085+ 0x01d0, /* IO_ACX_ENABLE */
22086+
22087+ 0x0338, /* IO_ACX_EEPROM_CTL */
22088+ 0x033c, /* IO_ACX_EEPROM_ADDR */
22089+ 0x0340, /* IO_ACX_EEPROM_DATA */
22090+ 0x0344, /* IO_ACX_EEPROM_CFG */
22091+
22092+ 0x0350, /* IO_ACX_PHY_ADDR */
22093+ 0x0354, /* IO_ACX_PHY_DATA */
22094+ 0x0358, /* IO_ACX_PHY_CTL */
22095+
22096+ 0x0374, /* IO_ACX_GPIO_OE */
22097+
22098+ 0x037c, /* IO_ACX_GPIO_OUT */
22099+
22100+ 0x0388, /* IO_ACX_CMD_MAILBOX_OFFS */
22101+ 0x038c, /* IO_ACX_INFO_MAILBOX_OFFS */
22102+ 0x0390, /* IO_ACX_EEPROM_INFORMATION */
22103+
22104+ 0x0100, /* IO_ACX_EE_START */
22105+ 0x0104, /* IO_ACX_SOR_CFG */
22106+ 0x0108, /* IO_ACX_ECPU_CTRL */
22107+};
22108+
22109+static void
22110+dummy_netdev_init(struct net_device *ndev) {}
22111+
22112+/*
22113+ * Most of the acx specific pieces of hardware reset.
22114+ */
22115+static int
22116+acxmem_complete_hw_reset (acx_device_t *adev)
22117+{
22118+ acx111_ie_configoption_t co;
22119+
22120+ /* NB: read_reg() reads may return bogus data before reset_dev(),
22121+ * since the firmware which directly controls large parts of the I/O
22122+ * registers isn't initialized yet.
22123+ * acx100 seems to be more affected than acx111 */
22124+ if (OK != acxmem_s_reset_dev (adev))
22125+ return -1;
22126+
22127+ if (IS_ACX100(adev)) {
22128+ /* ACX100: configopt struct in cmd mailbox - directly after reset */
22129+ copy_from_slavemem (adev, (u8*) &co, (u32) adev->cmd_area, sizeof (co));
22130+ }
22131+
22132+ if (OK != acx_s_init_mac(adev))
22133+ return -3;
22134+
22135+ if (IS_ACX111(adev)) {
22136+ /* ACX111: configopt struct needs to be queried after full init */
22137+ acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS);
22138+ }
22139+
22140+ /*
22141+ * Set up transmit buffer administration
22142+ */
22143+ init_acx_txbuf (adev);
22144+
22145+ /*
22146+ * Windows driver writes 0x01000000 to register 0x288, RADIO_CTL, if the form factor
22147+ * is 3. It also write protects the EEPROM by writing 1<<9 to GPIO_OUT
22148+ */
22149+ if (adev->form_factor == 3) {
22150+ set_regbits (adev, 0x288, 0x01000000);
22151+ set_regbits (adev, 0x298, 1<<9);
22152+ }
22153+
22154+/* TODO: merge them into one function, they are called just once and are the same for pci & usb */
22155+ if (OK != acxmem_read_eeprom_byte(adev, 0x05, &adev->eeprom_version))
22156+ return -2;
22157+
22158+ acx_s_parse_configoption(adev, &co);
22159+ acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */
22160+ acx_display_hardware_details(adev);
22161+
22162+ return 0;
22163+}
22164+
22165+static int __devinit
22166+acxmem_e_probe(struct platform_device *pdev)
22167+{
22168+ struct acx_hardware_data *hwdata = pdev->dev.platform_data;
22169+ acx_device_t *adev = NULL;
22170+ struct net_device *ndev = NULL;
22171+ const char *chip_name;
22172+ int result = -EIO;
22173+ int err;
22174+ int i;
22175+ unsigned long addr_size=0;
22176+ u8 chip_type;
22177+
22178+ FN_ENTER;
22179+ (void) hwdata->start_hw();
22180+
22181+ /* FIXME: prism54 calls pci_set_mwi() here,
22182+ * should we do/support the same? */
22183+
22184+ /* chiptype is u8 but id->driver_data is ulong
22185+ ** Works for now (possible values are 1 and 2) */
22186+ chip_type = CHIPTYPE_ACX100;
22187+ /* acx100 and acx111 have different PCI memory regions */
22188+ if (chip_type == CHIPTYPE_ACX100) {
22189+ chip_name = "ACX100";
22190+ } else if (chip_type == CHIPTYPE_ACX111) {
22191+ chip_name = "ACX111";
22192+ } else {
22193+ printk("acx: unknown chip type 0x%04X\n", chip_type);
22194+ goto fail_unknown_chiptype;
22195+ }
22196+
22197+ printk("acx: found %s-based wireless network card\n", chip_name);
22198+ log(L_ANY, "initial debug setting is 0x%04X\n", acx_debug);
22199+
22200+ ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init);
22201+ /* (NB: memsets to 0 entire area) */
22202+ if (!ndev) {
22203+ printk("acx: no memory for netdevice struct\n");
22204+ goto fail_alloc_netdev;
22205+ }
22206+
22207+ platform_set_drvdata (pdev, ndev);
22208+
22209+ ether_setup(ndev);
22210+
22211+ /*
22212+ * use platform_data resources that were provided
22213+ */
22214+ ndev->irq = 0;
22215+ for (i=0; i<pdev->num_resources; i++) {
22216+ if (pdev->resource[i].flags == IORESOURCE_IRQ) {
22217+ ndev->irq = pdev->resource[i].start;
22218+ }
22219+ else if (pdev->resource[i].flags == IORESOURCE_MEM) {
22220+ ndev->base_addr = pdev->resource[i].start;
22221+ addr_size = pdev->resource[i].end - pdev->resource[i].start;
22222+ }
22223+ }
22224+ if (addr_size == 0 || ndev->irq == 0)
22225+ goto fail_hw_params;
22226+ ndev->open = &acxmem_e_open;
22227+ ndev->stop = &acxmem_e_close;
22228+ pdev->dev.release = &acxmem_e_release;
22229+ ndev->hard_start_xmit = &acx_i_start_xmit;
22230+ ndev->get_stats = &acx_e_get_stats;
22231+#if IW_HANDLER_VERSION <= 5
22232+ ndev->get_wireless_stats = &acx_e_get_wireless_stats;
22233+#endif
22234+ ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def;
22235+ ndev->set_multicast_list = &acxmem_i_set_multicast_list;
22236+ ndev->tx_timeout = &acxmem_i_tx_timeout;
22237+ ndev->change_mtu = &acx_e_change_mtu;
22238+ ndev->watchdog_timeo = 4 * HZ;
22239+
22240+ adev = ndev2adev(ndev);
22241+ spin_lock_init(&adev->lock); /* initial state: unlocked */
22242+ spin_lock_init(&adev->txbuf_lock);
22243+ /* We do not start with downed sem: we want PARANOID_LOCKING to work */
22244+ sema_init(&adev->sem, 1); /* initial state: 1 (upped) */
22245+ /* since nobody can see new netdev yet, we can as well
22246+ ** just _presume_ that we're under sem (instead of actually taking it): */
22247+ /* acx_sem_lock(adev); */
22248+ adev->dev = &pdev->dev;
22249+ adev->ndev = ndev;
22250+ adev->dev_type = DEVTYPE_MEM;
22251+ adev->chip_type = chip_type;
22252+ adev->chip_name = chip_name;
22253+ adev->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111;
22254+ adev->membase = (volatile u32 *) ndev->base_addr;
22255+ adev->iobase = (volatile u32 *) ioremap_nocache (ndev->base_addr, addr_size);
22256+ /* to find crashes due to weird driver access
22257+ * to unconfigured interface (ifup) */
22258+ adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead;
22259+
22260+#if defined(NONESSENTIAL_FEATURES)
22261+ acx_show_card_eeprom_id(adev);
22262+#endif /* NONESSENTIAL_FEATURES */
22263+
22264+#ifdef SET_MODULE_OWNER
22265+ SET_MODULE_OWNER(ndev);
22266+#endif
22267+ SET_NETDEV_DEV(ndev, &pdev->dev);
22268+
22269+ log(L_IRQ|L_INIT, "using IRQ %d\n", ndev->irq);
22270+
22271+ /* ok, pci setup is finished, now start initializing the card */
22272+
22273+ if (OK != acxmem_complete_hw_reset (adev))
22274+ goto fail_reset;
22275+
22276+ /*
22277+ * Set up default things for most of the card settings.
22278+ */
22279+ acx_s_set_defaults(adev);
22280+
22281+ /* Register the card, AFTER everything else has been set up,
22282+ * since otherwise an ioctl could step on our feet due to
22283+ * firmware operations happening in parallel or uninitialized data */
22284+ err = register_netdev(ndev);
22285+ if (OK != err) {
22286+ printk("acx: register_netdev() FAILED: %d\n", err);
22287+ goto fail_register_netdev;
22288+ }
22289+
22290+ acx_proc_register_entries(ndev);
22291+
22292+ /* Now we have our device, so make sure the kernel doesn't try
22293+ * to send packets even though we're not associated to a network yet */
22294+ acx_stop_queue(ndev, "on probe");
22295+ acx_carrier_off(ndev, "on probe");
22296+
22297+ /*
22298+ * Set up a default monitor type so that poor combinations of initialization
22299+ * sequences in monitor mode don't end up destroying the hardware type.
22300+ */
22301+ adev->monitor_type = ARPHRD_ETHER;
22302+
22303+ /*
22304+ * Register to receive inetaddr notifier changes. This will allow us to
22305+ * catch if the user changes the MAC address of the interface.
22306+ */
22307+ register_netdevice_notifier(&acx_netdev_notifier);
22308+
22309+ /* after register_netdev() userspace may start working with dev
22310+ * (in particular, on other CPUs), we only need to up the sem */
22311+ /* acx_sem_unlock(adev); */
22312+
22313+ printk("acx "ACX_RELEASE": net device %s, driver compiled "
22314+ "against wireless extensions %d and Linux %s\n",
22315+ ndev->name, WIRELESS_EXT, UTS_RELEASE);
22316+
22317+#if CMD_DISCOVERY
22318+ great_inquisitor(adev);
22319+#endif
22320+
22321+ result = OK;
22322+ goto done;
22323+
22324+ /* error paths: undo everything in reverse order... */
22325+
22326+fail_register_netdev:
22327+
22328+ acxmem_s_delete_dma_regions(adev);
22329+
22330+fail_reset:
22331+fail_hw_params:
22332+ free_netdev(ndev);
22333+fail_alloc_netdev:
22334+fail_unknown_chiptype:
22335+
22336+
22337+done:
22338+ FN_EXIT1(result);
22339+ return result;
22340+}
22341+
22342+
22343+/***********************************************************************
22344+** acxmem_e_remove
22345+**
22346+** Shut device down (if not hot unplugged)
22347+** and deallocate PCI resources for the acx chip.
22348+**
22349+** pdev - ptr to PCI device structure containing info about pci configuration
22350+*/
22351+static int __devexit
22352+acxmem_e_remove(struct platform_device *pdev)
22353+{
22354+ struct acx_hardware_data *hwdata = pdev->dev.platform_data;
22355+ struct net_device *ndev;
22356+ acx_device_t *adev;
22357+ unsigned long flags;
22358+
22359+ FN_ENTER;
22360+
22361+ ndev = (struct net_device*) platform_get_drvdata(pdev);
22362+ if (!ndev) {
22363+ log(L_DEBUG, "%s: card is unused. Skipping any release code\n",
22364+ __func__);
22365+ goto end;
22366+ }
22367+
22368+ adev = ndev2adev(ndev);
22369+
22370+ /* If device wasn't hot unplugged... */
22371+ if (adev_present(adev)) {
22372+
22373+ acx_sem_lock(adev);
22374+
22375+ /* disable both Tx and Rx to shut radio down properly */
22376+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
22377+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0);
22378+
22379+#ifdef REDUNDANT
22380+ /* put the eCPU to sleep to save power
22381+ * Halting is not possible currently,
22382+ * since not supported by all firmware versions */
22383+ acx_s_issue_cmd(adev, ACX100_CMD_SLEEP, NULL, 0);
22384+#endif
22385+ acx_lock(adev, flags);
22386+
22387+ /* disable power LED to save power :-) */
22388+ log(L_INIT, "switching off power LED to save power\n");
22389+ acxmem_l_power_led(adev, 0);
22390+
22391+ /* stop our eCPU */
22392+ if (IS_ACX111(adev)) {
22393+ /* FIXME: does this actually keep halting the eCPU?
22394+ * I don't think so...
22395+ */
22396+ acxmem_l_reset_mac(adev);
22397+ } else {
22398+ u16 temp;
22399+
22400+ /* halt eCPU */
22401+ temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1;
22402+ write_reg16(adev, IO_ACX_ECPU_CTRL, temp);
22403+ write_flush(adev);
22404+ }
22405+
22406+ acx_unlock(adev, flags);
22407+
22408+ acx_sem_unlock(adev);
22409+ }
22410+
22411+
22412+ /*
22413+ * Unregister the notifier chain
22414+ */
22415+ unregister_netdevice_notifier(&acx_netdev_notifier);
22416+
22417+ /* unregister the device to not let the kernel
22418+ * (e.g. ioctls) access a half-deconfigured device
22419+ * NB: this will cause acxmem_e_close() to be called,
22420+ * thus we shouldn't call it under sem! */
22421+ log(L_INIT, "removing device %s\n", ndev->name);
22422+ unregister_netdev(ndev);
22423+
22424+ /* unregister_netdev ensures that no references to us left.
22425+ * For paranoid reasons we continue to follow the rules */
22426+ acx_sem_lock(adev);
22427+
22428+ if (adev->dev_state_mask & ACX_STATE_IFACE_UP) {
22429+ acxmem_s_down(ndev);
22430+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
22431+ }
22432+
22433+ acx_proc_unregister_entries(ndev);
22434+
22435+ acxmem_s_delete_dma_regions(adev);
22436+
22437+ /* finally, clean up PCI bus state */
22438+ if (adev->iobase) iounmap((void *)adev->iobase);
22439+
22440+ acx_sem_unlock(adev);
22441+
22442+ /* Free netdev (quite late,
22443+ * since otherwise we might get caught off-guard
22444+ * by a netdev timeout handler execution
22445+ * expecting to see a working dev...) */
22446+ free_netdev(ndev);
22447+
22448+ (void) hwdata->stop_hw();
22449+
22450+ printk ("e_remove done\n");
22451+end:
22452+ FN_EXIT0;
22453+
22454+ return 0;
22455+}
22456+
22457+
22458+/***********************************************************************
22459+** TODO: PM code needs to be fixed / debugged / tested.
22460+*/
22461+#ifdef CONFIG_PM
22462+static int
22463+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
22464+acxmem_e_suspend(struct platform_device *pdev, pm_message_t state)
22465+#else
22466+acxmem_e_suspend(struct device *pdev, u32 state)
22467+#endif
22468+{
22469+ struct net_device *ndev = platform_get_drvdata(pdev);
22470+ acx_device_t *adev;
22471+ struct acx_hardware_data *hwdata;
22472+
22473+ FN_ENTER;
22474+ printk("acx: suspend handler is experimental!\n");
22475+ printk("sus: dev %p\n", ndev);
22476+
22477+ if (!netif_running(ndev))
22478+ goto end;
22479+
22480+ adev = ndev2adev(ndev);
22481+ printk("sus: adev %p\n", adev);
22482+
22483+ hwdata = adev->dev->platform_data;
22484+
22485+ acx_sem_lock(adev);
22486+
22487+ netif_device_detach(ndev); /* this one cannot sleep */
22488+ acxmem_s_down(ndev);
22489+ /* down() does not set it to 0xffff, but here we really want that */
22490+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
22491+ write_reg16(adev, IO_ACX_FEMR, 0x0);
22492+ acxmem_s_delete_dma_regions(adev);
22493+
22494+ /*
22495+ * Turn the ACX chip off.
22496+ */
22497+ hwdata->stop_hw();
22498+
22499+ acx_sem_unlock(adev);
22500+end:
22501+ FN_EXIT0;
22502+ return OK;
22503+}
22504+
22505+
22506+
22507+static void
22508+fw_resumer(struct work_struct *notused)
22509+{
22510+ struct platform_device *pdev = resume_pdev;
22511+ struct net_device *ndev = platform_get_drvdata(pdev);
22512+ acx_device_t *adev;
22513+ struct acx_hardware_data *hwdata;
22514+
22515+ printk("acx: resume handler is experimental!\n");
22516+ printk("rsm: got dev %p\n", ndev);
22517+
22518+ if (!netif_running(ndev))
22519+ return;
22520+
22521+ adev = ndev2adev(ndev);
22522+ printk("rsm: got adev %p\n", adev);
22523+
22524+ acx_sem_lock(adev);
22525+
22526+ hwdata = adev->dev->platform_data;
22527+
22528+ /*
22529+ * Turn on the ACX.
22530+ */
22531+ hwdata->start_hw();
22532+
22533+ acxmem_complete_hw_reset (adev);
22534+
22535+ /*
22536+ * done by acx_s_set_defaults for initial startup
22537+ */
22538+ acxmem_set_interrupt_mask(adev);
22539+
22540+ printk ("rsm: bringing up interface\n");
22541+ SET_BIT (adev->set_mask, GETSET_ALL);
22542+ acxmem_s_up(ndev);
22543+ printk("rsm: acx up done\n");
22544+
22545+ /* now even reload all card parameters as they were before suspend,
22546+ * and possibly be back in the network again already :-)
22547+ */
22548+ /* - most settings updated in acxmem_s_up()
22549+ if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
22550+ adev->set_mask = GETSET_ALL;
22551+ acx_s_update_card_settings(adev);
22552+ printk("rsm: settings updated\n");
22553+ }
22554+ */
22555+ netif_device_attach(ndev);
22556+ printk("rsm: device attached\n");
22557+
22558+ acx_sem_unlock(adev);
22559+}
22560+
22561+DECLARE_WORK( fw_resume_work, fw_resumer );
22562+
22563+static int
22564+acxmem_e_resume(struct platform_device *pdev)
22565+{
22566+ FN_ENTER;
22567+
22568+ resume_pdev = pdev;
22569+ schedule_work( &fw_resume_work );
22570+
22571+ FN_EXIT0;
22572+ return OK;
22573+}
22574+#endif /* CONFIG_PM */
22575+
22576+
22577+/***********************************************************************
22578+** acxmem_s_up
22579+**
22580+** This function is called by acxmem_e_open (when ifconfig sets the device as up)
22581+**
22582+** Side effects:
22583+** - Enables on-card interrupt requests
22584+** - calls acx_s_start
22585+*/
22586+
22587+static void
22588+enable_acx_irq(acx_device_t *adev)
22589+{
22590+ FN_ENTER;
22591+ write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask);
22592+ write_reg16(adev, IO_ACX_FEMR, 0x8000);
22593+ adev->irqs_active = 1;
22594+ FN_EXIT0;
22595+}
22596+
22597+static void
22598+acxmem_s_up(struct net_device *ndev)
22599+{
22600+ acx_device_t *adev = ndev2adev(ndev);
22601+ unsigned long flags;
22602+
22603+ FN_ENTER;
22604+
22605+ acx_lock(adev, flags);
22606+ enable_acx_irq(adev);
22607+ acx_unlock(adev, flags);
22608+
22609+ /* acx fw < 1.9.3.e has a hardware timer, and older drivers
22610+ ** used to use it. But we don't do that anymore, our OS
22611+ ** has reliable software timers */
22612+ init_timer(&adev->mgmt_timer);
22613+ adev->mgmt_timer.function = acx_i_timer;
22614+ adev->mgmt_timer.data = (unsigned long)adev;
22615+
22616+ /* Need to set ACX_STATE_IFACE_UP first, or else
22617+ ** timer won't be started by acx_set_status() */
22618+ SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
22619+ switch (adev->mode) {
22620+ case ACX_MODE_0_ADHOC:
22621+ case ACX_MODE_2_STA:
22622+ /* actual scan cmd will happen in start() */
22623+ acx_set_status(adev, ACX_STATUS_1_SCANNING); break;
22624+ case ACX_MODE_3_AP:
22625+ case ACX_MODE_MONITOR:
22626+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); break;
22627+ }
22628+
22629+ acx_s_start(adev);
22630+
22631+ FN_EXIT0;
22632+}
22633+
22634+
22635+/***********************************************************************
22636+** acxmem_s_down
22637+**
22638+** This disables the netdevice
22639+**
22640+** Side effects:
22641+** - disables on-card interrupt request
22642+*/
22643+
22644+static void
22645+disable_acx_irq(acx_device_t *adev)
22646+{
22647+ FN_ENTER;
22648+
22649+ /* I guess mask is not 0xffff because acx100 won't signal
22650+ ** cmd completion then (needed for ifup).
22651+ ** Someone with acx100 please confirm */
22652+ write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask_off);
22653+ write_reg16(adev, IO_ACX_FEMR, 0x0);
22654+ adev->irqs_active = 0;
22655+ FN_EXIT0;
22656+}
22657+
22658+static void
22659+acxmem_s_down(struct net_device *ndev)
22660+{
22661+ acx_device_t *adev = ndev2adev(ndev);
22662+ unsigned long flags;
22663+
22664+ FN_ENTER;
22665+
22666+ /* Disable IRQs first, so that IRQs cannot race with us */
22667+ /* then wait until interrupts have finished executing on other CPUs */
22668+ acx_lock(adev, flags);
22669+ disable_acx_irq(adev);
22670+ synchronize_irq(adev->pdev->irq);
22671+ acx_unlock(adev, flags);
22672+
22673+ /* we really don't want to have an asynchronous tasklet disturb us
22674+ ** after something vital for its job has been shut down, so
22675+ ** end all remaining work now.
22676+ **
22677+ ** NB: carrier_off (done by set_status below) would lead to
22678+ ** not yet fully understood deadlock in FLUSH_SCHEDULED_WORK().
22679+ ** That's why we do FLUSH first.
22680+ **
22681+ ** NB2: we have a bad locking bug here: FLUSH_SCHEDULED_WORK()
22682+ ** waits for acx_e_after_interrupt_task to complete if it is running
22683+ ** on another CPU, but acx_e_after_interrupt_task
22684+ ** will sleep on sem forever, because it is taken by us!
22685+ ** Work around that by temporary sem unlock.
22686+ ** This will fail miserably if we'll be hit by concurrent
22687+ ** iwconfig or something in between. TODO! */
22688+ acx_sem_unlock(adev);
22689+ FLUSH_SCHEDULED_WORK();
22690+ acx_sem_lock(adev);
22691+
22692+ /* This is possible:
22693+ ** FLUSH_SCHEDULED_WORK -> acx_e_after_interrupt_task ->
22694+ ** -> set_status(ASSOCIATED) -> wake_queue()
22695+ ** That's why we stop queue _after_ FLUSH_SCHEDULED_WORK
22696+ ** lock/unlock is just paranoia, maybe not needed */
22697+ acx_lock(adev, flags);
22698+ acx_stop_queue(ndev, "on ifdown");
22699+ acx_set_status(adev, ACX_STATUS_0_STOPPED);
22700+ acx_unlock(adev, flags);
22701+
22702+ /* kernel/timer.c says it's illegal to del_timer_sync()
22703+ ** a timer which restarts itself. We guarantee this cannot
22704+ ** ever happen because acx_i_timer() never does this if
22705+ ** status is ACX_STATUS_0_STOPPED */
22706+ del_timer_sync(&adev->mgmt_timer);
22707+
22708+ FN_EXIT0;
22709+}
22710+
22711+
22712+/***********************************************************************
22713+** acxmem_e_open
22714+**
22715+** Called as a result of SIOCSIFFLAGS ioctl changing the flags bit IFF_UP
22716+** from clear to set. In other words: ifconfig up.
22717+**
22718+** Returns:
22719+** 0 success
22720+** >0 f/w reported error
22721+** <0 driver reported error
22722+*/
22723+static int
22724+acxmem_e_open(struct net_device *ndev)
22725+{
22726+ acx_device_t *adev = ndev2adev(ndev);
22727+ int result = OK;
22728+
22729+ FN_ENTER;
22730+
22731+ acx_sem_lock(adev);
22732+
22733+ acx_init_task_scheduler(adev);
22734+
22735+/* TODO: pci_set_power_state(pdev, PCI_D0); ? */
22736+
22737+ /* request shared IRQ handler */
22738+ if (request_irq(ndev->irq, acxmem_i_interrupt, SA_INTERRUPT, ndev->name, ndev)) {
22739+ printk("%s: request_irq FAILED\n", ndev->name);
22740+ result = -EAGAIN;
22741+ goto done;
22742+ }
22743+ set_irq_type (ndev->irq, IRQT_FALLING);
22744+ log(L_DEBUG|L_IRQ, "request_irq %d successful\n", ndev->irq);
22745+
22746+ /* ifup device */
22747+ acxmem_s_up(ndev);
22748+
22749+ /* We don't currently have to do anything else.
22750+ * The setup of the MAC should be subsequently completed via
22751+ * the mlme commands.
22752+ * Higher layers know we're ready from dev->start==1 and
22753+ * dev->tbusy==0. Our rx path knows to pass up received/
22754+ * frames because of dev->flags&IFF_UP is true.
22755+ */
22756+done:
22757+ acx_sem_unlock(adev);
22758+
22759+ FN_EXIT1(result);
22760+ return result;
22761+}
22762+
22763+
22764+/***********************************************************************
22765+** acxmem_e_close
22766+**
22767+** Called as a result of SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
22768+** from set to clear. I.e. called by "ifconfig DEV down"
22769+**
22770+** Returns:
22771+** 0 success
22772+** >0 f/w reported error
22773+** <0 driver reported error
22774+*/
22775+static int
22776+acxmem_e_close(struct net_device *ndev)
22777+{
22778+ acx_device_t *adev = ndev2adev(ndev);
22779+
22780+ FN_ENTER;
22781+
22782+ acx_sem_lock(adev);
22783+
22784+ /* ifdown device */
22785+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
22786+ if (netif_device_present(ndev)) {
22787+ acxmem_s_down(ndev);
22788+ }
22789+
22790+ /* disable all IRQs, release shared IRQ handler */
22791+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
22792+ write_reg16(adev, IO_ACX_FEMR, 0x0);
22793+ free_irq(ndev->irq, ndev);
22794+
22795+/* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */
22796+
22797+ /* We currently don't have to do anything else.
22798+ * Higher layers know we're not ready from dev->start==0 and
22799+ * dev->tbusy==1. Our rx path knows to not pass up received
22800+ * frames because of dev->flags&IFF_UP is false.
22801+ */
22802+ acx_sem_unlock(adev);
22803+
22804+ log(L_INIT, "closed device\n");
22805+ FN_EXIT0;
22806+ return OK;
22807+}
22808+
22809+
22810+/***********************************************************************
22811+** acxmem_i_tx_timeout
22812+**
22813+** Called from network core. Must not sleep!
22814+*/
22815+static void
22816+acxmem_i_tx_timeout(struct net_device *ndev)
22817+{
22818+ acx_device_t *adev = ndev2adev(ndev);
22819+ unsigned long flags;
22820+ unsigned int tx_num_cleaned;
22821+
22822+ FN_ENTER;
22823+
22824+ acx_lock(adev, flags);
22825+
22826+ /* clean processed tx descs, they may have been completely full */
22827+ tx_num_cleaned = acxmem_l_clean_txdesc(adev);
22828+
22829+ /* nothing cleaned, yet (almost) no free buffers available?
22830+ * --> clean all tx descs, no matter which status!!
22831+ * Note that I strongly suspect that doing emergency cleaning
22832+ * may confuse the firmware. This is a last ditch effort to get
22833+ * ANYTHING to work again...
22834+ *
22835+ * TODO: it's best to simply reset & reinit hw from scratch...
22836+ */
22837+ if ((adev->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) {
22838+ printk("%s: FAILED to free any of the many full tx buffers. "
22839+ "Switching to emergency freeing. "
22840+ "Please report!\n", ndev->name);
22841+ acxmem_l_clean_txdesc_emergency(adev);
22842+ }
22843+
22844+ if (acx_queue_stopped(ndev) && (ACX_STATUS_4_ASSOCIATED == adev->status))
22845+ acx_wake_queue(ndev, "after tx timeout");
22846+
22847+ /* stall may have happened due to radio drift, so recalib radio */
22848+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
22849+
22850+ /* do unimportant work last */
22851+ printk("%s: tx timeout!\n", ndev->name);
22852+ adev->stats.tx_errors++;
22853+
22854+ acx_unlock(adev, flags);
22855+
22856+ FN_EXIT0;
22857+}
22858+
22859+
22860+/***********************************************************************
22861+** acxmem_i_set_multicast_list
22862+** FIXME: most likely needs refinement
22863+*/
22864+static void
22865+acxmem_i_set_multicast_list(struct net_device *ndev)
22866+{
22867+ acx_device_t *adev = ndev2adev(ndev);
22868+ unsigned long flags;
22869+
22870+ FN_ENTER;
22871+
22872+ acx_lock(adev, flags);
22873+
22874+ /* firmwares don't have allmulti capability,
22875+ * so just use promiscuous mode instead in this case. */
22876+ if (ndev->flags & (IFF_PROMISC|IFF_ALLMULTI)) {
22877+ SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
22878+ CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
22879+ SET_BIT(adev->set_mask, SET_RXCONFIG);
22880+ /* let kernel know in case *we* needed to set promiscuous */
22881+ ndev->flags |= (IFF_PROMISC|IFF_ALLMULTI);
22882+ } else {
22883+ CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
22884+ SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
22885+ SET_BIT(adev->set_mask, SET_RXCONFIG);
22886+ ndev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI);
22887+ }
22888+
22889+ /* cannot update card settings directly here, atomic context */
22890+ acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
22891+
22892+ acx_unlock(adev, flags);
22893+
22894+ FN_EXIT0;
22895+}
22896+
22897+
22898+/***************************************************************
22899+** acxmem_l_process_rxdesc
22900+**
22901+** Called directly and only from the IRQ handler
22902+*/
22903+
22904+#if !ACX_DEBUG
22905+static inline void log_rxbuffer(const acx_device_t *adev) {}
22906+#else
22907+static void
22908+log_rxbuffer(const acx_device_t *adev)
22909+{
22910+ register const struct rxhostdesc *rxhostdesc;
22911+ int i;
22912+ /* no FN_ENTER here, we don't want that */
22913+
22914+ rxhostdesc = adev->rxhostdesc_start;
22915+ if (unlikely(!rxhostdesc)) return;
22916+ for (i = 0; i < RX_CNT; i++) {
22917+ if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
22918+ && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
22919+ printk("rx: buf %d full\n", i);
22920+ rxhostdesc++;
22921+ }
22922+}
22923+#endif
22924+
22925+static void
22926+acxmem_l_process_rxdesc(acx_device_t *adev)
22927+{
22928+ register rxhostdesc_t *hostdesc;
22929+ register rxdesc_t *rxdesc;
22930+ unsigned count, tail;
22931+ u32 addr;
22932+ u8 Ctl_8;
22933+
22934+ FN_ENTER;
22935+
22936+ if (unlikely(acx_debug & L_BUFR))
22937+ log_rxbuffer(adev);
22938+
22939+ /* First, have a loop to determine the first descriptor that's
22940+ * full, just in case there's a mismatch between our current
22941+ * rx_tail and the full descriptor we're supposed to handle. */
22942+ tail = adev->rx_tail;
22943+ count = RX_CNT;
22944+ while (1) {
22945+ hostdesc = &adev->rxhostdesc_start[tail];
22946+ rxdesc = &adev->rxdesc_start[tail];
22947+ /* advance tail regardless of outcome of the below test */
22948+ tail = (tail + 1) % RX_CNT;
22949+
22950+ /*
22951+ * Unlike the PCI interface, where the ACX can write directly to
22952+ * the host descriptors, on the slave memory interface we have to
22953+ * pull these. All we really need to do is check the Ctl_8 field
22954+ * in the rx descriptor on the ACX, which should be 0x11000000 if
22955+ * we should process it.
22956+ */
22957+ Ctl_8 = hostdesc->Ctl_16 = read_slavemem8 (adev, (u32) &(rxdesc->Ctl_8));
22958+ if ((Ctl_8 & DESC_CTL_HOSTOWN) &&
22959+ (Ctl_8 & DESC_CTL_ACXDONE))
22960+ break; /* found it! */
22961+
22962+ if (unlikely(!--count)) /* hmm, no luck: all descs empty, bail out */
22963+ goto end;
22964+ }
22965+
22966+ /* now process descriptors, starting with the first we figured out */
22967+ while (1) {
22968+ log(L_BUFR, "rx: tail=%u Ctl_8=%02X\n", tail, Ctl_8);
22969+ /*
22970+ * If the ACX has CTL_RECLAIM set on this descriptor there
22971+ * is no buffer associated; it just wants us to tell it to
22972+ * reclaim the memory.
22973+ */
22974+ if (!(Ctl_8 & DESC_CTL_RECLAIM)) {
22975+
22976+ /*
22977+ * slave interface - pull data now
22978+ */
22979+ hostdesc->length = read_slavemem16 (adev, (u32) &(rxdesc->total_length));
22980+
22981+ /*
22982+ * hostdesc->data is an rxbuffer_t, which includes header information,
22983+ * but the length in the data packet doesn't. The header information
22984+ * takes up an additional 12 bytes, so add that to the length we copy.
22985+ */
22986+ addr = read_slavemem32 (adev, (u32) &(rxdesc->ACXMemPtr));
22987+ if (addr) {
22988+ /*
22989+ * How can &(rxdesc->ACXMemPtr) above ever be zero? Looks like we
22990+ * get that now and then - try to trap it for debug.
22991+ */
22992+ if (addr & 0xffff0000) {
22993+ printk("rxdesc 0x%08x\n", (u32) rxdesc);
22994+ dump_acxmem (adev, 0, 0x10000);
22995+ panic ("Bad access!");
22996+ }
22997+ chaincopy_from_slavemem (adev, (u8 *) hostdesc->data, addr,
22998+ hostdesc->length +
22999+ (u32) &((rxbuffer_t *)0)->hdr_a3);
23000+ acx_l_process_rxbuf(adev, hostdesc->data);
23001+ }
23002+ }
23003+ else {
23004+ printk ("rx reclaim only!\n");
23005+ }
23006+
23007+ hostdesc->Status = 0;
23008+
23009+ /*
23010+ * Let the ACX know we're done.
23011+ */
23012+ CLEAR_BIT (Ctl_8, DESC_CTL_HOSTOWN);
23013+ SET_BIT (Ctl_8, DESC_CTL_HOSTDONE);
23014+ SET_BIT (Ctl_8, DESC_CTL_RECLAIM);
23015+ write_slavemem8 (adev, (u32) &rxdesc->Ctl_8, Ctl_8);
23016+
23017+ /*
23018+ * Now tell the ACX we've finished with the receive buffer so
23019+ * it can finish the reclaim.
23020+ */
23021+ write_reg16 (adev, IO_ACX_INT_TRIG, INT_TRIG_RXPRC);
23022+
23023+ /* ok, descriptor is handled, now check the next descriptor */
23024+ hostdesc = &adev->rxhostdesc_start[tail];
23025+ rxdesc = &adev->rxdesc_start[tail];
23026+
23027+ Ctl_8 = hostdesc->Ctl_16 = read_slavemem8 (adev, (u32) &(rxdesc->Ctl_8));
23028+
23029+ /* if next descriptor is empty, then bail out */
23030+ if (!(Ctl_8 & DESC_CTL_HOSTOWN) || !(Ctl_8 & DESC_CTL_ACXDONE))
23031+ break;
23032+
23033+ tail = (tail + 1) % RX_CNT;
23034+ }
23035+end:
23036+ adev->rx_tail = tail;
23037+ FN_EXIT0;
23038+}
23039+
23040+
23041+/***********************************************************************
23042+** acxmem_i_interrupt
23043+**
23044+** IRQ handler (atomic context, must not sleep, blah, blah)
23045+*/
23046+
23047+/* scan is complete. all frames now on the receive queue are valid */
23048+#define INFO_SCAN_COMPLETE 0x0001
23049+#define INFO_WEP_KEY_NOT_FOUND 0x0002
23050+/* hw has been reset as the result of a watchdog timer timeout */
23051+#define INFO_WATCH_DOG_RESET 0x0003
23052+/* failed to send out NULL frame from PS mode notification to AP */
23053+/* recommended action: try entering 802.11 PS mode again */
23054+#define INFO_PS_FAIL 0x0004
23055+/* encryption/decryption process on a packet failed */
23056+#define INFO_IV_ICV_FAILURE 0x0005
23057+
23058+/* Info mailbox format:
23059+2 bytes: type
23060+2 bytes: status
23061+more bytes may follow
23062+ rumors say about status:
23063+ 0x0000 info available (set by hw)
23064+ 0x0001 information received (must be set by host)
23065+ 0x1000 info available, mailbox overflowed (messages lost) (set by hw)
23066+ but in practice we've seen:
23067+ 0x9000 when we did not set status to 0x0001 on prev message
23068+ 0x1001 when we did set it
23069+ 0x0000 was never seen
23070+ conclusion: this is really a bitfield:
23071+ 0x1000 is 'info available' bit
23072+ 'mailbox overflowed' bit is 0x8000, not 0x1000
23073+ value of 0x0000 probably means that there are no messages at all
23074+ P.S. I dunno how in hell hw is supposed to notice that messages are lost -
23075+ it does NOT clear bit 0x0001, and this bit will probably stay forever set
23076+ after we set it once. Let's hope this will be fixed in firmware someday
23077+*/
23078+
23079+static void
23080+handle_info_irq(acx_device_t *adev)
23081+{
23082+#if ACX_DEBUG
23083+ static const char * const info_type_msg[] = {
23084+ "(unknown)",
23085+ "scan complete",
23086+ "WEP key not found",
23087+ "internal watchdog reset was done",
23088+ "failed to send powersave (NULL frame) notification to AP",
23089+ "encrypt/decrypt on a packet has failed",
23090+ "TKIP tx keys disabled",
23091+ "TKIP rx keys disabled",
23092+ "TKIP rx: key ID not found",
23093+ "???",
23094+ "???",
23095+ "???",
23096+ "???",
23097+ "???",
23098+ "???",
23099+ "???",
23100+ "TKIP IV value exceeds thresh"
23101+ };
23102+#endif
23103+ u32 info_type, info_status;
23104+
23105+ info_type = read_slavemem32 (adev, (u32) adev->info_area);
23106+
23107+ info_status = (info_type >> 16);
23108+ info_type = (u16)info_type;
23109+
23110+ /* inform fw that we have read this info message */
23111+ write_slavemem32(adev, (u32) adev->info_area, info_type | 0x00010000);
23112+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_INFOACK);
23113+ write_flush(adev);
23114+
23115+ log(L_CTL, "info_type:%04X info_status:%04X\n",
23116+ info_type, info_status);
23117+
23118+ log(L_IRQ, "got Info IRQ: status %04X type %04X: %s\n",
23119+ info_status, info_type,
23120+ info_type_msg[(info_type >= VEC_SIZE(info_type_msg)) ?
23121+ 0 : info_type]
23122+ );
23123+}
23124+
23125+
23126+static void
23127+log_unusual_irq(u16 irqtype) {
23128+ /*
23129+ if (!printk_ratelimit())
23130+ return;
23131+ */
23132+
23133+ printk("acx: got");
23134+ if (irqtype & HOST_INT_TX_XFER) {
23135+ printk(" Tx_Xfer");
23136+ }
23137+ if (irqtype & HOST_INT_RX_COMPLETE) {
23138+ printk(" Rx_Complete");
23139+ }
23140+ if (irqtype & HOST_INT_DTIM) {
23141+ printk(" DTIM");
23142+ }
23143+ if (irqtype & HOST_INT_BEACON) {
23144+ printk(" Beacon");
23145+ }
23146+ if (irqtype & HOST_INT_TIMER) {
23147+ log(L_IRQ, " Timer");
23148+ }
23149+ if (irqtype & HOST_INT_KEY_NOT_FOUND) {
23150+ printk(" Key_Not_Found");
23151+ }
23152+ if (irqtype & HOST_INT_IV_ICV_FAILURE) {
23153+ printk(" IV_ICV_Failure (crypto)");
23154+ }
23155+ /* HOST_INT_CMD_COMPLETE */
23156+ /* HOST_INT_INFO */
23157+ if (irqtype & HOST_INT_OVERFLOW) {
23158+ printk(" Overflow");
23159+ }
23160+ if (irqtype & HOST_INT_PROCESS_ERROR) {
23161+ printk(" Process_Error");
23162+ }
23163+ /* HOST_INT_SCAN_COMPLETE */
23164+ if (irqtype & HOST_INT_FCS_THRESHOLD) {
23165+ printk(" FCS_Threshold");
23166+ }
23167+ if (irqtype & HOST_INT_UNKNOWN) {
23168+ printk(" Unknown");
23169+ }
23170+ printk(" IRQ(s)\n");
23171+}
23172+
23173+
23174+static void
23175+update_link_quality_led(acx_device_t *adev)
23176+{
23177+ int qual;
23178+
23179+ qual = acx_signal_determine_quality(adev->wstats.qual.level, adev->wstats.qual.noise);
23180+ if (qual > adev->brange_max_quality)
23181+ qual = adev->brange_max_quality;
23182+
23183+ if (time_after(jiffies, adev->brange_time_last_state_change +
23184+ (HZ/2 - HZ/2 * (unsigned long)qual / adev->brange_max_quality ) )) {
23185+ acxmem_l_power_led(adev, (adev->brange_last_state == 0));
23186+ adev->brange_last_state ^= 1; /* toggle */
23187+ adev->brange_time_last_state_change = jiffies;
23188+ }
23189+}
23190+
23191+
23192+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */
23193+
23194+static irqreturn_t
23195+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
23196+acxmem_i_interrupt(int irq, void *dev_id)
23197+#else
23198+acxmwm_i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
23199+#endif
23200+{
23201+ acx_device_t *adev;
23202+ unsigned long flags;
23203+ unsigned int irqcount = MAX_IRQLOOPS_PER_JIFFY;
23204+ register u16 irqtype;
23205+ u16 unmasked;
23206+
23207+ adev = ndev2adev((struct net_device*)dev_id);
23208+
23209+ /* LOCKING: can just spin_lock() since IRQs are disabled anyway.
23210+ * I am paranoid */
23211+ acx_lock(adev, flags);
23212+
23213+ unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR);
23214+ if (unlikely(0xffff == unmasked)) {
23215+ /* 0xffff value hints at missing hardware,
23216+ * so don't do anything.
23217+ * Not very clean, but other drivers do the same... */
23218+ log(L_IRQ, "IRQ type:FFFF - device removed? IRQ_NONE\n");
23219+ goto none;
23220+ }
23221+
23222+ /* We will check only "interesting" IRQ types */
23223+ irqtype = unmasked & ~adev->irq_mask;
23224+ if (!irqtype) {
23225+ /* We are on a shared IRQ line and it wasn't our IRQ */
23226+ log(L_IRQ, "IRQ type:%04X, mask:%04X - all are masked, IRQ_NONE\n",
23227+ unmasked, adev->irq_mask);
23228+ goto none;
23229+ }
23230+
23231+ /* Done here because IRQ_NONEs taking three lines of log
23232+ ** drive me crazy */
23233+ FN_ENTER;
23234+
23235+#define IRQ_ITERATE 1
23236+#if IRQ_ITERATE
23237+if (jiffies != adev->irq_last_jiffies) {
23238+ adev->irq_loops_this_jiffy = 0;
23239+ adev->irq_last_jiffies = jiffies;
23240+}
23241+
23242+/* safety condition; we'll normally abort loop below
23243+ * in case no IRQ type occurred */
23244+while (likely(--irqcount)) {
23245+#endif
23246+ /* ACK all IRQs ASAP */
23247+ write_reg16(adev, IO_ACX_IRQ_ACK, 0xffff);
23248+
23249+ log(L_IRQ, "IRQ type:%04X, mask:%04X, type & ~mask:%04X\n",
23250+ unmasked, adev->irq_mask, irqtype);
23251+
23252+ /* Handle most important IRQ types first */
23253+ if (irqtype & HOST_INT_RX_DATA) {
23254+ log(L_IRQ, "got Rx_Data IRQ\n");
23255+ acxmem_l_process_rxdesc(adev);
23256+ }
23257+ if (irqtype & HOST_INT_TX_COMPLETE) {
23258+ log(L_IRQ, "got Tx_Complete IRQ\n");
23259+ /* don't clean up on each Tx complete, wait a bit
23260+ * unless we're going towards full, in which case
23261+ * we do it immediately, too (otherwise we might lockup
23262+ * with a full Tx buffer if we go into
23263+ * acxmem_l_clean_txdesc() at a time when we won't wakeup
23264+ * the net queue in there for some reason...) */
23265+ if (adev->tx_free <= TX_START_CLEAN) {
23266+#if TX_CLEANUP_IN_SOFTIRQ
23267+ acx_schedule_task(adev, ACX_AFTER_IRQ_TX_CLEANUP);
23268+#else
23269+ acxmem_l_clean_txdesc(adev);
23270+#endif
23271+ }
23272+ }
23273+
23274+ /* Less frequent ones */
23275+ if (irqtype & (0
23276+ | HOST_INT_CMD_COMPLETE
23277+ | HOST_INT_INFO
23278+ | HOST_INT_SCAN_COMPLETE
23279+ )) {
23280+ if (irqtype & HOST_INT_CMD_COMPLETE) {
23281+ log(L_IRQ, "got Command_Complete IRQ\n");
23282+ /* save the state for the running issue_cmd() */
23283+ SET_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE);
23284+ }
23285+ if (irqtype & HOST_INT_INFO) {
23286+ handle_info_irq(adev);
23287+ }
23288+ if (irqtype & HOST_INT_SCAN_COMPLETE) {
23289+ log(L_IRQ, "got Scan_Complete IRQ\n");
23290+ /* need to do that in process context */
23291+ acx_schedule_task(adev, ACX_AFTER_IRQ_COMPLETE_SCAN);
23292+ /* remember that fw is not scanning anymore */
23293+ SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
23294+ }
23295+ }
23296+
23297+ /* These we just log, but either they happen rarely
23298+ * or we keep them masked out */
23299+ if (irqtype & (0
23300+ /* | HOST_INT_RX_DATA */
23301+ /* | HOST_INT_TX_COMPLETE */
23302+ | HOST_INT_TX_XFER
23303+ | HOST_INT_RX_COMPLETE
23304+ | HOST_INT_DTIM
23305+ | HOST_INT_BEACON
23306+ | HOST_INT_TIMER
23307+ | HOST_INT_KEY_NOT_FOUND
23308+ | HOST_INT_IV_ICV_FAILURE
23309+ /* | HOST_INT_CMD_COMPLETE */
23310+ /* | HOST_INT_INFO */
23311+ | HOST_INT_OVERFLOW
23312+ | HOST_INT_PROCESS_ERROR
23313+ /* | HOST_INT_SCAN_COMPLETE */
23314+ | HOST_INT_FCS_THRESHOLD
23315+ | HOST_INT_UNKNOWN
23316+ )) {
23317+ log_unusual_irq(irqtype);
23318+ }
23319+
23320+#if IRQ_ITERATE
23321+ unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR);
23322+ irqtype = unmasked & ~adev->irq_mask;
23323+ /* Bail out if no new IRQ bits or if all are masked out */
23324+ if (!irqtype)
23325+ break;
23326+
23327+ if (unlikely(++adev->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) {
23328+ printk(KERN_ERR "acx: too many interrupts per jiffy!\n");
23329+ /* Looks like card floods us with IRQs! Try to stop that */
23330+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
23331+ /* This will short-circuit all future attempts to handle IRQ.
23332+ * We cant do much more... */
23333+ adev->irq_mask = 0;
23334+ break;
23335+ }
23336+}
23337+#endif
23338+ /* Routine to perform blink with range */
23339+ if (unlikely(adev->led_power == 2))
23340+ update_link_quality_led(adev);
23341+
23342+/* handled: */
23343+ /* write_flush(adev); - not needed, last op was read anyway */
23344+ acx_unlock(adev, flags);
23345+ FN_EXIT0;
23346+ return IRQ_HANDLED;
23347+
23348+none:
23349+ acx_unlock(adev, flags);
23350+ return IRQ_NONE;
23351+}
23352+
23353+
23354+/***********************************************************************
23355+** acxmem_l_power_led
23356+*/
23357+void
23358+acxmem_l_power_led(acx_device_t *adev, int enable)
23359+{
23360+ u16 gpio_pled = IS_ACX111(adev) ? 0x0040 : 0x0800;
23361+
23362+ /* A hack. Not moving message rate limiting to adev->xxx
23363+ * (it's only a debug message after all) */
23364+ static int rate_limit = 0;
23365+
23366+ if (rate_limit++ < 3)
23367+ log(L_IOCTL, "Please report in case toggling the power "
23368+ "LED doesn't work for your card!\n");
23369+ if (enable)
23370+ write_reg16(adev, IO_ACX_GPIO_OUT,
23371+ read_reg16(adev, IO_ACX_GPIO_OUT) & ~gpio_pled);
23372+ else
23373+ write_reg16(adev, IO_ACX_GPIO_OUT,
23374+ read_reg16(adev, IO_ACX_GPIO_OUT) | gpio_pled);
23375+}
23376+
23377+
23378+/***********************************************************************
23379+** Ioctls
23380+*/
23381+
23382+/***********************************************************************
23383+*/
23384+int
23385+acx111pci_ioctl_info(
23386+ struct net_device *ndev,
23387+ struct iw_request_info *info,
23388+ struct iw_param *vwrq,
23389+ char *extra)
23390+{
23391+#if ACX_DEBUG > 1
23392+ acx_device_t *adev = ndev2adev(ndev);
23393+ rxdesc_t *rxdesc;
23394+ txdesc_t *txdesc;
23395+ rxhostdesc_t *rxhostdesc;
23396+ txhostdesc_t *txhostdesc;
23397+ struct acx111_ie_memoryconfig memconf;
23398+ struct acx111_ie_queueconfig queueconf;
23399+ unsigned long flags;
23400+ int i;
23401+ char memmap[0x34];
23402+ char rxconfig[0x8];
23403+ char fcserror[0x8];
23404+ char ratefallback[0x5];
23405+
23406+ if ( !(acx_debug & (L_IOCTL|L_DEBUG)) )
23407+ return OK;
23408+ /* using printk() since we checked debug flag already */
23409+
23410+ acx_sem_lock(adev);
23411+
23412+ if (!IS_ACX111(adev)) {
23413+ printk("acx111-specific function called "
23414+ "with non-acx111 chip, aborting\n");
23415+ goto end_ok;
23416+ }
23417+
23418+ /* get Acx111 Memory Configuration */
23419+ memset(&memconf, 0, sizeof(memconf));
23420+ /* BTW, fails with 12 (Write only) error code.
23421+ ** Retained for easy testing of issue_cmd error handling :) */
23422+ printk ("Interrogating queue config\n");
23423+ acx_s_interrogate(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG);
23424+ printk ("done with queue config\n");
23425+
23426+ /* get Acx111 Queue Configuration */
23427+ memset(&queueconf, 0, sizeof(queueconf));
23428+ printk ("Interrogating mem config options\n");
23429+ acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
23430+ printk ("done with mem config options\n");
23431+
23432+ /* get Acx111 Memory Map */
23433+ memset(memmap, 0, sizeof(memmap));
23434+ printk ("Interrogating mem map\n");
23435+ acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP);
23436+ printk ("done with mem map\n");
23437+
23438+ /* get Acx111 Rx Config */
23439+ memset(rxconfig, 0, sizeof(rxconfig));
23440+ printk ("Interrogating rxconfig\n");
23441+ acx_s_interrogate(adev, &rxconfig, ACX1xx_IE_RXCONFIG);
23442+ printk ("done with queue rxconfig\n");
23443+
23444+ /* get Acx111 fcs error count */
23445+ memset(fcserror, 0, sizeof(fcserror));
23446+ printk ("Interrogating fcs err count\n");
23447+ acx_s_interrogate(adev, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT);
23448+ printk ("done with err count\n");
23449+
23450+ /* get Acx111 rate fallback */
23451+ memset(ratefallback, 0, sizeof(ratefallback));
23452+ printk ("Interrogating rate fallback\n");
23453+ acx_s_interrogate(adev, &ratefallback, ACX1xx_IE_RATE_FALLBACK);
23454+ printk ("done with rate fallback\n");
23455+
23456+ /* force occurrence of a beacon interrupt */
23457+ /* TODO: comment why is this necessary */
23458+ write_reg16(adev, IO_ACX_HINT_TRIG, HOST_INT_BEACON);
23459+
23460+ /* dump Acx111 Mem Configuration */
23461+ printk("dump mem config:\n"
23462+ "data read: %d, struct size: %d\n"
23463+ "Number of stations: %1X\n"
23464+ "Memory block size: %1X\n"
23465+ "tx/rx memory block allocation: %1X\n"
23466+ "count rx: %X / tx: %X queues\n"
23467+ "options %1X\n"
23468+ "fragmentation %1X\n"
23469+ "Rx Queue 1 Count Descriptors: %X\n"
23470+ "Rx Queue 1 Host Memory Start: %X\n"
23471+ "Tx Queue 1 Count Descriptors: %X\n"
23472+ "Tx Queue 1 Attributes: %X\n",
23473+ memconf.len, (int) sizeof(memconf),
23474+ memconf.no_of_stations,
23475+ memconf.memory_block_size,
23476+ memconf.tx_rx_memory_block_allocation,
23477+ memconf.count_rx_queues, memconf.count_tx_queues,
23478+ memconf.options,
23479+ memconf.fragmentation,
23480+ memconf.rx_queue1_count_descs,
23481+ acx2cpu(memconf.rx_queue1_host_rx_start),
23482+ memconf.tx_queue1_count_descs,
23483+ memconf.tx_queue1_attributes);
23484+
23485+ /* dump Acx111 Queue Configuration */
23486+ printk("dump queue head:\n"
23487+ "data read: %d, struct size: %d\n"
23488+ "tx_memory_block_address (from card): %X\n"
23489+ "rx_memory_block_address (from card): %X\n"
23490+ "rx1_queue address (from card): %X\n"
23491+ "tx1_queue address (from card): %X\n"
23492+ "tx1_queue attributes (from card): %X\n",
23493+ queueconf.len, (int) sizeof(queueconf),
23494+ queueconf.tx_memory_block_address,
23495+ queueconf.rx_memory_block_address,
23496+ queueconf.rx1_queue_address,
23497+ queueconf.tx1_queue_address,
23498+ queueconf.tx1_attributes);
23499+
23500+ /* dump Acx111 Mem Map */
23501+ printk("dump mem map:\n"
23502+ "data read: %d, struct size: %d\n"
23503+ "Code start: %X\n"
23504+ "Code end: %X\n"
23505+ "WEP default key start: %X\n"
23506+ "WEP default key end: %X\n"
23507+ "STA table start: %X\n"
23508+ "STA table end: %X\n"
23509+ "Packet template start: %X\n"
23510+ "Packet template end: %X\n"
23511+ "Queue memory start: %X\n"
23512+ "Queue memory end: %X\n"
23513+ "Packet memory pool start: %X\n"
23514+ "Packet memory pool end: %X\n"
23515+ "iobase: %p\n"
23516+ "iobase2: %p\n",
23517+ *((u16 *)&memmap[0x02]), (int) sizeof(memmap),
23518+ *((u32 *)&memmap[0x04]),
23519+ *((u32 *)&memmap[0x08]),
23520+ *((u32 *)&memmap[0x0C]),
23521+ *((u32 *)&memmap[0x10]),
23522+ *((u32 *)&memmap[0x14]),
23523+ *((u32 *)&memmap[0x18]),
23524+ *((u32 *)&memmap[0x1C]),
23525+ *((u32 *)&memmap[0x20]),
23526+ *((u32 *)&memmap[0x24]),
23527+ *((u32 *)&memmap[0x28]),
23528+ *((u32 *)&memmap[0x2C]),
23529+ *((u32 *)&memmap[0x30]),
23530+ adev->iobase,
23531+ adev->iobase2);
23532+
23533+ /* dump Acx111 Rx Config */
23534+ printk("dump rx config:\n"
23535+ "data read: %d, struct size: %d\n"
23536+ "rx config: %X\n"
23537+ "rx filter config: %X\n",
23538+ *((u16 *)&rxconfig[0x02]), (int) sizeof(rxconfig),
23539+ *((u16 *)&rxconfig[0x04]),
23540+ *((u16 *)&rxconfig[0x06]));
23541+
23542+ /* dump Acx111 fcs error */
23543+ printk("dump fcserror:\n"
23544+ "data read: %d, struct size: %d\n"
23545+ "fcserrors: %X\n",
23546+ *((u16 *)&fcserror[0x02]), (int) sizeof(fcserror),
23547+ *((u32 *)&fcserror[0x04]));
23548+
23549+ /* dump Acx111 rate fallback */
23550+ printk("dump rate fallback:\n"
23551+ "data read: %d, struct size: %d\n"
23552+ "ratefallback: %X\n",
23553+ *((u16 *)&ratefallback[0x02]), (int) sizeof(ratefallback),
23554+ *((u8 *)&ratefallback[0x04]));
23555+
23556+ /* protect against IRQ */
23557+ acx_lock(adev, flags);
23558+
23559+ /* dump acx111 internal rx descriptor ring buffer */
23560+ rxdesc = adev->rxdesc_start;
23561+
23562+ /* loop over complete receive pool */
23563+ if (rxdesc) for (i = 0; i < RX_CNT; i++) {
23564+ printk("\ndump internal rxdesc %d:\n"
23565+ "mem pos %p\n"
23566+ "next 0x%X\n"
23567+ "acx mem pointer (dynamic) 0x%X\n"
23568+ "CTL (dynamic) 0x%X\n"
23569+ "Rate (dynamic) 0x%X\n"
23570+ "RxStatus (dynamic) 0x%X\n"
23571+ "Mod/Pre (dynamic) 0x%X\n",
23572+ i,
23573+ rxdesc,
23574+ acx2cpu(rxdesc->pNextDesc),
23575+ acx2cpu(rxdesc->ACXMemPtr),
23576+ rxdesc->Ctl_8,
23577+ rxdesc->rate,
23578+ rxdesc->error,
23579+ rxdesc->SNR);
23580+ rxdesc++;
23581+ }
23582+
23583+ /* dump host rx descriptor ring buffer */
23584+
23585+ rxhostdesc = adev->rxhostdesc_start;
23586+
23587+ /* loop over complete receive pool */
23588+ if (rxhostdesc) for (i = 0; i < RX_CNT; i++) {
23589+ printk("\ndump host rxdesc %d:\n"
23590+ "mem pos %p\n"
23591+ "buffer mem pos 0x%X\n"
23592+ "buffer mem offset 0x%X\n"
23593+ "CTL 0x%X\n"
23594+ "Length 0x%X\n"
23595+ "next 0x%X\n"
23596+ "Status 0x%X\n",
23597+ i,
23598+ rxhostdesc,
23599+ acx2cpu(rxhostdesc->data_phy),
23600+ rxhostdesc->data_offset,
23601+ le16_to_cpu(rxhostdesc->Ctl_16),
23602+ le16_to_cpu(rxhostdesc->length),
23603+ acx2cpu(rxhostdesc->desc_phy_next),
23604+ rxhostdesc->Status);
23605+ rxhostdesc++;
23606+ }
23607+
23608+ /* dump acx111 internal tx descriptor ring buffer */
23609+ txdesc = adev->txdesc_start;
23610+
23611+ /* loop over complete transmit pool */
23612+ if (txdesc) for (i = 0; i < TX_CNT; i++) {
23613+ printk("\ndump internal txdesc %d:\n"
23614+ "size 0x%X\n"
23615+ "mem pos %p\n"
23616+ "next 0x%X\n"
23617+ "acx mem pointer (dynamic) 0x%X\n"
23618+ "host mem pointer (dynamic) 0x%X\n"
23619+ "length (dynamic) 0x%X\n"
23620+ "CTL (dynamic) 0x%X\n"
23621+ "CTL2 (dynamic) 0x%X\n"
23622+ "Status (dynamic) 0x%X\n"
23623+ "Rate (dynamic) 0x%X\n",
23624+ i,
23625+ (int) sizeof(struct txdesc),
23626+ txdesc,
23627+ acx2cpu(txdesc->pNextDesc),
23628+ acx2cpu(txdesc->AcxMemPtr),
23629+ acx2cpu(txdesc->HostMemPtr),
23630+ le16_to_cpu(txdesc->total_length),
23631+ txdesc->Ctl_8,
23632+ txdesc->Ctl2_8, txdesc->error,
23633+ txdesc->u.r1.rate);
23634+ txdesc = advance_txdesc(adev, txdesc, 1);
23635+ }
23636+
23637+ /* dump host tx descriptor ring buffer */
23638+
23639+ txhostdesc = adev->txhostdesc_start;
23640+
23641+ /* loop over complete host send pool */
23642+ if (txhostdesc) for (i = 0; i < TX_CNT * 2; i++) {
23643+ printk("\ndump host txdesc %d:\n"
23644+ "mem pos %p\n"
23645+ "buffer mem pos 0x%X\n"
23646+ "buffer mem offset 0x%X\n"
23647+ "CTL 0x%X\n"
23648+ "Length 0x%X\n"
23649+ "next 0x%X\n"
23650+ "Status 0x%X\n",
23651+ i,
23652+ txhostdesc,
23653+ acx2cpu(txhostdesc->data_phy),
23654+ txhostdesc->data_offset,
23655+ le16_to_cpu(txhostdesc->Ctl_16),
23656+ le16_to_cpu(txhostdesc->length),
23657+ acx2cpu(txhostdesc->desc_phy_next),
23658+ le32_to_cpu(txhostdesc->Status));
23659+ txhostdesc++;
23660+ }
23661+
23662+ /* write_reg16(adev, 0xb4, 0x4); */
23663+
23664+ acx_unlock(adev, flags);
23665+end_ok:
23666+
23667+ acx_sem_unlock(adev);
23668+#endif /* ACX_DEBUG */
23669+ return OK;
23670+}
23671+
23672+
23673+/***********************************************************************
23674+*/
23675+int
23676+acx100mem_ioctl_set_phy_amp_bias(
23677+ struct net_device *ndev,
23678+ struct iw_request_info *info,
23679+ struct iw_param *vwrq,
23680+ char *extra)
23681+{
23682+ acx_device_t *adev = ndev2adev(ndev);
23683+ unsigned long flags;
23684+ u16 gpio_old;
23685+
23686+ if (!IS_ACX100(adev)) {
23687+ /* WARNING!!!
23688+ * Removing this check *might* damage
23689+ * hardware, since we're tweaking GPIOs here after all!!!
23690+ * You've been warned...
23691+ * WARNING!!! */
23692+ printk("acx: sorry, setting bias level for non-acx100 "
23693+ "is not supported yet\n");
23694+ return OK;
23695+ }
23696+
23697+ if (*extra > 7) {
23698+ printk("acx: invalid bias parameter, range is 0-7\n");
23699+ return -EINVAL;
23700+ }
23701+
23702+ acx_sem_lock(adev);
23703+
23704+ /* Need to lock accesses to [IO_ACX_GPIO_OUT]:
23705+ * IRQ handler uses it to update LED */
23706+ acx_lock(adev, flags);
23707+ gpio_old = read_reg16(adev, IO_ACX_GPIO_OUT);
23708+ write_reg16(adev, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8));
23709+ acx_unlock(adev, flags);
23710+
23711+ log(L_DEBUG, "gpio_old: 0x%04X\n", gpio_old);
23712+ printk("%s: PHY power amplifier bias: old:%d, new:%d\n",
23713+ ndev->name,
23714+ (gpio_old & 0x0700) >> 8, (unsigned char)*extra);
23715+
23716+ acx_sem_unlock(adev);
23717+
23718+ return OK;
23719+}
23720+
23721+/***************************************************************
23722+** acxmem_l_alloc_tx
23723+** Actually returns a txdesc_t* ptr
23724+**
23725+** FIXME: in case of fragments, should allocate multiple descrs
23726+** after figuring out how many we need and whether we still have
23727+** sufficiently many.
23728+*/
23729+tx_t*
23730+acxmem_l_alloc_tx(acx_device_t *adev)
23731+{
23732+ struct txdesc *txdesc;
23733+ unsigned head;
23734+ u8 ctl8;
23735+ static int txattempts = 0;
23736+
23737+ FN_ENTER;
23738+
23739+ if (unlikely(!adev->tx_free)) {
23740+ printk("acx: BUG: no free txdesc left\n");
23741+ /*
23742+ * Probably the ACX ignored a transmit attempt and now there's a packet
23743+ * sitting in the queue we think should be transmitting but the ACX doesn't
23744+ * know about.
23745+ * On the first pass, send the ACX a TxProc interrupt to try moving
23746+ * things along, and if that doesn't work (ie, we get called again) completely
23747+ * flush the transmit queue.
23748+ */
23749+ if (txattempts < 10) {
23750+ txattempts++;
23751+ printk ("acx: trying to wake up ACX\n");
23752+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC);
23753+ write_flush(adev); }
23754+ else {
23755+ txattempts = 0;
23756+ printk ("acx: flushing transmit queue.\n");
23757+ acxmem_l_clean_txdesc_emergency (adev);
23758+ }
23759+ txdesc = NULL;
23760+ goto end;
23761+ }
23762+
23763+ /*
23764+ * Make a quick check to see if there is transmit buffer space on
23765+ * the ACX. This can't guarantee there is enough space for the packet
23766+ * since we don't yet know how big it is, but it will prevent at least some
23767+ * annoyances.
23768+ */
23769+ if (!adev->acx_txbuf_blocks_free) {
23770+ txdesc = NULL;
23771+ goto end;
23772+ }
23773+
23774+ head = adev->tx_head;
23775+ /*
23776+ * txdesc points to ACX memory
23777+ */
23778+ txdesc = get_txdesc(adev, head);
23779+ ctl8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
23780+
23781+ /*
23782+ * If we don't own the buffer (HOSTOWN) it is certainly not free; however,
23783+ * we may have previously thought we had enough memory to send
23784+ * a packet, allocated the buffer then gave up when we found not enough
23785+ * transmit buffer space on the ACX. In that case, HOSTOWN and
23786+ * ACXDONE will both be set.
23787+ */
23788+ if (unlikely(DESC_CTL_HOSTOWN != (ctl8 & DESC_CTL_HOSTOWN))) {
23789+ /* whoops, descr at current index is not free, so probably
23790+ * ring buffer already full */
23791+ printk("acx: BUG: tx_head:%d Ctl8:0x%02X - failed to find "
23792+ "free txdesc\n", head, ctl8);
23793+ txdesc = NULL;
23794+ goto end;
23795+ }
23796+
23797+ /* Needed in case txdesc won't be eventually submitted for tx */
23798+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), DESC_CTL_ACXDONE_HOSTOWN);
23799+
23800+ adev->tx_free--;
23801+ log(L_BUFT, "tx: got desc %u, %u remain\n",
23802+ head, adev->tx_free);
23803+ /* Keep a few free descs between head and tail of tx ring.
23804+ ** It is not absolutely needed, just feels safer */
23805+ if (adev->tx_free < TX_STOP_QUEUE) {
23806+ log(L_BUF, "stop queue (%u tx desc left)\n",
23807+ adev->tx_free);
23808+ acx_stop_queue(adev->ndev, NULL);
23809+ }
23810+
23811+ /* returning current descriptor, so advance to next free one */
23812+ adev->tx_head = (head + 1) % TX_CNT;
23813+end:
23814+ FN_EXIT0;
23815+
23816+ return (tx_t*)txdesc;
23817+}
23818+
23819+
23820+/***************************************************************
23821+** acxmem_l_dealloc_tx
23822+** Clears out a previously allocatedvoid acxmem_l_dealloc_tx(tx_t *tx_opaque);
23823+ transmit descriptor. The ACX
23824+** can get confused if we skip transmit descriptors in the queue,
23825+** so when we don't need a descriptor return it to its original
23826+** state and move the queue head pointer back.
23827+**
23828+*/
23829+void
23830+acxmem_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque)
23831+{
23832+ /*
23833+ * txdesc is the address of the descriptor on the ACX.
23834+ */
23835+ txdesc_t *txdesc = (txdesc_t*)tx_opaque;
23836+ txdesc_t tmptxdesc;
23837+ int index;
23838+
23839+ memset (&tmptxdesc, 0, sizeof(tmptxdesc));
23840+ tmptxdesc.Ctl_8 = DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG;
23841+ tmptxdesc.u.r1.rate = 0x0a;
23842+
23843+ /*
23844+ * Clear out all of the transmit descriptor except for the next pointer
23845+ */
23846+ copy_to_slavemem (adev, (u32) &(txdesc->HostMemPtr),
23847+ (u8 *) &(tmptxdesc.HostMemPtr),
23848+ sizeof (tmptxdesc) - sizeof(tmptxdesc.pNextDesc));
23849+
23850+ /*
23851+ * This is only called immediately after we've allocated, so we should
23852+ * be able to set the head back to this descriptor.
23853+ */
23854+ index = ((u8*) txdesc - (u8*)adev->txdesc_start) / adev->txdesc_size;
23855+ printk ("acx_dealloc: moving head from %d to %d\n", adev->tx_head, index);
23856+ adev->tx_head = index;
23857+}
23858+
23859+
23860+/***********************************************************************
23861+*/
23862+void*
23863+acxmem_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque)
23864+{
23865+ return get_txhostdesc(adev, (txdesc_t*)tx_opaque)->data;
23866+}
23867+
23868+
23869+/***********************************************************************
23870+** acxmem_l_tx_data
23871+**
23872+** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx).
23873+** Can be called from acx_i_start_xmit (data frames from net core).
23874+**
23875+** FIXME: in case of fragments, should loop over the number of
23876+** pre-allocated tx descrs, properly setting up transfer data and
23877+** CTL_xxx flags according to fragment number.
23878+*/
23879+void
23880+acxmem_update_queue_indicator (acx_device_t *adev, int txqueue)
23881+{
23882+#ifdef USING_MORE_THAN_ONE_TRANSMIT_QUEUE
23883+ u32 indicator;
23884+ unsigned long flags;
23885+ int count;
23886+
23887+ /*
23888+ * Can't handle an interrupt while we're fiddling with the ACX's lock,
23889+ * according to TI. The ACX is supposed to hold fw_lock for at most
23890+ * 500ns.
23891+ */
23892+ local_irq_save (flags);
23893+
23894+ /*
23895+ * Wait for ACX to release the lock (at most 500ns).
23896+ */
23897+ count = 0;
23898+ while (read_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->fw_lock))
23899+ && (count++ < 50)) {
23900+ ndelay (10);
23901+ }
23902+ if (count < 50) {
23903+
23904+ /*
23905+ * Take out the host lock - anything non-zero will work, so don't worry about
23906+ * be/le
23907+ */
23908+ write_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->host_lock), 1);
23909+
23910+ /*
23911+ * Avoid a race condition
23912+ */
23913+ count = 0;
23914+ while (read_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->fw_lock))
23915+ && (count++ < 50)) {
23916+ ndelay (10);
23917+ }
23918+
23919+ if (count < 50) {
23920+ /*
23921+ * Mark the queue active
23922+ */
23923+ indicator = read_slavemem32 (adev, (u32) &(adev->acx_queue_indicator->indicator));
23924+ indicator |= cpu_to_le32 (1 << txqueue);
23925+ write_slavemem32 (adev, (u32) &(adev->acx_queue_indicator->indicator), indicator);
23926+ }
23927+
23928+ /*
23929+ * Release the host lock
23930+ */
23931+ write_slavemem16 (adev, (u32) &(adev->acx_queue_indicator->host_lock), 0);
23932+
23933+ }
23934+
23935+ /*
23936+ * Restore interrupts
23937+ */
23938+ local_irq_restore (flags);
23939+#endif
23940+}
23941+
23942+void
23943+acxmem_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int len)
23944+{
23945+ /*
23946+ * txdesc is the address on the ACX
23947+ */
23948+ txdesc_t *txdesc = (txdesc_t*)tx_opaque;
23949+ txhostdesc_t *hostdesc1, *hostdesc2;
23950+ client_t *clt;
23951+ u16 rate_cur;
23952+ u8 Ctl_8, Ctl2_8;
23953+ u32 addr;
23954+
23955+ FN_ENTER;
23956+ /* fw doesn't tx such packets anyhow */
23957+ if (unlikely(len < WLAN_HDR_A3_LEN))
23958+ goto end;
23959+
23960+ hostdesc1 = get_txhostdesc(adev, txdesc);
23961+ /* modify flag status in separate variable to be able to write it back
23962+ * in one big swoop later (also in order to have less device memory
23963+ * accesses) */
23964+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
23965+ Ctl2_8 = 0; /* really need to init it to 0, not txdesc->Ctl2_8, it seems */
23966+
23967+ hostdesc2 = hostdesc1 + 1;
23968+
23969+ /* DON'T simply set Ctl field to 0 here globally,
23970+ * it needs to maintain a consistent flag status (those are state flags!!),
23971+ * otherwise it may lead to severe disruption. Only set or reset particular
23972+ * flags at the exact moment this is needed... */
23973+
23974+ /* let chip do RTS/CTS handshaking before sending
23975+ * in case packet size exceeds threshold */
23976+ if (len > adev->rts_threshold)
23977+ SET_BIT(Ctl2_8, DESC_CTL2_RTS);
23978+ else
23979+ CLEAR_BIT(Ctl2_8, DESC_CTL2_RTS);
23980+
23981+ switch (adev->mode) {
23982+ case ACX_MODE_0_ADHOC:
23983+ case ACX_MODE_3_AP:
23984+ clt = acx_l_sta_list_get(adev, ((wlan_hdr_t*)hostdesc1->data)->a1);
23985+ break;
23986+ case ACX_MODE_2_STA:
23987+ clt = adev->ap_client;
23988+ break;
23989+#if 0
23990+/* testing was done on acx111: */
23991+ case ACX_MODE_MONITOR:
23992+ SET_BIT(Ctl2_8, 0
23993+/* sends CTS to self before packet */
23994+ + DESC_CTL2_SEQ /* don't increase sequence field */
23995+/* not working (looks like good fcs is still added) */
23996+ + DESC_CTL2_FCS /* don't add the FCS */
23997+/* not tested */
23998+ + DESC_CTL2_MORE_FRAG
23999+/* not tested */
24000+ + DESC_CTL2_RETRY /* don't increase retry field */
24001+/* not tested */
24002+ + DESC_CTL2_POWER /* don't increase power mgmt. field */
24003+/* no effect */
24004+ + DESC_CTL2_WEP /* encrypt this frame */
24005+/* not tested */
24006+ + DESC_CTL2_DUR /* don't increase duration field */
24007+ );
24008+ /* fallthrough */
24009+#endif
24010+ default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */
24011+ clt = NULL;
24012+ break;
24013+ }
24014+
24015+ rate_cur = clt ? clt->rate_cur : adev->rate_bcast;
24016+ if (unlikely(!rate_cur)) {
24017+ printk("acx: driver bug! bad ratemask\n");
24018+ goto end;
24019+ }
24020+
24021+ /* used in tx cleanup routine for auto rate and accounting: */
24022+ put_txcr(adev, txdesc, clt, rate_cur);
24023+
24024+ write_slavemem16 (adev, (u32) &(txdesc->total_length), cpu_to_le16(len));
24025+ hostdesc2->length = cpu_to_le16(len - WLAN_HDR_A3_LEN);
24026+ if (IS_ACX111(adev)) {
24027+ /* note that if !txdesc->do_auto, txrate->cur
24028+ ** has only one nonzero bit */
24029+ txdesc->u.r2.rate111 = cpu_to_le16(
24030+ rate_cur
24031+ /* WARNING: I was never able to make it work with prism54 AP.
24032+ ** It was falling down to 1Mbit where shortpre is not applicable,
24033+ ** and not working at all at "5,11 basic rates only" setting.
24034+ ** I even didn't see tx packets in radio packet capture.
24035+ ** Disabled for now --vda */
24036+ /*| ((clt->shortpre && clt->cur!=RATE111_1) ? RATE111_SHORTPRE : 0) */
24037+ );
24038+#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS
24039+ /* should add this to rate111 above as necessary */
24040+ | (clt->pbcc511 ? RATE111_PBCC511 : 0)
24041+#endif
24042+ hostdesc1->length = cpu_to_le16(len);
24043+ } else { /* ACX100 */
24044+ u8 rate_100 = clt ? clt->rate_100 : adev->rate_bcast100;
24045+ write_slavemem8 (adev, (u32) &(txdesc->u.r1.rate), rate_100);
24046+#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS
24047+ if (clt->pbcc511) {
24048+ if (n == RATE100_5 || n == RATE100_11)
24049+ n |= RATE100_PBCC511;
24050+ }
24051+
24052+ if (clt->shortpre && (clt->cur != RATE111_1))
24053+ SET_BIT(Ctl_8, DESC_CTL_SHORT_PREAMBLE); /* set Short Preamble */
24054+#endif
24055+ /* set autodma and reclaim and 1st mpdu */
24056+ SET_BIT(Ctl_8, DESC_CTL_FIRSTFRAG);
24057+
24058+#if ACX_FRAGMENTATION
24059+ /* SET_BIT(Ctl2_8, DESC_CTL2_MORE_FRAG); cannot set it unconditionally, needs to be set for all non-last fragments */
24060+#endif
24061+ hostdesc1->length = cpu_to_le16(WLAN_HDR_A3_LEN);
24062+
24063+ /*
24064+ * Since we're not using autodma copy the packet data to the acx now.
24065+ * Even host descriptors point to the packet header, and the odd indexed
24066+ * descriptor following points to the packet data.
24067+ *
24068+ * The first step is to find free memory in the ACX transmit buffers.
24069+ * They don't necessarily map one to one with the transmit queue entries,
24070+ * so search through them starting just after the last one used.
24071+ */
24072+ addr = allocate_acx_txbuf_space (adev, len);
24073+ if (addr) {
24074+ chaincopy_to_slavemem (adev, addr, hostdesc1->data, len);
24075+ }
24076+ else {
24077+ /*
24078+ * Bummer. We thought we might have enough room in the transmit
24079+ * buffers to send this packet, but it turns out we don't. alloc_tx
24080+ * has already marked this transmit descriptor as HOSTOWN and ACXDONE,
24081+ * which means the ACX will hang when it gets to this descriptor unless
24082+ * we do something about it. Having a bubble in the transmit queue just
24083+ * doesn't seem to work, so we have to reset this transmit queue entry's
24084+ * state to its original value and back up our head pointer to point
24085+ * back to this entry.
24086+ */
24087+ hostdesc1->length = 0;
24088+ hostdesc2->length = 0;
24089+ write_slavemem16 (adev, (u32) &(txdesc->total_length), 0);
24090+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG);
24091+ adev->tx_head = ((u8*) txdesc - (u8*) adev->txdesc_start) / adev->txdesc_size;
24092+ goto end;
24093+ }
24094+ /*
24095+ * Tell the ACX where the packet is.
24096+ */
24097+ write_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr), addr);
24098+
24099+ }
24100+ /* don't need to clean ack/rts statistics here, already
24101+ * done on descr cleanup */
24102+
24103+ /* clears HOSTOWN and ACXDONE bits, thus telling that the descriptors
24104+ * are now owned by the acx100; do this as LAST operation */
24105+ CLEAR_BIT(Ctl_8, DESC_CTL_ACXDONE_HOSTOWN);
24106+ /* flush writes before we release hostdesc to the adapter here */
24107+ //wmb();
24108+
24109+ /* write back modified flags */
24110+ /*
24111+ * At this point Ctl_8 should just be FIRSTFRAG
24112+ */
24113+ write_slavemem8 (adev, (u32) &(txdesc->Ctl2_8),Ctl2_8);
24114+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), Ctl_8);
24115+ /* unused: txdesc->tx_time = cpu_to_le32(jiffies); */
24116+
24117+ /*
24118+ * Update the queue indicator to say there's data on the first queue.
24119+ */
24120+ acxmem_update_queue_indicator (adev, 0);
24121+
24122+ /* flush writes before we tell the adapter that it's its turn now */
24123+ mmiowb();
24124+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC);
24125+ write_flush(adev);
24126+
24127+ /* log the packet content AFTER sending it,
24128+ * in order to not delay sending any further than absolutely needed
24129+ * Do separate logs for acx100/111 to have human-readable rates */
24130+ if (unlikely(acx_debug & (L_XFER|L_DATA))) {
24131+ u16 fc = ((wlan_hdr_t*)hostdesc1->data)->fc;
24132+ if (IS_ACX111(adev))
24133+ printk("tx: pkt (%s): len %d "
24134+ "rate %04X%s status %u\n",
24135+ acx_get_packet_type_string(le16_to_cpu(fc)), len,
24136+ le16_to_cpu(txdesc->u.r2.rate111),
24137+ (le16_to_cpu(txdesc->u.r2.rate111) & RATE111_SHORTPRE) ? "(SPr)" : "",
24138+ adev->status);
24139+ else
24140+ printk("tx: pkt (%s): len %d rate %03u%s status %u\n",
24141+ acx_get_packet_type_string(fc), len,
24142+ read_slavemem8 (adev, (u32) &(txdesc->u.r1.rate)),
24143+ (Ctl_8 & DESC_CTL_SHORT_PREAMBLE) ? "(SPr)" : "",
24144+ adev->status);
24145+
24146+ if (acx_debug & L_DATA) {
24147+ printk("tx: 802.11 [%d]: ", len);
24148+ acx_dump_bytes(hostdesc1->data, len);
24149+ }
24150+ }
24151+end:
24152+ FN_EXIT0;
24153+}
24154+
24155+
24156+/***********************************************************************
24157+** acxmem_l_clean_txdesc
24158+**
24159+** This function resets the txdescs' status when the ACX100
24160+** signals the TX done IRQ (txdescs have been processed), starting with
24161+** the pool index of the descriptor which we would use next,
24162+** in order to make sure that we can be as fast as possible
24163+** in filling new txdescs.
24164+** Everytime we get called we know where the next packet to be cleaned is.
24165+*/
24166+
24167+#if !ACX_DEBUG
24168+static inline void log_txbuffer(const acx_device_t *adev) {}
24169+#else
24170+static void
24171+log_txbuffer(acx_device_t *adev)
24172+{
24173+ txdesc_t *txdesc;
24174+ int i;
24175+ u8 Ctl_8;
24176+
24177+ /* no FN_ENTER here, we don't want that */
24178+ /* no locks here, since it's entirely non-critical code */
24179+ txdesc = adev->txdesc_start;
24180+ if (unlikely(!txdesc)) return;
24181+ printk("tx: desc->Ctl8's:");
24182+ for (i = 0; i < TX_CNT; i++) {
24183+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
24184+ printk(" %02X", Ctl_8);
24185+ txdesc = advance_txdesc(adev, txdesc, 1);
24186+ }
24187+ printk("\n");
24188+}
24189+#endif
24190+
24191+
24192+static void
24193+handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger)
24194+{
24195+ const char *err = "unknown error";
24196+
24197+ /* hmm, should we handle this as a mask
24198+ * of *several* bits?
24199+ * For now I think only caring about
24200+ * individual bits is ok... */
24201+ switch (error) {
24202+ case 0x01:
24203+ err = "no Tx due to error in other fragment";
24204+ adev->wstats.discard.fragment++;
24205+ break;
24206+ case 0x02:
24207+ err = "Tx aborted";
24208+ adev->stats.tx_aborted_errors++;
24209+ break;
24210+ case 0x04:
24211+ err = "Tx desc wrong parameters";
24212+ adev->wstats.discard.misc++;
24213+ break;
24214+ case 0x08:
24215+ err = "WEP key not found";
24216+ adev->wstats.discard.misc++;
24217+ break;
24218+ case 0x10:
24219+ err = "MSDU lifetime timeout? - try changing "
24220+ "'iwconfig retry lifetime XXX'";
24221+ adev->wstats.discard.misc++;
24222+ break;
24223+ case 0x20:
24224+ err = "excessive Tx retries due to either distance "
24225+ "too high or unable to Tx or Tx frame error - "
24226+ "try changing 'iwconfig txpower XXX' or "
24227+ "'sens'itivity or 'retry'";
24228+ adev->wstats.discard.retries++;
24229+ /* Tx error 0x20 also seems to occur on
24230+ * overheating, so I'm not sure whether we
24231+ * actually want to do aggressive radio recalibration,
24232+ * since people maybe won't notice then that their hardware
24233+ * is slowly getting cooked...
24234+ * Or is it still a safe long distance from utter
24235+ * radio non-functionality despite many radio recalibs
24236+ * to final destructive overheating of the hardware?
24237+ * In this case we really should do recalib here...
24238+ * I guess the only way to find out is to do a
24239+ * potentially fatal self-experiment :-\
24240+ * Or maybe only recalib in case we're using Tx
24241+ * rate auto (on errors switching to lower speed
24242+ * --> less heat?) or 802.11 power save mode?
24243+ *
24244+ * ok, just do it. */
24245+ if (++adev->retry_errors_msg_ratelimit % 4 == 0) {
24246+ if (adev->retry_errors_msg_ratelimit <= 20) {
24247+ printk("%s: several excessive Tx "
24248+ "retry errors occurred, attempting "
24249+ "to recalibrate radio. Radio "
24250+ "drift might be caused by increasing "
24251+ "card temperature, please check the card "
24252+ "before it's too late!\n",
24253+ adev->ndev->name);
24254+ if (adev->retry_errors_msg_ratelimit == 20)
24255+ printk("disabling above message\n");
24256+ }
24257+
24258+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
24259+ }
24260+ break;
24261+ case 0x40:
24262+ err = "Tx buffer overflow";
24263+ adev->stats.tx_fifo_errors++;
24264+ break;
24265+ case 0x80:
24266+ err = "DMA error";
24267+ adev->wstats.discard.misc++;
24268+ break;
24269+ }
24270+ adev->stats.tx_errors++;
24271+ if (adev->stats.tx_errors <= 20)
24272+ printk("%s: tx error 0x%02X, buf %02u! (%s)\n",
24273+ adev->ndev->name, error, finger, err);
24274+ else
24275+ printk("%s: tx error 0x%02X, buf %02u!\n",
24276+ adev->ndev->name, error, finger);
24277+}
24278+
24279+
24280+unsigned int
24281+acxmem_l_clean_txdesc(acx_device_t *adev)
24282+{
24283+ txdesc_t *txdesc;
24284+ unsigned finger;
24285+ int num_cleaned;
24286+ u16 r111;
24287+ u8 error, ack_failures, rts_failures, rts_ok, r100, Ctl_8;
24288+ u32 acxmem;
24289+ txdesc_t tmptxdesc;
24290+
24291+ FN_ENTER;
24292+
24293+ /*
24294+ * Set up a template descriptor for re-initialization. The only
24295+ * things that get set are Ctl_8 and the rate, and the rate defaults
24296+ * to 1Mbps.
24297+ */
24298+ memset (&tmptxdesc, 0, sizeof (tmptxdesc));
24299+ tmptxdesc.Ctl_8 = DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG;
24300+ tmptxdesc.u.r1.rate = 0x0a;
24301+
24302+ if (unlikely(acx_debug & L_DEBUG))
24303+ log_txbuffer(adev);
24304+
24305+ log(L_BUFT, "tx: cleaning up bufs from %u\n", adev->tx_tail);
24306+
24307+ /* We know first descr which is not free yet. We advance it as far
24308+ ** as we see correct bits set in following descs (if next desc
24309+ ** is NOT free, we shouldn't advance at all). We know that in
24310+ ** front of tx_tail may be "holes" with isolated free descs.
24311+ ** We will catch up when all intermediate descs will be freed also */
24312+
24313+ finger = adev->tx_tail;
24314+ num_cleaned = 0;
24315+ while (likely(finger != adev->tx_head)) {
24316+ txdesc = get_txdesc(adev, finger);
24317+
24318+ /* If we allocated txdesc on tx path but then decided
24319+ ** to NOT use it, then it will be left as a free "bubble"
24320+ ** in the "allocated for tx" part of the ring.
24321+ ** We may meet it on the next ring pass here. */
24322+
24323+ /* stop if not marked as "tx finished" and "host owned" */
24324+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
24325+ if ((Ctl_8 & DESC_CTL_ACXDONE_HOSTOWN)
24326+ != DESC_CTL_ACXDONE_HOSTOWN) {
24327+ if (unlikely(!num_cleaned)) { /* maybe remove completely */
24328+ log(L_BUFT, "clean_txdesc: tail isn't free. "
24329+ "tail:%d head:%d\n",
24330+ adev->tx_tail, adev->tx_head);
24331+ }
24332+ break;
24333+ }
24334+
24335+ /* remember desc values... */
24336+ error = read_slavemem8 (adev, (u32) &(txdesc->error));
24337+ ack_failures = read_slavemem8 (adev, (u32) &(txdesc->ack_failures));
24338+ rts_failures = read_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_failures));
24339+ rts_ok = read_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_ok));
24340+ r100 = read_slavemem8 (adev, (u32) &(txdesc->u.r1.rate));
24341+ r111 = le16_to_cpu(read_slavemem16 (adev, (u32) &(txdesc->u.r2.rate111)));
24342+
24343+ /* need to check for certain error conditions before we
24344+ * clean the descriptor: we still need valid descr data here */
24345+ if (unlikely(0x30 & error)) {
24346+ /* only send IWEVTXDROP in case of retry or lifetime exceeded;
24347+ * all other errors mean we screwed up locally */
24348+ union iwreq_data wrqu;
24349+ wlan_hdr_t *hdr;
24350+ txhostdesc_t *hostdesc;
24351+
24352+ hostdesc = get_txhostdesc(adev, txdesc);
24353+ hdr = (wlan_hdr_t *)hostdesc->data;
24354+ MAC_COPY(wrqu.addr.sa_data, hdr->a1);
24355+ wireless_send_event(adev->ndev, IWEVTXDROP, &wrqu, NULL);
24356+ }
24357+
24358+ /*
24359+ * Free up the transmit data buffers
24360+ */
24361+ acxmem = read_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr));
24362+ if (acxmem) {
24363+ reclaim_acx_txbuf_space (adev, acxmem);
24364+ }
24365+
24366+ /* ...and free the desc by clearing all the fields
24367+ except the next pointer */
24368+ copy_to_slavemem (adev,
24369+ (u32) &(txdesc->HostMemPtr),
24370+ (u8 *) &(tmptxdesc.HostMemPtr),
24371+ sizeof (tmptxdesc) - sizeof(tmptxdesc.pNextDesc)
24372+ );
24373+
24374+ adev->tx_free++;
24375+ num_cleaned++;
24376+
24377+ if ((adev->tx_free >= TX_START_QUEUE)
24378+ && (adev->status == ACX_STATUS_4_ASSOCIATED)
24379+ && (acx_queue_stopped(adev->ndev))
24380+ ) {
24381+ log(L_BUF, "tx: wake queue (avail. Tx desc %u)\n",
24382+ adev->tx_free);
24383+ acx_wake_queue(adev->ndev, NULL);
24384+ }
24385+
24386+ /* do error checking, rate handling and logging
24387+ * AFTER having done the work, it's faster */
24388+
24389+ /* do rate handling */
24390+ if (adev->rate_auto) {
24391+ struct client *clt = get_txc(adev, txdesc);
24392+ if (clt) {
24393+ u16 cur = get_txr(adev, txdesc);
24394+ if (clt->rate_cur == cur) {
24395+ acx_l_handle_txrate_auto(adev, clt,
24396+ cur, /* intended rate */
24397+ r100, r111, /* actually used rate */
24398+ (error & 0x30), /* was there an error? */
24399+ TX_CNT + TX_CLEAN_BACKLOG - adev->tx_free);
24400+ }
24401+ }
24402+ }
24403+
24404+ if (unlikely(error))
24405+ handle_tx_error(adev, error, finger);
24406+
24407+ if (IS_ACX111(adev))
24408+ log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u r111=%04X\n",
24409+ finger, ack_failures, rts_failures, rts_ok, r111);
24410+ else
24411+ log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u rate=%u\n",
24412+ finger, ack_failures, rts_failures, rts_ok, r100);
24413+
24414+ /* update pointer for descr to be cleaned next */
24415+ finger = (finger + 1) % TX_CNT;
24416+ }
24417+
24418+ /* remember last position */
24419+ adev->tx_tail = finger;
24420+/* end: */
24421+ FN_EXIT1(num_cleaned);
24422+ return num_cleaned;
24423+}
24424+
24425+/* clean *all* Tx descriptors, and regardless of their previous state.
24426+ * Used for brute-force reset handling. */
24427+void
24428+acxmem_l_clean_txdesc_emergency(acx_device_t *adev)
24429+{
24430+ txdesc_t *txdesc;
24431+ int i;
24432+ u32 acxmem;
24433+
24434+ FN_ENTER;
24435+
24436+ for (i = 0; i < TX_CNT; i++) {
24437+ txdesc = get_txdesc(adev, i);
24438+
24439+ /* free it */
24440+ write_slavemem8 (adev, (u32) &(txdesc->ack_failures), 0);
24441+ write_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_failures), 0);
24442+ write_slavemem8 (adev, (u32) &(txdesc->u.rts.rts_ok), 0);
24443+ write_slavemem8 (adev, (u32) &(txdesc->error), 0);
24444+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8), DESC_CTL_HOSTOWN);
24445+
24446+ /*
24447+ * Clean up the memory allocated on the ACX for this transmit descriptor.
24448+ */
24449+ acxmem = read_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr));
24450+ if (acxmem) {
24451+ reclaim_acx_txbuf_space (adev, acxmem);
24452+ }
24453+
24454+ write_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr), 0);
24455+ }
24456+
24457+ adev->tx_free = TX_CNT;
24458+
24459+ FN_EXIT0;
24460+}
24461+
24462+
24463+/***********************************************************************
24464+** acxmem_s_create_tx_host_desc_queue
24465+*/
24466+
24467+static void*
24468+allocate(acx_device_t *adev, size_t size, dma_addr_t *phy, const char *msg)
24469+{
24470+ void *ptr;
24471+ ptr = kmalloc (size, GFP_KERNEL);
24472+ /*
24473+ * The ACX can't use the physical address, so we'll have to fake it
24474+ * later and it might be handy to have the virtual address.
24475+ */
24476+ *phy = (dma_addr_t) NULL;
24477+
24478+ if (ptr) {
24479+ log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n",
24480+ msg, (int)size, ptr, (unsigned long long)*phy);
24481+ memset(ptr, 0, size);
24482+ return ptr;
24483+ }
24484+ printk(KERN_ERR "acx: %s allocation FAILED (%d bytes)\n",
24485+ msg, (int)size);
24486+ return NULL;
24487+}
24488+
24489+
24490+/*
24491+ * In the generic slave memory access mode, most of the stuff in
24492+ * the txhostdesc_t is unused. It's only here because the rest of
24493+ * the ACX driver expects it to be since the PCI version uses indirect
24494+ * host memory organization with DMA. Since we're not using DMA the
24495+ * only use we have for the host descriptors is to store the packets
24496+ * on the way out.
24497+ */
24498+static int
24499+acxmem_s_create_tx_host_desc_queue(acx_device_t *adev)
24500+{
24501+ txhostdesc_t *hostdesc;
24502+ u8 *txbuf;
24503+ int i;
24504+
24505+ FN_ENTER;
24506+
24507+ /* allocate TX buffer */
24508+ adev->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS;
24509+
24510+ adev->txbuf_start = allocate(adev, adev->txbuf_area_size,
24511+ &adev->txbuf_startphy, "txbuf_start");
24512+ if (!adev->txbuf_start)
24513+ goto fail;
24514+
24515+ /* allocate the TX host descriptor queue pool */
24516+ adev->txhostdesc_area_size = TX_CNT * 2*sizeof(*hostdesc);
24517+
24518+ adev->txhostdesc_start = allocate(adev, adev->txhostdesc_area_size,
24519+ &adev->txhostdesc_startphy, "txhostdesc_start");
24520+ if (!adev->txhostdesc_start)
24521+ goto fail;
24522+
24523+ /* check for proper alignment of TX host descriptor pool */
24524+ if ((long) adev->txhostdesc_start & 3) {
24525+ printk("acx: driver bug: dma alloc returns unaligned address\n");
24526+ goto fail;
24527+ }
24528+
24529+ hostdesc = adev->txhostdesc_start;
24530+ txbuf = adev->txbuf_start;
24531+
24532+#if 0
24533+/* Each tx buffer is accessed by hardware via
24534+** txdesc -> txhostdesc(s) -> txbuffer(s).
24535+** We use only one txhostdesc per txdesc, but it looks like
24536+** acx111 is buggy: it accesses second txhostdesc
24537+** (via hostdesc.desc_phy_next field) even if
24538+** txdesc->length == hostdesc->length and thus
24539+** entire packet was placed into first txhostdesc.
24540+** Due to this bug acx111 hangs unless second txhostdesc
24541+** has le16_to_cpu(hostdesc.length) = 3 (or larger)
24542+** Storing NULL into hostdesc.desc_phy_next
24543+** doesn't seem to help.
24544+**
24545+** Update: although it worked on Xterasys XN-2522g
24546+** with len=3 trick, WG311v2 is even more bogus, doesn't work.
24547+** Keeping this code (#ifdef'ed out) for documentational purposes.
24548+*/
24549+ for (i = 0; i < TX_CNT*2; i++) {
24550+ hostdesc_phy += sizeof(*hostdesc);
24551+ if (!(i & 1)) {
24552+ hostdesc->data_phy = cpu2acx(txbuf_phy);
24553+ /* hostdesc->data_offset = ... */
24554+ /* hostdesc->reserved = ... */
24555+ hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN);
24556+ /* hostdesc->length = ... */
24557+ hostdesc->desc_phy_next = cpu2acx(hostdesc_phy);
24558+ hostdesc->pNext = ptr2acx(NULL);
24559+ /* hostdesc->Status = ... */
24560+ /* below: non-hardware fields */
24561+ hostdesc->data = txbuf;
24562+
24563+ txbuf += WLAN_A4FR_MAXLEN_WEP_FCS;
24564+ txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS;
24565+ } else {
24566+ /* hostdesc->data_phy = ... */
24567+ /* hostdesc->data_offset = ... */
24568+ /* hostdesc->reserved = ... */
24569+ /* hostdesc->Ctl_16 = ... */
24570+ hostdesc->length = cpu_to_le16(3); /* bug workaround */
24571+ /* hostdesc->desc_phy_next = ... */
24572+ /* hostdesc->pNext = ... */
24573+ /* hostdesc->Status = ... */
24574+ /* below: non-hardware fields */
24575+ /* hostdesc->data = ... */
24576+ }
24577+ hostdesc++;
24578+ }
24579+#endif
24580+/* We initialize two hostdescs so that they point to adjacent
24581+** memory areas. Thus txbuf is really just a contiguous memory area */
24582+ for (i = 0; i < TX_CNT*2; i++) {
24583+ /* ->data is a non-hardware field: */
24584+ hostdesc->data = txbuf;
24585+
24586+ if (!(i & 1)) {
24587+ txbuf += WLAN_HDR_A3_LEN;
24588+ } else {
24589+ txbuf += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN;
24590+ }
24591+ hostdesc++;
24592+ }
24593+ hostdesc--;
24594+
24595+ FN_EXIT1(OK);
24596+ return OK;
24597+fail:
24598+ printk("acx: create_tx_host_desc_queue FAILED\n");
24599+ /* dealloc will be done by free function on error case */
24600+ FN_EXIT1(NOT_OK);
24601+ return NOT_OK;
24602+}
24603+
24604+
24605+/***************************************************************
24606+** acxmem_s_create_rx_host_desc_queue
24607+*/
24608+/* the whole size of a data buffer (header plus data body)
24609+ * plus 32 bytes safety offset at the end */
24610+#define RX_BUFFER_SIZE (sizeof(rxbuffer_t) + 32)
24611+
24612+static int
24613+acxmem_s_create_rx_host_desc_queue(acx_device_t *adev)
24614+{
24615+ rxhostdesc_t *hostdesc;
24616+ rxbuffer_t *rxbuf;
24617+ int i;
24618+
24619+ FN_ENTER;
24620+
24621+ /* allocate the RX host descriptor queue pool */
24622+ adev->rxhostdesc_area_size = RX_CNT * sizeof(*hostdesc);
24623+
24624+ adev->rxhostdesc_start = allocate(adev, adev->rxhostdesc_area_size,
24625+ &adev->rxhostdesc_startphy, "rxhostdesc_start");
24626+ if (!adev->rxhostdesc_start)
24627+ goto fail;
24628+
24629+ /* check for proper alignment of RX host descriptor pool */
24630+ if ((long) adev->rxhostdesc_start & 3) {
24631+ printk("acx: driver bug: dma alloc returns unaligned address\n");
24632+ goto fail;
24633+ }
24634+
24635+ /* allocate Rx buffer pool which will be used by the acx
24636+ * to store the whole content of the received frames in it */
24637+ adev->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE;
24638+
24639+ adev->rxbuf_start = allocate(adev, adev->rxbuf_area_size,
24640+ &adev->rxbuf_startphy, "rxbuf_start");
24641+ if (!adev->rxbuf_start)
24642+ goto fail;
24643+
24644+ rxbuf = adev->rxbuf_start;
24645+ hostdesc = adev->rxhostdesc_start;
24646+
24647+ /* don't make any popular C programming pointer arithmetic mistakes
24648+ * here, otherwise I'll kill you...
24649+ * (and don't dare asking me why I'm warning you about that...) */
24650+ for (i = 0; i < RX_CNT; i++) {
24651+ hostdesc->data = rxbuf;
24652+ hostdesc->length = cpu_to_le16(RX_BUFFER_SIZE);
24653+ rxbuf++;
24654+ hostdesc++;
24655+ }
24656+ hostdesc--;
24657+ FN_EXIT1(OK);
24658+ return OK;
24659+fail:
24660+ printk("acx: create_rx_host_desc_queue FAILED\n");
24661+ /* dealloc will be done by free function on error case */
24662+ FN_EXIT1(NOT_OK);
24663+ return NOT_OK;
24664+}
24665+
24666+
24667+/***************************************************************
24668+** acxmem_s_create_hostdesc_queues
24669+*/
24670+int
24671+acxmem_s_create_hostdesc_queues(acx_device_t *adev)
24672+{
24673+ int result;
24674+ result = acxmem_s_create_tx_host_desc_queue(adev);
24675+ if (OK != result) return result;
24676+ result = acxmem_s_create_rx_host_desc_queue(adev);
24677+ return result;
24678+}
24679+
24680+
24681+/***************************************************************
24682+** acxmem_create_tx_desc_queue
24683+*/
24684+static void
24685+acxmem_create_tx_desc_queue(acx_device_t *adev, u32 tx_queue_start)
24686+{
24687+ txdesc_t *txdesc;
24688+ u32 clr;
24689+ int i;
24690+
24691+ FN_ENTER;
24692+
24693+ if (IS_ACX100(adev))
24694+ adev->txdesc_size = sizeof(*txdesc);
24695+ else
24696+ /* the acx111 txdesc is 4 bytes larger */
24697+ adev->txdesc_size = sizeof(*txdesc) + 4;
24698+
24699+ /*
24700+ * This refers to an ACX address, not one of ours
24701+ */
24702+ adev->txdesc_start = (txdesc_t *) tx_queue_start;
24703+
24704+ log(L_DEBUG, "adev->txdesc_start=%p\n",
24705+ adev->txdesc_start);
24706+
24707+ adev->tx_free = TX_CNT;
24708+ /* done by memset: adev->tx_head = 0; */
24709+ /* done by memset: adev->tx_tail = 0; */
24710+ txdesc = adev->txdesc_start;
24711+
24712+ if (IS_ACX111(adev)) {
24713+ /* ACX111 has a preinitialized Tx buffer! */
24714+ /* loop over whole send pool */
24715+ /* FIXME: do we have to do the hostmemptr stuff here?? */
24716+ for (i = 0; i < TX_CNT; i++) {
24717+ txdesc->Ctl_8 = DESC_CTL_HOSTOWN;
24718+ /* reserve two (hdr desc and payload desc) */
24719+ txdesc = advance_txdesc(adev, txdesc, 1);
24720+ }
24721+ } else {
24722+ /* ACX100 Tx buffer needs to be initialized by us */
24723+ /* clear whole send pool. sizeof is safe here (we are acx100) */
24724+
24725+ /*
24726+ * adev->txdesc_start refers to device memory, so we can't write
24727+ * directly to it.
24728+ */
24729+ clr = (u32) adev->txdesc_start;
24730+ while (clr < (u32) adev->txdesc_start + (TX_CNT * sizeof(*txdesc))) {
24731+ write_slavemem32 (adev, clr, 0);
24732+ clr += 4;
24733+ }
24734+
24735+ /* loop over whole send pool */
24736+ for (i = 0; i < TX_CNT; i++) {
24737+ log(L_DEBUG, "configure card tx descriptor: 0x%p, "
24738+ "size: 0x%X\n", txdesc, adev->txdesc_size);
24739+
24740+ /* initialise ctl */
24741+ /*
24742+ * No auto DMA here
24743+ */
24744+ write_slavemem8 (adev, (u32) &(txdesc->Ctl_8),
24745+ (u8) (DESC_CTL_HOSTOWN | DESC_CTL_FIRSTFRAG));
24746+ /* done by memset(0): txdesc->Ctl2_8 = 0; */
24747+
24748+ /* point to next txdesc */
24749+ write_slavemem32 (adev, (u32) &(txdesc->pNextDesc),
24750+ (u32) cpu_to_le32 ((u8 *) txdesc + adev->txdesc_size));
24751+
24752+ /* go to the next one */
24753+ /* ++ is safe here (we are acx100) */
24754+ txdesc++;
24755+ }
24756+ /* go back to the last one */
24757+ txdesc--;
24758+ /* and point to the first making it a ring buffer */
24759+ write_slavemem32 (adev, (u32) &(txdesc->pNextDesc),
24760+ (u32) cpu_to_le32 (tx_queue_start));
24761+ }
24762+ FN_EXIT0;
24763+}
24764+
24765+
24766+/***************************************************************
24767+** acxmem_create_rx_desc_queue
24768+*/
24769+static void
24770+acxmem_create_rx_desc_queue(acx_device_t *adev, u32 rx_queue_start)
24771+{
24772+ rxdesc_t *rxdesc;
24773+ u32 mem_offs;
24774+ int i;
24775+
24776+ FN_ENTER;
24777+
24778+ /* done by memset: adev->rx_tail = 0; */
24779+
24780+ /* ACX111 doesn't need any further config: preconfigures itself.
24781+ * Simply print ring buffer for debugging */
24782+ if (IS_ACX111(adev)) {
24783+ /* rxdesc_start already set here */
24784+
24785+ adev->rxdesc_start = (rxdesc_t *) rx_queue_start;
24786+
24787+ rxdesc = adev->rxdesc_start;
24788+ for (i = 0; i < RX_CNT; i++) {
24789+ log(L_DEBUG, "rx descriptor %d @ 0x%p\n", i, rxdesc);
24790+ rxdesc = adev->rxdesc_start = (rxdesc_t *)
24791+ acx2cpu(rxdesc->pNextDesc);
24792+ }
24793+ } else {
24794+ /* we didn't pre-calculate rxdesc_start in case of ACX100 */
24795+ /* rxdesc_start should be right AFTER Tx pool */
24796+ adev->rxdesc_start = (rxdesc_t *)
24797+ ((u8 *) adev->txdesc_start + (TX_CNT * sizeof(txdesc_t)));
24798+ /* NB: sizeof(txdesc_t) above is valid because we know
24799+ ** we are in if (acx100) block. Beware of cut-n-pasting elsewhere!
24800+ ** acx111's txdesc is larger! */
24801+
24802+ mem_offs = (u32) adev->rxdesc_start;
24803+ while (mem_offs < (u32) adev->rxdesc_start + (RX_CNT * sizeof (*rxdesc))) {
24804+ write_slavemem32 (adev, mem_offs, 0);
24805+ mem_offs += 4;
24806+ }
24807+
24808+ /* loop over whole receive pool */
24809+ rxdesc = adev->rxdesc_start;
24810+ for (i = 0; i < RX_CNT; i++) {
24811+ log(L_DEBUG, "rx descriptor @ 0x%p\n", rxdesc);
24812+ /* point to next rxdesc */
24813+ write_slavemem32 (adev, (u32) &(rxdesc->pNextDesc),
24814+ (u32) cpu_to_le32 ((u8 *) rxdesc + sizeof(*rxdesc)));
24815+ /* go to the next one */
24816+ rxdesc++;
24817+ }
24818+ /* go to the last one */
24819+ rxdesc--;
24820+
24821+ /* and point to the first making it a ring buffer */
24822+ write_slavemem32 (adev, (u32) &(rxdesc->pNextDesc),
24823+ (u32) cpu_to_le32 (rx_queue_start));
24824+ }
24825+ FN_EXIT0;
24826+}
24827+
24828+
24829+/***************************************************************
24830+** acxmem_create_desc_queues
24831+*/
24832+void
24833+acxmem_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start)
24834+{
24835+ u32 *p;
24836+ int i;
24837+
24838+ acxmem_create_tx_desc_queue(adev, tx_queue_start);
24839+ acxmem_create_rx_desc_queue(adev, rx_queue_start);
24840+ p = (u32 *) adev->acx_queue_indicator;
24841+ for (i = 0; i < 4; i++) {
24842+ write_slavemem32 (adev, (u32) p, 0);
24843+ p++;
24844+ }
24845+}
24846+
24847+
24848+/***************************************************************
24849+** acxmem_s_proc_diag_output
24850+*/
24851+char*
24852+acxmem_s_proc_diag_output(char *p, acx_device_t *adev)
24853+{
24854+ const char *rtl, *thd, *ttl;
24855+ txdesc_t *txdesc;
24856+ u8 Ctl_8;
24857+ rxdesc_t *rxdesc;
24858+ int i;
24859+ u32 tmp;
24860+ txdesc_t txd;
24861+ u8 buf[0x200];
24862+ int j, k;
24863+
24864+ FN_ENTER;
24865+
24866+#if DUMP_MEM_DURING_DIAG > 0
24867+ dump_acxmem (adev, 0, 0x10000);
24868+ panic ("dump finished");
24869+#endif
24870+
24871+ p += sprintf(p, "** Rx buf **\n");
24872+ rxdesc = adev->rxdesc_start;
24873+ if (rxdesc) for (i = 0; i < RX_CNT; i++) {
24874+ rtl = (i == adev->rx_tail) ? " [tail]" : "";
24875+ Ctl_8 = read_slavemem8 (adev, (u32) &(rxdesc->Ctl_8));
24876+ if (Ctl_8 & DESC_CTL_HOSTOWN)
24877+ p += sprintf(p, "%02u (%02x) FULL%s\n", i, Ctl_8, rtl);
24878+ else
24879+ p += sprintf(p, "%02u (%02x) empty%s\n", i, Ctl_8, rtl);
24880+ rxdesc++;
24881+ }
24882+ p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", adev->tx_free,
24883+ acx_queue_stopped(adev->ndev) ? "STOPPED" : "running");
24884+
24885+ p += sprintf(p, "** Tx buf %d blocks total, %d available, free list head %04x\n",
24886+ adev->acx_txbuf_numblocks, adev->acx_txbuf_blocks_free, adev->acx_txbuf_free);
24887+ txdesc = adev->txdesc_start;
24888+ if (txdesc) {
24889+ for (i = 0; i < TX_CNT; i++) {
24890+ thd = (i == adev->tx_head) ? " [head]" : "";
24891+ ttl = (i == adev->tx_tail) ? " [tail]" : "";
24892+ copy_from_slavemem (adev, (u8 *) &txd, (u32) txdesc, sizeof (txd));
24893+ Ctl_8 = read_slavemem8 (adev, (u32) &(txdesc->Ctl_8));
24894+ if (Ctl_8 & DESC_CTL_ACXDONE)
24895+ p += sprintf(p, "%02u ready to free (%02X)%s%s", i, Ctl_8, thd, ttl);
24896+ else if (Ctl_8 & DESC_CTL_HOSTOWN)
24897+ p += sprintf(p, "%02u available (%02X)%s%s", i, Ctl_8, thd, ttl);
24898+ else
24899+ p += sprintf(p, "%02u busy (%02X)%s%s", i, Ctl_8, thd, ttl);
24900+ tmp = read_slavemem32 (adev, (u32) &(txdesc->AcxMemPtr));
24901+ if (tmp) {
24902+ p += sprintf (p, " %04x", tmp);
24903+ while ((tmp = read_slavemem32 (adev, (u32) tmp)) != 0x02000000) {
24904+ tmp <<= 5;
24905+ p += sprintf (p, " %04x", tmp);
24906+ }
24907+ }
24908+ p += sprintf (p, "\n");
24909+ p += sprintf (p, " %04x: %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %02x %02x %02x %02x\n"
24910+ "%02x %02x %02x %02x %04x\n",
24911+ (u32) txdesc,
24912+ txd.pNextDesc.v, txd.HostMemPtr.v, txd.AcxMemPtr.v, txd.tx_time,
24913+ txd.total_length, txd.Reserved,
24914+ txd.dummy[0], txd.dummy[1], txd.dummy[2], txd.dummy[3],
24915+ txd.Ctl_8, txd.Ctl2_8, txd.error, txd.ack_failures,
24916+ txd.u.rts.rts_failures, txd.u.rts.rts_ok, txd.u.r1.rate, txd.u.r1.queue_ctrl,
24917+ txd.queue_info
24918+ );
24919+ if (txd.AcxMemPtr.v) {
24920+ copy_from_slavemem (adev, buf, txd.AcxMemPtr.v, sizeof (buf));
24921+ for (j = 0; (j < txd.total_length) && (j<(sizeof(buf)-4)); j+=16) {
24922+ p += sprintf (p, " ");
24923+ for (k = 0; (k < 16) && (j+k < txd.total_length); k++) {
24924+ p += sprintf (p, " %02x", buf[j+k+4]);
24925+ }
24926+ p += sprintf (p, "\n");
24927+ }
24928+ }
24929+ txdesc = advance_txdesc(adev, txdesc, 1);
24930+ }
24931+ }
24932+
24933+ p += sprintf(p,
24934+ "\n"
24935+ "** Generic slave data **\n"
24936+ "irq_mask 0x%04x irq_status 0x%04x irq on acx 0x%04x\n"
24937+ "txbuf_start 0x%p, txbuf_area_size %u\n"
24938+ "txdesc_size %u, txdesc_start 0x%p\n"
24939+ "txhostdesc_start 0x%p, txhostdesc_area_size %u\n"
24940+ "txbuf start 0x%04x, txbuf size %d\n"
24941+ "rxdesc_start 0x%p\n"
24942+ "rxhostdesc_start 0x%p, rxhostdesc_area_size %u\n"
24943+ "rxbuf_start 0x%p, rxbuf_area_size %u\n",
24944+ adev->irq_mask, adev->irq_status, read_reg32(adev, IO_ACX_IRQ_STATUS_NON_DES),
24945+ adev->txbuf_start, adev->txbuf_area_size,
24946+ adev->txdesc_size, adev->txdesc_start,
24947+ adev->txhostdesc_start, adev->txhostdesc_area_size,
24948+ adev->acx_txbuf_start, adev->acx_txbuf_numblocks * adev->memblocksize,
24949+ adev->rxdesc_start,
24950+ adev->rxhostdesc_start, adev->rxhostdesc_area_size,
24951+ adev->rxbuf_start, adev->rxbuf_area_size);
24952+ FN_EXIT0;
24953+ return p;
24954+}
24955+
24956+
24957+/***********************************************************************
24958+*/
24959+int
24960+acxmem_proc_eeprom_output(char *buf, acx_device_t *adev)
24961+{
24962+ char *p = buf;
24963+ int i;
24964+
24965+ FN_ENTER;
24966+
24967+ for (i = 0; i < 0x400; i++) {
24968+ acxmem_read_eeprom_byte(adev, i, p++);
24969+ }
24970+
24971+ FN_EXIT1(p - buf);
24972+ return p - buf;
24973+}
24974+
24975+
24976+/***********************************************************************
24977+*/
24978+void
24979+acxmem_set_interrupt_mask(acx_device_t *adev)
24980+{
24981+ if (IS_ACX111(adev)) {
24982+ adev->irq_mask = (u16) ~(0
24983+ | HOST_INT_RX_DATA
24984+ | HOST_INT_TX_COMPLETE
24985+ /* | HOST_INT_TX_XFER */
24986+ /* | HOST_INT_RX_COMPLETE */
24987+ /* | HOST_INT_DTIM */
24988+ /* | HOST_INT_BEACON */
24989+ /* | HOST_INT_TIMER */
24990+ /* | HOST_INT_KEY_NOT_FOUND */
24991+ | HOST_INT_IV_ICV_FAILURE
24992+ | HOST_INT_CMD_COMPLETE
24993+ | HOST_INT_INFO
24994+ | HOST_INT_OVERFLOW
24995+ /* | HOST_INT_PROCESS_ERROR */
24996+ | HOST_INT_SCAN_COMPLETE
24997+ | HOST_INT_FCS_THRESHOLD
24998+ | HOST_INT_UNKNOWN
24999+ );
25000+ /* Or else acx100 won't signal cmd completion, right? */
25001+ adev->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */
25002+ } else {
25003+ adev->irq_mask = (u16) ~(0
25004+ | HOST_INT_RX_DATA
25005+ | HOST_INT_TX_COMPLETE
25006+ /* | HOST_INT_TX_XFER */
25007+ /* | HOST_INT_RX_COMPLETE */
25008+ /* | HOST_INT_DTIM */
25009+ /* | HOST_INT_BEACON */
25010+ /* | HOST_INT_TIMER */
25011+ /* | HOST_INT_KEY_NOT_FOUND */
25012+ /* | HOST_INT_IV_ICV_FAILURE */
25013+ | HOST_INT_CMD_COMPLETE
25014+ | HOST_INT_INFO
25015+ /* | HOST_INT_OVERFLOW */
25016+ /* | HOST_INT_PROCESS_ERROR */
25017+ | HOST_INT_SCAN_COMPLETE
25018+ /* | HOST_INT_FCS_THRESHOLD */
25019+ /* | HOST_INT_BEACON_MISSED */
25020+ );
25021+ adev->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */
25022+ }
25023+}
25024+
25025+
25026+/***********************************************************************
25027+*/
25028+int
25029+acx100mem_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
25030+{
25031+ struct acx111_ie_tx_level tx_level;
25032+
25033+ /* since it can be assumed that at least the Maxim radio has a
25034+ * maximum power output of 20dBm and since it also can be
25035+ * assumed that these values drive the DAC responsible for
25036+ * setting the linear Tx level, I'd guess that these values
25037+ * should be the corresponding linear values for a dBm value,
25038+ * in other words: calculate the values from that formula:
25039+ * Y [dBm] = 10 * log (X [mW])
25040+ * then scale the 0..63 value range onto the 1..100mW range (0..20 dBm)
25041+ * and you're done...
25042+ * Hopefully that's ok, but you never know if we're actually
25043+ * right... (especially since Windows XP doesn't seem to show
25044+ * actual Tx dBm values :-P) */
25045+
25046+ /* NOTE: on Maxim, value 30 IS 30mW, and value 10 IS 10mW - so the
25047+ * values are EXACTLY mW!!! Not sure about RFMD and others,
25048+ * though... */
25049+ static const u8 dbm2val_maxim[21] = {
25050+ 63, 63, 63, 62,
25051+ 61, 61, 60, 60,
25052+ 59, 58, 57, 55,
25053+ 53, 50, 47, 43,
25054+ 38, 31, 23, 13,
25055+ 0
25056+ };
25057+ static const u8 dbm2val_rfmd[21] = {
25058+ 0, 0, 0, 1,
25059+ 2, 2, 3, 3,
25060+ 4, 5, 6, 8,
25061+ 10, 13, 16, 20,
25062+ 25, 32, 41, 50,
25063+ 63
25064+ };
25065+ const u8 *table;
25066+
25067+ switch (adev->radio_type) {
25068+ case RADIO_MAXIM_0D:
25069+ table = &dbm2val_maxim[0];
25070+ break;
25071+ case RADIO_RFMD_11:
25072+ case RADIO_RALINK_15:
25073+ table = &dbm2val_rfmd[0];
25074+ break;
25075+ default:
25076+ printk("%s: unknown/unsupported radio type, "
25077+ "cannot modify tx power level yet!\n",
25078+ adev->ndev->name);
25079+ return NOT_OK;
25080+ }
25081+ /*
25082+ * The hx4700 EEPROM, at least, only supports 1 power setting. The configure
25083+ * routine matches the PA bias with the gain, so just use its default value.
25084+ * The values are: 0x2b for the gain and 0x03 for the PA bias. The firmware
25085+ * writes the gain level to the Tx gain control DAC and the PA bias to the Maxim
25086+ * radio's PA bias register. The firmware limits itself to 0 - 64 when writing to the
25087+ * gain control DAC.
25088+ *
25089+ * Physically between the ACX and the radio, higher Tx gain control DAC values result
25090+ * in less power output; 0 volts to the Maxim radio results in the highest output power
25091+ * level, which I'm assuming matches up with 0 in the Tx Gain DAC register.
25092+ *
25093+ * Although there is only the 1 power setting, one of the radio firmware functions adjusts
25094+ * the transmit power level up and down. That function is called by the ACX FIQ handler
25095+ * under certain conditions.
25096+ */
25097+ tx_level.level = 1;
25098+ //return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL);
25099+
25100+ printk("%s: changing radio power level to %u dBm (%u)\n",
25101+ adev->ndev->name, level_dbm, table[level_dbm]);
25102+ acxmem_s_write_phy_reg(adev, 0x11, table[level_dbm]);
25103+
25104+ return 0;
25105+}
25106+
25107+
25108+static struct platform_driver
25109+acxmem_drv_id = {
25110+ .driver = {
25111+ .name = "acx-mem",
25112+ },
25113+ .probe = acxmem_e_probe,
25114+ .remove = __devexit_p(acxmem_e_remove),
25115+#ifdef CONFIG_PM
25116+ .suspend = acxmem_e_suspend,
25117+ .resume = acxmem_e_resume
25118+#endif /* CONFIG_PM */
25119+};
25120+
25121+
25122+/***********************************************************************
25123+** acxmem_e_init_module
25124+**
25125+** Module initialization routine, called once at module load time
25126+*/
25127+int __init
25128+acxmem_e_init_module(void)
25129+{
25130+ int res;
25131+
25132+ FN_ENTER;
25133+
25134+#if (ACX_IO_WIDTH==32)
25135+ printk("acx: compiled to use 32bit I/O access. "
25136+ "I/O timing issues might occur, such as "
25137+ "non-working firmware upload. Report them\n");
25138+#else
25139+ printk("acx: compiled to use 16bit I/O access only "
25140+ "(compatibility mode)\n");
25141+#endif
25142+
25143+#ifdef __LITTLE_ENDIAN
25144+#define ENDIANNESS_STRING "running on a little-endian CPU\n"
25145+#else
25146+#define ENDIANNESS_STRING "running on a BIG-ENDIAN CPU\n"
25147+#endif
25148+ log(L_INIT,
25149+ ENDIANNESS_STRING
25150+ "PCI module " ACX_RELEASE " initialized, "
25151+ "waiting for cards to probe...\n"
25152+ );
25153+
25154+ res = platform_driver_register (&acxmem_drv_id);
25155+ FN_EXIT1(res);
25156+ return res;
25157+}
25158+
25159+
25160+/***********************************************************************
25161+** acxmem_e_cleanup_module
25162+**
25163+** Called at module unload time. This is our last chance to
25164+** clean up after ourselves.
25165+*/
25166+void __exit
25167+acxmem_e_cleanup_module(void)
25168+{
25169+ FN_ENTER;
25170+
25171+ printk ("cleanup_module\n");
25172+ platform_driver_unregister( &acxmem_drv_id );
25173+
25174+ FN_EXIT0;
25175+}
25176+
25177+void acxmem_e_release(struct device *dev) {
25178+}
25179+
25180+MODULE_AUTHOR( "Todd Blumer <todd@sdgsystems.com>" );
25181+MODULE_DESCRIPTION( "ACX Slave Memory Driver" );
25182+MODULE_LICENSE( "GPL" );
25183+
25184Index: linux-2.6.22/drivers/net/wireless/acx/pci.c
25185===================================================================
25186--- /dev/null 1970-01-01 00:00:00.000000000 +0000
25187+++ linux-2.6.22/drivers/net/wireless/acx/pci.c 2007-08-23 18:34:19.000000000 +0200
25188@@ -0,0 +1,4234 @@
25189+/***********************************************************************
25190+** Copyright (C) 2003 ACX100 Open Source Project
25191+**
25192+** The contents of this file are subject to the Mozilla Public
25193+** License Version 1.1 (the "License"); you may not use this file
25194+** except in compliance with the License. You may obtain a copy of
25195+** the License at http://www.mozilla.org/MPL/
25196+**
25197+** Software distributed under the License is distributed on an "AS
25198+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
25199+** implied. See the License for the specific language governing
25200+** rights and limitations under the License.
25201+**
25202+** Alternatively, the contents of this file may be used under the
25203+** terms of the GNU Public License version 2 (the "GPL"), in which
25204+** case the provisions of the GPL are applicable instead of the
25205+** above. If you wish to allow the use of your version of this file
25206+** only under the terms of the GPL and not to allow others to use
25207+** your version of this file under the MPL, indicate your decision
25208+** by deleting the provisions above and replace them with the notice
25209+** and other provisions required by the GPL. If you do not delete
25210+** the provisions above, a recipient may use your version of this
25211+** file under either the MPL or the GPL.
25212+** ---------------------------------------------------------------------
25213+** Inquiries regarding the ACX100 Open Source Project can be
25214+** made directly to:
25215+**
25216+** acx100-users@lists.sf.net
25217+** http://acx100.sf.net
25218+** ---------------------------------------------------------------------
25219+*/
25220+#define ACX_PCI 1
25221+
25222+#include <linux/version.h>
25223+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
25224+#include <linux/config.h>
25225+#endif
25226+
25227+/* Linux 2.6.18+ uses <linux/utsrelease.h> */
25228+#ifndef UTS_RELEASE
25229+#include <linux/utsrelease.h>
25230+#endif
25231+
25232+#include <linux/compiler.h> /* required for Lx 2.6.8 ?? */
25233+#include <linux/kernel.h>
25234+#include <linux/module.h>
25235+#include <linux/moduleparam.h>
25236+#include <linux/sched.h>
25237+#include <linux/types.h>
25238+#include <linux/skbuff.h>
25239+#include <linux/slab.h>
25240+#include <linux/if_arp.h>
25241+#include <linux/rtnetlink.h>
25242+#include <linux/wireless.h>
25243+#include <net/iw_handler.h>
25244+#include <linux/netdevice.h>
25245+#include <linux/ioport.h>
25246+#include <linux/pci.h>
25247+#include <linux/pm.h>
25248+#include <linux/vmalloc.h>
25249+#include <linux/dma-mapping.h>
25250+
25251+#include "acx.h"
25252+
25253+
25254+/***********************************************************************
25255+*/
25256+#define PCI_TYPE (PCI_USES_MEM | PCI_ADDR0 | PCI_NO_ACPI_WAKE)
25257+#define PCI_ACX100_REGION1 0x01
25258+#define PCI_ACX100_REGION1_SIZE 0x1000 /* Memory size - 4K bytes */
25259+#define PCI_ACX100_REGION2 0x02
25260+#define PCI_ACX100_REGION2_SIZE 0x10000 /* Memory size - 64K bytes */
25261+
25262+#define PCI_ACX111_REGION1 0x00
25263+#define PCI_ACX111_REGION1_SIZE 0x2000 /* Memory size - 8K bytes */
25264+#define PCI_ACX111_REGION2 0x01
25265+#define PCI_ACX111_REGION2_SIZE 0x20000 /* Memory size - 128K bytes */
25266+
25267+/* Texas Instruments Vendor ID */
25268+#define PCI_VENDOR_ID_TI 0x104c
25269+
25270+/* ACX100 22Mb/s WLAN controller */
25271+#define PCI_DEVICE_ID_TI_TNETW1100A 0x8400
25272+#define PCI_DEVICE_ID_TI_TNETW1100B 0x8401
25273+
25274+/* ACX111 54Mb/s WLAN controller */
25275+#define PCI_DEVICE_ID_TI_TNETW1130 0x9066
25276+
25277+/* PCI Class & Sub-Class code, Network-'Other controller' */
25278+#define PCI_CLASS_NETWORK_OTHERS 0x0280
25279+
25280+#define CARD_EEPROM_ID_SIZE 6
25281+
25282+#ifndef PCI_D0
25283+/* From include/linux/pci.h */
25284+#define PCI_D0 0
25285+#define PCI_D1 1
25286+#define PCI_D2 2
25287+#define PCI_D3hot 3
25288+#define PCI_D3cold 4
25289+#define PCI_UNKNOWN 5
25290+#define PCI_POWER_ERROR -1
25291+#endif
25292+
25293+
25294+/***********************************************************************
25295+*/
25296+static void acxpci_i_tx_timeout(struct net_device *ndev);
25297+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
25298+static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id);
25299+#else
25300+static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
25301+#endif
25302+static void acxpci_i_set_multicast_list(struct net_device *ndev);
25303+
25304+static int acxpci_e_open(struct net_device *ndev);
25305+static int acxpci_e_close(struct net_device *ndev);
25306+static void acxpci_s_up(struct net_device *ndev);
25307+static void acxpci_s_down(struct net_device *ndev);
25308+
25309+
25310+/***********************************************************************
25311+** Register access
25312+*/
25313+
25314+/* Pick one */
25315+/* #define INLINE_IO static */
25316+#define INLINE_IO static inline
25317+
25318+INLINE_IO u32
25319+read_reg32(acx_device_t *adev, unsigned int offset)
25320+{
25321+#if ACX_IO_WIDTH == 32
25322+ return readl((u8 *)adev->iobase + adev->io[offset]);
25323+#else
25324+ return readw((u8 *)adev->iobase + adev->io[offset])
25325+ + (readw((u8 *)adev->iobase + adev->io[offset] + 2) << 16);
25326+#endif
25327+}
25328+
25329+INLINE_IO u16
25330+read_reg16(acx_device_t *adev, unsigned int offset)
25331+{
25332+ return readw((u8 *)adev->iobase + adev->io[offset]);
25333+}
25334+
25335+INLINE_IO u8
25336+read_reg8(acx_device_t *adev, unsigned int offset)
25337+{
25338+ return readb((u8 *)adev->iobase + adev->io[offset]);
25339+}
25340+
25341+INLINE_IO void
25342+write_reg32(acx_device_t *adev, unsigned int offset, u32 val)
25343+{
25344+#if ACX_IO_WIDTH == 32
25345+ writel(val, (u8 *)adev->iobase + adev->io[offset]);
25346+#else
25347+ writew(val & 0xffff, (u8 *)adev->iobase + adev->io[offset]);
25348+ writew(val >> 16, (u8 *)adev->iobase + adev->io[offset] + 2);
25349+#endif
25350+}
25351+
25352+INLINE_IO void
25353+write_reg16(acx_device_t *adev, unsigned int offset, u16 val)
25354+{
25355+ writew(val, (u8 *)adev->iobase + adev->io[offset]);
25356+}
25357+
25358+INLINE_IO void
25359+write_reg8(acx_device_t *adev, unsigned int offset, u8 val)
25360+{
25361+ writeb(val, (u8 *)adev->iobase + adev->io[offset]);
25362+}
25363+
25364+/* Handle PCI posting properly:
25365+ * Make sure that writes reach the adapter in case they require to be executed
25366+ * *before* the next write, by reading a random (and safely accessible) register.
25367+ * This call has to be made if there is no read following (which would flush the data
25368+ * to the adapter), yet the written data has to reach the adapter immediately. */
25369+INLINE_IO void
25370+write_flush(acx_device_t *adev)
25371+{
25372+ /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */
25373+ /* faster version (accesses the first register, IO_ACX_SOFT_RESET,
25374+ * which should also be safe): */
25375+ readb(adev->iobase);
25376+}
25377+
25378+INLINE_IO int
25379+adev_present(acx_device_t *adev)
25380+{
25381+ /* fast version (accesses the first register, IO_ACX_SOFT_RESET,
25382+ * which should be safe): */
25383+ return readl(adev->iobase) != 0xffffffff;
25384+}
25385+
25386+
25387+/***********************************************************************
25388+*/
25389+static inline txdesc_t*
25390+get_txdesc(acx_device_t *adev, int index)
25391+{
25392+ return (txdesc_t*) (((u8*)adev->txdesc_start) + index * adev->txdesc_size);
25393+}
25394+
25395+static inline txdesc_t*
25396+advance_txdesc(acx_device_t *adev, txdesc_t* txdesc, int inc)
25397+{
25398+ return (txdesc_t*) (((u8*)txdesc) + inc * adev->txdesc_size);
25399+}
25400+
25401+static txhostdesc_t*
25402+get_txhostdesc(acx_device_t *adev, txdesc_t* txdesc)
25403+{
25404+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
25405+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
25406+ printk("bad txdesc ptr %p\n", txdesc);
25407+ return NULL;
25408+ }
25409+ index /= adev->txdesc_size;
25410+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
25411+ printk("bad txdesc ptr %p\n", txdesc);
25412+ return NULL;
25413+ }
25414+ return &adev->txhostdesc_start[index*2];
25415+}
25416+
25417+static inline client_t*
25418+get_txc(acx_device_t *adev, txdesc_t* txdesc)
25419+{
25420+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
25421+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
25422+ printk("bad txdesc ptr %p\n", txdesc);
25423+ return NULL;
25424+ }
25425+ index /= adev->txdesc_size;
25426+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
25427+ printk("bad txdesc ptr %p\n", txdesc);
25428+ return NULL;
25429+ }
25430+ return adev->txc[index];
25431+}
25432+
25433+static inline u16
25434+get_txr(acx_device_t *adev, txdesc_t* txdesc)
25435+{
25436+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
25437+ index /= adev->txdesc_size;
25438+ return adev->txr[index];
25439+}
25440+
25441+static inline void
25442+put_txcr(acx_device_t *adev, txdesc_t* txdesc, client_t* c, u16 r111)
25443+{
25444+ int index = (u8*)txdesc - (u8*)adev->txdesc_start;
25445+ if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) {
25446+ printk("bad txdesc ptr %p\n", txdesc);
25447+ return;
25448+ }
25449+ index /= adev->txdesc_size;
25450+ if (unlikely(ACX_DEBUG && (index >= TX_CNT))) {
25451+ printk("bad txdesc ptr %p\n", txdesc);
25452+ return;
25453+ }
25454+ adev->txc[index] = c;
25455+ adev->txr[index] = r111;
25456+}
25457+
25458+
25459+/***********************************************************************
25460+** EEPROM and PHY read/write helpers
25461+*/
25462+/***********************************************************************
25463+** acxpci_read_eeprom_byte
25464+**
25465+** Function called to read an octet in the EEPROM.
25466+**
25467+** This function is used by acxpci_e_probe to check if the
25468+** connected card is a legal one or not.
25469+**
25470+** Arguments:
25471+** adev ptr to acx_device structure
25472+** addr address to read in the EEPROM
25473+** charbuf ptr to a char. This is where the read octet
25474+** will be stored
25475+*/
25476+int
25477+acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf)
25478+{
25479+ int result;
25480+ int count;
25481+
25482+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
25483+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr);
25484+ write_flush(adev);
25485+ write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
25486+
25487+ count = 0xffff;
25488+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
25489+ /* scheduling away instead of CPU burning loop
25490+ * doesn't seem to work here at all:
25491+ * awful delay, sometimes also failure.
25492+ * Doesn't matter anyway (only small delay). */
25493+ if (unlikely(!--count)) {
25494+ printk("%s: timeout waiting for EEPROM read\n",
25495+ adev->ndev->name);
25496+ result = NOT_OK;
25497+ goto fail;
25498+ }
25499+ cpu_relax();
25500+ }
25501+
25502+ *charbuf = read_reg8(adev, IO_ACX_EEPROM_DATA);
25503+ log(L_DEBUG, "EEPROM at 0x%04X = 0x%02X\n", addr, *charbuf);
25504+ result = OK;
25505+
25506+fail:
25507+ return result;
25508+}
25509+
25510+
25511+/***********************************************************************
25512+** We don't lock hw accesses here since we never r/w eeprom in IRQ
25513+** Note: this function sleeps only because of GFP_KERNEL alloc
25514+*/
25515+#ifdef UNUSED
25516+int
25517+acxpci_s_write_eeprom(acx_device_t *adev, u32 addr, u32 len, const u8 *charbuf)
25518+{
25519+ u8 *data_verify = NULL;
25520+ unsigned long flags;
25521+ int count, i;
25522+ int result = NOT_OK;
25523+ u16 gpio_orig;
25524+
25525+ printk("acx: WARNING! I would write to EEPROM now. "
25526+ "Since I really DON'T want to unless you know "
25527+ "what you're doing (THIS CODE WILL PROBABLY "
25528+ "NOT WORK YET!), I will abort that now. And "
25529+ "definitely make sure to make a "
25530+ "/proc/driver/acx_wlan0_eeprom backup copy first!!! "
25531+ "(the EEPROM content includes the PCI config header!! "
25532+ "If you kill important stuff, then you WILL "
25533+ "get in trouble and people DID get in trouble already)\n");
25534+ return OK;
25535+
25536+ FN_ENTER;
25537+
25538+ data_verify = kmalloc(len, GFP_KERNEL);
25539+ if (!data_verify) {
25540+ goto end;
25541+ }
25542+
25543+ /* first we need to enable the OE (EEPROM Output Enable) GPIO line
25544+ * to be able to write to the EEPROM.
25545+ * NOTE: an EEPROM writing success has been reported,
25546+ * but you probably have to modify GPIO_OUT, too,
25547+ * and you probably need to activate a different GPIO
25548+ * line instead! */
25549+ gpio_orig = read_reg16(adev, IO_ACX_GPIO_OE);
25550+ write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig & ~1);
25551+ write_flush(adev);
25552+
25553+ /* ok, now start writing the data out */
25554+ for (i = 0; i < len; i++) {
25555+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
25556+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
25557+ write_reg32(adev, IO_ACX_EEPROM_DATA, *(charbuf + i));
25558+ write_flush(adev);
25559+ write_reg32(adev, IO_ACX_EEPROM_CTL, 1);
25560+
25561+ count = 0xffff;
25562+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
25563+ if (unlikely(!--count)) {
25564+ printk("WARNING, DANGER!!! "
25565+ "Timeout waiting for EEPROM write\n");
25566+ goto end;
25567+ }
25568+ cpu_relax();
25569+ }
25570+ }
25571+
25572+ /* disable EEPROM writing */
25573+ write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig);
25574+ write_flush(adev);
25575+
25576+ /* now start a verification run */
25577+ for (i = 0; i < len; i++) {
25578+ write_reg32(adev, IO_ACX_EEPROM_CFG, 0);
25579+ write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i);
25580+ write_flush(adev);
25581+ write_reg32(adev, IO_ACX_EEPROM_CTL, 2);
25582+
25583+ count = 0xffff;
25584+ while (read_reg16(adev, IO_ACX_EEPROM_CTL)) {
25585+ if (unlikely(!--count)) {
25586+ printk("timeout waiting for EEPROM read\n");
25587+ goto end;
25588+ }
25589+ cpu_relax();
25590+ }
25591+
25592+ data_verify[i] = read_reg16(adev, IO_ACX_EEPROM_DATA);
25593+ }
25594+
25595+ if (0 == memcmp(charbuf, data_verify, len))
25596+ result = OK; /* read data matches, success */
25597+
25598+end:
25599+ kfree(data_verify);
25600+ FN_EXIT1(result);
25601+ return result;
25602+}
25603+#endif /* UNUSED */
25604+
25605+
25606+/***********************************************************************
25607+** acxpci_s_read_phy_reg
25608+**
25609+** Messing with rx/tx disabling and enabling here
25610+** (write_reg32(adev, IO_ACX_ENABLE, 0b000000xx)) kills traffic
25611+*/
25612+int
25613+acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf)
25614+{
25615+ int result = NOT_OK;
25616+ int count;
25617+
25618+ FN_ENTER;
25619+
25620+ write_reg32(adev, IO_ACX_PHY_ADDR, reg);
25621+ write_flush(adev);
25622+ write_reg32(adev, IO_ACX_PHY_CTL, 2);
25623+
25624+ count = 0xffff;
25625+ while (read_reg32(adev, IO_ACX_PHY_CTL)) {
25626+ /* scheduling away instead of CPU burning loop
25627+ * doesn't seem to work here at all:
25628+ * awful delay, sometimes also failure.
25629+ * Doesn't matter anyway (only small delay). */
25630+ if (unlikely(!--count)) {
25631+ printk("%s: timeout waiting for phy read\n",
25632+ adev->ndev->name);
25633+ *charbuf = 0;
25634+ goto fail;
25635+ }
25636+ cpu_relax();
25637+ }
25638+
25639+ log(L_DEBUG, "count was %u\n", count);
25640+ *charbuf = read_reg8(adev, IO_ACX_PHY_DATA);
25641+
25642+ log(L_DEBUG, "radio PHY at 0x%04X = 0x%02X\n", *charbuf, reg);
25643+ result = OK;
25644+ goto fail; /* silence compiler warning */
25645+fail:
25646+ FN_EXIT1(result);
25647+ return result;
25648+}
25649+
25650+
25651+/***********************************************************************
25652+*/
25653+int
25654+acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value)
25655+{
25656+ FN_ENTER;
25657+
25658+ /* mprusko said that 32bit accesses result in distorted sensitivity
25659+ * on his card. Unconfirmed, looks like it's not true (most likely since we
25660+ * now properly flush writes). */
25661+ write_reg32(adev, IO_ACX_PHY_DATA, value);
25662+ write_reg32(adev, IO_ACX_PHY_ADDR, reg);
25663+ write_flush(adev);
25664+ write_reg32(adev, IO_ACX_PHY_CTL, 1);
25665+ write_flush(adev);
25666+ log(L_DEBUG, "radio PHY write 0x%02X at 0x%04X\n", value, reg);
25667+
25668+ FN_EXIT1(OK);
25669+ return OK;
25670+}
25671+
25672+
25673+#define NO_AUTO_INCREMENT 1
25674+
25675+/***********************************************************************
25676+** acxpci_s_write_fw
25677+**
25678+** Write the firmware image into the card.
25679+**
25680+** Arguments:
25681+** adev wlan device structure
25682+** fw_image firmware image.
25683+**
25684+** Returns:
25685+** 1 firmware image corrupted
25686+** 0 success
25687+*/
25688+static int
25689+acxpci_s_write_fw(acx_device_t *adev, const firmware_image_t *fw_image, u32 offset)
25690+{
25691+ int len, size;
25692+ u32 sum, v32;
25693+ /* we skip the first four bytes which contain the control sum */
25694+ const u8 *p = (u8*)fw_image + 4;
25695+
25696+ /* start the image checksum by adding the image size value */
25697+ sum = p[0]+p[1]+p[2]+p[3];
25698+ p += 4;
25699+
25700+ write_reg32(adev, IO_ACX_SLV_END_CTL, 0);
25701+
25702+#if NO_AUTO_INCREMENT
25703+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */
25704+#else
25705+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */
25706+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */
25707+ write_flush(adev);
25708+#endif
25709+
25710+ len = 0;
25711+ size = le32_to_cpu(fw_image->size) & (~3);
25712+
25713+ while (likely(len < size)) {
25714+ v32 = be32_to_cpu(*(u32*)p);
25715+ sum += p[0]+p[1]+p[2]+p[3];
25716+ p += 4;
25717+ len += 4;
25718+
25719+#if NO_AUTO_INCREMENT
25720+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4);
25721+ write_flush(adev);
25722+#endif
25723+ write_reg32(adev, IO_ACX_SLV_MEM_DATA, v32);
25724+ }
25725+
25726+ log(L_DEBUG, "firmware written, size:%d sum1:%x sum2:%x\n",
25727+ size, sum, le32_to_cpu(fw_image->chksum));
25728+
25729+ /* compare our checksum with the stored image checksum */
25730+ return (sum != le32_to_cpu(fw_image->chksum));
25731+}
25732+
25733+
25734+/***********************************************************************
25735+** acxpci_s_validate_fw
25736+**
25737+** Compare the firmware image given with
25738+** the firmware image written into the card.
25739+**
25740+** Arguments:
25741+** adev wlan device structure
25742+** fw_image firmware image.
25743+**
25744+** Returns:
25745+** NOT_OK firmware image corrupted or not correctly written
25746+** OK success
25747+*/
25748+static int
25749+acxpci_s_validate_fw(acx_device_t *adev, const firmware_image_t *fw_image,
25750+ u32 offset)
25751+{
25752+ u32 sum, v32, w32;
25753+ int len, size;
25754+ int result = OK;
25755+ /* we skip the first four bytes which contain the control sum */
25756+ const u8 *p = (u8*)fw_image + 4;
25757+
25758+ /* start the image checksum by adding the image size value */
25759+ sum = p[0]+p[1]+p[2]+p[3];
25760+ p += 4;
25761+
25762+ write_reg32(adev, IO_ACX_SLV_END_CTL, 0);
25763+
25764+#if NO_AUTO_INCREMENT
25765+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */
25766+#else
25767+ write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */
25768+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */
25769+#endif
25770+
25771+ len = 0;
25772+ size = le32_to_cpu(fw_image->size) & (~3);
25773+
25774+ while (likely(len < size)) {
25775+ v32 = be32_to_cpu(*(u32*)p);
25776+ p += 4;
25777+ len += 4;
25778+
25779+#if NO_AUTO_INCREMENT
25780+ write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4);
25781+#endif
25782+ w32 = read_reg32(adev, IO_ACX_SLV_MEM_DATA);
25783+
25784+ if (unlikely(w32 != v32)) {
25785+ printk("acx: FATAL: firmware upload: "
25786+ "data parts at offset %d don't match (0x%08X vs. 0x%08X)! "
25787+ "I/O timing issues or defective memory, with DWL-xx0+? "
25788+ "ACX_IO_WIDTH=16 may help. Please report\n",
25789+ len, v32, w32);
25790+ result = NOT_OK;
25791+ break;
25792+ }
25793+
25794+ sum += (u8)w32 + (u8)(w32>>8) + (u8)(w32>>16) + (u8)(w32>>24);
25795+ }
25796+
25797+ /* sum control verification */
25798+ if (result != NOT_OK) {
25799+ if (sum != le32_to_cpu(fw_image->chksum)) {
25800+ printk("acx: FATAL: firmware upload: "
25801+ "checksums don't match!\n");
25802+ result = NOT_OK;
25803+ }
25804+ }
25805+
25806+ return result;
25807+}
25808+
25809+
25810+/***********************************************************************
25811+** acxpci_s_upload_fw
25812+**
25813+** Called from acx_reset_dev
25814+*/
25815+static int
25816+acxpci_s_upload_fw(acx_device_t *adev)
25817+{
25818+ firmware_image_t *fw_image = NULL;
25819+ int res = NOT_OK;
25820+ int try;
25821+ u32 file_size;
25822+ char filename[sizeof("tiacx1NNcNN")];
25823+
25824+ FN_ENTER;
25825+
25826+ /* print exact chipset and radio ID to make sure people really get a clue on which files exactly they are supposed to provide,
25827+ * since firmware loading is the biggest enduser PITA with these chipsets.
25828+ * Not printing radio ID in 0xHEX in order to not confuse them into wrong file naming */
25829+ printk( "acx: need to load firmware for acx1%02d chipset with radio ID %02x, please provide via firmware hotplug:\n"
25830+ "acx: either one file only (<c>ombined firmware image file, radio-specific) or two files (radio-less base image file *plus* separate <r>adio-specific extension file)\n",
25831+ IS_ACX111(adev)*11, adev->radio_type);
25832+
25833+ /* Try combined, then main image */
25834+ adev->need_radio_fw = 0;
25835+ snprintf(filename, sizeof(filename), "tiacx1%02dc%02X",
25836+ IS_ACX111(adev)*11, adev->radio_type);
25837+
25838+ fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size);
25839+ if (!fw_image) {
25840+ adev->need_radio_fw = 1;
25841+ filename[sizeof("tiacx1NN")-1] = '\0';
25842+ fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size);
25843+ if (!fw_image) {
25844+ FN_EXIT1(NOT_OK);
25845+ return NOT_OK;
25846+ }
25847+ }
25848+
25849+ for (try = 1; try <= 5; try++) {
25850+ res = acxpci_s_write_fw(adev, fw_image, 0);
25851+ log(L_DEBUG|L_INIT, "acx_write_fw (main/combined): %d\n", res);
25852+ if (OK == res) {
25853+ res = acxpci_s_validate_fw(adev, fw_image, 0);
25854+ log(L_DEBUG|L_INIT, "acx_validate_fw "
25855+ "(main/combined): %d\n", res);
25856+ }
25857+
25858+ if (OK == res) {
25859+ SET_BIT(adev->dev_state_mask, ACX_STATE_FW_LOADED);
25860+ break;
25861+ }
25862+ printk("acx: firmware upload attempt #%d FAILED, "
25863+ "retrying...\n", try);
25864+ acx_s_msleep(1000); /* better wait for a while... */
25865+ }
25866+
25867+ vfree(fw_image);
25868+
25869+ FN_EXIT1(res);
25870+ return res;
25871+}
25872+
25873+
25874+/***********************************************************************
25875+** acxpci_s_upload_radio
25876+**
25877+** Uploads the appropriate radio module firmware into the card.
25878+*/
25879+int
25880+acxpci_s_upload_radio(acx_device_t *adev)
25881+{
25882+ acx_ie_memmap_t mm;
25883+ firmware_image_t *radio_image;
25884+ acx_cmd_radioinit_t radioinit;
25885+ int res = NOT_OK;
25886+ int try;
25887+ u32 offset;
25888+ u32 size;
25889+ char filename[sizeof("tiacx1NNrNN")];
25890+
25891+ if (!adev->need_radio_fw) return OK;
25892+
25893+ FN_ENTER;
25894+
25895+ acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP);
25896+ offset = le32_to_cpu(mm.CodeEnd);
25897+
25898+ snprintf(filename, sizeof(filename), "tiacx1%02dr%02X",
25899+ IS_ACX111(adev)*11,
25900+ adev->radio_type);
25901+ radio_image = acx_s_read_fw(&adev->pdev->dev, filename, &size);
25902+ if (!radio_image) {
25903+ printk("acx: can't load radio module '%s'\n", filename);
25904+ goto fail;
25905+ }
25906+
25907+ acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0);
25908+
25909+ for (try = 1; try <= 5; try++) {
25910+ res = acxpci_s_write_fw(adev, radio_image, offset);
25911+ log(L_DEBUG|L_INIT, "acx_write_fw (radio): %d\n", res);
25912+ if (OK == res) {
25913+ res = acxpci_s_validate_fw(adev, radio_image, offset);
25914+ log(L_DEBUG|L_INIT, "acx_validate_fw (radio): %d\n", res);
25915+ }
25916+
25917+ if (OK == res)
25918+ break;
25919+ printk("acx: radio firmware upload attempt #%d FAILED, "
25920+ "retrying...\n", try);
25921+ acx_s_msleep(1000); /* better wait for a while... */
25922+ }
25923+
25924+ acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0);
25925+ radioinit.offset = cpu_to_le32(offset);
25926+ /* no endian conversion needed, remains in card CPU area: */
25927+ radioinit.len = radio_image->size;
25928+
25929+ vfree(radio_image);
25930+
25931+ if (OK != res)
25932+ goto fail;
25933+
25934+ /* will take a moment so let's have a big timeout */
25935+ acx_s_issue_cmd_timeo(adev, ACX1xx_CMD_RADIOINIT,
25936+ &radioinit, sizeof(radioinit), CMD_TIMEOUT_MS(1000));
25937+
25938+ res = acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP);
25939+fail:
25940+ FN_EXIT1(res);
25941+ return res;
25942+}
25943+
25944+
25945+/***********************************************************************
25946+** acxpci_l_reset_mac
25947+**
25948+** MAC will be reset
25949+** Call context: reset_dev
25950+*/
25951+static void
25952+acxpci_l_reset_mac(acx_device_t *adev)
25953+{
25954+ u16 temp;
25955+
25956+ FN_ENTER;
25957+
25958+ /* halt eCPU */
25959+ temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1;
25960+ write_reg16(adev, IO_ACX_ECPU_CTRL, temp);
25961+
25962+ /* now do soft reset of eCPU, set bit */
25963+ temp = read_reg16(adev, IO_ACX_SOFT_RESET) | 0x1;
25964+ log(L_DEBUG, "%s: enable soft reset...\n", __func__);
25965+ write_reg16(adev, IO_ACX_SOFT_RESET, temp);
25966+ write_flush(adev);
25967+
25968+ /* now clear bit again: deassert eCPU reset */
25969+ log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__);
25970+ write_reg16(adev, IO_ACX_SOFT_RESET, temp & ~0x1);
25971+
25972+ /* now start a burst read from initial EEPROM */
25973+ temp = read_reg16(adev, IO_ACX_EE_START) | 0x1;
25974+ write_reg16(adev, IO_ACX_EE_START, temp);
25975+ write_flush(adev);
25976+
25977+ FN_EXIT0;
25978+}
25979+
25980+
25981+/***********************************************************************
25982+** acxpci_s_verify_init
25983+*/
25984+static int
25985+acxpci_s_verify_init(acx_device_t *adev)
25986+{
25987+ int result = NOT_OK;
25988+ unsigned long timeout;
25989+
25990+ FN_ENTER;
25991+
25992+ timeout = jiffies + 2*HZ;
25993+ for (;;) {
25994+ u16 irqstat = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES);
25995+ if (irqstat & HOST_INT_FCS_THRESHOLD) {
25996+ result = OK;
25997+ write_reg16(adev, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD);
25998+ break;
25999+ }
26000+ if (time_after(jiffies, timeout))
26001+ break;
26002+ /* Init may take up to ~0.5 sec total */
26003+ acx_s_msleep(50);
26004+ }
26005+
26006+ FN_EXIT1(result);
26007+ return result;
26008+}
26009+
26010+
26011+/***********************************************************************
26012+** A few low-level helpers
26013+**
26014+** Note: these functions are not protected by lock
26015+** and thus are never allowed to be called from IRQ.
26016+** Also they must not race with fw upload which uses same hw regs
26017+*/
26018+
26019+/***********************************************************************
26020+** acxpci_write_cmd_type_status
26021+*/
26022+
26023+static inline void
26024+acxpci_write_cmd_type_status(acx_device_t *adev, u16 type, u16 status)
26025+{
26026+ writel(type | (status << 16), adev->cmd_area);
26027+ write_flush(adev);
26028+}
26029+
26030+
26031+/***********************************************************************
26032+** acxpci_read_cmd_type_status
26033+*/
26034+static u32
26035+acxpci_read_cmd_type_status(acx_device_t *adev)
26036+{
26037+ u32 cmd_type, cmd_status;
26038+
26039+ cmd_type = readl(adev->cmd_area);
26040+ cmd_status = (cmd_type >> 16);
26041+ cmd_type = (u16)cmd_type;
26042+
26043+ log(L_CTL, "cmd_type:%04X cmd_status:%04X [%s]\n",
26044+ cmd_type, cmd_status,
26045+ acx_cmd_status_str(cmd_status));
26046+
26047+ return cmd_status;
26048+}
26049+
26050+
26051+/***********************************************************************
26052+** acxpci_s_reset_dev
26053+**
26054+** Arguments:
26055+** netdevice that contains the adev variable
26056+** Returns:
26057+** NOT_OK on fail
26058+** OK on success
26059+** Side effects:
26060+** device is hard reset
26061+** Call context:
26062+** acxpci_e_probe
26063+** Comment:
26064+** This resets the device using low level hardware calls
26065+** as well as uploads and verifies the firmware to the card
26066+*/
26067+
26068+static inline void
26069+init_mboxes(acx_device_t *adev)
26070+{
26071+ u32 cmd_offs, info_offs;
26072+
26073+ cmd_offs = read_reg32(adev, IO_ACX_CMD_MAILBOX_OFFS);
26074+ info_offs = read_reg32(adev, IO_ACX_INFO_MAILBOX_OFFS);
26075+ adev->cmd_area = (u8 *)adev->iobase2 + cmd_offs;
26076+ adev->info_area = (u8 *)adev->iobase2 + info_offs;
26077+ log(L_DEBUG, "iobase2=%p\n"
26078+ "cmd_mbox_offset=%X cmd_area=%p\n"
26079+ "info_mbox_offset=%X info_area=%p\n",
26080+ adev->iobase2,
26081+ cmd_offs, adev->cmd_area,
26082+ info_offs, adev->info_area);
26083+}
26084+
26085+
26086+static inline void
26087+read_eeprom_area(acx_device_t *adev)
26088+{
26089+#if ACX_DEBUG > 1
26090+ int offs;
26091+ u8 tmp;
26092+
26093+ for (offs = 0x8c; offs < 0xb9; offs++)
26094+ acxpci_read_eeprom_byte(adev, offs, &tmp);
26095+#endif
26096+}
26097+
26098+
26099+static int
26100+acxpci_s_reset_dev(acx_device_t *adev)
26101+{
26102+ const char* msg = "";
26103+ unsigned long flags;
26104+ int result = NOT_OK;
26105+ u16 hardware_info;
26106+ u16 ecpu_ctrl;
26107+ int count;
26108+
26109+ FN_ENTER;
26110+
26111+ /* reset the device to make sure the eCPU is stopped
26112+ * to upload the firmware correctly */
26113+
26114+ acx_lock(adev, flags);
26115+
26116+ acxpci_l_reset_mac(adev);
26117+
26118+ ecpu_ctrl = read_reg16(adev, IO_ACX_ECPU_CTRL) & 1;
26119+ if (!ecpu_ctrl) {
26120+ msg = "eCPU is already running. ";
26121+ goto end_unlock;
26122+ }
26123+
26124+#ifdef WE_DONT_NEED_THAT_DO_WE
26125+ if (read_reg16(adev, IO_ACX_SOR_CFG) & 2) {
26126+ /* eCPU most likely means "embedded CPU" */
26127+ msg = "eCPU did not start after boot from flash. ";
26128+ goto end_unlock;
26129+ }
26130+
26131+ /* check sense on reset flags */
26132+ if (read_reg16(adev, IO_ACX_SOR_CFG) & 0x10) {
26133+ printk("%s: eCPU did not start after boot (SOR), "
26134+ "is this fatal?\n", adev->ndev->name);
26135+ }
26136+#endif
26137+ /* scan, if any, is stopped now, setting corresponding IRQ bit */
26138+ adev->irq_status |= HOST_INT_SCAN_COMPLETE;
26139+
26140+ acx_unlock(adev, flags);
26141+
26142+ /* need to know radio type before fw load */
26143+ /* Need to wait for arrival of this information in a loop,
26144+ * most probably since eCPU runs some init code from EEPROM
26145+ * (started burst read in reset_mac()) which also
26146+ * sets the radio type ID */
26147+
26148+ count = 0xffff;
26149+ do {
26150+ hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION);
26151+ if (!--count) {
26152+ msg = "eCPU didn't indicate radio type";
26153+ goto end_fail;
26154+ }
26155+ cpu_relax();
26156+ } while (!(hardware_info & 0xff00)); /* radio type still zero? */
26157+
26158+ /* printk("DEBUG: count %d\n", count); */
26159+ adev->form_factor = hardware_info & 0xff;
26160+ adev->radio_type = hardware_info >> 8;
26161+
26162+ /* load the firmware */
26163+ if (OK != acxpci_s_upload_fw(adev))
26164+ goto end_fail;
26165+
26166+ /* acx_s_msleep(10); this one really shouldn't be required */
26167+
26168+ /* now start eCPU by clearing bit */
26169+ write_reg16(adev, IO_ACX_ECPU_CTRL, ecpu_ctrl & ~0x1);
26170+ log(L_DEBUG, "booted eCPU up and waiting for completion...\n");
26171+
26172+ /* wait for eCPU bootup */
26173+ if (OK != acxpci_s_verify_init(adev)) {
26174+ msg = "timeout waiting for eCPU. ";
26175+ goto end_fail;
26176+ }
26177+ log(L_DEBUG, "eCPU has woken up, card is ready to be configured\n");
26178+
26179+ init_mboxes(adev);
26180+ acxpci_write_cmd_type_status(adev, 0, 0);
26181+
26182+ /* test that EEPROM is readable */
26183+ read_eeprom_area(adev);
26184+
26185+ result = OK;
26186+ goto end;
26187+
26188+/* Finish error message. Indicate which function failed */
26189+end_unlock:
26190+ acx_unlock(adev, flags);
26191+end_fail:
26192+ printk("acx: %sreset_dev() FAILED\n", msg);
26193+end:
26194+ FN_EXIT1(result);
26195+ return result;
26196+}
26197+
26198+
26199+/***********************************************************************
26200+** acxpci_s_issue_cmd_timeo
26201+**
26202+** Sends command to fw, extract result
26203+**
26204+** NB: we do _not_ take lock inside, so be sure to not touch anything
26205+** which may interfere with IRQ handler operation
26206+**
26207+** TODO: busy wait is a bit silly, so:
26208+** 1) stop doing many iters - go to sleep after first
26209+** 2) go to waitqueue based approach: wait, not poll!
26210+*/
26211+#undef FUNC
26212+#define FUNC "issue_cmd"
26213+
26214+#if !ACX_DEBUG
26215+int
26216+acxpci_s_issue_cmd_timeo(
26217+ acx_device_t *adev,
26218+ unsigned int cmd,
26219+ void *buffer,
26220+ unsigned buflen,
26221+ unsigned cmd_timeout)
26222+{
26223+#else
26224+int
26225+acxpci_s_issue_cmd_timeo_debug(
26226+ acx_device_t *adev,
26227+ unsigned cmd,
26228+ void *buffer,
26229+ unsigned buflen,
26230+ unsigned cmd_timeout,
26231+ const char* cmdstr)
26232+{
26233+ unsigned long start = jiffies;
26234+#endif
26235+ const char *devname;
26236+ unsigned counter;
26237+ u16 irqtype;
26238+ u16 cmd_status;
26239+ unsigned long timeout;
26240+
26241+ FN_ENTER;
26242+
26243+ devname = adev->ndev->name;
26244+ if (!devname || !devname[0] || devname[4]=='%')
26245+ devname = "acx";
26246+
26247+ log(L_CTL, FUNC"(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n",
26248+ cmdstr, buflen, cmd_timeout,
26249+ buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1);
26250+
26251+ if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) {
26252+ printk("%s: "FUNC"(): firmware is not loaded yet, "
26253+ "cannot execute commands!\n", devname);
26254+ goto bad;
26255+ }
26256+
26257+ if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) {
26258+ printk("input buffer (len=%u):\n", buflen);
26259+ acx_dump_bytes(buffer, buflen);
26260+ }
26261+
26262+ /* wait for firmware to become idle for our command submission */
26263+ timeout = HZ/5;
26264+ counter = (timeout * 1000 / HZ) - 1; /* in ms */
26265+ timeout += jiffies;
26266+ do {
26267+ cmd_status = acxpci_read_cmd_type_status(adev);
26268+ /* Test for IDLE state */
26269+ if (!cmd_status)
26270+ break;
26271+ if (counter % 8 == 0) {
26272+ if (time_after(jiffies, timeout)) {
26273+ counter = 0;
26274+ break;
26275+ }
26276+ /* we waited 8 iterations, no luck. Sleep 8 ms */
26277+ acx_s_msleep(8);
26278+ }
26279+ } while (likely(--counter));
26280+
26281+ if (!counter) {
26282+ /* the card doesn't get idle, we're in trouble */
26283+ printk("%s: "FUNC"(): cmd_status is not IDLE: 0x%04X!=0\n",
26284+ devname, cmd_status);
26285+ goto bad;
26286+ } else if (counter < 190) { /* if waited >10ms... */
26287+ log(L_CTL|L_DEBUG, FUNC"(): waited for IDLE %dms. "
26288+ "Please report\n", 199 - counter);
26289+ }
26290+
26291+ /* now write the parameters of the command if needed */
26292+ if (buffer && buflen) {
26293+ /* if it's an INTERROGATE command, just pass the length
26294+ * of parameters to read, as data */
26295+#if CMD_DISCOVERY
26296+ if (cmd == ACX1xx_CMD_INTERROGATE)
26297+ memset_io(adev->cmd_area + 4, 0xAA, buflen);
26298+#endif
26299+ /* adev->cmd_area points to PCI device's memory, not to RAM! */
26300+ memcpy_toio(adev->cmd_area + 4, buffer,
26301+ (cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen);
26302+ }
26303+ /* now write the actual command type */
26304+ acxpci_write_cmd_type_status(adev, cmd, 0);
26305+ /* execute command */
26306+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD);
26307+ write_flush(adev);
26308+
26309+ /* wait for firmware to process command */
26310+
26311+ /* Ensure nonzero and not too large timeout.
26312+ ** Also converts e.g. 100->99, 200->199
26313+ ** which is nice but not essential */
26314+ cmd_timeout = (cmd_timeout-1) | 1;
26315+ if (unlikely(cmd_timeout > 1199))
26316+ cmd_timeout = 1199;
26317+ /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */
26318+ adev->irq_status &= ~HOST_INT_CMD_COMPLETE;
26319+
26320+ /* we schedule away sometimes (timeout can be large) */
26321+ counter = cmd_timeout;
26322+ timeout = jiffies + cmd_timeout * HZ / 1000;
26323+ do {
26324+ if (!adev->irqs_active) { /* IRQ disabled: poll */
26325+ irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES);
26326+ if (irqtype & HOST_INT_CMD_COMPLETE) {
26327+ write_reg16(adev, IO_ACX_IRQ_ACK,
26328+ HOST_INT_CMD_COMPLETE);
26329+ break;
26330+ }
26331+ } else { /* Wait when IRQ will set the bit */
26332+ irqtype = adev->irq_status;
26333+ if (irqtype & HOST_INT_CMD_COMPLETE)
26334+ break;
26335+ }
26336+
26337+ if (counter % 8 == 0) {
26338+ if (time_after(jiffies, timeout)) {
26339+ counter = 0;
26340+ break;
26341+ }
26342+ /* we waited 8 iterations, no luck. Sleep 8 ms */
26343+ acx_s_msleep(8);
26344+ }
26345+ } while (likely(--counter));
26346+
26347+ /* save state for debugging */
26348+ cmd_status = acxpci_read_cmd_type_status(adev);
26349+
26350+ /* put the card in IDLE state */
26351+ acxpci_write_cmd_type_status(adev, 0, 0);
26352+
26353+ if (!counter) { /* timed out! */
26354+ printk("%s: "FUNC"(): timed out %s for CMD_COMPLETE. "
26355+ "irq bits:0x%04X irq_status:0x%04X timeout:%dms "
26356+ "cmd_status:%d (%s)\n",
26357+ devname, (adev->irqs_active) ? "waiting" : "polling",
26358+ irqtype, adev->irq_status, cmd_timeout,
26359+ cmd_status, acx_cmd_status_str(cmd_status));
26360+ goto bad;
26361+ } else if (cmd_timeout - counter > 30) { /* if waited >30ms... */
26362+ log(L_CTL|L_DEBUG, FUNC"(): %s for CMD_COMPLETE %dms. "
26363+ "count:%d. Please report\n",
26364+ (adev->irqs_active) ? "waited" : "polled",
26365+ cmd_timeout - counter, counter);
26366+ }
26367+
26368+ if (1 != cmd_status) { /* it is not a 'Success' */
26369+ printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s). "
26370+ "Took %dms of %d\n",
26371+ devname, cmd_status, acx_cmd_status_str(cmd_status),
26372+ cmd_timeout - counter, cmd_timeout);
26373+ /* zero out result buffer
26374+ * WARNING: this will trash stack in case of illegally large input
26375+ * length! */
26376+ if (buffer && buflen)
26377+ memset(buffer, 0, buflen);
26378+ goto bad;
26379+ }
26380+
26381+ /* read in result parameters if needed */
26382+ if (buffer && buflen && (cmd == ACX1xx_CMD_INTERROGATE)) {
26383+ /* adev->cmd_area points to PCI device's memory, not to RAM! */
26384+ memcpy_fromio(buffer, adev->cmd_area + 4, buflen);
26385+ if (acx_debug & L_DEBUG) {
26386+ printk("output buffer (len=%u): ", buflen);
26387+ acx_dump_bytes(buffer, buflen);
26388+ }
26389+ }
26390+/* ok: */
26391+ log(L_CTL, FUNC"(%s): took %ld jiffies to complete\n",
26392+ cmdstr, jiffies - start);
26393+ FN_EXIT1(OK);
26394+ return OK;
26395+
26396+bad:
26397+ /* Give enough info so that callers can avoid
26398+ ** printing their own diagnostic messages */
26399+#if ACX_DEBUG
26400+ printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr);
26401+#else
26402+ printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd);
26403+#endif
26404+ dump_stack();
26405+ FN_EXIT1(NOT_OK);
26406+ return NOT_OK;
26407+}
26408+
26409+
26410+/***********************************************************************
26411+*/
26412+#ifdef NONESSENTIAL_FEATURES
26413+typedef struct device_id {
26414+ unsigned char id[6];
26415+ char *descr;
26416+ char *type;
26417+} device_id_t;
26418+
26419+static const device_id_t
26420+device_ids[] =
26421+{
26422+ {
26423+ {'G', 'l', 'o', 'b', 'a', 'l'},
26424+ NULL,
26425+ NULL,
26426+ },
26427+ {
26428+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
26429+ "uninitialized",
26430+ "SpeedStream SS1021 or Gigafast WF721-AEX"
26431+ },
26432+ {
26433+ {0x80, 0x81, 0x82, 0x83, 0x84, 0x85},
26434+ "non-standard",
26435+ "DrayTek Vigor 520"
26436+ },
26437+ {
26438+ {'?', '?', '?', '?', '?', '?'},
26439+ "non-standard",
26440+ "Level One WPC-0200"
26441+ },
26442+ {
26443+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
26444+ "empty",
26445+ "DWL-650+ variant"
26446+ }
26447+};
26448+
26449+static void
26450+acx_show_card_eeprom_id(acx_device_t *adev)
26451+{
26452+ unsigned char buffer[CARD_EEPROM_ID_SIZE];
26453+ int i;
26454+
26455+ memset(&buffer, 0, CARD_EEPROM_ID_SIZE);
26456+ /* use direct EEPROM access */
26457+ for (i = 0; i < CARD_EEPROM_ID_SIZE; i++) {
26458+ if (OK != acxpci_read_eeprom_byte(adev,
26459+ ACX100_EEPROM_ID_OFFSET + i,
26460+ &buffer[i])) {
26461+ printk("acx: reading EEPROM FAILED\n");
26462+ break;
26463+ }
26464+ }
26465+
26466+ for (i = 0; i < VEC_SIZE(device_ids); i++) {
26467+ if (!memcmp(&buffer, device_ids[i].id, CARD_EEPROM_ID_SIZE)) {
26468+ if (device_ids[i].descr) {
26469+ printk("acx: EEPROM card ID string check "
26470+ "found %s card ID: is this %s?\n",
26471+ device_ids[i].descr, device_ids[i].type);
26472+ }
26473+ break;
26474+ }
26475+ }
26476+ if (i == VEC_SIZE(device_ids)) {
26477+ printk("acx: EEPROM card ID string check found "
26478+ "unknown card: expected 'Global', got '%.*s\'. "
26479+ "Please report\n", CARD_EEPROM_ID_SIZE, buffer);
26480+ }
26481+}
26482+#endif /* NONESSENTIAL_FEATURES */
26483+
26484+
26485+/***********************************************************************
26486+** acxpci_free_desc_queues
26487+**
26488+** Releases the queues that have been allocated, the
26489+** others have been initialised to NULL so this
26490+** function can be used if only part of the queues were allocated.
26491+*/
26492+
26493+static inline void
26494+free_coherent(struct pci_dev *hwdev, size_t size,
26495+ void *vaddr, dma_addr_t dma_handle)
26496+{
26497+ dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev,
26498+ size, vaddr, dma_handle);
26499+}
26500+
26501+void
26502+acxpci_free_desc_queues(acx_device_t *adev)
26503+{
26504+#define ACX_FREE_QUEUE(size, ptr, phyaddr) \
26505+ if (ptr) { \
26506+ free_coherent(0, size, ptr, phyaddr); \
26507+ ptr = NULL; \
26508+ size = 0; \
26509+ }
26510+
26511+ FN_ENTER;
26512+
26513+ ACX_FREE_QUEUE(adev->txhostdesc_area_size, adev->txhostdesc_start, adev->txhostdesc_startphy);
26514+ ACX_FREE_QUEUE(adev->txbuf_area_size, adev->txbuf_start, adev->txbuf_startphy);
26515+
26516+ adev->txdesc_start = NULL;
26517+
26518+ ACX_FREE_QUEUE(adev->rxhostdesc_area_size, adev->rxhostdesc_start, adev->rxhostdesc_startphy);
26519+ ACX_FREE_QUEUE(adev->rxbuf_area_size, adev->rxbuf_start, adev->rxbuf_startphy);
26520+
26521+ adev->rxdesc_start = NULL;
26522+
26523+ FN_EXIT0;
26524+}
26525+
26526+
26527+/***********************************************************************
26528+** acxpci_s_delete_dma_regions
26529+*/
26530+static void
26531+acxpci_s_delete_dma_regions(acx_device_t *adev)
26532+{
26533+ unsigned long flags;
26534+
26535+ FN_ENTER;
26536+ /* disable radio Tx/Rx. Shouldn't we use the firmware commands
26537+ * here instead? Or are we that much down the road that it's no
26538+ * longer possible here? */
26539+ write_reg16(adev, IO_ACX_ENABLE, 0);
26540+
26541+ acx_s_msleep(100);
26542+
26543+ acx_lock(adev, flags);
26544+ acxpci_free_desc_queues(adev);
26545+ acx_unlock(adev, flags);
26546+
26547+ FN_EXIT0;
26548+}
26549+
26550+
26551+/***********************************************************************
26552+** acxpci_e_probe
26553+**
26554+** Probe routine called when a PCI device w/ matching ID is found.
26555+** Here's the sequence:
26556+** - Allocate the PCI resources.
26557+** - Read the PCMCIA attribute memory to make sure we have a WLAN card
26558+** - Reset the MAC
26559+** - Initialize the dev and wlan data
26560+** - Initialize the MAC
26561+**
26562+** pdev - ptr to pci device structure containing info about pci configuration
26563+** id - ptr to the device id entry that matched this device
26564+*/
26565+static const u16
26566+IO_ACX100[] =
26567+{
26568+ 0x0000, /* IO_ACX_SOFT_RESET */
26569+
26570+ 0x0014, /* IO_ACX_SLV_MEM_ADDR */
26571+ 0x0018, /* IO_ACX_SLV_MEM_DATA */
26572+ 0x001c, /* IO_ACX_SLV_MEM_CTL */
26573+ 0x0020, /* IO_ACX_SLV_END_CTL */
26574+
26575+ 0x0034, /* IO_ACX_FEMR */
26576+
26577+ 0x007c, /* IO_ACX_INT_TRIG */
26578+ 0x0098, /* IO_ACX_IRQ_MASK */
26579+ 0x00a4, /* IO_ACX_IRQ_STATUS_NON_DES */
26580+ 0x00a8, /* IO_ACX_IRQ_STATUS_CLEAR */
26581+ 0x00ac, /* IO_ACX_IRQ_ACK */
26582+ 0x00b0, /* IO_ACX_HINT_TRIG */
26583+
26584+ 0x0104, /* IO_ACX_ENABLE */
26585+
26586+ 0x0250, /* IO_ACX_EEPROM_CTL */
26587+ 0x0254, /* IO_ACX_EEPROM_ADDR */
26588+ 0x0258, /* IO_ACX_EEPROM_DATA */
26589+ 0x025c, /* IO_ACX_EEPROM_CFG */
26590+
26591+ 0x0268, /* IO_ACX_PHY_ADDR */
26592+ 0x026c, /* IO_ACX_PHY_DATA */
26593+ 0x0270, /* IO_ACX_PHY_CTL */
26594+
26595+ 0x0290, /* IO_ACX_GPIO_OE */
26596+
26597+ 0x0298, /* IO_ACX_GPIO_OUT */
26598+
26599+ 0x02a4, /* IO_ACX_CMD_MAILBOX_OFFS */
26600+ 0x02a8, /* IO_ACX_INFO_MAILBOX_OFFS */
26601+ 0x02ac, /* IO_ACX_EEPROM_INFORMATION */
26602+
26603+ 0x02d0, /* IO_ACX_EE_START */
26604+ 0x02d4, /* IO_ACX_SOR_CFG */
26605+ 0x02d8 /* IO_ACX_ECPU_CTRL */
26606+};
26607+
26608+static const u16
26609+IO_ACX111[] =
26610+{
26611+ 0x0000, /* IO_ACX_SOFT_RESET */
26612+
26613+ 0x0014, /* IO_ACX_SLV_MEM_ADDR */
26614+ 0x0018, /* IO_ACX_SLV_MEM_DATA */
26615+ 0x001c, /* IO_ACX_SLV_MEM_CTL */
26616+ 0x0020, /* IO_ACX_SLV_END_CTL */
26617+
26618+ 0x0034, /* IO_ACX_FEMR */
26619+
26620+ 0x00b4, /* IO_ACX_INT_TRIG */
26621+ 0x00d4, /* IO_ACX_IRQ_MASK */
26622+ /* we do mean NON_DES (0xf0), not NON_DES_MASK which is at 0xe0: */
26623+ 0x00f0, /* IO_ACX_IRQ_STATUS_NON_DES */
26624+ 0x00e4, /* IO_ACX_IRQ_STATUS_CLEAR */
26625+ 0x00e8, /* IO_ACX_IRQ_ACK */
26626+ 0x00ec, /* IO_ACX_HINT_TRIG */
26627+
26628+ 0x01d0, /* IO_ACX_ENABLE */
26629+
26630+ 0x0338, /* IO_ACX_EEPROM_CTL */
26631+ 0x033c, /* IO_ACX_EEPROM_ADDR */
26632+ 0x0340, /* IO_ACX_EEPROM_DATA */
26633+ 0x0344, /* IO_ACX_EEPROM_CFG */
26634+
26635+ 0x0350, /* IO_ACX_PHY_ADDR */
26636+ 0x0354, /* IO_ACX_PHY_DATA */
26637+ 0x0358, /* IO_ACX_PHY_CTL */
26638+
26639+ 0x0374, /* IO_ACX_GPIO_OE */
26640+
26641+ 0x037c, /* IO_ACX_GPIO_OUT */
26642+
26643+ 0x0388, /* IO_ACX_CMD_MAILBOX_OFFS */
26644+ 0x038c, /* IO_ACX_INFO_MAILBOX_OFFS */
26645+ 0x0390, /* IO_ACX_EEPROM_INFORMATION */
26646+
26647+ 0x0100, /* IO_ACX_EE_START */
26648+ 0x0104, /* IO_ACX_SOR_CFG */
26649+ 0x0108, /* IO_ACX_ECPU_CTRL */
26650+};
26651+
26652+static void
26653+dummy_netdev_init(struct net_device *ndev) {}
26654+
26655+static int __devinit
26656+acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
26657+{
26658+ acx111_ie_configoption_t co;
26659+ unsigned long mem_region1 = 0;
26660+ unsigned long mem_region2 = 0;
26661+ unsigned long mem_region1_size;
26662+ unsigned long mem_region2_size;
26663+ unsigned long phymem1;
26664+ unsigned long phymem2;
26665+ void *mem1 = NULL;
26666+ void *mem2 = NULL;
26667+ acx_device_t *adev = NULL;
26668+ struct net_device *ndev = NULL;
26669+ const char *chip_name;
26670+ int result = -EIO;
26671+ int err;
26672+ u8 chip_type;
26673+
26674+ FN_ENTER;
26675+
26676+ /* Enable the PCI device */
26677+ if (pci_enable_device(pdev)) {
26678+ printk("acx: pci_enable_device() FAILED\n");
26679+ result = -ENODEV;
26680+ goto fail_pci_enable_device;
26681+ }
26682+
26683+ /* enable busmastering (required for CardBus) */
26684+ pci_set_master(pdev);
26685+
26686+ /* FIXME: prism54 calls pci_set_mwi() here,
26687+ * should we do/support the same? */
26688+
26689+ /* chiptype is u8 but id->driver_data is ulong
26690+ ** Works for now (possible values are 1 and 2) */
26691+ chip_type = (u8)id->driver_data;
26692+ /* acx100 and acx111 have different PCI memory regions */
26693+ if (chip_type == CHIPTYPE_ACX100) {
26694+ chip_name = "ACX100";
26695+ mem_region1 = PCI_ACX100_REGION1;
26696+ mem_region1_size = PCI_ACX100_REGION1_SIZE;
26697+
26698+ mem_region2 = PCI_ACX100_REGION2;
26699+ mem_region2_size = PCI_ACX100_REGION2_SIZE;
26700+ } else if (chip_type == CHIPTYPE_ACX111) {
26701+ chip_name = "ACX111";
26702+ mem_region1 = PCI_ACX111_REGION1;
26703+ mem_region1_size = PCI_ACX111_REGION1_SIZE;
26704+
26705+ mem_region2 = PCI_ACX111_REGION2;
26706+ mem_region2_size = PCI_ACX111_REGION2_SIZE;
26707+ } else {
26708+ printk("acx: unknown chip type 0x%04X\n", chip_type);
26709+ goto fail_unknown_chiptype;
26710+ }
26711+
26712+ /* Figure out our resources */
26713+ phymem1 = pci_resource_start(pdev, mem_region1);
26714+ phymem2 = pci_resource_start(pdev, mem_region2);
26715+ if (!request_mem_region(phymem1, pci_resource_len(pdev, mem_region1), "acx_1")) {
26716+ printk("acx: cannot reserve PCI memory region 1 (are you sure "
26717+ "you have CardBus support in kernel?)\n");
26718+ goto fail_request_mem_region1;
26719+ }
26720+ if (!request_mem_region(phymem2, pci_resource_len(pdev, mem_region2), "acx_2")) {
26721+ printk("acx: cannot reserve PCI memory region 2\n");
26722+ goto fail_request_mem_region2;
26723+ }
26724+
26725+ /* this used to be ioremap(), but ioremap_nocache()
26726+ * is much less risky, right? (and slower?)
26727+ * FIXME: we may want to go back to cached variant if it's
26728+ * certain that our code really properly handles
26729+ * cached operation (memory barriers, volatile?, ...)
26730+ * (but always keep this comment here regardless!)
26731+ * Possibly make this a driver config setting? */
26732+
26733+ mem1 = ioremap_nocache(phymem1, mem_region1_size);
26734+ if (!mem1) {
26735+ printk("acx: ioremap() FAILED\n");
26736+ goto fail_ioremap1;
26737+ }
26738+ mem2 = ioremap_nocache(phymem2, mem_region2_size);
26739+ if (!mem2) {
26740+ printk("acx: ioremap() #2 FAILED\n");
26741+ goto fail_ioremap2;
26742+ }
26743+
26744+ printk("acx: found %s-based wireless network card at %s, irq:%d, "
26745+ "phymem1:0x%lX, phymem2:0x%lX, mem1:0x%p, mem1_size:%ld, "
26746+ "mem2:0x%p, mem2_size:%ld\n",
26747+ chip_name, pci_name(pdev), pdev->irq, phymem1, phymem2,
26748+ mem1, mem_region1_size,
26749+ mem2, mem_region2_size);
26750+ log(L_ANY, "initial debug setting is 0x%04X\n", acx_debug);
26751+
26752+ if (0 == pdev->irq) {
26753+ printk("acx: can't use IRQ 0\n");
26754+ goto fail_irq;
26755+ }
26756+
26757+ ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init);
26758+ /* (NB: memsets to 0 entire area) */
26759+ if (!ndev) {
26760+ printk("acx: no memory for netdevice struct\n");
26761+ goto fail_alloc_netdev;
26762+ }
26763+
26764+ ether_setup(ndev);
26765+ ndev->open = &acxpci_e_open;
26766+ ndev->stop = &acxpci_e_close;
26767+ ndev->hard_start_xmit = &acx_i_start_xmit;
26768+ ndev->get_stats = &acx_e_get_stats;
26769+#if IW_HANDLER_VERSION <= 5
26770+ ndev->get_wireless_stats = &acx_e_get_wireless_stats;
26771+#endif
26772+ ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def;
26773+ ndev->set_multicast_list = &acxpci_i_set_multicast_list;
26774+ ndev->tx_timeout = &acxpci_i_tx_timeout;
26775+ ndev->change_mtu = &acx_e_change_mtu;
26776+ ndev->watchdog_timeo = 4 * HZ;
26777+ ndev->irq = pdev->irq;
26778+ ndev->base_addr = pci_resource_start(pdev, 0);
26779+
26780+ adev = ndev2adev(ndev);
26781+ spin_lock_init(&adev->lock); /* initial state: unlocked */
26782+ /* We do not start with downed sem: we want PARANOID_LOCKING to work */
26783+ sema_init(&adev->sem, 1); /* initial state: 1 (upped) */
26784+ /* since nobody can see new netdev yet, we can as well
26785+ ** just _presume_ that we're under sem (instead of actually taking it): */
26786+ /* acx_sem_lock(adev); */
26787+ adev->pdev = pdev;
26788+ adev->ndev = ndev;
26789+ adev->dev_type = DEVTYPE_PCI;
26790+ adev->chip_type = chip_type;
26791+ adev->chip_name = chip_name;
26792+ adev->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111;
26793+ adev->membase = phymem1;
26794+ adev->iobase = mem1;
26795+ adev->membase2 = phymem2;
26796+ adev->iobase2 = mem2;
26797+ /* to find crashes due to weird driver access
26798+ * to unconfigured interface (ifup) */
26799+ adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead;
26800+
26801+#ifdef NONESSENTIAL_FEATURES
26802+ acx_show_card_eeprom_id(adev);
26803+#endif /* NONESSENTIAL_FEATURES */
26804+
26805+#ifdef SET_MODULE_OWNER
26806+ SET_MODULE_OWNER(ndev);
26807+#endif
26808+ SET_NETDEV_DEV(ndev, &pdev->dev);
26809+
26810+ log(L_IRQ|L_INIT, "using IRQ %d\n", pdev->irq);
26811+
26812+ /* need to be able to restore PCI state after a suspend */
26813+ pci_save_state(pdev);
26814+ pci_set_drvdata(pdev, ndev);
26815+
26816+ /* ok, pci setup is finished, now start initializing the card */
26817+
26818+ /* NB: read_reg() reads may return bogus data before reset_dev(),
26819+ * since the firmware which directly controls large parts of the I/O
26820+ * registers isn't initialized yet.
26821+ * acx100 seems to be more affected than acx111 */
26822+ if (OK != acxpci_s_reset_dev(adev))
26823+ goto fail_reset;
26824+
26825+ if (IS_ACX100(adev)) {
26826+ /* ACX100: configopt struct in cmd mailbox - directly after reset */
26827+ memcpy_fromio(&co, adev->cmd_area, sizeof(co));
26828+ }
26829+
26830+ if (OK != acx_s_init_mac(adev))
26831+ goto fail_init_mac;
26832+
26833+ if (IS_ACX111(adev)) {
26834+ /* ACX111: configopt struct needs to be queried after full init */
26835+ acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS);
26836+ }
26837+
26838+/* TODO: merge them into one function, they are called just once and are the same for pci & usb */
26839+ if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version))
26840+ goto fail_read_eeprom_version;
26841+
26842+ acx_s_parse_configoption(adev, &co);
26843+ acx_s_set_defaults(adev);
26844+ acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */
26845+ acx_display_hardware_details(adev);
26846+
26847+ /* Register the card, AFTER everything else has been set up,
26848+ * since otherwise an ioctl could step on our feet due to
26849+ * firmware operations happening in parallel or uninitialized data */
26850+ err = register_netdev(ndev);
26851+ if (OK != err) {
26852+ printk("acx: register_netdev() FAILED: %d\n", err);
26853+ goto fail_register_netdev;
26854+ }
26855+
26856+ acx_proc_register_entries(ndev);
26857+
26858+ /* Now we have our device, so make sure the kernel doesn't try
26859+ * to send packets even though we're not associated to a network yet */
26860+ acx_stop_queue(ndev, "on probe");
26861+ acx_carrier_off(ndev, "on probe");
26862+
26863+ /* after register_netdev() userspace may start working with dev
26864+ * (in particular, on other CPUs), we only need to up the sem */
26865+ /* acx_sem_unlock(adev); */
26866+
26867+ printk("acx "ACX_RELEASE": net device %s, driver compiled "
26868+ "against wireless extensions %d and Linux %s\n",
26869+ ndev->name, WIRELESS_EXT, UTS_RELEASE);
26870+
26871+#if CMD_DISCOVERY
26872+ great_inquisitor(adev);
26873+#endif
26874+
26875+ result = OK;
26876+ goto done;
26877+
26878+ /* error paths: undo everything in reverse order... */
26879+
26880+fail_register_netdev:
26881+
26882+ acxpci_s_delete_dma_regions(adev);
26883+ pci_set_drvdata(pdev, NULL);
26884+
26885+fail_init_mac:
26886+fail_read_eeprom_version:
26887+fail_reset:
26888+
26889+ free_netdev(ndev);
26890+fail_alloc_netdev:
26891+fail_irq:
26892+
26893+ iounmap(mem2);
26894+fail_ioremap2:
26895+
26896+ iounmap(mem1);
26897+fail_ioremap1:
26898+
26899+ release_mem_region(pci_resource_start(pdev, mem_region2),
26900+ pci_resource_len(pdev, mem_region2));
26901+fail_request_mem_region2:
26902+
26903+ release_mem_region(pci_resource_start(pdev, mem_region1),
26904+ pci_resource_len(pdev, mem_region1));
26905+fail_request_mem_region1:
26906+fail_unknown_chiptype:
26907+
26908+ pci_disable_device(pdev);
26909+fail_pci_enable_device:
26910+
26911+ pci_set_power_state(pdev, PCI_D3hot);
26912+
26913+done:
26914+ FN_EXIT1(result);
26915+ return result;
26916+}
26917+
26918+
26919+/***********************************************************************
26920+** acxpci_e_remove
26921+**
26922+** Shut device down (if not hot unplugged)
26923+** and deallocate PCI resources for the acx chip.
26924+**
26925+** pdev - ptr to PCI device structure containing info about pci configuration
26926+*/
26927+static void __devexit
26928+acxpci_e_remove(struct pci_dev *pdev)
26929+{
26930+ struct net_device *ndev;
26931+ acx_device_t *adev;
26932+ unsigned long mem_region1, mem_region2;
26933+ unsigned long flags;
26934+
26935+ FN_ENTER;
26936+
26937+ ndev = (struct net_device*) pci_get_drvdata(pdev);
26938+ if (!ndev) {
26939+ log(L_DEBUG, "%s: card is unused. Skipping any release code\n",
26940+ __func__);
26941+ goto end;
26942+ }
26943+
26944+ adev = ndev2adev(ndev);
26945+
26946+ /* If device wasn't hot unplugged... */
26947+ if (adev_present(adev)) {
26948+
26949+ acx_sem_lock(adev);
26950+
26951+ /* disable both Tx and Rx to shut radio down properly */
26952+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
26953+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0);
26954+
26955+#ifdef REDUNDANT
26956+ /* put the eCPU to sleep to save power
26957+ * Halting is not possible currently,
26958+ * since not supported by all firmware versions */
26959+ acx_s_issue_cmd(adev, ACX100_CMD_SLEEP, NULL, 0);
26960+#endif
26961+ acx_lock(adev, flags);
26962+ /* disable power LED to save power :-) */
26963+ log(L_INIT, "switching off power LED to save power\n");
26964+ acxpci_l_power_led(adev, 0);
26965+ /* stop our eCPU */
26966+ if (IS_ACX111(adev)) {
26967+ /* FIXME: does this actually keep halting the eCPU?
26968+ * I don't think so...
26969+ */
26970+ acxpci_l_reset_mac(adev);
26971+ } else {
26972+ u16 temp;
26973+ /* halt eCPU */
26974+ temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1;
26975+ write_reg16(adev, IO_ACX_ECPU_CTRL, temp);
26976+ write_flush(adev);
26977+ }
26978+ acx_unlock(adev, flags);
26979+
26980+ acx_sem_unlock(adev);
26981+ }
26982+
26983+ /* unregister the device to not let the kernel
26984+ * (e.g. ioctls) access a half-deconfigured device
26985+ * NB: this will cause acxpci_e_close() to be called,
26986+ * thus we shouldn't call it under sem! */
26987+ log(L_INIT, "removing device %s\n", ndev->name);
26988+ unregister_netdev(ndev);
26989+
26990+ /* unregister_netdev ensures that no references to us left.
26991+ * For paranoid reasons we continue to follow the rules */
26992+ acx_sem_lock(adev);
26993+
26994+ if (adev->dev_state_mask & ACX_STATE_IFACE_UP) {
26995+ acxpci_s_down(ndev);
26996+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
26997+ }
26998+
26999+ acx_proc_unregister_entries(ndev);
27000+
27001+ if (IS_ACX100(adev)) {
27002+ mem_region1 = PCI_ACX100_REGION1;
27003+ mem_region2 = PCI_ACX100_REGION2;
27004+ } else {
27005+ mem_region1 = PCI_ACX111_REGION1;
27006+ mem_region2 = PCI_ACX111_REGION2;
27007+ }
27008+
27009+ /* finally, clean up PCI bus state */
27010+ acxpci_s_delete_dma_regions(adev);
27011+ if (adev->iobase) iounmap(adev->iobase);
27012+ if (adev->iobase2) iounmap(adev->iobase2);
27013+ release_mem_region(pci_resource_start(pdev, mem_region1),
27014+ pci_resource_len(pdev, mem_region1));
27015+ release_mem_region(pci_resource_start(pdev, mem_region2),
27016+ pci_resource_len(pdev, mem_region2));
27017+ pci_disable_device(pdev);
27018+
27019+ /* remove dev registration */
27020+ pci_set_drvdata(pdev, NULL);
27021+
27022+ acx_sem_unlock(adev);
27023+
27024+ /* Free netdev (quite late,
27025+ * since otherwise we might get caught off-guard
27026+ * by a netdev timeout handler execution
27027+ * expecting to see a working dev...) */
27028+ free_netdev(ndev);
27029+
27030+ /* put device into ACPI D3 mode (shutdown) */
27031+ pci_set_power_state(pdev, PCI_D3hot);
27032+
27033+end:
27034+ FN_EXIT0;
27035+}
27036+
27037+
27038+/***********************************************************************
27039+** TODO: PM code needs to be fixed / debugged / tested.
27040+*/
27041+#ifdef CONFIG_PM
27042+static int
27043+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
27044+acxpci_e_suspend(struct pci_dev *pdev, pm_message_t state)
27045+#else
27046+acxpci_e_suspend(struct pci_dev *pdev, u32 state)
27047+#endif
27048+{
27049+ struct net_device *ndev = pci_get_drvdata(pdev);
27050+ acx_device_t *adev;
27051+
27052+ FN_ENTER;
27053+ printk("acx: suspend handler is experimental!\n");
27054+ printk("sus: dev %p\n", ndev);
27055+
27056+ if (!netif_running(ndev))
27057+ goto end;
27058+
27059+ adev = ndev2adev(ndev);
27060+ printk("sus: adev %p\n", adev);
27061+
27062+ acx_sem_lock(adev);
27063+
27064+ netif_device_detach(ndev); /* this one cannot sleep */
27065+ acxpci_s_down(ndev);
27066+ /* down() does not set it to 0xffff, but here we really want that */
27067+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
27068+ write_reg16(adev, IO_ACX_FEMR, 0x0);
27069+ acxpci_s_delete_dma_regions(adev);
27070+ pci_save_state(pdev);
27071+ pci_set_power_state(pdev, PCI_D3hot);
27072+
27073+ acx_sem_unlock(adev);
27074+end:
27075+ FN_EXIT0;
27076+ return OK;
27077+}
27078+
27079+
27080+static int
27081+acxpci_e_resume(struct pci_dev *pdev)
27082+{
27083+ struct net_device *ndev = pci_get_drvdata(pdev);
27084+ acx_device_t *adev;
27085+
27086+ FN_ENTER;
27087+
27088+ printk("acx: resume handler is experimental!\n");
27089+ printk("rsm: got dev %p\n", ndev);
27090+
27091+ if (!netif_running(ndev))
27092+ goto end;
27093+
27094+ adev = ndev2adev(ndev);
27095+ printk("rsm: got adev %p\n", adev);
27096+
27097+ acx_sem_lock(adev);
27098+
27099+ pci_set_power_state(pdev, PCI_D0);
27100+ printk("rsm: power state PCI_D0 set\n");
27101+ pci_restore_state(pdev);
27102+ printk("rsm: PCI state restored\n");
27103+
27104+ if (OK != acxpci_s_reset_dev(adev))
27105+ goto end_unlock;
27106+ printk("rsm: device reset done\n");
27107+ if (OK != acx_s_init_mac(adev))
27108+ goto end_unlock;
27109+ printk("rsm: init MAC done\n");
27110+
27111+ acxpci_s_up(ndev);
27112+ printk("rsm: acx up done\n");
27113+
27114+ /* now even reload all card parameters as they were before suspend,
27115+ * and possibly be back in the network again already :-) */
27116+ if (ACX_STATE_IFACE_UP & adev->dev_state_mask) {
27117+ adev->set_mask = GETSET_ALL;
27118+ acx_s_update_card_settings(adev);
27119+ printk("rsm: settings updated\n");
27120+ }
27121+ netif_device_attach(ndev);
27122+ printk("rsm: device attached\n");
27123+
27124+end_unlock:
27125+ acx_sem_unlock(adev);
27126+end:
27127+ /* we need to return OK here anyway, right? */
27128+ FN_EXIT0;
27129+ return OK;
27130+}
27131+#endif /* CONFIG_PM */
27132+
27133+
27134+/***********************************************************************
27135+** acxpci_s_up
27136+**
27137+** This function is called by acxpci_e_open (when ifconfig sets the device as up)
27138+**
27139+** Side effects:
27140+** - Enables on-card interrupt requests
27141+** - calls acx_s_start
27142+*/
27143+
27144+static void
27145+enable_acx_irq(acx_device_t *adev)
27146+{
27147+ FN_ENTER;
27148+ write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask);
27149+ write_reg16(adev, IO_ACX_FEMR, 0x8000);
27150+ adev->irqs_active = 1;
27151+ FN_EXIT0;
27152+}
27153+
27154+static void
27155+acxpci_s_up(struct net_device *ndev)
27156+{
27157+ acx_device_t *adev = ndev2adev(ndev);
27158+ unsigned long flags;
27159+
27160+ FN_ENTER;
27161+
27162+ acx_lock(adev, flags);
27163+ enable_acx_irq(adev);
27164+ acx_unlock(adev, flags);
27165+
27166+ /* acx fw < 1.9.3.e has a hardware timer, and older drivers
27167+ ** used to use it. But we don't do that anymore, our OS
27168+ ** has reliable software timers */
27169+ init_timer(&adev->mgmt_timer);
27170+ adev->mgmt_timer.function = acx_i_timer;
27171+ adev->mgmt_timer.data = (unsigned long)adev;
27172+
27173+ /* Need to set ACX_STATE_IFACE_UP first, or else
27174+ ** timer won't be started by acx_set_status() */
27175+ SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
27176+ switch (adev->mode) {
27177+ case ACX_MODE_0_ADHOC:
27178+ case ACX_MODE_2_STA:
27179+ /* actual scan cmd will happen in start() */
27180+ acx_set_status(adev, ACX_STATUS_1_SCANNING); break;
27181+ case ACX_MODE_3_AP:
27182+ case ACX_MODE_MONITOR:
27183+ acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); break;
27184+ }
27185+
27186+ acx_s_start(adev);
27187+
27188+ FN_EXIT0;
27189+}
27190+
27191+
27192+/***********************************************************************
27193+** acxpci_s_down
27194+**
27195+** NB: device may be already hot unplugged if called from acxpci_e_remove()
27196+**
27197+** Disables on-card interrupt request, stops softirq and timer, stops queue,
27198+** sets status == STOPPED
27199+*/
27200+
27201+static void
27202+disable_acx_irq(acx_device_t *adev)
27203+{
27204+ FN_ENTER;
27205+
27206+ /* I guess mask is not 0xffff because acx100 won't signal
27207+ ** cmd completion then (needed for ifup).
27208+ ** Someone with acx100 please confirm */
27209+ write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask_off);
27210+ write_reg16(adev, IO_ACX_FEMR, 0x0);
27211+ adev->irqs_active = 0;
27212+ FN_EXIT0;
27213+}
27214+
27215+static void
27216+acxpci_s_down(struct net_device *ndev)
27217+{
27218+ acx_device_t *adev = ndev2adev(ndev);
27219+ unsigned long flags;
27220+
27221+ FN_ENTER;
27222+
27223+ /* Disable IRQs first, so that IRQs cannot race with us */
27224+ /* then wait until interrupts have finished executing on other CPUs */
27225+ acx_lock(adev, flags);
27226+ disable_acx_irq(adev);
27227+ synchronize_irq(adev->pdev->irq);
27228+ acx_unlock(adev, flags);
27229+
27230+ /* we really don't want to have an asynchronous tasklet disturb us
27231+ ** after something vital for its job has been shut down, so
27232+ ** end all remaining work now.
27233+ **
27234+ ** NB: carrier_off (done by set_status below) would lead to
27235+ ** not yet fully understood deadlock in FLUSH_SCHEDULED_WORK().
27236+ ** That's why we do FLUSH first.
27237+ **
27238+ ** NB2: we have a bad locking bug here: FLUSH_SCHEDULED_WORK()
27239+ ** waits for acx_e_after_interrupt_task to complete if it is running
27240+ ** on another CPU, but acx_e_after_interrupt_task
27241+ ** will sleep on sem forever, because it is taken by us!
27242+ ** Work around that by temporary sem unlock.
27243+ ** This will fail miserably if we'll be hit by concurrent
27244+ ** iwconfig or something in between. TODO! */
27245+ acx_sem_unlock(adev);
27246+ FLUSH_SCHEDULED_WORK();
27247+ acx_sem_lock(adev);
27248+
27249+ /* This is possible:
27250+ ** FLUSH_SCHEDULED_WORK -> acx_e_after_interrupt_task ->
27251+ ** -> set_status(ASSOCIATED) -> wake_queue()
27252+ ** That's why we stop queue _after_ FLUSH_SCHEDULED_WORK
27253+ ** lock/unlock is just paranoia, maybe not needed */
27254+ acx_lock(adev, flags);
27255+ acx_stop_queue(ndev, "on ifdown");
27256+ acx_set_status(adev, ACX_STATUS_0_STOPPED);
27257+ acx_unlock(adev, flags);
27258+
27259+ /* kernel/timer.c says it's illegal to del_timer_sync()
27260+ ** a timer which restarts itself. We guarantee this cannot
27261+ ** ever happen because acx_i_timer() never does this if
27262+ ** status is ACX_STATUS_0_STOPPED */
27263+ del_timer_sync(&adev->mgmt_timer);
27264+
27265+ FN_EXIT0;
27266+}
27267+
27268+
27269+/***********************************************************************
27270+** acxpci_e_open
27271+**
27272+** Called as a result of SIOCSIFFLAGS ioctl changing the flags bit IFF_UP
27273+** from clear to set. In other words: ifconfig up.
27274+**
27275+** Returns:
27276+** 0 success
27277+** >0 f/w reported error
27278+** <0 driver reported error
27279+*/
27280+static int
27281+acxpci_e_open(struct net_device *ndev)
27282+{
27283+ acx_device_t *adev = ndev2adev(ndev);
27284+ int result = OK;
27285+
27286+ FN_ENTER;
27287+
27288+ acx_sem_lock(adev);
27289+
27290+ acx_init_task_scheduler(adev);
27291+
27292+/* TODO: pci_set_power_state(pdev, PCI_D0); ? */
27293+
27294+ /* request shared IRQ handler */
27295+ if (request_irq(ndev->irq, acxpci_i_interrupt, SA_SHIRQ, ndev->name, ndev)) {
27296+ printk("%s: request_irq FAILED\n", ndev->name);
27297+ result = -EAGAIN;
27298+ goto done;
27299+ }
27300+ log(L_DEBUG|L_IRQ, "request_irq %d successful\n", ndev->irq);
27301+
27302+ /* ifup device */
27303+ acxpci_s_up(ndev);
27304+
27305+ /* We don't currently have to do anything else.
27306+ * The setup of the MAC should be subsequently completed via
27307+ * the mlme commands.
27308+ * Higher layers know we're ready from dev->start==1 and
27309+ * dev->tbusy==0. Our rx path knows to pass up received/
27310+ * frames because of dev->flags&IFF_UP is true.
27311+ */
27312+done:
27313+ acx_sem_unlock(adev);
27314+
27315+ FN_EXIT1(result);
27316+ return result;
27317+}
27318+
27319+
27320+/***********************************************************************
27321+** acxpci_e_close
27322+**
27323+** Called as a result of SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
27324+** from set to clear. I.e. called by "ifconfig DEV down"
27325+**
27326+** Returns:
27327+** 0 success
27328+** >0 f/w reported error
27329+** <0 driver reported error
27330+*/
27331+static int
27332+acxpci_e_close(struct net_device *ndev)
27333+{
27334+ acx_device_t *adev = ndev2adev(ndev);
27335+
27336+ FN_ENTER;
27337+
27338+ acx_sem_lock(adev);
27339+
27340+ /* ifdown device */
27341+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
27342+ if (netif_device_present(ndev)) {
27343+ acxpci_s_down(ndev);
27344+ }
27345+
27346+ /* disable all IRQs, release shared IRQ handler */
27347+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
27348+ write_reg16(adev, IO_ACX_FEMR, 0x0);
27349+ free_irq(ndev->irq, ndev);
27350+
27351+/* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */
27352+
27353+ /* We currently don't have to do anything else.
27354+ * Higher layers know we're not ready from dev->start==0 and
27355+ * dev->tbusy==1. Our rx path knows to not pass up received
27356+ * frames because of dev->flags&IFF_UP is false.
27357+ */
27358+ acx_sem_unlock(adev);
27359+
27360+ log(L_INIT, "closed device\n");
27361+ FN_EXIT0;
27362+ return OK;
27363+}
27364+
27365+
27366+/***********************************************************************
27367+** acxpci_i_tx_timeout
27368+**
27369+** Called from network core. Must not sleep!
27370+*/
27371+static void
27372+acxpci_i_tx_timeout(struct net_device *ndev)
27373+{
27374+ acx_device_t *adev = ndev2adev(ndev);
27375+ unsigned long flags;
27376+ unsigned int tx_num_cleaned;
27377+
27378+ FN_ENTER;
27379+
27380+ acx_lock(adev, flags);
27381+
27382+ /* clean processed tx descs, they may have been completely full */
27383+ tx_num_cleaned = acxpci_l_clean_txdesc(adev);
27384+
27385+ /* nothing cleaned, yet (almost) no free buffers available?
27386+ * --> clean all tx descs, no matter which status!!
27387+ * Note that I strongly suspect that doing emergency cleaning
27388+ * may confuse the firmware. This is a last ditch effort to get
27389+ * ANYTHING to work again...
27390+ *
27391+ * TODO: it's best to simply reset & reinit hw from scratch...
27392+ */
27393+ if ((adev->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) {
27394+ printk("%s: FAILED to free any of the many full tx buffers. "
27395+ "Switching to emergency freeing. "
27396+ "Please report!\n", ndev->name);
27397+ acxpci_l_clean_txdesc_emergency(adev);
27398+ }
27399+
27400+ if (acx_queue_stopped(ndev) && (ACX_STATUS_4_ASSOCIATED == adev->status))
27401+ acx_wake_queue(ndev, "after tx timeout");
27402+
27403+ /* stall may have happened due to radio drift, so recalib radio */
27404+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
27405+
27406+ /* do unimportant work last */
27407+ printk("%s: tx timeout!\n", ndev->name);
27408+ adev->stats.tx_errors++;
27409+
27410+ acx_unlock(adev, flags);
27411+
27412+ FN_EXIT0;
27413+}
27414+
27415+
27416+/***********************************************************************
27417+** acxpci_i_set_multicast_list
27418+** FIXME: most likely needs refinement
27419+*/
27420+static void
27421+acxpci_i_set_multicast_list(struct net_device *ndev)
27422+{
27423+ acx_device_t *adev = ndev2adev(ndev);
27424+ unsigned long flags;
27425+
27426+ FN_ENTER;
27427+
27428+ acx_lock(adev, flags);
27429+
27430+ /* firmwares don't have allmulti capability,
27431+ * so just use promiscuous mode instead in this case. */
27432+ if (ndev->flags & (IFF_PROMISC|IFF_ALLMULTI)) {
27433+ SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
27434+ CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
27435+ SET_BIT(adev->set_mask, SET_RXCONFIG);
27436+ /* let kernel know in case *we* needed to set promiscuous */
27437+ ndev->flags |= (IFF_PROMISC|IFF_ALLMULTI);
27438+ } else {
27439+ CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS);
27440+ SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI);
27441+ SET_BIT(adev->set_mask, SET_RXCONFIG);
27442+ ndev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI);
27443+ }
27444+
27445+ /* cannot update card settings directly here, atomic context */
27446+ acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG);
27447+
27448+ acx_unlock(adev, flags);
27449+
27450+ FN_EXIT0;
27451+}
27452+
27453+
27454+/***************************************************************
27455+** acxpci_l_process_rxdesc
27456+**
27457+** Called directly and only from the IRQ handler
27458+*/
27459+
27460+#if !ACX_DEBUG
27461+static inline void log_rxbuffer(const acx_device_t *adev) {}
27462+#else
27463+static void
27464+log_rxbuffer(const acx_device_t *adev)
27465+{
27466+ register const struct rxhostdesc *rxhostdesc;
27467+ int i;
27468+ /* no FN_ENTER here, we don't want that */
27469+
27470+ rxhostdesc = adev->rxhostdesc_start;
27471+ if (unlikely(!rxhostdesc)) return;
27472+ for (i = 0; i < RX_CNT; i++) {
27473+ if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
27474+ && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
27475+ printk("rx: buf %d full\n", i);
27476+ rxhostdesc++;
27477+ }
27478+}
27479+#endif
27480+
27481+static void
27482+acxpci_l_process_rxdesc(acx_device_t *adev)
27483+{
27484+ register rxhostdesc_t *hostdesc;
27485+ unsigned count, tail;
27486+
27487+ FN_ENTER;
27488+
27489+ if (unlikely(acx_debug & L_BUFR))
27490+ log_rxbuffer(adev);
27491+
27492+ /* First, have a loop to determine the first descriptor that's
27493+ * full, just in case there's a mismatch between our current
27494+ * rx_tail and the full descriptor we're supposed to handle. */
27495+ tail = adev->rx_tail;
27496+ count = RX_CNT;
27497+ while (1) {
27498+ hostdesc = &adev->rxhostdesc_start[tail];
27499+ /* advance tail regardless of outcome of the below test */
27500+ tail = (tail + 1) % RX_CNT;
27501+
27502+ if ((hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
27503+ && (hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
27504+ break; /* found it! */
27505+
27506+ if (unlikely(!--count)) /* hmm, no luck: all descs empty, bail out */
27507+ goto end;
27508+ }
27509+
27510+ /* now process descriptors, starting with the first we figured out */
27511+ while (1) {
27512+ log(L_BUFR, "rx: tail=%u Ctl_16=%04X Status=%08X\n",
27513+ tail, hostdesc->Ctl_16, hostdesc->Status);
27514+
27515+ acx_l_process_rxbuf(adev, hostdesc->data);
27516+
27517+ hostdesc->Status = 0;
27518+ /* flush all writes before adapter sees CTL_HOSTOWN change */
27519+ wmb();
27520+ /* Host no longer owns this, needs to be LAST */
27521+ CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN));
27522+
27523+ /* ok, descriptor is handled, now check the next descriptor */
27524+ hostdesc = &adev->rxhostdesc_start[tail];
27525+
27526+ /* if next descriptor is empty, then bail out */
27527+ if (!(hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
27528+ || !(hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)))
27529+ break;
27530+
27531+ tail = (tail + 1) % RX_CNT;
27532+ }
27533+end:
27534+ adev->rx_tail = tail;
27535+ FN_EXIT0;
27536+}
27537+
27538+
27539+/***********************************************************************
27540+** acxpci_i_interrupt
27541+**
27542+** IRQ handler (atomic context, must not sleep, blah, blah)
27543+*/
27544+
27545+/* scan is complete. all frames now on the receive queue are valid */
27546+#define INFO_SCAN_COMPLETE 0x0001
27547+#define INFO_WEP_KEY_NOT_FOUND 0x0002
27548+/* hw has been reset as the result of a watchdog timer timeout */
27549+#define INFO_WATCH_DOG_RESET 0x0003
27550+/* failed to send out NULL frame from PS mode notification to AP */
27551+/* recommended action: try entering 802.11 PS mode again */
27552+#define INFO_PS_FAIL 0x0004
27553+/* encryption/decryption process on a packet failed */
27554+#define INFO_IV_ICV_FAILURE 0x0005
27555+
27556+/* Info mailbox format:
27557+2 bytes: type
27558+2 bytes: status
27559+more bytes may follow
27560+ rumors say about status:
27561+ 0x0000 info available (set by hw)
27562+ 0x0001 information received (must be set by host)
27563+ 0x1000 info available, mailbox overflowed (messages lost) (set by hw)
27564+ but in practice we've seen:
27565+ 0x9000 when we did not set status to 0x0001 on prev message
27566+ 0x1001 when we did set it
27567+ 0x0000 was never seen
27568+ conclusion: this is really a bitfield:
27569+ 0x1000 is 'info available' bit
27570+ 'mailbox overflowed' bit is 0x8000, not 0x1000
27571+ value of 0x0000 probably means that there are no messages at all
27572+ P.S. I dunno how in hell hw is supposed to notice that messages are lost -
27573+ it does NOT clear bit 0x0001, and this bit will probably stay forever set
27574+ after we set it once. Let's hope this will be fixed in firmware someday
27575+*/
27576+
27577+static void
27578+handle_info_irq(acx_device_t *adev)
27579+{
27580+#if ACX_DEBUG
27581+ static const char * const info_type_msg[] = {
27582+ "(unknown)",
27583+ "scan complete",
27584+ "WEP key not found",
27585+ "internal watchdog reset was done",
27586+ "failed to send powersave (NULL frame) notification to AP",
27587+ "encrypt/decrypt on a packet has failed",
27588+ "TKIP tx keys disabled",
27589+ "TKIP rx keys disabled",
27590+ "TKIP rx: key ID not found",
27591+ "???",
27592+ "???",
27593+ "???",
27594+ "???",
27595+ "???",
27596+ "???",
27597+ "???",
27598+ "TKIP IV value exceeds thresh"
27599+ };
27600+#endif
27601+ u32 info_type, info_status;
27602+
27603+ info_type = readl(adev->info_area);
27604+ info_status = (info_type >> 16);
27605+ info_type = (u16)info_type;
27606+
27607+ /* inform fw that we have read this info message */
27608+ writel(info_type | 0x00010000, adev->info_area);
27609+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_INFOACK);
27610+ write_flush(adev);
27611+
27612+ log(L_CTL, "info_type:%04X info_status:%04X\n",
27613+ info_type, info_status);
27614+
27615+ log(L_IRQ, "got Info IRQ: status %04X type %04X: %s\n",
27616+ info_status, info_type,
27617+ info_type_msg[(info_type >= VEC_SIZE(info_type_msg)) ?
27618+ 0 : info_type]
27619+ );
27620+}
27621+
27622+
27623+static void
27624+log_unusual_irq(u16 irqtype) {
27625+ /*
27626+ if (!printk_ratelimit())
27627+ return;
27628+ */
27629+
27630+ printk("acx: got");
27631+ if (irqtype & HOST_INT_RX_DATA) {
27632+ printk(" Rx_Data");
27633+ }
27634+ /* HOST_INT_TX_COMPLETE */
27635+ if (irqtype & HOST_INT_TX_XFER) {
27636+ printk(" Tx_Xfer");
27637+ }
27638+ /* HOST_INT_RX_COMPLETE */
27639+ if (irqtype & HOST_INT_DTIM) {
27640+ printk(" DTIM");
27641+ }
27642+ if (irqtype & HOST_INT_BEACON) {
27643+ printk(" Beacon");
27644+ }
27645+ if (irqtype & HOST_INT_TIMER) {
27646+ log(L_IRQ, " Timer");
27647+ }
27648+ if (irqtype & HOST_INT_KEY_NOT_FOUND) {
27649+ printk(" Key_Not_Found");
27650+ }
27651+ if (irqtype & HOST_INT_IV_ICV_FAILURE) {
27652+ printk(" IV_ICV_Failure (crypto)");
27653+ }
27654+ /* HOST_INT_CMD_COMPLETE */
27655+ /* HOST_INT_INFO */
27656+ if (irqtype & HOST_INT_OVERFLOW) {
27657+ printk(" Overflow");
27658+ }
27659+ if (irqtype & HOST_INT_PROCESS_ERROR) {
27660+ printk(" Process_Error");
27661+ }
27662+ /* HOST_INT_SCAN_COMPLETE */
27663+ if (irqtype & HOST_INT_FCS_THRESHOLD) {
27664+ printk(" FCS_Threshold");
27665+ }
27666+ if (irqtype & HOST_INT_UNKNOWN) {
27667+ printk(" Unknown");
27668+ }
27669+ printk(" IRQ(s)\n");
27670+}
27671+
27672+
27673+static void
27674+update_link_quality_led(acx_device_t *adev)
27675+{
27676+ int qual;
27677+
27678+ qual = acx_signal_determine_quality(adev->wstats.qual.level, adev->wstats.qual.noise);
27679+ if (qual > adev->brange_max_quality)
27680+ qual = adev->brange_max_quality;
27681+
27682+ if (time_after(jiffies, adev->brange_time_last_state_change +
27683+ (HZ/2 - HZ/2 * (unsigned long)qual / adev->brange_max_quality ) )) {
27684+ acxpci_l_power_led(adev, (adev->brange_last_state == 0));
27685+ adev->brange_last_state ^= 1; /* toggle */
27686+ adev->brange_time_last_state_change = jiffies;
27687+ }
27688+}
27689+
27690+
27691+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */
27692+
27693+static irqreturn_t
27694+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
27695+acxpci_i_interrupt(int irq, void *dev_id)
27696+#else
27697+acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
27698+#endif
27699+{
27700+ acx_device_t *adev;
27701+ unsigned long flags;
27702+ unsigned int irqcount = MAX_IRQLOOPS_PER_JIFFY;
27703+ register u16 irqtype;
27704+ u16 unmasked;
27705+
27706+ adev = ndev2adev((struct net_device*)dev_id);
27707+
27708+ /* LOCKING: can just spin_lock() since IRQs are disabled anyway.
27709+ * I am paranoid */
27710+ acx_lock(adev, flags);
27711+
27712+ unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR);
27713+ if (unlikely(0xffff == unmasked)) {
27714+ /* 0xffff value hints at missing hardware,
27715+ * so don't do anything.
27716+ * Not very clean, but other drivers do the same... */
27717+ log(L_IRQ, "IRQ type:FFFF - device removed? IRQ_NONE\n");
27718+ goto none;
27719+ }
27720+
27721+ /* We will check only "interesting" IRQ types */
27722+ irqtype = unmasked & ~adev->irq_mask;
27723+ if (!irqtype) {
27724+ /* We are on a shared IRQ line and it wasn't our IRQ */
27725+ log(L_IRQ, "IRQ type:%04X, mask:%04X - all are masked, IRQ_NONE\n",
27726+ unmasked, adev->irq_mask);
27727+ goto none;
27728+ }
27729+
27730+ /* Done here because IRQ_NONEs taking three lines of log
27731+ ** drive me crazy */
27732+ FN_ENTER;
27733+
27734+#define IRQ_ITERATE 1
27735+#if IRQ_ITERATE
27736+if (jiffies != adev->irq_last_jiffies) {
27737+ adev->irq_loops_this_jiffy = 0;
27738+ adev->irq_last_jiffies = jiffies;
27739+}
27740+
27741+/* safety condition; we'll normally abort loop below
27742+ * in case no IRQ type occurred */
27743+while (likely(--irqcount)) {
27744+#endif
27745+ /* ACK all IRQs ASAP */
27746+ write_reg16(adev, IO_ACX_IRQ_ACK, 0xffff);
27747+
27748+ log(L_IRQ, "IRQ type:%04X, mask:%04X, type & ~mask:%04X\n",
27749+ unmasked, adev->irq_mask, irqtype);
27750+
27751+ /* Handle most important IRQ types first */
27752+ if (irqtype & HOST_INT_RX_COMPLETE) {
27753+ log(L_IRQ, "got Rx_Complete IRQ\n");
27754+ acxpci_l_process_rxdesc(adev);
27755+ }
27756+ if (irqtype & HOST_INT_TX_COMPLETE) {
27757+ log(L_IRQ, "got Tx_Complete IRQ\n");
27758+ /* don't clean up on each Tx complete, wait a bit
27759+ * unless we're going towards full, in which case
27760+ * we do it immediately, too (otherwise we might lockup
27761+ * with a full Tx buffer if we go into
27762+ * acxpci_l_clean_txdesc() at a time when we won't wakeup
27763+ * the net queue in there for some reason...) */
27764+ if (adev->tx_free <= TX_START_CLEAN) {
27765+#if TX_CLEANUP_IN_SOFTIRQ
27766+ acx_schedule_task(adev, ACX_AFTER_IRQ_TX_CLEANUP);
27767+#else
27768+ acxpci_l_clean_txdesc(adev);
27769+#endif
27770+ }
27771+ }
27772+
27773+ /* Less frequent ones */
27774+ if (irqtype & (0
27775+ | HOST_INT_CMD_COMPLETE
27776+ | HOST_INT_INFO
27777+ | HOST_INT_SCAN_COMPLETE
27778+ )) {
27779+ if (irqtype & HOST_INT_CMD_COMPLETE) {
27780+ log(L_IRQ, "got Command_Complete IRQ\n");
27781+ /* save the state for the running issue_cmd() */
27782+ SET_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE);
27783+ }
27784+ if (irqtype & HOST_INT_INFO) {
27785+ handle_info_irq(adev);
27786+ }
27787+ if (irqtype & HOST_INT_SCAN_COMPLETE) {
27788+ log(L_IRQ, "got Scan_Complete IRQ\n");
27789+ /* need to do that in process context */
27790+ acx_schedule_task(adev, ACX_AFTER_IRQ_COMPLETE_SCAN);
27791+ /* remember that fw is not scanning anymore */
27792+ SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE);
27793+ }
27794+ }
27795+
27796+ /* These we just log, but either they happen rarely
27797+ * or we keep them masked out */
27798+ if (irqtype & (0
27799+ | HOST_INT_RX_DATA
27800+ /* | HOST_INT_TX_COMPLETE */
27801+ | HOST_INT_TX_XFER
27802+ /* | HOST_INT_RX_COMPLETE */
27803+ | HOST_INT_DTIM
27804+ | HOST_INT_BEACON
27805+ | HOST_INT_TIMER
27806+ | HOST_INT_KEY_NOT_FOUND
27807+ | HOST_INT_IV_ICV_FAILURE
27808+ /* | HOST_INT_CMD_COMPLETE */
27809+ /* | HOST_INT_INFO */
27810+ | HOST_INT_OVERFLOW
27811+ | HOST_INT_PROCESS_ERROR
27812+ /* | HOST_INT_SCAN_COMPLETE */
27813+ | HOST_INT_FCS_THRESHOLD
27814+ | HOST_INT_UNKNOWN
27815+ )) {
27816+ log_unusual_irq(irqtype);
27817+ }
27818+
27819+#if IRQ_ITERATE
27820+ unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR);
27821+ irqtype = unmasked & ~adev->irq_mask;
27822+ /* Bail out if no new IRQ bits or if all are masked out */
27823+ if (!irqtype)
27824+ break;
27825+
27826+ if (unlikely(++adev->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) {
27827+ printk(KERN_ERR "acx: too many interrupts per jiffy!\n");
27828+ /* Looks like card floods us with IRQs! Try to stop that */
27829+ write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff);
27830+ /* This will short-circuit all future attempts to handle IRQ.
27831+ * We cant do much more... */
27832+ adev->irq_mask = 0;
27833+ break;
27834+ }
27835+}
27836+#endif
27837+ /* Routine to perform blink with range */
27838+ if (unlikely(adev->led_power == 2))
27839+ update_link_quality_led(adev);
27840+
27841+/* handled: */
27842+ /* write_flush(adev); - not needed, last op was read anyway */
27843+ acx_unlock(adev, flags);
27844+ FN_EXIT0;
27845+ return IRQ_HANDLED;
27846+
27847+none:
27848+ acx_unlock(adev, flags);
27849+ return IRQ_NONE;
27850+}
27851+
27852+
27853+/***********************************************************************
27854+** acxpci_l_power_led
27855+*/
27856+void
27857+acxpci_l_power_led(acx_device_t *adev, int enable)
27858+{
27859+ u16 gpio_pled = IS_ACX111(adev) ? 0x0040 : 0x0800;
27860+
27861+ /* A hack. Not moving message rate limiting to adev->xxx
27862+ * (it's only a debug message after all) */
27863+ static int rate_limit = 0;
27864+
27865+ if (rate_limit++ < 3)
27866+ log(L_IOCTL, "Please report in case toggling the power "
27867+ "LED doesn't work for your card!\n");
27868+ if (enable)
27869+ write_reg16(adev, IO_ACX_GPIO_OUT,
27870+ read_reg16(adev, IO_ACX_GPIO_OUT) & ~gpio_pled);
27871+ else
27872+ write_reg16(adev, IO_ACX_GPIO_OUT,
27873+ read_reg16(adev, IO_ACX_GPIO_OUT) | gpio_pled);
27874+}
27875+
27876+
27877+/***********************************************************************
27878+** Ioctls
27879+*/
27880+
27881+/***********************************************************************
27882+*/
27883+int
27884+acx111pci_ioctl_info(
27885+ struct net_device *ndev,
27886+ struct iw_request_info *info,
27887+ struct iw_param *vwrq,
27888+ char *extra)
27889+{
27890+#if ACX_DEBUG > 1
27891+ acx_device_t *adev = ndev2adev(ndev);
27892+ rxdesc_t *rxdesc;
27893+ txdesc_t *txdesc;
27894+ rxhostdesc_t *rxhostdesc;
27895+ txhostdesc_t *txhostdesc;
27896+ struct acx111_ie_memoryconfig memconf;
27897+ struct acx111_ie_queueconfig queueconf;
27898+ unsigned long flags;
27899+ int i;
27900+ char memmap[0x34];
27901+ char rxconfig[0x8];
27902+ char fcserror[0x8];
27903+ char ratefallback[0x5];
27904+
27905+ if ( !(acx_debug & (L_IOCTL|L_DEBUG)) )
27906+ return OK;
27907+ /* using printk() since we checked debug flag already */
27908+
27909+ acx_sem_lock(adev);
27910+
27911+ if (!IS_ACX111(adev)) {
27912+ printk("acx111-specific function called "
27913+ "with non-acx111 chip, aborting\n");
27914+ goto end_ok;
27915+ }
27916+
27917+ /* get Acx111 Memory Configuration */
27918+ memset(&memconf, 0, sizeof(memconf));
27919+ /* BTW, fails with 12 (Write only) error code.
27920+ ** Retained for easy testing of issue_cmd error handling :) */
27921+ acx_s_interrogate(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG);
27922+
27923+ /* get Acx111 Queue Configuration */
27924+ memset(&queueconf, 0, sizeof(queueconf));
27925+ acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS);
27926+
27927+ /* get Acx111 Memory Map */
27928+ memset(memmap, 0, sizeof(memmap));
27929+ acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP);
27930+
27931+ /* get Acx111 Rx Config */
27932+ memset(rxconfig, 0, sizeof(rxconfig));
27933+ acx_s_interrogate(adev, &rxconfig, ACX1xx_IE_RXCONFIG);
27934+
27935+ /* get Acx111 fcs error count */
27936+ memset(fcserror, 0, sizeof(fcserror));
27937+ acx_s_interrogate(adev, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT);
27938+
27939+ /* get Acx111 rate fallback */
27940+ memset(ratefallback, 0, sizeof(ratefallback));
27941+ acx_s_interrogate(adev, &ratefallback, ACX1xx_IE_RATE_FALLBACK);
27942+
27943+ /* force occurrence of a beacon interrupt */
27944+ /* TODO: comment why is this necessary */
27945+ write_reg16(adev, IO_ACX_HINT_TRIG, HOST_INT_BEACON);
27946+
27947+ /* dump Acx111 Mem Configuration */
27948+ printk("dump mem config:\n"
27949+ "data read: %d, struct size: %d\n"
27950+ "Number of stations: %1X\n"
27951+ "Memory block size: %1X\n"
27952+ "tx/rx memory block allocation: %1X\n"
27953+ "count rx: %X / tx: %X queues\n"
27954+ "options %1X\n"
27955+ "fragmentation %1X\n"
27956+ "Rx Queue 1 Count Descriptors: %X\n"
27957+ "Rx Queue 1 Host Memory Start: %X\n"
27958+ "Tx Queue 1 Count Descriptors: %X\n"
27959+ "Tx Queue 1 Attributes: %X\n",
27960+ memconf.len, (int) sizeof(memconf),
27961+ memconf.no_of_stations,
27962+ memconf.memory_block_size,
27963+ memconf.tx_rx_memory_block_allocation,
27964+ memconf.count_rx_queues, memconf.count_tx_queues,
27965+ memconf.options,
27966+ memconf.fragmentation,
27967+ memconf.rx_queue1_count_descs,
27968+ acx2cpu(memconf.rx_queue1_host_rx_start),
27969+ memconf.tx_queue1_count_descs,
27970+ memconf.tx_queue1_attributes);
27971+
27972+ /* dump Acx111 Queue Configuration */
27973+ printk("dump queue head:\n"
27974+ "data read: %d, struct size: %d\n"
27975+ "tx_memory_block_address (from card): %X\n"
27976+ "rx_memory_block_address (from card): %X\n"
27977+ "rx1_queue address (from card): %X\n"
27978+ "tx1_queue address (from card): %X\n"
27979+ "tx1_queue attributes (from card): %X\n",
27980+ queueconf.len, (int) sizeof(queueconf),
27981+ queueconf.tx_memory_block_address,
27982+ queueconf.rx_memory_block_address,
27983+ queueconf.rx1_queue_address,
27984+ queueconf.tx1_queue_address,
27985+ queueconf.tx1_attributes);
27986+
27987+ /* dump Acx111 Mem Map */
27988+ printk("dump mem map:\n"
27989+ "data read: %d, struct size: %d\n"
27990+ "Code start: %X\n"
27991+ "Code end: %X\n"
27992+ "WEP default key start: %X\n"
27993+ "WEP default key end: %X\n"
27994+ "STA table start: %X\n"
27995+ "STA table end: %X\n"
27996+ "Packet template start: %X\n"
27997+ "Packet template end: %X\n"
27998+ "Queue memory start: %X\n"
27999+ "Queue memory end: %X\n"
28000+ "Packet memory pool start: %X\n"
28001+ "Packet memory pool end: %X\n"
28002+ "iobase: %p\n"
28003+ "iobase2: %p\n",
28004+ *((u16 *)&memmap[0x02]), (int) sizeof(memmap),
28005+ *((u32 *)&memmap[0x04]),
28006+ *((u32 *)&memmap[0x08]),
28007+ *((u32 *)&memmap[0x0C]),
28008+ *((u32 *)&memmap[0x10]),
28009+ *((u32 *)&memmap[0x14]),
28010+ *((u32 *)&memmap[0x18]),
28011+ *((u32 *)&memmap[0x1C]),
28012+ *((u32 *)&memmap[0x20]),
28013+ *((u32 *)&memmap[0x24]),
28014+ *((u32 *)&memmap[0x28]),
28015+ *((u32 *)&memmap[0x2C]),
28016+ *((u32 *)&memmap[0x30]),
28017+ adev->iobase,
28018+ adev->iobase2);
28019+
28020+ /* dump Acx111 Rx Config */
28021+ printk("dump rx config:\n"
28022+ "data read: %d, struct size: %d\n"
28023+ "rx config: %X\n"
28024+ "rx filter config: %X\n",
28025+ *((u16 *)&rxconfig[0x02]), (int) sizeof(rxconfig),
28026+ *((u16 *)&rxconfig[0x04]),
28027+ *((u16 *)&rxconfig[0x06]));
28028+
28029+ /* dump Acx111 fcs error */
28030+ printk("dump fcserror:\n"
28031+ "data read: %d, struct size: %d\n"
28032+ "fcserrors: %X\n",
28033+ *((u16 *)&fcserror[0x02]), (int) sizeof(fcserror),
28034+ *((u32 *)&fcserror[0x04]));
28035+
28036+ /* dump Acx111 rate fallback */
28037+ printk("dump rate fallback:\n"
28038+ "data read: %d, struct size: %d\n"
28039+ "ratefallback: %X\n",
28040+ *((u16 *)&ratefallback[0x02]), (int) sizeof(ratefallback),
28041+ *((u8 *)&ratefallback[0x04]));
28042+
28043+ /* protect against IRQ */
28044+ acx_lock(adev, flags);
28045+
28046+ /* dump acx111 internal rx descriptor ring buffer */
28047+ rxdesc = adev->rxdesc_start;
28048+
28049+ /* loop over complete receive pool */
28050+ if (rxdesc) for (i = 0; i < RX_CNT; i++) {
28051+ printk("\ndump internal rxdesc %d:\n"
28052+ "mem pos %p\n"
28053+ "next 0x%X\n"
28054+ "acx mem pointer (dynamic) 0x%X\n"
28055+ "CTL (dynamic) 0x%X\n"
28056+ "Rate (dynamic) 0x%X\n"
28057+ "RxStatus (dynamic) 0x%X\n"
28058+ "Mod/Pre (dynamic) 0x%X\n",
28059+ i,
28060+ rxdesc,
28061+ acx2cpu(rxdesc->pNextDesc),
28062+ acx2cpu(rxdesc->ACXMemPtr),
28063+ rxdesc->Ctl_8,
28064+ rxdesc->rate,
28065+ rxdesc->error,
28066+ rxdesc->SNR);
28067+ rxdesc++;
28068+ }
28069+
28070+ /* dump host rx descriptor ring buffer */
28071+
28072+ rxhostdesc = adev->rxhostdesc_start;
28073+
28074+ /* loop over complete receive pool */
28075+ if (rxhostdesc) for (i = 0; i < RX_CNT; i++) {
28076+ printk("\ndump host rxdesc %d:\n"
28077+ "mem pos %p\n"
28078+ "buffer mem pos 0x%X\n"
28079+ "buffer mem offset 0x%X\n"
28080+ "CTL 0x%X\n"
28081+ "Length 0x%X\n"
28082+ "next 0x%X\n"
28083+ "Status 0x%X\n",
28084+ i,
28085+ rxhostdesc,
28086+ acx2cpu(rxhostdesc->data_phy),
28087+ rxhostdesc->data_offset,
28088+ le16_to_cpu(rxhostdesc->Ctl_16),
28089+ le16_to_cpu(rxhostdesc->length),
28090+ acx2cpu(rxhostdesc->desc_phy_next),
28091+ rxhostdesc->Status);
28092+ rxhostdesc++;
28093+ }
28094+
28095+ /* dump acx111 internal tx descriptor ring buffer */
28096+ txdesc = adev->txdesc_start;
28097+
28098+ /* loop over complete transmit pool */
28099+ if (txdesc) for (i = 0; i < TX_CNT; i++) {
28100+ printk("\ndump internal txdesc %d:\n"
28101+ "size 0x%X\n"
28102+ "mem pos %p\n"
28103+ "next 0x%X\n"
28104+ "acx mem pointer (dynamic) 0x%X\n"
28105+ "host mem pointer (dynamic) 0x%X\n"
28106+ "length (dynamic) 0x%X\n"
28107+ "CTL (dynamic) 0x%X\n"
28108+ "CTL2 (dynamic) 0x%X\n"
28109+ "Status (dynamic) 0x%X\n"
28110+ "Rate (dynamic) 0x%X\n",
28111+ i,
28112+ (int) sizeof(struct txdesc),
28113+ txdesc,
28114+ acx2cpu(txdesc->pNextDesc),
28115+ acx2cpu(txdesc->AcxMemPtr),
28116+ acx2cpu(txdesc->HostMemPtr),
28117+ le16_to_cpu(txdesc->total_length),
28118+ txdesc->Ctl_8,
28119+ txdesc->Ctl2_8, txdesc->error,
28120+ txdesc->u.r1.rate);
28121+ txdesc = advance_txdesc(adev, txdesc, 1);
28122+ }
28123+
28124+ /* dump host tx descriptor ring buffer */
28125+
28126+ txhostdesc = adev->txhostdesc_start;
28127+
28128+ /* loop over complete host send pool */
28129+ if (txhostdesc) for (i = 0; i < TX_CNT * 2; i++) {
28130+ printk("\ndump host txdesc %d:\n"
28131+ "mem pos %p\n"
28132+ "buffer mem pos 0x%X\n"
28133+ "buffer mem offset 0x%X\n"
28134+ "CTL 0x%X\n"
28135+ "Length 0x%X\n"
28136+ "next 0x%X\n"
28137+ "Status 0x%X\n",
28138+ i,
28139+ txhostdesc,
28140+ acx2cpu(txhostdesc->data_phy),
28141+ txhostdesc->data_offset,
28142+ le16_to_cpu(txhostdesc->Ctl_16),
28143+ le16_to_cpu(txhostdesc->length),
28144+ acx2cpu(txhostdesc->desc_phy_next),
28145+ le32_to_cpu(txhostdesc->Status));
28146+ txhostdesc++;
28147+ }
28148+
28149+ /* write_reg16(adev, 0xb4, 0x4); */
28150+
28151+ acx_unlock(adev, flags);
28152+end_ok:
28153+
28154+ acx_sem_unlock(adev);
28155+#endif /* ACX_DEBUG */
28156+ return OK;
28157+}
28158+
28159+
28160+/***********************************************************************
28161+*/
28162+int
28163+acx100pci_ioctl_set_phy_amp_bias(
28164+ struct net_device *ndev,
28165+ struct iw_request_info *info,
28166+ struct iw_param *vwrq,
28167+ char *extra)
28168+{
28169+ acx_device_t *adev = ndev2adev(ndev);
28170+ unsigned long flags;
28171+ u16 gpio_old;
28172+
28173+ if (!IS_ACX100(adev)) {
28174+ /* WARNING!!!
28175+ * Removing this check *might* damage
28176+ * hardware, since we're tweaking GPIOs here after all!!!
28177+ * You've been warned...
28178+ * WARNING!!! */
28179+ printk("acx: sorry, setting bias level for non-acx100 "
28180+ "is not supported yet\n");
28181+ return OK;
28182+ }
28183+
28184+ if (*extra > 7) {
28185+ printk("acx: invalid bias parameter, range is 0-7\n");
28186+ return -EINVAL;
28187+ }
28188+
28189+ acx_sem_lock(adev);
28190+
28191+ /* Need to lock accesses to [IO_ACX_GPIO_OUT]:
28192+ * IRQ handler uses it to update LED */
28193+ acx_lock(adev, flags);
28194+ gpio_old = read_reg16(adev, IO_ACX_GPIO_OUT);
28195+ write_reg16(adev, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8));
28196+ acx_unlock(adev, flags);
28197+
28198+ log(L_DEBUG, "gpio_old: 0x%04X\n", gpio_old);
28199+ printk("%s: PHY power amplifier bias: old:%d, new:%d\n",
28200+ ndev->name,
28201+ (gpio_old & 0x0700) >> 8, (unsigned char)*extra);
28202+
28203+ acx_sem_unlock(adev);
28204+
28205+ return OK;
28206+}
28207+
28208+
28209+/***************************************************************
28210+** acxpci_l_alloc_tx
28211+** Actually returns a txdesc_t* ptr
28212+**
28213+** FIXME: in case of fragments, should allocate multiple descrs
28214+** after figuring out how many we need and whether we still have
28215+** sufficiently many.
28216+*/
28217+tx_t*
28218+acxpci_l_alloc_tx(acx_device_t *adev)
28219+{
28220+ struct txdesc *txdesc;
28221+ unsigned head;
28222+ u8 ctl8;
28223+
28224+ FN_ENTER;
28225+
28226+ if (unlikely(!adev->tx_free)) {
28227+ printk("acx: BUG: no free txdesc left\n");
28228+ txdesc = NULL;
28229+ goto end;
28230+ }
28231+
28232+ head = adev->tx_head;
28233+ txdesc = get_txdesc(adev, head);
28234+ ctl8 = txdesc->Ctl_8;
28235+
28236+ /* 2005-10-11: there were several bug reports on this happening
28237+ ** but now cause seems to be understood & fixed */
28238+ if (unlikely(DESC_CTL_HOSTOWN != (ctl8 & DESC_CTL_ACXDONE_HOSTOWN))) {
28239+ /* whoops, descr at current index is not free, so probably
28240+ * ring buffer already full */
28241+ printk("acx: BUG: tx_head:%d Ctl8:0x%02X - failed to find "
28242+ "free txdesc\n", head, ctl8);
28243+ txdesc = NULL;
28244+ goto end;
28245+ }
28246+
28247+ /* Needed in case txdesc won't be eventually submitted for tx */
28248+ txdesc->Ctl_8 = DESC_CTL_ACXDONE_HOSTOWN;
28249+
28250+ adev->tx_free--;
28251+ log(L_BUFT, "tx: got desc %u, %u remain\n",
28252+ head, adev->tx_free);
28253+ /* Keep a few free descs between head and tail of tx ring.
28254+ ** It is not absolutely needed, just feels safer */
28255+ if (adev->tx_free < TX_STOP_QUEUE) {
28256+ log(L_BUF, "stop queue (%u tx desc left)\n",
28257+ adev->tx_free);
28258+ acx_stop_queue(adev->ndev, NULL);
28259+ }
28260+
28261+ /* returning current descriptor, so advance to next free one */
28262+ adev->tx_head = (head + 1) % TX_CNT;
28263+end:
28264+ FN_EXIT0;
28265+
28266+ return (tx_t*)txdesc;
28267+}
28268+
28269+
28270+/***********************************************************************
28271+*/
28272+void*
28273+acxpci_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque)
28274+{
28275+ return get_txhostdesc(adev, (txdesc_t*)tx_opaque)->data;
28276+}
28277+
28278+
28279+/***********************************************************************
28280+** acxpci_l_tx_data
28281+**
28282+** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx).
28283+** Can be called from acx_i_start_xmit (data frames from net core).
28284+**
28285+** FIXME: in case of fragments, should loop over the number of
28286+** pre-allocated tx descrs, properly setting up transfer data and
28287+** CTL_xxx flags according to fragment number.
28288+*/
28289+void
28290+acxpci_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int len)
28291+{
28292+ txdesc_t *txdesc = (txdesc_t*)tx_opaque;
28293+ txhostdesc_t *hostdesc1, *hostdesc2;
28294+ client_t *clt;
28295+ u16 rate_cur;
28296+ u8 Ctl_8, Ctl2_8;
28297+
28298+ FN_ENTER;
28299+
28300+ /* fw doesn't tx such packets anyhow */
28301+ if (unlikely(len < WLAN_HDR_A3_LEN))
28302+ goto end;
28303+
28304+ hostdesc1 = get_txhostdesc(adev, txdesc);
28305+ /* modify flag status in separate variable to be able to write it back
28306+ * in one big swoop later (also in order to have less device memory
28307+ * accesses) */
28308+ Ctl_8 = txdesc->Ctl_8;
28309+ Ctl2_8 = 0; /* really need to init it to 0, not txdesc->Ctl2_8, it seems */
28310+
28311+ hostdesc2 = hostdesc1 + 1;
28312+
28313+ /* DON'T simply set Ctl field to 0 here globally,
28314+ * it needs to maintain a consistent flag status (those are state flags!!),
28315+ * otherwise it may lead to severe disruption. Only set or reset particular
28316+ * flags at the exact moment this is needed... */
28317+
28318+ /* let chip do RTS/CTS handshaking before sending
28319+ * in case packet size exceeds threshold */
28320+ if (len > adev->rts_threshold)
28321+ SET_BIT(Ctl2_8, DESC_CTL2_RTS);
28322+ else
28323+ CLEAR_BIT(Ctl2_8, DESC_CTL2_RTS);
28324+
28325+ switch (adev->mode) {
28326+ case ACX_MODE_0_ADHOC:
28327+ case ACX_MODE_3_AP:
28328+ clt = acx_l_sta_list_get(adev, ((wlan_hdr_t*)hostdesc1->data)->a1);
28329+ break;
28330+ case ACX_MODE_2_STA:
28331+ clt = adev->ap_client;
28332+ break;
28333+#if 0
28334+/* testing was done on acx111: */
28335+ case ACX_MODE_MONITOR:
28336+ SET_BIT(Ctl2_8, 0
28337+/* sends CTS to self before packet */
28338+ + DESC_CTL2_SEQ /* don't increase sequence field */
28339+/* not working (looks like good fcs is still added) */
28340+ + DESC_CTL2_FCS /* don't add the FCS */
28341+/* not tested */
28342+ + DESC_CTL2_MORE_FRAG
28343+/* not tested */
28344+ + DESC_CTL2_RETRY /* don't increase retry field */
28345+/* not tested */
28346+ + DESC_CTL2_POWER /* don't increase power mgmt. field */
28347+/* no effect */
28348+ + DESC_CTL2_WEP /* encrypt this frame */
28349+/* not tested */
28350+ + DESC_CTL2_DUR /* don't increase duration field */
28351+ );
28352+ /* fallthrough */
28353+#endif
28354+ default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */
28355+ clt = NULL;
28356+ break;
28357+ }
28358+
28359+ rate_cur = clt ? clt->rate_cur : adev->rate_bcast;
28360+ if (unlikely(!rate_cur)) {
28361+ printk("acx: driver bug! bad ratemask\n");
28362+ goto end;
28363+ }
28364+
28365+ /* used in tx cleanup routine for auto rate and accounting: */
28366+ put_txcr(adev, txdesc, clt, rate_cur);
28367+
28368+ txdesc->total_length = cpu_to_le16(len);
28369+ hostdesc2->length = cpu_to_le16(len - WLAN_HDR_A3_LEN);
28370+ if (IS_ACX111(adev)) {
28371+ /* note that if !txdesc->do_auto, txrate->cur
28372+ ** has only one nonzero bit */
28373+ txdesc->u.r2.rate111 = cpu_to_le16(
28374+ rate_cur
28375+ /* WARNING: I was never able to make it work with prism54 AP.
28376+ ** It was falling down to 1Mbit where shortpre is not applicable,
28377+ ** and not working at all at "5,11 basic rates only" setting.
28378+ ** I even didn't see tx packets in radio packet capture.
28379+ ** Disabled for now --vda */
28380+ /*| ((clt->shortpre && clt->cur!=RATE111_1) ? RATE111_SHORTPRE : 0) */
28381+ );
28382+#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS
28383+ /* should add this to rate111 above as necessary */
28384+ | (clt->pbcc511 ? RATE111_PBCC511 : 0)
28385+#endif
28386+ hostdesc1->length = cpu_to_le16(len);
28387+ } else { /* ACX100 */
28388+ u8 rate_100 = clt ? clt->rate_100 : adev->rate_bcast100;
28389+ txdesc->u.r1.rate = rate_100;
28390+#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS
28391+ if (clt->pbcc511) {
28392+ if (n == RATE100_5 || n == RATE100_11)
28393+ n |= RATE100_PBCC511;
28394+ }
28395+
28396+ if (clt->shortpre && (clt->cur != RATE111_1))
28397+ SET_BIT(Ctl_8, DESC_CTL_SHORT_PREAMBLE); /* set Short Preamble */
28398+#endif
28399+ /* set autodma and reclaim and 1st mpdu */
28400+ SET_BIT(Ctl_8, DESC_CTL_AUTODMA | DESC_CTL_RECLAIM | DESC_CTL_FIRSTFRAG);
28401+#if ACX_FRAGMENTATION
28402+ /* SET_BIT(Ctl2_8, DESC_CTL2_MORE_FRAG); cannot set it unconditionally, needs to be set for all non-last fragments */
28403+#endif
28404+ hostdesc1->length = cpu_to_le16(WLAN_HDR_A3_LEN);
28405+ }
28406+ /* don't need to clean ack/rts statistics here, already
28407+ * done on descr cleanup */
28408+
28409+ /* clears HOSTOWN and ACXDONE bits, thus telling that the descriptors
28410+ * are now owned by the acx100; do this as LAST operation */
28411+ CLEAR_BIT(Ctl_8, DESC_CTL_ACXDONE_HOSTOWN);
28412+ /* flush writes before we release hostdesc to the adapter here */
28413+ wmb();
28414+ CLEAR_BIT(hostdesc1->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN));
28415+ CLEAR_BIT(hostdesc2->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN));
28416+
28417+ /* write back modified flags */
28418+ txdesc->Ctl2_8 = Ctl2_8;
28419+ txdesc->Ctl_8 = Ctl_8;
28420+ /* unused: txdesc->tx_time = cpu_to_le32(jiffies); */
28421+
28422+ /* flush writes before we tell the adapter that it's its turn now */
28423+ mmiowb();
28424+ write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC);
28425+ write_flush(adev);
28426+
28427+ /* log the packet content AFTER sending it,
28428+ * in order to not delay sending any further than absolutely needed
28429+ * Do separate logs for acx100/111 to have human-readable rates */
28430+ if (unlikely(acx_debug & (L_XFER|L_DATA))) {
28431+ u16 fc = ((wlan_hdr_t*)hostdesc1->data)->fc;
28432+ if (IS_ACX111(adev))
28433+ printk("tx: pkt (%s): len %d "
28434+ "rate %04X%s status %u\n",
28435+ acx_get_packet_type_string(le16_to_cpu(fc)), len,
28436+ le16_to_cpu(txdesc->u.r2.rate111),
28437+ (le16_to_cpu(txdesc->u.r2.rate111) & RATE111_SHORTPRE) ? "(SPr)" : "",
28438+ adev->status);
28439+ else
28440+ printk("tx: pkt (%s): len %d rate %03u%s status %u\n",
28441+ acx_get_packet_type_string(fc), len,
28442+ txdesc->u.r1.rate,
28443+ (Ctl_8 & DESC_CTL_SHORT_PREAMBLE) ? "(SPr)" : "",
28444+ adev->status);
28445+
28446+ if (acx_debug & L_DATA) {
28447+ printk("tx: 802.11 [%d]: ", len);
28448+ acx_dump_bytes(hostdesc1->data, len);
28449+ }
28450+ }
28451+end:
28452+ FN_EXIT0;
28453+}
28454+
28455+
28456+/***********************************************************************
28457+** acxpci_l_clean_txdesc
28458+**
28459+** This function resets the txdescs' status when the ACX100
28460+** signals the TX done IRQ (txdescs have been processed), starting with
28461+** the pool index of the descriptor which we would use next,
28462+** in order to make sure that we can be as fast as possible
28463+** in filling new txdescs.
28464+** Everytime we get called we know where the next packet to be cleaned is.
28465+*/
28466+
28467+#if !ACX_DEBUG
28468+static inline void log_txbuffer(const acx_device_t *adev) {}
28469+#else
28470+static void
28471+log_txbuffer(acx_device_t *adev)
28472+{
28473+ txdesc_t *txdesc;
28474+ int i;
28475+
28476+ /* no FN_ENTER here, we don't want that */
28477+ /* no locks here, since it's entirely non-critical code */
28478+ txdesc = adev->txdesc_start;
28479+ if (unlikely(!txdesc)) return;
28480+ printk("tx: desc->Ctl8's:");
28481+ for (i = 0; i < TX_CNT; i++) {
28482+ printk(" %02X", txdesc->Ctl_8);
28483+ txdesc = advance_txdesc(adev, txdesc, 1);
28484+ }
28485+ printk("\n");
28486+}
28487+#endif
28488+
28489+
28490+static void
28491+handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger)
28492+{
28493+ const char *err = "unknown error";
28494+
28495+ /* hmm, should we handle this as a mask
28496+ * of *several* bits?
28497+ * For now I think only caring about
28498+ * individual bits is ok... */
28499+ switch (error) {
28500+ case 0x01:
28501+ err = "no Tx due to error in other fragment";
28502+ adev->wstats.discard.fragment++;
28503+ break;
28504+ case 0x02:
28505+ err = "Tx aborted";
28506+ adev->stats.tx_aborted_errors++;
28507+ break;
28508+ case 0x04:
28509+ err = "Tx desc wrong parameters";
28510+ adev->wstats.discard.misc++;
28511+ break;
28512+ case 0x08:
28513+ err = "WEP key not found";
28514+ adev->wstats.discard.misc++;
28515+ break;
28516+ case 0x10:
28517+ err = "MSDU lifetime timeout? - try changing "
28518+ "'iwconfig retry lifetime XXX'";
28519+ adev->wstats.discard.misc++;
28520+ break;
28521+ case 0x20:
28522+ err = "excessive Tx retries due to either distance "
28523+ "too high or unable to Tx or Tx frame error - "
28524+ "try changing 'iwconfig txpower XXX' or "
28525+ "'sens'itivity or 'retry'";
28526+ adev->wstats.discard.retries++;
28527+ /* Tx error 0x20 also seems to occur on
28528+ * overheating, so I'm not sure whether we
28529+ * actually want to do aggressive radio recalibration,
28530+ * since people maybe won't notice then that their hardware
28531+ * is slowly getting cooked...
28532+ * Or is it still a safe long distance from utter
28533+ * radio non-functionality despite many radio recalibs
28534+ * to final destructive overheating of the hardware?
28535+ * In this case we really should do recalib here...
28536+ * I guess the only way to find out is to do a
28537+ * potentially fatal self-experiment :-\
28538+ * Or maybe only recalib in case we're using Tx
28539+ * rate auto (on errors switching to lower speed
28540+ * --> less heat?) or 802.11 power save mode?
28541+ *
28542+ * ok, just do it. */
28543+ if (++adev->retry_errors_msg_ratelimit % 4 == 0) {
28544+ if (adev->retry_errors_msg_ratelimit <= 20) {
28545+ printk("%s: several excessive Tx "
28546+ "retry errors occurred, attempting "
28547+ "to recalibrate radio. Radio "
28548+ "drift might be caused by increasing "
28549+ "card temperature, please check the card "
28550+ "before it's too late!\n",
28551+ adev->ndev->name);
28552+ if (adev->retry_errors_msg_ratelimit == 20)
28553+ printk("disabling above message\n");
28554+ }
28555+
28556+ acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB);
28557+ }
28558+ break;
28559+ case 0x40:
28560+ err = "Tx buffer overflow";
28561+ adev->stats.tx_fifo_errors++;
28562+ break;
28563+ case 0x80:
28564+ /* possibly ACPI C-state powersaving related!!!
28565+ * (DMA timeout due to excessively high wakeup
28566+ * latency after C-state activation!?)
28567+ * Disable C-State powersaving and try again,
28568+ * then PLEASE REPORT, I'm VERY interested in
28569+ * whether my theory is correct that this is
28570+ * actually the problem here.
28571+ * In that case, use new Linux idle wakeup latency
28572+ * requirements kernel API to prevent this issue. */
28573+ err = "DMA error";
28574+ adev->wstats.discard.misc++;
28575+ break;
28576+ }
28577+ adev->stats.tx_errors++;
28578+ if (adev->stats.tx_errors <= 20)
28579+ printk("%s: tx error 0x%02X, buf %02u! (%s)\n",
28580+ adev->ndev->name, error, finger, err);
28581+ else
28582+ printk("%s: tx error 0x%02X, buf %02u!\n",
28583+ adev->ndev->name, error, finger);
28584+}
28585+
28586+
28587+unsigned int
28588+acxpci_l_clean_txdesc(acx_device_t *adev)
28589+{
28590+ txdesc_t *txdesc;
28591+ unsigned finger;
28592+ int num_cleaned;
28593+ u16 r111;
28594+ u8 error, ack_failures, rts_failures, rts_ok, r100;
28595+
28596+ FN_ENTER;
28597+
28598+ if (unlikely(acx_debug & L_DEBUG))
28599+ log_txbuffer(adev);
28600+
28601+ log(L_BUFT, "tx: cleaning up bufs from %u\n", adev->tx_tail);
28602+
28603+ /* We know first descr which is not free yet. We advance it as far
28604+ ** as we see correct bits set in following descs (if next desc
28605+ ** is NOT free, we shouldn't advance at all). We know that in
28606+ ** front of tx_tail may be "holes" with isolated free descs.
28607+ ** We will catch up when all intermediate descs will be freed also */
28608+
28609+ finger = adev->tx_tail;
28610+ num_cleaned = 0;
28611+ while (likely(finger != adev->tx_head)) {
28612+ txdesc = get_txdesc(adev, finger);
28613+
28614+ /* If we allocated txdesc on tx path but then decided
28615+ ** to NOT use it, then it will be left as a free "bubble"
28616+ ** in the "allocated for tx" part of the ring.
28617+ ** We may meet it on the next ring pass here. */
28618+
28619+ /* stop if not marked as "tx finished" and "host owned" */
28620+ if ((txdesc->Ctl_8 & DESC_CTL_ACXDONE_HOSTOWN)
28621+ != DESC_CTL_ACXDONE_HOSTOWN) {
28622+ if (unlikely(!num_cleaned)) { /* maybe remove completely */
28623+ log(L_BUFT, "clean_txdesc: tail isn't free. "
28624+ "tail:%d head:%d\n",
28625+ adev->tx_tail, adev->tx_head);
28626+ }
28627+ break;
28628+ }
28629+
28630+ /* remember desc values... */
28631+ error = txdesc->error;
28632+ ack_failures = txdesc->ack_failures;
28633+ rts_failures = txdesc->rts_failures;
28634+ rts_ok = txdesc->rts_ok;
28635+ r100 = txdesc->u.r1.rate;
28636+ r111 = le16_to_cpu(txdesc->u.r2.rate111);
28637+
28638+ /* need to check for certain error conditions before we
28639+ * clean the descriptor: we still need valid descr data here */
28640+ if (unlikely(0x30 & error)) {
28641+ /* only send IWEVTXDROP in case of retry or lifetime exceeded;
28642+ * all other errors mean we screwed up locally */
28643+ union iwreq_data wrqu;
28644+ wlan_hdr_t *hdr;
28645+ txhostdesc_t *hostdesc;
28646+
28647+ hostdesc = get_txhostdesc(adev, txdesc);
28648+ hdr = (wlan_hdr_t *)hostdesc->data;
28649+ MAC_COPY(wrqu.addr.sa_data, hdr->a1);
28650+ wireless_send_event(adev->ndev, IWEVTXDROP, &wrqu, NULL);
28651+ }
28652+
28653+ /* ...and free the desc */
28654+ txdesc->error = 0;
28655+ txdesc->ack_failures = 0;
28656+ txdesc->rts_failures = 0;
28657+ txdesc->rts_ok = 0;
28658+ /* signal host owning it LAST, since ACX already knows that this
28659+ ** descriptor is finished since it set Ctl_8 accordingly. */
28660+ txdesc->Ctl_8 = DESC_CTL_HOSTOWN;
28661+
28662+ adev->tx_free++;
28663+ num_cleaned++;
28664+
28665+ if ((adev->tx_free >= TX_START_QUEUE)
28666+ && (adev->status == ACX_STATUS_4_ASSOCIATED)
28667+ && (acx_queue_stopped(adev->ndev))
28668+ ) {
28669+ log(L_BUF, "tx: wake queue (avail. Tx desc %u)\n",
28670+ adev->tx_free);
28671+ acx_wake_queue(adev->ndev, NULL);
28672+ }
28673+
28674+ /* do error checking, rate handling and logging
28675+ * AFTER having done the work, it's faster */
28676+
28677+ /* do rate handling */
28678+ if (adev->rate_auto) {
28679+ struct client *clt = get_txc(adev, txdesc);
28680+ if (clt) {
28681+ u16 cur = get_txr(adev, txdesc);
28682+ if (clt->rate_cur == cur) {
28683+ acx_l_handle_txrate_auto(adev, clt,
28684+ cur, /* intended rate */
28685+ r100, r111, /* actually used rate */
28686+ (error & 0x30), /* was there an error? */
28687+ TX_CNT + TX_CLEAN_BACKLOG - adev->tx_free);
28688+ }
28689+ }
28690+ }
28691+
28692+ if (unlikely(error))
28693+ handle_tx_error(adev, error, finger);
28694+
28695+ if (IS_ACX111(adev))
28696+ log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u r111=%04X\n",
28697+ finger, ack_failures, rts_failures, rts_ok, r111);
28698+ else
28699+ log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u rate=%u\n",
28700+ finger, ack_failures, rts_failures, rts_ok, r100);
28701+
28702+ /* update pointer for descr to be cleaned next */
28703+ finger = (finger + 1) % TX_CNT;
28704+ }
28705+
28706+ /* remember last position */
28707+ adev->tx_tail = finger;
28708+/* end: */
28709+ FN_EXIT1(num_cleaned);
28710+ return num_cleaned;
28711+}
28712+
28713+/* clean *all* Tx descriptors, and regardless of their previous state.
28714+ * Used for brute-force reset handling. */
28715+void
28716+acxpci_l_clean_txdesc_emergency(acx_device_t *adev)
28717+{
28718+ txdesc_t *txdesc;
28719+ int i;
28720+
28721+ FN_ENTER;
28722+
28723+ for (i = 0; i < TX_CNT; i++) {
28724+ txdesc = get_txdesc(adev, i);
28725+
28726+ /* free it */
28727+ txdesc->ack_failures = 0;
28728+ txdesc->rts_failures = 0;
28729+ txdesc->rts_ok = 0;
28730+ txdesc->error = 0;
28731+ txdesc->Ctl_8 = DESC_CTL_HOSTOWN;
28732+ }
28733+
28734+ adev->tx_free = TX_CNT;
28735+
28736+ FN_EXIT0;
28737+}
28738+
28739+
28740+/***********************************************************************
28741+** acxpci_s_create_tx_host_desc_queue
28742+*/
28743+
28744+static void*
28745+allocate(acx_device_t *adev, size_t size, dma_addr_t *phy, const char *msg)
28746+{
28747+ void *ptr;
28748+
28749+ ptr = dma_alloc_coherent(adev->pdev ? &adev->pdev->dev : NULL,
28750+ size, phy, GFP_KERNEL);
28751+
28752+ if (ptr) {
28753+ log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n",
28754+ msg, (int)size, ptr, (unsigned long long)*phy);
28755+ memset(ptr, 0, size);
28756+ return ptr;
28757+ }
28758+ printk(KERN_ERR "acx: %s allocation FAILED (%d bytes)\n",
28759+ msg, (int)size);
28760+ return NULL;
28761+}
28762+
28763+
28764+static int
28765+acxpci_s_create_tx_host_desc_queue(acx_device_t *adev)
28766+{
28767+ txhostdesc_t *hostdesc;
28768+ u8 *txbuf;
28769+ dma_addr_t hostdesc_phy;
28770+ dma_addr_t txbuf_phy;
28771+ int i;
28772+
28773+ FN_ENTER;
28774+
28775+ /* allocate TX buffer */
28776+ adev->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS;
28777+ adev->txbuf_start = allocate(adev, adev->txbuf_area_size,
28778+ &adev->txbuf_startphy, "txbuf_start");
28779+ if (!adev->txbuf_start)
28780+ goto fail;
28781+
28782+ /* allocate the TX host descriptor queue pool */
28783+ adev->txhostdesc_area_size = TX_CNT * 2*sizeof(*hostdesc);
28784+ adev->txhostdesc_start = allocate(adev, adev->txhostdesc_area_size,
28785+ &adev->txhostdesc_startphy, "txhostdesc_start");
28786+ if (!adev->txhostdesc_start)
28787+ goto fail;
28788+ /* check for proper alignment of TX host descriptor pool */
28789+ if ((long) adev->txhostdesc_start & 3) {
28790+ printk("acx: driver bug: dma alloc returns unaligned address\n");
28791+ goto fail;
28792+ }
28793+
28794+ hostdesc = adev->txhostdesc_start;
28795+ hostdesc_phy = adev->txhostdesc_startphy;
28796+ txbuf = adev->txbuf_start;
28797+ txbuf_phy = adev->txbuf_startphy;
28798+
28799+#if 0
28800+/* Each tx buffer is accessed by hardware via
28801+** txdesc -> txhostdesc(s) -> txbuffer(s).
28802+** We use only one txhostdesc per txdesc, but it looks like
28803+** acx111 is buggy: it accesses second txhostdesc
28804+** (via hostdesc.desc_phy_next field) even if
28805+** txdesc->length == hostdesc->length and thus
28806+** entire packet was placed into first txhostdesc.
28807+** Due to this bug acx111 hangs unless second txhostdesc
28808+** has le16_to_cpu(hostdesc.length) = 3 (or larger)
28809+** Storing NULL into hostdesc.desc_phy_next
28810+** doesn't seem to help.
28811+**
28812+** Update: although it worked on Xterasys XN-2522g
28813+** with len=3 trick, WG311v2 is even more bogus, doesn't work.
28814+** Keeping this code (#ifdef'ed out) for documentational purposes.
28815+*/
28816+ for (i = 0; i < TX_CNT*2; i++) {
28817+ hostdesc_phy += sizeof(*hostdesc);
28818+ if (!(i & 1)) {
28819+ hostdesc->data_phy = cpu2acx(txbuf_phy);
28820+ /* hostdesc->data_offset = ... */
28821+ /* hostdesc->reserved = ... */
28822+ hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN);
28823+ /* hostdesc->length = ... */
28824+ hostdesc->desc_phy_next = cpu2acx(hostdesc_phy);
28825+ hostdesc->pNext = ptr2acx(NULL);
28826+ /* hostdesc->Status = ... */
28827+ /* below: non-hardware fields */
28828+ hostdesc->data = txbuf;
28829+
28830+ txbuf += WLAN_A4FR_MAXLEN_WEP_FCS;
28831+ txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS;
28832+ } else {
28833+ /* hostdesc->data_phy = ... */
28834+ /* hostdesc->data_offset = ... */
28835+ /* hostdesc->reserved = ... */
28836+ /* hostdesc->Ctl_16 = ... */
28837+ hostdesc->length = cpu_to_le16(3); /* bug workaround */
28838+ /* hostdesc->desc_phy_next = ... */
28839+ /* hostdesc->pNext = ... */
28840+ /* hostdesc->Status = ... */
28841+ /* below: non-hardware fields */
28842+ /* hostdesc->data = ... */
28843+ }
28844+ hostdesc++;
28845+ }
28846+#endif
28847+/* We initialize two hostdescs so that they point to adjacent
28848+** memory areas. Thus txbuf is really just a contiguous memory area */
28849+ for (i = 0; i < TX_CNT*2; i++) {
28850+ hostdesc_phy += sizeof(*hostdesc);
28851+
28852+ hostdesc->data_phy = cpu2acx(txbuf_phy);
28853+ /* done by memset(0): hostdesc->data_offset = 0; */
28854+ /* hostdesc->reserved = ... */
28855+ hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN);
28856+ /* hostdesc->length = ... */
28857+ hostdesc->desc_phy_next = cpu2acx(hostdesc_phy);
28858+ /* done by memset(0): hostdesc->pNext = ptr2acx(NULL); */
28859+ /* hostdesc->Status = ... */
28860+ /* ->data is a non-hardware field: */
28861+ hostdesc->data = txbuf;
28862+
28863+ if (!(i & 1)) {
28864+ txbuf += WLAN_HDR_A3_LEN;
28865+ txbuf_phy += WLAN_HDR_A3_LEN;
28866+ } else {
28867+ txbuf += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN;
28868+ txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN;
28869+ }
28870+ hostdesc++;
28871+ }
28872+ hostdesc--;
28873+ hostdesc->desc_phy_next = cpu2acx(adev->txhostdesc_startphy);
28874+
28875+ FN_EXIT1(OK);
28876+ return OK;
28877+fail:
28878+ printk("acx: create_tx_host_desc_queue FAILED\n");
28879+ /* dealloc will be done by free function on error case */
28880+ FN_EXIT1(NOT_OK);
28881+ return NOT_OK;
28882+}
28883+
28884+
28885+/***************************************************************
28886+** acxpci_s_create_rx_host_desc_queue
28887+*/
28888+/* the whole size of a data buffer (header plus data body)
28889+ * plus 32 bytes safety offset at the end */
28890+#define RX_BUFFER_SIZE (sizeof(rxbuffer_t) + 32)
28891+
28892+static int
28893+acxpci_s_create_rx_host_desc_queue(acx_device_t *adev)
28894+{
28895+ rxhostdesc_t *hostdesc;
28896+ rxbuffer_t *rxbuf;
28897+ dma_addr_t hostdesc_phy;
28898+ dma_addr_t rxbuf_phy;
28899+ int i;
28900+
28901+ FN_ENTER;
28902+
28903+ /* allocate the RX host descriptor queue pool */
28904+ adev->rxhostdesc_area_size = RX_CNT * sizeof(*hostdesc);
28905+ adev->rxhostdesc_start = allocate(adev, adev->rxhostdesc_area_size,
28906+ &adev->rxhostdesc_startphy, "rxhostdesc_start");
28907+ if (!adev->rxhostdesc_start)
28908+ goto fail;
28909+ /* check for proper alignment of RX host descriptor pool */
28910+ if ((long) adev->rxhostdesc_start & 3) {
28911+ printk("acx: driver bug: dma alloc returns unaligned address\n");
28912+ goto fail;
28913+ }
28914+
28915+ /* allocate Rx buffer pool which will be used by the acx
28916+ * to store the whole content of the received frames in it */
28917+ adev->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE;
28918+ adev->rxbuf_start = allocate(adev, adev->rxbuf_area_size,
28919+ &adev->rxbuf_startphy, "rxbuf_start");
28920+ if (!adev->rxbuf_start)
28921+ goto fail;
28922+
28923+ rxbuf = adev->rxbuf_start;
28924+ rxbuf_phy = adev->rxbuf_startphy;
28925+ hostdesc = adev->rxhostdesc_start;
28926+ hostdesc_phy = adev->rxhostdesc_startphy;
28927+
28928+ /* don't make any popular C programming pointer arithmetic mistakes
28929+ * here, otherwise I'll kill you...
28930+ * (and don't dare asking me why I'm warning you about that...) */
28931+ for (i = 0; i < RX_CNT; i++) {
28932+ hostdesc->data = rxbuf;
28933+ hostdesc->data_phy = cpu2acx(rxbuf_phy);
28934+ hostdesc->length = cpu_to_le16(RX_BUFFER_SIZE);
28935+ CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN));
28936+ rxbuf++;
28937+ rxbuf_phy += sizeof(*rxbuf);
28938+ hostdesc_phy += sizeof(*hostdesc);
28939+ hostdesc->desc_phy_next = cpu2acx(hostdesc_phy);
28940+ hostdesc++;
28941+ }
28942+ hostdesc--;
28943+ hostdesc->desc_phy_next = cpu2acx(adev->rxhostdesc_startphy);
28944+ FN_EXIT1(OK);
28945+ return OK;
28946+fail:
28947+ printk("acx: create_rx_host_desc_queue FAILED\n");
28948+ /* dealloc will be done by free function on error case */
28949+ FN_EXIT1(NOT_OK);
28950+ return NOT_OK;
28951+}
28952+
28953+
28954+/***************************************************************
28955+** acxpci_s_create_hostdesc_queues
28956+*/
28957+int
28958+acxpci_s_create_hostdesc_queues(acx_device_t *adev)
28959+{
28960+ int result;
28961+ result = acxpci_s_create_tx_host_desc_queue(adev);
28962+ if (OK != result) return result;
28963+ result = acxpci_s_create_rx_host_desc_queue(adev);
28964+ return result;
28965+}
28966+
28967+
28968+/***************************************************************
28969+** acxpci_create_tx_desc_queue
28970+*/
28971+static void
28972+acxpci_create_tx_desc_queue(acx_device_t *adev, u32 tx_queue_start)
28973+{
28974+ txdesc_t *txdesc;
28975+ txhostdesc_t *hostdesc;
28976+ dma_addr_t hostmemptr;
28977+ u32 mem_offs;
28978+ int i;
28979+
28980+ FN_ENTER;
28981+
28982+ if (IS_ACX100(adev))
28983+ adev->txdesc_size = sizeof(*txdesc);
28984+ else
28985+ /* the acx111 txdesc is 4 bytes larger */
28986+ adev->txdesc_size = sizeof(*txdesc) + 4;
28987+
28988+ adev->txdesc_start = (txdesc_t *) (adev->iobase2 + tx_queue_start);
28989+
28990+ log(L_DEBUG, "adev->iobase2=%p\n"
28991+ "tx_queue_start=%08X\n"
28992+ "adev->txdesc_start=%p\n",
28993+ adev->iobase2,
28994+ tx_queue_start,
28995+ adev->txdesc_start);
28996+
28997+ adev->tx_free = TX_CNT;
28998+ /* done by memset: adev->tx_head = 0; */
28999+ /* done by memset: adev->tx_tail = 0; */
29000+ txdesc = adev->txdesc_start;
29001+ mem_offs = tx_queue_start;
29002+ hostmemptr = adev->txhostdesc_startphy;
29003+ hostdesc = adev->txhostdesc_start;
29004+
29005+ if (IS_ACX111(adev)) {
29006+ /* ACX111 has a preinitialized Tx buffer! */
29007+ /* loop over whole send pool */
29008+ /* FIXME: do we have to do the hostmemptr stuff here?? */
29009+ for (i = 0; i < TX_CNT; i++) {
29010+ txdesc->HostMemPtr = ptr2acx(hostmemptr);
29011+ txdesc->Ctl_8 = DESC_CTL_HOSTOWN;
29012+ /* reserve two (hdr desc and payload desc) */
29013+ hostdesc += 2;
29014+ hostmemptr += 2 * sizeof(*hostdesc);
29015+ txdesc = advance_txdesc(adev, txdesc, 1);
29016+ }
29017+ } else {
29018+ /* ACX100 Tx buffer needs to be initialized by us */
29019+ /* clear whole send pool. sizeof is safe here (we are acx100) */
29020+ memset(adev->txdesc_start, 0, TX_CNT * sizeof(*txdesc));
29021+
29022+ /* loop over whole send pool */
29023+ for (i = 0; i < TX_CNT; i++) {
29024+ log(L_DEBUG, "configure card tx descriptor: 0x%p, "
29025+ "size: 0x%X\n", txdesc, adev->txdesc_size);
29026+
29027+ /* pointer to hostdesc memory */
29028+ txdesc->HostMemPtr = ptr2acx(hostmemptr);
29029+ /* initialise ctl */
29030+ txdesc->Ctl_8 = ( DESC_CTL_HOSTOWN | DESC_CTL_RECLAIM
29031+ | DESC_CTL_AUTODMA | DESC_CTL_FIRSTFRAG);
29032+ /* done by memset(0): txdesc->Ctl2_8 = 0; */
29033+ /* point to next txdesc */
29034+ txdesc->pNextDesc = cpu2acx(mem_offs + adev->txdesc_size);
29035+ /* reserve two (hdr desc and payload desc) */
29036+ hostdesc += 2;
29037+ hostmemptr += 2 * sizeof(*hostdesc);
29038+ /* go to the next one */
29039+ mem_offs += adev->txdesc_size;
29040+ /* ++ is safe here (we are acx100) */
29041+ txdesc++;
29042+ }
29043+ /* go back to the last one */
29044+ txdesc--;
29045+ /* and point to the first making it a ring buffer */
29046+ txdesc->pNextDesc = cpu2acx(tx_queue_start);
29047+ }
29048+ FN_EXIT0;
29049+}
29050+
29051+
29052+/***************************************************************
29053+** acxpci_create_rx_desc_queue
29054+*/
29055+static void
29056+acxpci_create_rx_desc_queue(acx_device_t *adev, u32 rx_queue_start)
29057+{
29058+ rxdesc_t *rxdesc;
29059+ u32 mem_offs;
29060+ int i;
29061+
29062+ FN_ENTER;
29063+
29064+ /* done by memset: adev->rx_tail = 0; */
29065+
29066+ /* ACX111 doesn't need any further config: preconfigures itself.
29067+ * Simply print ring buffer for debugging */
29068+ if (IS_ACX111(adev)) {
29069+ /* rxdesc_start already set here */
29070+
29071+ adev->rxdesc_start = (rxdesc_t *) ((u8 *)adev->iobase2 + rx_queue_start);
29072+
29073+ rxdesc = adev->rxdesc_start;
29074+ for (i = 0; i < RX_CNT; i++) {
29075+ log(L_DEBUG, "rx descriptor %d @ 0x%p\n", i, rxdesc);
29076+ rxdesc = adev->rxdesc_start = (rxdesc_t *)
29077+ (adev->iobase2 + acx2cpu(rxdesc->pNextDesc));
29078+ }
29079+ } else {
29080+ /* we didn't pre-calculate rxdesc_start in case of ACX100 */
29081+ /* rxdesc_start should be right AFTER Tx pool */
29082+ adev->rxdesc_start = (rxdesc_t *)
29083+ ((u8 *) adev->txdesc_start + (TX_CNT * sizeof(txdesc_t)));
29084+ /* NB: sizeof(txdesc_t) above is valid because we know
29085+ ** we are in if (acx100) block. Beware of cut-n-pasting elsewhere!
29086+ ** acx111's txdesc is larger! */
29087+
29088+ memset(adev->rxdesc_start, 0, RX_CNT * sizeof(*rxdesc));
29089+
29090+ /* loop over whole receive pool */
29091+ rxdesc = adev->rxdesc_start;
29092+ mem_offs = rx_queue_start;
29093+ for (i = 0; i < RX_CNT; i++) {
29094+ log(L_DEBUG, "rx descriptor @ 0x%p\n", rxdesc);
29095+ rxdesc->Ctl_8 = DESC_CTL_RECLAIM | DESC_CTL_AUTODMA;
29096+ /* point to next rxdesc */
29097+ rxdesc->pNextDesc = cpu2acx(mem_offs + sizeof(*rxdesc));
29098+ /* go to the next one */
29099+ mem_offs += sizeof(*rxdesc);
29100+ rxdesc++;
29101+ }
29102+ /* go to the last one */
29103+ rxdesc--;
29104+
29105+ /* and point to the first making it a ring buffer */
29106+ rxdesc->pNextDesc = cpu2acx(rx_queue_start);
29107+ }
29108+ FN_EXIT0;
29109+}
29110+
29111+
29112+/***************************************************************
29113+** acxpci_create_desc_queues
29114+*/
29115+void
29116+acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start)
29117+{
29118+ acxpci_create_tx_desc_queue(adev, tx_queue_start);
29119+ acxpci_create_rx_desc_queue(adev, rx_queue_start);
29120+}
29121+
29122+
29123+/***************************************************************
29124+** acxpci_s_proc_diag_output
29125+*/
29126+char*
29127+acxpci_s_proc_diag_output(char *p, acx_device_t *adev)
29128+{
29129+ const char *rtl, *thd, *ttl;
29130+ rxhostdesc_t *rxhostdesc;
29131+ txdesc_t *txdesc;
29132+ int i;
29133+
29134+ FN_ENTER;
29135+
29136+ p += sprintf(p, "** Rx buf **\n");
29137+ rxhostdesc = adev->rxhostdesc_start;
29138+ if (rxhostdesc) for (i = 0; i < RX_CNT; i++) {
29139+ rtl = (i == adev->rx_tail) ? " [tail]" : "";
29140+ if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN))
29141+ && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)) )
29142+ p += sprintf(p, "%02u FULL%s\n", i, rtl);
29143+ else
29144+ p += sprintf(p, "%02u empty%s\n", i, rtl);
29145+ rxhostdesc++;
29146+ }
29147+ p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", adev->tx_free,
29148+ acx_queue_stopped(adev->ndev) ? "STOPPED" : "running");
29149+ txdesc = adev->txdesc_start;
29150+ if (txdesc) for (i = 0; i < TX_CNT; i++) {
29151+ thd = (i == adev->tx_head) ? " [head]" : "";
29152+ ttl = (i == adev->tx_tail) ? " [tail]" : "";
29153+ if (txdesc->Ctl_8 & DESC_CTL_ACXDONE)
29154+ p += sprintf(p, "%02u free (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl);
29155+ else
29156+ p += sprintf(p, "%02u tx (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl);
29157+ txdesc = advance_txdesc(adev, txdesc, 1);
29158+ }
29159+ p += sprintf(p,
29160+ "\n"
29161+ "** PCI data **\n"
29162+ "txbuf_start %p, txbuf_area_size %u, txbuf_startphy %08llx\n"
29163+ "txdesc_size %u, txdesc_start %p\n"
29164+ "txhostdesc_start %p, txhostdesc_area_size %u, txhostdesc_startphy %08llx\n"
29165+ "rxdesc_start %p\n"
29166+ "rxhostdesc_start %p, rxhostdesc_area_size %u, rxhostdesc_startphy %08llx\n"
29167+ "rxbuf_start %p, rxbuf_area_size %u, rxbuf_startphy %08llx\n",
29168+ adev->txbuf_start, adev->txbuf_area_size,
29169+ (unsigned long long)adev->txbuf_startphy,
29170+ adev->txdesc_size, adev->txdesc_start,
29171+ adev->txhostdesc_start, adev->txhostdesc_area_size,
29172+ (unsigned long long)adev->txhostdesc_startphy,
29173+ adev->rxdesc_start,
29174+ adev->rxhostdesc_start, adev->rxhostdesc_area_size,
29175+ (unsigned long long)adev->rxhostdesc_startphy,
29176+ adev->rxbuf_start, adev->rxbuf_area_size,
29177+ (unsigned long long)adev->rxbuf_startphy);
29178+
29179+ FN_EXIT0;
29180+ return p;
29181+}
29182+
29183+
29184+/***********************************************************************
29185+*/
29186+int
29187+acxpci_proc_eeprom_output(char *buf, acx_device_t *adev)
29188+{
29189+ char *p = buf;
29190+ int i;
29191+
29192+ FN_ENTER;
29193+
29194+ for (i = 0; i < 0x400; i++) {
29195+ acxpci_read_eeprom_byte(adev, i, p++);
29196+ }
29197+
29198+ FN_EXIT1(p - buf);
29199+ return p - buf;
29200+}
29201+
29202+
29203+/***********************************************************************
29204+*/
29205+void
29206+acxpci_set_interrupt_mask(acx_device_t *adev)
29207+{
29208+ if (IS_ACX111(adev)) {
29209+ adev->irq_mask = (u16) ~(0
29210+ /* | HOST_INT_RX_DATA */
29211+ | HOST_INT_TX_COMPLETE
29212+ /* | HOST_INT_TX_XFER */
29213+ | HOST_INT_RX_COMPLETE
29214+ /* | HOST_INT_DTIM */
29215+ /* | HOST_INT_BEACON */
29216+ /* | HOST_INT_TIMER */
29217+ /* | HOST_INT_KEY_NOT_FOUND */
29218+ | HOST_INT_IV_ICV_FAILURE
29219+ | HOST_INT_CMD_COMPLETE
29220+ | HOST_INT_INFO
29221+ /* | HOST_INT_OVERFLOW */
29222+ /* | HOST_INT_PROCESS_ERROR */
29223+ | HOST_INT_SCAN_COMPLETE
29224+ | HOST_INT_FCS_THRESHOLD
29225+ /* | HOST_INT_UNKNOWN */
29226+ );
29227+ /* Or else acx100 won't signal cmd completion, right? */
29228+ adev->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */
29229+ } else {
29230+ adev->irq_mask = (u16) ~(0
29231+ /* | HOST_INT_RX_DATA */
29232+ | HOST_INT_TX_COMPLETE
29233+ /* | HOST_INT_TX_XFER */
29234+ | HOST_INT_RX_COMPLETE
29235+ /* | HOST_INT_DTIM */
29236+ /* | HOST_INT_BEACON */
29237+ /* | HOST_INT_TIMER */
29238+ /* | HOST_INT_KEY_NOT_FOUND */
29239+ /* | HOST_INT_IV_ICV_FAILURE */
29240+ | HOST_INT_CMD_COMPLETE
29241+ | HOST_INT_INFO
29242+ /* | HOST_INT_OVERFLOW */
29243+ /* | HOST_INT_PROCESS_ERROR */
29244+ | HOST_INT_SCAN_COMPLETE
29245+ /* | HOST_INT_FCS_THRESHOLD */
29246+ /* | HOST_INT_UNKNOWN */
29247+ );
29248+ adev->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */
29249+ }
29250+}
29251+
29252+
29253+/***********************************************************************
29254+*/
29255+int
29256+acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm)
29257+{
29258+ /* since it can be assumed that at least the Maxim radio has a
29259+ * maximum power output of 20dBm and since it also can be
29260+ * assumed that these values drive the DAC responsible for
29261+ * setting the linear Tx level, I'd guess that these values
29262+ * should be the corresponding linear values for a dBm value,
29263+ * in other words: calculate the values from that formula:
29264+ * Y [dBm] = 10 * log (X [mW])
29265+ * then scale the 0..63 value range onto the 1..100mW range (0..20 dBm)
29266+ * and you're done...
29267+ * Hopefully that's ok, but you never know if we're actually
29268+ * right... (especially since Windows XP doesn't seem to show
29269+ * actual Tx dBm values :-P) */
29270+
29271+ /* NOTE: on Maxim, value 30 IS 30mW, and value 10 IS 10mW - so the
29272+ * values are EXACTLY mW!!! Not sure about RFMD and others,
29273+ * though... */
29274+ static const u8 dbm2val_maxim[21] = {
29275+ 63, 63, 63, 62,
29276+ 61, 61, 60, 60,
29277+ 59, 58, 57, 55,
29278+ 53, 50, 47, 43,
29279+ 38, 31, 23, 13,
29280+ 0
29281+ };
29282+ static const u8 dbm2val_rfmd[21] = {
29283+ 0, 0, 0, 1,
29284+ 2, 2, 3, 3,
29285+ 4, 5, 6, 8,
29286+ 10, 13, 16, 20,
29287+ 25, 32, 41, 50,
29288+ 63
29289+ };
29290+ const u8 *table;
29291+
29292+ switch (adev->radio_type) {
29293+ case RADIO_MAXIM_0D:
29294+ table = &dbm2val_maxim[0];
29295+ break;
29296+ case RADIO_RFMD_11:
29297+ case RADIO_RALINK_15:
29298+ table = &dbm2val_rfmd[0];
29299+ break;
29300+ default:
29301+ printk("%s: unknown/unsupported radio type, "
29302+ "cannot modify tx power level yet!\n",
29303+ adev->ndev->name);
29304+ return NOT_OK;
29305+ }
29306+ printk("%s: changing radio power level to %u dBm (%u)\n",
29307+ adev->ndev->name, level_dbm, table[level_dbm]);
29308+ acxpci_s_write_phy_reg(adev, 0x11, table[level_dbm]);
29309+ return OK;
29310+}
29311+
29312+
29313+/***********************************************************************
29314+** Data for init_module/cleanup_module
29315+*/
29316+static const struct pci_device_id
29317+acxpci_id_tbl[] __devinitdata = {
29318+ {
29319+ .vendor = PCI_VENDOR_ID_TI,
29320+ .device = PCI_DEVICE_ID_TI_TNETW1100A,
29321+ .subvendor = PCI_ANY_ID,
29322+ .subdevice = PCI_ANY_ID,
29323+ .driver_data = CHIPTYPE_ACX100,
29324+ },
29325+ {
29326+ .vendor = PCI_VENDOR_ID_TI,
29327+ .device = PCI_DEVICE_ID_TI_TNETW1100B,
29328+ .subvendor = PCI_ANY_ID,
29329+ .subdevice = PCI_ANY_ID,
29330+ .driver_data = CHIPTYPE_ACX100,
29331+ },
29332+ {
29333+ .vendor = PCI_VENDOR_ID_TI,
29334+ .device = PCI_DEVICE_ID_TI_TNETW1130,
29335+ .subvendor = PCI_ANY_ID,
29336+ .subdevice = PCI_ANY_ID,
29337+ .driver_data = CHIPTYPE_ACX111,
29338+ },
29339+ {
29340+ .vendor = 0,
29341+ .device = 0,
29342+ .subvendor = 0,
29343+ .subdevice = 0,
29344+ .driver_data = 0,
29345+ }
29346+};
29347+
29348+MODULE_DEVICE_TABLE(pci, acxpci_id_tbl);
29349+
29350+/* FIXME: checks should be removed once driver is included in the kernel */
29351+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
29352+/* pci_name() got introduced at start of 2.6.x,
29353+ * got mandatory (slot_name member removed) in 2.6.11-bk1 */
29354+#define pci_name(x) x->slot_name
29355+#endif
29356+
29357+static struct pci_driver
29358+acxpci_drv_id = {
29359+ .name = "acx_pci",
29360+ .id_table = acxpci_id_tbl,
29361+ .probe = acxpci_e_probe,
29362+ .remove = __devexit_p(acxpci_e_remove),
29363+#ifdef CONFIG_PM
29364+ .suspend = acxpci_e_suspend,
29365+ .resume = acxpci_e_resume
29366+#endif /* CONFIG_PM */
29367+};
29368+
29369+
29370+/***********************************************************************
29371+** acxpci_e_init_module
29372+**
29373+** Module initialization routine, called once at module load time
29374+*/
29375+int __init
29376+acxpci_e_init_module(void)
29377+{
29378+ int res;
29379+
29380+ FN_ENTER;
29381+
29382+#if (ACX_IO_WIDTH==32)
29383+ printk("acx: compiled to use 32bit I/O access. "
29384+ "I/O timing issues might occur, such as "
29385+ "non-working firmware upload. Report them\n");
29386+#else
29387+ printk("acx: compiled to use 16bit I/O access only "
29388+ "(compatibility mode)\n");
29389+#endif
29390+
29391+#ifdef __LITTLE_ENDIAN
29392+#define ENDIANNESS_STRING "running on a little-endian CPU\n"
29393+#else
29394+#define ENDIANNESS_STRING "running on a BIG-ENDIAN CPU\n"
29395+#endif
29396+ log(L_INIT,
29397+ ENDIANNESS_STRING
29398+ "PCI module " ACX_RELEASE " initialized, "
29399+ "waiting for cards to probe...\n"
29400+ );
29401+
29402+ res = pci_register_driver(&acxpci_drv_id);
29403+ FN_EXIT1(res);
29404+ return res;
29405+}
29406+
29407+
29408+/***********************************************************************
29409+** acxpci_e_cleanup_module
29410+**
29411+** Called at module unload time. This is our last chance to
29412+** clean up after ourselves.
29413+*/
29414+void __exit
29415+acxpci_e_cleanup_module(void)
29416+{
29417+ FN_ENTER;
29418+
29419+ pci_unregister_driver(&acxpci_drv_id);
29420+
29421+ FN_EXIT0;
29422+}
29423Index: linux-2.6.22/drivers/net/wireless/acx/rx3000_acx.c
29424===================================================================
29425--- /dev/null 1970-01-01 00:00:00.000000000 +0000
29426+++ linux-2.6.22/drivers/net/wireless/acx/rx3000_acx.c 2007-08-23 18:34:19.000000000 +0200
29427@@ -0,0 +1,110 @@
29428+/*
29429+ * WLAN (TI TNETW1100B) support in the HP iPAQ RX3000
29430+ *
29431+ * Copyright (c) 2006 SDG Systems, LLC
29432+ * Copyright (c) 2006 Roman Moravcik
29433+ *
29434+ * This file is subject to the terms and conditions of the GNU General Public
29435+ * License. See the file COPYING in the main directory of this archive for
29436+ * more details.
29437+ *
29438+ * Based on hx4700_acx.c
29439+ */
29440+
29441+
29442+#include <linux/kernel.h>
29443+#include <linux/platform_device.h>
29444+#include <linux/delay.h>
29445+#include <linux/dpm.h>
29446+#include <linux/leds.h>
29447+
29448+#include <asm/hardware.h>
29449+
29450+#include <asm/arch/regs-gpio.h>
29451+#include <linux/mfd/asic3_base.h>
29452+#include <asm/arch/rx3000.h>
29453+#include <asm/arch/rx3000-asic3.h>
29454+#include <asm/io.h>
29455+
29456+#include "acx_hw.h"
29457+
29458+extern struct platform_device s3c_device_asic3;
29459+
29460+static int rx3000_wlan_start(void)
29461+{
29462+ DPM_DEBUG("rx3000_acx: Turning on\n");
29463+ asic3_set_gpio_out_b(&s3c_device_asic3.dev, ASIC3_GPB3, ASIC3_GPB3);
29464+ mdelay(20);
29465+ asic3_set_gpio_out_c(&s3c_device_asic3.dev, ASIC3_GPC13, ASIC3_GPC13);
29466+ mdelay(20);
29467+ asic3_set_gpio_out_c(&s3c_device_asic3.dev, ASIC3_GPC11, ASIC3_GPC11);
29468+ mdelay(100);
29469+ asic3_set_gpio_out_b(&s3c_device_asic3.dev, ASIC3_GPB3, ASIC3_GPB3);
29470+ mdelay(20);
29471+ s3c2410_gpio_cfgpin(S3C2410_GPA15, S3C2410_GPA15_nGCS4);
29472+ mdelay(100);
29473+ s3c2410_gpio_setpin(S3C2410_GPA11, 0);
29474+ mdelay(50);
29475+ s3c2410_gpio_setpin(S3C2410_GPA11, 1);
29476+ led_trigger_event_shared(rx3000_radio_trig, LED_FULL);
29477+ return 0;
29478+}
29479+
29480+static int rx3000_wlan_stop(void)
29481+{
29482+ DPM_DEBUG("rx3000_acx: Turning off\n");
29483+ s3c2410_gpio_setpin(S3C2410_GPA15, 1);
29484+ s3c2410_gpio_cfgpin(S3C2410_GPA15, S3C2410_GPA15_OUT);
29485+ asic3_set_gpio_out_b(&s3c_device_asic3.dev, ASIC3_GPB3, 0);
29486+ asic3_set_gpio_out_c(&s3c_device_asic3.dev, ASIC3_GPC13, 0);
29487+ asic3_set_gpio_out_c(&s3c_device_asic3.dev, ASIC3_GPC11, 0);
29488+ led_trigger_event_shared(rx3000_radio_trig, LED_OFF);
29489+ return 0;
29490+}
29491+
29492+static struct resource acx_resources[] = {
29493+ [0] = {
29494+ .start = RX3000_PA_WLAN,
29495+ .end = RX3000_PA_WLAN + 0x20,
29496+ .flags = IORESOURCE_MEM,
29497+ },
29498+ [1] = {
29499+ .start = IRQ_EINT16,
29500+ .end = IRQ_EINT16,
29501+ .flags = IORESOURCE_IRQ,
29502+ },
29503+};
29504+
29505+static struct acx_hardware_data acx_data = {
29506+ .start_hw = rx3000_wlan_start,
29507+ .stop_hw = rx3000_wlan_stop,
29508+};
29509+
29510+static struct platform_device acx_device = {
29511+ .name = "acx-mem",
29512+ .dev = {
29513+ .platform_data = &acx_data,
29514+ },
29515+ .num_resources = ARRAY_SIZE(acx_resources),
29516+ .resource = acx_resources,
29517+};
29518+
29519+static int __init rx3000_wlan_init(void)
29520+{
29521+ printk("rx3000_wlan_init: acx-mem platform_device_register\n");
29522+ return platform_device_register(&acx_device);
29523+}
29524+
29525+
29526+static void __exit rx3000_wlan_exit(void)
29527+{
29528+ platform_device_unregister(&acx_device);
29529+}
29530+
29531+module_init(rx3000_wlan_init);
29532+module_exit(rx3000_wlan_exit);
29533+
29534+MODULE_AUTHOR("Todd Blumer <todd@sdgsystems.com>, Roman Moravcik <roman.moravcik@gmail.com>");
29535+MODULE_DESCRIPTION("WLAN driver for HP iPAQ RX3000");
29536+MODULE_LICENSE("GPL");
29537+
29538Index: linux-2.6.22/drivers/net/wireless/acx/setrate.c
29539===================================================================
29540--- /dev/null 1970-01-01 00:00:00.000000000 +0000
29541+++ linux-2.6.22/drivers/net/wireless/acx/setrate.c 2007-08-23 18:34:19.000000000 +0200
29542@@ -0,0 +1,213 @@
29543+/* TODO: stop #including, move into wireless.c
29544+ * until then, keep in sync copies in prism54/ and acx/ dirs
29545+ * code+data size: less than 1k */
29546+
29547+enum {
29548+ DOT11_RATE_1,
29549+ DOT11_RATE_2,
29550+ DOT11_RATE_5,
29551+ DOT11_RATE_11,
29552+ DOT11_RATE_22,
29553+ DOT11_RATE_33,
29554+ DOT11_RATE_6,
29555+ DOT11_RATE_9,
29556+ DOT11_RATE_12,
29557+ DOT11_RATE_18,
29558+ DOT11_RATE_24,
29559+ DOT11_RATE_36,
29560+ DOT11_RATE_48,
29561+ DOT11_RATE_54
29562+};
29563+enum {
29564+ DOT11_MOD_DBPSK,
29565+ DOT11_MOD_DQPSK,
29566+ DOT11_MOD_CCK,
29567+ DOT11_MOD_OFDM,
29568+ DOT11_MOD_CCKOFDM,
29569+ DOT11_MOD_PBCC
29570+};
29571+static const u8 ratelist[] = { 1,2,5,11,22,33,6,9,12,18,24,36,48,54 };
29572+static const u8 dot11ratebyte[] = { 1*2,2*2,11,11*2,22*2,33*2,6*2,9*2,12*2,18*2,24*2,36*2,48*2,54*2 };
29573+static const u8 default_modulation[] = {
29574+ DOT11_MOD_DBPSK,
29575+ DOT11_MOD_DQPSK,
29576+ DOT11_MOD_CCK,
29577+ DOT11_MOD_CCK,
29578+ DOT11_MOD_PBCC,
29579+ DOT11_MOD_PBCC,
29580+ DOT11_MOD_OFDM,
29581+ DOT11_MOD_OFDM,
29582+ DOT11_MOD_OFDM,
29583+ DOT11_MOD_OFDM,
29584+ DOT11_MOD_OFDM,
29585+ DOT11_MOD_OFDM,
29586+ DOT11_MOD_OFDM,
29587+ DOT11_MOD_OFDM
29588+};
29589+
29590+static /* TODO: remove 'static' when moved to wireless.c */
29591+int
29592+rate_mbit2enum(int n) {
29593+ int i=0;
29594+ while(i<sizeof(ratelist)) {
29595+ if(n==ratelist[i]) return i;
29596+ i++;
29597+ }
29598+ return -EINVAL;
29599+}
29600+
29601+static int
29602+get_modulation(int r_enum, char suffix) {
29603+ if(suffix==',' || suffix==' ' || suffix=='\0') {
29604+ /* could shorten default_mod by 8 bytes:
29605+ if(r_enum>=DOT11_RATE_6) return DOT11_MOD_OFDM; */
29606+ return default_modulation[r_enum];
29607+ }
29608+ if(suffix=='c') {
29609+ if(r_enum<DOT11_RATE_5 || r_enum>DOT11_RATE_11) return -EINVAL;
29610+ return DOT11_MOD_CCK;
29611+ }
29612+ if(suffix=='p') {
29613+ if(r_enum<DOT11_RATE_5 || r_enum>DOT11_RATE_33) return -EINVAL;
29614+ return DOT11_MOD_PBCC;
29615+ }
29616+ if(suffix=='o') {
29617+ if(r_enum<DOT11_RATE_6) return -EINVAL;
29618+ return DOT11_MOD_OFDM;
29619+ }
29620+ if(suffix=='d') {
29621+ if(r_enum<DOT11_RATE_6) return -EINVAL;
29622+ return DOT11_MOD_CCKOFDM;
29623+ }
29624+ return -EINVAL;
29625+}
29626+
29627+#ifdef UNUSED
29628+static int
29629+fill_ratevector(const char **pstr, u8 *vector, int size,
29630+ int (*supported)(int mbit, int mod, void *opaque), void *opaque, int or_mask)
29631+{
29632+ unsigned long rate_mbit;
29633+ int rate_enum,mod;
29634+ const char *str = *pstr;
29635+ char c;
29636+
29637+ do {
29638+ rate_mbit = simple_strtoul(str, (char**)&str, 10);
29639+ if(rate_mbit>INT_MAX) return -EINVAL;
29640+
29641+ rate_enum = rate_mbit2enum(rate_mbit);
29642+ if(rate_enum<0) return rate_enum;
29643+
29644+ c = *str;
29645+ mod = get_modulation(rate_enum, c);
29646+ if(mod<0) return mod;
29647+
29648+ if(c>='a' && c<='z') c = *++str;
29649+ if(c!=',' && c!=' ' && c!='\0') return -EINVAL;
29650+
29651+ if(supported) {
29652+ int r = supported(rate_mbit, mod, opaque);
29653+ if(r) return r;
29654+ }
29655+
29656+ *vector++ = dot11ratebyte[rate_enum] | or_mask;
29657+
29658+ size--;
29659+ str++;
29660+ } while(size>0 && c==',');
29661+
29662+ if(size<1) return -E2BIG;
29663+ *vector=0; /* TODO: sort, remove dups? */
29664+
29665+ *pstr = str-1;
29666+ return 0;
29667+}
29668+
29669+static /* TODO: remove 'static' when moved to wireless.c */
29670+int
29671+fill_ratevectors(const char *str, u8 *brate, u8 *orate, int size,
29672+ int (*supported)(int mbit, int mod, void *opaque), void *opaque)
29673+{
29674+ int r;
29675+
29676+ r = fill_ratevector(&str, brate, size, supported, opaque, 0x80);
29677+ if(r) return r;
29678+
29679+ orate[0] = 0;
29680+ if(*str==' ') {
29681+ str++;
29682+ r = fill_ratevector(&str, orate, size, supported, opaque, 0);
29683+ if(r) return r;
29684+ /* TODO: sanitize, e.g. remove/error on rates already in basic rate set? */
29685+ }
29686+ if(*str)
29687+ return -EINVAL;
29688+
29689+ return 0;
29690+}
29691+#endif
29692+
29693+/* TODO: use u64 masks? */
29694+
29695+static int
29696+fill_ratemask(const char **pstr, u32* mask,
29697+ int (*supported)(int mbit, int mod,void *opaque),
29698+ u32 (*gen_mask)(int mbit, int mod,void *opaque),
29699+ void *opaque)
29700+{
29701+ unsigned long rate_mbit;
29702+ int rate_enum,mod;
29703+ u32 m = 0;
29704+ const char *str = *pstr;
29705+ char c;
29706+
29707+ do {
29708+ rate_mbit = simple_strtoul(str, (char**)&str, 10);
29709+ if(rate_mbit>INT_MAX) return -EINVAL;
29710+
29711+ rate_enum = rate_mbit2enum(rate_mbit);
29712+ if(rate_enum<0) return rate_enum;
29713+
29714+ c = *str;
29715+ mod = get_modulation(rate_enum, c);
29716+ if(mod<0) return mod;
29717+
29718+ if(c>='a' && c<='z') c = *++str;
29719+ if(c!=',' && c!=' ' && c!='\0') return -EINVAL;
29720+
29721+ if(supported) {
29722+ int r = supported(rate_mbit, mod, opaque);
29723+ if(r) return r;
29724+ }
29725+
29726+ m |= gen_mask(rate_mbit, mod, opaque);
29727+ str++;
29728+ } while(c==',');
29729+
29730+ *pstr = str-1;
29731+ *mask |= m;
29732+ return 0;
29733+}
29734+
29735+static /* TODO: remove 'static' when moved to wireless.c */
29736+int
29737+fill_ratemasks(const char *str, u32 *bmask, u32 *omask,
29738+ int (*supported)(int mbit, int mod,void *opaque),
29739+ u32 (*gen_mask)(int mbit, int mod,void *opaque),
29740+ void *opaque)
29741+{
29742+ int r;
29743+
29744+ r = fill_ratemask(&str, bmask, supported, gen_mask, opaque);
29745+ if(r) return r;
29746+
29747+ if(*str==' ') {
29748+ str++;
29749+ r = fill_ratemask(&str, omask, supported, gen_mask, opaque);
29750+ if(r) return r;
29751+ }
29752+ if(*str)
29753+ return -EINVAL;
29754+ return 0;
29755+}
29756Index: linux-2.6.22/drivers/net/wireless/acx/usb.c
29757===================================================================
29758--- /dev/null 1970-01-01 00:00:00.000000000 +0000
29759+++ linux-2.6.22/drivers/net/wireless/acx/usb.c 2007-08-23 18:34:19.000000000 +0200
29760@@ -0,0 +1,1922 @@
29761+/***********************************************************************
29762+** Copyright (C) 2003 ACX100 Open Source Project
29763+**
29764+** The contents of this file are subject to the Mozilla Public
29765+** License Version 1.1 (the "License"); you may not use this file
29766+** except in compliance with the License. You may obtain a copy of
29767+** the License at http://www.mozilla.org/MPL/
29768+**
29769+** Software distributed under the License is distributed on an "AS
29770+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
29771+** implied. See the License for the specific language governing
29772+** rights and limitations under the License.
29773+**
29774+** Alternatively, the contents of this file may be used under the
29775+** terms of the GNU Public License version 2 (the "GPL"), in which
29776+** case the provisions of the GPL are applicable instead of the
29777+** above. If you wish to allow the use of your version of this file
29778+** only under the terms of the GPL and not to allow others to use
29779+** your version of this file under the MPL, indicate your decision
29780+** by deleting the provisions above and replace them with the notice
29781+** and other provisions required by the GPL. If you do not delete
29782+** the provisions above, a recipient may use your version of this
29783+** file under either the MPL or the GPL.
29784+** ---------------------------------------------------------------------
29785+** Inquiries regarding the ACX100 Open Source Project can be
29786+** made directly to:
29787+**
29788+** acx100-users@lists.sf.net
29789+** http://acx100.sf.net
29790+** ---------------------------------------------------------------------
29791+*/
29792+
29793+/***********************************************************************
29794+** USB support for TI ACX100 based devices. Many parts are taken from
29795+** the PCI driver.
29796+**
29797+** Authors:
29798+** Martin Wawro <martin.wawro AT uni-dortmund.de>
29799+** Andreas Mohr <andi AT lisas.de>
29800+**
29801+** LOCKING
29802+** callback functions called by USB core are running in interrupt context
29803+** and thus have names with _i_.
29804+*/
29805+#define ACX_USB 1
29806+
29807+#include <linux/version.h>
29808+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
29809+#include <linux/config.h>
29810+#endif
29811+#include <linux/types.h>
29812+#include <linux/module.h>
29813+#include <linux/moduleparam.h>
29814+#include <linux/kernel.h>
29815+#include <linux/usb.h>
29816+#include <linux/netdevice.h>
29817+#include <linux/rtnetlink.h>
29818+#include <linux/etherdevice.h>
29819+#include <linux/wireless.h>
29820+#include <net/iw_handler.h>
29821+#include <linux/vmalloc.h>
29822+
29823+#include "acx.h"
29824+
29825+
29826+/***********************************************************************
29827+*/
29828+/* number of endpoints of an interface */
29829+#define NUM_EP(intf) (intf)->altsetting[0].desc.bNumEndpoints
29830+#define EP(intf, nr) (intf)->altsetting[0].endpoint[(nr)].desc
29831+#define GET_DEV(udev) usb_get_dev((udev))
29832+#define PUT_DEV(udev) usb_put_dev((udev))
29833+#define SET_NETDEV_OWNER(ndev, owner) /* not needed anymore ??? */
29834+
29835+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
29836+/* removed in 2.6.14. We will use fake value for now */
29837+#define URB_ASYNC_UNLINK 0
29838+#endif
29839+
29840+
29841+/***********************************************************************
29842+*/
29843+/* ACX100 (TNETW1100) USB device: D-Link DWL-120+ */
29844+#define ACX100_VENDOR_ID 0x2001
29845+#define ACX100_PRODUCT_ID_UNBOOTED 0x3B01
29846+#define ACX100_PRODUCT_ID_BOOTED 0x3B00
29847+
29848+/* TNETW1450 USB devices */
29849+#define VENDOR_ID_DLINK 0x07b8 /* D-Link Corp. */
29850+#define PRODUCT_ID_WUG2400 0xb21a /* AboCom WUG2400 or SafeCom SWLUT-54125 */
29851+#define VENDOR_ID_AVM_GMBH 0x057c
29852+#define PRODUCT_ID_AVM_WLAN_USB 0x5601
29853+#define PRODUCT_ID_AVM_WLAN_USB_si 0x6201 /* "self install" named Version: driver kills kernel on inbound scans from fritz box ??? */
29854+#define VENDOR_ID_ZCOM 0x0cde
29855+#define PRODUCT_ID_ZCOM_XG750 0x0017 /* not tested yet */
29856+#define VENDOR_ID_TI 0x0451
29857+#define PRODUCT_ID_TI_UNKNOWN 0x60c5 /* not tested yet */
29858+
29859+#define ACX_USB_CTRL_TIMEOUT 5500 /* steps in ms */
29860+
29861+/* Buffer size for fw upload, same for both ACX100 USB and TNETW1450 */
29862+#define USB_RWMEM_MAXLEN 2048
29863+
29864+/* The number of bulk URBs to use */
29865+#define ACX_TX_URB_CNT 8
29866+#define ACX_RX_URB_CNT 2
29867+
29868+/* Should be sent to the bulkout endpoint */
29869+#define ACX_USB_REQ_UPLOAD_FW 0x10
29870+#define ACX_USB_REQ_ACK_CS 0x11
29871+#define ACX_USB_REQ_CMD 0x12
29872+
29873+/***********************************************************************
29874+** Prototypes
29875+*/
29876+static int acxusb_e_probe(struct usb_interface *, const struct usb_device_id *);
29877+static void acxusb_e_disconnect(struct usb_interface *);
29878+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
29879+static void acxusb_i_complete_tx(struct urb *);
29880+static void acxusb_i_complete_rx(struct urb *);
29881+#else
29882+static void acxusb_i_complete_tx(struct urb *, struct pt_regs *);
29883+static void acxusb_i_complete_rx(struct urb *, struct pt_regs *);
29884+#endif
29885+static int acxusb_e_open(struct net_device *);
29886+static int acxusb_e_close(struct net_device *);
29887+static void acxusb_i_set_rx_mode(struct net_device *);
29888+static int acxusb_boot(struct usb_device *, int is_tnetw1450, int *radio_type);
29889+
29890+static void acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx);
29891+
29892+static void acxusb_i_tx_timeout(struct net_device *);
29893+
29894+/* static void dump_device(struct usb_device *); */
29895+/* static void dump_device_descriptor(struct usb_device_descriptor *); */
29896+/* static void dump_config_descriptor(struct usb_config_descriptor *); */
29897+
29898+/***********************************************************************
29899+** Module Data
29900+*/
29901+#define TXBUFSIZE sizeof(usb_txbuffer_t)
29902+/*
29903+ * Now, this is just plain lying, but the device insists in giving us
29904+ * huge packets. We supply extra space after rxbuffer. Need to understand
29905+ * it better...
29906+ */
29907+#define RXBUFSIZE (sizeof(rxbuffer_t) + \
29908+ (sizeof(usb_rx_t) - sizeof(struct usb_rx_plain)))
29909+
29910+static const struct usb_device_id
29911+acxusb_ids[] = {
29912+ { USB_DEVICE(ACX100_VENDOR_ID, ACX100_PRODUCT_ID_BOOTED) },
29913+ { USB_DEVICE(ACX100_VENDOR_ID, ACX100_PRODUCT_ID_UNBOOTED) },
29914+ { USB_DEVICE(VENDOR_ID_DLINK, PRODUCT_ID_WUG2400) },
29915+ { USB_DEVICE(VENDOR_ID_AVM_GMBH, PRODUCT_ID_AVM_WLAN_USB) },
29916+ { USB_DEVICE(VENDOR_ID_AVM_GMBH, PRODUCT_ID_AVM_WLAN_USB_si) },
29917+ { USB_DEVICE(VENDOR_ID_ZCOM, PRODUCT_ID_ZCOM_XG750) },
29918+ { USB_DEVICE(VENDOR_ID_TI, PRODUCT_ID_TI_UNKNOWN) },
29919+ {}
29920+};
29921+
29922+MODULE_DEVICE_TABLE(usb, acxusb_ids);
29923+
29924+/* USB driver data structure as required by the kernel's USB core */
29925+static struct usb_driver
29926+acxusb_driver = {
29927+ .name = "acx_usb",
29928+ .probe = acxusb_e_probe,
29929+ .disconnect = acxusb_e_disconnect,
29930+ .id_table = acxusb_ids
29931+};
29932+
29933+
29934+/***********************************************************************
29935+** USB helper
29936+**
29937+** ldd3 ch13 says:
29938+** When the function is usb_kill_urb, the urb lifecycle is stopped. This
29939+** function is usually used when the device is disconnected from the system,
29940+** in the disconnect callback. For some drivers, the usb_unlink_urb function
29941+** should be used to tell the USB core to stop an urb. This function does not
29942+** wait for the urb to be fully stopped before returning to the caller.
29943+** This is useful for stoppingthe urb while in an interrupt handler or when
29944+** a spinlock is held, as waiting for a urb to fully stop requires the ability
29945+** for the USB core to put the calling process to sleep. This function requires
29946+** that the URB_ASYNC_UNLINK flag value be set in the urb that is being asked
29947+** to be stopped in order to work properly.
29948+**
29949+** (URB_ASYNC_UNLINK is obsolete, usb_unlink_urb will always be
29950+** asynchronous while usb_kill_urb is synchronous and should be called
29951+** directly (drivers/usb/core/urb.c))
29952+**
29953+** In light of this, timeout is just for paranoid reasons...
29954+*
29955+* Actually, it's useful for debugging. If we reach timeout, we're doing
29956+* something wrong with the urbs.
29957+*/
29958+static void
29959+acxusb_unlink_urb(struct urb* urb)
29960+{
29961+ if (!urb)
29962+ return;
29963+
29964+ if (urb->status == -EINPROGRESS) {
29965+ int timeout = 10;
29966+
29967+ usb_unlink_urb(urb);
29968+ while (--timeout && urb->status == -EINPROGRESS) {
29969+ mdelay(1);
29970+ }
29971+ if (!timeout) {
29972+ printk("acx_usb: urb unlink timeout!\n");
29973+ }
29974+ }
29975+}
29976+
29977+
29978+/***********************************************************************
29979+** EEPROM and PHY read/write helpers
29980+*/
29981+/***********************************************************************
29982+** acxusb_s_read_phy_reg
29983+*/
29984+int
29985+acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf)
29986+{
29987+ /* mem_read_write_t mem; */
29988+
29989+ FN_ENTER;
29990+
29991+ printk("%s doesn't seem to work yet, disabled.\n", __func__);
29992+
29993+ /*
29994+ mem.addr = cpu_to_le16(reg);
29995+ mem.type = cpu_to_le16(0x82);
29996+ mem.len = cpu_to_le32(4);
29997+ acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_READ, &mem, sizeof(mem));
29998+ *charbuf = mem.data;
29999+ log(L_DEBUG, "read radio PHY[0x%04X]=0x%02X\n", reg, *charbuf);
30000+ */
30001+
30002+ FN_EXIT1(OK);
30003+ return OK;
30004+}
30005+
30006+
30007+/***********************************************************************
30008+*/
30009+int
30010+acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value)
30011+{
30012+ mem_read_write_t mem;
30013+
30014+ FN_ENTER;
30015+
30016+ mem.addr = cpu_to_le16(reg);
30017+ mem.type = cpu_to_le16(0x82);
30018+ mem.len = cpu_to_le32(4);
30019+ mem.data = value;
30020+ acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_WRITE, &mem, sizeof(mem));
30021+ log(L_DEBUG, "write radio PHY[0x%04X]=0x%02X\n", reg, value);
30022+
30023+ FN_EXIT1(OK);
30024+ return OK;
30025+}
30026+
30027+
30028+/***********************************************************************
30029+** acxusb_s_issue_cmd_timeo
30030+** Excecutes a command in the command mailbox
30031+**
30032+** buffer = a pointer to the data.
30033+** The data must not include 4 byte command header
30034+*/
30035+
30036+/* TODO: ideally we shall always know how much we need
30037+** and this shall be 0 */
30038+#define BOGUS_SAFETY_PADDING 0x40
30039+
30040+#undef FUNC
30041+#define FUNC "issue_cmd"
30042+
30043+#if !ACX_DEBUG
30044+int
30045+acxusb_s_issue_cmd_timeo(
30046+ acx_device_t *adev,
30047+ unsigned cmd,
30048+ void *buffer,
30049+ unsigned buflen,
30050+ unsigned timeout)
30051+{
30052+#else
30053+int
30054+acxusb_s_issue_cmd_timeo_debug(
30055+ acx_device_t *adev,
30056+ unsigned cmd,
30057+ void *buffer,
30058+ unsigned buflen,
30059+ unsigned timeout,
30060+ const char* cmdstr)
30061+{
30062+#endif
30063+ /* USB ignores timeout param */
30064+
30065+ struct usb_device *usbdev;
30066+ struct {
30067+ u16 cmd;
30068+ u16 status;
30069+ u8 data[1];
30070+ } ACX_PACKED *loc;
30071+ const char *devname;
30072+ int acklen, blocklen, inpipe, outpipe;
30073+ int cmd_status;
30074+ int result;
30075+
30076+ FN_ENTER;
30077+
30078+ devname = adev->ndev->name;
30079+ /* no "wlan%%d: ..." please */
30080+ if (!devname || !devname[0] || devname[4]=='%')
30081+ devname = "acx";
30082+
30083+ log(L_CTL, FUNC"(cmd:%s,buflen:%u,type:0x%04X)\n",
30084+ cmdstr, buflen,
30085+ buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1);
30086+
30087+ loc = kmalloc(buflen + 4 + BOGUS_SAFETY_PADDING, GFP_KERNEL);
30088+ if (!loc) {
30089+ printk("%s: "FUNC"(): no memory for data buffer\n", devname);
30090+ goto bad;
30091+ }
30092+
30093+ /* get context from acx_device */
30094+ usbdev = adev->usbdev;
30095+
30096+ /* check which kind of command was issued */
30097+ loc->cmd = cpu_to_le16(cmd);
30098+ loc->status = 0;
30099+
30100+/* NB: buflen == frmlen + 4
30101+**
30102+** Interrogate: write 8 bytes: (cmd,status,rid,frmlen), then
30103+** read (cmd,status,rid,frmlen,data[frmlen]) back
30104+**
30105+** Configure: write (cmd,status,rid,frmlen,data[frmlen])
30106+**
30107+** Possibly bogus special handling of ACX1xx_IE_SCAN_STATUS removed
30108+*/
30109+
30110+ /* now write the parameters of the command if needed */
30111+ acklen = buflen + 4 + BOGUS_SAFETY_PADDING;
30112+ blocklen = buflen;
30113+ if (buffer && buflen) {
30114+ /* if it's an INTERROGATE command, just pass the length
30115+ * of parameters to read, as data */
30116+ if (cmd == ACX1xx_CMD_INTERROGATE) {
30117+ blocklen = 4;
30118+ acklen = buflen + 4;
30119+ }
30120+ memcpy(loc->data, buffer, blocklen);
30121+ }
30122+ blocklen += 4; /* account for cmd,status */
30123+
30124+ /* obtain the I/O pipes */
30125+ outpipe = usb_sndctrlpipe(usbdev, 0);
30126+ inpipe = usb_rcvctrlpipe(usbdev, 0);
30127+ log(L_CTL, "ctrl inpipe=0x%X outpipe=0x%X\n", inpipe, outpipe);
30128+ log(L_CTL, "sending USB control msg (out) (blocklen=%d)\n", blocklen);
30129+ if (acx_debug & L_DATA)
30130+ acx_dump_bytes(loc, blocklen);
30131+
30132+ result = usb_control_msg(usbdev, outpipe,
30133+ ACX_USB_REQ_CMD, /* request */
30134+ USB_TYPE_VENDOR|USB_DIR_OUT, /* requesttype */
30135+ 0, /* value */
30136+ 0, /* index */
30137+ loc, /* dataptr */
30138+ blocklen, /* size */
30139+ ACX_USB_CTRL_TIMEOUT /* timeout in ms */
30140+ );
30141+
30142+ if (result == -ENODEV) {
30143+ log(L_CTL, "no device present (unplug?)\n");
30144+ goto good;
30145+ }
30146+
30147+ log(L_CTL, "wrote %d bytes\n", result);
30148+ if (result < 0) {
30149+ goto bad;
30150+ }
30151+
30152+ /* check for device acknowledge */
30153+ log(L_CTL, "sending USB control msg (in) (acklen=%d)\n", acklen);
30154+ loc->status = 0; /* delete old status flag -> set to IDLE */
30155+ /* shall we zero out the rest? */
30156+ result = usb_control_msg(usbdev, inpipe,
30157+ ACX_USB_REQ_CMD, /* request */
30158+ USB_TYPE_VENDOR|USB_DIR_IN, /* requesttype */
30159+ 0, /* value */
30160+ 0, /* index */
30161+ loc, /* dataptr */
30162+ acklen, /* size */
30163+ ACX_USB_CTRL_TIMEOUT /* timeout in ms */
30164+ );
30165+ if (result < 0) {
30166+ printk("%s: "FUNC"(): USB read error %d\n", devname, result);
30167+ goto bad;
30168+ }
30169+ if (acx_debug & L_CTL) {
30170+ printk("read %d bytes: ", result);
30171+ acx_dump_bytes(loc, result);
30172+ }
30173+
30174+/*
30175+ check for result==buflen+4? Was seen:
30176+
30177+interrogate(type:ACX100_IE_DOT11_ED_THRESHOLD,len:4)
30178+issue_cmd(cmd:ACX1xx_CMD_INTERROGATE,buflen:8,type:4111)
30179+ctrl inpipe=0x80000280 outpipe=0x80000200
30180+sending USB control msg (out) (blocklen=8)
30181+01 00 00 00 0F 10 04 00
30182+wrote 8 bytes
30183+sending USB control msg (in) (acklen=12) sizeof(loc->data
30184+read 4 bytes <==== MUST BE 12!!
30185+*/
30186+
30187+ cmd_status = le16_to_cpu(loc->status);
30188+ if (cmd_status != 1) {
30189+ printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s)\n",
30190+ devname, cmd_status, acx_cmd_status_str(cmd_status));
30191+ /* TODO: goto bad; ? */
30192+ }
30193+ if ((cmd == ACX1xx_CMD_INTERROGATE) && buffer && buflen) {
30194+ memcpy(buffer, loc->data, buflen);
30195+ log(L_CTL, "response frame: cmd=0x%04X status=%d\n",
30196+ le16_to_cpu(loc->cmd),
30197+ cmd_status);
30198+ }
30199+good:
30200+ kfree(loc);
30201+ FN_EXIT1(OK);
30202+ return OK;
30203+bad:
30204+ /* Give enough info so that callers can avoid
30205+ ** printing their own diagnostic messages */
30206+#if ACX_DEBUG
30207+ printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr);
30208+#else
30209+ printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd);
30210+#endif
30211+ dump_stack();
30212+ kfree(loc);
30213+ FN_EXIT1(NOT_OK);
30214+ return NOT_OK;
30215+}
30216+
30217+
30218+/***********************************************************************
30219+** acxusb_boot()
30220+** Inputs:
30221+** usbdev -> Pointer to kernel's usb_device structure
30222+**
30223+** Returns:
30224+** (int) Errorcode or 0 on success
30225+**
30226+** This function triggers the loading of the firmware image from harddisk
30227+** and then uploads the firmware to the USB device. After uploading the
30228+** firmware and transmitting the checksum, the device resets and appears
30229+** as a new device on the USB bus (the device we can finally deal with)
30230+*/
30231+static inline int
30232+acxusb_fw_needs_padding(firmware_image_t *fw_image, unsigned int usb_maxlen)
30233+{
30234+ unsigned int num_xfers = ((fw_image->size - 1) / usb_maxlen) + 1;
30235+
30236+ return ((num_xfers % 2) == 0);
30237+}
30238+
30239+static int
30240+acxusb_boot(struct usb_device *usbdev, int is_tnetw1450, int *radio_type)
30241+{
30242+ char filename[sizeof("tiacx1NNusbcRR")];
30243+
30244+ firmware_image_t *fw_image = NULL;
30245+ char *usbbuf;
30246+ unsigned int offset;
30247+ unsigned int blk_len, inpipe, outpipe;
30248+ u32 num_processed;
30249+ u32 img_checksum, sum;
30250+ u32 file_size;
30251+ int result = -EIO;
30252+ int i;
30253+
30254+ FN_ENTER;
30255+
30256+ /* dump_device(usbdev); */
30257+
30258+ usbbuf = kmalloc(USB_RWMEM_MAXLEN, GFP_KERNEL);
30259+ if (!usbbuf) {
30260+ printk(KERN_ERR "acx: no memory for USB transfer buffer (%d bytes)\n", USB_RWMEM_MAXLEN);
30261+ result = -ENOMEM;
30262+ goto end;
30263+ }
30264+ if (is_tnetw1450) {
30265+ /* Obtain the I/O pipes */
30266+ outpipe = usb_sndbulkpipe(usbdev, 1);
30267+ inpipe = usb_rcvbulkpipe(usbdev, 2);
30268+
30269+ printk(KERN_DEBUG "wait for device ready\n");
30270+ for (i = 0; i <= 2; i++) {
30271+ result = usb_bulk_msg(usbdev, inpipe,
30272+ usbbuf,
30273+ USB_RWMEM_MAXLEN,
30274+ &num_processed,
30275+ 2000
30276+ );
30277+
30278+ if ((*(u32 *)&usbbuf[4] == 0x40000001)
30279+ && (*(u16 *)&usbbuf[2] == 0x1)
30280+ && ((*(u16 *)usbbuf & 0x3fff) == 0)
30281+ && ((*(u16 *)usbbuf & 0xc000) == 0xc000))
30282+ break;
30283+ msleep(10);
30284+ }
30285+ if (i == 2)
30286+ goto fw_end;
30287+
30288+ *radio_type = usbbuf[8];
30289+ } else {
30290+ /* Obtain the I/O pipes */
30291+ outpipe = usb_sndctrlpipe(usbdev, 0);
30292+ inpipe = usb_rcvctrlpipe(usbdev, 0);
30293+
30294+ /* FIXME: shouldn't be hardcoded */
30295+ *radio_type = RADIO_MAXIM_0D;
30296+ }
30297+
30298+ snprintf(filename, sizeof(filename), "tiacx1%02dusbc%02X",
30299+ is_tnetw1450 * 11, *radio_type);
30300+
30301+ fw_image = acx_s_read_fw(&usbdev->dev, filename, &file_size);
30302+ if (!fw_image) {
30303+ result = -EIO;
30304+ goto end;
30305+ }
30306+ log(L_INIT, "firmware size: %d bytes\n", file_size);
30307+
30308+ img_checksum = le32_to_cpu(fw_image->chksum);
30309+
30310+ if (is_tnetw1450) {
30311+ u8 cmdbuf[20];
30312+ const u8 *p;
30313+ u8 need_padding;
30314+ u32 tmplen, val;
30315+
30316+ memset(cmdbuf, 0, 16);
30317+
30318+ need_padding = acxusb_fw_needs_padding(fw_image, USB_RWMEM_MAXLEN);
30319+ tmplen = need_padding ? file_size-4 : file_size-8;
30320+ *(u16 *)&cmdbuf[0] = 0xc000;
30321+ *(u16 *)&cmdbuf[2] = 0x000b;
30322+ *(u32 *)&cmdbuf[4] = tmplen;
30323+ *(u32 *)&cmdbuf[8] = file_size-8;
30324+ *(u32 *)&cmdbuf[12] = img_checksum;
30325+
30326+ result = usb_bulk_msg(usbdev, outpipe, cmdbuf, 16, &num_processed, HZ);
30327+ if (result < 0)
30328+ goto fw_end;
30329+
30330+ p = (const u8 *)&fw_image->size;
30331+
30332+ /* first calculate checksum for image size part */
30333+ sum = p[0]+p[1]+p[2]+p[3];
30334+ p += 4;
30335+
30336+ /* now continue checksum for firmware data part */
30337+ tmplen = le32_to_cpu(fw_image->size);
30338+ for (i = 0; i < tmplen /* image size */; i++) {
30339+ sum += *p++;
30340+ }
30341+
30342+ if (sum != le32_to_cpu(fw_image->chksum)) {
30343+ printk("acx: FATAL: firmware upload: "
30344+ "checksums don't match! "
30345+ "(0x%08x vs. 0x%08x)\n",
30346+ sum, fw_image->chksum);
30347+ goto fw_end;
30348+ }
30349+
30350+ offset = 8;
30351+ while (offset < file_size) {
30352+ blk_len = file_size - offset;
30353+ if (blk_len > USB_RWMEM_MAXLEN) {
30354+ blk_len = USB_RWMEM_MAXLEN;
30355+ }
30356+
30357+ log(L_INIT, "uploading firmware (%d bytes, offset=%d)\n",
30358+ blk_len, offset);
30359+ memcpy(usbbuf, ((u8 *)fw_image) + offset, blk_len);
30360+
30361+ p = usbbuf;
30362+ for (i = 0; i < blk_len; i += 4) {
30363+ *(u32 *)p = be32_to_cpu(*(u32 *)p);
30364+ p += 4;
30365+ }
30366+
30367+ result = usb_bulk_msg(usbdev, outpipe, usbbuf, blk_len, &num_processed, HZ);
30368+ if ((result < 0) || (num_processed != blk_len))
30369+ goto fw_end;
30370+ offset += blk_len;
30371+ }
30372+ if (need_padding) {
30373+ printk(KERN_DEBUG "send padding\n");
30374+ memset(usbbuf, 0, 4);
30375+ result = usb_bulk_msg(usbdev, outpipe, usbbuf, 4, &num_processed, HZ);
30376+ if ((result < 0) || (num_processed != 4))
30377+ goto fw_end;
30378+ }
30379+ printk(KERN_DEBUG "read firmware upload result\n");
30380+ memset(cmdbuf, 0, 20); /* additional memset */
30381+ result = usb_bulk_msg(usbdev, inpipe, cmdbuf, 20, &num_processed, 2000);
30382+ if (result < 0)
30383+ goto fw_end;
30384+ if (*(u32 *)&cmdbuf[4] == 0x40000003)
30385+ goto fw_end;
30386+ if (*(u32 *)&cmdbuf[4])
30387+ goto fw_end;
30388+ if (*(u16 *)&cmdbuf[16] != 1)
30389+ goto fw_end;
30390+
30391+ val = *(u32 *)&cmdbuf[0];
30392+ if ((val & 0x3fff)
30393+ || ((val & 0xc000) != 0xc000))
30394+ goto fw_end;
30395+
30396+ val = *(u32 *)&cmdbuf[8];
30397+ if (val & 2) {
30398+ result = usb_bulk_msg(usbdev, inpipe, cmdbuf, 20, &num_processed, 2000);
30399+ if (result < 0)
30400+ goto fw_end;
30401+ val = *(u32 *)&cmdbuf[8];
30402+ }
30403+ /* yup, no "else" here! */
30404+ if (val & 1) {
30405+ memset(usbbuf, 0, 4);
30406+ result = usb_bulk_msg(usbdev, outpipe, usbbuf, 4, &num_processed, HZ);
30407+ if ((result < 0) || (!num_processed))
30408+ goto fw_end;
30409+ }
30410+
30411+ printk("TNETW1450 firmware upload successful!\n");
30412+ result = 0;
30413+ goto end;
30414+fw_end:
30415+ result = -EIO;
30416+ goto end;
30417+ } else {
30418+ /* ACX100 USB */
30419+
30420+ /* now upload the firmware, slice the data into blocks */
30421+ offset = 8;
30422+ while (offset < file_size) {
30423+ blk_len = file_size - offset;
30424+ if (blk_len > USB_RWMEM_MAXLEN) {
30425+ blk_len = USB_RWMEM_MAXLEN;
30426+ }
30427+ log(L_INIT, "uploading firmware (%d bytes, offset=%d)\n",
30428+ blk_len, offset);
30429+ memcpy(usbbuf, ((u8 *)fw_image) + offset, blk_len);
30430+ result = usb_control_msg(usbdev, outpipe,
30431+ ACX_USB_REQ_UPLOAD_FW,
30432+ USB_TYPE_VENDOR|USB_DIR_OUT,
30433+ (file_size - 8) & 0xffff, /* value */
30434+ (file_size - 8) >> 16, /* index */
30435+ usbbuf, /* dataptr */
30436+ blk_len, /* size */
30437+ 3000 /* timeout in ms */
30438+ );
30439+ offset += blk_len;
30440+ if (result < 0) {
30441+ printk(KERN_ERR "acx: error %d during upload "
30442+ "of firmware, aborting\n", result);
30443+ goto end;
30444+ }
30445+ }
30446+
30447+ /* finally, send the checksum and reboot the device */
30448+ /* does this trigger the reboot? */
30449+ result = usb_control_msg(usbdev, outpipe,
30450+ ACX_USB_REQ_UPLOAD_FW,
30451+ USB_TYPE_VENDOR|USB_DIR_OUT,
30452+ img_checksum & 0xffff, /* value */
30453+ img_checksum >> 16, /* index */
30454+ NULL, /* dataptr */
30455+ 0, /* size */
30456+ 3000 /* timeout in ms */
30457+ );
30458+ if (result < 0) {
30459+ printk(KERN_ERR "acx: error %d during tx of checksum, "
30460+ "aborting\n", result);
30461+ goto end;
30462+ }
30463+ result = usb_control_msg(usbdev, inpipe,
30464+ ACX_USB_REQ_ACK_CS,
30465+ USB_TYPE_VENDOR|USB_DIR_IN,
30466+ img_checksum & 0xffff, /* value */
30467+ img_checksum >> 16, /* index */
30468+ usbbuf, /* dataptr */
30469+ 8, /* size */
30470+ 3000 /* timeout in ms */
30471+ );
30472+ if (result < 0) {
30473+ printk(KERN_ERR "acx: error %d during ACK of checksum, "
30474+ "aborting\n", result);
30475+ goto end;
30476+ }
30477+ if (*usbbuf != 0x10) {
30478+ printk(KERN_ERR "acx: invalid checksum?\n");
30479+ result = -EINVAL;
30480+ goto end;
30481+ }
30482+ result = 0;
30483+ }
30484+
30485+end:
30486+ vfree(fw_image);
30487+ kfree(usbbuf);
30488+
30489+ FN_EXIT1(result);
30490+ return result;
30491+}
30492+
30493+
30494+/* FIXME: maybe merge it with usual eeprom reading, into common code? */
30495+static void
30496+acxusb_s_read_eeprom_version(acx_device_t *adev)
30497+{
30498+ u8 eeprom_ver[0x8];
30499+
30500+ memset(eeprom_ver, 0, sizeof(eeprom_ver));
30501+ acx_s_interrogate(adev, &eeprom_ver, ACX1FF_IE_EEPROM_VER);
30502+
30503+ /* FIXME: which one of those values to take? */
30504+ adev->eeprom_version = eeprom_ver[5];
30505+}
30506+
30507+
30508+/*
30509+ * temporary helper function to at least fill important cfgopt members with
30510+ * useful replacement values until we figure out how one manages to fetch
30511+ * the configoption struct in the USB device case...
30512+ */
30513+static int
30514+acxusb_s_fill_configoption(acx_device_t *adev)
30515+{
30516+ adev->cfgopt_probe_delay = 200;
30517+ adev->cfgopt_dot11CCAModes = 4;
30518+ adev->cfgopt_dot11Diversity = 1;
30519+ adev->cfgopt_dot11ShortPreambleOption = 1;
30520+ adev->cfgopt_dot11PBCCOption = 1;
30521+ adev->cfgopt_dot11ChannelAgility = 0;
30522+ adev->cfgopt_dot11PhyType = 5;
30523+ adev->cfgopt_dot11TempType = 1;
30524+ return OK;
30525+}
30526+
30527+
30528+/***********************************************************************
30529+** acxusb_e_probe()
30530+**
30531+** This function is invoked by the kernel's USB core whenever a new device is
30532+** attached to the system or the module is loaded. It is presented a usb_device
30533+** structure from which information regarding the device is obtained and evaluated.
30534+** In case this driver is able to handle one of the offered devices, it returns
30535+** a non-null pointer to a driver context and thereby claims the device.
30536+*/
30537+
30538+static void
30539+dummy_netdev_init(struct net_device *ndev) {}
30540+
30541+static int
30542+acxusb_e_probe(struct usb_interface *intf, const struct usb_device_id *devID)
30543+{
30544+ struct usb_device *usbdev = interface_to_usbdev(intf);
30545+ acx_device_t *adev = NULL;
30546+ struct net_device *ndev = NULL;
30547+ struct usb_config_descriptor *config;
30548+ struct usb_endpoint_descriptor *epdesc;
30549+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
30550+ struct usb_host_endpoint *ep;
30551+#endif
30552+ struct usb_interface_descriptor *ifdesc;
30553+ const char* msg;
30554+ int numconfigs, numfaces, numep;
30555+ int result = OK;
30556+ int i;
30557+ int radio_type;
30558+ /* this one needs to be more precise in case there appears a TNETW1450 from the same vendor */
30559+ int is_tnetw1450 = (usbdev->descriptor.idVendor != ACX100_VENDOR_ID);
30560+
30561+ FN_ENTER;
30562+
30563+ if (is_tnetw1450) {
30564+ /* Boot the device (i.e. upload the firmware) */
30565+ acxusb_boot(usbdev, is_tnetw1450, &radio_type);
30566+
30567+ /* TNETW1450-based cards will continue right away with
30568+ * the same USB ID after booting */
30569+ } else {
30570+ /* First check if this is the "unbooted" hardware */
30571+ if (usbdev->descriptor.idProduct == ACX100_PRODUCT_ID_UNBOOTED) {
30572+
30573+ /* Boot the device (i.e. upload the firmware) */
30574+ acxusb_boot(usbdev, is_tnetw1450, &radio_type);
30575+
30576+ /* DWL-120+ will first boot the firmware,
30577+ * then later have a *separate* probe() run
30578+ * since its USB ID will have changed after
30579+ * firmware boot!
30580+ * Since the first probe() run has no
30581+ * other purpose than booting the firmware,
30582+ * simply return immediately.
30583+ */
30584+ log(L_INIT, "finished booting, returning from probe()\n");
30585+ result = OK; /* success */
30586+ goto end;
30587+ }
30588+ else
30589+ /* device not unbooted, but invalid USB ID!? */
30590+ if (usbdev->descriptor.idProduct != ACX100_PRODUCT_ID_BOOTED)
30591+ goto end_nodev;
30592+ }
30593+
30594+/* Ok, so it's our device and it has already booted */
30595+
30596+ /* Allocate memory for a network device */
30597+
30598+ ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init);
30599+ /* (NB: memsets to 0 entire area) */
30600+ if (!ndev) {
30601+ msg = "acx: no memory for netdev\n";
30602+ goto end_nomem;
30603+ }
30604+
30605+ /* Register the callbacks for the network device functions */
30606+
30607+ ether_setup(ndev);
30608+ ndev->open = &acxusb_e_open;
30609+ ndev->stop = &acxusb_e_close;
30610+ ndev->hard_start_xmit = (void *)&acx_i_start_xmit;
30611+ ndev->get_stats = (void *)&acx_e_get_stats;
30612+#if IW_HANDLER_VERSION <= 5
30613+ ndev->get_wireless_stats = (void *)&acx_e_get_wireless_stats;
30614+#endif
30615+ ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def;
30616+ ndev->set_multicast_list = (void *)&acxusb_i_set_rx_mode;
30617+#ifdef HAVE_TX_TIMEOUT
30618+ ndev->tx_timeout = &acxusb_i_tx_timeout;
30619+ ndev->watchdog_timeo = 4 * HZ;
30620+#endif
30621+ ndev->change_mtu = &acx_e_change_mtu;
30622+ SET_MODULE_OWNER(ndev);
30623+
30624+ /* Setup private driver context */
30625+
30626+ adev = ndev2adev(ndev);
30627+ adev->ndev = ndev;
30628+
30629+ adev->dev_type = DEVTYPE_USB;
30630+ adev->radio_type = radio_type;
30631+ if (is_tnetw1450) {
30632+ /* well, actually it's a TNETW1450, but since it
30633+ * seems to be sufficiently similar to TNETW1130,
30634+ * I don't want to change large amounts of code now */
30635+ adev->chip_type = CHIPTYPE_ACX111;
30636+ } else {
30637+ adev->chip_type = CHIPTYPE_ACX100;
30638+ }
30639+
30640+ adev->usbdev = usbdev;
30641+ spin_lock_init(&adev->lock); /* initial state: unlocked */
30642+ sema_init(&adev->sem, 1); /* initial state: 1 (upped) */
30643+
30644+ /* Check that this is really the hardware we know about.
30645+ ** If not sure, at least notify the user that he
30646+ ** may be in trouble...
30647+ */
30648+ numconfigs = (int)usbdev->descriptor.bNumConfigurations;
30649+ if (numconfigs != 1)
30650+ printk("acx: number of configurations is %d, "
30651+ "this driver only knows how to handle 1, "
30652+ "be prepared for surprises\n", numconfigs);
30653+
30654+ config = &usbdev->config->desc;
30655+ numfaces = config->bNumInterfaces;
30656+ if (numfaces != 1)
30657+ printk("acx: number of interfaces is %d, "
30658+ "this driver only knows how to handle 1, "
30659+ "be prepared for surprises\n", numfaces);
30660+
30661+ ifdesc = &intf->altsetting->desc;
30662+ numep = ifdesc->bNumEndpoints;
30663+ log(L_DEBUG, "# of endpoints: %d\n", numep);
30664+
30665+ if (is_tnetw1450) {
30666+ adev->bulkoutep = 1;
30667+ adev->bulkinep = 2;
30668+ } else {
30669+ /* obtain information about the endpoint
30670+ ** addresses, begin with some default values
30671+ */
30672+ adev->bulkoutep = 1;
30673+ adev->bulkinep = 1;
30674+ for (i = 0; i < numep; i++) {
30675+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
30676+ ep = usbdev->ep_in[i];
30677+ if (!ep)
30678+ continue;
30679+ epdesc = &ep->desc;
30680+#else
30681+ epdesc = usb_epnum_to_ep_desc(usbdev, i);
30682+ if (!epdesc)
30683+ continue;
30684+#endif
30685+ if (epdesc->bmAttributes & USB_ENDPOINT_XFER_BULK) {
30686+ if (epdesc->bEndpointAddress & 0x80)
30687+ adev->bulkinep = epdesc->bEndpointAddress & 0xF;
30688+ else
30689+ adev->bulkoutep = epdesc->bEndpointAddress & 0xF;
30690+ }
30691+ }
30692+ }
30693+ log(L_DEBUG, "bulkout ep: 0x%X\n", adev->bulkoutep);
30694+ log(L_DEBUG, "bulkin ep: 0x%X\n", adev->bulkinep);
30695+
30696+ /* already done by memset: adev->rxtruncsize = 0; */
30697+ log(L_DEBUG, "TXBUFSIZE=%d RXBUFSIZE=%d\n",
30698+ (int) TXBUFSIZE, (int) RXBUFSIZE);
30699+
30700+ /* Allocate the RX/TX containers. */
30701+ adev->usb_tx = kmalloc(sizeof(usb_tx_t) * ACX_TX_URB_CNT, GFP_KERNEL);
30702+ if (!adev->usb_tx) {
30703+ msg = "acx: no memory for tx container";
30704+ goto end_nomem;
30705+ }
30706+ adev->usb_rx = kmalloc(sizeof(usb_rx_t) * ACX_RX_URB_CNT, GFP_KERNEL);
30707+ if (!adev->usb_rx) {
30708+ msg = "acx: no memory for rx container";
30709+ goto end_nomem;
30710+ }
30711+
30712+ /* Setup URBs for bulk-in/out messages */
30713+ for (i = 0; i < ACX_RX_URB_CNT; i++) {
30714+ adev->usb_rx[i].urb = usb_alloc_urb(0, GFP_KERNEL);
30715+ if (!adev->usb_rx[i].urb) {
30716+ msg = "acx: no memory for input URB\n";
30717+ goto end_nomem;
30718+ }
30719+ adev->usb_rx[i].urb->status = 0;
30720+ adev->usb_rx[i].adev = adev;
30721+ adev->usb_rx[i].busy = 0;
30722+ }
30723+
30724+ for (i = 0; i< ACX_TX_URB_CNT; i++) {
30725+ adev->usb_tx[i].urb = usb_alloc_urb(0, GFP_KERNEL);
30726+ if (!adev->usb_tx[i].urb) {
30727+ msg = "acx: no memory for output URB\n";
30728+ goto end_nomem;
30729+ }
30730+ adev->usb_tx[i].urb->status = 0;
30731+ adev->usb_tx[i].adev = adev;
30732+ adev->usb_tx[i].busy = 0;
30733+ }
30734+ adev->tx_free = ACX_TX_URB_CNT;
30735+
30736+ usb_set_intfdata(intf, adev);
30737+ SET_NETDEV_DEV(ndev, &intf->dev);
30738+
30739+ /* TODO: move all of fw cmds to open()? But then we won't know our MAC addr
30740+ until ifup (it's available via reading ACX1xx_IE_DOT11_STATION_ID)... */
30741+
30742+ /* put acx out of sleep mode and initialize it */
30743+ acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0);
30744+
30745+ result = acx_s_init_mac(adev);
30746+ if (result)
30747+ goto end;
30748+
30749+ /* TODO: see similar code in pci.c */
30750+ acxusb_s_read_eeprom_version(adev);
30751+ acxusb_s_fill_configoption(adev);
30752+ acx_s_set_defaults(adev);
30753+ acx_s_get_firmware_version(adev);
30754+ acx_display_hardware_details(adev);
30755+
30756+ /* Register the network device */
30757+ log(L_INIT, "registering network device\n");
30758+ result = register_netdev(ndev);
30759+ if (result) {
30760+ msg = "acx: failed to register USB network device "
30761+ "(error %d)\n";
30762+ goto end_nomem;
30763+ }
30764+
30765+ acx_proc_register_entries(ndev);
30766+
30767+ acx_stop_queue(ndev, "on probe");
30768+ acx_carrier_off(ndev, "on probe");
30769+
30770+ printk("acx: USB module " ACX_RELEASE " loaded successfully\n");
30771+
30772+#if CMD_DISCOVERY
30773+ great_inquisitor(adev);
30774+#endif
30775+
30776+ /* Everything went OK, we are happy now */
30777+ result = OK;
30778+ goto end;
30779+
30780+end_nomem:
30781+ printk(msg, result);
30782+
30783+ if (ndev) {
30784+ if (adev->usb_rx) {
30785+ for (i = 0; i < ACX_RX_URB_CNT; i++)
30786+ usb_free_urb(adev->usb_rx[i].urb);
30787+ kfree(adev->usb_rx);
30788+ }
30789+ if (adev->usb_tx) {
30790+ for (i = 0; i < ACX_TX_URB_CNT; i++)
30791+ usb_free_urb(adev->usb_tx[i].urb);
30792+ kfree(adev->usb_tx);
30793+ }
30794+ free_netdev(ndev);
30795+ }
30796+
30797+ result = -ENOMEM;
30798+ goto end;
30799+
30800+end_nodev:
30801+ /* no device we could handle, return error. */
30802+ result = -EIO;
30803+
30804+end:
30805+ FN_EXIT1(result);
30806+ return result;
30807+}
30808+
30809+
30810+/***********************************************************************
30811+** acxusb_e_disconnect()
30812+**
30813+** This function is invoked whenever the user pulls the plug from the USB
30814+** device or the module is removed from the kernel. In these cases, the
30815+** network devices have to be taken down and all allocated memory has
30816+** to be freed.
30817+*/
30818+static void
30819+acxusb_e_disconnect(struct usb_interface *intf)
30820+{
30821+ acx_device_t *adev = usb_get_intfdata(intf);
30822+ unsigned long flags;
30823+ int i;
30824+
30825+ FN_ENTER;
30826+
30827+ /* No WLAN device... no sense */
30828+ if (!adev)
30829+ goto end;
30830+
30831+ /* Unregister network device
30832+ *
30833+ * If the interface is up, unregister_netdev() will take
30834+ * care of calling our close() function, which takes
30835+ * care of unlinking the urbs, sending the device to
30836+ * sleep, etc...
30837+ * This can't be called with sem or lock held because
30838+ * _close() will try to grab it as well if it's called,
30839+ * deadlocking the machine.
30840+ */
30841+ unregister_netdev(adev->ndev);
30842+
30843+ acx_sem_lock(adev);
30844+ acx_lock(adev, flags);
30845+ /* This device exists no more */
30846+ usb_set_intfdata(intf, NULL);
30847+ acx_proc_unregister_entries(adev->ndev);
30848+
30849+ /*
30850+ * Here we only free them. _close() took care of
30851+ * unlinking them.
30852+ */
30853+ for (i = 0; i < ACX_RX_URB_CNT; ++i) {
30854+ usb_free_urb(adev->usb_rx[i].urb);
30855+ }
30856+ for (i = 0; i< ACX_TX_URB_CNT; ++i) {
30857+ usb_free_urb(adev->usb_tx[i].urb);
30858+ }
30859+
30860+ /* Freeing containers */
30861+ kfree(adev->usb_rx);
30862+ kfree(adev->usb_tx);
30863+
30864+ acx_unlock(adev, flags);
30865+ acx_sem_unlock(adev);
30866+
30867+ free_netdev(adev->ndev);
30868+end:
30869+ FN_EXIT0;
30870+}
30871+
30872+
30873+/***********************************************************************
30874+** acxusb_e_open()
30875+** This function is called when the user sets up the network interface.
30876+** It initializes a management timer, sets up the USB card and starts
30877+** the network tx queue and USB receive.
30878+*/
30879+static int
30880+acxusb_e_open(struct net_device *ndev)
30881+{
30882+ acx_device_t *adev = ndev2adev(ndev);
30883+ unsigned long flags;
30884+ int i;
30885+
30886+ FN_ENTER;
30887+
30888+ acx_sem_lock(adev);
30889+
30890+ /* put the ACX100 out of sleep mode */
30891+ acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0);
30892+
30893+ acx_init_task_scheduler(adev);
30894+
30895+ init_timer(&adev->mgmt_timer);
30896+ adev->mgmt_timer.function = acx_i_timer;
30897+ adev->mgmt_timer.data = (unsigned long)adev;
30898+
30899+ /* acx_s_start needs it */
30900+ SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
30901+ acx_s_start(adev);
30902+
30903+ /* don't acx_start_queue() here, we need to associate first */
30904+
30905+ acx_lock(adev, flags);
30906+ for (i = 0; i < ACX_RX_URB_CNT; i++) {
30907+ adev->usb_rx[i].urb->status = 0;
30908+ }
30909+
30910+ acxusb_l_poll_rx(adev, &adev->usb_rx[0]);
30911+
30912+ acx_unlock(adev, flags);
30913+
30914+ acx_sem_unlock(adev);
30915+
30916+ FN_EXIT0;
30917+ return 0;
30918+}
30919+
30920+
30921+/***********************************************************************
30922+** acxusb_e_close()
30923+**
30924+** This function stops the network functionality of the interface (invoked
30925+** when the user calls ifconfig <wlan> down). The tx queue is halted and
30926+** the device is marked as down. In case there were any pending USB bulk
30927+** transfers, these are unlinked (asynchronously). The module in-use count
30928+** is also decreased in this function.
30929+*/
30930+static int
30931+acxusb_e_close(struct net_device *ndev)
30932+{
30933+ acx_device_t *adev = ndev2adev(ndev);
30934+ unsigned long flags;
30935+ int i;
30936+
30937+ FN_ENTER;
30938+
30939+#ifdef WE_STILL_DONT_CARE_ABOUT_IT
30940+ /* Transmit a disassociate frame */
30941+ lock
30942+ acx_l_transmit_disassoc(adev, &client);
30943+ unlock
30944+#endif
30945+
30946+ acx_sem_lock(adev);
30947+
30948+ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
30949+
30950+/* Code below is remarkably similar to acxpci_s_down(). Maybe we can merge them? */
30951+
30952+ /* Make sure we don't get any more rx requests */
30953+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0);
30954+ acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
30955+
30956+ /*
30957+ * We must do FLUSH *without* holding sem to avoid a deadlock.
30958+ * See pci.c:acxpci_s_down() for deails.
30959+ */
30960+ acx_sem_unlock(adev);
30961+ FLUSH_SCHEDULED_WORK();
30962+ acx_sem_lock(adev);
30963+
30964+ /* Power down the device */
30965+ acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0);
30966+
30967+ /* Stop the transmit queue, mark the device as DOWN */
30968+ acx_lock(adev, flags);
30969+ acx_stop_queue(ndev, "on ifdown");
30970+ acx_set_status(adev, ACX_STATUS_0_STOPPED);
30971+ /* stop pending rx/tx urb transfers */
30972+ for (i = 0; i < ACX_TX_URB_CNT; i++) {
30973+ acxusb_unlink_urb(adev->usb_tx[i].urb);
30974+ adev->usb_tx[i].busy = 0;
30975+ }
30976+ for (i = 0; i < ACX_RX_URB_CNT; i++) {
30977+ acxusb_unlink_urb(adev->usb_rx[i].urb);
30978+ adev->usb_rx[i].busy = 0;
30979+ }
30980+ adev->tx_free = ACX_TX_URB_CNT;
30981+ acx_unlock(adev, flags);
30982+
30983+ /* Must do this outside of lock */
30984+ del_timer_sync(&adev->mgmt_timer);
30985+
30986+ acx_sem_unlock(adev);
30987+
30988+ FN_EXIT0;
30989+ return 0;
30990+}
30991+
30992+
30993+/***********************************************************************
30994+** acxusb_l_poll_rx
30995+** This function (re)initiates a bulk-in USB transfer on a given urb
30996+*/
30997+static void
30998+acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx)
30999+{
31000+ struct usb_device *usbdev;
31001+ struct urb *rxurb;
31002+ int errcode, rxnum;
31003+ unsigned int inpipe;
31004+
31005+ FN_ENTER;
31006+
31007+ rxurb = rx->urb;
31008+ usbdev = adev->usbdev;
31009+
31010+ rxnum = rx - adev->usb_rx;
31011+
31012+ inpipe = usb_rcvbulkpipe(usbdev, adev->bulkinep);
31013+ if (unlikely(rxurb->status == -EINPROGRESS)) {
31014+ printk(KERN_ERR "acx: error, rx triggered while rx urb in progress\n");
31015+ /* FIXME: this is nasty, receive is being cancelled by this code
31016+ * on the other hand, this should not happen anyway...
31017+ */
31018+ usb_unlink_urb(rxurb);
31019+ } else
31020+ if (unlikely(rxurb->status == -ECONNRESET)) {
31021+ log(L_USBRXTX, "acx_usb: _poll_rx: connection reset\n");
31022+ goto end;
31023+ }
31024+ rxurb->actual_length = 0;
31025+ usb_fill_bulk_urb(rxurb, usbdev, inpipe,
31026+ &rx->bulkin, /* dataptr */
31027+ RXBUFSIZE, /* size */
31028+ acxusb_i_complete_rx, /* handler */
31029+ rx /* handler param */
31030+ );
31031+ rxurb->transfer_flags = URB_ASYNC_UNLINK;
31032+
31033+ /* ATOMIC: we may be called from complete_rx() usb callback */
31034+ errcode = usb_submit_urb(rxurb, GFP_ATOMIC);
31035+ /* FIXME: evaluate the error code! */
31036+ log(L_USBRXTX, "SUBMIT RX (%d) inpipe=0x%X size=%d errcode=%d\n",
31037+ rxnum, inpipe, (int) RXBUFSIZE, errcode);
31038+end:
31039+ FN_EXIT0;
31040+}
31041+
31042+
31043+/***********************************************************************
31044+** acxusb_i_complete_rx()
31045+** Inputs:
31046+** urb -> pointer to USB request block
31047+** regs -> pointer to register-buffer for syscalls (see asm/ptrace.h)
31048+**
31049+** This function is invoked by USB subsystem whenever a bulk receive
31050+** request returns.
31051+** The received data is then committed to the network stack and the next
31052+** USB receive is triggered.
31053+*/
31054+static void
31055+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
31056+acxusb_i_complete_rx(struct urb *urb)
31057+#else
31058+acxusb_i_complete_rx(struct urb *urb, struct pt_regs *regs)
31059+#endif
31060+{
31061+ acx_device_t *adev;
31062+ rxbuffer_t *ptr;
31063+ rxbuffer_t *inbuf;
31064+ usb_rx_t *rx;
31065+ unsigned long flags;
31066+ int size, remsize, packetsize, rxnum;
31067+
31068+ FN_ENTER;
31069+
31070+ BUG_ON(!urb->context);
31071+
31072+ rx = (usb_rx_t *)urb->context;
31073+ adev = rx->adev;
31074+
31075+ acx_lock(adev, flags);
31076+
31077+ /*
31078+ * Happens on disconnect or close. Don't play with the urb.
31079+ * Don't resubmit it. It will get unlinked by close()
31080+ */
31081+ if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
31082+ log(L_USBRXTX, "rx: device is down, not doing anything\n");
31083+ goto end_unlock;
31084+ }
31085+
31086+ inbuf = &rx->bulkin;
31087+ size = urb->actual_length;
31088+ remsize = size;
31089+ rxnum = rx - adev->usb_rx;
31090+
31091+ log(L_USBRXTX, "RETURN RX (%d) status=%d size=%d\n",
31092+ rxnum, urb->status, size);
31093+
31094+ /* Send the URB that's waiting. */
31095+ log(L_USBRXTX, "rxnum=%d, sending=%d\n", rxnum, rxnum^1);
31096+ acxusb_l_poll_rx(adev, &adev->usb_rx[rxnum^1]);
31097+
31098+ if (unlikely(size > sizeof(rxbuffer_t)))
31099+ printk("acx_usb: rx too large: %d, please report\n", size);
31100+
31101+ /* check if the transfer was aborted */
31102+ switch (urb->status) {
31103+ case 0: /* No error */
31104+ break;
31105+ case -EOVERFLOW:
31106+ printk(KERN_ERR "acx: rx data overrun\n");
31107+ adev->rxtruncsize = 0; /* Not valid anymore. */
31108+ goto end_unlock;
31109+ case -ECONNRESET:
31110+ adev->rxtruncsize = 0;
31111+ goto end_unlock;
31112+ case -ESHUTDOWN: /* rmmod */
31113+ adev->rxtruncsize = 0;
31114+ goto end_unlock;
31115+ default:
31116+ adev->rxtruncsize = 0;
31117+ adev->stats.rx_errors++;
31118+ printk("acx: rx error (urb status=%d)\n", urb->status);
31119+ goto end_unlock;
31120+ }
31121+
31122+ if (unlikely(!size))
31123+ printk("acx: warning, encountered zerolength rx packet\n");
31124+
31125+ if (urb->transfer_buffer != inbuf)
31126+ goto end_unlock;
31127+
31128+ /* check if previous frame was truncated
31129+ ** FIXME: this code can only handle truncation
31130+ ** of consecutive packets!
31131+ */
31132+ ptr = inbuf;
31133+ if (adev->rxtruncsize) {
31134+ int tail_size;
31135+
31136+ ptr = &adev->rxtruncbuf;
31137+ packetsize = RXBUF_BYTES_USED(ptr);
31138+ if (acx_debug & L_USBRXTX) {
31139+ printk("handling truncated frame (truncsize=%d size=%d "
31140+ "packetsize(from trunc)=%d)\n",
31141+ adev->rxtruncsize, size, packetsize);
31142+ acx_dump_bytes(ptr, RXBUF_HDRSIZE);
31143+ acx_dump_bytes(inbuf, RXBUF_HDRSIZE);
31144+ }
31145+
31146+ /* bytes needed for rxtruncbuf completion: */
31147+ tail_size = packetsize - adev->rxtruncsize;
31148+
31149+ if (size < tail_size) {
31150+ /* there is not enough data to complete this packet,
31151+ ** simply append the stuff to the truncation buffer
31152+ */
31153+ memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, size);
31154+ adev->rxtruncsize += size;
31155+ remsize = 0;
31156+ } else {
31157+ /* ok, this data completes the previously
31158+ ** truncated packet. copy it into a descriptor
31159+ ** and give it to the rest of the stack */
31160+
31161+ /* append tail to previously truncated part
31162+ ** NB: adev->rxtruncbuf (pointed to by ptr) can't
31163+ ** overflow because this is already checked before
31164+ ** truncation buffer was filled. See below,
31165+ ** "if (packetsize > sizeof(rxbuffer_t))..." code */
31166+ memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, tail_size);
31167+
31168+ if (acx_debug & L_USBRXTX) {
31169+ printk("full trailing packet + 12 bytes:\n");
31170+ acx_dump_bytes(inbuf, tail_size + RXBUF_HDRSIZE);
31171+ }
31172+ acx_l_process_rxbuf(adev, ptr);
31173+ adev->rxtruncsize = 0;
31174+ ptr = (rxbuffer_t *) (((char *)inbuf) + tail_size);
31175+ remsize -= tail_size;
31176+ }
31177+ log(L_USBRXTX, "post-merge size=%d remsize=%d\n",
31178+ size, remsize);
31179+ }
31180+
31181+ /* size = USB data block size
31182+ ** remsize = unprocessed USB bytes left
31183+ ** ptr = current pos in USB data block
31184+ */
31185+ while (remsize) {
31186+ if (remsize < RXBUF_HDRSIZE) {
31187+ printk("acx: truncated rx header (%d bytes)!\n",
31188+ remsize);
31189+ if (ACX_DEBUG)
31190+ acx_dump_bytes(ptr, remsize);
31191+ break;
31192+ }
31193+
31194+ packetsize = RXBUF_BYTES_USED(ptr);
31195+ log(L_USBRXTX, "packet with packetsize=%d\n", packetsize);
31196+
31197+ if (RXBUF_IS_TXSTAT(ptr)) {
31198+ /* do rate handling */
31199+ usb_txstatus_t *stat = (void*)ptr;
31200+ u16 client_no = (u16)stat->hostdata;
31201+
31202+ log(L_USBRXTX, "tx: stat: mac_cnt_rcvd:%04X "
31203+ "queue_index:%02X mac_status:%02X hostdata:%08X "
31204+ "rate:%u ack_failures:%02X rts_failures:%02X "
31205+ "rts_ok:%02X\n",
31206+ stat->mac_cnt_rcvd,
31207+ stat->queue_index, stat->mac_status, stat->hostdata,
31208+ stat->rate, stat->ack_failures, stat->rts_failures,
31209+ stat->rts_ok);
31210+
31211+ if (adev->rate_auto && client_no < VEC_SIZE(adev->sta_list)) {
31212+ client_t *clt = &adev->sta_list[client_no];
31213+ u16 cur = stat->hostdata >> 16;
31214+
31215+ if (clt && clt->rate_cur == cur) {
31216+ acx_l_handle_txrate_auto(adev, clt,
31217+ cur, /* intended rate */
31218+ stat->rate, 0, /* actually used rate */
31219+ stat->mac_status, /* error? */
31220+ ACX_TX_URB_CNT - adev->tx_free);
31221+ }
31222+ }
31223+ goto next;
31224+ }
31225+
31226+ if (packetsize > sizeof(rxbuffer_t)) {
31227+ printk("acx: packet exceeds max wlan "
31228+ "frame size (%d > %d). size=%d\n",
31229+ packetsize, (int) sizeof(rxbuffer_t), size);
31230+ if (ACX_DEBUG)
31231+ acx_dump_bytes(ptr, 16);
31232+ /* FIXME: put some real error-handling in here! */
31233+ break;
31234+ }
31235+
31236+ if (packetsize > remsize) {
31237+ /* frame truncation handling */
31238+ if (acx_debug & L_USBRXTX) {
31239+ printk("need to truncate packet, "
31240+ "packetsize=%d remsize=%d "
31241+ "size=%d bytes:",
31242+ packetsize, remsize, size);
31243+ acx_dump_bytes(ptr, RXBUF_HDRSIZE);
31244+ }
31245+ memcpy(&adev->rxtruncbuf, ptr, remsize);
31246+ adev->rxtruncsize = remsize;
31247+ break;
31248+ }
31249+
31250+ /* packetsize <= remsize */
31251+ /* now handle the received data */
31252+ acx_l_process_rxbuf(adev, ptr);
31253+next:
31254+ ptr = (rxbuffer_t *)(((char *)ptr) + packetsize);
31255+ remsize -= packetsize;
31256+ if ((acx_debug & L_USBRXTX) && remsize) {
31257+ printk("more than one packet in buffer, "
31258+ "second packet hdr:");
31259+ acx_dump_bytes(ptr, RXBUF_HDRSIZE);
31260+ }
31261+ }
31262+
31263+end_unlock:
31264+ acx_unlock(adev, flags);
31265+/* end: */
31266+ FN_EXIT0;
31267+}
31268+
31269+
31270+/***********************************************************************
31271+** acxusb_i_complete_tx()
31272+** Inputs:
31273+** urb -> pointer to USB request block
31274+** regs -> pointer to register-buffer for syscalls (see asm/ptrace.h)
31275+**
31276+** This function is invoked upon termination of a USB transfer.
31277+*/
31278+static void
31279+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
31280+acxusb_i_complete_tx(struct urb *urb)
31281+#else
31282+acxusb_i_complete_tx(struct urb *urb, struct pt_regs *regs)
31283+#endif
31284+{
31285+ acx_device_t *adev;
31286+ usb_tx_t *tx;
31287+ unsigned long flags;
31288+ int txnum;
31289+
31290+ FN_ENTER;
31291+
31292+ BUG_ON(!urb->context);
31293+
31294+ tx = (usb_tx_t *)urb->context;
31295+ adev = tx->adev;
31296+
31297+ txnum = tx - adev->usb_tx;
31298+
31299+ acx_lock(adev, flags);
31300+
31301+ /*
31302+ * If the iface isn't up, we don't have any right
31303+ * to play with them. The urb may get unlinked.
31304+ */
31305+ if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) {
31306+ log(L_USBRXTX, "tx: device is down, not doing anything\n");
31307+ goto end_unlock;
31308+ }
31309+
31310+ log(L_USBRXTX, "RETURN TX (%d): status=%d size=%d\n",
31311+ txnum, urb->status, urb->actual_length);
31312+
31313+ /* handle USB transfer errors */
31314+ switch (urb->status) {
31315+ case 0: /* No error */
31316+ break;
31317+ case -ESHUTDOWN:
31318+ goto end_unlock;
31319+ break;
31320+ case -ECONNRESET:
31321+ goto end_unlock;
31322+ break;
31323+ /* FIXME: real error-handling code here please */
31324+ default:
31325+ printk(KERN_ERR "acx: tx error, urb status=%d\n", urb->status);
31326+ /* FIXME: real error-handling code here please */
31327+ }
31328+
31329+ /* free the URB and check for more data */
31330+ tx->busy = 0;
31331+ adev->tx_free++;
31332+ if ((adev->tx_free >= TX_START_QUEUE)
31333+ && (adev->status == ACX_STATUS_4_ASSOCIATED)
31334+ && (acx_queue_stopped(adev->ndev))
31335+ ) {
31336+ log(L_BUF, "tx: wake queue (%u free txbufs)\n",
31337+ adev->tx_free);
31338+ acx_wake_queue(adev->ndev, NULL);
31339+ }
31340+
31341+end_unlock:
31342+ acx_unlock(adev, flags);
31343+/* end: */
31344+ FN_EXIT0;
31345+}
31346+
31347+
31348+/***************************************************************
31349+** acxusb_l_alloc_tx
31350+** Actually returns a usb_tx_t* ptr
31351+*/
31352+tx_t*
31353+acxusb_l_alloc_tx(acx_device_t *adev)
31354+{
31355+ usb_tx_t *tx;
31356+ unsigned head;
31357+
31358+ FN_ENTER;
31359+
31360+ head = adev->tx_head;
31361+ do {
31362+ head = (head + 1) % ACX_TX_URB_CNT;
31363+ if (!adev->usb_tx[head].busy) {
31364+ log(L_USBRXTX, "allocated tx %d\n", head);
31365+ tx = &adev->usb_tx[head];
31366+ tx->busy = 1;
31367+ adev->tx_free--;
31368+ /* Keep a few free descs between head and tail of tx ring.
31369+ ** It is not absolutely needed, just feels safer */
31370+ if (adev->tx_free < TX_STOP_QUEUE) {
31371+ log(L_BUF, "tx: stop queue "
31372+ "(%u free txbufs)\n", adev->tx_free);
31373+ acx_stop_queue(adev->ndev, NULL);
31374+ }
31375+ goto end;
31376+ }
31377+ } while (likely(head!=adev->tx_head));
31378+ tx = NULL;
31379+ printk_ratelimited("acx: tx buffers full\n");
31380+end:
31381+ adev->tx_head = head;
31382+ FN_EXIT0;
31383+ return (tx_t*)tx;
31384+}
31385+
31386+
31387+/***************************************************************
31388+** Used if alloc_tx()'ed buffer needs to be cancelled without doing tx
31389+*/
31390+void
31391+acxusb_l_dealloc_tx(tx_t *tx_opaque)
31392+{
31393+ usb_tx_t* tx = (usb_tx_t*)tx_opaque;
31394+ tx->busy = 0;
31395+}
31396+
31397+
31398+/***************************************************************
31399+*/
31400+void*
31401+acxusb_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque)
31402+{
31403+ usb_tx_t* tx = (usb_tx_t*)tx_opaque;
31404+ return &tx->bulkout.data;
31405+}
31406+
31407+
31408+/***************************************************************
31409+** acxusb_l_tx_data
31410+**
31411+** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx).
31412+** Can be called from acx_i_start_xmit (data frames from net core).
31413+*/
31414+void
31415+acxusb_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int wlanpkt_len)
31416+{
31417+ struct usb_device *usbdev;
31418+ struct urb* txurb;
31419+ usb_tx_t* tx;
31420+ usb_txbuffer_t* txbuf;
31421+ client_t *clt;
31422+ wlan_hdr_t* whdr;
31423+ unsigned int outpipe;
31424+ int ucode, txnum;
31425+
31426+ FN_ENTER;
31427+
31428+ tx = ((usb_tx_t *)tx_opaque);
31429+ txurb = tx->urb;
31430+ txbuf = &tx->bulkout;
31431+ whdr = (wlan_hdr_t *)txbuf->data;
31432+ txnum = tx - adev->usb_tx;
31433+
31434+ log(L_DEBUG, "using buf#%d free=%d len=%d\n",
31435+ txnum, adev->tx_free, wlanpkt_len);
31436+
31437+ switch (adev->mode) {
31438+ case ACX_MODE_0_ADHOC:
31439+ case ACX_MODE_3_AP:
31440+ clt = acx_l_sta_list_get(adev, whdr->a1);
31441+ break;
31442+ case ACX_MODE_2_STA:
31443+ clt = adev->ap_client;
31444+ break;
31445+ default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */
31446+ clt = NULL;
31447+ break;
31448+ }
31449+
31450+ if (unlikely(clt && !clt->rate_cur)) {
31451+ printk("acx: driver bug! bad ratemask\n");
31452+ goto end;
31453+ }
31454+
31455+ /* fill the USB transfer header */
31456+ txbuf->desc = cpu_to_le16(USB_TXBUF_TXDESC);
31457+ txbuf->mpdu_len = cpu_to_le16(wlanpkt_len);
31458+ txbuf->queue_index = 1;
31459+ if (clt) {
31460+ txbuf->rate = clt->rate_100;
31461+ txbuf->hostdata = (clt - adev->sta_list) | (clt->rate_cur << 16);
31462+ } else {
31463+ txbuf->rate = adev->rate_bcast100;
31464+ txbuf->hostdata = ((u16)-1) | (adev->rate_bcast << 16);
31465+ }
31466+ txbuf->ctrl1 = DESC_CTL_FIRSTFRAG;
31467+ if (1 == adev->preamble_cur)
31468+ SET_BIT(txbuf->ctrl1, DESC_CTL_SHORT_PREAMBLE);
31469+ txbuf->ctrl2 = 0;
31470+ txbuf->data_len = cpu_to_le16(wlanpkt_len);
31471+
31472+ if (unlikely(acx_debug & L_DATA)) {
31473+ printk("dump of bulk out urb:\n");
31474+ acx_dump_bytes(txbuf, wlanpkt_len + USB_TXBUF_HDRSIZE);
31475+ }
31476+
31477+ if (unlikely(txurb->status == -EINPROGRESS)) {
31478+ printk("acx: trying to submit tx urb while already in progress\n");
31479+ }
31480+
31481+ /* now schedule the USB transfer */
31482+ usbdev = adev->usbdev;
31483+ outpipe = usb_sndbulkpipe(usbdev, adev->bulkoutep);
31484+
31485+ usb_fill_bulk_urb(txurb, usbdev, outpipe,
31486+ txbuf, /* dataptr */
31487+ wlanpkt_len + USB_TXBUF_HDRSIZE, /* size */
31488+ acxusb_i_complete_tx, /* handler */
31489+ tx /* handler param */
31490+ );
31491+
31492+ txurb->transfer_flags = URB_ASYNC_UNLINK|URB_ZERO_PACKET;
31493+ ucode = usb_submit_urb(txurb, GFP_ATOMIC);
31494+ log(L_USBRXTX, "SUBMIT TX (%d): outpipe=0x%X buf=%p txsize=%d "
31495+ "rate=%u errcode=%d\n", txnum, outpipe, txbuf,
31496+ wlanpkt_len + USB_TXBUF_HDRSIZE, txbuf->rate, ucode);
31497+
31498+ if (unlikely(ucode)) {
31499+ printk(KERN_ERR "acx: submit_urb() error=%d txsize=%d\n",
31500+ ucode, wlanpkt_len + USB_TXBUF_HDRSIZE);
31501+
31502+ /* on error, just mark the frame as done and update
31503+ ** the statistics
31504+ */
31505+ adev->stats.tx_errors++;
31506+ tx->busy = 0;
31507+ adev->tx_free++;
31508+ /* needed? if (adev->tx_free > TX_START_QUEUE) acx_wake_queue(...) */
31509+ }
31510+end:
31511+ FN_EXIT0;
31512+}
31513+
31514+
31515+/***********************************************************************
31516+*/
31517+static void
31518+acxusb_i_set_rx_mode(struct net_device *ndev)
31519+{
31520+}
31521+
31522+
31523+/***********************************************************************
31524+*/
31525+#ifdef HAVE_TX_TIMEOUT
31526+static void
31527+acxusb_i_tx_timeout(struct net_device *ndev)
31528+{
31529+ acx_device_t *adev = ndev2adev(ndev);
31530+ unsigned long flags;
31531+ int i;
31532+
31533+ FN_ENTER;
31534+
31535+ acx_lock(adev, flags);
31536+ /* unlink the URBs */
31537+ for (i = 0; i < ACX_TX_URB_CNT; i++) {
31538+ acxusb_unlink_urb(adev->usb_tx[i].urb);
31539+ adev->usb_tx[i].busy = 0;
31540+ }
31541+ adev->tx_free = ACX_TX_URB_CNT;
31542+ /* TODO: stats update */
31543+ acx_unlock(adev, flags);
31544+
31545+ FN_EXIT0;
31546+}
31547+#endif
31548+
31549+
31550+/***********************************************************************
31551+** init_module()
31552+**
31553+** This function is invoked upon loading of the kernel module.
31554+** It registers itself at the kernel's USB subsystem.
31555+**
31556+** Returns: Errorcode on failure, 0 on success
31557+*/
31558+int __init
31559+acxusb_e_init_module(void)
31560+{
31561+ log(L_INIT, "USB module " ACX_RELEASE " initialized, "
31562+ "probing for devices...\n");
31563+ return usb_register(&acxusb_driver);
31564+}
31565+
31566+
31567+
31568+/***********************************************************************
31569+** cleanup_module()
31570+**
31571+** This function is invoked as last step of the module unloading. It simply
31572+** deregisters this module at the kernel's USB subsystem.
31573+*/
31574+void __exit
31575+acxusb_e_cleanup_module()
31576+{
31577+ usb_deregister(&acxusb_driver);
31578+}
31579+
31580+
31581+/***********************************************************************
31582+** DEBUG STUFF
31583+*/
31584+#if ACX_DEBUG
31585+
31586+#ifdef UNUSED
31587+static void
31588+dump_device(struct usb_device *usbdev)
31589+{
31590+ int i;
31591+ struct usb_config_descriptor *cd;
31592+
31593+ printk("acx device dump:\n");
31594+ printk(" devnum: %d\n", usbdev->devnum);
31595+ printk(" speed: %d\n", usbdev->speed);
31596+ printk(" tt: 0x%X\n", (unsigned int)(usbdev->tt));
31597+ printk(" ttport: %d\n", (unsigned int)(usbdev->ttport));
31598+ printk(" toggle[0]: 0x%X toggle[1]: 0x%X\n", (unsigned int)(usbdev->toggle[0]), (unsigned int)(usbdev->toggle[1]));
31599+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
31600+ /* This saw a change after 2.6.10 */
31601+ printk(" ep_in wMaxPacketSize: ");
31602+ for (i = 0; i < 16; ++i)
31603+ if (usbdev->ep_in[i] != NULL)
31604+ printk("%d:%d ", i, usbdev->ep_in[i]->desc.wMaxPacketSize);
31605+ printk("\n");
31606+ printk(" ep_out wMaxPacketSize: ");
31607+ for (i = 0; i < VEC_SIZE(usbdev->ep_out); ++i)
31608+ if (usbdev->ep_out[i] != NULL)
31609+ printk("%d:%d ", i, usbdev->ep_out[i]->desc.wMaxPacketSize);
31610+ printk("\n");
31611+#else
31612+ printk(" epmaxpacketin: ");
31613+ for (i = 0; i < 16; i++)
31614+ printk("%d ", usbdev->epmaxpacketin[i]);
31615+ printk("\n");
31616+ printk(" epmaxpacketout: ");
31617+ for (i = 0; i < 16; i++)
31618+ printk("%d ", usbdev->epmaxpacketout[i]);
31619+ printk("\n");
31620+#endif
31621+ printk(" parent: 0x%X\n", (unsigned int)usbdev->parent);
31622+ printk(" bus: 0x%X\n", (unsigned int)usbdev->bus);
31623+#ifdef NO_DATATYPE
31624+ printk(" configs: ");
31625+ for (i = 0; i < usbdev->descriptor.bNumConfigurations; i++)
31626+ printk("0x%X ", usbdev->config[i]);
31627+ printk("\n");
31628+#endif
31629+ printk(" actconfig: %p\n", usbdev->actconfig);
31630+ dump_device_descriptor(&usbdev->descriptor);
31631+
31632+ cd = &usbdev->config->desc;
31633+ dump_config_descriptor(cd);
31634+}
31635+
31636+
31637+/***********************************************************************
31638+*/
31639+static void
31640+dump_config_descriptor(struct usb_config_descriptor *cd)
31641+{
31642+ printk("Configuration Descriptor:\n");
31643+ if (!cd) {
31644+ printk("NULL\n");
31645+ return;
31646+ }
31647+ printk(" bLength: %d (0x%X)\n", cd->bLength, cd->bLength);
31648+ printk(" bDescriptorType: %d (0x%X)\n", cd->bDescriptorType, cd->bDescriptorType);
31649+ printk(" bNumInterfaces: %d (0x%X)\n", cd->bNumInterfaces, cd->bNumInterfaces);
31650+ printk(" bConfigurationValue: %d (0x%X)\n", cd->bConfigurationValue, cd->bConfigurationValue);
31651+ printk(" iConfiguration: %d (0x%X)\n", cd->iConfiguration, cd->iConfiguration);
31652+ printk(" bmAttributes: %d (0x%X)\n", cd->bmAttributes, cd->bmAttributes);
31653+ /* printk(" MaxPower: %d (0x%X)\n", cd->bMaxPower, cd->bMaxPower); */
31654+}
31655+
31656+
31657+static void
31658+dump_device_descriptor(struct usb_device_descriptor *dd)
31659+{
31660+ printk("Device Descriptor:\n");
31661+ if (!dd) {
31662+ printk("NULL\n");
31663+ return;
31664+ }
31665+ printk(" bLength: %d (0x%X)\n", dd->bLength, dd->bLength);
31666+ printk(" bDescriptortype: %d (0x%X)\n", dd->bDescriptorType, dd->bDescriptorType);
31667+ printk(" bcdUSB: %d (0x%X)\n", dd->bcdUSB, dd->bcdUSB);
31668+ printk(" bDeviceClass: %d (0x%X)\n", dd->bDeviceClass, dd->bDeviceClass);
31669+ printk(" bDeviceSubClass: %d (0x%X)\n", dd->bDeviceSubClass, dd->bDeviceSubClass);
31670+ printk(" bDeviceProtocol: %d (0x%X)\n", dd->bDeviceProtocol, dd->bDeviceProtocol);
31671+ printk(" bMaxPacketSize0: %d (0x%X)\n", dd->bMaxPacketSize0, dd->bMaxPacketSize0);
31672+ printk(" idVendor: %d (0x%X)\n", dd->idVendor, dd->idVendor);
31673+ printk(" idProduct: %d (0x%X)\n", dd->idProduct, dd->idProduct);
31674+ printk(" bcdDevice: %d (0x%X)\n", dd->bcdDevice, dd->bcdDevice);
31675+ printk(" iManufacturer: %d (0x%X)\n", dd->iManufacturer, dd->iManufacturer);
31676+ printk(" iProduct: %d (0x%X)\n", dd->iProduct, dd->iProduct);
31677+ printk(" iSerialNumber: %d (0x%X)\n", dd->iSerialNumber, dd->iSerialNumber);
31678+ printk(" bNumConfigurations: %d (0x%X)\n", dd->bNumConfigurations, dd->bNumConfigurations);
31679+}
31680+#endif /* UNUSED */
31681+
31682+#endif /* ACX_DEBUG */
31683Index: linux-2.6.22/drivers/net/wireless/acx/wlan.c
31684===================================================================
31685--- /dev/null 1970-01-01 00:00:00.000000000 +0000
31686+++ linux-2.6.22/drivers/net/wireless/acx/wlan.c 2007-08-23 18:34:19.000000000 +0200
31687@@ -0,0 +1,424 @@
31688+/***********************************************************************
31689+** Copyright (C) 2003 ACX100 Open Source Project
31690+**
31691+** The contents of this file are subject to the Mozilla Public
31692+** License Version 1.1 (the "License"); you may not use this file
31693+** except in compliance with the License. You may obtain a copy of
31694+** the License at http://www.mozilla.org/MPL/
31695+**
31696+** Software distributed under the License is distributed on an "AS
31697+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
31698+** implied. See the License for the specific language governing
31699+** rights and limitations under the License.
31700+**
31701+** Alternatively, the contents of this file may be used under the
31702+** terms of the GNU Public License version 2 (the "GPL"), in which
31703+** case the provisions of the GPL are applicable instead of the
31704+** above. If you wish to allow the use of your version of this file
31705+** only under the terms of the GPL and not to allow others to use
31706+** your version of this file under the MPL, indicate your decision
31707+** by deleting the provisions above and replace them with the notice
31708+** and other provisions required by the GPL. If you do not delete
31709+** the provisions above, a recipient may use your version of this
31710+** file under either the MPL or the GPL.
31711+** ---------------------------------------------------------------------
31712+** Inquiries regarding the ACX100 Open Source Project can be
31713+** made directly to:
31714+**
31715+** acx100-users@lists.sf.net
31716+** http://acx100.sf.net
31717+** ---------------------------------------------------------------------
31718+*/
31719+
31720+/***********************************************************************
31721+** This code is based on elements which are
31722+** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
31723+** info@linux-wlan.com
31724+** http://www.linux-wlan.com
31725+*/
31726+
31727+#include <linux/version.h>
31728+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
31729+#include <linux/config.h>
31730+#endif
31731+#include <linux/types.h>
31732+#include <linux/if_arp.h>
31733+#include <linux/wireless.h>
31734+#include <net/iw_handler.h>
31735+
31736+#include "acx.h"
31737+
31738+
31739+/***********************************************************************
31740+*/
31741+#define LOG_BAD_EID(hdr,len,ie_ptr) acx_log_bad_eid(hdr, len, ((wlan_ie_t*)ie_ptr))
31742+
31743+#define IE_EID(ie_ptr) (((wlan_ie_t*)(ie_ptr))->eid)
31744+#define IE_LEN(ie_ptr) (((wlan_ie_t*)(ie_ptr))->len)
31745+#define OFFSET(hdr,off) (WLAN_HDR_A3_DATAP(hdr) + (off))
31746+
31747+
31748+/***********************************************************************
31749+** wlan_mgmt_decode_XXX
31750+**
31751+** Given a complete frame in f->hdr, sets the pointers in f to
31752+** the areas that correspond to the parts of the frame.
31753+**
31754+** Assumptions:
31755+** 1) f->len and f->hdr are already set
31756+** 2) f->len is the length of the MAC header + data, the FCS
31757+** is NOT included
31758+** 3) all members except len and hdr are zero
31759+** Arguments:
31760+** f frame structure
31761+**
31762+** Returns:
31763+** nothing
31764+**
31765+** Side effects:
31766+** frame structure members are pointing at their
31767+** respective portions of the frame buffer.
31768+*/
31769+void
31770+wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f)
31771+{
31772+ u8 *ie_ptr;
31773+ u8 *end = (u8*)f->hdr + f->len;
31774+
31775+ f->type = WLAN_FSTYPE_BEACON;
31776+
31777+ /*-- Fixed Fields ----*/
31778+ f->ts = (u64 *) OFFSET(f->hdr, WLAN_BEACON_OFF_TS);
31779+ f->bcn_int = (u16 *) OFFSET(f->hdr, WLAN_BEACON_OFF_BCN_INT);
31780+ f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_BEACON_OFF_CAPINFO);
31781+
31782+ /*-- Information elements */
31783+ ie_ptr = OFFSET(f->hdr, WLAN_BEACON_OFF_SSID);
31784+ while (ie_ptr < end) {
31785+ switch (IE_EID(ie_ptr)) {
31786+ case WLAN_EID_SSID:
31787+ f->ssid = (wlan_ie_ssid_t *) ie_ptr;
31788+ break;
31789+ case WLAN_EID_SUPP_RATES:
31790+ f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
31791+ break;
31792+ case WLAN_EID_EXT_RATES:
31793+ f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
31794+ break;
31795+ case WLAN_EID_FH_PARMS:
31796+ f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr;
31797+ break;
31798+ case WLAN_EID_DS_PARMS:
31799+ f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr;
31800+ break;
31801+ case WLAN_EID_CF_PARMS:
31802+ f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr;
31803+ break;
31804+ case WLAN_EID_IBSS_PARMS:
31805+ f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr;
31806+ break;
31807+ case WLAN_EID_TIM:
31808+ f->tim = (wlan_ie_tim_t *) ie_ptr;
31809+ break;
31810+ case WLAN_EID_ERP_INFO:
31811+ f->erp = (wlan_ie_erp_t *) ie_ptr;
31812+ break;
31813+
31814+ case WLAN_EID_COUNTRY:
31815+ /* was seen: 07 06 47 42 20 01 0D 14 */
31816+ case WLAN_EID_PWR_CONSTRAINT:
31817+ /* was seen by Ashwin Mansinghka <ashwin_man@yahoo.com> from
31818+ Atheros-based PCI card in AP mode using madwifi drivers: */
31819+ /* 20 01 00 */
31820+ case WLAN_EID_NONERP:
31821+ /* was seen from WRT54GS with OpenWrt: 2F 01 07 */
31822+ case WLAN_EID_UNKNOWN128:
31823+ /* was seen by Jacek Jablonski <conexion2000@gmail.com> from Orinoco AP */
31824+ /* 80 06 00 60 1D 2C 3B 00 */
31825+ case WLAN_EID_UNKNOWN133:
31826+ /* was seen by David Bronaugh <dbronaugh@linuxboxen.org> from ???? */
31827+ /* 85 1E 00 00 84 12 07 00 FF 00 11 00 61 70 63 31 */
31828+ /* 63 73 72 30 34 32 00 00 00 00 00 00 00 00 00 25 */
31829+ case WLAN_EID_UNKNOWN223:
31830+ /* was seen by Carlos Martin <carlosmn@gmail.com> from ???? */
31831+ /* DF 20 01 1E 04 00 00 00 06 63 09 02 FF 0F 30 30 */
31832+ /* 30 42 36 42 33 34 30 39 46 31 00 00 00 00 00 00 00 00 */
31833+ case WLAN_EID_GENERIC:
31834+ /* WPA: hostap code:
31835+ if (pos[1] >= 4 &&
31836+ pos[2] == 0x00 && pos[3] == 0x50 &&
31837+ pos[4] == 0xf2 && pos[5] == 1) {
31838+ wpa = pos;
31839+ wpa_len = pos[1] + 2;
31840+ }
31841+ TI x4 mode: seen DD 04 08 00 28 00
31842+ (08 00 28 is TI's OUI)
31843+ last byte is probably 0/1 - disabled/enabled
31844+ */
31845+ case WLAN_EID_RSN:
31846+ /* hostap does something with it:
31847+ rsn = pos;
31848+ rsn_len = pos[1] + 2;
31849+ */
31850+ break;
31851+
31852+ default:
31853+ LOG_BAD_EID(f->hdr, f->len, ie_ptr);
31854+ break;
31855+ }
31856+ ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
31857+ }
31858+}
31859+
31860+
31861+#ifdef UNUSED
31862+void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t * f)
31863+{
31864+ f->type = WLAN_FSTYPE_ATIM;
31865+ /*-- Fixed Fields ----*/
31866+ /*-- Information elements */
31867+}
31868+#endif /* UNUSED */
31869+
31870+void
31871+wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f)
31872+{
31873+ f->type = WLAN_FSTYPE_DISASSOC;
31874+
31875+ /*-- Fixed Fields ----*/
31876+ f->reason = (u16 *) OFFSET(f->hdr, WLAN_DISASSOC_OFF_REASON);
31877+
31878+ /*-- Information elements */
31879+}
31880+
31881+
31882+void
31883+wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f)
31884+{
31885+ u8 *ie_ptr;
31886+ u8 *end = (u8*)f->hdr + f->len;
31887+
31888+
31889+ f->type = WLAN_FSTYPE_ASSOCREQ;
31890+
31891+ /*-- Fixed Fields ----*/
31892+ f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_CAP_INFO);
31893+ f->listen_int = (u16 *) OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_LISTEN_INT);
31894+
31895+ /*-- Information elements */
31896+ ie_ptr = OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_SSID);
31897+ while (ie_ptr < end) {
31898+ switch (IE_EID(ie_ptr)) {
31899+ case WLAN_EID_SSID:
31900+ f->ssid = (wlan_ie_ssid_t *) ie_ptr;
31901+ break;
31902+ case WLAN_EID_SUPP_RATES:
31903+ f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
31904+ break;
31905+ case WLAN_EID_EXT_RATES:
31906+ f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
31907+ break;
31908+ default:
31909+ LOG_BAD_EID(f->hdr, f->len, ie_ptr);
31910+ break;
31911+ }
31912+ ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
31913+ }
31914+}
31915+
31916+
31917+void
31918+wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f)
31919+{
31920+ f->type = WLAN_FSTYPE_ASSOCRESP;
31921+
31922+ /*-- Fixed Fields ----*/
31923+ f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_CAP_INFO);
31924+ f->status = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_STATUS);
31925+ f->aid = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_AID);
31926+
31927+ /*-- Information elements */
31928+ f->supp_rates = (wlan_ie_supp_rates_t *)
31929+ OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_SUPP_RATES);
31930+}
31931+
31932+
31933+#ifdef UNUSED
31934+void
31935+wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f)
31936+{
31937+ u8 *ie_ptr;
31938+ u8 *end = (u8*)f->hdr + f->len;
31939+
31940+ f->type = WLAN_FSTYPE_REASSOCREQ;
31941+
31942+ /*-- Fixed Fields ----*/
31943+ f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_CAP_INFO);
31944+ f->listen_int = (u16 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_LISTEN_INT);
31945+ f->curr_ap = (u8 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_CURR_AP);
31946+
31947+ /*-- Information elements */
31948+ ie_ptr = OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_SSID);
31949+ while (ie_ptr < end) {
31950+ switch (IE_EID(ie_ptr)) {
31951+ case WLAN_EID_SSID:
31952+ f->ssid = (wlan_ie_ssid_t *) ie_ptr;
31953+ break;
31954+ case WLAN_EID_SUPP_RATES:
31955+ f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
31956+ break;
31957+ case WLAN_EID_EXT_RATES:
31958+ f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
31959+ break;
31960+ default:
31961+ LOG_BAD_EID(f->hdr, f->len, ie_ptr);
31962+ break;
31963+ }
31964+ ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
31965+ }
31966+}
31967+
31968+
31969+void
31970+wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f)
31971+{
31972+ f->type = WLAN_FSTYPE_REASSOCRESP;
31973+
31974+ /*-- Fixed Fields ----*/
31975+ f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_CAP_INFO);
31976+ f->status = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_STATUS);
31977+ f->aid = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_AID);
31978+
31979+ /*-- Information elements */
31980+ f->supp_rates = (wlan_ie_supp_rates_t *)
31981+ OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_SUPP_RATES);
31982+}
31983+
31984+
31985+void
31986+wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f)
31987+{
31988+ u8 *ie_ptr;
31989+ u8 *end = (u8*)f->hdr + f->len;
31990+
31991+ f->type = WLAN_FSTYPE_PROBEREQ;
31992+
31993+ /*-- Fixed Fields ----*/
31994+
31995+ /*-- Information elements */
31996+ ie_ptr = OFFSET(f->hdr, WLAN_PROBEREQ_OFF_SSID);
31997+ while (ie_ptr < end) {
31998+ switch (IE_EID(ie_ptr)) {
31999+ case WLAN_EID_SSID:
32000+ f->ssid = (wlan_ie_ssid_t *) ie_ptr;
32001+ break;
32002+ case WLAN_EID_SUPP_RATES:
32003+ f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
32004+ break;
32005+ case WLAN_EID_EXT_RATES:
32006+ f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
32007+ break;
32008+ default:
32009+ LOG_BAD_EID(f->hdr, f->len, ie_ptr);
32010+ break;
32011+ }
32012+ ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
32013+ }
32014+}
32015+#endif /* UNUSED */
32016+
32017+
32018+/* TODO: decoding of beacon and proberesp can be merged (similar structure) */
32019+void
32020+wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f)
32021+{
32022+ u8 *ie_ptr;
32023+ u8 *end = (u8*)f->hdr + f->len;
32024+
32025+ f->type = WLAN_FSTYPE_PROBERESP;
32026+
32027+ /*-- Fixed Fields ----*/
32028+ f->ts = (u64 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_TS);
32029+ f->bcn_int = (u16 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_BCN_INT);
32030+ f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_CAP_INFO);
32031+
32032+ /*-- Information elements */
32033+ ie_ptr = OFFSET(f->hdr, WLAN_PROBERESP_OFF_SSID);
32034+ while (ie_ptr < end) {
32035+ switch (IE_EID(ie_ptr)) {
32036+ case WLAN_EID_SSID:
32037+ f->ssid = (wlan_ie_ssid_t *) ie_ptr;
32038+ break;
32039+ case WLAN_EID_SUPP_RATES:
32040+ f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
32041+ break;
32042+ case WLAN_EID_EXT_RATES:
32043+ f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
32044+ break;
32045+ case WLAN_EID_FH_PARMS:
32046+ f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr;
32047+ break;
32048+ case WLAN_EID_DS_PARMS:
32049+ f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr;
32050+ break;
32051+ case WLAN_EID_CF_PARMS:
32052+ f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr;
32053+ break;
32054+ case WLAN_EID_IBSS_PARMS:
32055+ f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr;
32056+ break;
32057+#ifdef DONT_DO_IT_ADD_REAL_HANDLING_INSTEAD
32058+ case WLAN_EID_COUNTRY:
32059+ break;
32060+ ...
32061+#endif
32062+#ifdef SENT_HERE_BY_OPENWRT
32063+ /* should those be trapped or handled?? */
32064+ case WLAN_EID_ERP_INFO:
32065+ break;
32066+ case WLAN_EID_NONERP:
32067+ break;
32068+ case WLAN_EID_GENERIC:
32069+ break;
32070+#endif
32071+ default:
32072+ LOG_BAD_EID(f->hdr, f->len, ie_ptr);
32073+ break;
32074+ }
32075+
32076+ ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
32077+ }
32078+}
32079+
32080+
32081+void
32082+wlan_mgmt_decode_authen(wlan_fr_authen_t * f)
32083+{
32084+ u8 *ie_ptr;
32085+ u8 *end = (u8*)f->hdr + f->len;
32086+
32087+ f->type = WLAN_FSTYPE_AUTHEN;
32088+
32089+ /*-- Fixed Fields ----*/
32090+ f->auth_alg = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_AUTH_ALG);
32091+ f->auth_seq = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_AUTH_SEQ);
32092+ f->status = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_STATUS);
32093+
32094+ /*-- Information elements */
32095+ ie_ptr = OFFSET(f->hdr, WLAN_AUTHEN_OFF_CHALLENGE);
32096+ if ((ie_ptr < end) && (IE_EID(ie_ptr) == WLAN_EID_CHALLENGE)) {
32097+ f->challenge = (wlan_ie_challenge_t *) ie_ptr;
32098+ }
32099+}
32100+
32101+
32102+void
32103+wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f)
32104+{
32105+ f->type = WLAN_FSTYPE_DEAUTHEN;
32106+
32107+ /*-- Fixed Fields ----*/
32108+ f->reason = (u16 *) OFFSET(f->hdr, WLAN_DEAUTHEN_OFF_REASON);
32109+
32110+ /*-- Information elements */
32111+}
32112Index: linux-2.6.22/drivers/net/wireless/acx/wlan_compat.h
32113===================================================================
32114--- /dev/null 1970-01-01 00:00:00.000000000 +0000
32115+++ linux-2.6.22/drivers/net/wireless/acx/wlan_compat.h 2007-08-23 18:34:19.000000000 +0200
32116@@ -0,0 +1,260 @@
32117+/***********************************************************************
32118+** Copyright (C) 2003 ACX100 Open Source Project
32119+**
32120+** The contents of this file are subject to the Mozilla Public
32121+** License Version 1.1 (the "License"); you may not use this file
32122+** except in compliance with the License. You may obtain a copy of
32123+** the License at http://www.mozilla.org/MPL/
32124+**
32125+** Software distributed under the License is distributed on an "AS
32126+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
32127+** implied. See the License for the specific language governing
32128+** rights and limitations under the License.
32129+**
32130+** Alternatively, the contents of this file may be used under the
32131+** terms of the GNU Public License version 2 (the "GPL"), in which
32132+** case the provisions of the GPL are applicable instead of the
32133+** above. If you wish to allow the use of your version of this file
32134+** only under the terms of the GPL and not to allow others to use
32135+** your version of this file under the MPL, indicate your decision
32136+** by deleting the provisions above and replace them with the notice
32137+** and other provisions required by the GPL. If you do not delete
32138+** the provisions above, a recipient may use your version of this
32139+** file under either the MPL or the GPL.
32140+** ---------------------------------------------------------------------
32141+** Inquiries regarding the ACX100 Open Source Project can be
32142+** made directly to:
32143+**
32144+** acx100-users@lists.sf.net
32145+** http://acx100.sf.net
32146+** ---------------------------------------------------------------------
32147+*/
32148+
32149+/***********************************************************************
32150+** This code is based on elements which are
32151+** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
32152+** info@linux-wlan.com
32153+** http://www.linux-wlan.com
32154+*/
32155+
32156+/*=============================================================*/
32157+/*------ Establish Platform Identity --------------------------*/
32158+/*=============================================================*/
32159+/* Key macros: */
32160+/* WLAN_CPU_FAMILY */
32161+#define WLAN_Ix86 1
32162+#define WLAN_PPC 2
32163+#define WLAN_Ix96 3
32164+#define WLAN_ARM 4
32165+#define WLAN_ALPHA 5
32166+#define WLAN_MIPS 6
32167+#define WLAN_HPPA 7
32168+#define WLAN_SPARC 8
32169+#define WLAN_SH 9
32170+#define WLAN_x86_64 10
32171+/* WLAN_CPU_CORE */
32172+#define WLAN_I386CORE 1
32173+#define WLAN_PPCCORE 2
32174+#define WLAN_I296 3
32175+#define WLAN_ARMCORE 4
32176+#define WLAN_ALPHACORE 5
32177+#define WLAN_MIPSCORE 6
32178+#define WLAN_HPPACORE 7
32179+/* WLAN_CPU_PART */
32180+#define WLAN_I386PART 1
32181+#define WLAN_MPC860 2
32182+#define WLAN_MPC823 3
32183+#define WLAN_I296SA 4
32184+#define WLAN_PPCPART 5
32185+#define WLAN_ARMPART 6
32186+#define WLAN_ALPHAPART 7
32187+#define WLAN_MIPSPART 8
32188+#define WLAN_HPPAPART 9
32189+/* WLAN_SYSARCH */
32190+#define WLAN_PCAT 1
32191+#define WLAN_MBX 2
32192+#define WLAN_RPX 3
32193+#define WLAN_LWARCH 4
32194+#define WLAN_PMAC 5
32195+#define WLAN_SKIFF 6
32196+#define WLAN_BITSY 7
32197+#define WLAN_ALPHAARCH 7
32198+#define WLAN_MIPSARCH 9
32199+#define WLAN_HPPAARCH 10
32200+/* WLAN_HOSTIF (generally set on the command line, not detected) */
32201+#define WLAN_PCMCIA 1
32202+#define WLAN_ISA 2
32203+#define WLAN_PCI 3
32204+#define WLAN_USB 4
32205+#define WLAN_PLX 5
32206+
32207+/* Note: the PLX HOSTIF above refers to some vendors implementations for */
32208+/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */
32209+/* isn't a real PCMCIA host interface adapter providing all the */
32210+/* card&socket services. */
32211+
32212+#ifdef __powerpc__
32213+#ifndef __ppc__
32214+#define __ppc__
32215+#endif
32216+#endif
32217+
32218+#if (defined(CONFIG_PPC) || defined(CONFIG_8xx))
32219+#ifndef __ppc__
32220+#define __ppc__
32221+#endif
32222+#endif
32223+
32224+#if defined(__x86_64__)
32225+ #define WLAN_CPU_FAMILY WLAN_x86_64
32226+ #define WLAN_SYSARCH WLAN_PCAT
32227+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
32228+ #define WLAN_CPU_FAMILY WLAN_Ix86
32229+ #define WLAN_CPU_CORE WLAN_I386CORE
32230+ #define WLAN_CPU_PART WLAN_I386PART
32231+ #define WLAN_SYSARCH WLAN_PCAT
32232+#elif defined(__ppc__)
32233+ #define WLAN_CPU_FAMILY WLAN_PPC
32234+ #define WLAN_CPU_CORE WLAN_PPCCORE
32235+ #if defined(CONFIG_MBX)
32236+ #define WLAN_CPU_PART WLAN_MPC860
32237+ #define WLAN_SYSARCH WLAN_MBX
32238+ #elif defined(CONFIG_RPXLITE)
32239+ #define WLAN_CPU_PART WLAN_MPC823
32240+ #define WLAN_SYSARCH WLAN_RPX
32241+ #elif defined(CONFIG_RPXCLASSIC)
32242+ #define WLAN_CPU_PART WLAN_MPC860
32243+ #define WLAN_SYSARCH WLAN_RPX
32244+ #else
32245+ #define WLAN_CPU_PART WLAN_PPCPART
32246+ #define WLAN_SYSARCH WLAN_PMAC
32247+ #endif
32248+#elif defined(__arm__)
32249+ #define WLAN_CPU_FAMILY WLAN_ARM
32250+ #define WLAN_CPU_CORE WLAN_ARMCORE
32251+ #define WLAN_CPU_PART WLAN_ARM_PART
32252+ #define WLAN_SYSARCH WLAN_SKIFF
32253+#elif defined(__alpha__)
32254+ #define WLAN_CPU_FAMILY WLAN_ALPHA
32255+ #define WLAN_CPU_CORE WLAN_ALPHACORE
32256+ #define WLAN_CPU_PART WLAN_ALPHAPART
32257+ #define WLAN_SYSARCH WLAN_ALPHAARCH
32258+#elif defined(__mips__)
32259+ #define WLAN_CPU_FAMILY WLAN_MIPS
32260+ #define WLAN_CPU_CORE WLAN_MIPSCORE
32261+ #define WLAN_CPU_PART WLAN_MIPSPART
32262+ #define WLAN_SYSARCH WLAN_MIPSARCH
32263+#elif defined(__hppa__)
32264+ #define WLAN_CPU_FAMILY WLAN_HPPA
32265+ #define WLAN_CPU_CORE WLAN_HPPACORE
32266+ #define WLAN_CPU_PART WLAN_HPPAPART
32267+ #define WLAN_SYSARCH WLAN_HPPAARCH
32268+#elif defined(__sparc__)
32269+ #define WLAN_CPU_FAMILY WLAN_SPARC
32270+ #define WLAN_SYSARCH WLAN_SPARC
32271+#elif defined(__sh__)
32272+ #define WLAN_CPU_FAMILY WLAN_SH
32273+ #define WLAN_SYSARCH WLAN_SHARCH
32274+ #ifndef __LITTLE_ENDIAN__
32275+ #define __LITTLE_ENDIAN__
32276+ #endif
32277+#else
32278+ #error "No CPU identified!"
32279+#endif
32280+
32281+/*
32282+ Some big endian machines implicitly do all I/O in little endian mode.
32283+
32284+ In particular:
32285+ Linux/PPC on PowerMacs (PCI)
32286+ Arm/Intel Xscale (PCI)
32287+
32288+ This may also affect PLX boards and other BE &| PPC platforms;
32289+ as new ones are discovered, add them below.
32290+*/
32291+
32292+#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC))
32293+#define REVERSE_ENDIAN
32294+#endif
32295+
32296+/*=============================================================*/
32297+/*------ Hardware Portability Macros --------------------------*/
32298+/*=============================================================*/
32299+#if (WLAN_CPU_FAMILY == WLAN_PPC)
32300+#define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE))
32301+#define wlan_inw_le16_to_cpu(a) inw((a))
32302+#define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v))
32303+#define wlan_outw_cpu_to_le16(v,a) outw((v),(a))
32304+#else
32305+#define wlan_inw(a) inw((a))
32306+#define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a)))
32307+#define wlan_outw(v,a) outw((v),(a))
32308+#define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a))
32309+#endif
32310+
32311+/*=============================================================*/
32312+/*------ Bit settings -----------------------------------------*/
32313+/*=============================================================*/
32314+#define ieee2host16(n) __le16_to_cpu(n)
32315+#define ieee2host32(n) __le32_to_cpu(n)
32316+#define host2ieee16(n) __cpu_to_le16(n)
32317+#define host2ieee32(n) __cpu_to_le32(n)
32318+
32319+/* for constants */
32320+#ifdef __LITTLE_ENDIAN
32321+ #define IEEE16(a,n) a = n, a##i = n,
32322+#else
32323+ #ifdef __BIG_ENDIAN
32324+ /* shifts would produce gcc warnings. Oh well... */
32325+ #define IEEE16(a,n) a = n, a##i = ((n&0xff)*256 + ((n&0xff00)/256)),
32326+ #else
32327+ #error give me endianness or give me death
32328+ #endif
32329+#endif
32330+
32331+/*=============================================================*/
32332+/*------ Compiler Portability Macros --------------------------*/
32333+/*=============================================================*/
32334+#define WLAN_PACKED __attribute__ ((packed))
32335+
32336+/* Interrupt handler backwards compatibility stuff */
32337+#ifndef IRQ_NONE
32338+#define IRQ_NONE
32339+#define IRQ_HANDLED
32340+typedef void irqreturn_t;
32341+#endif
32342+
32343+#ifndef ARPHRD_IEEE80211_PRISM
32344+#define ARPHRD_IEEE80211_PRISM 802
32345+#endif
32346+
32347+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
32348+
32349+/*============================================================================*
32350+ * Constants *
32351+ *============================================================================*/
32352+#define WLAN_IEEE_OUI_LEN 3
32353+
32354+/*============================================================================*
32355+ * Types *
32356+ *============================================================================*/
32357+
32358+/* local ether header type */
32359+typedef struct wlan_ethhdr {
32360+ u8 daddr[ETH_ALEN];
32361+ u8 saddr[ETH_ALEN];
32362+ u16 type;
32363+} WLAN_PACKED wlan_ethhdr_t;
32364+
32365+/* local llc header type */
32366+typedef struct wlan_llc {
32367+ u8 dsap;
32368+ u8 ssap;
32369+ u8 ctl;
32370+} WLAN_PACKED wlan_llc_t;
32371+
32372+/* local snap header type */
32373+typedef struct wlan_snap {
32374+ u8 oui[WLAN_IEEE_OUI_LEN];
32375+ u16 type;
32376+} WLAN_PACKED wlan_snap_t;
32377Index: linux-2.6.22/drivers/net/wireless/acx/wlan_hdr.h
32378===================================================================
32379--- /dev/null 1970-01-01 00:00:00.000000000 +0000
32380+++ linux-2.6.22/drivers/net/wireless/acx/wlan_hdr.h 2007-08-23 18:34:19.000000000 +0200
32381@@ -0,0 +1,497 @@
32382+/***********************************************************************
32383+** Copyright (C) 2003 ACX100 Open Source Project
32384+**
32385+** The contents of this file are subject to the Mozilla Public
32386+** License Version 1.1 (the "License"); you may not use this file
32387+** except in compliance with the License. You may obtain a copy of
32388+** the License at http://www.mozilla.org/MPL/
32389+**
32390+** Software distributed under the License is distributed on an "AS
32391+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
32392+** implied. See the License for the specific language governing
32393+** rights and limitations under the License.
32394+**
32395+** Alternatively, the contents of this file may be used under the
32396+** terms of the GNU Public License version 2 (the "GPL"), in which
32397+** case the provisions of the GPL are applicable instead of the
32398+** above. If you wish to allow the use of your version of this file
32399+** only under the terms of the GPL and not to allow others to use
32400+** your version of this file under the MPL, indicate your decision
32401+** by deleting the provisions above and replace them with the notice
32402+** and other provisions required by the GPL. If you do not delete
32403+** the provisions above, a recipient may use your version of this
32404+** file under either the MPL or the GPL.
32405+** ---------------------------------------------------------------------
32406+** Inquiries regarding the ACX100 Open Source Project can be
32407+** made directly to:
32408+**
32409+** acx100-users@lists.sf.net
32410+** http://acx100.sf.net
32411+** ---------------------------------------------------------------------
32412+*/
32413+
32414+/***********************************************************************
32415+** This code is based on elements which are
32416+** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
32417+** info@linux-wlan.com
32418+** http://www.linux-wlan.com
32419+*/
32420+
32421+/* mini-doc
32422+
32423+Here are all 11b/11g/11a rates and modulations:
32424+
32425+ 11b 11g 11a
32426+ --- --- ---
32427+ 1 |B |B |
32428+ 2 |Q |Q |
32429+ 5.5|Cp |C p|
32430+ 6 | |Od |O
32431+ 9 | |od |o
32432+11 |Cp |C p|
32433+12 | |Od |O
32434+18 | |od |o
32435+22 | | p|
32436+24 | |Od |O
32437+33 | | p|
32438+36 | |od |o
32439+48 | |od |o
32440+54 | |od |o
32441+
32442+Mandatory:
32443+ B - DBPSK (Differential Binary Phase Shift Keying)
32444+ Q - DQPSK (Differential Quaternary Phase Shift Keying)
32445+ C - CCK (Complementary Code Keying, a form of DSSS
32446+ (Direct Sequence Spread Spectrum) modulation)
32447+ O - OFDM (Orthogonal Frequency Division Multiplexing)
32448+Optional:
32449+ o - OFDM
32450+ d - CCK-OFDM (also known as DSSS-OFDM)
32451+ p - PBCC (Packet Binary Convolutional Coding)
32452+
32453+The term CCK-OFDM may be used interchangeably with DSSS-OFDM
32454+(the IEEE 802.11g-2003 standard uses the latter terminology).
32455+In the CCK-OFDM, the PLCP header of the frame uses the CCK form of DSSS,
32456+while the PLCP payload (the MAC frame) is modulated using OFDM.
32457+
32458+Basically, you must use CCK-OFDM if you have mixed 11b/11g environment,
32459+or else (pure OFDM) 11b equipment may not realize that AP
32460+is sending a packet and start sending its own one.
32461+Sadly, looks like acx111 does not support CCK-OFDM, only pure OFDM.
32462+
32463+Re PBCC: avoid using it. It makes sense only if you have
32464+TI "11b+" hardware. You _must_ use PBCC in order to reach 22Mbps on it.
32465+
32466+Preambles:
32467+
32468+Long preamble (at 1Mbit rate, takes 144 us):
32469+ 16 bytes ones
32470+ 2 bytes 0xF3A0 (lsb sent first)
32471+PLCP header follows (at 1Mbit also):
32472+ 1 byte Signal: speed, in 0.1Mbit units, except for:
32473+ 33Mbit: 33 (instead of 330 - doesn't fit in octet)
32474+ all CCK-OFDM rates: 30
32475+ 1 byte Service
32476+ 0,1,4: reserved
32477+ 2: 1=locked clock
32478+ 3: 1=PBCC
32479+ 5: Length Extension (PBCC 22,33Mbit (11g only)) <-
32480+ 6: Length Extension (PBCC 22,33Mbit (11g only)) <- BLACK MAGIC HERE
32481+ 7: Length Extension <-
32482+ 2 bytes Length (time needed to tx this frame)
32483+ a) 5.5 Mbit/s CCK
32484+ Length = octets*8/5.5, rounded up to integer
32485+ b) 11 Mbit/s CCK
32486+ Length = octets*8/11, rounded up to integer
32487+ Service bit 7:
32488+ 0 = rounding took less than 8/11
32489+ 1 = rounding took more than or equal to 8/11
32490+ c) 5.5 Mbit/s PBCC
32491+ Length = (octets+1)*8/5.5, rounded up to integer
32492+ d) 11 Mbit/s PBCC
32493+ Length = (octets+1)*8/11, rounded up to integer
32494+ Service bit 7:
32495+ 0 = rounding took less than 8/11
32496+ 1 = rounding took more than or equal to 8/11
32497+ e) 22 Mbit/s PBCC
32498+ Length = (octets+1)*8/22, rounded up to integer
32499+ Service bits 6,7:
32500+ 00 = rounding took less than 8/22ths
32501+ 01 = rounding took 8/22...15/22ths
32502+ 10 = rounding took 16/22ths or more.
32503+ f) 33 Mbit/s PBCC
32504+ Length = (octets+1)*8/33, rounded up to integer
32505+ Service bits 5,6,7:
32506+ 000 rounding took less than 8/33
32507+ 001 rounding took 8/33...15/33
32508+ 010 rounding took 16/33...23/33
32509+ 011 rounding took 24/33...31/33
32510+ 100 rounding took 32/33 or more
32511+ 2 bytes CRC
32512+
32513+PSDU follows (up to 2346 bytes at selected rate)
32514+
32515+While Signal value alone is not enough to determine rate and modulation,
32516+Signal+Service is always sufficient.
32517+
32518+Short preamble (at 1Mbit rate, takes 72 us):
32519+ 7 bytes zeroes
32520+ 2 bytes 0x05CF (lsb sent first)
32521+PLCP header follows *at 2Mbit/s*. Format is the same as in long preamble.
32522+PSDU follows (up to 2346 bytes at selected rate)
32523+
32524+OFDM preamble is completely different, uses OFDM
32525+modulation from the start and thus easily identifiable.
32526+Not shown here.
32527+*/
32528+
32529+
32530+/***********************************************************************
32531+** Constants
32532+*/
32533+
32534+#define WLAN_HDR_A3_LEN 24
32535+#define WLAN_HDR_A4_LEN 30
32536+/* IV structure:
32537+** 3 bytes: Initialization Vector (24 bits)
32538+** 1 byte: 0..5: padding, must be 0; 6..7: key selector (0-3)
32539+*/
32540+#define WLAN_WEP_IV_LEN 4
32541+/* 802.11 says 2312 but looks like 2312 is a max size of _WEPed data_ */
32542+#define WLAN_DATA_MAXLEN 2304
32543+#define WLAN_WEP_ICV_LEN 4
32544+#define WLAN_FCS_LEN 4
32545+#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN)
32546+#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN)
32547+#define WLAN_A3FR_MAXLEN_FCS (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + 4)
32548+#define WLAN_A4FR_MAXLEN_FCS (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + 4)
32549+#define WLAN_A3FR_MAXLEN_WEP (WLAN_A3FR_MAXLEN + 8)
32550+#define WLAN_A4FR_MAXLEN_WEP (WLAN_A4FR_MAXLEN + 8)
32551+#define WLAN_A3FR_MAXLEN_WEP_FCS (WLAN_A3FR_MAXLEN_FCS + 8)
32552+#define WLAN_A4FR_MAXLEN_WEP_FCS (WLAN_A4FR_MAXLEN_FCS + 8)
32553+
32554+#define WLAN_BSS_TS_LEN 8
32555+#define WLAN_SSID_MAXLEN 32
32556+#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334)
32557+#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0)
32558+#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
32559+#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48)
32560+#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
32561+#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54)
32562+#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
32563+#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44)
32564+#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78)
32565+#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261)
32566+#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
32567+#define WLAN_CHALLENGE_IE_LEN 130
32568+#define WLAN_CHALLENGE_LEN 128
32569+#define WLAN_WEP_MAXKEYLEN 13
32570+#define WLAN_WEP_NKEYS 4
32571+
32572+/*--- Frame Control Field -------------------------------------*/
32573+/* Frame Types */
32574+#define WLAN_FTYPE_MGMT 0x00
32575+#define WLAN_FTYPE_CTL 0x01
32576+#define WLAN_FTYPE_DATA 0x02
32577+
32578+/* Frame subtypes */
32579+/* Management */
32580+#define WLAN_FSTYPE_ASSOCREQ 0x00
32581+#define WLAN_FSTYPE_ASSOCRESP 0x01
32582+#define WLAN_FSTYPE_REASSOCREQ 0x02
32583+#define WLAN_FSTYPE_REASSOCRESP 0x03
32584+#define WLAN_FSTYPE_PROBEREQ 0x04
32585+#define WLAN_FSTYPE_PROBERESP 0x05
32586+#define WLAN_FSTYPE_BEACON 0x08
32587+#define WLAN_FSTYPE_ATIM 0x09
32588+#define WLAN_FSTYPE_DISASSOC 0x0a
32589+#define WLAN_FSTYPE_AUTHEN 0x0b
32590+#define WLAN_FSTYPE_DEAUTHEN 0x0c
32591+
32592+/* Control */
32593+#define WLAN_FSTYPE_PSPOLL 0x0a
32594+#define WLAN_FSTYPE_RTS 0x0b
32595+#define WLAN_FSTYPE_CTS 0x0c
32596+#define WLAN_FSTYPE_ACK 0x0d
32597+#define WLAN_FSTYPE_CFEND 0x0e
32598+#define WLAN_FSTYPE_CFENDCFACK 0x0f
32599+
32600+/* Data */
32601+#define WLAN_FSTYPE_DATAONLY 0x00
32602+#define WLAN_FSTYPE_DATA_CFACK 0x01
32603+#define WLAN_FSTYPE_DATA_CFPOLL 0x02
32604+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03
32605+#define WLAN_FSTYPE_NULL 0x04
32606+#define WLAN_FSTYPE_CFACK 0x05
32607+#define WLAN_FSTYPE_CFPOLL 0x06
32608+#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
32609+
32610+/*--- FC Constants v. 2.0 ------------------------------------*/
32611+/* Each constant is defined twice: WF_CONST is in host */
32612+/* byteorder, WF_CONSTi is in ieee byteorder. */
32613+/* Usage: */
32614+/* printf("the frame subtype is %X", WF_FC_FTYPEi & rx.fc); */
32615+/* tx.fc = WF_FTYPE_CTLi | WF_FSTYPE_RTSi; */
32616+/*------------------------------------------------------------*/
32617+
32618+enum {
32619+/*--- Frame Control Field -------------------------------------*/
32620+/* Protocol version: always 0 for current 802.11 standards */
32621+IEEE16(WF_FC_PVER, 0x0003)
32622+IEEE16(WF_FC_FTYPE, 0x000c)
32623+IEEE16(WF_FC_FSTYPE, 0x00f0)
32624+IEEE16(WF_FC_TODS, 0x0100)
32625+IEEE16(WF_FC_FROMDS, 0x0200)
32626+IEEE16(WF_FC_FROMTODS, 0x0300)
32627+IEEE16(WF_FC_MOREFRAG, 0x0400)
32628+IEEE16(WF_FC_RETRY, 0x0800)
32629+/* Indicates PS mode in which STA will be after successful completion
32630+** of current frame exchange sequence. Always 0 for AP frames */
32631+IEEE16(WF_FC_PWRMGT, 0x1000)
32632+/* What MoreData=1 means:
32633+** From AP to STA in PS mode: don't sleep yet, I have more frames for you
32634+** From Contention-Free (CF) Pollable STA in response to a CF-Poll:
32635+** STA has buffered frames for transmission in response to next CF-Poll
32636+** Bcast/mcast frames transmitted from AP:
32637+** when additional bcast/mcast frames remain to be transmitted by AP
32638+** during this beacon interval
32639+** In all other cases MoreData=0 */
32640+IEEE16(WF_FC_MOREDATA, 0x2000)
32641+IEEE16(WF_FC_ISWEP, 0x4000)
32642+IEEE16(WF_FC_ORDER, 0x8000)
32643+
32644+/* Frame Types */
32645+IEEE16(WF_FTYPE_MGMT, 0x00)
32646+IEEE16(WF_FTYPE_CTL, 0x04)
32647+IEEE16(WF_FTYPE_DATA, 0x08)
32648+
32649+/* Frame subtypes */
32650+/* Management */
32651+IEEE16(WF_FSTYPE_ASSOCREQ, 0x00)
32652+IEEE16(WF_FSTYPE_ASSOCRESP, 0x10)
32653+IEEE16(WF_FSTYPE_REASSOCREQ, 0x20)
32654+IEEE16(WF_FSTYPE_REASSOCRESP, 0x30)
32655+IEEE16(WF_FSTYPE_PROBEREQ, 0x40)
32656+IEEE16(WF_FSTYPE_PROBERESP, 0x50)
32657+IEEE16(WF_FSTYPE_BEACON, 0x80)
32658+IEEE16(WF_FSTYPE_ATIM, 0x90)
32659+IEEE16(WF_FSTYPE_DISASSOC, 0xa0)
32660+IEEE16(WF_FSTYPE_AUTHEN, 0xb0)
32661+IEEE16(WF_FSTYPE_DEAUTHEN, 0xc0)
32662+
32663+/* Control */
32664+IEEE16(WF_FSTYPE_PSPOLL, 0xa0)
32665+IEEE16(WF_FSTYPE_RTS, 0xb0)
32666+IEEE16(WF_FSTYPE_CTS, 0xc0)
32667+IEEE16(WF_FSTYPE_ACK, 0xd0)
32668+IEEE16(WF_FSTYPE_CFEND, 0xe0)
32669+IEEE16(WF_FSTYPE_CFENDCFACK, 0xf0)
32670+
32671+/* Data */
32672+IEEE16(WF_FSTYPE_DATAONLY, 0x00)
32673+IEEE16(WF_FSTYPE_DATA_CFACK, 0x10)
32674+IEEE16(WF_FSTYPE_DATA_CFPOLL, 0x20)
32675+IEEE16(WF_FSTYPE_DATA_CFACK_CFPOLL, 0x30)
32676+IEEE16(WF_FSTYPE_NULL, 0x40)
32677+IEEE16(WF_FSTYPE_CFACK, 0x50)
32678+IEEE16(WF_FSTYPE_CFPOLL, 0x60)
32679+IEEE16(WF_FSTYPE_CFACK_CFPOLL, 0x70)
32680+};
32681+
32682+
32683+/***********************************************************************
32684+** Macros
32685+*/
32686+
32687+/*--- Duration Macros ----------------------------------------*/
32688+/* Macros to get/set the bitfields of the Duration Field */
32689+/* - the duration value is only valid when bit15 is zero */
32690+/* - the firmware handles these values, so I'm not going */
32691+/* to use these macros right now. */
32692+/*------------------------------------------------------------*/
32693+
32694+/*--- Sequence Control Macros -------------------------------*/
32695+/* Macros to get/set the bitfields of the Sequence Control */
32696+/* Field. */
32697+/*------------------------------------------------------------*/
32698+#define WLAN_GET_SEQ_FRGNUM(n) ((u16)(n) & 0x000f)
32699+#define WLAN_GET_SEQ_SEQNUM(n) (((u16)(n) & 0xfff0) >> 4)
32700+
32701+/*--- Data ptr macro -----------------------------------------*/
32702+/* Creates a u8* to the data portion of a frame */
32703+/* Assumes you're passing in a ptr to the beginning of the hdr*/
32704+/*------------------------------------------------------------*/
32705+#define WLAN_HDR_A3_DATAP(p) (((u8*)(p)) + WLAN_HDR_A3_LEN)
32706+#define WLAN_HDR_A4_DATAP(p) (((u8*)(p)) + WLAN_HDR_A4_LEN)
32707+
32708+
32709+/***********************************************************************
32710+** Types
32711+*/
32712+
32713+/* 802.11 header type
32714+**
32715+** Note the following:
32716+** a1 *always* is receiver's mac or bcast/mcast
32717+** a2 *always* is transmitter's mac, if a2 exists
32718+** seq: [0:3] frag#, [4:15] seq# - used for dup detection
32719+** (dups from retries have same seq#) */
32720+typedef struct wlan_hdr {
32721+ u16 fc;
32722+ u16 dur;
32723+ u8 a1[ETH_ALEN];
32724+ u8 a2[ETH_ALEN];
32725+ u8 a3[ETH_ALEN];
32726+ u16 seq;
32727+ u8 a4[ETH_ALEN];
32728+} WLAN_PACKED wlan_hdr_t;
32729+
32730+/* Separate structs for use if frame type is known */
32731+typedef struct wlan_hdr_a3 {
32732+ u16 fc;
32733+ u16 dur;
32734+ u8 a1[ETH_ALEN];
32735+ u8 a2[ETH_ALEN];
32736+ u8 a3[ETH_ALEN];
32737+ u16 seq;
32738+} WLAN_PACKED wlan_hdr_a3_t;
32739+
32740+typedef struct wlan_hdr_mgmt {
32741+ u16 fc;
32742+ u16 dur;
32743+ u8 da[ETH_ALEN];
32744+ u8 sa[ETH_ALEN];
32745+ u8 bssid[ETH_ALEN];
32746+ u16 seq;
32747+} WLAN_PACKED wlan_hdr_mgmt_t;
32748+
32749+#ifdef NOT_NEEDED_YET
32750+typedef struct { /* ad-hoc peer->peer (to/from DS = 0/0) */
32751+ u16 fc;
32752+ u16 dur;
32753+ u8 da[ETH_ALEN];
32754+ u8 sa[ETH_ALEN];
32755+ u8 bssid[ETH_ALEN];
32756+ u16 seq;
32757+} WLAN_PACKED ibss;
32758+typedef struct { /* ap->sta (to/from DS = 0/1) */
32759+ u16 fc;
32760+ u16 dur;
32761+ u8 da[ETH_ALEN];
32762+ u8 bssid[ETH_ALEN];
32763+ u8 sa[ETH_ALEN];
32764+ u16 seq;
32765+} WLAN_PACKED fromap;
32766+typedef struct { /* sta->ap (to/from DS = 1/0) */
32767+ u16 fc;
32768+ u16 dur;
32769+ u8 bssid[ETH_ALEN];
32770+ u8 sa[ETH_ALEN];
32771+ u8 da[ETH_ALEN];
32772+ u16 seq;
32773+} WLAN_PACKED toap;
32774+typedef struct { /* wds->wds (to/from DS = 1/1), the only 4addr pkt */
32775+ u16 fc;
32776+ u16 dur;
32777+ u8 ra[ETH_ALEN];
32778+ u8 ta[ETH_ALEN];
32779+ u8 da[ETH_ALEN];
32780+ u16 seq;
32781+ u8 sa[ETH_ALEN];
32782+} WLAN_PACKED wds;
32783+typedef struct { /* all management packets */
32784+ u16 fc;
32785+ u16 dur;
32786+ u8 da[ETH_ALEN];
32787+ u8 sa[ETH_ALEN];
32788+ u8 bssid[ETH_ALEN];
32789+ u16 seq;
32790+} WLAN_PACKED mgmt;
32791+typedef struct { /* has no body, just a FCS */
32792+ u16 fc;
32793+ u16 dur;
32794+ u8 ra[ETH_ALEN];
32795+ u8 ta[ETH_ALEN];
32796+} WLAN_PACKED rts;
32797+typedef struct { /* has no body, just a FCS */
32798+ u16 fc;
32799+ u16 dur;
32800+ u8 ra[ETH_ALEN];
32801+} WLAN_PACKED cts;
32802+typedef struct { /* has no body, just a FCS */
32803+ u16 fc;
32804+ u16 dur;
32805+ u8 ra[ETH_ALEN];
32806+} WLAN_PACKED ack;
32807+typedef struct { /* has no body, just a FCS */
32808+ u16 fc;
32809+ /* NB: this one holds Assoc ID in dur field: */
32810+ u16 aid;
32811+ u8 bssid[ETH_ALEN];
32812+ u8 ta[ETH_ALEN];
32813+} WLAN_PACKED pspoll;
32814+typedef struct { /* has no body, just a FCS */
32815+ u16 fc;
32816+ u16 dur;
32817+ u8 ra[ETH_ALEN];
32818+ u8 bssid[ETH_ALEN];
32819+} WLAN_PACKED cfend;
32820+typedef struct { /* has no body, just a FCS */
32821+ u16 fc;
32822+ u16 dur;
32823+ u8 ra[ETH_ALEN];
32824+ u8 bssid[ETH_ALEN];
32825+} WLAN_PACKED cfendcfack;
32826+#endif
32827+
32828+/* Prism header emulation (monitor mode) */
32829+typedef struct wlanitem_u32 {
32830+ u32 did;
32831+ u16 status;
32832+ u16 len;
32833+ u32 data;
32834+} WLAN_PACKED wlanitem_u32_t;
32835+#define WLANITEM_STATUS_data_ok 0
32836+#define WLANITEM_STATUS_no_value 1
32837+#define WLANITEM_STATUS_invalid_itemname 2
32838+#define WLANITEM_STATUS_invalid_itemdata 3
32839+#define WLANITEM_STATUS_missing_itemdata 4
32840+#define WLANITEM_STATUS_incomplete_itemdata 5
32841+#define WLANITEM_STATUS_invalid_msg_did 6
32842+#define WLANITEM_STATUS_invalid_mib_did 7
32843+#define WLANITEM_STATUS_missing_conv_func 8
32844+#define WLANITEM_STATUS_string_too_long 9
32845+#define WLANITEM_STATUS_data_out_of_range 10
32846+#define WLANITEM_STATUS_string_too_short 11
32847+#define WLANITEM_STATUS_missing_valid_func 12
32848+#define WLANITEM_STATUS_unknown 13
32849+#define WLANITEM_STATUS_invalid_did 14
32850+#define WLANITEM_STATUS_missing_print_func 15
32851+
32852+#define WLAN_DEVNAMELEN_MAX 16
32853+typedef struct wlansniffrm {
32854+ u32 msgcode;
32855+ u32 msglen;
32856+ u8 devname[WLAN_DEVNAMELEN_MAX];
32857+ wlanitem_u32_t hosttime;
32858+ wlanitem_u32_t mactime;
32859+ wlanitem_u32_t channel;
32860+ wlanitem_u32_t rssi;
32861+ wlanitem_u32_t sq;
32862+ wlanitem_u32_t signal;
32863+ wlanitem_u32_t noise;
32864+ wlanitem_u32_t rate;
32865+ wlanitem_u32_t istx; /* tx? 0:no 1:yes */
32866+ wlanitem_u32_t frmlen;
32867+} WLAN_PACKED wlansniffrm_t;
32868+#define WLANSNIFFFRM 0x0041
32869+#define WLANSNIFFFRM_hosttime 0x1041
32870+#define WLANSNIFFFRM_mactime 0x2041
32871+#define WLANSNIFFFRM_channel 0x3041
32872+#define WLANSNIFFFRM_rssi 0x4041
32873+#define WLANSNIFFFRM_sq 0x5041
32874+#define WLANSNIFFFRM_signal 0x6041
32875+#define WLANSNIFFFRM_noise 0x7041
32876+#define WLANSNIFFFRM_rate 0x8041
32877+#define WLANSNIFFFRM_istx 0x9041
32878+#define WLANSNIFFFRM_frmlen 0xA041
32879Index: linux-2.6.22/drivers/net/wireless/acx/wlan_mgmt.h
32880===================================================================
32881--- /dev/null 1970-01-01 00:00:00.000000000 +0000
32882+++ linux-2.6.22/drivers/net/wireless/acx/wlan_mgmt.h 2007-08-23 18:34:19.000000000 +0200
32883@@ -0,0 +1,582 @@
32884+/***********************************************************************
32885+** Copyright (C) 2003 ACX100 Open Source Project
32886+**
32887+** The contents of this file are subject to the Mozilla Public
32888+** License Version 1.1 (the "License"); you may not use this file
32889+** except in compliance with the License. You may obtain a copy of
32890+** the License at http://www.mozilla.org/MPL/
32891+**
32892+** Software distributed under the License is distributed on an "AS
32893+** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
32894+** implied. See the License for the specific language governing
32895+** rights and limitations under the License.
32896+**
32897+** Alternatively, the contents of this file may be used under the
32898+** terms of the GNU Public License version 2 (the "GPL"), in which
32899+** case the provisions of the GPL are applicable instead of the
32900+** above. If you wish to allow the use of your version of this file
32901+** only under the terms of the GPL and not to allow others to use
32902+** your version of this file under the MPL, indicate your decision
32903+** by deleting the provisions above and replace them with the notice
32904+** and other provisions required by the GPL. If you do not delete
32905+** the provisions above, a recipient may use your version of this
32906+** file under either the MPL or the GPL.
32907+** ---------------------------------------------------------------------
32908+** Inquiries regarding the ACX100 Open Source Project can be
32909+** made directly to:
32910+**
32911+** acx100-users@lists.sf.net
32912+** http://acx100.sf.net
32913+** ---------------------------------------------------------------------
32914+*/
32915+
32916+/***********************************************************************
32917+** This code is based on elements which are
32918+** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
32919+** info@linux-wlan.com
32920+** http://www.linux-wlan.com
32921+*/
32922+
32923+/***********************************************************************
32924+** Constants
32925+*/
32926+
32927+/*-- Information Element IDs --------------------*/
32928+#define WLAN_EID_SSID 0
32929+#define WLAN_EID_SUPP_RATES 1
32930+#define WLAN_EID_FH_PARMS 2
32931+#define WLAN_EID_DS_PARMS 3
32932+#define WLAN_EID_CF_PARMS 4
32933+#define WLAN_EID_TIM 5
32934+#define WLAN_EID_IBSS_PARMS 6
32935+#define WLAN_EID_COUNTRY 7 /* 802.11d */
32936+#define WLAN_EID_FH_HOP_PARMS 8 /* 802.11d */
32937+#define WLAN_EID_FH_TABLE 9 /* 802.11d */
32938+#define WLAN_EID_REQUEST 10 /* 802.11d */
32939+/*-- values 11-15 reserved --*/
32940+#define WLAN_EID_CHALLENGE 16
32941+/*-- values 17-31 reserved for challenge text extension --*/
32942+#define WLAN_EID_PWR_CONSTRAINT 32 /* 11h PowerConstraint */
32943+#define WLAN_EID_ERP_INFO 42 /* was seen from WRT54GS with OpenWrt */
32944+#define WLAN_EID_NONERP 47 /* was seen from WRT54GS with OpenWrt */
32945+#define WLAN_EID_RSN 48
32946+#define WLAN_EID_EXT_RATES 50
32947+#define WLAN_EID_UNKNOWN128 128
32948+#define WLAN_EID_UNKNOWN133 133
32949+#define WLAN_EID_GENERIC 221 /* was seen from WRT54GS with OpenWrt */
32950+#define WLAN_EID_UNKNOWN223 223
32951+
32952+#if 0
32953+#define WLAN_EID_PWR_CAP 33 /* 11h PowerCapability */
32954+#define WLAN_EID_TPC_REQUEST 34 /* 11h TPC Request */
32955+#define WLAN_EID_TPC_REPORT 35 /* 11h TPC Report */
32956+#define WLAN_EID_SUPP_CHANNELS 36 /* 11h Supported Channels */
32957+#define WLAN_EID_CHANNEL_SWITCH 37 /* 11h ChannelSwitch */
32958+#define WLAN_EID_MEASURE_REQUEST 38 /* 11h MeasurementRequest */
32959+#define WLAN_EID_MEASURE_REPORT 39 /* 11h MeasurementReport */
32960+#define WLAN_EID_QUIET_ID 40 /* 11h Quiet */
32961+#define WLAN_EID_IBSS_DFS_ID 41 /* 11h IBSS_DFS */
32962+#endif
32963+
32964+/*-- Reason Codes -------------------------------*/
32965+#define WLAN_MGMT_REASON_RSVD 0
32966+#define WLAN_MGMT_REASON_UNSPEC 1
32967+#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2
32968+#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3
32969+#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4
32970+#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5
32971+#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6
32972+#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7
32973+#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8
32974+#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9
32975+
32976+/*-- Status Codes -------------------------------*/
32977+#define WLAN_MGMT_STATUS_SUCCESS 0
32978+#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1
32979+#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10
32980+#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11
32981+#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12
32982+#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13
32983+#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14
32984+#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15
32985+#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16
32986+#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17
32987+#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18
32988+/* p80211b additions */
32989+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19
32990+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20
32991+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21
32992+
32993+/*-- Auth Algorithm Field ---------------------------*/
32994+#define WLAN_AUTH_ALG_OPENSYSTEM 0
32995+#define WLAN_AUTH_ALG_SHAREDKEY 1
32996+
32997+/*-- Management Frame Field Offsets -------------*/
32998+/* Note: Not all fields are listed because of variable lengths */
32999+/* Note: These offsets are from the start of the frame data */
33000+
33001+#define WLAN_BEACON_OFF_TS 0
33002+#define WLAN_BEACON_OFF_BCN_INT 8
33003+#define WLAN_BEACON_OFF_CAPINFO 10
33004+#define WLAN_BEACON_OFF_SSID 12
33005+
33006+#define WLAN_DISASSOC_OFF_REASON 0
33007+
33008+#define WLAN_ASSOCREQ_OFF_CAP_INFO 0
33009+#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2
33010+#define WLAN_ASSOCREQ_OFF_SSID 4
33011+
33012+#define WLAN_ASSOCRESP_OFF_CAP_INFO 0
33013+#define WLAN_ASSOCRESP_OFF_STATUS 2
33014+#define WLAN_ASSOCRESP_OFF_AID 4
33015+#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6
33016+
33017+#define WLAN_REASSOCREQ_OFF_CAP_INFO 0
33018+#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2
33019+#define WLAN_REASSOCREQ_OFF_CURR_AP 4
33020+#define WLAN_REASSOCREQ_OFF_SSID 10
33021+
33022+#define WLAN_REASSOCRESP_OFF_CAP_INFO 0
33023+#define WLAN_REASSOCRESP_OFF_STATUS 2
33024+#define WLAN_REASSOCRESP_OFF_AID 4
33025+#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6
33026+
33027+#define WLAN_PROBEREQ_OFF_SSID 0
33028+
33029+#define WLAN_PROBERESP_OFF_TS 0
33030+#define WLAN_PROBERESP_OFF_BCN_INT 8
33031+#define WLAN_PROBERESP_OFF_CAP_INFO 10
33032+#define WLAN_PROBERESP_OFF_SSID 12
33033+
33034+#define WLAN_AUTHEN_OFF_AUTH_ALG 0
33035+#define WLAN_AUTHEN_OFF_AUTH_SEQ 2
33036+#define WLAN_AUTHEN_OFF_STATUS 4
33037+#define WLAN_AUTHEN_OFF_CHALLENGE 6
33038+
33039+#define WLAN_DEAUTHEN_OFF_REASON 0
33040+
33041+enum {
33042+IEEE16(WF_MGMT_CAP_ESS, 0x0001)
33043+IEEE16(WF_MGMT_CAP_IBSS, 0x0002)
33044+/* In (re)assoc request frames by STA:
33045+** Pollable=0, PollReq=0: STA is not CF-Pollable
33046+** 0 1: STA is CF-Pollable, not requesting to be placed on the CF-Polling list
33047+** 1 0: STA is CF-Pollable, requesting to be placed on the CF-Polling list
33048+** 1 1: STA is CF-Pollable, requesting never to be polled
33049+** In beacon, proberesp, (re)assoc resp frames by AP:
33050+** 0 0: No point coordinator at AP
33051+** 0 1: Point coordinator at AP for delivery only (no polling)
33052+** 1 0: Point coordinator at AP for delivery and polling
33053+** 1 1: Reserved */
33054+IEEE16(WF_MGMT_CAP_CFPOLLABLE, 0x0004)
33055+IEEE16(WF_MGMT_CAP_CFPOLLREQ, 0x0008)
33056+/* 1=non-WEP data frames are disallowed */
33057+IEEE16(WF_MGMT_CAP_PRIVACY, 0x0010)
33058+/* In beacon, proberesp, (re)assocresp by AP/AdHoc:
33059+** 1=use of shortpre is allowed ("I can receive shortpre") */
33060+IEEE16(WF_MGMT_CAP_SHORT, 0x0020)
33061+IEEE16(WF_MGMT_CAP_PBCC, 0x0040)
33062+IEEE16(WF_MGMT_CAP_AGILITY, 0x0080)
33063+/* In (re)assoc request frames by STA:
33064+** 1=short slot time implemented and enabled
33065+** NB: AP shall use long slot time beginning at the next Beacon after assoc
33066+** of STA with this bit set to 0
33067+** In beacon, proberesp, (re)assoc resp frames by AP:
33068+** currently used slot time value: 0/1 - long/short */
33069+IEEE16(WF_MGMT_CAP_SHORTSLOT, 0x0400)
33070+/* In (re)assoc request frames by STA: 1=CCK-OFDM is implemented and enabled
33071+** In beacon, proberesp, (re)assoc resp frames by AP/AdHoc:
33072+** 1=CCK-OFDM is allowed */
33073+IEEE16(WF_MGMT_CAP_CCKOFDM, 0x2000)
33074+};
33075+
33076+
33077+/***********************************************************************
33078+** Types
33079+*/
33080+
33081+/* Information Element types */
33082+
33083+/* prototype structure, all IEs start with these members */
33084+typedef struct wlan_ie {
33085+ u8 eid;
33086+ u8 len;
33087+} WLAN_PACKED wlan_ie_t;
33088+
33089+/*-- Service Set Identity (SSID) -----------------*/
33090+typedef struct wlan_ie_ssid {
33091+ u8 eid;
33092+ u8 len;
33093+ u8 ssid[1]; /* may be zero */
33094+} WLAN_PACKED wlan_ie_ssid_t;
33095+
33096+/*-- Supported Rates -----------------------------*/
33097+typedef struct wlan_ie_supp_rates {
33098+ u8 eid;
33099+ u8 len;
33100+ u8 rates[1]; /* had better be at LEAST one! */
33101+} WLAN_PACKED wlan_ie_supp_rates_t;
33102+
33103+/*-- FH Parameter Set ----------------------------*/
33104+typedef struct wlan_ie_fh_parms {
33105+ u8 eid;
33106+ u8 len;
33107+ u16 dwell;
33108+ u8 hopset;
33109+ u8 hoppattern;
33110+ u8 hopindex;
33111+} WLAN_PACKED wlan_ie_fh_parms_t;
33112+
33113+/*-- DS Parameter Set ----------------------------*/
33114+typedef struct wlan_ie_ds_parms {
33115+ u8 eid;
33116+ u8 len;
33117+ u8 curr_ch;
33118+} WLAN_PACKED wlan_ie_ds_parms_t;
33119+
33120+/*-- CF Parameter Set ----------------------------*/
33121+typedef struct wlan_ie_cf_parms {
33122+ u8 eid;
33123+ u8 len;
33124+ u8 cfp_cnt;
33125+ u8 cfp_period;
33126+ u16 cfp_maxdur;
33127+ u16 cfp_durremaining;
33128+} WLAN_PACKED wlan_ie_cf_parms_t;
33129+
33130+/*-- TIM ------------------------------------------*/
33131+typedef struct wlan_ie_tim {
33132+ u8 eid;
33133+ u8 len;
33134+ u8 dtim_cnt;
33135+ u8 dtim_period;
33136+ u8 bitmap_ctl;
33137+ u8 virt_bm[1];
33138+} WLAN_PACKED wlan_ie_tim_t;
33139+
33140+/*-- IBSS Parameter Set ---------------------------*/
33141+typedef struct wlan_ie_ibss_parms {
33142+ u8 eid;
33143+ u8 len;
33144+ u16 atim_win;
33145+} WLAN_PACKED wlan_ie_ibss_parms_t;
33146+
33147+/*-- Challenge Text ------------------------------*/
33148+typedef struct wlan_ie_challenge {
33149+ u8 eid;
33150+ u8 len;
33151+ u8 challenge[1];
33152+} WLAN_PACKED wlan_ie_challenge_t;
33153+
33154+/*-- ERP (42) -------------------------------------*/
33155+typedef struct wlan_ie_erp {
33156+ u8 eid;
33157+ u8 len;
33158+ /* bit 0:Non ERP present
33159+ ** 1:Use Protection
33160+ ** 2:Barker Preamble mode
33161+ ** 3-7:reserved */
33162+ u8 erp;
33163+} WLAN_PACKED wlan_ie_erp_t;
33164+
33165+/* Types for parsing mgmt frames */
33166+
33167+/* prototype structure, all mgmt frame types will start with these members */
33168+typedef struct wlan_fr_mgmt {
33169+ u16 type;
33170+ u16 len; /* DOES NOT include FCS */
33171+ wlan_hdr_t *hdr;
33172+ /* used for target specific data, skb in Linux */
33173+ /*-- fixed fields -----------*/
33174+ /*-- info elements ----------*/
33175+} WLAN_PACKED wlan_fr_mgmt_t;
33176+
33177+/*-- Beacon ---------------------------------------*/
33178+typedef struct wlan_fr_beacon {
33179+ u16 type;
33180+ u16 len;
33181+ wlan_hdr_t *hdr;
33182+ /*-- fixed fields -----------*/
33183+ u64 *ts;
33184+ u16 *bcn_int;
33185+ u16 *cap_info;
33186+ /*-- info elements ----------*/
33187+ wlan_ie_ssid_t *ssid;
33188+ wlan_ie_supp_rates_t *supp_rates;
33189+ wlan_ie_supp_rates_t *ext_rates;
33190+ wlan_ie_fh_parms_t *fh_parms;
33191+ wlan_ie_ds_parms_t *ds_parms;
33192+ wlan_ie_cf_parms_t *cf_parms;
33193+ wlan_ie_ibss_parms_t *ibss_parms;
33194+ wlan_ie_tim_t *tim; /* in beacon only, not proberesp */
33195+ wlan_ie_erp_t *erp; /* in beacon only, not proberesp */
33196+} wlan_fr_beacon_t;
33197+#define wlan_fr_proberesp wlan_fr_beacon
33198+#define wlan_fr_proberesp_t wlan_fr_beacon_t
33199+
33200+/*-- IBSS ATIM ------------------------------------*/
33201+typedef struct wlan_fr_ibssatim {
33202+ u16 type;
33203+ u16 len;
33204+ wlan_hdr_t *hdr;
33205+ /*-- fixed fields -----------*/
33206+ /*-- info elements ----------*/
33207+ /* this frame type has a null body */
33208+} wlan_fr_ibssatim_t;
33209+
33210+/*-- Disassociation -------------------------------*/
33211+typedef struct wlan_fr_disassoc {
33212+ u16 type;
33213+ u16 len;
33214+ wlan_hdr_t *hdr;
33215+ /*-- fixed fields -----------*/
33216+ u16 *reason;
33217+ /*-- info elements ----------*/
33218+} wlan_fr_disassoc_t;
33219+
33220+/*-- Association Request --------------------------*/
33221+typedef struct wlan_fr_assocreq {
33222+ u16 type;
33223+ u16 len;
33224+ wlan_hdr_t *hdr;
33225+ /*-- fixed fields -----------*/
33226+ u16 *cap_info;
33227+ u16 *listen_int;
33228+ /*-- info elements ----------*/
33229+ wlan_ie_ssid_t *ssid;
33230+ wlan_ie_supp_rates_t *supp_rates;
33231+ wlan_ie_supp_rates_t *ext_rates;
33232+} wlan_fr_assocreq_t;
33233+
33234+/*-- Association Response -------------------------*/
33235+typedef struct wlan_fr_assocresp {
33236+ u16 type;
33237+ u16 len;
33238+ wlan_hdr_t *hdr;
33239+ /*-- fixed fields -----------*/
33240+ u16 *cap_info;
33241+ u16 *status;
33242+ u16 *aid;
33243+ /*-- info elements ----------*/
33244+ wlan_ie_supp_rates_t *supp_rates;
33245+ wlan_ie_supp_rates_t *ext_rates;
33246+} wlan_fr_assocresp_t;
33247+
33248+/*-- Reassociation Request ------------------------*/
33249+typedef struct wlan_fr_reassocreq {
33250+ u16 type;
33251+ u16 len;
33252+ wlan_hdr_t *hdr;
33253+ /*-- fixed fields -----------*/
33254+ u16 *cap_info;
33255+ u16 *listen_int;
33256+ u8 *curr_ap;
33257+ /*-- info elements ----------*/
33258+ wlan_ie_ssid_t *ssid;
33259+ wlan_ie_supp_rates_t *supp_rates;
33260+ wlan_ie_supp_rates_t *ext_rates;
33261+} wlan_fr_reassocreq_t;
33262+
33263+/*-- Reassociation Response -----------------------*/
33264+typedef struct wlan_fr_reassocresp {
33265+ u16 type;
33266+ u16 len;
33267+ wlan_hdr_t *hdr;
33268+ /*-- fixed fields -----------*/
33269+ u16 *cap_info;
33270+ u16 *status;
33271+ u16 *aid;
33272+ /*-- info elements ----------*/
33273+ wlan_ie_supp_rates_t *supp_rates;
33274+ wlan_ie_supp_rates_t *ext_rates;
33275+} wlan_fr_reassocresp_t;
33276+
33277+/*-- Probe Request --------------------------------*/
33278+typedef struct wlan_fr_probereq {
33279+ u16 type;
33280+ u16 len;
33281+ wlan_hdr_t *hdr;
33282+ /*-- fixed fields -----------*/
33283+ /*-- info elements ----------*/
33284+ wlan_ie_ssid_t *ssid;
33285+ wlan_ie_supp_rates_t *supp_rates;
33286+ wlan_ie_supp_rates_t *ext_rates;
33287+} wlan_fr_probereq_t;
33288+
33289+/*-- Authentication -------------------------------*/
33290+typedef struct wlan_fr_authen {
33291+ u16 type;
33292+ u16 len;
33293+ wlan_hdr_t *hdr;
33294+ /*-- fixed fields -----------*/
33295+ u16 *auth_alg;
33296+ u16 *auth_seq;
33297+ u16 *status;
33298+ /*-- info elements ----------*/
33299+ wlan_ie_challenge_t *challenge;
33300+} wlan_fr_authen_t;
33301+
33302+/*-- Deauthenication -----------------------------*/
33303+typedef struct wlan_fr_deauthen {
33304+ u16 type;
33305+ u16 len;
33306+ wlan_hdr_t *hdr;
33307+ /*-- fixed fields -----------*/
33308+ u16 *reason;
33309+ /*-- info elements ----------*/
33310+} wlan_fr_deauthen_t;
33311+
33312+/* Types for building mgmt frames */
33313+
33314+/* Warning. Several types used in below structs are
33315+** in fact variable length. Use structs with such fields with caution */
33316+typedef struct auth_frame_body {
33317+ u16 auth_alg;
33318+ u16 auth_seq;
33319+ u16 status;
33320+ wlan_ie_challenge_t challenge;
33321+} WLAN_PACKED auth_frame_body_t;
33322+
33323+typedef struct assocresp_frame_body {
33324+ u16 cap_info;
33325+ u16 status;
33326+ u16 aid;
33327+ wlan_ie_supp_rates_t rates;
33328+} WLAN_PACKED assocresp_frame_body_t;
33329+
33330+typedef struct reassocreq_frame_body {
33331+ u16 cap_info;
33332+ u16 listen_int;
33333+ u8 current_ap[ETH_ALEN];
33334+ wlan_ie_ssid_t ssid;
33335+/* access to this one is disabled since ssid_t is variable length: */
33336+ /* wlan_ie_supp_rates_t rates; */
33337+} WLAN_PACKED reassocreq_frame_body_t;
33338+
33339+typedef struct reassocresp_frame_body {
33340+ u16 cap_info;
33341+ u16 status;
33342+ u16 aid;
33343+ wlan_ie_supp_rates_t rates;
33344+} WLAN_PACKED reassocresp_frame_body_t;
33345+
33346+typedef struct deauthen_frame_body {
33347+ u16 reason;
33348+} WLAN_PACKED deauthen_frame_body_t;
33349+
33350+typedef struct disassoc_frame_body {
33351+ u16 reason;
33352+} WLAN_PACKED disassoc_frame_body_t;
33353+
33354+typedef struct probereq_frame_body {
33355+ wlan_ie_ssid_t ssid;
33356+ wlan_ie_supp_rates_t rates;
33357+} WLAN_PACKED probereq_frame_body_t;
33358+
33359+typedef struct proberesp_frame_body {
33360+ u8 timestamp[8];
33361+ u16 beacon_int;
33362+ u16 cap_info;
33363+ wlan_ie_ssid_t ssid;
33364+/* access to these is disabled since ssid_t is variable length: */
33365+ /* wlan_ie_supp_rates_t rates; */
33366+ /* fhps_t fhps; */
33367+ /* dsps_t dsps; */
33368+ /* cfps_t cfps; */
33369+} WLAN_PACKED proberesp_frame_body_t;
33370+
33371+
33372+/***********************************************************************
33373+** Functions
33374+*/
33375+
33376+/* Helpers for parsing mgmt frames */
33377+void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t *f);
33378+void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f);
33379+void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f);
33380+void wlan_mgmt_decode_authen(wlan_fr_authen_t *f);
33381+void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f);
33382+void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f);
33383+void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f);
33384+void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f);
33385+void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f);
33386+void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f);
33387+void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f);
33388+
33389+/* Helpers for building mgmt frames */
33390+static inline u8*
33391+wlan_fill_ie_ssid(u8 *p, int len, const char *ssid)
33392+{
33393+ struct wlan_ie_ssid *ie = (void*)p;
33394+ ie->eid = WLAN_EID_SSID;
33395+ ie->len = len;
33396+ memcpy(ie->ssid, ssid, len);
33397+ return p + len + 2;
33398+}
33399+/* This controls whether we create 802.11g 'ext supported rates' IEs
33400+** or just create overlong 'supported rates' IEs instead
33401+** (non-11g compliant) */
33402+#define WE_OBEY_802_11G 1
33403+static inline u8*
33404+wlan_fill_ie_rates(u8 *p, int len, const u8 *rates)
33405+{
33406+ struct wlan_ie_supp_rates *ie = (void*)p;
33407+#if WE_OBEY_802_11G
33408+ if (len > 8 ) len = 8;
33409+#endif
33410+ /* supported rates (1 to 8 octets) */
33411+ ie->eid = WLAN_EID_SUPP_RATES;
33412+ ie->len = len;
33413+ memcpy(ie->rates, rates, len);
33414+ return p + len + 2;
33415+}
33416+/* This one wouldn't create an IE at all if not needed */
33417+static inline u8*
33418+wlan_fill_ie_rates_ext(u8 *p, int len, const u8 *rates)
33419+{
33420+ struct wlan_ie_supp_rates *ie = (void*)p;
33421+#if !WE_OBEY_802_11G
33422+ return p;
33423+#endif
33424+ len -= 8;
33425+ if (len <= 0) return p;
33426+ /* ext supported rates */
33427+ ie->eid = WLAN_EID_EXT_RATES;
33428+ ie->len = len;
33429+ memcpy(ie->rates, rates+8, len);
33430+ return p + len + 2;
33431+}
33432+static inline u8*
33433+wlan_fill_ie_ds_parms(u8 *p, int channel)
33434+{
33435+ struct wlan_ie_ds_parms *ie = (void*)p;
33436+ ie->eid = WLAN_EID_DS_PARMS;
33437+ ie->len = 1;
33438+ ie->curr_ch = channel;
33439+ return p + sizeof(*ie);
33440+}
33441+static inline u8*
33442+wlan_fill_ie_ibss_parms(u8 *p, int atim_win)
33443+{
33444+ struct wlan_ie_ibss_parms *ie = (void*)p;
33445+ ie->eid = WLAN_EID_IBSS_PARMS;
33446+ ie->len = 2;
33447+ ie->atim_win = atim_win;
33448+ return p + sizeof(*ie);
33449+}
33450+static inline u8*
33451+wlan_fill_ie_tim(u8 *p, int rem, int period, int bcast,
33452+ int ofs, int len, const u8 *vbm)
33453+{
33454+ struct wlan_ie_tim *ie = (void*)p;
33455+ ie->eid = WLAN_EID_TIM;
33456+ ie->len = len + 3;
33457+ ie->dtim_cnt = rem;
33458+ ie->dtim_period = period;
33459+ ie->bitmap_ctl = ofs | (bcast!=0);
33460+ if (vbm)
33461+ memcpy(ie->virt_bm, vbm, len); /* min 1 byte */
33462+ else
33463+ ie->virt_bm[0] = 0;
33464+ return p + len + 3 + 2;
33465+}
33466Index: linux-2.6.22/drivers/net/wireless/Kconfig
33467===================================================================
33468--- linux-2.6.22.orig/drivers/net/wireless/Kconfig 2007-07-09 01:32:17.000000000 +0200
33469+++ linux-2.6.22/drivers/net/wireless/Kconfig 2007-08-23 18:34:19.000000000 +0200
33470@@ -5,6 +5,36 @@
33471 menu "Wireless LAN"
33472 depends on !S390
33473
33474+config NET_RADIO
33475+ bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
33476+ select WIRELESS_EXT
33477+ ---help---
33478+ Support for wireless LANs and everything having to do with radio,
33479+ but not with amateur radio or FM broadcasting.
33480+
33481+ Saying Y here also enables the Wireless Extensions (creates
33482+ /proc/net/wireless and enables iwconfig access). The Wireless
33483+ Extension is a generic API allowing a driver to expose to the user
33484+ space configuration and statistics specific to common Wireless LANs.
33485+ The beauty of it is that a single set of tool can support all the
33486+ variations of Wireless LANs, regardless of their type (as long as
33487+ the driver supports Wireless Extension). Another advantage is that
33488+ these parameters may be changed on the fly without restarting the
33489+ driver (or Linux). If you wish to use Wireless Extensions with
33490+ wireless PCMCIA (PC-) cards, you need to say Y here; you can fetch
33491+ the tools from
33492+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
33493+
33494+config NET_WIRELESS_RTNETLINK
33495+ bool "Wireless Extension API over RtNetlink"
33496+ depends on NET_RADIO
33497+ ---help---
33498+ Support the Wireless Extension API over the RtNetlink socket
33499+ in addition to the traditional ioctl interface (selected above).
33500+
33501+ For now, few tools use this facility, but it might grow in the
33502+ future. The only downside is that it adds 4.5 kB to your kernel.
33503+
33504 config WLAN_PRE80211
33505 bool "Wireless LAN (pre-802.11)"
33506 depends on NETDEVICES
33507@@ -549,5 +579,6 @@
33508 source "drivers/net/wireless/hostap/Kconfig"
33509 source "drivers/net/wireless/bcm43xx/Kconfig"
33510 source "drivers/net/wireless/zd1211rw/Kconfig"
33511+source "drivers/net/wireless/acx/Kconfig"
33512
33513 endmenu
33514Index: linux-2.6.22/drivers/net/wireless/Makefile
33515===================================================================
33516--- linux-2.6.22.orig/drivers/net/wireless/Makefile 2007-07-09 01:32:17.000000000 +0200
33517+++ linux-2.6.22/drivers/net/wireless/Makefile 2007-08-23 18:34:19.000000000 +0200
33518@@ -34,6 +34,8 @@
33519
33520 obj-$(CONFIG_PRISM54) += prism54/
33521
33522+obj-$(CONFIG_ACX) += acx/
33523+
33524 obj-$(CONFIG_HOSTAP) += hostap/
33525 obj-$(CONFIG_BCM43XX) += bcm43xx/
33526 obj-$(CONFIG_ZD1211RW) += zd1211rw/
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni.patch
new file mode 100644
index 0000000000..4d746749c5
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/htcuni.patch
@@ -0,0 +1,8044 @@
1---
2 arch/arm/Kconfig | 2
3 arch/arm/mach-pxa/Kconfig | 89 +
4 arch/arm/mach-pxa/Makefile | 1
5 arch/arm/mach-pxa/corgi.c | 3
6 arch/arm/mach-pxa/generic.c | 13
7 arch/arm/mach-pxa/htcuniversal/Makefile | 19
8 arch/arm/mach-pxa/htcuniversal/htcuniversal.c | 468 +++++
9 arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c | 917 +++++++++++
10 arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h | 65
11 arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c | 143 +
12 arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c | 61
13 arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c | 135 +
14 arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h | 17
15 arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c | 87 +
16 arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c | 226 ++
17 arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c | 212 ++
18 arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c | 167 ++
19 arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h | 16
20 arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c | 69
21 arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c | 97 +
22 arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c | 490 ++++++
23 arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c | 71
24 arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h | 20
25 arch/arm/mach-pxa/spitz.c | 2
26 drivers/input/keyboard/Kconfig | 7
27 drivers/input/keyboard/Makefile | 2
28 drivers/input/keyboard/asic3_keys.c | 131 +
29 drivers/leds/Kconfig | 7
30 drivers/leds/Makefile | 1
31 drivers/leds/leds-asic3.c | 189 ++
32 drivers/mfd/Kconfig | 10
33 drivers/mfd/Makefile | 2
34 drivers/mfd/asic3_base.c | 1208 +++++++++++++++
35 drivers/mfd/soc-core.c | 106 +
36 drivers/mfd/soc-core.h | 30
37 drivers/mmc/host/Kconfig | 6
38 drivers/mmc/host/Makefile | 2
39 drivers/mmc/host/asic3_mmc.c | 900 +++++++++++
40 drivers/mmc/host/asic3_mmc.h | 25
41 drivers/serial/pxa.c | 22
42 drivers/video/backlight/Kconfig | 2
43 drivers/video/backlight/corgi_bl.c | 4
44 include/asm-arm/arch-pxa/clock.h | 27
45 include/asm-arm/arch-pxa/htcuniversal-asic.h | 213 ++
46 include/asm-arm/arch-pxa/htcuniversal-gpio.h | 220 ++
47 include/asm-arm/arch-pxa/htcuniversal-init.h | 14
48 include/asm-arm/arch-pxa/htcuniversal.h | 3
49 include/asm-arm/arch-pxa/irqs.h | 2
50 include/asm-arm/arch-pxa/pxa-pm_ll.h | 6
51 include/asm-arm/arch-pxa/pxa-regs.h | 2
52 include/asm-arm/arch-pxa/serial.h | 78
53 include/asm-arm/arch-pxa/sharpsl.h | 6
54 include/asm-arm/hardware/asic3_keys.h | 18
55 include/asm-arm/hardware/asic3_leds.h | 34
56 include/asm-arm/hardware/ipaq-asic3.h | 602 +++++++
57 include/linux/backlight.h | 7
58 include/linux/gpiodev.h | 44
59 include/linux/input_pda.h | 47
60 include/linux/ioport.h | 1
61 include/linux/soc/asic3_base.h | 104 +
62 include/linux/soc/tmio_mmc.h | 17
63 61 files changed, 7475 insertions(+), 14 deletions(-)
64
65Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/Makefile
66===================================================================
67--- /dev/null 1970-01-01 00:00:00.000000000 +0000
68+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/Makefile 2007-09-11 12:53:37.000000000 +0200
69@@ -0,0 +1,19 @@
70+#
71+# Makefile for HTC Universal
72+#
73+
74+snd-htcuniversal-ak4641-objs := htcuniversal_ak4641.o
75+
76+obj-$(CONFIG_MACH_HTCUNIVERSAL) += htcuniversal.o
77+obj-$(CONFIG_HTCUNIVERSAL_CORE) += htcuniversal_core.o
78+obj-$(CONFIG_HTCUNIVERSAL_POWER) += htcuniversal_power2.o
79+obj-$(CONFIG_HTCUNIVERSAL_LCD) += htcuniversal_lcd.o
80+obj-$(CONFIG_HTCUNIVERSAL_BACKLIGHT) += htcuniversal_bl.o
81+obj-$(CONFIG_HTCUNIVERSAL_TS2) += htcuniversal_ts2.o
82+obj-$(CONFIG_HTCUNIVERSAL_BUTTONS) += htcuniversal_buttons.o
83+obj-$(CONFIG_HTCUNIVERSAL_BLUETOOTH) += htcuniversal_bt.o
84+obj-$(CONFIG_HTCUNIVERSAL_PHONE) += htcuniversal_phone.o
85+obj-$(CONFIG_HTCUNIVERSAL_ASIC3_LEDS) += htcuniversal_asic3_leds.o
86+obj-$(CONFIG_HTCUNIVERSAL_UDC) += htcuniversal_udc.o
87+
88+obj-$(CONFIG_HTCUNIVERSAL_AK4641) += htcuniversal_ak4641.o
89Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal.c
90===================================================================
91--- /dev/null 1970-01-01 00:00:00.000000000 +0000
92+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal.c 2007-09-11 12:53:37.000000000 +0200
93@@ -0,0 +1,468 @@
94+/*
95+ * Hardware definitions for HTC Universal
96+ *
97+ * Copyright (c) 2006 Oleg Gusev
98+ *
99+ * Use consistent with the GNU GPL is permitted,
100+ * provided that this copyright notice is
101+ * preserved in its entirety in all copies and derived works.
102+ *
103+ */
104+
105+#include <linux/kernel.h>
106+#include <linux/init.h>
107+#include <linux/platform_device.h>
108+#include <linux/irq.h>
109+#include <linux/input.h>
110+#include <linux/gpio_keys.h>
111+#include <linux/soc/asic3_base.h>
112+
113+#include <asm/mach-types.h>
114+#include <asm/hardware.h>
115+#include <asm/setup.h>
116+
117+#include <asm/mach/irq.h>
118+#include <asm/mach/arch.h>
119+
120+#include <asm/arch/bitfield.h>
121+#include <asm/arch/pxa-regs.h>
122+#include <asm/arch/serial.h>
123+#include <asm/arch/pxa27x_keyboard.h>
124+#include <asm/arch/pxafb.h>
125+#include <asm/arch/irda.h>
126+#include <asm/arch/ohci.h>
127+
128+#include <asm/arch/htcuniversal.h>
129+#include <asm/arch/htcuniversal-gpio.h>
130+#include <asm/arch/htcuniversal-init.h>
131+#include <asm/arch/htcuniversal-asic.h>
132+
133+#include <asm/hardware/ipaq-asic3.h>
134+
135+#include "../generic.h"
136+
137+#include "htcuniversal_bt.h"
138+#include "htcuniversal_phone.h"
139+#include "tsc2046_ts.h"
140+
141+/*
142+ * IRDA
143+ */
144+
145+static void htcuniversal_irda_transceiver_mode(struct device *dev, int mode)
146+{
147+ /* */
148+}
149+
150+static struct pxaficp_platform_data htcuniversal_ficp_platform_data = {
151+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
152+ .transceiver_mode = htcuniversal_irda_transceiver_mode,
153+};
154+
155+/*
156+ * Bluetooth - Relies on other loadable modules, like ASIC3 and Core,
157+ * so make the calls indirectly through pointers. Requires that the
158+ * htcuniversal_bt module be loaded before any attempt to use
159+ * bluetooth (obviously).
160+ */
161+
162+static struct htcuniversal_bt_funcs bt_funcs;
163+
164+static void
165+htcuniversal_bt_configure( int state )
166+{
167+ if (bt_funcs.configure != NULL)
168+ bt_funcs.configure( state );
169+}
170+
171+static struct htcuniversal_phone_funcs phone_funcs;
172+
173+static void
174+htcuniversal_phone_configure( int state )
175+{
176+ if (phone_funcs.configure != NULL)
177+ phone_funcs.configure( state );
178+}
179+
180+//void htcuniversal_ll_pm_init(void);
181+
182+extern struct platform_device htcuniversal_bl;
183+static struct platform_device htcuniversal_lcd = { .name = "htcuniversal_lcd", };
184+//static struct platform_device htcuniversal_kbd = { .name = "htcuniversal_kbd", };
185+static struct platform_device htcuniversal_buttons = { .name = "htcuniversal_buttons", };
186+//static struct platform_device htcuniversal_ts = { .name = "htcuniversal_ts", };
187+//static struct platform_device htcuniversal_bt = { .name = "htcuniversal_bt", };
188+//static struct platform_device htcuniversal_phone = { .name = "htcuniversal_phone", };
189+static struct platform_device htcuniversal_power = { .name = "htcuniversal_power", };
190+static struct platform_device htcuniversal_udc = { .name = "htcuniversal_udc", };
191+
192+static struct tsc2046_mach_info htcuniversal_ts_platform_data = {
193+ .port = 1,
194+ .clock = CKEN_SSP1,
195+ .pwrbit_X = 1,
196+ .pwrbit_Y = 1,
197+ .irq = 0 /* asic3 irq */
198+};
199+
200+static struct platform_device htcuniversal_ts = {
201+ .name = "htcuniversal_ts",
202+ .dev = {
203+ .platform_data = &htcuniversal_ts_platform_data,
204+ },
205+};
206+
207+
208+/* Bluetooth */
209+
210+static struct platform_device htcuniversal_bt = {
211+ .name = "htcuniversal_bt",
212+ .id = -1,
213+ .dev = {
214+ .platform_data = &bt_funcs,
215+ },
216+};
217+
218+static struct platform_device htcuniversal_phone = {
219+ .name = "htcuniversal_phone",
220+ .id = -1,
221+ .dev = {
222+ .platform_data = &phone_funcs,
223+ },
224+};
225+
226+/* PXA2xx Keys */
227+
228+static struct gpio_keys_button htcuniversal_button_table[] = {
229+ { KEY_POWER, GPIO_NR_HTCUNIVERSAL_KEY_ON_N, 1 },
230+};
231+
232+static struct gpio_keys_platform_data htcuniversal_pxa_keys_data = {
233+ .buttons = htcuniversal_button_table,
234+ .nbuttons = ARRAY_SIZE(htcuniversal_button_table),
235+};
236+
237+static struct platform_device htcuniversal_pxa_keys = {
238+ .name = "gpio-keys",
239+ .dev = {
240+ .platform_data = &htcuniversal_pxa_keys_data,
241+ },
242+ .id = -1,
243+};
244+
245+/****************************************************************
246+ * Keyboard
247+ ****************************************************************/
248+
249+static struct pxa27x_keyboard_platform_data htcuniversal_kbd = {
250+ .nr_rows = 8,
251+ .nr_cols = 8,
252+ .keycodes = {
253+ {
254+ /* row 0 */
255+ KEY_ENTER,
256+ KEY_MINUS,
257+ KEY_ESC,
258+ KEY_1,
259+ KEY_TAB,
260+ KEY_CAPSLOCK,
261+ KEY_LEFTSHIFT,
262+ KEY_RIGHTALT, /* Fn */
263+ }, { /* row 1 */
264+ KEY_COMMA,
265+ KEY_EQUAL,
266+ KEY_F1,
267+ KEY_2,
268+ KEY_Q,
269+ KEY_A,
270+ KEY_Z,
271+ KEY_LEFTCTRL,
272+ }, { /* row 2 */
273+ KEY_UP,
274+ KEY_I,
275+ KEY_F2,
276+ KEY_3,
277+ KEY_W,
278+ KEY_S,
279+ KEY_X,
280+ KEY_F6,
281+ }, { /* row 3 */
282+ KEY_DOT,
283+ KEY_O,
284+ KEY_F3,
285+ KEY_4,
286+ KEY_E,
287+ KEY_D,
288+ KEY_C,
289+ KEY_LEFTALT,
290+ }, { /* row 4 */
291+ KEY_F9,
292+ KEY_P,
293+ KEY_F4,
294+ KEY_5,
295+ KEY_R,
296+ KEY_F,
297+ KEY_V,
298+ KEY_SPACE,
299+ }, { /* row 5 */
300+ KEY_RIGHT,
301+ KEY_BACKSPACE,
302+ KEY_F5,
303+ KEY_6,
304+ KEY_T,
305+ KEY_G,
306+ KEY_B,
307+ KEY_F7,
308+ }, { /* row 6 */
309+ KEY_F9,
310+ KEY_K,
311+ KEY_9,
312+ KEY_7,
313+ KEY_Y,
314+ KEY_H,
315+ KEY_N,
316+ KEY_LEFT,
317+ }, { /* row 7 */
318+ KEY_F10,
319+ KEY_L,
320+ KEY_0,
321+ KEY_8,
322+ KEY_U,
323+ KEY_J,
324+ KEY_M,
325+ KEY_DOWN,
326+ },
327+ },
328+ .gpio_modes = {
329+ GPIO_NR_HTCUNIVERSAL_KP_MKIN0_MD,
330+ GPIO_NR_HTCUNIVERSAL_KP_MKIN1_MD,
331+ GPIO_NR_HTCUNIVERSAL_KP_MKIN2_MD,
332+ GPIO_NR_HTCUNIVERSAL_KP_MKIN3_MD,
333+ GPIO_NR_HTCUNIVERSAL_KP_MKIN4_MD,
334+ GPIO_NR_HTCUNIVERSAL_KP_MKIN5_MD,
335+ GPIO_NR_HTCUNIVERSAL_KP_MKIN6_MD,
336+ GPIO_NR_HTCUNIVERSAL_KP_MKIN7_MD,
337+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT0_MD,
338+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT1_MD,
339+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT2_MD,
340+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT3_MD,
341+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT4_MD,
342+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT5_MD,
343+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT6_MD,
344+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT7_MD,
345+ },
346+};
347+
348+static struct platform_device htcuniversal_pxa_keyboard = {
349+ .name = "pxa27x-keyboard",
350+ .id = -1,
351+ .dev = {
352+ .platform_data = &htcuniversal_kbd,
353+ },
354+};
355+/* Core Hardware Functions */
356+
357+struct platform_device htcuniversal_core = {
358+ .name = "htcuniversal_core",
359+ .id = 0,
360+ .dev = {
361+ .platform_data = NULL,
362+ },
363+};
364+
365+static struct platform_device *devices[] __initdata = {
366+ &htcuniversal_core,
367+// &htcuniversal_flash,
368+ &htcuniversal_pxa_keyboard,
369+ &htcuniversal_pxa_keys,
370+};
371+
372+static struct platform_device *htcuniversal_asic3_devices[] __initdata = {
373+ &htcuniversal_lcd,
374+#ifdef CONFIG_HTCUNIVERSAL_BACKLIGHT
375+ &htcuniversal_bl,
376+#endif
377+ &htcuniversal_buttons,
378+ &htcuniversal_ts,
379+ &htcuniversal_bt,
380+ &htcuniversal_phone,
381+ &htcuniversal_power,
382+ &htcuniversal_udc,
383+};
384+
385+static struct asic3_platform_data htcuniversal_asic3_platform_data = {
386+
387+ /* Setting ASIC3 GPIO registers to the below initialization states
388+ * HTC Universal asic3 information:
389+ * http://wiki.xda-developers.com/index.php?pagename=UniversalASIC3
390+ * http://wiki.xda-developers.com/index.php?pagename=ASIC3
391+ *
392+ * dir: Direction of the GPIO pin. 0: input, 1: output.
393+ * If unknown, set as output to avoid power consuming floating input nodes
394+ * init: Initial state of the GPIO bits
395+ *
396+ * These registers are configured as they are on Wince.
397+ */
398+ .gpio_a = {
399+ .dir = (1<<GPIOA_LCD_PWR5_ON) |
400+ (1<<GPIOA_FLASHLIGHT) |
401+ (1<<GPIOA_UNKNOWN9) |
402+ (1<<GPIOA_SPK_PWR2_ON) |
403+ (1<<GPIOA_UNKNOWN4) |
404+ (1<<GPIOA_EARPHONE_PWR_ON)|
405+ (1<<GPIOA_AUDIO_PWR_ON) |
406+ (1<<GPIOA_SPK_PWR1_ON) |
407+ (1<<GPIOA_I2C_EN),
408+ .init = (1<<GPIOA_LCD_PWR5_ON) |
409+ (1<<GPIOA_I2C_EN),
410+ .sleep_out = 0x0000,
411+ .batt_fault_out = 0x0000,
412+ .alt_function = 0x0000,
413+ .sleep_conf = 0x000c,
414+ },
415+ .gpio_b = {
416+ .dir = 0xc142,
417+ .init = 0x8842, // TODO: 0x0900
418+ .sleep_out = 0x0000,
419+ .batt_fault_out = 0x0000,
420+ .alt_function = 0x0000,
421+ .sleep_conf = 0x000c,
422+ },
423+ .gpio_c = {
424+ .dir = 0xc7e7,
425+ .init = 0xc6e0, // TODO: 0x8000
426+ .sleep_out = 0x0000,
427+ .batt_fault_out = 0x0000,
428+ .alt_function = 0x0007, // GPIOC_LED_RED | GPIOC_LED_GREEN | GPIOC_LED_BLUE
429+ .sleep_conf = 0x000c,
430+ },
431+ .gpio_d = {
432+ .dir = 0xffc0,
433+ .init = 0x7840, // TODO: 0x0000
434+ .sleep_out = 0x0000,
435+ .batt_fault_out = 0x0000,
436+ .alt_function = 0x0000,
437+ .sleep_conf = 0x0008,
438+ },
439+ .bus_shift = 1,
440+ .irq_base = HTCUNIVERSAL_ASIC3_IRQ_BASE,
441+
442+ .child_platform_devs = htcuniversal_asic3_devices,
443+ .num_child_platform_devs = ARRAY_SIZE(htcuniversal_asic3_devices),
444+};
445+
446+static struct resource htcuniversal_asic3_resources[] = {
447+ [0] = {
448+ .start = HTCUNIVERSAL_ASIC3_GPIO_PHYS,
449+ .end = HTCUNIVERSAL_ASIC3_GPIO_PHYS + IPAQ_ASIC3_MAP_SIZE,
450+ .flags = IORESOURCE_MEM,
451+ },
452+ [1] = {
453+ .start = HTCUNIVERSAL_IRQ(ASIC3_EXT_INT),
454+ .end = HTCUNIVERSAL_IRQ(ASIC3_EXT_INT),
455+ .flags = IORESOURCE_IRQ,
456+ },
457+ [2] = {
458+ .start = HTCUNIVERSAL_ASIC3_MMC_PHYS,
459+ .end = HTCUNIVERSAL_ASIC3_MMC_PHYS + IPAQ_ASIC3_MAP_SIZE,
460+ .flags = IORESOURCE_MEM,
461+ },
462+ [3] = {
463+ .start = HTCUNIVERSAL_IRQ(ASIC3_SDIO_INT_N),
464+ .flags = IORESOURCE_IRQ,
465+ },
466+};
467+
468+struct platform_device htcuniversal_asic3 = {
469+ .name = "asic3",
470+ .id = 0,
471+ .num_resources = ARRAY_SIZE(htcuniversal_asic3_resources),
472+ .resource = htcuniversal_asic3_resources,
473+ .dev = { .platform_data = &htcuniversal_asic3_platform_data, },
474+};
475+EXPORT_SYMBOL(htcuniversal_asic3);
476+
477+static struct pxafb_mode_info htcuniversal_lcd_modes[] = {
478+{
479+ .pixclock = 96153,
480+ .xres = 480,
481+ .yres = 640,
482+ .bpp = 16,
483+ .hsync_len = 4,
484+ .vsync_len = 1,
485+ .left_margin = 20,
486+ .right_margin = 8,
487+ .upper_margin = 7,
488+ .lower_margin = 8,
489+
490+// .sync = FB_SYNC_HOR_LOW_ACT|FB_SYNC_VERT_LOW_ACT,
491+
492+},
493+};
494+
495+static struct pxafb_mach_info sony_acx526akm = {
496+ .modes = htcuniversal_lcd_modes,
497+ .num_modes = ARRAY_SIZE(htcuniversal_lcd_modes),
498+
499+ /* fixme: use constants defined in pxafb.h */
500+ .lccr0 = 0x00000080,
501+ .lccr3 = 0x00400000,
502+// .lccr4 = 0x80000000,
503+};
504+
505+static void __init htcuniversal_init_irq(void)
506+{
507+ pxa27x_init_irq();
508+}
509+
510+static struct platform_pxa_serial_funcs htcuniversal_pxa_bt_funcs = {
511+ .configure = htcuniversal_bt_configure,
512+};
513+static struct platform_pxa_serial_funcs htcuniversal_pxa_phone_funcs = {
514+ .configure = htcuniversal_phone_configure,
515+};
516+
517+/* USB OHCI */
518+
519+static int htcuniversal_ohci_init(struct device *dev)
520+{
521+ /* missing GPIO setup here */
522+
523+ /* got the value from wince */
524+ UHCHR=UHCHR_CGR;
525+
526+ return 0;
527+}
528+
529+static struct pxaohci_platform_data htcuniversal_ohci_platform_data = {
530+ .port_mode = PMM_PERPORT_MODE,
531+ .init = htcuniversal_ohci_init,
532+};
533+
534+static void __init htcuniversal_map_io(void)
535+{
536+ pxa_map_io();
537+
538+ pxa_set_btuart_info(&htcuniversal_pxa_bt_funcs);
539+ pxa_set_ffuart_info(&htcuniversal_pxa_phone_funcs);
540+}
541+
542+static void __init htcuniversal_init(void)
543+{
544+ set_pxa_fb_info(&sony_acx526akm);
545+
546+ platform_device_register(&htcuniversal_asic3);
547+ platform_add_devices(devices, ARRAY_SIZE(devices) );
548+ pxa_set_ficp_info(&htcuniversal_ficp_platform_data);
549+ pxa_set_ohci_info(&htcuniversal_ohci_platform_data);
550+}
551+
552+MACHINE_START(HTCUNIVERSAL, "HTC Universal")
553+ /* Maintainer xanadux.org */
554+ .phys_io = 0x40000000,
555+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
556+ .boot_params = 0xa0000100,
557+ .map_io = htcuniversal_map_io,
558+ .init_irq = htcuniversal_init_irq,
559+ .init_machine = htcuniversal_init,
560+ .timer = &pxa_timer,
561+MACHINE_END
562Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c
563===================================================================
564--- /dev/null 1970-01-01 00:00:00.000000000 +0000
565+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c 2007-09-11 12:53:37.000000000 +0200
566@@ -0,0 +1,917 @@
567+/*
568+ * Audio support for codec Asahi Kasei AK4641
569+ *
570+ * This program is free software; you can redistribute it and/or modify
571+ * it under the terms of the GNU General Public License version 2 as
572+ * published by the Free Software Foundation.
573+ *
574+ * Copyright (c) 2006 Giorgio Padrin <giorgio@mandarinlogiq.org>
575+ *
576+ * History:
577+ *
578+ * 2006-03 Written -- Giorgio Padrin
579+ * 2006-09 Test and debug on machine (HP hx4700) -- Elshin Roman <roxmail@list.ru>
580+ *
581+ * AK4641 codec device driver
582+ *
583+ * Copyright (c) 2005 SDG Systems, LLC
584+ *
585+ * Based on code:
586+ * Copyright (c) 2002 Hewlett-Packard Company
587+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
588+ * Copyright (c) 2000 Lernout & Hauspie Speech Products, N.V.
589+ *
590+ * This program is free software; you can redistribute it and/or
591+ * modify it under the terms of the GNU General Public License.
592+ */
593+
594+#include <sound/driver.h>
595+
596+#include <linux/module.h>
597+#include <linux/init.h>
598+#include <linux/types.h>
599+#include <linux/string.h>
600+#include <linux/slab.h>
601+#include <linux/errno.h>
602+#include <linux/ioctl.h>
603+#include <linux/delay.h>
604+#include <linux/i2c.h>
605+
606+#include <sound/core.h>
607+#include <sound/control.h>
608+#include <sound/initval.h>
609+#include <sound/info.h>
610+
611+#include "htcuniversal_ak4641.h"
612+
613+/* Registers */
614+#define R_PM1 0x00
615+#define R_PM2 0x01
616+#define R_SEL1 0x02
617+#define R_SEL2 0x03
618+#define R_MODE1 0x04
619+#define R_MODE2 0x05
620+#define R_DAC 0x06
621+#define R_MIC 0x07
622+#define REG_TIMER 0x08
623+#define REG_ALC1 0x09
624+#define REG_ALC2 0x0a
625+#define R_PGA 0x0b
626+#define R_ATTL 0x0c
627+#define R_ATTR 0x0d
628+#define REG_VOL 0x0e
629+#define R_STATUS 0x0f
630+#define REG_EQLO 0x10
631+#define REG_EQMID 0x11
632+#define REG_EQHI 0x12
633+#define REG_BTIF 0x13
634+
635+/* Register flags */
636+/* REG_PWR1 */
637+#define R_PM1_PMADC 0x01
638+#define R_PM1_PMMIC 0x02
639+#define REG_PWR1_PMAUX 0x04
640+#define REG_PWR1_PMMO 0x08
641+#define R_PM1_PMLO 0x10
642+/* unused 0x20 */
643+/* unused 0x40 */
644+#define R_PM1_PMVCM 0x80
645+
646+/* REG_PWR2 */
647+#define R_PM2_PMDAC 0x01
648+/* unused 0x02 */
649+/* unused 0x04 */
650+#define R_PM2_PMMO2 0x08
651+#define REG_PWR2_MCKAC 0x10
652+/* unused 0x20 */
653+/* unused 0x40 */
654+#define R_PM2_MCKPD 0x80
655+
656+/* REG_SEL1 */
657+#define R_SEL1_PSMO2 0x01
658+/* unused 0x02 */
659+/* unused 0x04 */
660+/* unused 0x08 */
661+#define REG_SEL1_MICM 0x10
662+#define REG_SEL1_DACM 0x20
663+#define REG_SEL1_PSMO 0x40
664+#define REG_SEL1_MOGN 0x80
665+
666+/* REG_SEL2 */
667+#define R_SEL2_PSLOR 0x01
668+#define R_SEL2_PSLOL 0x02
669+#define REG_SEL2_AUXSI 0x04
670+/* unused 0x08 */
671+#define REG_SEL2_MICL 0x10
672+#define REG_SEL2_AUXL 0x20
673+/* unused 0x40 */
674+#define R_SEL2_DACL 0x80
675+
676+/* REG_MODE1 */
677+#define REG_MODE1_DIF0 0x01
678+#define REG_MODE1_DIF1 0x02
679+/* unused 0x04 */
680+/* unused 0x08 */
681+/* unused 0x10 */
682+/* unused 0x20 */
683+/* unused 0x40 */
684+/* unused 0x80 */
685+
686+/* REG_MODE2 */
687+/* unused 0x01 */
688+#define REG_MODE2_LOOP 0x02
689+#define REG_MODE2_HPM 0x04
690+/* unused 0x08 */
691+/* unused 0x10 */
692+#define REG_MODE2_MCK0 0x20
693+#define REG_MODE2_MCK1 0x40
694+/* unused 0x80 */
695+
696+/* REG_DAC */
697+#define REG_DAC_DEM0 0x01
698+#define REG_DAC_DEM1 0x02
699+#define REG_DAC_EQ 0x04
700+/* unused 0x08 */
701+#define R_DAC_DATTC 0x10
702+#define R_DAC_SMUTE 0x20
703+#define REG_DAC_TM 0x40
704+/* unused 0x80 */
705+
706+/* REG_MIC */
707+#define R_MIC_MGAIN 0x01
708+#define R_MIC_MSEL 0x02
709+#define R_MIC_MICAD 0x04
710+#define R_MIC_MPWRI 0x08
711+#define R_MIC_MPWRE 0x10
712+#define REG_MIC_AUXAD 0x20
713+/* unused 0x40 */
714+/* unused 0x80 */
715+
716+/* REG_TIMER */
717+
718+#define REG_TIMER_LTM0 0x01
719+#define REG_TIMER_LTM1 0x02
720+#define REG_TIMER_WTM0 0x04
721+#define REG_TIMER_WTM1 0x08
722+#define REG_TIMER_ZTM0 0x10
723+#define REG_TIMER_ZTM1 0x20
724+/* unused 0x40 */
725+/* unused 0x80 */
726+
727+#define REG_ALC1_LMTH 0x01
728+#define REG_ALC1_RATT 0x02
729+#define REG_ALC1_LMAT0 0x04
730+#define REG_ALC1_LMAT1 0x08
731+#define REG_ALC1_ZELM 0x10
732+#define REG_ALC1_ALC1 0x20
733+/* unused 0x40 */
734+/* unused 0x80 */
735+
736+/* REG_ALC2 */
737+
738+/* REG_PGA */
739+
740+/* REG_ATTL */
741+
742+/* REG_ATTR */
743+
744+/* REG_VOL */
745+#define REG_VOL_ATTM 0x80
746+
747+/* REG_STATUS */
748+#define R_STATUS_DTMIC 0x01
749+
750+/* REG_EQ controls use 4 bits for each of 5 EQ levels */
751+
752+/* Bluetooth not yet implemented */
753+#define REG_BTIF_PMAD2 0x01
754+#define REG_BTIF_PMDA2 0x02
755+#define REG_BTIF_PMBIF 0x04
756+#define REG_BTIF_ADC2 0x08
757+#define REG_BTIF_DAC2 0x10
758+#define REG_BTIF_BTFMT0 0x20
759+#define REG_BTIF_BTFMT1 0x40
760+/* unused 0x80 */
761+
762+/* begin {{ I2C }} */
763+
764+static struct i2c_driver snd_ak4641_i2c_driver = {
765+ .driver = {
766+ .name = "ak4641-i2c"
767+ },
768+};
769+
770+static int snd_ak4641_i2c_init(void)
771+{
772+ return i2c_add_driver(&snd_ak4641_i2c_driver);
773+}
774+
775+static void snd_ak4641_i2c_free(void)
776+{
777+ i2c_del_driver(&snd_ak4641_i2c_driver);
778+}
779+
780+static inline int snd_ak4641_i2c_probe(struct snd_ak4641 *ak)
781+{
782+ if (ak->i2c_client.adapter == NULL) return -EINVAL;
783+ ak->i2c_client.addr = 0x12;
784+ if (i2c_smbus_xfer(ak->i2c_client.adapter, ak->i2c_client.addr,
785+ 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
786+ return -ENODEV;
787+ else return 0;
788+}
789+
790+static int snd_ak4641_i2c_attach(struct snd_ak4641 *ak)
791+{
792+ int ret = 0;
793+ if ((ret = snd_ak4641_i2c_probe(ak)) < 0) return ret;
794+ snprintf(ak->i2c_client.name, sizeof(ak->i2c_client.name),
795+ "ak4641-i2c at %d-%04x",
796+ i2c_adapter_id(ak->i2c_client.adapter), ak->i2c_client.addr);
797+ return i2c_attach_client(&ak->i2c_client);
798+}
799+
800+static void snd_ak4641_i2c_detach(struct snd_ak4641 *ak)
801+{
802+ i2c_detach_client(&ak->i2c_client);
803+}
804+
805+/* end {{ I2C }} */
806+
807+
808+/* begin {{ Registers & Cache Ops }} */
809+
810+static int snd_ak4641_hwsync(struct snd_ak4641 *ak, int read, u8 reg)
811+{
812+ struct i2c_msg msgs[2];
813+ u8 buf[2];
814+ int ret;
815+
816+ snd_assert(reg < ARRAY_SIZE(ak->regs), return -EINVAL);
817+
818+ /* setup i2c msgs */
819+ msgs[0].addr = ak->i2c_client.addr;
820+ msgs[0].flags = 0;
821+ msgs[0].buf = buf;
822+ if (!read)
823+ msgs[0].len = 2;
824+ else {
825+ msgs[1].flags = I2C_M_RD;
826+ msgs[1].addr = msgs[0].addr;
827+ msgs[1].buf = msgs[0].buf + 1;
828+ msgs[0].len = 1;
829+ msgs[1].len = 1;
830+ }
831+
832+ buf[0] = reg;
833+
834+ /* regs[reg] -> buffer, on write */
835+ if (!read) buf[1] = ak->regs[reg];
836+
837+ /* i2c transfer */
838+ ret = i2c_transfer(ak->i2c_client.adapter, msgs, read ? 2 : 1);
839+ if (ret != (read ? 2 : 1)) return ret; /* transfer error */ //@@ error ret < 0, or not ?
840+
841+ /* regs[reg] <- buffer, on read */
842+ if (read) ak->regs[reg] = buf[1];
843+
844+ return 0;
845+}
846+
847+static inline int snd_ak4641_hwsync_read(struct snd_ak4641 *ak, u8 reg)
848+{
849+ return snd_ak4641_hwsync(ak, 1, reg);
850+}
851+
852+static inline int snd_ak4641_hwsync_write(struct snd_ak4641 *ak, u8 reg)
853+{
854+ return snd_ak4641_hwsync(ak, 0, reg);
855+}
856+
857+static int snd_ak4641_hwsync_read_all(struct snd_ak4641 *ak)
858+{
859+ u8 reg;
860+ for (reg = 0; reg < ARRAY_SIZE(ak->regs); reg++)
861+ if (snd_ak4641_hwsync_read(ak, reg) < 0) return -1;
862+ return 0;
863+}
864+
865+static int snd_ak4641_hwsync_write_all(struct snd_ak4641 *ak)
866+{
867+ u8 reg;
868+ for (reg = 0; reg < ARRAY_SIZE(ak->regs); reg++)
869+ if (snd_ak4641_hwsync_write(ak, reg) < 0) return -1;
870+ return 0;
871+}
872+
873+static int snd_ak4641_reg_changed(struct snd_ak4641 *ak, u8 reg)
874+{
875+ if ((reg != R_PGA && ak->powered_on) ||
876+ (reg == R_PGA && (ak->regs[R_PM1] & R_PM1_PMMIC)))
877+ return snd_ak4641_hwsync_write(ak, reg);
878+ return 0;
879+}
880+
881+/* end {{ Registers & Cache Ops }}*/
882+
883+
884+static inline void snd_ak4641_lock(struct snd_ak4641 *ak)
885+{
886+ down(&ak->sem);
887+}
888+
889+static inline void snd_ak4641_unlock(struct snd_ak4641 *ak)
890+{
891+ up(&ak->sem);
892+}
893+
894+#define WRITE_MASK(i, val, mask) (((i) & ~(mask)) | ((val) & (mask)))
895+
896+
897+/* begin {{ Controls }} */
898+
899+#define INV_RANGE(val, mask) \
900+ (~(val) & (mask))
901+
902+/*-begin----------------------------------------------------------*/
903+static int snd_ak4641_actl_playback_volume_info(struct snd_kcontrol *kcontrol,
904+ struct snd_ctl_elem_info *uinfo)
905+{
906+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
907+ uinfo->count = 2;
908+ uinfo->value.integer.min = 0;
909+ uinfo->value.integer.max = 0xff;
910+ return 0;
911+}
912+
913+static int snd_ak4641_actl_playback_volume_get(struct snd_kcontrol *kcontrol,
914+ struct snd_ctl_elem_value *ucontrol)
915+{
916+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
917+
918+ snd_ak4641_lock(ak);
919+ ucontrol->value.integer.value[0] = INV_RANGE(ak->regs[R_ATTL], 0xff);
920+ ucontrol->value.integer.value[1] = INV_RANGE(ak->regs[R_ATTR], 0xff);
921+ snd_ak4641_unlock(ak);
922+ return 0;
923+}
924+
925+static int snd_ak4641_actl_playback_volume_put(struct snd_kcontrol *kcontrol,
926+ struct snd_ctl_elem_value *ucontrol)
927+{
928+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
929+
930+ snd_ak4641_lock(ak);
931+ ak->regs[R_ATTL] = INV_RANGE(ucontrol->value.integer.value[0], 0xff);
932+ ak->regs[R_ATTR] = INV_RANGE(ucontrol->value.integer.value[1], 0xff);
933+ snd_ak4641_reg_changed(ak, R_ATTL);
934+ snd_ak4641_reg_changed(ak, R_ATTR);
935+ snd_ak4641_unlock(ak);
936+ return 0;
937+}
938+/*-end------------------------------------------------------------*/
939+
940+/*-begin----------------------------------------------------------*/
941+static int snd_ak4641_actl_mic_gain_info(struct snd_kcontrol *kcontrol,
942+ struct snd_ctl_elem_info *uinfo)
943+{
944+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
945+ uinfo->count = 1;
946+ uinfo->value.integer.min = 0;
947+ uinfo->value.integer.max = 0x7f;
948+ return 0;
949+}
950+
951+static int snd_ak4641_actl_mic_gain_get(struct snd_kcontrol *kcontrol,
952+ struct snd_ctl_elem_value *ucontrol)
953+{
954+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
955+
956+ ucontrol->value.integer.value[0] = ak->regs[R_PGA];
957+ return 0;
958+}
959+
960+static int snd_ak4641_actl_mic_gain_put(struct snd_kcontrol *kcontrol,
961+ struct snd_ctl_elem_value *ucontrol)
962+{
963+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
964+
965+ snd_ak4641_lock(ak);
966+ ak->regs[R_PGA] = ucontrol->value.integer.value[0];
967+ snd_ak4641_reg_changed(ak, R_PGA);
968+ snd_ak4641_unlock(ak);
969+ return 0;
970+}
971+/*-end------------------------------------------------------------*/
972+
973+#define ACTL(ctl_name, _name) \
974+static struct snd_kcontrol_new snd_ak4641_actl_ ## ctl_name = \
975+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = _name, \
976+ .info = snd_ak4641_actl_ ## ctl_name ## _info, \
977+ .get = snd_ak4641_actl_ ## ctl_name ## _get, .put = snd_ak4641_actl_ ## ctl_name ## _put };
978+
979+ACTL(playback_volume, "Master Playback Volume")
980+ACTL(mic_gain, "Mic Capture Gain")
981+
982+struct snd_ak4641_uctl_bool {
983+ int (*get) (struct snd_ak4641 *uda);
984+ int (*set) (struct snd_ak4641 *uda, int on);
985+};
986+
987+static int snd_ak4641_actl_bool_info(struct snd_kcontrol *kcontrol,
988+ struct snd_ctl_elem_info *uinfo)
989+{
990+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
991+ uinfo->count = 1;
992+ return 0;
993+}
994+
995+static int snd_ak4641_actl_bool_get(struct snd_kcontrol *kcontrol,
996+ struct snd_ctl_elem_value *ucontrol)
997+{
998+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
999+ struct snd_ak4641_uctl_bool *uctl =
1000+ (struct snd_ak4641_uctl_bool *) kcontrol->private_value;
1001+
1002+ ucontrol->value.integer.value[0] = uctl->get(ak);
1003+ return 0;
1004+}
1005+
1006+static int snd_ak4641_actl_bool_put(struct snd_kcontrol *kcontrol,
1007+ struct snd_ctl_elem_value *ucontrol)
1008+{
1009+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
1010+ struct snd_ak4641_uctl_bool *uctl =
1011+ (struct snd_ak4641_uctl_bool *) kcontrol->private_value;
1012+
1013+ return uctl->set(ak, ucontrol->value.integer.value[0]);
1014+}
1015+
1016+/*-begin----------------------------------------------------------*/
1017+static int snd_ak4641_uctl_playback_switch_get(struct snd_ak4641 *ak)
1018+{
1019+ return (ak->regs[R_DAC] & R_DAC_SMUTE) == 0x00;
1020+}
1021+
1022+static int snd_ak4641_uctl_playback_switch_set(struct snd_ak4641 *ak, int on)
1023+{
1024+ snd_ak4641_lock(ak);
1025+ ak->regs[R_DAC] = WRITE_MASK(ak->regs[R_DAC],
1026+ on ? 0x00 : R_DAC_SMUTE, R_DAC_SMUTE);
1027+ snd_ak4641_reg_changed(ak, R_DAC);
1028+ snd_ak4641_unlock(ak);
1029+ return 0;
1030+}
1031+/*-end------------------------------------------------------------*/
1032+
1033+/*-begin----------------------------------------------------------*/
1034+static int snd_ak4641_uctl_mic_boost_get(struct snd_ak4641 *ak)
1035+{
1036+ return (ak->regs[R_MIC] & R_MIC_MGAIN) == R_MIC_MGAIN;
1037+}
1038+
1039+static int snd_ak4641_uctl_mic_boost_set(struct snd_ak4641 *ak, int on)
1040+{
1041+ snd_ak4641_lock(ak);
1042+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC],
1043+ on ? R_MIC_MGAIN : 0x00, R_MIC_MGAIN);
1044+ snd_ak4641_reg_changed(ak, R_MIC);
1045+ snd_ak4641_unlock(ak);
1046+ return 0;
1047+}
1048+/*-end------------------------------------------------------------*/
1049+
1050+/*-begin----------------------------------------------------------*/
1051+static int snd_ak4641_uctl_mono_out_get(struct snd_ak4641 *ak)
1052+{
1053+ printk("mono_out status 0x%8.8x -> 0x%8.8x\n",ak->regs[R_SEL1], ak->regs[R_SEL1] & REG_SEL1_PSMO);
1054+ return (ak->regs[R_SEL1] & REG_SEL1_PSMO) == REG_SEL1_PSMO;
1055+}
1056+
1057+static int snd_ak4641_uctl_mono_out_set(struct snd_ak4641 *ak, int on)
1058+{
1059+ printk("phone mic enable called. on=%d\n",on);
1060+ snd_ak4641_lock(ak);
1061+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], on ? R_PM1_PMMIC : 0x00, R_PM1_PMMIC);
1062+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], on ? REG_PWR1_PMMO : 0x00, REG_PWR1_PMMO);
1063+ snd_ak4641_reg_changed(ak, R_PM1);
1064+
1065+ snd_ak4641_hwsync_write(ak, R_PGA); /* mic PGA gain is reset when PMMIC = 0 */
1066+
1067+ /* internal mic */
1068+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC], on ? R_MIC_MPWRI : 0x0, R_MIC_MPWRI);
1069+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC], 0x0, R_MIC_MSEL);
1070+ snd_ak4641_hwsync_write(ak, R_MIC);
1071+
1072+// ak->regs[REG_BTIF] = WRITE_MASK(ak->regs[REG_BTIF], 0x0, REG_BTIF_DAC2);
1073+// snd_ak4641_hwsync_write(ak, REG_BTIF);
1074+ /* */
1075+// ak->regs[REG_VOL] = WRITE_MASK(ak->regs[REG_VOL], on ? REG_VOL_ATTM : 0x00, REG_VOL_ATTM);
1076+// ak->regs[R_SEL1] = WRITE_MASK(ak->regs[R_SEL1], on ? REG_SEL1_MOGN : 0x00, REG_SEL1_MOGN);
1077+ ak->regs[R_SEL1] = WRITE_MASK(ak->regs[R_SEL1], on ? REG_SEL1_MICM : 0x00, REG_SEL1_MICM);
1078+ ak->regs[R_SEL1] = WRITE_MASK(ak->regs[R_SEL1], on ? REG_SEL1_PSMO : 0x00, REG_SEL1_PSMO);
1079+ snd_ak4641_reg_changed(ak, R_SEL1);
1080+ snd_ak4641_unlock(ak);
1081+ return 0;
1082+}
1083+/*-end------------------------------------------------------------*/
1084+
1085+#define ACTL_BOOL(ctl_name, _name) \
1086+static struct snd_ak4641_uctl_bool snd_ak4641_actl_ ## ctl_name ## _pvalue = \
1087+{ .get = snd_ak4641_uctl_ ## ctl_name ## _get, \
1088+ .set = snd_ak4641_uctl_ ## ctl_name ## _set }; \
1089+static struct snd_kcontrol_new snd_ak4641_actl_ ## ctl_name = \
1090+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = _name, .info = snd_ak4641_actl_bool_info, \
1091+ .get = snd_ak4641_actl_bool_get, .put = snd_ak4641_actl_bool_put, \
1092+ .private_value = (unsigned long) &snd_ak4641_actl_ ## ctl_name ## _pvalue };
1093+
1094+ACTL_BOOL(playback_switch, "Master Playback Switch")
1095+ACTL_BOOL(mic_boost, "Mic Boost (+20dB)")
1096+ACTL_BOOL(mono_out, "Phone mic enable")
1097+
1098+static void snd_ak4641_headphone_on(struct snd_ak4641 *ak, int on);
1099+static void snd_ak4641_speaker_on(struct snd_ak4641 *ak, int on);
1100+static void snd_ak4641_select_mic(struct snd_ak4641 *ak);
1101+
1102+void snd_ak4641_hp_connected(struct snd_ak4641 *ak, int connected)
1103+{
1104+ snd_ak4641_lock(ak);
1105+ if (connected != ak->hp_connected) {
1106+ ak->hp_connected = connected;
1107+
1108+ /* headphone or speaker, on playback */
1109+ if (ak->playback_on) {
1110+ if (connected) {
1111+ snd_ak4641_headphone_on(ak, 1);
1112+ snd_ak4641_speaker_on(ak, 0);
1113+ } else {
1114+ snd_ak4641_speaker_on(ak, 1);
1115+ snd_ak4641_headphone_on(ak, 0);
1116+ }
1117+ }
1118+
1119+ /* headset or internal mic, on capture */
1120+ if (ak->capture_on)
1121+ snd_ak4641_select_mic(ak);
1122+ }
1123+ snd_ak4641_unlock(ak);
1124+}
1125+
1126+/* end {{ Controls }} */
1127+
1128+
1129+/* begin {{ Headphone Detected Notification }} */
1130+
1131+static void snd_ak4641_hp_detected_w_fn(void *p)
1132+{
1133+ struct snd_ak4641 *ak = (struct snd_ak4641 *)p;
1134+
1135+ snd_ak4641_hp_connected(ak, ak->hp_detected.detected);
1136+}
1137+
1138+void snd_ak4641_hp_detected(struct snd_ak4641 *ak, int detected)
1139+{
1140+ if (detected != ak->hp_detected.detected) {
1141+ ak->hp_detected.detected = detected;
1142+ queue_work(ak->hp_detected.wq, &ak->hp_detected.w);
1143+ }
1144+}
1145+
1146+static int snd_ak4641_hp_detected_init(struct snd_ak4641 *ak)
1147+{
1148+ INIT_WORK(&ak->hp_detected.w, snd_ak4641_hp_detected_w_fn);
1149+ ak->hp_detected.detected = ak->hp_connected;
1150+ ak->hp_detected.wq = create_singlethread_workqueue("ak4641");
1151+ if (ak->hp_detected.wq) return 0;
1152+ else return -1;
1153+}
1154+
1155+static void snd_ak4641_hp_detected_free(struct snd_ak4641 *ak)
1156+{
1157+ destroy_workqueue(ak->hp_detected.wq);
1158+}
1159+
1160+/* end {{ Headphone Detected Notification }} */
1161+
1162+
1163+/* begin {{ Codec Control }} */
1164+
1165+static void snd_ak4641_headphone_on(struct snd_ak4641 *ak, int on)
1166+{
1167+ if (on) {
1168+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMLO, R_PM1_PMLO);
1169+ snd_ak4641_hwsync_write(ak, R_PM1);
1170+ ak->headphone_out_on(1);
1171+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1172+ R_SEL2_PSLOL | R_SEL2_PSLOR,
1173+ R_SEL2_PSLOL | R_SEL2_PSLOR);
1174+ snd_ak4641_hwsync_write(ak, R_SEL2);
1175+ } else {
1176+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1177+ 0x00, R_SEL2_PSLOL | R_SEL2_PSLOR);
1178+ snd_ak4641_hwsync_write(ak, R_SEL2);
1179+ ak->headphone_out_on(0);
1180+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMLO);
1181+ snd_ak4641_hwsync_write(ak, R_PM1);
1182+ }
1183+}
1184+
1185+static void snd_ak4641_speaker_on(struct snd_ak4641 *ak, int on)
1186+{
1187+ if (on) {
1188+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMLO, R_PM1_PMLO);
1189+ snd_ak4641_hwsync_write(ak, R_PM1);
1190+ ak->speaker_out_on(1);
1191+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1192+ R_SEL2_PSLOL | R_SEL2_PSLOR,
1193+ R_SEL2_PSLOL | R_SEL2_PSLOR);
1194+ snd_ak4641_hwsync_write(ak, R_SEL2);
1195+ } else {
1196+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1197+ 0x00, R_SEL2_PSLOL | R_SEL2_PSLOR);
1198+ snd_ak4641_hwsync_write(ak, R_SEL2);
1199+ ak->speaker_out_on(0);
1200+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMLO);
1201+ snd_ak4641_hwsync_write(ak, R_PM1);
1202+ }
1203+}
1204+
1205+static inline int snd_ak4641_power_on(struct snd_ak4641 *ak)
1206+{
1207+ ak->reset_pin(1);
1208+ ak->power_on_chip(1);
1209+ msleep(1);
1210+ ak->reset_pin(0);
1211+ ak->powered_on = 1;
1212+ return 0;
1213+}
1214+
1215+static inline int snd_ak4641_power_off(struct snd_ak4641 *ak)
1216+{
1217+ ak->powered_on = 0;
1218+ ak->power_on_chip(0);
1219+ return 0;
1220+}
1221+
1222+static inline void snd_ak4641_headphone_out_on(struct snd_ak4641 *ak, int on)
1223+{
1224+ if (ak->headphone_out_on) ak->headphone_out_on(on);
1225+}
1226+
1227+static inline void snd_ak4641_speaker_out_on(struct snd_ak4641 *ak, int on)
1228+{
1229+ if (ak->speaker_out_on) ak->speaker_out_on(on);
1230+}
1231+
1232+static int snd_ak4641_playback_on(struct snd_ak4641 *ak)
1233+{
1234+ if (ak->playback_on) return 0;
1235+
1236+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2],
1237+ R_PM2_PMDAC, R_PM2_MCKPD | R_PM2_PMDAC);
1238+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMLO, R_PM1_PMLO);
1239+ snd_ak4641_hwsync_write(ak, R_PM2);
1240+ snd_ak4641_hwsync_write(ak, R_PM1);
1241+ if (ak->hp_connected) snd_ak4641_headphone_on(ak, 1);
1242+ else snd_ak4641_speaker_on(ak, 1);
1243+
1244+ ak->playback_on = 1;
1245+
1246+ return 0;
1247+}
1248+
1249+static int snd_ak4641_playback_off(struct snd_ak4641 *ak)
1250+{
1251+ if (!ak->playback_on) return 0;
1252+
1253+ ak->playback_on = 0;
1254+
1255+ if (ak->hp_connected) snd_ak4641_headphone_on(ak, 0);
1256+ else snd_ak4641_speaker_on(ak, 0);
1257+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMLO);
1258+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2],
1259+ (!ak->capture_on ? R_PM2_MCKPD : 0x00) | R_PM2_PMDAC,
1260+ R_PM2_MCKPD | R_PM2_PMDAC);
1261+ snd_ak4641_hwsync_write(ak, R_PM1);
1262+ snd_ak4641_hwsync_write(ak, R_PM2);
1263+
1264+ return 0;
1265+}
1266+
1267+static void snd_ak4641_select_mic(struct snd_ak4641 *ak)
1268+{
1269+ int mic = 0;
1270+ u8 r_mic;
1271+
1272+ if (ak->hp_connected) {
1273+ /* check headset mic */
1274+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC], R_MIC_MPWRE, R_MIC_MPWRE);
1275+ snd_ak4641_hwsync_write(ak, R_MIC);
1276+ snd_ak4641_hwsync_read(ak, R_STATUS);
1277+ mic = (ak->regs[R_STATUS] & R_STATUS_DTMIC) == R_STATUS_DTMIC;
1278+
1279+ printk("htcuniversal_ak4641_select_mic: mic=%d\n",mic);
1280+
1281+ r_mic = WRITE_MASK(ak->regs[R_MIC],
1282+ R_MIC_MSEL | (ak->capture_on ? R_MIC_MPWRE : 0x00),
1283+ R_MIC_MSEL | R_MIC_MPWRI | R_MIC_MPWRE);
1284+ }
1285+ else
1286+ r_mic = WRITE_MASK(ak->regs[R_MIC],
1287+ 0x00 | (ak->capture_on ? R_MIC_MPWRI : 0x00),
1288+ R_MIC_MSEL | R_MIC_MPWRI | R_MIC_MPWRE);
1289+
1290+ if (r_mic != ak->regs[R_MIC]) {
1291+ ak->regs[R_MIC] = r_mic;
1292+ snd_ak4641_hwsync_write(ak, R_MIC);
1293+ }
1294+}
1295+
1296+static int snd_ak4641_capture_on(struct snd_ak4641 *ak)
1297+{
1298+ if (ak->capture_on) return 0;
1299+
1300+ if (!ak->playback_on) {
1301+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2], 0x00, R_PM2_MCKPD);
1302+ snd_ak4641_hwsync_write(ak, R_PM2);
1303+ }
1304+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMMIC | R_PM1_PMADC,
1305+ R_PM1_PMMIC | R_PM1_PMADC);
1306+ snd_ak4641_hwsync_write(ak, R_PM1);
1307+ snd_ak4641_hwsync_write(ak, R_PGA); /* mic PGA gain is reset when PMMIC = 0 */
1308+
1309+ ak->capture_on = 1;
1310+
1311+ snd_ak4641_select_mic(ak);
1312+
1313+ msleep(47); /* accounts for ADC init cycle, time enough for fs >= 44.1 kHz */
1314+
1315+ return 0;
1316+}
1317+
1318+static int snd_ak4641_capture_off(struct snd_ak4641 *ak)
1319+{
1320+ if (!ak->capture_on) return 0;
1321+
1322+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC],
1323+ 0x00, R_MIC_MPWRI | R_MIC_MPWRE | R_MIC_MSEL);
1324+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMMIC | R_PM1_PMADC);
1325+ snd_ak4641_hwsync_write(ak, R_MIC);
1326+ snd_ak4641_hwsync_write(ak, R_PM1);
1327+ if (!ak->playback_on) {
1328+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2], R_PM2_MCKPD, R_PM2_MCKPD);
1329+ snd_ak4641_hwsync_write(ak, R_PM2);
1330+ }
1331+
1332+ ak->capture_on = 0;
1333+
1334+ return 0;
1335+}
1336+
1337+int snd_ak4641_open_stream(struct snd_ak4641 *ak, int stream)
1338+{
1339+ snd_ak4641_lock(ak);
1340+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1341+ ak->playback_stream_opened = 1;
1342+ snd_ak4641_playback_on(ak);
1343+ } else {
1344+ ak->capture_stream_opened = 1;
1345+ snd_ak4641_capture_on(ak);
1346+ }
1347+ snd_ak4641_unlock(ak);
1348+ return 0;
1349+}
1350+
1351+int snd_ak4641_close_stream(struct snd_ak4641 *ak, int stream)
1352+{
1353+ snd_ak4641_lock(ak);
1354+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1355+ ak->playback_stream_opened = 0;
1356+ snd_ak4641_playback_off(ak);
1357+ } else {
1358+ ak->capture_stream_opened = 0;
1359+ snd_ak4641_capture_off(ak);
1360+ }
1361+ snd_ak4641_unlock(ak);
1362+ return 0;
1363+}
1364+
1365+static int snd_ak4641_init_regs(struct snd_ak4641 *ak)
1366+{
1367+ snd_ak4641_hwsync_read_all(ak);
1368+
1369+ //@@ MEMO: add some configs
1370+
1371+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMVCM, R_PM1_PMVCM);
1372+ ak->regs[R_DAC] = WRITE_MASK(ak->regs[R_DAC], 0x00, R_DAC_DATTC);
1373+ snd_ak4641_hwsync_write(ak, R_PM1);
1374+ snd_ak4641_hwsync_write(ak, R_DAC);
1375+
1376+ return 0;
1377+}
1378+
1379+int snd_ak4641_suspend(struct snd_ak4641 *ak, pm_message_t state)
1380+{
1381+ snd_ak4641_lock(ak);
1382+ if (ak->playback_on) snd_ak4641_playback_off(ak);
1383+ if (ak->capture_on) snd_ak4641_capture_off(ak);
1384+ snd_ak4641_power_off(ak);
1385+ snd_ak4641_unlock(ak);
1386+ return 0;
1387+}
1388+
1389+int snd_ak4641_resume(struct snd_ak4641 *ak)
1390+{
1391+ snd_ak4641_lock(ak);
1392+ snd_ak4641_power_on(ak);
1393+ snd_ak4641_hwsync_write_all(ak);
1394+ if (ak->playback_stream_opened) snd_ak4641_playback_on(ak);
1395+ if (ak->capture_stream_opened) snd_ak4641_capture_on(ak);
1396+ snd_ak4641_unlock(ak);
1397+ return 0;
1398+}
1399+
1400+static void snd_ak4641_init_ak(struct snd_ak4641 *ak)
1401+{
1402+ init_MUTEX(&ak->sem);
1403+ ak->i2c_client.driver = &snd_ak4641_i2c_driver;
1404+}
1405+
1406+int snd_ak4641_activate(struct snd_ak4641 *ak)
1407+{
1408+ int ret = 0;
1409+
1410+ snd_ak4641_init_ak(ak);
1411+ snd_ak4641_lock(ak);
1412+ snd_ak4641_power_on(ak);
1413+ if ((ret = snd_ak4641_i2c_attach(ak)) < 0)
1414+ goto failed_i2c_attach;
1415+ snd_ak4641_init_regs(ak);
1416+ if ((ret = snd_ak4641_hp_detected_init(ak)) < 0)
1417+ goto failed_hp_detected_init;
1418+ snd_ak4641_unlock(ak);
1419+ return 0;
1420+
1421+ failed_hp_detected_init:
1422+ snd_ak4641_i2c_detach(ak);
1423+ failed_i2c_attach:
1424+ snd_ak4641_power_off(ak);
1425+ snd_ak4641_unlock(ak);
1426+ return ret;
1427+}
1428+
1429+void snd_ak4641_deactivate(struct snd_ak4641 *ak)
1430+{
1431+ snd_ak4641_lock(ak);
1432+ snd_ak4641_hp_detected_free(ak);
1433+ snd_ak4641_i2c_detach(ak);
1434+ snd_ak4641_power_off(ak);
1435+ snd_ak4641_unlock(ak);
1436+}
1437+
1438+int snd_ak4641_add_mixer_controls(struct snd_ak4641 *ak, struct snd_card *card)
1439+{
1440+ snd_ak4641_lock(ak);
1441+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_playback_volume, ak));
1442+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_playback_switch, ak));
1443+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_mic_gain, ak));
1444+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_mic_boost, ak));
1445+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_mono_out, ak));
1446+ snd_ak4641_unlock(ak);
1447+ return 0;
1448+}
1449+
1450+/* end {{ Codec Control }} */
1451+
1452+
1453+/* begin {{ Module }} */
1454+
1455+static int __init snd_ak4641_module_on_load(void)
1456+{
1457+ snd_ak4641_i2c_init();
1458+ return 0;
1459+}
1460+
1461+static void __exit snd_ak4641_module_on_unload(void)
1462+{
1463+ snd_ak4641_i2c_free();
1464+}
1465+
1466+module_init(snd_ak4641_module_on_load);
1467+module_exit(snd_ak4641_module_on_unload);
1468+
1469+EXPORT_SYMBOL(snd_ak4641_activate);
1470+EXPORT_SYMBOL(snd_ak4641_deactivate);
1471+EXPORT_SYMBOL(snd_ak4641_add_mixer_controls);
1472+EXPORT_SYMBOL(snd_ak4641_open_stream);
1473+EXPORT_SYMBOL(snd_ak4641_close_stream);
1474+EXPORT_SYMBOL(snd_ak4641_suspend);
1475+EXPORT_SYMBOL(snd_ak4641_resume);
1476+EXPORT_SYMBOL(snd_ak4641_hp_connected);
1477+EXPORT_SYMBOL(snd_ak4641_hp_detected);
1478+
1479+MODULE_AUTHOR("Giorgio Padrin");
1480+MODULE_DESCRIPTION("Audio support for codec Asahi Kasei AK4641");
1481+MODULE_LICENSE("GPL");
1482+
1483+/* end {{ Module }} */
1484Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h
1485===================================================================
1486--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1487+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h 2007-09-11 12:53:37.000000000 +0200
1488@@ -0,0 +1,65 @@
1489+/*
1490+ * Audio support for codec Asahi Kasei AK4641
1491+ *
1492+ * This program is free software; you can redistribute it and/or modify
1493+ * it under the terms of the GNU General Public License version 2 as
1494+ * published by the Free Software Foundation.
1495+ *
1496+ * Copyright (c) 2006 Giorgio Padrin <giorgio@mandarinlogiq.org>
1497+ */
1498+
1499+#ifndef __SOUND_AK4641_H
1500+#define __SOUND_AK4641_H
1501+
1502+#include <linux/i2c.h>
1503+
1504+struct snd_ak4641 {
1505+ struct semaphore sem;
1506+
1507+ u8 regs[0x14]; /* registers cache */
1508+
1509+ unsigned int
1510+ powered_on:1,
1511+ playback_on:1,
1512+ playback_stream_opened:1,
1513+ capture_on:1,
1514+ capture_stream_opened:1;
1515+
1516+ unsigned int
1517+ hp_connected:1;
1518+
1519+ /* -- configuration (to fill before activation) -- */
1520+ void (*power_on_chip)(int on);
1521+ void (*reset_pin)(int on);
1522+ void (*headphone_out_on)(int on);
1523+ void (*speaker_out_on)(int on);
1524+
1525+ struct i2c_client i2c_client; /* to fill .adapter */
1526+ /* ----------------------------------------------- */
1527+
1528+ struct {
1529+ int detected;
1530+ struct workqueue_struct *wq;
1531+ struct work_struct w;
1532+ } hp_detected;
1533+};
1534+
1535+
1536+/* Note: opening, closing, suspending and resuming a stream
1537+ * require the clocks (MCLK and I2S ones) running
1538+ */
1539+
1540+/* don't forget to specify I2C adapter in i2c_client field */
1541+int snd_ak4641_activate(struct snd_ak4641 *ak);
1542+
1543+void snd_ak4641_deactivate(struct snd_ak4641 *ak);
1544+int snd_ak4641_add_mixer_controls(struct snd_ak4641 *ak, struct snd_card *card);
1545+int snd_ak4641_open_stream(struct snd_ak4641 *ak, int stream);
1546+int snd_ak4641_close_stream(struct snd_ak4641 *ak, int stream);
1547+int snd_ak4641_suspend(struct snd_ak4641 *ak, pm_message_t state);
1548+int snd_ak4641_resume(struct snd_ak4641 *ak);
1549+
1550+void snd_ak4641_hp_connected(struct snd_ak4641 *ak, int connected); /* non atomic context */
1551+void snd_ak4641_hp_detected(struct snd_ak4641 *ak, int detected); /* atomic context */
1552+
1553+#endif /* __SOUND_AK4641_H */
1554Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c
1555===================================================================
1556--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1557+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c 2007-09-11 12:53:37.000000000 +0200
1558@@ -0,0 +1,143 @@
1559+/*
1560+ * LEDs support for the HP iPaq hx4700
1561+ *
1562+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
1563+ *
1564+ * This file is subject to the terms and conditions of the GNU General Public
1565+ * License. See the file COPYING in the main directory of this archive for
1566+ * more details.
1567+ *
1568+ */
1569+
1570+#include <linux/kernel.h>
1571+#include <linux/init.h>
1572+#include <linux/platform_device.h>
1573+#include <linux/leds.h>
1574+#include <linux/soc/asic3_base.h>
1575+
1576+#include <asm/hardware/ipaq-asic3.h>
1577+#include <asm/mach-types.h>
1578+#include <asm/hardware/asic3_leds.h>
1579+#include <asm/arch/htcuniversal-asic.h>
1580+
1581+//FIXME
1582+//DEFINE_LED_TRIGGER_SHARED_GLOBAL(htcuniversal_radio_trig);
1583+//EXPORT_LED_TRIGGER_SHARED(htcuniversal_radio_trig);
1584+
1585+static struct asic3_led htcuniversal_leds[] = {
1586+ {
1587+ .led_cdev = {
1588+ .name = "htcuniversal:red",
1589+ .default_trigger = "htcuniversal-charging",
1590+ },
1591+ .hw_num = 2,
1592+
1593+ },
1594+ {
1595+ .led_cdev = {
1596+ .name = "htcuniversal:green",
1597+ .default_trigger = "htcuniversal-chargefull",
1598+ },
1599+ .hw_num = 1,
1600+ },
1601+ {
1602+ .led_cdev = {
1603+ .name = "htcuniversal:wifi-bt",
1604+ .default_trigger = "htcuniversal-radio",
1605+ },
1606+ .hw_num = 0,
1607+ },
1608+ {
1609+ .led_cdev = {
1610+ .name = "htcuniversal:phonebuttons",
1611+ .default_trigger = "htcuniversal-phonebuttons",
1612+ },
1613+ .hw_num = -1,
1614+ .gpio_num = ('D'-'A')*16+GPIOD_BL_KEYP_PWR_ON,
1615+ },
1616+ {
1617+ .led_cdev = {
1618+ .name = "htcuniversal:vibra",
1619+ .default_trigger = "htcuniversal-vibra",
1620+ },
1621+ .hw_num = -1,
1622+ .gpio_num = ('D'-'A')*16+GPIOD_VIBRA_PWR_ON,
1623+ },
1624+ {
1625+ .led_cdev = {
1626+ .name = "htcuniversal:flashlight1",
1627+ .default_trigger = "htcuniversal-flashlight1",
1628+ },
1629+ .hw_num = -1,
1630+ .gpio_num = ('A'-'A')*16+GPIOA_FLASHLIGHT,
1631+ },
1632+ {
1633+ .led_cdev = {
1634+ .name = "htcuniversal:kbdbacklight",
1635+ .default_trigger = "htcuniversal-kbdbacklight",
1636+ },
1637+ .hw_num = -1,
1638+ .gpio_num = ('D'-'A')*16+GPIOD_BL_KEYB_PWR_ON,
1639+ },
1640+};
1641+
1642+void htcuniversal_leds_release(struct device *dev)
1643+{
1644+ return;
1645+}
1646+
1647+static
1648+struct asic3_leds_machinfo htcuniversal_leds_machinfo = {
1649+ .num_leds = ARRAY_SIZE(htcuniversal_leds),
1650+ .leds = htcuniversal_leds,
1651+ .asic3_pdev = &htcuniversal_asic3,
1652+};
1653+
1654+static
1655+struct platform_device htcuniversal_leds_pdev = {
1656+ .name = "asic3-leds",
1657+ .dev = {
1658+ .platform_data = &htcuniversal_leds_machinfo,
1659+ .release = htcuniversal_leds_release,
1660+ },
1661+};
1662+
1663+static
1664+int __init htcuniversal_leds_init(void)
1665+{
1666+ int ret;
1667+ printk("htcuniversal LEDs Driver\n");
1668+// led_trigger_register_shared("htcuniversal-radio", &htcuniversal_radio_trig);
1669+
1670+ ret = asic3_leds_register();
1671+ if (ret) goto asic3_leds_failed;
1672+
1673+ ret = platform_device_register(&htcuniversal_leds_pdev);
1674+ if (ret) goto platform_device_failed;
1675+
1676+ goto success;
1677+
1678+platform_device_failed:
1679+ asic3_leds_unregister();
1680+asic3_leds_failed:
1681+// led_trigger_unregister_shared(htcuniversal_radio_trig);
1682+ printk("htcuniversal LEDs Driver failed to init");
1683+success:
1684+ return ret;
1685+}
1686+
1687+static
1688+void __exit htcuniversal_leds_exit(void)
1689+{
1690+// led_trigger_unregister_shared(htcuniversal_radio_trig);
1691+ platform_device_unregister(&htcuniversal_leds_pdev);
1692+ asic3_leds_unregister();
1693+ return;
1694+}
1695+
1696+module_init(htcuniversal_leds_init);
1697+module_exit(htcuniversal_leds_exit);
1698+
1699+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
1700+MODULE_DESCRIPTION("htcuniversal LEDs driver");
1701+MODULE_LICENSE("GPL");
1702Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c
1703===================================================================
1704--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1705+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c 2007-09-11 12:53:37.000000000 +0200
1706@@ -0,0 +1,61 @@
1707+/*
1708+ * Use consistent with the GNU GPL is permitted,
1709+ * provided that this copyright notice is
1710+ * preserved in its entirety in all copies and derived works.
1711+ *
1712+ * Copyright (C) 2006 Paul Sokolosvky
1713+ * Based on code from older versions of htcuniversal_lcd.c
1714+ *
1715+ */
1716+
1717+#include <linux/types.h>
1718+#include <linux/platform_device.h>
1719+#include <asm/arch/hardware.h> /* for pxa-regs.h (__REG) */
1720+#include <asm/arch/pxa-regs.h>
1721+#include <asm/mach-types.h> /* machine_is_htcuniversal */
1722+//#include <linux/corgi_bl.h>
1723+#include <linux/backlight.h>
1724+#include <linux/err.h>
1725+
1726+#include <asm/arch/htcuniversal-gpio.h>
1727+#include <asm/arch/htcuniversal-asic.h>
1728+#include <asm/hardware/ipaq-asic3.h>
1729+#include <linux/soc/asic3_base.h>
1730+
1731+#define HTCUNIVERSAL_MAX_INTENSITY 0xc7
1732+
1733+static void htcuniversal_set_bl_intensity(int intensity)
1734+{
1735+ PWM_CTRL1 = 1; /* pre-scaler */
1736+ PWM_PWDUTY1 = intensity; /* duty cycle */
1737+ PWM_PERVAL1 = HTCUNIVERSAL_MAX_INTENSITY+1; /* period */
1738+
1739+ if (intensity > 0) {
1740+ pxa_set_cken(CKEN_PWM1, 1);
1741+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev,
1742+ (1<<GPIOD_FL_PWR_ON), (1<<GPIOD_FL_PWR_ON));
1743+ } else {
1744+ pxa_set_cken(CKEN_PWM1, 0);
1745+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev,
1746+ (1<<GPIOD_FL_PWR_ON), 0);
1747+ }
1748+}
1749+
1750+
1751+static struct generic_bl_info htcuniversal_bl_machinfo = {
1752+ .default_intensity = HTCUNIVERSAL_MAX_INTENSITY / 4,
1753+ .limit_mask = 0xff,
1754+ .max_intensity = HTCUNIVERSAL_MAX_INTENSITY,
1755+ .set_bl_intensity = htcuniversal_set_bl_intensity,
1756+};
1757+
1758+struct platform_device htcuniversal_bl = {
1759+ .name = "corgi-bl",
1760+ .dev = {
1761+ .platform_data = &htcuniversal_bl_machinfo,
1762+ },
1763+};
1764+
1765+MODULE_AUTHOR("Paul Sokolovsky <pmiscml@gmail.com>");
1766+MODULE_DESCRIPTION("Backlight driver for HTC Universal");
1767+MODULE_LICENSE("GPL");
1768Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c
1769===================================================================
1770--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1771+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c 2007-09-11 12:53:37.000000000 +0200
1772@@ -0,0 +1,135 @@
1773+/* Bluetooth interface driver for TI BRF6150 on HX4700
1774+ *
1775+ * Copyright (c) 2005 SDG Systems, LLC
1776+ *
1777+ * 2005-04-21 Todd Blumer Created.
1778+ */
1779+
1780+#include <linux/module.h>
1781+#include <linux/kernel.h>
1782+#include <linux/delay.h>
1783+#include <linux/platform_device.h>
1784+#include <linux/soc/asic3_base.h>
1785+
1786+#include <asm/hardware.h>
1787+#include <asm/arch/serial.h>
1788+#include <asm/hardware/ipaq-asic3.h>
1789+#include <asm/arch/htcuniversal-gpio.h>
1790+#include <asm/arch/htcuniversal-asic.h>
1791+
1792+#include "htcuniversal_bt.h"
1793+
1794+static uint use_led=1;
1795+
1796+static void
1797+htcuniversal_bt_configure( int state )
1798+{
1799+ int tries;
1800+
1801+ printk( KERN_NOTICE "htcuniversal configure bluetooth: %d\n", state );
1802+ switch (state) {
1803+
1804+ case PXA_UART_CFG_PRE_STARTUP:
1805+ break;
1806+
1807+ case PXA_UART_CFG_POST_STARTUP:
1808+ /* pre-serial-up hardware configuration */
1809+ htcuniversal_egpio_enable(1<<EGPIO5_BT_3V3_ON);
1810+ mdelay(50);
1811+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_PWR_ON, 1<<GPIOC_BT_PWR_ON);
1812+ mdelay(10);
1813+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_RESET, 0);
1814+ mdelay(10);
1815+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_RESET, 1<<GPIOC_BT_RESET);
1816+ mdelay(10);
1817+
1818+ /*
1819+ * BRF6150's RTS goes low when firmware is ready
1820+ * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
1821+ */
1822+ tries = 0;
1823+ do {
1824+ mdelay(10);
1825+ } while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
1826+ if (use_led) {
1827+// htcuniversal_set_led(2, 16, 16);
1828+ }
1829+ break;
1830+
1831+ case PXA_UART_CFG_PRE_SHUTDOWN:
1832+ htcuniversal_egpio_disable(1<<EGPIO5_BT_3V3_ON );
1833+ mdelay(50);
1834+// htcuniversal_clear_led(2);
1835+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_PWR_ON, 0);
1836+ break;
1837+
1838+ default:
1839+ break;
1840+ }
1841+}
1842+
1843+
1844+static int
1845+htcuniversal_bt_probe( struct platform_device *dev )
1846+{
1847+ struct htcuniversal_bt_funcs *funcs = dev->dev.platform_data;
1848+
1849+ /* configure bluetooth UART */
1850+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_RXD_MD );
1851+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_TXD_MD );
1852+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_UART_CTS_MD );
1853+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_UART_RTS_MD );
1854+
1855+ funcs->configure = htcuniversal_bt_configure;
1856+
1857+ /* Make sure the LED is off */
1858+// htcuniversal_clear_led(2);
1859+
1860+ return 0;
1861+}
1862+
1863+static int
1864+htcuniversal_bt_remove( struct platform_device *dev )
1865+{
1866+ struct htcuniversal_bt_funcs *funcs = dev->dev.platform_data;
1867+
1868+ funcs->configure = NULL;
1869+
1870+ /* Make sure the LED is off */
1871+// htcuniversal_clear_led(2);
1872+
1873+ return 0;
1874+}
1875+
1876+static struct platform_driver bt_driver = {
1877+ .driver = {
1878+ .name = "htcuniversal_bt",
1879+ },
1880+ .probe = htcuniversal_bt_probe,
1881+ .remove = htcuniversal_bt_remove,
1882+};
1883+
1884+module_param(use_led, uint, 0);
1885+
1886+static int __init
1887+htcuniversal_bt_init( void )
1888+{
1889+ printk(KERN_NOTICE "htcuniversal Bluetooth Driver\n");
1890+ return platform_driver_register( &bt_driver );
1891+}
1892+
1893+static void __exit
1894+htcuniversal_bt_exit( void )
1895+{
1896+ platform_driver_unregister( &bt_driver );
1897+}
1898+
1899+module_init( htcuniversal_bt_init );
1900+module_exit( htcuniversal_bt_exit );
1901+
1902+MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
1903+MODULE_DESCRIPTION("HTC Universal Bluetooth Support Driver");
1904+MODULE_LICENSE("GPL");
1905+
1906+/* vim600: set noexpandtab sw=8 ts=8 :*/
1907+
1908Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h
1909===================================================================
1910--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1911+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h 2007-09-11 12:53:37.000000000 +0200
1912@@ -0,0 +1,17 @@
1913+/*
1914+ * Bluetooth support file for calling bluetooth configuration functions
1915+ *
1916+ * Copyright (c) 2005 SDG Systems, LLC
1917+ *
1918+ * 2005-06 Todd Blumer Initial Revision
1919+ */
1920+
1921+#ifndef _HTCUNIVERSAL_BT_H
1922+#define _HTCUNIVERSAL_BT_H
1923+
1924+struct htcuniversal_bt_funcs {
1925+ void (*configure) ( int state );
1926+};
1927+
1928+
1929+#endif
1930Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c
1931===================================================================
1932--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1933+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c 2007-09-11 12:53:37.000000000 +0200
1934@@ -0,0 +1,87 @@
1935+/*
1936+ * Buttons driver for HTC Universal
1937+ *
1938+ * This file is subject to the terms and conditions of the GNU General Public
1939+ * License.
1940+ *
1941+ * Copyright (C) 2005 Pawel Kolodziejski
1942+ * Copyright (C) 2003 Joshua Wise
1943+ *
1944+ */
1945+
1946+#include <linux/input.h>
1947+#include <linux/input_pda.h>
1948+#include <linux/module.h>
1949+#include <linux/init.h>
1950+#include <linux/interrupt.h>
1951+#include <linux/irq.h>
1952+#include <linux/platform_device.h>
1953+#include <linux/gpio_keys.h>
1954+#include <linux/soc/asic3_base.h>
1955+#include <asm/mach-types.h>
1956+#include <asm/hardware/asic3_keys.h>
1957+#include <asm/arch/htcuniversal-gpio.h>
1958+#include <asm/arch/htcuniversal-asic.h>
1959+
1960+static struct asic3_keys_button asic3_buttons[] = {
1961+//{KEY_SCREEN, ASIC3_GPIOA_IRQ_BASE+GPIOA_COVER_ROTATE_N, 1, "screen_cover", EV_SW},
1962+//{KEY_SWITCHVIDEOMODE, ASIC3_GPIOB_IRQ_BASE+GPIOB_CLAMSHELL_N, 1, "clamshell_rotate", EV_SW},
1963+//{KEY_KBDILLUMTOGGLE, ASIC3_GPIOB_IRQ_BASE+GPIOB_NIGHT_SENSOR, 1, "night_sensor", EV_SW},
1964+{SW_LID, ASIC3_GPIOA_IRQ_BASE+GPIOA_COVER_ROTATE_N, 1, "screen_cover", EV_SW},
1965+{SW_TABLET_MODE, ASIC3_GPIOB_IRQ_BASE+GPIOB_CLAMSHELL_N, 1, "clamshell_rotate", EV_SW},
1966+//{SW_NIGHT_SENSOR, ASIC3_GPIOB_IRQ_BASE+GPIOB_NIGHT_SENSOR, 1, "night_sensor", EV_SW},
1967+{KEY_F10, ASIC3_GPIOA_IRQ_BASE+GPIOA_BUTTON_BACKLIGHT_N, 1, "backlight_button"},
1968+{KEY_RECORD, ASIC3_GPIOA_IRQ_BASE+GPIOA_BUTTON_RECORD_N, 1, "record_button"},
1969+{KEY_CAMERA, ASIC3_GPIOA_IRQ_BASE+GPIOA_BUTTON_CAMERA_N, 1, "camera_button"},
1970+{KEY_VOLUMEDOWN, ASIC3_GPIOA_IRQ_BASE+GPIOA_VOL_UP_N, 1, "volume_slider_down"},
1971+{KEY_VOLUMEUP, ASIC3_GPIOA_IRQ_BASE+GPIOA_VOL_DOWN_N, 1, "volume_slider_up"},
1972+{KEY_KPENTER, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_OK_N, 1, "select"},
1973+{KEY_RIGHT, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_RIGHT_N, 1, "right"},
1974+{KEY_LEFT, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_LEFT_N, 1, "left"},
1975+{KEY_DOWN, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_DOWN_N, 1, "down"},
1976+{KEY_UP, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_UP_N, 1, "up"},
1977+};
1978+
1979+static struct asic3_keys_platform_data asic3_keys_data = {
1980+ .buttons = asic3_buttons,
1981+ .nbuttons = ARRAY_SIZE(asic3_buttons),
1982+ .asic3_dev = &htcuniversal_asic3.dev,
1983+};
1984+
1985+static struct platform_device htcuniversal_keys_asic3 = {
1986+ .name = "asic3-keys",
1987+ .dev = { .platform_data = &asic3_keys_data, }
1988+};
1989+
1990+static int __init htcuniversal_buttons_probe(struct platform_device *dev)
1991+{
1992+ platform_device_register(&htcuniversal_keys_asic3);
1993+ return 0;
1994+}
1995+
1996+static struct platform_driver htcuniversal_buttons_driver = {
1997+ .driver = {
1998+ .name = "htcuniversal_buttons",
1999+ },
2000+ .probe = htcuniversal_buttons_probe,
2001+};
2002+
2003+static int __init htcuniversal_buttons_init(void)
2004+{
2005+ if (!machine_is_htcuniversal())
2006+ return -ENODEV;
2007+
2008+ return platform_driver_register(&htcuniversal_buttons_driver);
2009+}
2010+
2011+static void __exit htcuniversal_buttons_exit(void)
2012+{
2013+ platform_driver_unregister(&htcuniversal_buttons_driver);
2014+}
2015+
2016+module_init(htcuniversal_buttons_init);
2017+module_exit(htcuniversal_buttons_exit);
2018+
2019+MODULE_AUTHOR ("Joshua Wise, Pawel Kolodziejski, Paul Sokolosvky");
2020+MODULE_DESCRIPTION ("Buttons support for HTC Universal");
2021+MODULE_LICENSE ("GPL");
2022Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c
2023===================================================================
2024--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2025+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c 2007-09-11 12:53:37.000000000 +0200
2026@@ -0,0 +1,226 @@
2027+/* Core Hardware driver for Hx4700 (Serial, ASIC3, EGPIOs)
2028+ *
2029+ * Copyright (c) 2005 SDG Systems, LLC
2030+ *
2031+ * 2005-03-29 Todd Blumer Converted basic structure to support hx4700
2032+ * 2005-04-30 Todd Blumer Add IRDA code from H2200
2033+ */
2034+
2035+#include <linux/module.h>
2036+#include <linux/version.h>
2037+#include <linux/interrupt.h>
2038+#include <linux/platform_device.h>
2039+#include <linux/delay.h>
2040+#include <linux/pm.h>
2041+#include <linux/irq.h>
2042+
2043+#include <asm/io.h>
2044+#include <asm/mach/irq.h>
2045+#include <asm/arch/pxa-regs.h>
2046+#include <asm/arch/pxa-pm_ll.h>
2047+#include <asm/arch/htcuniversal-gpio.h>
2048+#include <asm/arch/htcuniversal-asic.h>
2049+
2050+#include <linux/soc/asic3_base.h>
2051+#include <asm/hardware/ipaq-asic3.h>
2052+
2053+volatile u_int16_t *egpios;
2054+u_int16_t egpio_reg;
2055+
2056+static int htc_bootloader = 0; /* Is the stock HTC bootloader installed? */
2057+
2058+/*
2059+ * may make sense to put egpios elsewhere, but they're here now
2060+ * since they share some of the same address space with the TI WLAN
2061+ *
2062+ * EGPIO register is write-only
2063+ */
2064+
2065+void
2066+htcuniversal_egpio_enable( u_int16_t bits )
2067+{
2068+ unsigned long flags;
2069+
2070+ local_irq_save(flags);
2071+
2072+ egpio_reg |= bits;
2073+ *egpios = egpio_reg;
2074+
2075+ local_irq_restore(flags);
2076+}
2077+EXPORT_SYMBOL_GPL(htcuniversal_egpio_enable);
2078+
2079+void
2080+htcuniversal_egpio_disable( u_int16_t bits )
2081+{
2082+ unsigned long flags;
2083+
2084+ local_irq_save(flags);
2085+
2086+ egpio_reg &= ~bits;
2087+ *egpios = egpio_reg;
2088+
2089+ local_irq_restore(flags);
2090+}
2091+EXPORT_SYMBOL_GPL(htcuniversal_egpio_disable);
2092+
2093+#ifdef CONFIG_PM
2094+
2095+//void htcuniversal_ll_pm_init(void);
2096+
2097+static int htcuniversal_suspend(struct platform_device *dev, pm_message_t state)
2098+{
2099+ /* Turn off external clocks here, because htcuniversal_power and asic3_mmc
2100+ * scared to do so to not hurt each other. (-5 mA) */
2101+
2102+
2103+ /* 0x20c2 is HTC clock value
2104+ * CLOCK_CDEX_SOURCE 2
2105+ * CLOCK_CDEX_SPI 0
2106+ * CLOCK_CDEX_OWM 0
2107+ *
2108+ * CLOCK_CDEX_PWM0 0
2109+ * CLOCK_CDEX_PWM1 0
2110+ * CLOCK_CDEX_LED0 1
2111+ * CLOCK_CDEX_LED1 1
2112+ *
2113+ * CLOCK_CDEX_LED2 0
2114+ * CLOCK_CDEX_SD_HOST 0
2115+ * CLOCK_CDEX_SD_BUS 0
2116+ * CLOCK_CDEX_SMBUS 0
2117+ *
2118+ * CLOCK_CDEX_CONTROL_CX 0
2119+ * CLOCK_CDEX_EX0 1
2120+ * CLOCK_CDEX_EX1 0
2121+ * */
2122+ asic3_set_clock_cdex(&htcuniversal_asic3.dev, 0xffff, CLOCK_CDEX_SOURCE1
2123+ |CLOCK_CDEX_LED0
2124+ |CLOCK_CDEX_LED1
2125+ |CLOCK_CDEX_LED2
2126+ |CLOCK_CDEX_EX0
2127+ |CLOCK_CDEX_EX1);
2128+
2129+ *egpios = 0; /* turn off all egpio power */
2130+
2131+ /* Wake up enable. */
2132+ PWER = PWER_GPIO0
2133+ | PWER_GPIO1 /* reset */
2134+ | PWER_GPIO9 /* USB */
2135+ | PWER_GPIO10 /* AC on USB */
2136+ | PWER_GPIO14 /* ASIC3 mux */
2137+ | PWER_RTC;
2138+ /* Wake up on falling edge. */
2139+ PFER = PWER_GPIO0
2140+ | PWER_GPIO1
2141+ | PWER_GPIO9
2142+ | PWER_GPIO10
2143+ | PWER_GPIO14;
2144+
2145+ /* Wake up on rising edge. */
2146+ PRER = PWER_GPIO0
2147+ | PWER_GPIO1
2148+ | PWER_GPIO9
2149+ | PWER_GPIO10;
2150+ /* 3.6864 MHz oscillator power-down enable */
2151+ PCFR = PCFR_OPDE | PCFR_PI2CEN | PCFR_GPROD | PCFR_GPR_EN;
2152+
2153+ PGSR0 = 0x09088004;
2154+ PGSR1 = 0x00020002;
2155+ PGSR2 = 0x8001c000;
2156+ PGSR3 = 0x00106284;
2157+
2158+ PSLR = 0xcc000000;
2159+
2160+#if 0
2161+ /*
2162+ * If we're using bootldr and not the stock HTC bootloader,
2163+ * we want to wake up periodically to see if the charge is full while
2164+ * it is suspended. We do this with the OS timer 4 in the pxa270.
2165+ */
2166+ if (!htc_bootloader) {
2167+ OMCR4 = 0x4b; /* Periodic, self-resetting, 1-second timer */
2168+ OSMR4 = 5; /* Wake up bootldr after x seconds so it can
2169+ figure out what to do with the LEDs. */
2170+ OIER |= 0x10; /* Enable interrupt source for Timer 4 */
2171+ OSCR4 = 0; /* This starts the timer */
2172+ }
2173+#endif
2174+
2175+ asic3_set_extcf_select(&htcuniversal_asic3.dev, ASIC3_EXTCF_OWM_EN, 0);
2176+
2177+ return 0;
2178+}
2179+
2180+static int htcuniversal_resume(struct platform_device *dev)
2181+{
2182+ htcuniversal_egpio_enable(0);
2183+
2184+ return 0;
2185+}
2186+#else
2187+# define htcuniversal_suspend NULL
2188+# define htcuniversal_resume NULL
2189+#endif
2190+
2191+static int
2192+htcuniversal_core_probe( struct platform_device *dev )
2193+{
2194+
2195+ printk( KERN_NOTICE "HTC Universal Core Hardware Driver\n" );
2196+
2197+ egpios = (volatile u_int16_t *)ioremap_nocache(HTCUNIVERSAL_EGPIO_BASE, sizeof *egpios );
2198+ if (!egpios)
2199+ return -ENODEV;
2200+ else
2201+ printk( KERN_NOTICE "HTC Universal Core: egpio at phy=0x%8.8x is at virt=0x%p\n",
2202+ HTCUNIVERSAL_EGPIO_BASE, egpios );
2203+
2204+ printk("Using stock HTC first stage bootloader\n");
2205+ htc_bootloader = 1;
2206+
2207+// htcuniversal_ll_pm_init();
2208+
2209+ return 0;
2210+}
2211+
2212+static int
2213+htcuniversal_core_remove( struct platform_device *dev )
2214+{
2215+
2216+ if (egpios != NULL)
2217+ iounmap( (void *)egpios );
2218+
2219+ return 0;
2220+}
2221+
2222+static struct platform_driver htcuniversal_core_driver = {
2223+ .driver = {
2224+ .name = "htcuniversal_core",
2225+ },
2226+ .probe = htcuniversal_core_probe,
2227+ .remove = htcuniversal_core_remove,
2228+ .suspend = htcuniversal_suspend,
2229+ .resume = htcuniversal_resume,
2230+};
2231+
2232+static int __init
2233+htcuniversal_core_init( void )
2234+{
2235+ return platform_driver_register( &htcuniversal_core_driver );
2236+}
2237+
2238+
2239+static void __exit
2240+htcuniversal_core_exit( void )
2241+{
2242+ platform_driver_unregister( &htcuniversal_core_driver );
2243+}
2244+
2245+module_init( htcuniversal_core_init );
2246+module_exit( htcuniversal_core_exit );
2247+
2248+MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
2249+MODULE_DESCRIPTION("HTC Universal Core Hardware Driver");
2250+MODULE_LICENSE("GPL");
2251+
2252+/* vim600: set noexpandtab sw=8 ts=8 :*/
2253Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c
2254===================================================================
2255--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2256+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c 2007-09-11 12:53:37.000000000 +0200
2257@@ -0,0 +1,212 @@
2258+/*
2259+ * Use consistent with the GNU GPL is permitted,
2260+ * provided that this copyright notice is
2261+ * preserved in its entirety in all copies and derived works.
2262+ *
2263+ * History:
2264+ *
2265+ * 2004-03-01 Eddi De Pieri Adapted for htcuniversal using h3900_lcd.c
2266+ * 2004 Shawn Anderson Lcd hacking on htcuniversal
2267+ * see h3900_lcd.c for more history.
2268+ *
2269+ */
2270+
2271+#include <linux/types.h>
2272+#include <asm/arch/hardware.h> /* for pxa-regs.h (__REG) */
2273+#include <linux/platform_device.h>
2274+#include <asm/arch/pxa-regs.h> /* LCCR[0,1,2,3]* */
2275+#include <asm/arch/bitfield.h> /* for pxa-regs.h (Fld, etc) */
2276+#include <asm/arch/pxafb.h> /* pxafb_mach_info, set_pxa_fb_info */
2277+#include <asm/mach-types.h> /* machine_is_htcuniversal */
2278+#include <linux/lcd.h> /* lcd_device */
2279+#include <linux/err.h>
2280+#include <linux/delay.h>
2281+
2282+#include <asm/arch/htcuniversal-gpio.h>
2283+#include <asm/arch/htcuniversal-asic.h>
2284+#include <asm/hardware/ipaq-asic3.h>
2285+#include <linux/soc/asic3_base.h>
2286+
2287+static int saved_lcdpower=-1;
2288+
2289+static int powerup_lcd(void)
2290+{
2291+ printk( KERN_INFO "htcuniversal powerup_lcd: called\n");
2292+
2293+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 0);
2294+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 0);
2295+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 0);
2296+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 0);
2297+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 0);
2298+#if 1
2299+ LCCR4|=LCCR4_PCDDIV;
2300+#endif
2301+ pxa_set_cken(CKEN_LCD, 0);
2302+
2303+ mdelay(100);
2304+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 1<<GPIOA_LCD_PWR5_ON);
2305+ mdelay(5);
2306+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 1<<GPIOB_LCD_PWR3_ON);
2307+ mdelay(2);
2308+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 1<<GPIOC_LCD_PWR1_ON);
2309+ mdelay(2);
2310+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 1<<GPIOC_LCD_PWR2_ON);
2311+ mdelay(20);
2312+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 1<<GPIOD_LCD_PWR4_ON);
2313+ mdelay(1);
2314+ pxa_set_cken(CKEN_LCD, 1);
2315+
2316+ SET_HTCUNIVERSAL_GPIO(LCD1,1);
2317+ SET_HTCUNIVERSAL_GPIO(LCD2,1);
2318+ return 0;
2319+}
2320+
2321+static int powerdown_lcd(void)
2322+{
2323+ printk( KERN_INFO "htcuniversal powerdown_lcd: called\n");
2324+
2325+#if 1
2326+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 0);
2327+ mdelay(100);
2328+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 0);
2329+ mdelay(10);
2330+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 0);
2331+ mdelay(1);
2332+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 0);
2333+ mdelay(1);
2334+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 0);
2335+ pxa_set_cken(CKEN_LCD, 0);
2336+
2337+ SET_HTCUNIVERSAL_GPIO(LCD1,0);
2338+ SET_HTCUNIVERSAL_GPIO(LCD2,0);
2339+#else
2340+ pxa_set_cken(CKEN_LCD, 0);
2341+
2342+ SET_HTCUNIVERSAL_GPIO(LCD1,0);
2343+ SET_HTCUNIVERSAL_GPIO(LCD2,0);
2344+
2345+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 0);
2346+ mdelay(100);
2347+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 0);
2348+ mdelay(10);
2349+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 0);
2350+ mdelay(1);
2351+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 0);
2352+ mdelay(1);
2353+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 0);
2354+#endif
2355+ return 0;
2356+}
2357+
2358+static int htcuniversal_lcd_set_power(struct lcd_device *lm, int power)
2359+{
2360+ /* Enable or disable power to the LCD (0: on; 4: off) */
2361+
2362+ if ( power < 1 ) {
2363+
2364+ powerup_lcd();
2365+
2366+ } else {
2367+
2368+ powerdown_lcd();
2369+
2370+ }
2371+
2372+ saved_lcdpower=power;
2373+
2374+ return 0;
2375+}
2376+
2377+static int htcuniversal_lcd_get_power(struct lcd_device *lm)
2378+{
2379+ /* Get the LCD panel power status (0: full on, 1..3: controller
2380+ * power on, flat panel power off, 4: full off) */
2381+
2382+ if (saved_lcdpower == -1)
2383+ {
2384+ htcuniversal_lcd_set_power(lm, 4);
2385+ saved_lcdpower=4;
2386+ }
2387+
2388+ return saved_lcdpower;
2389+}
2390+
2391+static struct lcd_ops htcuniversal_lcd_properties =
2392+{
2393+ .get_power = htcuniversal_lcd_get_power,
2394+ .set_power = htcuniversal_lcd_set_power,
2395+};
2396+
2397+static struct lcd_device *htcuniversal_lcd_dev;
2398+
2399+static int htcuniversal_lcd_probe(struct platform_device * dev)
2400+{
2401+ htcuniversal_lcd_dev = lcd_device_register("pxa2xx-fb", &dev->dev, NULL,
2402+ &htcuniversal_lcd_properties);
2403+ if (IS_ERR(htcuniversal_lcd_dev)) {
2404+ printk("htcuniversal_lcd_probe: error registering devices\n");
2405+ return -1;
2406+ }
2407+
2408+ return 0;
2409+}
2410+
2411+static int htcuniversal_lcd_remove(struct platform_device * dev)
2412+{
2413+ htcuniversal_lcd_set_power(htcuniversal_lcd_dev, 4);
2414+ lcd_device_unregister(htcuniversal_lcd_dev);
2415+
2416+ return 0;
2417+}
2418+
2419+static int htcuniversal_lcd_suspend(struct platform_device * dev, pm_message_t state)
2420+{
2421+// printk("htcuniversal_lcd_suspend: called.\n");
2422+ htcuniversal_lcd_set_power(htcuniversal_lcd_dev, 4);
2423+ return 0;
2424+}
2425+
2426+static int htcuniversal_lcd_resume(struct platform_device * dev)
2427+{
2428+// printk("htcuniversal_lcd_resume: called.\n");
2429+
2430+ /* */
2431+#if 1
2432+ LCCR4|=LCCR4_PCDDIV;
2433+#endif
2434+
2435+ htcuniversal_lcd_set_power(htcuniversal_lcd_dev, 0);
2436+ return 0;
2437+}
2438+
2439+static struct platform_driver htcuniversal_lcd_driver = {
2440+ .driver = {
2441+ .name = "htcuniversal_lcd",
2442+ },
2443+ .probe = htcuniversal_lcd_probe,
2444+ .remove = htcuniversal_lcd_remove,
2445+ .suspend = htcuniversal_lcd_suspend,
2446+ .resume = htcuniversal_lcd_resume,
2447+};
2448+
2449+static int htcuniversal_lcd_init(void)
2450+{
2451+ if (!machine_is_htcuniversal())
2452+ return -ENODEV;
2453+
2454+ return platform_driver_register(&htcuniversal_lcd_driver);
2455+}
2456+
2457+static void htcuniversal_lcd_exit(void)
2458+{
2459+ lcd_device_unregister(htcuniversal_lcd_dev);
2460+ platform_driver_unregister(&htcuniversal_lcd_driver);
2461+}
2462+
2463+module_init(htcuniversal_lcd_init);
2464+module_exit(htcuniversal_lcd_exit);
2465+
2466+MODULE_AUTHOR("xanadux.org");
2467+MODULE_DESCRIPTION("Framebuffer driver for HTC Universal");
2468+MODULE_LICENSE("GPL");
2469+
2470Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c
2471===================================================================
2472--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2473+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c 2007-09-11 12:53:37.000000000 +0200
2474@@ -0,0 +1,167 @@
2475+
2476+/* Phone interface driver for Qualcomm MSM6250 on HTC Universal
2477+ *
2478+ * Copyright (c) 2005 SDG Systems, LLC
2479+ *
2480+ * 2005-04-21 Todd Blumer Created.
2481+ */
2482+
2483+#include <linux/module.h>
2484+#include <linux/kernel.h>
2485+#include <linux/delay.h>
2486+#include <linux/platform_device.h>
2487+#include <linux/soc/asic3_base.h>
2488+
2489+#include <asm/hardware.h>
2490+#include <asm/arch/serial.h>
2491+#include <asm/hardware/ipaq-asic3.h>
2492+#include <asm/arch/htcuniversal-gpio.h>
2493+#include <asm/arch/htcuniversal-asic.h>
2494+
2495+#include "htcuniversal_phone.h"
2496+
2497+static void phone_reset(void)
2498+{
2499+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_RESET2, 0);
2500+
2501+ SET_HTCUNIVERSAL_GPIO(PHONE_RESET,0);
2502+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 0);
2503+ mdelay(1);
2504+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 1<<GPIOD_BB_RESET1);
2505+ mdelay(20);
2506+ SET_HTCUNIVERSAL_GPIO(PHONE_RESET,1);
2507+ mdelay(200);
2508+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 0);
2509+}
2510+
2511+static void phone_off(void)
2512+{
2513+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 1<<GPIOD_BB_RESET1);
2514+ mdelay(2000);
2515+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 0);
2516+
2517+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_RESET2, 1<<GPIOB_BB_RESET2);
2518+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,0);
2519+}
2520+
2521+static void
2522+htcuniversal_phone_configure( int state )
2523+{
2524+ int tries;
2525+ unsigned short statusb;
2526+
2527+ printk( KERN_NOTICE "htcuniversal configure phone: %d\n", state );
2528+ switch (state) {
2529+
2530+ case PXA_UART_CFG_PRE_STARTUP:
2531+ break;
2532+
2533+ case PXA_UART_CFG_POST_STARTUP:
2534+ /* pre-serial-up hardware configuration */
2535+
2536+ SET_HTCUNIVERSAL_GPIO(PHONE_START,0); /* "bootloader" */
2537+ SET_HTCUNIVERSAL_GPIO(PHONE_UNKNOWN,0); /* not used */
2538+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,0); /* PHONE_OFF */
2539+
2540+ phone_reset();
2541+
2542+ SET_HTCUNIVERSAL_GPIO(PHONE_START,1); /* phone */
2543+
2544+ phone_reset();
2545+
2546+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_READY, 0);
2547+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_UNKNOWN3, 0);
2548+
2549+ /*
2550+ */
2551+ tries = 0;
2552+ do {
2553+ mdelay(10);
2554+ statusb = asic3_get_gpio_status_b( &htcuniversal_asic3.dev );
2555+ } while ( (statusb & (1<<GPIOB_UMTS_DCD)) == 0 && tries++ < 200);
2556+
2557+ printk("UMTS_DCD tries=%d of 200\n",tries);
2558+
2559+ tries = 0;
2560+ do {
2561+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,1);
2562+ mdelay(10);
2563+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,0);
2564+ mdelay(20);
2565+ statusb = asic3_get_gpio_status_b( &htcuniversal_asic3.dev );
2566+ } while ( (statusb & (1<<GPIOB_BB_READY)) == 0 && tries++ < 200);
2567+
2568+ printk("BB_READY tries=%d of 200\n",tries);
2569+
2570+ break;
2571+
2572+ case PXA_UART_CFG_PRE_SHUTDOWN:
2573+
2574+ phone_off();
2575+
2576+ break;
2577+
2578+ default:
2579+ break;
2580+ }
2581+}
2582+
2583+
2584+static int
2585+htcuniversal_phone_probe( struct platform_device *dev )
2586+{
2587+ struct htcuniversal_phone_funcs *funcs = dev->dev.platform_data;
2588+
2589+ /* configure phone UART */
2590+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_RXD_MD );
2591+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_TXD_MD );
2592+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_UART_CTS_MD );
2593+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_UART_RTS_MD );
2594+
2595+ funcs->configure = htcuniversal_phone_configure;
2596+
2597+ return 0;
2598+}
2599+
2600+static int
2601+htcuniversal_phone_remove( struct platform_device *dev )
2602+{
2603+ struct htcuniversal_phone_funcs *funcs = dev->dev.platform_data;
2604+
2605+ funcs->configure = NULL;
2606+
2607+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_READY, 1<<GPIOB_BB_READY);
2608+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_UNKNOWN3, 1<<GPIOB_BB_UNKNOWN3);
2609+
2610+ return 0;
2611+}
2612+
2613+static struct platform_driver phone_driver = {
2614+ .driver = {
2615+ .name = "htcuniversal_phone",
2616+ },
2617+ .probe = htcuniversal_phone_probe,
2618+ .remove = htcuniversal_phone_remove,
2619+};
2620+
2621+static int __init
2622+htcuniversal_phone_init( void )
2623+{
2624+ printk(KERN_NOTICE "htcuniversal Phone Driver\n");
2625+ return platform_driver_register( &phone_driver );
2626+}
2627+
2628+static void __exit
2629+htcuniversal_phone_exit( void )
2630+{
2631+ platform_driver_unregister( &phone_driver );
2632+}
2633+
2634+module_init( htcuniversal_phone_init );
2635+module_exit( htcuniversal_phone_exit );
2636+
2637+MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
2638+MODULE_DESCRIPTION("HTC Universal Phone Support Driver");
2639+MODULE_LICENSE("GPL");
2640+
2641+/* vim600: set noexpandtab sw=8 ts=8 :*/
2642Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h
2643===================================================================
2644--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2645+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h 2007-09-11 12:53:37.000000000 +0200
2646@@ -0,0 +1,16 @@
2647+/*
2648+ * Bluetooth support file for calling bluetooth configuration functions
2649+ *
2650+ * Copyright (c) 2005 SDG Systems, LLC
2651+ *
2652+ * 2005-06 Todd Blumer Initial Revision
2653+ */
2654+
2655+#ifndef _HTCUNIVERSAL_PHONE_H
2656+#define _HTCUNIVERSAL_PHONE_H
2657+
2658+struct htcuniversal_phone_funcs {
2659+ void (*configure) ( int state );
2660+};
2661+
2662+#endif
2663Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c
2664===================================================================
2665--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2666+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c 2007-09-11 12:53:37.000000000 +0200
2667@@ -0,0 +1,69 @@
2668+/*
2669+ * MyPal 716 power management support for the original HTC IPL in DoC G3
2670+ *
2671+ * Use consistent with the GNU GPL is permitted, provided that this
2672+ * copyright notice is preserved in its entirety in all copies and
2673+ * derived works.
2674+ *
2675+ * Copyright (C) 2005 Pawel Kolodziejski
2676+ *
2677+ */
2678+
2679+#include <linux/kernel.h>
2680+#include <linux/module.h>
2681+#include <linux/device.h>
2682+#include <linux/pm.h>
2683+
2684+#include <asm/mach-types.h>
2685+#include <asm/hardware.h>
2686+#include <asm/arch/pxa-regs.h>
2687+#include <asm/arch/pxa-pm_ll.h>
2688+
2689+#ifdef CONFIG_PM
2690+
2691+static u32 *addr_a0040000;
2692+static u32 *addr_a0040004;
2693+static u32 *addr_a0040008;
2694+static u32 *addr_a004000c;
2695+
2696+static u32 save_a0040000;
2697+static u32 save_a0040004;
2698+static u32 save_a0040008;
2699+static u32 save_a004000c;
2700+
2701+static void htcuniversal_pxa_ll_pm_suspend(unsigned long resume_addr)
2702+{
2703+ save_a0040000 = *addr_a0040000;
2704+ save_a0040004 = *addr_a0040004;
2705+ save_a0040008 = *addr_a0040008;
2706+ save_a004000c = *addr_a004000c;
2707+
2708+ /* jump to PSPR */
2709+ *addr_a0040000 = 0xe3a00101; // mov r0, #0x40000000
2710+ *addr_a0040004 = 0xe380060f; // orr r0, r0, #0x0f000000
2711+ *addr_a0040008 = 0xe3800008; // orr r0, r0, #8
2712+ *addr_a004000c = 0xe590f000; // ldr pc, [r0]
2713+}
2714+
2715+static void htcuniversal_pxa_ll_pm_resume(void)
2716+{
2717+ *addr_a0040000 = save_a0040000;
2718+ *addr_a0040004 = save_a0040004;
2719+ *addr_a0040008 = save_a0040008;
2720+ *addr_a004000c = save_a004000c;
2721+}
2722+
2723+static struct pxa_ll_pm_ops htcuniversal_ll_pm_ops = {
2724+ .suspend = htcuniversal_pxa_ll_pm_suspend,
2725+ .resume = htcuniversal_pxa_ll_pm_resume,
2726+};
2727+
2728+void htcuniversal_ll_pm_init(void) {
2729+ addr_a0040000 = phys_to_virt(0xa0040000);
2730+ addr_a0040004 = phys_to_virt(0xa0040004);
2731+ addr_a0040008 = phys_to_virt(0xa0040008);
2732+ addr_a004000c = phys_to_virt(0xa004000c);
2733+
2734+ pxa_pm_set_ll_ops(&htcuniversal_ll_pm_ops);
2735+}
2736+#endif /* CONFIG_PM */
2737Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c
2738===================================================================
2739--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2740+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c 2007-09-11 12:53:37.000000000 +0200
2741@@ -0,0 +1,97 @@
2742+/*
2743+ * pda_power driver for HTC Universal
2744+ *
2745+ * This program is free software; you can redistribute it and/or modify
2746+ * it under the terms of the GNU General Public License as published by
2747+ * the Free Software Foundation; either version 2 of the License, or (at
2748+ * your option) any later version.
2749+ *
2750+ */
2751+
2752+#include <linux/platform_device.h>
2753+#include <linux/module.h>
2754+#include <linux/pda_power.h>
2755+#include <linux/soc/asic3_base.h>
2756+
2757+#include <asm/mach-types.h>
2758+#include <asm/hardware.h>
2759+#include <asm/arch/htcuniversal-gpio.h>
2760+#include <asm/arch/htcuniversal-asic.h>
2761+
2762+static void charge_on(int flags)
2763+{
2764+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_CHARGE_EN, 0);
2765+}
2766+
2767+static int ac_on(void)
2768+{
2769+ return (GET_HTCUNIVERSAL_GPIO(POWER_DET) == 0);
2770+}
2771+
2772+static int usb_on(void)
2773+{
2774+ return (GET_HTCUNIVERSAL_GPIO(USB_DET) == 0);
2775+}
2776+
2777+static char *supplicants[] = {
2778+ "ds2760-battery.0", "backup-battery"
2779+};
2780+
2781+static struct pda_power_pdata power_pdata = {
2782+ .is_ac_online = ac_on,
2783+ .is_usb_online = usb_on,
2784+ .set_charge = charge_on,
2785+ .supplied_to = supplicants,
2786+ .num_supplicants = ARRAY_SIZE(supplicants),
2787+};
2788+
2789+static struct resource power_resources[] = {
2790+ [0] = {
2791+ .name = "ac",
2792+ .start = HTCUNIVERSAL_IRQ(POWER_DET),
2793+ .end = HTCUNIVERSAL_IRQ(POWER_DET),
2794+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
2795+ },
2796+ [1] = {
2797+ .name = "usb",
2798+ .start = HTCUNIVERSAL_IRQ(USB_DET),
2799+ .end = HTCUNIVERSAL_IRQ(USB_DET),
2800+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
2801+ },
2802+};
2803+
2804+static void dev_release(struct device *dev)
2805+{
2806+ return;
2807+}
2808+
2809+static struct platform_device power_dev =
2810+{
2811+ .name = "pda-power",
2812+ .id = -1,
2813+ .resource = power_resources,
2814+ .num_resources = ARRAY_SIZE(power_resources),
2815+ .dev =
2816+ {
2817+ .platform_data = &power_pdata,
2818+ .release = dev_release,
2819+ },
2820+};
2821+
2822+static int htcuniversal_power_init(void)
2823+{
2824+ return platform_device_register(&power_dev);
2825+}
2826+
2827+static void htcuniversal_power_exit(void)
2828+{
2829+ platform_device_unregister(&power_dev);
2830+
2831+ return;
2832+}
2833+
2834+module_init(htcuniversal_power_init);
2835+module_exit(htcuniversal_power_exit);
2836+
2837+MODULE_DESCRIPTION("Power driver for HTC Universal");
2838+MODULE_LICENSE("GPL");
2839Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c
2840===================================================================
2841--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2842+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c 2007-09-11 12:53:37.000000000 +0200
2843@@ -0,0 +1,490 @@
2844+/* Touch screen driver for the TI something-or-other
2845+ *
2846+ * Copyright © 2005 SDG Systems, LLC
2847+ *
2848+ * Based on code that was based on the SAMCOP driver.
2849+ * Copyright © 2003, 2004 Compaq Computer Corporation.
2850+ *
2851+ * Use consistent with the GNU GPL is permitted,
2852+ * provided that this copyright notice is
2853+ * preserved in its entirety in all copies and derived works.
2854+ *
2855+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
2856+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
2857+ * FITNESS FOR ANY PARTICULAR PURPOSE.
2858+ *
2859+ * Author: Keith Packard <keith.packard@hp.com>
2860+ * May 2003
2861+ *
2862+ * Updates:
2863+ *
2864+ * 2004-02-11 Michael Opdenacker Renamed names from samcop to shamcop,
2865+ * Goal:support HAMCOP and SAMCOP.
2866+ * 2004-02-14 Michael Opdenacker Temporary fix for device id handling
2867+ *
2868+ * 2005-02-18 Aric Blumer Converted basic structure to support hx4700
2869+ *
2870+ * 2005-06-07 Aric Blumer Added tssim device handling so we can
2871+ * hook in the fbvncserver.
2872+ */
2873+
2874+#include <linux/module.h>
2875+#include <linux/version.h>
2876+
2877+#include <linux/init.h>
2878+#include <linux/fs.h>
2879+#include <linux/cdev.h>
2880+#include <linux/interrupt.h>
2881+#include <linux/sched.h>
2882+#include <linux/pm.h>
2883+#include <linux/delay.h>
2884+#include <linux/input.h>
2885+#include <linux/platform_device.h>
2886+#include <linux/irq.h>
2887+
2888+#include <asm/arch/hardware.h>
2889+#include <asm/mach/irq.h>
2890+#include <asm/io.h>
2891+
2892+/* remove me */
2893+#include <asm/arch/pxa-regs.h>
2894+#include <asm/arch/htcuniversal-gpio.h>
2895+#include <asm/arch/htcuniversal-asic.h>
2896+#include <asm/mach-types.h>
2897+
2898+#include <asm/hardware/ipaq-asic3.h>
2899+#include <linux/soc/asic3_base.h>
2900+
2901+
2902+#include "tsc2046_ts.h"
2903+
2904+enum touchscreen_state {
2905+ STATE_WAIT_FOR_TOUCH, /* Waiting for a PEN interrupt */
2906+ STATE_SAMPLING /* Actively sampling ADC */
2907+};
2908+
2909+struct touchscreen_data {
2910+ enum touchscreen_state state;
2911+ struct timer_list timer;
2912+ int irq;
2913+ struct input_dev *input;
2914+ /* */
2915+ int port;
2916+ int clock;
2917+ int pwrbit_X;
2918+ int pwrbit_Y;
2919+ int (*pen_down)(void);
2920+};
2921+
2922+static unsigned long poll_sample_time = 10; /* Sample every 10 milliseconds */
2923+
2924+static struct touchscreen_data *ts_data;
2925+
2926+static int irqblock;
2927+
2928+module_param(poll_sample_time, ulong, 0644);
2929+MODULE_PARM_DESC(poll_sample_time, "Poll sample time");
2930+
2931+static inline void
2932+report_touchpanel(struct touchscreen_data *ts, int pressure, int x, int y)
2933+{
2934+ input_report_abs(ts->input, ABS_PRESSURE, pressure);
2935+ input_report_abs(ts->input, ABS_X, x);
2936+ input_report_abs(ts->input, ABS_Y, y);
2937+ input_sync(ts->input);
2938+}
2939+
2940+static void start_read(struct touchscreen_data *touch);
2941+
2942+static irqreturn_t
2943+pen_isr(int irq, void *irq_desc)
2944+{
2945+ struct touchscreen_data *ts = ts_data;
2946+
2947+ if(irq == ts->irq /* && !irqblock */) {
2948+ irqblock = 1;
2949+
2950+ /*
2951+ * Disable the pen interrupt. It's reenabled when the user lifts the
2952+ * pen.
2953+ */
2954+ disable_irq(ts->irq);
2955+
2956+ if (ts->state == STATE_WAIT_FOR_TOUCH) {
2957+ ts->state = STATE_SAMPLING;
2958+ start_read(ts);
2959+ } else {
2960+ /* Shouldn't happen */
2961+ printk(KERN_ERR "Unexpected ts interrupt\n");
2962+ }
2963+
2964+ }
2965+ return IRQ_HANDLED;
2966+}
2967+
2968+static void
2969+ssp_init(int port, int clock)
2970+{
2971+
2972+ pxa_set_cken(clock, 0);
2973+
2974+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_CLK_MD);
2975+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_FRM_MD);
2976+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DO_MD);
2977+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DI_MD);
2978+
2979+ SET_HTCUNIVERSAL_GPIO(SPI_FRM,1);
2980+
2981+ /* *** Set up the SPI Registers *** */
2982+ SSCR0_P(port) =
2983+ SSCR0_EDSS /* Extended Data Size Select */
2984+ | SSCR0_SerClkDiv(7) /* Serial Clock Rate */
2985+ /* Synchronous Serial Enable (Disable for now) */
2986+ | SSCR0_Motorola /* Motorola SPI Interface */
2987+ | SSCR0_DataSize(8) /* Data Size Select (24-bit) */
2988+ ;
2989+ SSCR1_P(port) = 0;
2990+ SSPSP_P(port) = 0;
2991+
2992+ /* Clear the Status */
2993+ SSSR_P(port) = SSSR_P(port) & 0x00fcfffc;
2994+
2995+ /* Now enable it */
2996+ SSCR0_P(port) =
2997+ SSCR0_EDSS /* Extended Data Size Select */
2998+ | SSCR0_SerClkDiv(7) /* Serial Clock Rate */
2999+ | SSCR0_SSE /* Synchronous Serial Enable */
3000+ | SSCR0_Motorola /* Motorola SPI Interface */
3001+ | SSCR0_DataSize(8) /* Data Size Select (24-bit) */
3002+ ;
3003+
3004+ pxa_set_cken(clock, 1);
3005+}
3006+
3007+static void
3008+start_read(struct touchscreen_data *touch)
3009+{
3010+ unsigned long inc = (poll_sample_time * HZ) / 1000;
3011+ int i;
3012+
3013+ /* Write here to the serial port. We request X and Y only for now.
3014+ * Then we have to wait for poll_sample_time before we read out the serial
3015+ * port. Then, when we read it out, we check to see if the pen is still
3016+ * down. If so, then we issue another request here.
3017+ */
3018+#define TS_SAMPLES 7
3019+
3020+ /*
3021+ * We do four samples for each, and throw out the highest and lowest, then
3022+ * average the other two.
3023+ */
3024+
3025+ for(i = 0; i < TS_SAMPLES; i++) {
3026+ while(!(SSSR_P(touch->port) & SSSR_TNF))
3027+ ;
3028+ /* It's not full. Write the command for X */
3029+ SSDR_P(touch->port) = (TSC2046_SAMPLE_X|(touch->pwrbit_X))<<16;
3030+ }
3031+
3032+ for(i = 0; i < TS_SAMPLES; i++) {
3033+ while(!(SSSR_P(touch->port) & SSSR_TNF))
3034+ ;
3035+ /* It's not full. Write the command for Y */
3036+ SSDR_P(touch->port) = (TSC2046_SAMPLE_Y|(touch->pwrbit_Y))<<16;
3037+ }
3038+
3039+ /*
3040+ * Enable the timer. We should get an interrupt, but we want keep a timer
3041+ * to ensure that we can detect missing data
3042+ */
3043+ mod_timer(&touch->timer, jiffies + inc);
3044+}
3045+
3046+static void
3047+ts_timer_callback(unsigned long data)
3048+{
3049+ struct touchscreen_data *ts = (struct touchscreen_data *)data;
3050+ int x, a[TS_SAMPLES], y;
3051+ static int oldx, oldy;
3052+ int ssrval;
3053+
3054+ /*
3055+ * Check here to see if there is anything in the SPI FIFO. If so,
3056+ * return it if there has been a change. If not, then we have a
3057+ * timeout. Generate an erro somehow.
3058+ */
3059+ ssrval = SSSR_P(ts->port);
3060+
3061+ if(ssrval & SSSR_RNE) { /* Look at Rx Not Empty bit */
3062+ int number_of_entries_in_fifo;
3063+
3064+ /* The FIFO is not emtpy. Good! Now make sure there are at least two
3065+ * entries. (Should be two exactly.) */
3066+
3067+ number_of_entries_in_fifo = ((ssrval >> 12) & 0xf) + 1;
3068+
3069+ if(number_of_entries_in_fifo < TS_SAMPLES * 2) {
3070+ /* Not ready yet. Come back later. */
3071+ unsigned long inc = (poll_sample_time * HZ) / 1000;
3072+ mod_timer(&ts->timer, jiffies + inc);
3073+ return;
3074+ }
3075+
3076+ if(number_of_entries_in_fifo == TS_SAMPLES * 2) {
3077+ int i, j;
3078+
3079+ for(i = 0; i < TS_SAMPLES; i++) {
3080+ a[i] = SSDR_P(ts->port);
3081+ }
3082+ /* Sort them (bubble) */
3083+ for(j = TS_SAMPLES - 1; j > 0; j--) {
3084+ for(i = 0; i < j; i++) {
3085+ if(a[i] > a[i + 1]) {
3086+ int tmp;
3087+ tmp = a[i+1];
3088+ a[i+1] = a[i];
3089+ a[i] = tmp;
3090+ }
3091+ }
3092+ }
3093+
3094+ /* Take the average of the middle two */
3095+ /* x = (a[TS_SAMPLES/2 - 1] + a[TS_SAMPLES/2] + a[TS_SAMPLES/2+1] + a[TS_SAMPLES/2+2]) >> 2; */
3096+ x = a[TS_SAMPLES/2];
3097+
3098+ for(i = 0; i < TS_SAMPLES; i++) {
3099+ a[i] = SSDR_P(ts->port);
3100+ }
3101+ /* Sort them (bubble) */
3102+ for(j = TS_SAMPLES - 1; j > 0; j--) {
3103+ for(i = 0; i < j; i++) {
3104+ if(a[i] > a[i + 1]) {
3105+ int tmp;
3106+ tmp = a[i+1];
3107+ a[i+1] = a[i];
3108+ a[i] = tmp;
3109+ }
3110+ }
3111+ }
3112+
3113+
3114+ /* Take the average of the middle two */
3115+ /* y = (a[TS_SAMPLES/2 - 1] + a[TS_SAMPLES/2] + a[TS_SAMPLES/2+1] + a[TS_SAMPLES/2+2]) >> 2; */
3116+ y = a[TS_SAMPLES/2];
3117+ } else {
3118+ /* We have an error! Too many entries. */
3119+ printk(KERN_ERR "TS: Expected %d entries. Got %d\n", TS_SAMPLES*2, number_of_entries_in_fifo);
3120+ /* Try to clear the FIFO */
3121+ while(number_of_entries_in_fifo--) {
3122+ (void)SSDR_P(ts->port);
3123+ }
3124+
3125+ if (ts->pen_down())
3126+ start_read(ts);
3127+
3128+ return;
3129+ }
3130+ } else {
3131+ /* Not ready yet. Come back later. */
3132+ unsigned long inc = (poll_sample_time * HZ) / 1000;
3133+ mod_timer(&ts->timer, jiffies + inc);
3134+ return;
3135+ }
3136+
3137+ /*
3138+ * Now we check to see if the pen is still down. If it is, then call
3139+ * start_read().
3140+ */
3141+ if (ts->pen_down())
3142+ {
3143+ /* Still down */
3144+ if(oldx != x || oldy != y) {
3145+ oldx = x;
3146+ oldy = y;
3147+ report_touchpanel(ts, 1, x, y);
3148+ }
3149+ start_read(ts);
3150+ } else {
3151+ /* Up */
3152+ report_touchpanel(ts, 0, 0, 0);
3153+ irqblock = 0;
3154+ ts->state = STATE_WAIT_FOR_TOUCH;
3155+ /* Re-enable pen down interrupt */
3156+ enable_irq(ts->irq);
3157+ }
3158+}
3159+
3160+static int pen_down(void)
3161+{
3162+ return ( asic3_get_gpio_status_a( &htcuniversal_asic3.dev ) & (1<<GPIOA_TOUCHSCREEN_N)) == 0 ;
3163+}
3164+
3165+static int
3166+ts_probe (struct platform_device *dev)
3167+{
3168+ int retval;
3169+ struct touchscreen_data *ts;
3170+ struct tsc2046_mach_info *mach = dev->dev.platform_data;
3171+
3172+ printk("htcuniversal: ts_probe\n");
3173+
3174+ ts = ts_data = kmalloc (sizeof (*ts), GFP_KERNEL);
3175+ if (ts == NULL) {
3176+ printk( KERN_NOTICE "htcuniversal_ts: unable to allocate memory\n" );
3177+ return -ENOMEM;
3178+ }
3179+ memset (ts, 0, sizeof (*ts));
3180+
3181+ ts->input = input_allocate_device();
3182+ if (ts->input == NULL) {
3183+ printk( KERN_NOTICE "htcuniversal_ts: unable to allocation touchscreen input\n" );
3184+ kfree(ts);
3185+ return -ENOMEM;
3186+ }
3187+ ts->input->evbit[0] = BIT(EV_ABS);
3188+ ts->input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
3189+ ts->input->absmin[ABS_X] = 0;
3190+ ts->input->absmax[ABS_X] = 32767;
3191+ ts->input->absmin[ABS_Y] = 0;
3192+ ts->input->absmax[ABS_Y] = 32767;
3193+ ts->input->absmin[ABS_PRESSURE] = 0;
3194+ ts->input->absmax[ABS_PRESSURE] = 1;
3195+
3196+ ts->input->name = "htcuniversal_ts";
3197+ ts->input->phys = "touchscreen/htcuniversal_ts";
3198+ ts->input->private = ts;
3199+
3200+ input_register_device(ts->input);
3201+
3202+ ts->timer.function = ts_timer_callback;
3203+ ts->timer.data = (unsigned long)ts;
3204+ ts->state = STATE_WAIT_FOR_TOUCH;
3205+ init_timer (&ts->timer);
3206+
3207+ platform_set_drvdata(dev, ts);
3208+
3209+ ts->port=-1;
3210+
3211+ if (mach) {
3212+ ts->port = mach->port;
3213+ ts->clock = mach->clock;
3214+ ts->pwrbit_X = mach->pwrbit_X;
3215+ ts->pwrbit_Y = mach->pwrbit_Y;
3216+
3217+ /* static irq */
3218+ if (mach->irq)
3219+ ts->irq = mach->irq;
3220+
3221+ if (mach->pen_down)
3222+ ts->pen_down=mach->pen_down;
3223+ }
3224+
3225+ if (ts->port == -1)
3226+ {
3227+ printk("tsc2046: your device is not supported by this driver\n");
3228+ return -ENODEV;
3229+ }
3230+
3231+ /* *** Initialize the SSP interface *** */
3232+ ssp_init(ts->port, ts->clock);
3233+
3234+ while(!(SSSR_P(ts->port) & SSSR_TNF))
3235+ ;
3236+ SSDR_P(ts->port) = (TSC2046_SAMPLE_X|(ts->pwrbit_X))<<16;
3237+
3238+ for(retval = 0; retval < 100; retval++) {
3239+ if(SSSR_P(ts->port) & SSSR_RNE) {
3240+ while(SSSR_P(ts->port) & SSSR_RNE) {
3241+ (void)SSDR_P(ts->port);
3242+ }
3243+ break;
3244+ }
3245+ mdelay(1);
3246+ }
3247+
3248+ if (machine_is_htcuniversal() )
3249+ {
3250+ ts->irq = asic3_irq_base( &htcuniversal_asic3.dev ) + ASIC3_GPIOA_IRQ_BASE + GPIOA_TOUCHSCREEN_N;
3251+ ts->pen_down=pen_down;
3252+ }
3253+
3254+ retval = request_irq(ts->irq, pen_isr, IRQF_DISABLED, "tsc2046_ts", ts);
3255+ if(retval) {
3256+ printk("Unable to get interrupt\n");
3257+ input_unregister_device (ts->input);
3258+ return -ENODEV;
3259+ }
3260+ set_irq_type(ts->irq, IRQ_TYPE_EDGE_FALLING);
3261+
3262+ return 0;
3263+}
3264+
3265+static int
3266+ts_remove (struct platform_device *dev)
3267+{
3268+ struct touchscreen_data *ts = platform_get_drvdata(dev);
3269+
3270+ input_unregister_device (ts->input);
3271+ del_timer_sync (&ts->timer);
3272+ free_irq (ts->irq, ts);
3273+ pxa_set_cken(ts->clock, 0);
3274+
3275+ kfree(ts);
3276+ return 0;
3277+}
3278+
3279+static int
3280+ts_suspend (struct platform_device *dev, pm_message_t state)
3281+{
3282+ struct touchscreen_data *ts = platform_get_drvdata(dev);
3283+
3284+ disable_irq(ts->irq);
3285+
3286+ printk("htcuniversal_ts2_suspend: called.\n");
3287+ return 0;
3288+}
3289+
3290+static int
3291+ts_resume (struct platform_device *dev)
3292+{
3293+ struct touchscreen_data *ts = platform_get_drvdata(dev);
3294+
3295+ ts->state = STATE_WAIT_FOR_TOUCH;
3296+ ssp_init(ts->port, ts->clock);
3297+ enable_irq(ts->irq);
3298+
3299+ printk("htcuniversal_ts2_resume: called.\n");
3300+ return 0;
3301+}
3302+
3303+static struct platform_driver ts_driver = {
3304+ .probe = ts_probe,
3305+ .remove = ts_remove,
3306+ .suspend = ts_suspend,
3307+ .resume = ts_resume,
3308+ .driver = {
3309+ .name = "htcuniversal_ts",
3310+ },
3311+};
3312+
3313+
3314+static int
3315+ts_module_init (void)
3316+{
3317+ printk(KERN_NOTICE "HTC Universal Touch Screen Driver\n");
3318+
3319+ return platform_driver_register(&ts_driver);
3320+}
3321+
3322+static void
3323+ts_module_cleanup (void)
3324+{
3325+ platform_driver_unregister (&ts_driver);
3326+}
3327+
3328+module_init(ts_module_init);
3329+module_exit(ts_module_cleanup);
3330+
3331+MODULE_LICENSE("GPL");
3332+MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
3333+MODULE_DESCRIPTION("HTC Universal Touch Screen Driver");
3334Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c
3335===================================================================
3336--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3337+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c 2007-09-11 12:53:37.000000000 +0200
3338@@ -0,0 +1,71 @@
3339+
3340+/*
3341+ *
3342+ * htcuniversal_udc.c:
3343+ * htcuniversal specific code for the pxa27x usb device controller.
3344+ *
3345+ * Use consistent with the GNU GPL is permitted.
3346+ *
3347+ */
3348+
3349+#include <linux/module.h>
3350+#include <linux/init.h>
3351+#include <linux/platform_device.h>
3352+#include <asm/arch/hardware.h>
3353+#include <asm/arch/pxa-regs.h>
3354+#include <asm/arch/udc.h>
3355+#include <linux/soc/asic3_base.h>
3356+#include <asm/arch/htcuniversal-gpio.h>
3357+#include <asm/arch/htcuniversal-asic.h>
3358+
3359+static void htcuniversal_udc_command(int cmd)
3360+{
3361+ switch (cmd) {
3362+ case PXA2XX_UDC_CMD_DISCONNECT:
3363+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev,
3364+ 1<<GPIOB_USB_PUEN, 0);
3365+// SET_HTCUNIVERSAL_GPIO(USB_PUEN,0);
3366+ break;
3367+ case PXA2XX_UDC_CMD_CONNECT:
3368+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev,
3369+ 1<<GPIOB_USB_PUEN, 1<<GPIOB_USB_PUEN);
3370+// SET_HTCUNIVERSAL_GPIO(USB_PUEN,1);
3371+ break;
3372+ default:
3373+ printk("_udc_control: unknown command!\n");
3374+ break;
3375+ }
3376+}
3377+
3378+static int htcuniversal_udc_is_connected(void)
3379+{
3380+ return (GET_HTCUNIVERSAL_GPIO(USB_DET) != 0);
3381+}
3382+
3383+static struct pxa2xx_udc_mach_info htcuniversal_udc_info __initdata = {
3384+ .udc_is_connected = htcuniversal_udc_is_connected,
3385+ .udc_command = htcuniversal_udc_command,
3386+};
3387+
3388+static int htcuniversal_udc_probe(struct platform_device * dev)
3389+{
3390+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_USB_PUEN, 1<<GPIOB_USB_PUEN);
3391+
3392+ pxa_set_udc_info(&htcuniversal_udc_info);
3393+ return 0;
3394+}
3395+
3396+static struct platform_driver htcuniversal_udc_driver = {
3397+ .driver = {
3398+ .name = "htcuniversal_udc",
3399+ },
3400+ .probe = htcuniversal_udc_probe,
3401+};
3402+
3403+static int __init htcuniversal_udc_init(void)
3404+{
3405+ return platform_driver_register(&htcuniversal_udc_driver);
3406+}
3407+
3408+module_init(htcuniversal_udc_init);
3409+MODULE_LICENSE("GPL");
3410Index: linux-2.6.22/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h
3411===================================================================
3412--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3413+++ linux-2.6.22/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h 2007-09-11 12:53:37.000000000 +0200
3414@@ -0,0 +1,20 @@
3415+/*
3416+ * temporary TSC2046 touchscreen hack
3417+ */
3418+
3419+#ifndef _TSC2046_TS_H
3420+#define _TSC2046_TS_H
3421+
3422+struct tsc2046_mach_info {
3423+ int port;
3424+ int clock;
3425+ int pwrbit_X;
3426+ int pwrbit_Y;
3427+ int irq;
3428+ int (*pen_down)(void);
3429+};
3430+
3431+#define TSC2046_SAMPLE_X 0xd0
3432+#define TSC2046_SAMPLE_Y 0x90
3433+
3434+#endif
3435Index: linux-2.6.22/arch/arm/mach-pxa/Kconfig
3436===================================================================
3437--- linux-2.6.22.orig/arch/arm/mach-pxa/Kconfig 2007-09-11 12:53:33.000000000 +0200
3438+++ linux-2.6.22/arch/arm/mach-pxa/Kconfig 2007-09-11 12:53:37.000000000 +0200
3439@@ -50,6 +50,14 @@
3440 help
3441 This enables support for the HP iPAQ HX2750 handheld.
3442
3443+config MACH_HTCUNIVERSAL
3444+ bool "HTC Universal"
3445+ select PXA27x
3446+ help
3447+ Say Y here if you intend to run this kernel on a
3448+ HTC Universal. Currently there is only basic support
3449+ for this PDA.
3450+
3451 endchoice
3452
3453 if PXA_SHARPSL
3454@@ -84,6 +92,86 @@
3455
3456 endif
3457
3458+if MACH_HTCUNIVERSAL
3459+
3460+menu "HTC Universal support"
3461+
3462+config HTCUNIVERSAL_CORE
3463+ tristate "HTC Universal core"
3464+ depends on MACH_HTCUNIVERSAL
3465+ help
3466+ This selection enables HTC Universal core support.
3467+
3468+config HTCUNIVERSAL_UDC
3469+ bool "USB Device Controller support"
3470+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3 && USB_PXA27X
3471+ help
3472+ Enables HTC Universal specific USB detection
3473+
3474+config HTCUNIVERSAL_POWER
3475+ tristate "HTC Universal power"
3476+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3
3477+ help
3478+ This selection enables HTC Universal power monitoring
3479+ hardware support (through ASIC3).
3480+
3481+config HTCUNIVERSAL_BACKLIGHT
3482+ bool "HTC Universal Backlight"
3483+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3 && BACKLIGHT_CLASS_DEVICE
3484+ help
3485+ This driver provides support for changing power and brightness
3486+ on HTC Universal LCD backlight.
3487+
3488+config HTCUNIVERSAL_LCD
3489+ tristate "HTC Universal LCD"
3490+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3 && LCD_CLASS_DEVICE
3491+ help
3492+ This driver provides support for changing power and brightness
3493+ on HTC Universal LCD display.
3494+
3495+config HTCUNIVERSAL_TS2
3496+ tristate "HTC Universal Touchscreen (old)"
3497+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3
3498+ help
3499+ Enable support for the HTC Universal Touchscreen Panel.
3500+
3501+config HTCUNIVERSAL_BUTTONS
3502+ tristate "HTC Universal buttons support"
3503+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3
3504+
3505+config HTCUNIVERSAL_BLUETOOTH
3506+ tristate "HTC Universal Bluetooth"
3507+ depends on MACH_HTCUNIVERSAL && HTCUNIVERSAL_CORE && HTC_ASIC3
3508+ help
3509+ Enables support for the TI BRF6150 Bluetooth Module
3510+ in the HTC Universal.
3511+
3512+config HTCUNIVERSAL_ASIC3_LEDS
3513+ tristate "HTC Universal ASIC3 LED support"
3514+ select LEDS_ASIC3
3515+ depends on MACH_HTCUNIVERSAL && HTCUNIVERSAL_CORE && HTC_ASIC3
3516+ ---help---
3517+ Support for right (colors red+green+(amber)) and left (green+blue) led
3518+ Off/on hook keys LED backlight
3519+ Keyboard backlight
3520+ Vibra
3521+ Flashlight
3522+
3523+config HTCUNIVERSAL_PHONE
3524+ tristate "HTC Universal Phone"
3525+ depends on MACH_HTCUNIVERSAL && HTCUNIVERSAL_CORE && HTC_ASIC3
3526+ help
3527+ Enables support for the Qualcomm MSM6520 Phone Module
3528+ in the HTC Universal.
3529+
3530+config HTCUNIVERSAL_AK4641
3531+ depends on SND && I2C
3532+ tristate "AK4641 chipset support"
3533+
3534+endmenu
3535+
3536+endif
3537+
3538 endmenu
3539
3540 config MACH_POODLE
3541@@ -164,4 +252,3 @@
3542 depends on (PXA25x || PXA27x) && INPUT
3543
3544 endif
3545-
3546Index: linux-2.6.22/arch/arm/mach-pxa/Makefile
3547===================================================================
3548--- linux-2.6.22.orig/arch/arm/mach-pxa/Makefile 2007-09-11 12:53:33.000000000 +0200
3549+++ linux-2.6.22/arch/arm/mach-pxa/Makefile 2007-09-11 12:53:37.000000000 +0200
3550@@ -20,6 +20,7 @@
3551 obj-$(CONFIG_MACH_TOSA) += tosa.o
3552 obj-$(CONFIG_MACH_EM_X270) += em-x270.o
3553 obj-$(CONFIG_MACH_HX2750) += hx2750.o hx2750_test.o
3554+obj-$(CONFIG_MACH_HTCUNIVERSAL) += htcuniversal/
3555
3556 # Support for blinky lights
3557 led-y := leds.o
3558Index: linux-2.6.22/drivers/leds/Kconfig
3559===================================================================
3560--- linux-2.6.22.orig/drivers/leds/Kconfig 2007-09-11 12:53:14.000000000 +0200
3561+++ linux-2.6.22/drivers/leds/Kconfig 2007-09-11 12:53:37.000000000 +0200
3562@@ -101,6 +101,13 @@
3563 outputs. To be useful the particular board must have LEDs
3564 and they must be connected to the GPIO lines.
3565
3566+config LEDS_ASIC3
3567+ tristate "LED Support for the HTC ASIC3 chip"
3568+ depends LEDS_CLASS && HTC_ASIC3
3569+ help
3570+ This option enables support for the LEDs connected to the
3571+ HTC ASIC3 chip.
3572+
3573 comment "LED Triggers"
3574
3575 config LEDS_TRIGGERS
3576Index: linux-2.6.22/drivers/leds/leds-asic3.c
3577===================================================================
3578--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3579+++ linux-2.6.22/drivers/leds/leds-asic3.c 2007-09-11 12:53:37.000000000 +0200
3580@@ -0,0 +1,189 @@
3581+/*
3582+ * LEDs support for HTC ASIC3 devices.
3583+ *
3584+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
3585+ *
3586+ * This file is subject to the terms and conditions of the GNU General Public
3587+ * License. See the file COPYING in the main directory of this archive for
3588+ * more details.
3589+ *
3590+ */
3591+
3592+#include <linux/kernel.h>
3593+#include <linux/init.h>
3594+#include <linux/platform_device.h>
3595+#include <linux/leds.h>
3596+#include "leds.h"
3597+
3598+#include <asm/hardware/ipaq-asic3.h>
3599+#include <linux/soc/asic3_base.h>
3600+#include <asm/mach-types.h>
3601+#include <asm/hardware/asic3_leds.h>
3602+
3603+#ifdef DEBUG
3604+#define dbg(msg, ...) printk(msg, __VA_ARGS__)
3605+#else
3606+#define dbg(msg, ...)
3607+#endif
3608+
3609+static
3610+void asic3_leds_set(struct led_classdev *led_cdev, enum led_brightness b)
3611+{
3612+ struct asic3_led *led = container_of(led_cdev, struct asic3_led,
3613+ led_cdev);
3614+ struct asic3_leds_machinfo *machinfo = led->machinfo;
3615+ struct device *asic3_dev = &machinfo->asic3_pdev->dev;
3616+
3617+ dbg("%s:%s %d(%d)-%s %d\n", __FILE__, __FUNCTION__, led->hw_num,
3618+ led->gpio_num, led->led_cdev.name, b);
3619+
3620+ if (led->hw_num == -1) {
3621+ asic3_gpio_set_value(asic3_dev, led->gpio_num, b);
3622+ return;
3623+ }
3624+
3625+ if (b == LED_OFF) {
3626+ asic3_set_led(asic3_dev, led->hw_num, 0, 16, 6);
3627+ asic3_set_gpio_out_c(asic3_dev, led->hw_num, 0);
3628+ }
3629+ else {
3630+ asic3_set_gpio_out_c(asic3_dev, led->hw_num, led->hw_num);
3631+ #ifdef CONFIG_LEDS_TRIGGER_HWTIMER
3632+ if (led_cdev->trigger && led_cdev->trigger->is_led_supported &&
3633+ (led_cdev->trigger->is_led_supported(led_cdev) &
3634+ LED_SUPPORTS_HWTIMER)) {
3635+ struct hwtimer_data *td = led_cdev->trigger_data;
3636+ if (!td) return;
3637+ asic3_set_led(asic3_dev, led->hw_num, td->delay_on/8,
3638+ (td->delay_on + td->delay_off)/8, 6);
3639+ }
3640+ else
3641+ #endif
3642+ asic3_set_led(asic3_dev, led->hw_num, 16, 16, 6);
3643+ }
3644+
3645+ return;
3646+}
3647+
3648+static
3649+int asic3_leds_probe(struct platform_device *pdev)
3650+{
3651+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3652+ struct asic3_led *leds = machinfo->leds;
3653+ int ret, i = 0;
3654+
3655+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3656+
3657+ // Turn on clocks early, for the case if trigger would enable
3658+ // led immediately after led_classdev_register().
3659+ asic3_set_clock_cdex(&machinfo->asic3_pdev->dev,
3660+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
3661+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2);
3662+
3663+ for (i = 0; i < machinfo->num_leds; i++) {
3664+ leds[i].machinfo = machinfo;
3665+ leds[i].led_cdev.brightness_set = asic3_leds_set;
3666+ ret = led_classdev_register(&pdev->dev, &leds[i].led_cdev);
3667+ if (ret) {
3668+ printk(KERN_ERR "Error: can't register %s led\n",
3669+ leds[i].led_cdev.name);
3670+ goto out_err;
3671+ }
3672+ }
3673+
3674+ return 0;
3675+
3676+out_err:
3677+ while (--i >= 0) led_classdev_unregister(&leds[i].led_cdev);
3678+
3679+ asic3_set_clock_cdex(&machinfo->asic3_pdev->dev,
3680+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
3681+ 0 | 0 | 0);
3682+
3683+ return ret;
3684+}
3685+
3686+static
3687+int asic3_leds_remove(struct platform_device *pdev)
3688+{
3689+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3690+ struct asic3_led *leds = machinfo->leds;
3691+ int i = 0;
3692+
3693+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3694+
3695+ for (i = 0; i < machinfo->num_leds; i++)
3696+ led_classdev_unregister(&leds[i].led_cdev);
3697+
3698+ asic3_set_clock_cdex(&machinfo->asic3_pdev->dev,
3699+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
3700+ 0 | 0 | 0);
3701+
3702+ return 0;
3703+}
3704+
3705+#ifdef CONFIG_PM
3706+
3707+static
3708+int asic3_leds_suspend(struct platform_device *pdev, pm_message_t state)
3709+{
3710+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3711+ struct asic3_led *leds = machinfo->leds;
3712+ int i = 0;
3713+
3714+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3715+
3716+ for (i = 0; i < machinfo->num_leds; i++)
3717+ led_classdev_suspend(&leds[i].led_cdev);
3718+
3719+ return 0;
3720+}
3721+
3722+static
3723+int asic3_leds_resume(struct platform_device *pdev)
3724+{
3725+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3726+ struct asic3_led *leds = machinfo->leds;
3727+ int i = 0;
3728+
3729+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3730+
3731+ for (i = 0; i < machinfo->num_leds; i++)
3732+ led_classdev_resume(&leds[i].led_cdev);
3733+
3734+ return 0;
3735+}
3736+
3737+#endif
3738+
3739+static
3740+struct platform_driver asic3_leds_driver = {
3741+ .probe = asic3_leds_probe,
3742+ .remove = asic3_leds_remove,
3743+#ifdef CONFIG_PM
3744+ .suspend = asic3_leds_suspend,
3745+ .resume = asic3_leds_resume,
3746+#endif
3747+ .driver = {
3748+ .name = "asic3-leds",
3749+ },
3750+};
3751+
3752+int asic3_leds_register(void)
3753+{
3754+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3755+ return platform_driver_register(&asic3_leds_driver);
3756+}
3757+
3758+void asic3_leds_unregister(void)
3759+{
3760+ platform_driver_unregister(&asic3_leds_driver);
3761+ return;
3762+}
3763+
3764+EXPORT_SYMBOL_GPL(asic3_leds_register);
3765+EXPORT_SYMBOL_GPL(asic3_leds_unregister);
3766+
3767+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
3768+MODULE_DESCRIPTION("HTC ASIC3 LEDs driver");
3769+MODULE_LICENSE("GPL");
3770Index: linux-2.6.22/drivers/mfd/Kconfig
3771===================================================================
3772--- linux-2.6.22.orig/drivers/mfd/Kconfig 2007-09-11 12:53:30.000000000 +0200
3773+++ linux-2.6.22/drivers/mfd/Kconfig 2007-09-11 12:53:37.000000000 +0200
3774@@ -15,6 +15,16 @@
3775 interface. The device may be connected by PCI or local bus with
3776 varying functions enabled.
3777
3778+config HTC_ASIC3
3779+ tristate "HTC ASIC3 (iPAQ h1900/h3900/h4000/hx4700/rx3000) support"
3780+
3781+config HTC_ASIC3_DS1WM
3782+ bool "Support HTC ASIC3 builtin DS1WM block"
3783+ help
3784+ Choose Y here if you want to include support for ASIC3's builtin
3785+ W1 controller. Some devices do not use it, and yet other have
3786+ separate DS1WM controller. For them, choose N.
3787+
3788 endmenu
3789
3790 menu "Multimedia Capabilities Port drivers"
3791Index: linux-2.6.22/drivers/mfd/Makefile
3792===================================================================
3793--- linux-2.6.22.orig/drivers/mfd/Makefile 2007-09-11 12:53:30.000000000 +0200
3794+++ linux-2.6.22/drivers/mfd/Makefile 2007-09-11 12:53:37.000000000 +0200
3795@@ -2,6 +2,8 @@
3796 # Makefile for multifunction miscellaneous devices
3797 #
3798
3799+obj-$(CONFIG_HTC_ASIC3) += asic3_base.o soc-core.o
3800+
3801 obj-$(CONFIG_MFD_SM501) += sm501.o
3802
3803 obj-$(CONFIG_MCP) += mcp-core.o
3804Index: linux-2.6.22/drivers/mfd/asic3_base.c
3805===================================================================
3806--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3807+++ linux-2.6.22/drivers/mfd/asic3_base.c 2007-09-11 12:53:37.000000000 +0200
3808@@ -0,0 +1,1208 @@
3809+/*
3810+ * Driver interface to HTC "ASIC3"
3811+ *
3812+ * Copyright 2001 Compaq Computer Corporation.
3813+ * Copyright 2004-2005 Phil Blundell
3814+ *
3815+ * This program is free software; you can redistribute it and/or modify
3816+ * it under the terms of the GNU General Public License as published by
3817+ * the Free Software Foundation; either version 2 of the License, or
3818+ * (at your option) any later version.
3819+ *
3820+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
3821+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
3822+ * FITNESS FOR ANY PARTICULAR PURPOSE.
3823+ *
3824+ * Author: Andrew Christian
3825+ * <Andrew.Christian@compaq.com>
3826+ * October 2001
3827+ */
3828+
3829+#include <linux/module.h>
3830+#include <linux/version.h>
3831+#include <linux/platform_device.h>
3832+#include <linux/delay.h>
3833+#include <linux/init.h>
3834+#include <linux/irq.h>
3835+#include <linux/clk.h>
3836+#include <linux/ds1wm.h>
3837+#include <asm/arch/clock.h>
3838+
3839+#include <asm/hardware.h>
3840+#include <asm/irq.h>
3841+#include <asm/io.h>
3842+
3843+#include <asm/hardware/ipaq-asic3.h>
3844+#include <linux/soc/asic3_base.h>
3845+#include <linux/soc/tmio_mmc.h>
3846+#include "soc-core.h"
3847+
3848+
3849+struct asic3_data {
3850+ void *mapping;
3851+ unsigned int bus_shift;
3852+ int irq_base;
3853+ int irq_nr;
3854+
3855+ u16 irq_bothedge[4];
3856+ struct device *dev;
3857+
3858+ struct platform_device *mmc_dev;
3859+};
3860+
3861+static DEFINE_SPINLOCK(asic3_gpio_lock);
3862+
3863+static int asic3_remove(struct platform_device *dev);
3864+
3865+static inline unsigned long asic3_address(struct device *dev,
3866+ unsigned int reg)
3867+{
3868+ struct asic3_data *adata;
3869+
3870+ adata = (struct asic3_data *)dev->driver_data;
3871+
3872+ return (unsigned long)adata->mapping + (reg >> (2 - adata->bus_shift));
3873+}
3874+
3875+void asic3_write_register(struct device *dev, unsigned int reg, u32 value)
3876+{
3877+ __raw_writew(value, asic3_address(dev, reg));
3878+}
3879+EXPORT_SYMBOL(asic3_write_register);
3880+
3881+u32 asic3_read_register(struct device *dev, unsigned int reg)
3882+{
3883+ return __raw_readw(asic3_address(dev, reg));
3884+}
3885+EXPORT_SYMBOL(asic3_read_register);
3886+
3887+static inline void __asic3_write_register(struct asic3_data *asic,
3888+ unsigned int reg, u32 value)
3889+{
3890+ __raw_writew(value, (unsigned long)asic->mapping
3891+ + (reg >> (2 - asic->bus_shift)));
3892+}
3893+
3894+static inline u32 __asic3_read_register(struct asic3_data *asic,
3895+ unsigned int reg)
3896+{
3897+ return __raw_readw((unsigned long)asic->mapping
3898+ + (reg >> (2 - asic->bus_shift)));
3899+}
3900+
3901+#define ASIC3_GPIO_FN(get_fn_name, set_fn_name, REG) \
3902+u32 get_fn_name(struct device *dev) \
3903+{ \
3904+ return asic3_read_register(dev, REG); \
3905+} \
3906+EXPORT_SYMBOL(get_fn_name); \
3907+ \
3908+void set_fn_name(struct device *dev, u32 bits, u32 val) \
3909+{ \
3910+ unsigned long flags; \
3911+ \
3912+ spin_lock_irqsave(&asic3_gpio_lock, flags); \
3913+ val |= (asic3_read_register(dev, REG) & ~bits); \
3914+ asic3_write_register(dev, REG, val); \
3915+ spin_unlock_irqrestore(&asic3_gpio_lock, flags); \
3916+} \
3917+EXPORT_SYMBOL(set_fn_name);
3918+
3919+#define ASIC3_GPIO_REGISTER(ACTION, action, fn, FN) \
3920+ ASIC3_GPIO_FN(asic3_get_gpio_ ## action ## _ ## fn , \
3921+ asic3_set_gpio_ ## action ## _ ## fn , \
3922+ _IPAQ_ASIC3_GPIO_ ## FN ## _Base \
3923+ + _IPAQ_ASIC3_GPIO_ ## ACTION )
3924+
3925+#define ASIC3_GPIO_FUNCTIONS(fn, FN) \
3926+ ASIC3_GPIO_REGISTER(Direction, dir, fn, FN) \
3927+ ASIC3_GPIO_REGISTER(Out, out, fn, FN) \
3928+ ASIC3_GPIO_REGISTER(SleepMask, sleepmask, fn, FN) \
3929+ ASIC3_GPIO_REGISTER(SleepOut, sleepout, fn, FN) \
3930+ ASIC3_GPIO_REGISTER(BattFaultOut, battfaultout, fn, FN) \
3931+ ASIC3_GPIO_REGISTER(AltFunction, alt_fn, fn, FN) \
3932+ ASIC3_GPIO_REGISTER(SleepConf, sleepconf, fn, FN) \
3933+ ASIC3_GPIO_REGISTER(Status, status, fn, FN)
3934+
3935+#if 0
3936+ ASIC3_GPIO_REGISTER(Mask, mask, fn, FN)
3937+ ASIC3_GPIO_REGISTER(TriggerType, trigtype, fn, FN)
3938+ ASIC3_GPIO_REGISTER(EdgeTrigger, rising, fn, FN)
3939+ ASIC3_GPIO_REGISTER(LevelTrigger, triglevel, fn, FN)
3940+ ASIC3_GPIO_REGISTER(IntStatus, intstatus, fn, FN)
3941+#endif
3942+
3943+ASIC3_GPIO_FUNCTIONS(a, A)
3944+ASIC3_GPIO_FUNCTIONS(b, B)
3945+ASIC3_GPIO_FUNCTIONS(c, C)
3946+ASIC3_GPIO_FUNCTIONS(d, D)
3947+
3948+int asic3_gpio_get_value(struct device *dev, unsigned gpio)
3949+{
3950+ u32 mask = ASIC3_GPIO_bit(gpio);
3951+ printk("%s(%d)\n", __FUNCTION__, gpio);
3952+ switch (gpio >> 4) {
3953+ case _IPAQ_ASIC3_GPIO_BANK_A:
3954+ return asic3_get_gpio_status_a(dev) & mask;
3955+ case _IPAQ_ASIC3_GPIO_BANK_B:
3956+ return asic3_get_gpio_status_b(dev) & mask;
3957+ case _IPAQ_ASIC3_GPIO_BANK_C:
3958+ return asic3_get_gpio_status_c(dev) & mask;
3959+ case _IPAQ_ASIC3_GPIO_BANK_D:
3960+ return asic3_get_gpio_status_d(dev) & mask;
3961+ }
3962+
3963+ printk(KERN_ERR "%s: invalid GPIO value 0x%x", __FUNCTION__, gpio);
3964+ return 0;
3965+}
3966+EXPORT_SYMBOL(asic3_gpio_get_value);
3967+
3968+void asic3_gpio_set_value(struct device *dev, unsigned gpio, int val)
3969+{
3970+ u32 mask = ASIC3_GPIO_bit(gpio);
3971+ u32 bitval = 0;
3972+ if (val) bitval = mask;
3973+ printk("%s(%d, %d)\n", __FUNCTION__, gpio, val);
3974+
3975+ switch (gpio >> 4) {
3976+ case _IPAQ_ASIC3_GPIO_BANK_A:
3977+ asic3_set_gpio_out_a(dev, mask, bitval);
3978+ return;
3979+ case _IPAQ_ASIC3_GPIO_BANK_B:
3980+ asic3_set_gpio_out_b(dev, mask, bitval);
3981+ return;
3982+ case _IPAQ_ASIC3_GPIO_BANK_C:
3983+ asic3_set_gpio_out_c(dev, mask, bitval);
3984+ return;
3985+ case _IPAQ_ASIC3_GPIO_BANK_D:
3986+ asic3_set_gpio_out_d(dev, mask, bitval);
3987+ return;
3988+ }
3989+
3990+ printk(KERN_ERR "%s: invalid GPIO value 0x%x", __FUNCTION__, gpio);
3991+}
3992+EXPORT_SYMBOL(asic3_gpio_set_value);
3993+
3994+int asic3_irq_base(struct device *dev)
3995+{
3996+ struct asic3_data *asic = dev->driver_data;
3997+
3998+ return asic->irq_base;
3999+}
4000+EXPORT_SYMBOL(asic3_irq_base);
4001+
4002+static int asic3_gpio_to_irq(struct device *dev, unsigned gpio)
4003+{
4004+ struct asic3_data *asic = dev->driver_data;
4005+ printk("%s(%d)\n", __FUNCTION__, gpio);
4006+
4007+ return asic->irq_base + gpio;
4008+}
4009+
4010+void asic3_set_led(struct device *dev, int led_num, int duty_time,
4011+ int cycle_time, int timebase)
4012+{
4013+ struct asic3_data *asic = dev->driver_data;
4014+ unsigned int led_base;
4015+
4016+ /* it's a macro thing: see #define _IPAQ_ASIC_LED_0_Base for why you
4017+ * can't substitute led_num in the macros below...
4018+ */
4019+
4020+ switch (led_num) {
4021+ case 0:
4022+ led_base = _IPAQ_ASIC3_LED_0_Base;
4023+ break;
4024+ case 1:
4025+ led_base = _IPAQ_ASIC3_LED_1_Base;
4026+ break;
4027+ case 2:
4028+ led_base = _IPAQ_ASIC3_LED_2_Base;
4029+ break;
4030+ default:
4031+ printk(KERN_ERR "%s: invalid led number %d", __FUNCTION__,
4032+ led_num);
4033+ return;
4034+ }
4035+
4036+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_TimeBase,
4037+ timebase | LED_EN);
4038+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_PeriodTime,
4039+ cycle_time);
4040+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_DutyTime,
4041+ 0);
4042+ udelay(20); /* asic voodoo - possibly need a whole duty cycle? */
4043+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_DutyTime,
4044+ duty_time);
4045+}
4046+EXPORT_SYMBOL(asic3_set_led);
4047+
4048+void asic3_set_clock_sel(struct device *dev, u32 bits, u32 val)
4049+{
4050+ struct asic3_data *asic = dev->driver_data;
4051+ unsigned long flags;
4052+ u32 v;
4053+
4054+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4055+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL));
4056+ v = (v & ~bits) | val;
4057+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL), v);
4058+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4059+}
4060+EXPORT_SYMBOL(asic3_set_clock_sel);
4061+
4062+void asic3_set_clock_cdex(struct device *dev, u32 bits, u32 val)
4063+{
4064+ struct asic3_data *asic = dev->driver_data;
4065+ unsigned long flags;
4066+ u32 v;
4067+
4068+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4069+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX));
4070+ v = (v & ~bits) | val;
4071+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX), v);
4072+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4073+}
4074+EXPORT_SYMBOL(asic3_set_clock_cdex);
4075+
4076+static void asic3_clock_cdex_enable(struct clk *clk)
4077+{
4078+ struct asic3_data *asic = (struct asic3_data *)clk->parent->ctrlbit;
4079+ unsigned long flags, val;
4080+
4081+ local_irq_save(flags);
4082+
4083+ val = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX));
4084+ val |= clk->ctrlbit;
4085+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX), val);
4086+
4087+ local_irq_restore(flags);
4088+}
4089+
4090+static void asic3_clock_cdex_disable(struct clk *clk)
4091+{
4092+ struct asic3_data *asic = (struct asic3_data *)clk->parent->ctrlbit;
4093+ unsigned long flags, val;
4094+
4095+ local_irq_save(flags);
4096+
4097+ val = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX));
4098+ val &= ~clk->ctrlbit;
4099+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX), val);
4100+
4101+ local_irq_restore(flags);
4102+}
4103+
4104+/* base clocks */
4105+
4106+static struct clk clk_g = {
4107+ .name = "gclk",
4108+ .rate = 0,
4109+ .parent = NULL,
4110+};
4111+
4112+/* clock definitions */
4113+
4114+static struct clk asic3_clocks[] = {
4115+ {
4116+ .name = "spi",
4117+ .id = -1,
4118+ .parent = &clk_g,
4119+ .enable = asic3_clock_cdex_enable,
4120+ .disable = asic3_clock_cdex_disable,
4121+ .ctrlbit = CLOCK_CDEX_SPI,
4122+ },
4123+#ifdef CONFIG_HTC_ASIC3_DS1WM
4124+ {
4125+ .name = "ds1wm",
4126+ .id = -1,
4127+ .rate = 5000000,
4128+ .parent = &clk_g,
4129+ .enable = asic3_clock_cdex_enable,
4130+ .disable = asic3_clock_cdex_disable,
4131+ .ctrlbit = CLOCK_CDEX_OWM,
4132+ },
4133+#endif
4134+ {
4135+ .name = "pwm0",
4136+ .id = -1,
4137+ .parent = &clk_g,
4138+ .enable = asic3_clock_cdex_enable,
4139+ .disable = asic3_clock_cdex_disable,
4140+ .ctrlbit = CLOCK_CDEX_PWM0,
4141+ },
4142+ {
4143+ .name = "pwm1",
4144+ .id = -1,
4145+ .parent = &clk_g,
4146+ .enable = asic3_clock_cdex_enable,
4147+ .disable = asic3_clock_cdex_disable,
4148+ .ctrlbit = CLOCK_CDEX_PWM1,
4149+ },
4150+ {
4151+ .name = "led0",
4152+ .id = -1,
4153+ .parent = &clk_g,
4154+ .enable = asic3_clock_cdex_enable,
4155+ .disable = asic3_clock_cdex_disable,
4156+ .ctrlbit = CLOCK_CDEX_LED0,
4157+ },
4158+ {
4159+ .name = "led1",
4160+ .id = -1,
4161+ .parent = &clk_g,
4162+ .enable = asic3_clock_cdex_enable,
4163+ .disable = asic3_clock_cdex_disable,
4164+ .ctrlbit = CLOCK_CDEX_LED1,
4165+ },
4166+ {
4167+ .name = "led2",
4168+ .id = -1,
4169+ .parent = &clk_g,
4170+ .enable = asic3_clock_cdex_enable,
4171+ .disable = asic3_clock_cdex_disable,
4172+ .ctrlbit = CLOCK_CDEX_LED2,
4173+ },
4174+ {
4175+ .name = "smbus",
4176+ .id = -1,
4177+ .parent = &clk_g,
4178+ .enable = asic3_clock_cdex_enable,
4179+ .disable = asic3_clock_cdex_disable,
4180+ .ctrlbit = CLOCK_CDEX_SMBUS,
4181+ },
4182+ {
4183+ .name = "ex0",
4184+ .id = -1,
4185+ .parent = &clk_g,
4186+ .enable = asic3_clock_cdex_enable,
4187+ .disable = asic3_clock_cdex_disable,
4188+ .ctrlbit = CLOCK_CDEX_EX0,
4189+ },
4190+ {
4191+ .name = "ex1",
4192+ .id = -1,
4193+ .parent = &clk_g,
4194+ .enable = asic3_clock_cdex_enable,
4195+ .disable = asic3_clock_cdex_disable,
4196+ .ctrlbit = CLOCK_CDEX_EX1,
4197+ },
4198+};
4199+
4200+void asic3_set_extcf_select(struct device *dev, u32 bits, u32 val)
4201+{
4202+ struct asic3_data *asic = dev->driver_data;
4203+ unsigned long flags;
4204+ u32 v;
4205+
4206+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4207+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Select));
4208+ v = (v & ~bits) | val;
4209+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Select), v);
4210+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4211+}
4212+EXPORT_SYMBOL(asic3_set_extcf_select);
4213+
4214+void asic3_set_extcf_reset(struct device *dev, u32 bits, u32 val)
4215+{
4216+ struct asic3_data *asic = dev->driver_data;
4217+ unsigned long flags;
4218+ u32 v;
4219+
4220+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4221+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Reset));
4222+ v = (v & ~bits) | val;
4223+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Reset), v);
4224+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4225+}
4226+EXPORT_SYMBOL(asic3_set_extcf_reset);
4227+
4228+void asic3_set_sdhwctrl(struct device *dev, u32 bits, u32 val)
4229+{
4230+ struct asic3_data *asic = dev->driver_data;
4231+ unsigned long flags;
4232+ u32 v;
4233+
4234+ spin_lock_irqsave (&asic3_gpio_lock, flags);
4235+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(SDHWCTRL, SDConf));
4236+ v = (v & ~bits) | val;
4237+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(SDHWCTRL, SDConf), v);
4238+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4239+}
4240+EXPORT_SYMBOL(asic3_set_sdhwctrl);
4241+
4242+
4243+#define MAX_ASIC_ISR_LOOPS 20
4244+#define _IPAQ_ASIC3_GPIO_Base_INCR \
4245+ (_IPAQ_ASIC3_GPIO_B_Base - _IPAQ_ASIC3_GPIO_A_Base)
4246+
4247+static inline void asic3_irq_flip_edge(struct asic3_data *asic,
4248+ u32 base, int bit)
4249+{
4250+ u16 edge = __asic3_read_register(asic,
4251+ base + _IPAQ_ASIC3_GPIO_EdgeTrigger);
4252+ edge ^= bit;
4253+ __asic3_write_register(asic,
4254+ base + _IPAQ_ASIC3_GPIO_EdgeTrigger, edge);
4255+}
4256+
4257+static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
4258+{
4259+ int iter;
4260+ struct asic3_data *asic;
4261+
4262+ /* Acknowledge the parrent (i.e. CPU's) IRQ */
4263+ desc->chip->ack(irq);
4264+
4265+ asic = desc->handler_data;
4266+
4267+ /* printk( KERN_NOTICE "asic3_irq_demux: irq=%d\n", irq ); */
4268+ for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) {
4269+ u32 status;
4270+ int bank;
4271+
4272+ status = __asic3_read_register(asic,
4273+ IPAQ_ASIC3_OFFSET(INTR, PIntStat));
4274+ /* Check all ten register bits */
4275+ if ((status & 0x3ff) == 0)
4276+ break;
4277+
4278+ /* Handle GPIO IRQs */
4279+ for (bank = 0; bank < 4; bank++) {
4280+ if (status & (1 << bank)) {
4281+ unsigned long base, i, istat;
4282+
4283+ base = _IPAQ_ASIC3_GPIO_A_Base
4284+ + bank * _IPAQ_ASIC3_GPIO_Base_INCR;
4285+ istat = __asic3_read_register(asic,
4286+ base + _IPAQ_ASIC3_GPIO_IntStatus);
4287+ /* IntStatus is write 0 to clear */
4288+ /* XXX could miss interrupts! */
4289+ __asic3_write_register(asic,
4290+ base + _IPAQ_ASIC3_GPIO_IntStatus, 0);
4291+
4292+ for (i = 0; i < 16; i++) {
4293+ int bit = (1 << i);
4294+ unsigned int irqnr;
4295+ if (!(istat & bit))
4296+ continue;
4297+
4298+ irqnr = asic->irq_base
4299+ + (16 * bank) + i;
4300+ desc = irq_desc + irqnr;
4301+ desc->handle_irq(irqnr, desc);
4302+ if (asic->irq_bothedge[bank] & bit) {
4303+ asic3_irq_flip_edge(asic, base,
4304+ bit);
4305+ }
4306+ }
4307+ }
4308+ }
4309+
4310+ /* Handle remaining IRQs in the status register */
4311+ {
4312+ int i;
4313+
4314+ for (i = ASIC3_LED0_IRQ; i <= ASIC3_OWM_IRQ; i++) {
4315+ /* They start at bit 4 and go up */
4316+ if (status & (1 << (i - ASIC3_LED0_IRQ + 4))) {
4317+ desc = irq_desc + asic->irq_base + i;
4318+ desc->handle_irq(asic->irq_base + i,
4319+ desc);
4320+ }
4321+ }
4322+ }
4323+
4324+ }
4325+
4326+ if (iter >= MAX_ASIC_ISR_LOOPS)
4327+ printk(KERN_ERR "%s: interrupt processing overrun\n",
4328+ __FUNCTION__);
4329+}
4330+
4331+static inline int asic3_irq_to_bank(struct asic3_data *asic, int irq)
4332+{
4333+ int n;
4334+
4335+ n = (irq - asic->irq_base) >> 4;
4336+
4337+ return (n * (_IPAQ_ASIC3_GPIO_B_Base - _IPAQ_ASIC3_GPIO_A_Base));
4338+}
4339+
4340+static inline int asic3_irq_to_index(struct asic3_data *asic, int irq)
4341+{
4342+ return (irq - asic->irq_base) & 15;
4343+}
4344+
4345+static void asic3_mask_gpio_irq(unsigned int irq)
4346+{
4347+ struct asic3_data *asic = get_irq_chip_data(irq);
4348+ u32 val, bank, index;
4349+ unsigned long flags;
4350+
4351+ bank = asic3_irq_to_bank(asic, irq);
4352+ index = asic3_irq_to_index(asic, irq);
4353+
4354+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4355+ val = __asic3_read_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask);
4356+ val |= 1 << index;
4357+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask, val);
4358+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4359+}
4360+
4361+static void asic3_mask_irq(unsigned int irq)
4362+{
4363+ struct asic3_data *asic = get_irq_chip_data(irq);
4364+ int regval;
4365+
4366+ if (irq < ASIC3_NR_GPIO_IRQS) {
4367+ printk(KERN_ERR "asic3_base: gpio mask attempt, irq %d\n",
4368+ irq);
4369+ return;
4370+ }
4371+
4372+ regval = __asic3_read_register(asic,
4373+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask);
4374+
4375+ switch (irq - asic->irq_base) {
4376+ case ASIC3_LED0_IRQ:
4377+ __asic3_write_register(asic,
4378+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4379+ regval & ~ASIC3_INTMASK_MASK0);
4380+ break;
4381+ case ASIC3_LED1_IRQ:
4382+ __asic3_write_register(asic,
4383+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4384+ regval & ~ASIC3_INTMASK_MASK1);
4385+ break;
4386+ case ASIC3_LED2_IRQ:
4387+ __asic3_write_register(asic,
4388+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4389+ regval & ~ASIC3_INTMASK_MASK2);
4390+ break;
4391+ case ASIC3_SPI_IRQ:
4392+ __asic3_write_register(asic,
4393+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4394+ regval & ~ASIC3_INTMASK_MASK3);
4395+ break;
4396+ case ASIC3_SMBUS_IRQ:
4397+ __asic3_write_register(asic,
4398+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4399+ regval & ~ASIC3_INTMASK_MASK4);
4400+ break;
4401+ case ASIC3_OWM_IRQ:
4402+ __asic3_write_register(asic,
4403+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4404+ regval & ~ASIC3_INTMASK_MASK5);
4405+ break;
4406+ default:
4407+ printk(KERN_ERR "asic3_base: bad non-gpio irq %d\n", irq);
4408+ break;
4409+ }
4410+}
4411+
4412+static void asic3_unmask_gpio_irq(unsigned int irq)
4413+{
4414+ struct asic3_data *asic = get_irq_chip_data(irq);
4415+ u32 val, bank, index;
4416+ unsigned long flags;
4417+
4418+ bank = asic3_irq_to_bank(asic, irq);
4419+ index = asic3_irq_to_index(asic, irq);
4420+
4421+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4422+ val = __asic3_read_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask);
4423+ val &= ~(1 << index);
4424+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask, val);
4425+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4426+}
4427+
4428+static void asic3_unmask_irq(unsigned int irq)
4429+{
4430+ struct asic3_data *asic = get_irq_chip_data(irq);
4431+ int regval;
4432+
4433+ if (irq < ASIC3_NR_GPIO_IRQS) {
4434+ printk(KERN_ERR "asic3_base: gpio unmask attempt, irq %d\n",
4435+ irq);
4436+ return;
4437+ }
4438+
4439+ regval = __asic3_read_register(asic,
4440+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask);
4441+
4442+ switch (irq - asic->irq_base) {
4443+ case ASIC3_LED0_IRQ:
4444+ __asic3_write_register(asic,
4445+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4446+ regval | ASIC3_INTMASK_MASK0);
4447+ break;
4448+ case ASIC3_LED1_IRQ:
4449+ __asic3_write_register(asic,
4450+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4451+ regval | ASIC3_INTMASK_MASK1);
4452+ break;
4453+ case ASIC3_LED2_IRQ:
4454+ __asic3_write_register(asic,
4455+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4456+ regval | ASIC3_INTMASK_MASK2);
4457+ break;
4458+ case ASIC3_SPI_IRQ:
4459+ __asic3_write_register(asic,
4460+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4461+ regval | ASIC3_INTMASK_MASK3);
4462+ break;
4463+ case ASIC3_SMBUS_IRQ:
4464+ __asic3_write_register(asic,
4465+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4466+ regval | ASIC3_INTMASK_MASK4);
4467+ break;
4468+ case ASIC3_OWM_IRQ:
4469+ __asic3_write_register(asic,
4470+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4471+ regval | ASIC3_INTMASK_MASK5);
4472+ break;
4473+ default:
4474+ printk(KERN_ERR "asic3_base: bad non-gpio irq %d\n", irq);
4475+ break;
4476+ }
4477+}
4478+
4479+static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
4480+{
4481+ struct asic3_data *asic = get_irq_chip_data(irq);
4482+ u32 bank, index;
4483+ unsigned long flags;
4484+ u16 trigger, level, edge, bit;
4485+
4486+ bank = asic3_irq_to_bank(asic, irq);
4487+ index = asic3_irq_to_index(asic, irq);
4488+ bit = 1<<index;
4489+
4490+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4491+ level = __asic3_read_register(asic,
4492+ bank + _IPAQ_ASIC3_GPIO_LevelTrigger);
4493+ edge = __asic3_read_register(asic,
4494+ bank + _IPAQ_ASIC3_GPIO_EdgeTrigger);
4495+ trigger = __asic3_read_register(asic,
4496+ bank + _IPAQ_ASIC3_GPIO_TriggerType);
4497+ asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit;
4498+
4499+ if (type == IRQT_RISING) {
4500+ trigger |= bit;
4501+ edge |= bit;
4502+ } else if (type == IRQT_FALLING) {
4503+ trigger |= bit;
4504+ edge &= ~bit;
4505+ } else if (type == IRQT_BOTHEDGE) {
4506+ trigger |= bit;
4507+ if (asic3_gpio_get_value(asic->dev, irq - asic->irq_base))
4508+ edge &= ~bit;
4509+ else
4510+ edge |= bit;
4511+ asic->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit;
4512+ } else if (type == IRQT_LOW) {
4513+ trigger &= ~bit;
4514+ level &= ~bit;
4515+ } else if (type == IRQT_HIGH) {
4516+ trigger &= ~bit;
4517+ level |= bit;
4518+ } else {
4519+ /*
4520+ * if type == IRQT_NOEDGE, we should mask interrupts, but
4521+ * be careful to not unmask them if mask was also called.
4522+ * Probably need internal state for mask.
4523+ */
4524+ printk(KERN_NOTICE "asic3: irq type not changed.\n");
4525+ }
4526+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_LevelTrigger,
4527+ level);
4528+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_EdgeTrigger,
4529+ edge);
4530+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_TriggerType,
4531+ trigger);
4532+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4533+ return 0;
4534+}
4535+
4536+static struct irq_chip asic3_gpio_irq_chip = {
4537+ .name = "ASIC3-GPIO",
4538+ .ack = asic3_mask_gpio_irq,
4539+ .mask = asic3_mask_gpio_irq,
4540+ .unmask = asic3_unmask_gpio_irq,
4541+ .set_type = asic3_gpio_irq_type,
4542+};
4543+
4544+static struct irq_chip asic3_irq_chip = {
4545+ .name = "ASIC3",
4546+ .ack = asic3_mask_irq,
4547+ .mask = asic3_mask_irq,
4548+ .unmask = asic3_unmask_irq,
4549+};
4550+
4551+static void asic3_release(struct device *dev)
4552+{
4553+ struct platform_device *sdev = to_platform_device(dev);
4554+
4555+ kfree(sdev->resource);
4556+ kfree(sdev);
4557+}
4558+
4559+int asic3_register_mmc(struct device *dev)
4560+{
4561+ struct platform_device *sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
4562+ struct tmio_mmc_hwconfig *mmc_config = kmalloc(sizeof(*mmc_config),
4563+ GFP_KERNEL);
4564+ struct platform_device *pdev = to_platform_device(dev);
4565+ struct asic3_data *asic = dev->driver_data;
4566+ struct asic3_platform_data *asic3_pdata = dev->platform_data;
4567+ struct resource *res;
4568+ int rc;
4569+
4570+ if (sdev == NULL || mmc_config == NULL)
4571+ return -ENOMEM;
4572+
4573+ if (asic3_pdata->tmio_mmc_hwconfig) {
4574+ memcpy(mmc_config, asic3_pdata->tmio_mmc_hwconfig,
4575+ sizeof(*mmc_config));
4576+ } else {
4577+ memset(mmc_config, 0, sizeof(*mmc_config));
4578+ }
4579+ mmc_config->address_shift = asic->bus_shift;
4580+
4581+ sdev->id = -1;
4582+ sdev->name = "asic3_mmc";
4583+ sdev->dev.parent = dev;
4584+ sdev->num_resources = 2;
4585+ sdev->dev.platform_data = mmc_config;
4586+ sdev->dev.release = asic3_release;
4587+
4588+ res = kzalloc(sdev->num_resources * sizeof(struct resource),
4589+ GFP_KERNEL);
4590+ if (res == NULL) {
4591+ kfree(sdev);
4592+ kfree(mmc_config);
4593+ return -ENOMEM;
4594+ }
4595+ sdev->resource = res;
4596+
4597+ res[0].start = pdev->resource[2].start;
4598+ res[0].end = pdev->resource[2].end;
4599+ res[0].flags = IORESOURCE_MEM;
4600+ res[1].start = res[1].end = pdev->resource[3].start;
4601+ res[1].flags = IORESOURCE_IRQ;
4602+
4603+ rc = platform_device_register(sdev);
4604+ if (rc) {
4605+ printk(KERN_ERR "asic3_base: "
4606+ "Could not register asic3_mmc device\n");
4607+ kfree(res);
4608+ kfree(sdev);
4609+ return rc;
4610+ }
4611+
4612+ asic->mmc_dev = sdev;
4613+
4614+ return 0;
4615+}
4616+EXPORT_SYMBOL(asic3_register_mmc);
4617+
4618+int asic3_unregister_mmc(struct device *dev)
4619+{
4620+ struct asic3_data *asic = dev->driver_data;
4621+ platform_device_unregister(asic->mmc_dev);
4622+ asic->mmc_dev = 0;
4623+
4624+ return 0;
4625+}
4626+EXPORT_SYMBOL(asic3_unregister_mmc);
4627+
4628+#ifdef CONFIG_HTC_ASIC3_DS1WM
4629+/*
4630+ * DS1WM subdevice
4631+ */
4632+
4633+static void asic3_ds1wm_enable(struct platform_device *ds1wm_dev)
4634+{
4635+ struct device *dev = ds1wm_dev->dev.parent;
4636+
4637+ /* Turn on external clocks and the OWM clock */
4638+ asic3_set_clock_cdex(dev,
4639+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | CLOCK_CDEX_OWM,
4640+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | CLOCK_CDEX_OWM);
4641+
4642+ mdelay(1);
4643+
4644+ asic3_set_extcf_reset(dev, ASIC3_EXTCF_OWM_RESET,
4645+ ASIC3_EXTCF_OWM_RESET);
4646+ mdelay(1);
4647+ asic3_set_extcf_reset(dev, ASIC3_EXTCF_OWM_RESET, 0);
4648+ mdelay(1);
4649+
4650+ /* Clear OWM_SMB, set OWM_EN */
4651+ asic3_set_extcf_select(dev,
4652+ ASIC3_EXTCF_OWM_SMB | ASIC3_EXTCF_OWM_EN,
4653+ 0 | ASIC3_EXTCF_OWM_EN);
4654+
4655+ mdelay(1);
4656+}
4657+
4658+static void asic3_ds1wm_disable(struct platform_device *ds1wm_dev)
4659+{
4660+ struct device *dev = ds1wm_dev->dev.parent;
4661+
4662+ asic3_set_extcf_select(dev,
4663+ ASIC3_EXTCF_OWM_SMB | ASIC3_EXTCF_OWM_EN,
4664+ 0 | 0);
4665+
4666+ asic3_set_clock_cdex(dev,
4667+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | CLOCK_CDEX_OWM,
4668+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | 0);
4669+}
4670+
4671+
4672+static struct resource asic3_ds1wm_resources[] = {
4673+ {
4674+ .start = _IPAQ_ASIC3_OWM_Base,
4675+ .end = _IPAQ_ASIC3_OWM_Base + 0x14 - 1,
4676+ .flags = IORESOURCE_MEM,
4677+ },
4678+ {
4679+ .start = ASIC3_OWM_IRQ,
4680+ .end = ASIC3_OWM_IRQ,
4681+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
4682+ IORESOURCE_IRQ_SOC_SUBDEVICE,
4683+ },
4684+};
4685+
4686+static struct ds1wm_platform_data ds1wm_pd = {
4687+ .enable = asic3_ds1wm_enable,
4688+ .disable = asic3_ds1wm_disable,
4689+};
4690+#endif
4691+
4692+static struct soc_device_data asic3_blocks[] = {
4693+#ifdef CONFIG_HTC_ASIC3_DS1WM
4694+ {
4695+ .name = "ds1wm",
4696+ .res = asic3_ds1wm_resources,
4697+ .num_resources = ARRAY_SIZE(asic3_ds1wm_resources),
4698+ .hwconfig = &ds1wm_pd,
4699+ },
4700+#endif
4701+};
4702+
4703+static int asic3_probe(struct platform_device *pdev)
4704+{
4705+ struct asic3_platform_data *pdata = pdev->dev.platform_data;
4706+ struct asic3_data *asic;
4707+ struct device *dev = &pdev->dev;
4708+ unsigned long clksel;
4709+ int i, rc;
4710+
4711+ asic = kzalloc(sizeof(struct asic3_data), GFP_KERNEL);
4712+ if (!asic)
4713+ return -ENOMEM;
4714+
4715+ platform_set_drvdata(pdev, asic);
4716+ asic->dev = &pdev->dev;
4717+
4718+ asic->mapping = ioremap(pdev->resource[0].start, IPAQ_ASIC3_MAP_SIZE);
4719+ if (!asic->mapping) {
4720+ printk(KERN_ERR "asic3: couldn't ioremap ASIC3\n");
4721+ kfree (asic);
4722+ return -ENOMEM;
4723+ }
4724+
4725+ if (pdata && pdata->bus_shift)
4726+ asic->bus_shift = pdata->bus_shift;
4727+ else
4728+ asic->bus_shift = 2;
4729+
4730+ /* XXX: should get correct SD clock values from pdata struct */
4731+ clksel = 0;
4732+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL), clksel);
4733+
4734+ /* Register ASIC3's clocks. */
4735+ clk_g.ctrlbit = (int)asic;
4736+
4737+ if (clk_register(&clk_g) < 0)
4738+ printk(KERN_ERR "asic3: failed to register ASIC3 gclk\n");
4739+
4740+ for (i = 0; i < ARRAY_SIZE(asic3_clocks); i++) {
4741+ rc = clk_register(&asic3_clocks[i]);
4742+ if (rc < 0)
4743+ printk(KERN_ERR "asic3: "
4744+ "failed to register clock %s (%d)\n",
4745+ asic3_clocks[i].name, rc);
4746+ }
4747+
4748+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
4749+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
4750+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
4751+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
4752+
4753+ asic3_set_gpio_sleepmask_a(dev, 0xffff, 0xffff);
4754+ asic3_set_gpio_sleepmask_b(dev, 0xffff, 0xffff);
4755+ asic3_set_gpio_sleepmask_c(dev, 0xffff, 0xffff);
4756+ asic3_set_gpio_sleepmask_d(dev, 0xffff, 0xffff);
4757+
4758+ if (pdata) {
4759+ asic3_set_gpio_out_a(dev, 0xffff, pdata->gpio_a.init);
4760+ asic3_set_gpio_out_b(dev, 0xffff, pdata->gpio_b.init);
4761+ asic3_set_gpio_out_c(dev, 0xffff, pdata->gpio_c.init);
4762+ asic3_set_gpio_out_d(dev, 0xffff, pdata->gpio_d.init);
4763+
4764+ asic3_set_gpio_dir_a(dev, 0xffff, pdata->gpio_a.dir);
4765+ asic3_set_gpio_dir_b(dev, 0xffff, pdata->gpio_b.dir);
4766+ asic3_set_gpio_dir_c(dev, 0xffff, pdata->gpio_c.dir);
4767+ asic3_set_gpio_dir_d(dev, 0xffff, pdata->gpio_d.dir);
4768+
4769+ asic3_set_gpio_sleepmask_a(dev, 0xffff,
4770+ pdata->gpio_a.sleep_mask);
4771+ asic3_set_gpio_sleepmask_b(dev, 0xffff,
4772+ pdata->gpio_b.sleep_mask);
4773+ asic3_set_gpio_sleepmask_c(dev, 0xffff,
4774+ pdata->gpio_c.sleep_mask);
4775+ asic3_set_gpio_sleepmask_d(dev, 0xffff,
4776+ pdata->gpio_d.sleep_mask);
4777+
4778+ asic3_set_gpio_sleepout_a(dev, 0xffff,
4779+ pdata->gpio_a.sleep_out);
4780+ asic3_set_gpio_sleepout_b(dev, 0xffff,
4781+ pdata->gpio_b.sleep_out);
4782+ asic3_set_gpio_sleepout_c(dev, 0xffff,
4783+ pdata->gpio_c.sleep_out);
4784+ asic3_set_gpio_sleepout_d(dev, 0xffff,
4785+ pdata->gpio_d.sleep_out);
4786+
4787+ asic3_set_gpio_battfaultout_a(dev, 0xffff,
4788+ pdata->gpio_a.batt_fault_out);
4789+ asic3_set_gpio_battfaultout_b(dev, 0xffff,
4790+ pdata->gpio_b.batt_fault_out);
4791+ asic3_set_gpio_battfaultout_c(dev, 0xffff,
4792+ pdata->gpio_c.batt_fault_out);
4793+ asic3_set_gpio_battfaultout_d(dev, 0xffff,
4794+ pdata->gpio_d.batt_fault_out);
4795+
4796+ asic3_set_gpio_sleepconf_a(dev, 0xffff,
4797+ pdata->gpio_a.sleep_conf);
4798+ asic3_set_gpio_sleepconf_b(dev, 0xffff,
4799+ pdata->gpio_b.sleep_conf);
4800+ asic3_set_gpio_sleepconf_c(dev, 0xffff,
4801+ pdata->gpio_c.sleep_conf);
4802+ asic3_set_gpio_sleepconf_d(dev, 0xffff,
4803+ pdata->gpio_d.sleep_conf);
4804+
4805+ asic3_set_gpio_alt_fn_a(dev, 0xffff,
4806+ pdata->gpio_a.alt_function);
4807+ asic3_set_gpio_alt_fn_b(dev, 0xffff,
4808+ pdata->gpio_b.alt_function);
4809+ asic3_set_gpio_alt_fn_c(dev, 0xffff,
4810+ pdata->gpio_c.alt_function);
4811+ asic3_set_gpio_alt_fn_d(dev, 0xffff,
4812+ pdata->gpio_d.alt_function);
4813+ }
4814+
4815+ asic->irq_nr = -1;
4816+ asic->irq_base = -1;
4817+
4818+ if (pdev->num_resources > 1)
4819+ asic->irq_nr = pdev->resource[1].start;
4820+
4821+ if (asic->irq_nr != -1) {
4822+ unsigned int i;
4823+
4824+ if (!pdata->irq_base) {
4825+ printk(KERN_ERR "asic3: IRQ base not specified\n");
4826+ asic3_remove(pdev);
4827+ return -EINVAL;
4828+ }
4829+
4830+ asic->irq_base = pdata->irq_base;
4831+
4832+ /* turn on clock to IRQ controller */
4833+ clksel |= CLOCK_SEL_CX;
4834+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL),
4835+ clksel);
4836+
4837+ printk(KERN_INFO "asic3: using irq %d-%d on irq %d\n",
4838+ asic->irq_base, asic->irq_base + ASIC3_NR_IRQS - 1,
4839+ asic->irq_nr);
4840+
4841+ for (i = 0 ; i < ASIC3_NR_IRQS ; i++) {
4842+ int irq = i + asic->irq_base;
4843+ if (i < ASIC3_NR_GPIO_IRQS) {
4844+ set_irq_chip(irq, &asic3_gpio_irq_chip);
4845+ set_irq_chip_data(irq, asic);
4846+ set_irq_handler(irq, handle_level_irq);
4847+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
4848+ } else {
4849+ /* The remaining IRQs are not GPIO */
4850+ set_irq_chip(irq, &asic3_irq_chip);
4851+ set_irq_chip_data(irq, asic);
4852+ set_irq_handler(irq, handle_level_irq);
4853+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
4854+ }
4855+ }
4856+
4857+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask),
4858+ ASIC3_INTMASK_GINTMASK);
4859+
4860+ set_irq_chained_handler(asic->irq_nr, asic3_irq_demux);
4861+ set_irq_type(asic->irq_nr, IRQT_RISING);
4862+ set_irq_data(asic->irq_nr, asic);
4863+ }
4864+
4865+#ifdef CONFIG_HTC_ASIC3_DS1WM
4866+ ds1wm_pd.bus_shift = asic->bus_shift;
4867+#endif
4868+
4869+ pdata->gpiodev_ops.get = asic3_gpio_get_value;
4870+ pdata->gpiodev_ops.set = asic3_gpio_set_value;
4871+ pdata->gpiodev_ops.to_irq = asic3_gpio_to_irq;
4872+
4873+ soc_add_devices(pdev, asic3_blocks, ARRAY_SIZE(asic3_blocks),
4874+ &pdev->resource[0],
4875+ asic->bus_shift - ASIC3_DEFAULT_ADDR_SHIFT,
4876+ asic->irq_base);
4877+
4878+ if (pdev->num_resources > 2) {
4879+ int rc;
4880+ rc = asic3_register_mmc(dev);
4881+ if (rc) {
4882+ asic3_remove(pdev);
4883+ return rc;
4884+ }
4885+ }
4886+
4887+ if (pdata && pdata->num_child_platform_devs != 0)
4888+ platform_add_devices(pdata->child_platform_devs,
4889+ pdata->num_child_platform_devs);
4890+
4891+ return 0;
4892+}
4893+
4894+static int asic3_remove(struct platform_device *pdev)
4895+{
4896+ struct asic3_platform_data *pdata = pdev->dev.platform_data;
4897+ struct asic3_data *asic = platform_get_drvdata(pdev);
4898+ int i;
4899+
4900+ if (pdata && pdata->num_child_platform_devs != 0) {
4901+ for (i = 0; i < pdata->num_child_platform_devs; i++) {
4902+ platform_device_unregister(
4903+ pdata->child_platform_devs[i]);
4904+ }
4905+ }
4906+
4907+ if (asic->irq_nr != -1) {
4908+ unsigned int i;
4909+
4910+ for (i = 0 ; i < ASIC3_NR_IRQS ; i++) {
4911+ int irq = i + asic->irq_base;
4912+ set_irq_flags(irq, 0);
4913+ set_irq_handler (irq, NULL);
4914+ set_irq_chip (irq, NULL);
4915+ set_irq_chip_data(irq, NULL);
4916+ }
4917+
4918+ set_irq_chained_handler(asic->irq_nr, NULL);
4919+ }
4920+
4921+ if (asic->mmc_dev)
4922+ asic3_unregister_mmc(&pdev->dev);
4923+
4924+ for (i = 0; i < ARRAY_SIZE(asic3_clocks); i++)
4925+ clk_unregister(&asic3_clocks[i]);
4926+ clk_unregister(&clk_g);
4927+
4928+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL), 0);
4929+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask), 0);
4930+
4931+ iounmap(asic->mapping);
4932+
4933+ kfree(asic);
4934+
4935+ return 0;
4936+}
4937+
4938+static void asic3_shutdown(struct platform_device *pdev)
4939+{
4940+}
4941+
4942+#define ASIC3_SUSPEND_CDEX_MASK \
4943+ (CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2)
4944+static unsigned short suspend_cdex;
4945+
4946+static int asic3_suspend(struct platform_device *pdev, pm_message_t state)
4947+{
4948+ struct asic3_data *asic = platform_get_drvdata(pdev);
4949+ suspend_cdex = __asic3_read_register(asic,
4950+ _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX);
4951+ /* The LEDs are still active during suspend */
4952+ __asic3_write_register(asic,
4953+ _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX,
4954+ suspend_cdex & ASIC3_SUSPEND_CDEX_MASK);
4955+ return 0;
4956+}
4957+
4958+static int asic3_resume(struct platform_device *pdev)
4959+{
4960+ struct asic3_data *asic = platform_get_drvdata(pdev);
4961+ unsigned short intmask;
4962+
4963+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX),
4964+ suspend_cdex);
4965+
4966+ if (asic->irq_nr != -1) {
4967+ /* Toggle the interrupt mask to try to get ASIC3 to show
4968+ * the CPU an interrupt edge. For more details see the
4969+ * kernel-discuss thread around 13 June 2005 with the
4970+ * subject "asic3 suspend / resume". */
4971+ intmask = __asic3_read_register(asic,
4972+ IPAQ_ASIC3_OFFSET(INTR, IntMask));
4973+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask),
4974+ intmask & ~ASIC3_INTMASK_GINTMASK);
4975+ mdelay(1);
4976+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask),
4977+ intmask | ASIC3_INTMASK_GINTMASK);
4978+ }
4979+
4980+ return 0;
4981+}
4982+
4983+static struct platform_driver asic3_device_driver = {
4984+ .driver = {
4985+ .name = "asic3",
4986+ },
4987+ .probe = asic3_probe,
4988+ .remove = asic3_remove,
4989+ .suspend = asic3_suspend,
4990+ .resume = asic3_resume,
4991+ .shutdown = asic3_shutdown,
4992+};
4993+
4994+static int __init asic3_base_init(void)
4995+{
4996+ int retval = 0;
4997+ retval = platform_driver_register(&asic3_device_driver);
4998+ return retval;
4999+}
5000+
5001+static void __exit asic3_base_exit(void)
5002+{
5003+ platform_driver_unregister(&asic3_device_driver);
5004+}
5005+
5006+#ifdef MODULE
5007+module_init(asic3_base_init);
5008+#else /* start early for dependencies */
5009+subsys_initcall(asic3_base_init);
5010+#endif
5011+module_exit(asic3_base_exit);
5012+
5013+MODULE_LICENSE("GPL");
5014+MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
5015+MODULE_DESCRIPTION("Core driver for HTC ASIC3");
5016+MODULE_SUPPORTED_DEVICE("asic3");
5017Index: linux-2.6.22/drivers/mfd/soc-core.c
5018===================================================================
5019--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5020+++ linux-2.6.22/drivers/mfd/soc-core.c 2007-09-11 12:53:37.000000000 +0200
5021@@ -0,0 +1,106 @@
5022+/*
5023+ * drivers/soc/soc-core.c
5024+ *
5025+ * core SoC support
5026+ * Copyright (c) 2006 Ian Molton
5027+ *
5028+ * This program is free software; you can redistribute it and/or modify
5029+ * it under the terms of the GNU General Public License version 2 as
5030+ * published by the Free Software Foundation.
5031+ *
5032+ * This file contains functionality used by many SoC type devices.
5033+ *
5034+ * Created: 2006-11-28
5035+ *
5036+ */
5037+
5038+#include <linux/ioport.h>
5039+#include <linux/slab.h>
5040+#include <linux/kernel.h>
5041+#include <linux/platform_device.h>
5042+#include "soc-core.h"
5043+
5044+void soc_free_devices(struct platform_device *devices, int nr_devs)
5045+{
5046+ struct platform_device *dev = devices;
5047+ int i;
5048+
5049+ for (i = 0; i < nr_devs; i++) {
5050+ struct resource *res = dev->resource;
5051+ platform_device_unregister(dev++);
5052+ kfree(res);
5053+ }
5054+ kfree(devices);
5055+}
5056+EXPORT_SYMBOL_GPL(soc_free_devices);
5057+
5058+#define SIGNED_SHIFT(val, shift) ((shift) >= 0 ? ((val) << (shift)) : ((val) >> -(shift)))
5059+
5060+struct platform_device *soc_add_devices(struct platform_device *dev,
5061+ struct soc_device_data *soc, int nr_devs,
5062+ struct resource *mem,
5063+ int relative_addr_shift, int irq_base)
5064+{
5065+ struct platform_device *devices;
5066+ int i, r, base;
5067+
5068+ devices = kzalloc(nr_devs * sizeof(struct platform_device), GFP_KERNEL);
5069+ if (!devices)
5070+ return NULL;
5071+
5072+ for (i = 0; i < nr_devs; i++) {
5073+ struct platform_device *sdev = &devices[i];
5074+ struct soc_device_data *blk = &soc[i];
5075+ struct resource *res;
5076+
5077+ sdev->id = -1;
5078+ sdev->name = blk->name;
5079+
5080+ sdev->dev.parent = &dev->dev;
5081+ sdev->dev.platform_data = (void *)blk->hwconfig;
5082+ sdev->num_resources = blk->num_resources;
5083+
5084+ /* Allocate space for the subdevice resources */
5085+ res = kzalloc (blk->num_resources * sizeof (struct resource), GFP_KERNEL);
5086+ if (!res)
5087+ goto fail;
5088+
5089+ for (r = 0 ; r < blk->num_resources ; r++) {
5090+ res[r].name = blk->res[r].name; // Fixme - should copy
5091+
5092+ /* Find out base to use */
5093+ base = 0;
5094+ if (blk->res[r].flags & IORESOURCE_MEM) {
5095+ base = mem->start;
5096+ } else if ((blk->res[r].flags & IORESOURCE_IRQ) &&
5097+ (blk->res[r].flags & IORESOURCE_IRQ_SOC_SUBDEVICE)) {
5098+ base = irq_base;
5099+ }
5100+
5101+ /* Adjust resource */
5102+ if (blk->res[r].flags & IORESOURCE_MEM) {
5103+ res[r].parent = mem;
5104+ res[r].start = base + SIGNED_SHIFT(blk->res[r].start, relative_addr_shift);
5105+ res[r].end = base + SIGNED_SHIFT(blk->res[r].end, relative_addr_shift);
5106+ } else {
5107+ res[r].start = base + blk->res[r].start;
5108+ res[r].end = base + blk->res[r].end;
5109+ }
5110+ res[r].flags = blk->res[r].flags;
5111+ }
5112+
5113+ sdev->resource = res;
5114+ if (platform_device_register(sdev)) {
5115+ kfree(res);
5116+ goto fail;
5117+ }
5118+
5119+ printk(KERN_INFO "SoC: registering %s\n", blk->name);
5120+ }
5121+ return devices;
5122+
5123+fail:
5124+ soc_free_devices(devices, i + 1);
5125+ return NULL;
5126+}
5127+EXPORT_SYMBOL_GPL(soc_add_devices);
5128Index: linux-2.6.22/drivers/mfd/soc-core.h
5129===================================================================
5130--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5131+++ linux-2.6.22/drivers/mfd/soc-core.h 2007-09-11 12:53:37.000000000 +0200
5132@@ -0,0 +1,30 @@
5133+/*
5134+ * drivers/soc/soc-core.h
5135+ *
5136+ * core SoC support
5137+ * Copyright (c) 2006 Ian Molton
5138+ *
5139+ * This program is free software; you can redistribute it and/or modify
5140+ * it under the terms of the GNU General Public License version 2 as
5141+ * published by the Free Software Foundation.
5142+ *
5143+ * This file contains prototypes for the functions in soc-core.c
5144+ *
5145+ * Created: 2006-11-28
5146+ *
5147+ */
5148+
5149+struct soc_device_data {
5150+ char *name;
5151+ struct resource *res;
5152+ int num_resources;
5153+ void *hwconfig; /* platform_data to pass to the subdevice */
5154+};
5155+
5156+struct platform_device *soc_add_devices(struct platform_device *dev,
5157+ struct soc_device_data *soc, int n_devs,
5158+ struct resource *mem,
5159+ int relative_addr_shift, int irq_base);
5160+
5161+void soc_free_devices(struct platform_device *devices, int nr_devs);
5162+
5163Index: linux-2.6.22/include/asm-arm/arch-pxa/clock.h
5164===================================================================
5165--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5166+++ linux-2.6.22/include/asm-arm/arch-pxa/clock.h 2007-09-11 12:53:37.000000000 +0200
5167@@ -0,0 +1,27 @@
5168+/*
5169+ * linux/include/asm-arm/arch-pxa/clock.h
5170+ *
5171+ * Copyright (C) 2006 Erik Hovland
5172+ *
5173+ * This program is free software; you can redistribute it and/or modify
5174+ * it under the terms of the GNU General Public License version 2 as
5175+ * published by the Free Software Foundation.
5176+ */
5177+
5178+struct clk {
5179+ struct list_head node;
5180+ struct module *owner;
5181+ struct clk *parent;
5182+ const char *name;
5183+ int id;
5184+ unsigned int enabled;
5185+ unsigned long rate;
5186+ unsigned long ctrlbit;
5187+
5188+ void (*enable)(struct clk *);
5189+ void (*disable)(struct clk *);
5190+};
5191+
5192+
5193+extern int clk_register(struct clk *clk);
5194+extern void clk_unregister(struct clk *clk);
5195Index: linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal-asic.h
5196===================================================================
5197--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5198+++ linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal-asic.h 2007-09-11 12:53:37.000000000 +0200
5199@@ -0,0 +1,213 @@
5200+/*
5201+ * include/asm/arm/arch-pxa/htcuniversal-asic.h
5202+ *
5203+ * Authors: Giuseppe Zompatori <giuseppe_zompatori@yahoo.it>
5204+ *
5205+ * based on previews work, see below:
5206+ *
5207+ * include/asm/arm/arch-pxa/hx4700-asic.h
5208+ * Copyright (c) 2004 SDG Systems, LLC
5209+ *
5210+ */
5211+
5212+#ifndef _HTCUNIVERSAL_ASIC_H_
5213+#define _HTCUNIVERSAL_ASIC_H_
5214+
5215+#include <asm/hardware/ipaq-asic3.h>
5216+
5217+/* ASIC3 */
5218+
5219+#define HTCUNIVERSAL_ASIC3_GPIO_PHYS PXA_CS4_PHYS
5220+#define HTCUNIVERSAL_ASIC3_MMC_PHYS PXA_CS3_PHYS
5221+
5222+/* TODO: some information is missing here */
5223+
5224+/* ASIC3 GPIO A bank */
5225+
5226+#define GPIOA_I2C_EN 0 /* Output */
5227+#define GPIOA_SPK_PWR1_ON 1 /* Output */
5228+#define GPIOA_AUDIO_PWR_ON 2 /* Output */
5229+#define GPIOA_EARPHONE_PWR_ON 3 /* Output */
5230+
5231+#define GPIOA_UNKNOWN4 4 /* Output */
5232+#define GPIOA_BUTTON_BACKLIGHT_N 5 /* Input */
5233+#define GPIOA_SPK_PWR2_ON 6 /* Output */
5234+#define GPIOA_BUTTON_RECORD_N 7 /* Input */
5235+
5236+#define GPIOA_BUTTON_CAMERA_N 8 /* Input */
5237+#define GPIOA_UNKNOWN9 9 /* Output */
5238+#define GPIOA_FLASHLIGHT 10 /* Output */
5239+#define GPIOA_COVER_ROTATE_N 11 /* Input */
5240+
5241+#define GPIOA_TOUCHSCREEN_N 12 /* Input */
5242+#define GPIOA_VOL_UP_N 13 /* Input */
5243+#define GPIOA_VOL_DOWN_N 14 /* Input */
5244+#define GPIOA_LCD_PWR5_ON 15 /* Output */
5245+
5246+/* ASIC3 GPIO B bank */
5247+
5248+#define GPIOB_BB_READY 0 /* Input */
5249+#define GPIOB_CODEC_PDN 1 /* Output */
5250+#define GPIOB_UNKNOWN2 2 /* Input */
5251+#define GPIOB_BB_UNKNOWN3 3 /* Input */
5252+
5253+#define GPIOB_BT_IRQ 4 /* Input */
5254+#define GPIOB_CLAMSHELL_N 5 /* Input */
5255+#define GPIOB_LCD_PWR3_ON 6 /* Output */
5256+#define GPIOB_BB_ALERT 7 /* Input */
5257+
5258+#define GPIOB_BB_RESET2 8 /* Output */
5259+#define GPIOB_EARPHONE_N 9 /* Input */
5260+#define GPIOB_MICRECORD_N 10 /* Input */
5261+#define GPIOB_NIGHT_SENSOR 11 /* Input */
5262+
5263+#define GPIOB_UMTS_DCD 12 /* Input */
5264+#define GPIOB_UNKNOWN13 13 /* Input */
5265+#define GPIOB_CHARGE_EN 14 /* Output */
5266+#define GPIOB_USB_PUEN 15 /* Output */
5267+
5268+/* ASIC3 GPIO C bank */
5269+
5270+#define GPIOC_LED_BTWIFI 0 /* Output */
5271+#define GPIOC_LED_RED 1 /* Output */
5272+#define GPIOC_LED_GREEN 2 /* Output */
5273+#define GPIOC_BOARDID3 3 /* Input */
5274+
5275+#define GPIOC_WIFI_IRQ_N 4 /* Input */
5276+#define GPIOC_WIFI_RESET 5 /* Output */
5277+#define GPIOC_WIFI_PWR1_ON 6 /* Output */
5278+#define GPIOC_BT_RESET 7 /* Output */
5279+
5280+#define GPIOC_UNKNOWN8 8 /* Output */
5281+#define GPIOC_LCD_PWR1_ON 9 /* Output */
5282+#define GPIOC_LCD_PWR2_ON 10 /* Output */
5283+#define GPIOC_BOARDID2 11 /* Input */
5284+
5285+#define GPIOC_BOARDID1 12 /* Input */
5286+#define GPIOC_BOARDID0 13 /* Input */
5287+#define GPIOC_BT_PWR_ON 14 /* Output */
5288+#define GPIOC_CHARGE_ON 15 /* Output */
5289+
5290+/* ASIC3 GPIO D bank */
5291+
5292+#define GPIOD_KEY_OK_N 0 /* Input */
5293+#define GPIOD_KEY_RIGHT_N 1 /* Input */
5294+#define GPIOD_KEY_LEFT_N 2 /* Input */
5295+#define GPIOD_KEY_DOWN_N 3 /* Input */
5296+
5297+#define GPIOD_KEY_UP_N 4 /* Input */
5298+#define GPIOD_SDIO_DET 5 /* Input */
5299+#define GPIOD_WIFI_PWR2_ON 6 /* Output */
5300+#define GPIOD_HW_REBOOT 7 /* Output */
5301+
5302+#define GPIOD_BB_RESET1 8 /* Output */
5303+#define GPIOD_UNKNOWN9 9 /* Output */
5304+#define GPIOD_VIBRA_PWR_ON 10 /* Output */
5305+#define GPIOD_WIFI_PWR3_ON 11 /* Output */
5306+
5307+#define GPIOD_FL_PWR_ON 12 /* Output */
5308+#define GPIOD_LCD_PWR4_ON 13 /* Output */
5309+#define GPIOD_BL_KEYP_PWR_ON 14 /* Output */
5310+#define GPIOD_BL_KEYB_PWR_ON 15 /* Output */
5311+
5312+extern struct platform_device htcuniversal_asic3;
5313+
5314+/* ASIC3 GPIO A bank */
5315+
5316+#define GPIO_I2C_EN 0*16+GPIOA_I2C_EN
5317+#define GPIO_SPK_PWR1_ON 0*16+GPIOA_SPK_PWR1_ON
5318+#define GPIO_AUDIO_PWR_ON 0*16+GPIOA_AUDIO_PWR_ON
5319+#define GPIO_EARPHONE_PWR_ON 0*16+GPIOA_EARPHONE_PWR_ON
5320+
5321+#define GPIO_UNKNOWNA4 0*16+GPIOA_UNKNOWN4
5322+#define GPIO_BUTTON_BACKLIGHT_N 0*16+GPIOA_BUTTON_BACKLIGHT_N
5323+#define GPIO_SPK_PWR2_ON 0*16+GPIOA_SPK_PWR2_ON
5324+#define GPIO_BUTTON_RECORD_N 0*16+GPIOA_BUTTON_RECORD_N
5325+
5326+#define GPIO_BUTTON_CAMERA_N 0*16+GPIOA_BUTTON_CAMERA_N
5327+#define GPIO_UNKNOWNA9 0*16+GPIOA_UNKNOWN9
5328+#define GPIO_FLASHLIGHT 0*16+GPIOA_FLASHLIGHT
5329+#define GPIO_COVER_ROTATE_N 0*16+GPIOA_COVER_ROTATE_N
5330+
5331+#define GPIO_TOUCHSCREEN_N 0*16+GPIOA_TOUCHSCREEN_N
5332+#define GPIO_VOL_UP_N 0*16+GPIOA_VOL_UP_N
5333+#define GPIO_VOL_DOWN_N 0*16+GPIOA_VOL_DOWN_N
5334+#define GPIO_LCD_PWR5_ON 0*16+GPIOA_LCD_PWR5_ON
5335+
5336+/* ASIC3 GPIO B bank */
5337+
5338+#define GPIO_BB_READY 1*16+GPIOB_BB_READY
5339+#define GPIO_CODEC_PDN 1*16+GPIOB_CODEC_PDN
5340+#define GPIO_UNKNOWNB2 1*16+GPIOB_UNKNOWN2
5341+#define GPIO_BB_UNKNOWN3 1*16+GPIOB_BB_UNKNOWN3
5342+
5343+#define GPIO_BT_IRQ 1*16+GPIOB_BT_IRQ
5344+#define GPIO_CLAMSHELL_N 1*16+GPIOB_CLAMSHELL_N
5345+#define GPIO_LCD_PWR3_ON 1*16+GPIOB_LCD_PWR3_ON
5346+#define GPIO_BB_ALERT 1*16+GPIOB_BB_ALERT
5347+
5348+#define GPIO_BB_RESET2 1*16+GPIOB_BB_RESET2
5349+#define GPIO_EARPHONE_N 1*16+GPIOB_EARPHONE_N
5350+#define GPIO_MICRECORD_N 1*16+GPIOB_MICRECORD_N
5351+#define GPIO_NIGHT_SENSOR 1*16+GPIOB_NIGHT_SENSOR
5352+
5353+#define GPIO_UMTS_DCD 1*16+GPIOB_UMTS_DCD
5354+#define GPIO_UNKNOWNB13 1*16+GPIOB_UNKNOWN13
5355+#define GPIO_CHARGE_EN 1*16+GPIOB_CHARGE_EN
5356+#define GPIO_USB_PUEN 1*16+GPIOB_USB_PUEN
5357+
5358+/* ASIC3 GPIO C bank */
5359+
5360+#define GPIO_LED_BTWIFI 2*16+GPIOC_LED_BTWIFI
5361+#define GPIO_LED_RED 2*16+GPIOC_LED_RED
5362+#define GPIO_LED_GREEN 2*16+GPIOC_LED_GREEN
5363+#define GPIO_BOARDID3 2*16+GPIOC_BOARDID3
5364+
5365+#define GPIO_WIFI_IRQ_N 2*16+GPIOC_WIFI_IRQ_N
5366+#define GPIO_WIFI_RESET 2*16+GPIOC_WIFI_RESET
5367+#define GPIO_WIFI_PWR1_ON 2*16+GPIOC_WIFI_PWR1_ON
5368+#define GPIO_BT_RESET 2*16+GPIOC_BT_RESET
5369+
5370+#define GPIO_UNKNOWNC8 2*16+GPIOC_UNKNOWN8
5371+#define GPIO_LCD_PWR1_ON 2*16+GPIOC_LCD_PWR1_ON
5372+#define GPIO_LCD_PWR2_ON 2*16+GPIOC_LCD_PWR2_ON
5373+#define GPIO_BOARDID2 2*16+GPIOC_BOARDID2
5374+
5375+#define GPIO_BOARDID1 2*16+GPIOC_BOARDID1
5376+#define GPIO_BOARDID0 2*16+GPIOC_BOARDID0
5377+#define GPIO_BT_PWR_ON 2*16+GPIOC_BT_PWR_ON
5378+#define GPIO_CHARGE_ON 2*16+GPIOC_CHARGE_ON
5379+
5380+/* ASIC3 GPIO D bank */
5381+
5382+#define GPIO_KEY_OK_N 3*16+GPIOD_KEY_OK_N
5383+#define GPIO_KEY_RIGHT_N 3*16+GPIOD_KEY_RIGHT_N
5384+#define GPIO_KEY_LEFT_N 3*16+GPIOD_KEY_LEFT_N
5385+#define GPIO_KEY_DOWN_N 3*16+GPIOD_KEY_DOWN_N
5386+
5387+#define GPIO_KEY_UP_N 3*16+GPIOD_KEY_UP_N
5388+#define GPIO_SDIO_DET 3*16+GPIOD_SDIO_DET
5389+#define GPIO_WIFI_PWR2_ON 3*16+GPIOD_WIFI_PWR2_ON
5390+#define GPIO_HW_REBOOT 3*16+GPIOD_HW_REBOOT
5391+
5392+#define GPIO_BB_RESET1 3*16+GPIOD_BB_RESET1
5393+#define GPIO_UNKNOWND9 3*16+GPIOD_UNKNOWN9
5394+#define GPIO_VIBRA_PWR_ON 3*16+GPIOD_VIBRA_PWR_ON
5395+#define GPIO_WIFI_PWR3_ON 3*16+GPIOD_WIFI_PWR3_ON
5396+
5397+#define GPIO_FL_PWR_ON 3*16+GPIOD_FL_PWR_ON
5398+#define GPIO_LCD_PWR4_ON 3*16+GPIOD_LCD_PWR4_ON
5399+#define GPIO_BL_KEYP_PWR_ON 3*16+GPIOD_BL_KEYP_PWR_ON
5400+#define GPIO_BL_KEYB_PWR_ON 3*16+GPIOD_BL_KEYB_PWR_ON
5401+
5402+#define HTCUNIVERSAL_EGPIO_BASE PXA_CS2_PHYS+0x02000000
5403+
5404+#define EGPIO4_ON 4 /* something */
5405+#define EGPIO5_BT_3V3_ON 5 /* Bluetooth related */
5406+#define EGPIO6_WIFI_ON 6 /* WLAN related*/
5407+
5408+extern void htcuniversal_egpio_enable( u_int16_t bits );
5409+extern void htcuniversal_egpio_disable( u_int16_t bits );
5410+
5411+#endif /* _HTCUNIVERSAL_ASIC_H_ */
5412+
5413Index: linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal-gpio.h
5414===================================================================
5415--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5416+++ linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal-gpio.h 2007-09-11 12:53:37.000000000 +0200
5417@@ -0,0 +1,220 @@
5418+/*
5419+ * include/asm-arm/arch-pxa/htcuniversal-gpio.h
5420+ * History:
5421+ *
5422+ * 2004-12-10 Michael Opdenacker. Wrote down GPIO settings as identified by Jamey Hicks.
5423+ * Reused the h2200-gpio.h file as a template.
5424+ */
5425+
5426+#ifndef _HTCUNIVERSAL_GPIO_H_
5427+#define _HTCUNIVERSAL_GPIO_H_
5428+
5429+#include <asm/arch/pxa-regs.h>
5430+
5431+#define GET_HTCUNIVERSAL_GPIO(gpio) \
5432+ (GPLR(GPIO_NR_HTCUNIVERSAL_ ## gpio) & GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio))
5433+
5434+#define SET_HTCUNIVERSAL_GPIO(gpio, setp) \
5435+do { \
5436+if (setp) \
5437+ GPSR(GPIO_NR_HTCUNIVERSAL_ ## gpio) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio); \
5438+else \
5439+ GPCR(GPIO_NR_HTCUNIVERSAL_ ## gpio) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio); \
5440+} while (0)
5441+
5442+#define SET_HTCUNIVERSAL_GPIO_N(gpio, setp) \
5443+do { \
5444+if (setp) \
5445+ GPCR(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N); \
5446+else \
5447+ GPSR(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N); \
5448+} while (0)
5449+
5450+#define HTCUNIVERSAL_IRQ(gpio) \
5451+ IRQ_GPIO(GPIO_NR_HTCUNIVERSAL_ ## gpio)
5452+
5453+#define GPIO_NR_HTCUNIVERSAL_KEY_ON_N 0
5454+#define GPIO_NR_HTCUNIVERSAL_GP_RST_N 1
5455+
5456+#define GPIO_NR_HTCUNIVERSAL_USB_DET 9
5457+#define GPIO_NR_HTCUNIVERSAL_POWER_DET 10
5458+
5459+#define GPIO_NR_HTCUNIVERSAL_CIF_DD7 12
5460+#define GPIO_NR_HTCUNIVERSAL_ASIC3_SDIO_INT_N 13
5461+#define GPIO_NR_HTCUNIVERSAL_ASIC3_EXT_INT 14
5462+#define GPIO_NR_HTCUNIVERSAL_CS1_N 15
5463+
5464+#define GPIO_NR_HTCUNIVERSAL_CIF_DD6 17
5465+#define GPIO_NR_HTCUNIVERSAL_RDY 18
5466+
5467+#define GPIO_NR_HTCUNIVERSAL_PHONE_START 19
5468+
5469+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT7 22
5470+#define GPIO_NR_HTCUNIVERSAL_SPI_CLK 23
5471+#define GPIO_NR_HTCUNIVERSAL_SPI_FRM 24
5472+#define GPIO_NR_HTCUNIVERSAL_SPI_DO 25
5473+#define GPIO_NR_HTCUNIVERSAL_SPI_DI 26
5474+
5475+#define GPIO_NR_HTCUNIVERSAL_CODEC_ON 27
5476+#define GPIO_NR_HTCUNIVERSAL_I2S_BCK 28
5477+#define GPIO_NR_HTCUNIVERSAL_I2S_DIN 29
5478+#define GPIO_NR_HTCUNIVERSAL_I2S_DOUT 30
5479+#define GPIO_NR_HTCUNIVERSAL_I2S_SYNC 31
5480+
5481+#define GPIO_NR_HTCUNIVERSAL_RS232_ON 32
5482+#define GPIO_NR_HTCUNIVERSAL_CS5_N 33
5483+
5484+#define GPIO_NR_HTCUNIVERSAL_PHONE_RXD 34
5485+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_CTS 35
5486+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN7 36
5487+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN3 37
5488+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN4 38
5489+#define GPIO_NR_HTCUNIVERSAL_PHONE_TXD 39
5490+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT6 40
5491+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_RTS 41
5492+#define GPIO_NR_HTCUNIVERSAL_BT_RXD 42
5493+#define GPIO_NR_HTCUNIVERSAL_BT_TXD 43
5494+#define GPIO_NR_HTCUNIVERSAL_BT_UART_CTS 44
5495+#define GPIO_NR_HTCUNIVERSAL_BT_UART_RTS 45
5496+
5497+#define GPIO_NR_HTCUNIVERSAL_SIR_RXD 42
5498+#define GPIO_NR_HTCUNIVERSAL_SIR_TXD 43
5499+
5500+#define GPIO_NR_HTCUNIVERSAL_POE_N 48
5501+#define GPIO_NR_HTCUNIVERSAL_PWE_N 49
5502+#define GPIO_NR_HTCUNIVERSAL_CIF_DD3 50
5503+#define GPIO_NR_HTCUNIVERSAL_CIF_DD2 51
5504+#define GPIO_NR_HTCUNIVERSAL_CIF_DD4 52
5505+
5506+#define GPIO_NR_HTCUNIVERSAL_CIF_MCLK 53
5507+#define GPIO_NR_HTCUNIVERSAL_CIF_PCLK 54
5508+#define GPIO_NR_HTCUNIVERSAL_CIF_DD1 55
5509+
5510+#define GPIO_NR_HTCUNIVERSAL_LDD0 58
5511+#define GPIO_NR_HTCUNIVERSAL_LDD1 59
5512+#define GPIO_NR_HTCUNIVERSAL_LDD2 60
5513+#define GPIO_NR_HTCUNIVERSAL_LDD3 61
5514+#define GPIO_NR_HTCUNIVERSAL_LDD4 62
5515+#define GPIO_NR_HTCUNIVERSAL_LDD5 63
5516+#define GPIO_NR_HTCUNIVERSAL_LDD6 64
5517+#define GPIO_NR_HTCUNIVERSAL_LDD7 65
5518+#define GPIO_NR_HTCUNIVERSAL_LDD8 66
5519+#define GPIO_NR_HTCUNIVERSAL_LDD9 67
5520+#define GPIO_NR_HTCUNIVERSAL_LDD10 68
5521+#define GPIO_NR_HTCUNIVERSAL_LDD11 69
5522+#define GPIO_NR_HTCUNIVERSAL_LDD12 70
5523+#define GPIO_NR_HTCUNIVERSAL_LDD13 71
5524+#define GPIO_NR_HTCUNIVERSAL_LDD14 72
5525+#define GPIO_NR_HTCUNIVERSAL_LDD15 73
5526+
5527+#define GPIO_NR_HTCUNIVERSAL_LFCLK_RD 74
5528+#define GPIO_NR_HTCUNIVERSAL_LFCLK_A0 75
5529+#define GPIO_NR_HTCUNIVERSAL_LFCLK_WR 76
5530+#define GPIO_NR_HTCUNIVERSAL_LBIAS 77
5531+
5532+#define GPIO_NR_HTCUNIVERSAL_CS2_N 78
5533+#define GPIO_NR_HTCUNIVERSAL_CS3_N 79
5534+#define GPIO_NR_HTCUNIVERSAL_CS4_N 80
5535+#define GPIO_NR_HTCUNIVERSAL_CIF_DD0 81
5536+#define GPIO_NR_HTCUNIVERSAL_CIF_DD5 82
5537+
5538+#define GPIO_NR_HTCUNIVERSAL_CIF_LV 84
5539+#define GPIO_NR_HTCUNIVERSAL_CIF_FV 85
5540+
5541+#define GPIO_NR_HTCUNIVERSAL_LCD1 86
5542+#define GPIO_NR_HTCUNIVERSAL_LCD2 87
5543+
5544+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN5 90
5545+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN6 91
5546+
5547+#define GPIO_NR_HTCUNIVERSAL_DREQ1 97
5548+
5549+#define GPIO_NR_HTCUNIVERSAL_PHONE_RESET 98
5550+
5551+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN0 100
5552+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN1 101
5553+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN2 102
5554+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT0 103
5555+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT1 104
5556+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT2 105
5557+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT3 106
5558+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT4 107
5559+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT5 108
5560+
5561+#define GPIO_NR_HTCUNIVERSAL_PHONE_UNKNOWN 109
5562+#define GPIO_NR_HTCUNIVERSAL_PHONE_OFF 110
5563+
5564+#define GPIO_NR_HTCUNIVERSAL_USB_PUEN 112
5565+#define GPIO_NR_HTCUNIVERSAL_I2S_SYSCLK 113
5566+
5567+#define GPIO_NR_HTCUNIVERSAL_PWM_OUT1 115
5568+
5569+#define GPIO_NR_HTCUNIVERSAL_I2C_SCL 117
5570+#define GPIO_NR_HTCUNIVERSAL_I2C_SDA 118
5571+
5572+#if 0
5573+#define GPIO_NR_HTCUNIVERSAL_CPU_BATT_FAULT_N
5574+#define GPIO_NR_HTCUNIVERSAL_ASIC3_RESET_N
5575+#define GPIO_NR_HTCUNIVERSAL_CHARGE_EN_N
5576+#define GPIO_NR_HTCUNIVERSAL_FLASH_VPEN
5577+#define GPIO_NR_HTCUNIVERSAL_BATT_OFF
5578+#define GPIO_NR_HTCUNIVERSAL_USB_CHARGE_RATE
5579+#define GPIO_NR_HTCUNIVERSAL_BL_DETECT_N
5580+#define GPIO_NR_HTCUNIVERSAL_CPU_HW_RESET_N
5581+#endif
5582+
5583+
5584+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_CLK_MD (23 | GPIO_ALT_FN_2_OUT)
5585+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_FRM_MD (24 | GPIO_ALT_FN_2_OUT)
5586+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DO_MD (25 | GPIO_ALT_FN_2_OUT)
5587+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DI_MD (26 | GPIO_ALT_FN_1_IN)
5588+
5589+#define GPIO_NR_HTCUNIVERSAL_I2S_BCK_MD (28 | GPIO_ALT_FN_1_OUT)
5590+#define GPIO_NR_HTCUNIVERSAL_I2S_DIN_MD (29 | GPIO_ALT_FN_2_IN)
5591+#define GPIO_NR_HTCUNIVERSAL_I2S_DOUT_MD (30 | GPIO_ALT_FN_1_OUT)
5592+#define GPIO_NR_HTCUNIVERSAL_I2S_SYNC_MD (31 | GPIO_ALT_FN_1_OUT)
5593+
5594+#define GPIO_NR_HTCUNIVERSAL_PHONE_RXD_MD (34 | GPIO_ALT_FN_1_IN)
5595+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_CTS_MD (35 | GPIO_ALT_FN_1_IN)
5596+
5597+#define GPIO_NR_HTCUNIVERSAL_PHONE_TXD_MD (39 | GPIO_ALT_FN_2_OUT)
5598+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_RTS_MD (41 | GPIO_ALT_FN_2_OUT)
5599+
5600+#define GPIO_NR_HTCUNIVERSAL_BT_RXD_MD (42 | GPIO_ALT_FN_1_IN)
5601+#define GPIO_NR_HTCUNIVERSAL_BT_TXD_MD (43 | GPIO_ALT_FN_2_OUT)
5602+#define GPIO_NR_HTCUNIVERSAL_BT_UART_CTS_MD (44 | GPIO_ALT_FN_1_IN)
5603+#define GPIO_NR_HTCUNIVERSAL_BT_UART_RTS_MD (45 | GPIO_ALT_FN_2_OUT)
5604+
5605+#define GPIO_NR_HTCUNIVERSAL_SIR_RXD_MD (46 | GPIO_ALT_FN_2_IN)
5606+#define GPIO_NR_HTCUNIVERSAL_SIR_TXD_MD (47 | GPIO_ALT_FN_1_OUT)
5607+
5608+#define GPIO_NR_HTCUNIVERSAL_POE_N_MD (48 | GPIO_ALT_FN_2_OUT | GPIO_DFLT_HIGH)
5609+#define GPIO_NR_HTCUNIVERSAL_PWE_N_MD (49 | GPIO_ALT_FN_2_OUT | GPIO_DFLT_HIGH)
5610+
5611+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN0_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN0 | GPIO_ALT_FN_1_IN)
5612+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN1_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN1 | GPIO_ALT_FN_1_IN)
5613+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN2_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN2 | GPIO_ALT_FN_1_IN)
5614+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN3_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN3 | GPIO_ALT_FN_3_IN)
5615+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN4_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN4 | GPIO_ALT_FN_2_IN)
5616+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN5_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN5 | GPIO_ALT_FN_1_IN)
5617+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN6_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN6 | GPIO_ALT_FN_1_IN)
5618+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN7_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN7 | GPIO_ALT_FN_3_IN)
5619+
5620+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT0_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT0 | GPIO_ALT_FN_2_OUT)
5621+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT1_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT1 | GPIO_ALT_FN_2_OUT)
5622+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT2_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT2 | GPIO_ALT_FN_2_OUT)
5623+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT3_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT3 | GPIO_ALT_FN_2_OUT)
5624+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT4_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT4 | GPIO_ALT_FN_2_OUT)
5625+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT5_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT5 | GPIO_ALT_FN_2_OUT)
5626+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT6_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT6 | GPIO_ALT_FN_1_OUT)
5627+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT7_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT7 | GPIO_ALT_FN_1_OUT)
5628+
5629+
5630+#define GPIO_NR_HTCUNIVERSAL_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT)
5631+
5632+#define GPIO_NR_HTCUNIVERSAL_PWM1OUT_MD (115 | GPIO_ALT_FN_3_OUT)
5633+
5634+#define GPIO_NR_HTCUNIVERSAL_I2C_SCL_MD (117 | GPIO_ALT_FN_1_OUT)
5635+#define GPIO_NR_HTCUNIVERSAL_I2C_SDA_MD (118 | GPIO_ALT_FN_1_OUT)
5636+
5637+#endif /* _HTCUNIVERSAL_GPIO_H */
5638Index: linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal-init.h
5639===================================================================
5640--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5641+++ linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal-init.h 2007-09-11 12:53:37.000000000 +0200
5642@@ -0,0 +1,14 @@
5643+/*
5644+ * include/asm/arm/arch-pxa/htcuniversal-init.h
5645+ * Copyright (c) 2004 SDG Systems, LLC
5646+ */
5647+
5648+#ifndef _HTCUNIVERSAL_INIT_H_
5649+#define _HTCUNIVERSAL_INIT_H_
5650+
5651+/* htcuniversal initialization data should be found here
5652+ * See -init.h files from other devices for details
5653+ */
5654+
5655+#endif /* _HTCUNIVERSAL_INIT_H_ */
5656+
5657Index: linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal.h
5658===================================================================
5659--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5660+++ linux-2.6.22/include/asm-arm/arch-pxa/htcuniversal.h 2007-09-11 12:53:37.000000000 +0200
5661@@ -0,0 +1,3 @@
5662+#include <asm/arch/irqs.h>
5663+
5664+#define HTCUNIVERSAL_ASIC3_IRQ_BASE IRQ_BOARD_START
5665Index: linux-2.6.22/include/asm-arm/arch-pxa/pxa-pm_ll.h
5666===================================================================
5667--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5668+++ linux-2.6.22/include/asm-arm/arch-pxa/pxa-pm_ll.h 2007-09-11 12:53:37.000000000 +0200
5669@@ -0,0 +1,6 @@
5670+struct pxa_ll_pm_ops {
5671+ void (*suspend)(unsigned long);
5672+ void (*resume)(void);
5673+};
5674+
5675+extern struct pxa_ll_pm_ops *pxa_pm_set_ll_ops(struct pxa_ll_pm_ops *new_ops);
5676Index: linux-2.6.22/include/asm-arm/arch-pxa/sharpsl.h
5677===================================================================
5678--- linux-2.6.22.orig/include/asm-arm/arch-pxa/sharpsl.h 2007-07-09 01:32:17.000000000 +0200
5679+++ linux-2.6.22/include/asm-arm/arch-pxa/sharpsl.h 2007-09-11 12:53:37.000000000 +0200
5680@@ -25,12 +25,6 @@
5681 /*
5682 * SharpSL Backlight
5683 */
5684-struct corgibl_machinfo {
5685- int max_intensity;
5686- int default_intensity;
5687- int limit_mask;
5688- void (*set_bl_intensity)(int intensity);
5689-};
5690 extern void corgibl_limit_intensity(int limit);
5691
5692
5693Index: linux-2.6.22/include/asm-arm/hardware/asic3_keys.h
5694===================================================================
5695--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5696+++ linux-2.6.22/include/asm-arm/hardware/asic3_keys.h 2007-09-11 12:53:37.000000000 +0200
5697@@ -0,0 +1,18 @@
5698+#include <linux/input.h>
5699+
5700+struct asic3_keys_button {
5701+ /* Configuration parameters */
5702+ int keycode;
5703+ int gpio;
5704+ int active_low;
5705+ char *desc;
5706+ int type;
5707+ /* Internal state vars - add below */
5708+};
5709+
5710+struct asic3_keys_platform_data {
5711+ struct asic3_keys_button *buttons;
5712+ int nbuttons;
5713+ struct input_dev *input;
5714+ struct device *asic3_dev;
5715+};
5716Index: linux-2.6.22/include/asm-arm/hardware/asic3_leds.h
5717===================================================================
5718--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5719+++ linux-2.6.22/include/asm-arm/hardware/asic3_leds.h 2007-09-11 12:53:37.000000000 +0200
5720@@ -0,0 +1,34 @@
5721+/*
5722+ * LEDs support for HTC ASIC3 devices.
5723+ *
5724+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
5725+ *
5726+ * This file is subject to the terms and conditions of the GNU General Public
5727+ * License. See the file COPYING in the main directory of this archive for
5728+ * more details.
5729+ *
5730+ */
5731+
5732+#include <linux/kernel.h>
5733+#include <linux/init.h>
5734+#include <linux/platform_device.h>
5735+#include <linux/leds.h>
5736+
5737+struct asic3_leds_machinfo;
5738+
5739+struct asic3_led {
5740+ struct led_classdev led_cdev;
5741+ int hw_num; /* Number of "hardware-accelerated" led */
5742+ int gpio_num; /* Number of GPIO if hw_num == -1 */
5743+ struct asic3_leds_machinfo *machinfo;
5744+};
5745+
5746+struct asic3_leds_machinfo {
5747+ int num_leds;
5748+ struct asic3_led *leds;
5749+ struct platform_device *asic3_pdev;
5750+};
5751+
5752+extern int asic3_leds_register(void);
5753+extern void asic3_leds_unregister(void);
5754+
5755Index: linux-2.6.22/include/asm-arm/hardware/ipaq-asic3.h
5756===================================================================
5757--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5758+++ linux-2.6.22/include/asm-arm/hardware/ipaq-asic3.h 2007-09-11 12:53:37.000000000 +0200
5759@@ -0,0 +1,602 @@
5760+/*
5761+ *
5762+ * Definitions for the HTC ASIC3 chip found in several handheld devices
5763+ *
5764+ * Copyright 2001 Compaq Computer Corporation.
5765+ *
5766+ * This program is free software; you can redistribute it and/or modify
5767+ * it under the terms of the GNU General Public License as published by
5768+ * the Free Software Foundation; either version 2 of the License, or
5769+ * (at your option) any later version.
5770+ *
5771+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
5772+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
5773+ * FITNESS FOR ANY PARTICULAR PURPOSE.
5774+ *
5775+ * Author: Andrew Christian
5776+ *
5777+ */
5778+
5779+#ifndef IPAQ_ASIC3_H
5780+#define IPAQ_ASIC3_H
5781+
5782+/****************************************************/
5783+/* IPAQ, ASIC #3, replaces ASIC #1 */
5784+
5785+#define IPAQ_ASIC3_OFFSET(x,y) (_IPAQ_ASIC3_ ## x ## _Base + _IPAQ_ASIC3_ ## x ## _ ## y)
5786+#define IPAQ_ASIC3_GPIO_OFFSET(x,y) (_IPAQ_ASIC3_GPIO_ ## x ## _Base + _IPAQ_ASIC3_GPIO_ ## y)
5787+
5788+
5789+/* All offsets below are specified with the following address bus shift */
5790+#define ASIC3_DEFAULT_ADDR_SHIFT 2
5791+
5792+#define _IPAQ_ASIC3_GPIO_A_Base 0x0000
5793+#define _IPAQ_ASIC3_GPIO_B_Base 0x0100
5794+#define _IPAQ_ASIC3_GPIO_C_Base 0x0200
5795+#define _IPAQ_ASIC3_GPIO_D_Base 0x0300
5796+
5797+#define _IPAQ_ASIC3_GPIO_Mask 0x00 /* R/W 0:don't mask, 1:mask interrupt */
5798+#define _IPAQ_ASIC3_GPIO_Direction 0x04 /* R/W 0:input, 1:output */
5799+#define _IPAQ_ASIC3_GPIO_Out 0x08 /* R/W 0:output low, 1:output high */
5800+#define _IPAQ_ASIC3_GPIO_TriggerType 0x0c /* R/W 0:level, 1:edge */
5801+#define _IPAQ_ASIC3_GPIO_EdgeTrigger 0x10 /* R/W 0:falling, 1:rising */
5802+#define _IPAQ_ASIC3_GPIO_LevelTrigger 0x14 /* R/W 0:low, 1:high level detect */
5803+#define _IPAQ_ASIC3_GPIO_SleepMask 0x18 /* R/W 0:don't mask, 1:mask trigger in sleep mode */
5804+#define _IPAQ_ASIC3_GPIO_SleepOut 0x1c /* R/W level 0:low, 1:high in sleep mode */
5805+#define _IPAQ_ASIC3_GPIO_BattFaultOut 0x20 /* R/W level 0:low, 1:high in batt_fault */
5806+#define _IPAQ_ASIC3_GPIO_IntStatus 0x24 /* R/W 0:none, 1:detect */
5807+#define _IPAQ_ASIC3_GPIO_AltFunction 0x28 /* R/W 0:normal control 1:LED register control */
5808+#define _IPAQ_ASIC3_GPIO_SleepConf 0x2c /* R/W bit 1: autosleep 0: disable gposlpout in normal mode, enable gposlpout in sleep mode */
5809+#define _IPAQ_ASIC3_GPIO_Status 0x30 /* R Pin status */
5810+
5811+#define IPAQ_ASIC3_GPIO_A_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Mask )
5812+#define IPAQ_ASIC3_GPIO_A_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Direction )
5813+#define IPAQ_ASIC3_GPIO_A_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Out )
5814+#define IPAQ_ASIC3_GPIO_A_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, A, TriggerType )
5815+#define IPAQ_ASIC3_GPIO_A_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, A, EdgeTrigger )
5816+#define IPAQ_ASIC3_GPIO_A_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, A, LevelTrigger )
5817+#define IPAQ_ASIC3_GPIO_A_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, A, SleepMask )
5818+#define IPAQ_ASIC3_GPIO_A_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, A, SleepOut )
5819+#define IPAQ_ASIC3_GPIO_A_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, A, BattFaultOut )
5820+#define IPAQ_ASIC3_GPIO_A_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, A, IntStatus )
5821+#define IPAQ_ASIC3_GPIO_A_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, A, AltFunction )
5822+#define IPAQ_ASIC3_GPIO_A_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, A, SleepConf )
5823+#define IPAQ_ASIC3_GPIO_A_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Status )
5824+
5825+#define IPAQ_ASIC3_GPIO_B_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Mask )
5826+#define IPAQ_ASIC3_GPIO_B_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Direction )
5827+#define IPAQ_ASIC3_GPIO_B_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Out )
5828+#define IPAQ_ASIC3_GPIO_B_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, B, TriggerType )
5829+#define IPAQ_ASIC3_GPIO_B_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, B, EdgeTrigger )
5830+#define IPAQ_ASIC3_GPIO_B_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, B, LevelTrigger )
5831+#define IPAQ_ASIC3_GPIO_B_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, B, SleepMask )
5832+#define IPAQ_ASIC3_GPIO_B_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, B, SleepOut )
5833+#define IPAQ_ASIC3_GPIO_B_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, B, BattFaultOut )
5834+#define IPAQ_ASIC3_GPIO_B_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, B, IntStatus )
5835+#define IPAQ_ASIC3_GPIO_B_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, B, AltFunction )
5836+#define IPAQ_ASIC3_GPIO_B_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, B, SleepConf )
5837+#define IPAQ_ASIC3_GPIO_B_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Status )
5838+
5839+#define IPAQ_ASIC3_GPIO_C_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Mask )
5840+#define IPAQ_ASIC3_GPIO_C_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Direction )
5841+#define IPAQ_ASIC3_GPIO_C_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Out )
5842+#define IPAQ_ASIC3_GPIO_C_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, C, TriggerType )
5843+#define IPAQ_ASIC3_GPIO_C_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, C, EdgeTrigger )
5844+#define IPAQ_ASIC3_GPIO_C_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, C, LevelTrigger )
5845+#define IPAQ_ASIC3_GPIO_C_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, C, SleepMask )
5846+#define IPAQ_ASIC3_GPIO_C_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, C, SleepOut )
5847+#define IPAQ_ASIC3_GPIO_C_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, C, BattFaultOut )
5848+#define IPAQ_ASIC3_GPIO_C_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, C, IntStatus )
5849+#define IPAQ_ASIC3_GPIO_C_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, C, AltFunction )
5850+#define IPAQ_ASIC3_GPIO_C_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, C, SleepConf )
5851+#define IPAQ_ASIC3_GPIO_C_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Status )
5852+
5853+#define IPAQ_ASIC3_GPIO_D_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Mask )
5854+#define IPAQ_ASIC3_GPIO_D_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Direction )
5855+#define IPAQ_ASIC3_GPIO_D_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Out )
5856+#define IPAQ_ASIC3_GPIO_D_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, D, TriggerType )
5857+#define IPAQ_ASIC3_GPIO_D_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, D, EdgeTrigger )
5858+#define IPAQ_ASIC3_GPIO_D_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, D, LevelTrigger )
5859+#define IPAQ_ASIC3_GPIO_D_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, D, SleepMask )
5860+#define IPAQ_ASIC3_GPIO_D_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, D, SleepOut )
5861+#define IPAQ_ASIC3_GPIO_D_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, D, BattFaultOut )
5862+#define IPAQ_ASIC3_GPIO_D_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, D, IntStatus )
5863+#define IPAQ_ASIC3_GPIO_D_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, D, AltFunction )
5864+#define IPAQ_ASIC3_GPIO_D_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, D, SleepConf )
5865+#define IPAQ_ASIC3_GPIO_D_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Status )
5866+
5867+#define _IPAQ_ASIC3_SPI_Base 0x0400
5868+#define _IPAQ_ASIC3_SPI_Control 0x0000
5869+#define _IPAQ_ASIC3_SPI_TxData 0x0004
5870+#define _IPAQ_ASIC3_SPI_RxData 0x0008
5871+#define _IPAQ_ASIC3_SPI_Int 0x000c
5872+#define _IPAQ_ASIC3_SPI_Status 0x0010
5873+
5874+#define IPAQ_ASIC3_SPI_Control(_b) IPAQ_ASIC3( _b, u16, SPI, Control )
5875+#define IPAQ_ASIC3_SPI_TxData(_b) IPAQ_ASIC3( _b, u16, SPI, TxData )
5876+#define IPAQ_ASIC3_SPI_RxData(_b) IPAQ_ASIC3( _b, u16, SPI, RxData )
5877+#define IPAQ_ASIC3_SPI_Int(_b) IPAQ_ASIC3( _b, u16, SPI, Int )
5878+#define IPAQ_ASIC3_SPI_Status(_b) IPAQ_ASIC3( _b, u16, SPI, Status )
5879+
5880+#define SPI_CONTROL_SPR(clk) ((clk) & 0x0f) /* Clock rate */
5881+
5882+#define _IPAQ_ASIC3_PWM_0_Base 0x0500
5883+#define _IPAQ_ASIC3_PWM_1_Base 0x0600
5884+#define _IPAQ_ASIC3_PWM_TimeBase 0x0000
5885+#define _IPAQ_ASIC3_PWM_PeriodTime 0x0004
5886+#define _IPAQ_ASIC3_PWM_DutyTime 0x0008
5887+
5888+#define IPAQ_ASIC3_PWM_TimeBase(_b, x) IPAQ_ASIC3_N( _b, u16, PWM, x, TimeBase )
5889+#define IPAQ_ASIC3_PWM_PeriodTime(_b, x) IPAQ_ASIC3_N( _b, u16, PWM, x, PeriodTime )
5890+#define IPAQ_ASIC3_PWM_DutyTime(_b, x) IPAQ_ASIC3_N( _b, u16, PWM, x, DutyTime )
5891+
5892+#define PWM_TIMEBASE_VALUE(x) ((x)&0xf) /* Low 4 bits sets time base */
5893+#define PWM_TIMEBASE_ENABLE (1 << 4) /* Enable clock */
5894+
5895+#define _IPAQ_ASIC3_LED_0_Base 0x0700
5896+#define _IPAQ_ASIC3_LED_1_Base 0x0800
5897+#define _IPAQ_ASIC3_LED_2_Base 0x0900
5898+#define _IPAQ_ASIC3_LED_TimeBase 0x0000 /* R/W 7 bits */
5899+#define _IPAQ_ASIC3_LED_PeriodTime 0x0004 /* R/W 12 bits */
5900+#define _IPAQ_ASIC3_LED_DutyTime 0x0008 /* R/W 12 bits */
5901+#define _IPAQ_ASIC3_LED_AutoStopCount 0x000c /* R/W 16 bits */
5902+
5903+#define IPAQ_ASIC3_LED_TimeBase(_b, x) IPAQ_ASIC3_N( _b, u8, LED, x, TimeBase )
5904+#define IPAQ_ASIC3_LED_PeriodTime(_b, x) IPAQ_ASIC3_N( _b, u16, LED, x, PeriodTime )
5905+#define IPAQ_ASIC3_LED_DutyTime(_b, x) IPAQ_ASIC3_N( _b, u16, LED, x, DutyTime )
5906+#define IPAQ_ASIC3_LED_AutoStopCount(_b, x) IPAQ_ASIC3_N( _b, u16, LED, x, AutoStopCount )
5907+
5908+/* LED TimeBase bits - match ASIC2 */
5909+#define LED_TBS 0x0f /* Low 4 bits sets time base, max = 13 */
5910+ /* Note: max = 5 on hx4700 */
5911+ /* 0: maximum time base */
5912+ /* 1: maximum time base / 2 */
5913+ /* n: maximum time base / 2^n */
5914+
5915+#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */
5916+#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
5917+#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
5918+
5919+#define _IPAQ_ASIC3_CLOCK_Base 0x0A00
5920+#define _IPAQ_ASIC3_CLOCK_CDEX 0x00
5921+#define _IPAQ_ASIC3_CLOCK_SEL 0x04
5922+
5923+#define IPAQ_ASIC3_CLOCK_CDEX(_b) IPAQ_ASIC3( _b, u16, CLOCK, CDEX )
5924+#define IPAQ_ASIC3_CLOCK_SEL(_b) IPAQ_ASIC3( _b, u16, CLOCK, SEL )
5925+
5926+#define CLOCK_CDEX_SOURCE (1 << 0) /* 2 bits */
5927+#define CLOCK_CDEX_SOURCE0 (1 << 0)
5928+#define CLOCK_CDEX_SOURCE1 (1 << 1)
5929+#define CLOCK_CDEX_SPI (1 << 2)
5930+#define CLOCK_CDEX_OWM (1 << 3)
5931+#define CLOCK_CDEX_PWM0 (1 << 4)
5932+#define CLOCK_CDEX_PWM1 (1 << 5)
5933+#define CLOCK_CDEX_LED0 (1 << 6)
5934+#define CLOCK_CDEX_LED1 (1 << 7)
5935+#define CLOCK_CDEX_LED2 (1 << 8)
5936+
5937+#define CLOCK_CDEX_SD_HOST (1 << 9) /* R/W: SD host clock source 24.576M/12.288M */
5938+#define CLOCK_CDEX_SD_BUS (1 << 10) /* R/W: SD bus clock source control 24.576M/12.288M */
5939+#define CLOCK_CDEX_SMBUS (1 << 11)
5940+#define CLOCK_CDEX_CONTROL_CX (1 << 12)
5941+
5942+#define CLOCK_CDEX_EX0 (1 << 13) /* R/W: 32.768 kHz crystal */
5943+#define CLOCK_CDEX_EX1 (1 << 14) /* R/W: 24.576 MHz crystal */
5944+
5945+#define CLOCK_SEL_SD_HCLK_SEL (1 << 0) /* R/W: SDIO host clock select - 1: 24.576 Mhz, 0: 12.288 MHz */
5946+#define CLOCK_SEL_SD_BCLK_SEL (1 << 1) /* R/W: SDIO bus clock select - 1: 24.576 MHz, 0: 12.288 MHz */
5947+#define CLOCK_SEL_CX (1 << 2) /* R/W: INT clock source control (32.768 kHz) */
5948+
5949+
5950+#define _IPAQ_ASIC3_INTR_Base 0x0B00
5951+
5952+#define _IPAQ_ASIC3_INTR_IntMask 0x00 /* Interrupt mask control */
5953+#define _IPAQ_ASIC3_INTR_PIntStat 0x04 /* Peripheral interrupt status */
5954+#define _IPAQ_ASIC3_INTR_IntCPS 0x08 /* Interrupt timer clock pre-scale */
5955+#define _IPAQ_ASIC3_INTR_IntTBS 0x0c /* Interrupt timer set */
5956+
5957+#define IPAQ_ASIC3_INTR_IntMask(_b) IPAQ_ASIC3( _b, u8, INTR, IntMask )
5958+#define IPAQ_ASIC3_INTR_PIntStat(_b) IPAQ_ASIC3( _b, u8, INTR, PIntStat )
5959+#define IPAQ_ASIC3_INTR_IntCPS(_b) IPAQ_ASIC3( _b, u8, INTR, IntCPS )
5960+#define IPAQ_ASIC3_INTR_IntTBS(_b) IPAQ_ASIC3( _b, u16, INTR, IntTBS )
5961+
5962+#define ASIC3_INTMASK_GINTMASK (1 << 0) /* Global interrupt mask 1:enable */
5963+#define ASIC3_INTMASK_GINTEL (1 << 1) /* 1: rising edge, 0: hi level */
5964+#define ASIC3_INTMASK_MASK0 (1 << 2)
5965+#define ASIC3_INTMASK_MASK1 (1 << 3)
5966+#define ASIC3_INTMASK_MASK2 (1 << 4)
5967+#define ASIC3_INTMASK_MASK3 (1 << 5)
5968+#define ASIC3_INTMASK_MASK4 (1 << 6)
5969+#define ASIC3_INTMASK_MASK5 (1 << 7)
5970+
5971+#define ASIC3_INTR_PERIPHERAL_A (1 << 0)
5972+#define ASIC3_INTR_PERIPHERAL_B (1 << 1)
5973+#define ASIC3_INTR_PERIPHERAL_C (1 << 2)
5974+#define ASIC3_INTR_PERIPHERAL_D (1 << 3)
5975+#define ASIC3_INTR_LED0 (1 << 4)
5976+#define ASIC3_INTR_LED1 (1 << 5)
5977+#define ASIC3_INTR_LED2 (1 << 6)
5978+#define ASIC3_INTR_SPI (1 << 7)
5979+#define ASIC3_INTR_SMBUS (1 << 8)
5980+#define ASIC3_INTR_OWM (1 << 9)
5981+
5982+#define ASIC3_INTR_CPS(x) ((x)&0x0f) /* 4 bits, max 14 */
5983+#define ASIC3_INTR_CPS_SET ( 1 << 4 ) /* Time base enable */
5984+
5985+
5986+/* Basic control of the SD ASIC */
5987+#define _IPAQ_ASIC3_SDHWCTRL_Base 0x0E00
5988+
5989+#define _IPAQ_ASIC3_SDHWCTRL_SDConf 0x00
5990+#define IPAQ_ASIC3_SDHWCTRL_SDConf(_b) IPAQ_ASIC3( _b, u8, SDHWCTRL, SDConf )
5991+
5992+#define ASIC3_SDHWCTRL_SUSPEND (1 << 0) /* 1=suspend all SD operations */
5993+#define ASIC3_SDHWCTRL_CLKSEL (1 << 1) /* 1=SDICK, 0=HCLK */
5994+#define ASIC3_SDHWCTRL_PCLR (1 << 2) /* All registers of SDIO cleared */
5995+#define ASIC3_SDHWCTRL_LEVCD (1 << 3) /* Level of SD card detection: 1:high, 0:low */
5996+#define ASIC3_SDHWCTRL_LEVWP (1 << 4) /* Level of SD card write protection: 1=low, 0=high */
5997+#define ASIC3_SDHWCTRL_SDLED (1 << 5) /* SD card LED signal 1=enable, 0=disable */
5998+#define ASIC3_SDHWCTRL_SDPWR (1 << 6) /* SD card power supply control 1=enable */
5999+
6000+
6001+/* This is a pointer to an array of 12 u32 values - but only the lower 2 bytes matter */
6002+/* Use it as "IPAQ_ASIC3_HWPROTECT_ARRAY[x]" */
6003+
6004+#define _IPAQ_ASIC3_HWPROTECT_Base 0x1000
6005+#define IPAQ_ASIC3_HWPROTECT_ARRAY ((volatile u32*)(_IPAQ_ASIC3_Base + _IPAQ_ASIC3_HWPROTECT_Base))
6006+#define HWPROTECT_ARRAY_LEN 12
6007+#define HWPROTECT_ARRAY_VALUES {0x4854,0x432d,0x5344,0x494f,0x2050,0x2f4e,0x3a33,0x3048,0x3830,0x3032,0x382d,0x3030}
6008+
6009+
6010+#define _IPAQ_ASIC3_EXTCF_Base 0x1100
6011+
6012+#define _IPAQ_ASIC3_EXTCF_Select 0x00
6013+#define _IPAQ_ASIC3_EXTCF_Reset 0x04
6014+
6015+#define IPAQ_ASIC3_EXTCF_Select(_b) IPAQ_ASIC3( _b, u16, EXTCF, Select )
6016+#define IPAQ_ASIC3_EXTCF_Reset(_b) IPAQ_ASIC3( _b, u16, EXTCF, Reset )
6017+
6018+#define ASIC3_EXTCF_SMOD0 (1 << 0) /* slot number of mode 0 */
6019+#define ASIC3_EXTCF_SMOD1 (1 << 1) /* slot number of mode 1 */
6020+#define ASIC3_EXTCF_SMOD2 (1 << 2) /* slot number of mode 2 */
6021+#define ASIC3_EXTCF_OWM_EN (1 << 4) /* enable onewire module */
6022+#define ASIC3_EXTCF_OWM_SMB (1 << 5) /* OWM bus selection */
6023+#define ASIC3_EXTCF_OWM_RESET (1 << 6) /* undocumented, used by OWM and CF */
6024+#define ASIC3_EXTCF_CF0_SLEEP_MODE (1 << 7) /* CF0 sleep state control */
6025+#define ASIC3_EXTCF_CF1_SLEEP_MODE (1 << 8) /* CF1 sleep state control */
6026+#define ASIC3_EXTCF_CF0_PWAIT_EN (1 << 10) /* CF0 PWAIT_n control */
6027+#define ASIC3_EXTCF_CF1_PWAIT_EN (1 << 11) /* CF1 PWAIT_n control */
6028+#define ASIC3_EXTCF_CF0_BUF_EN (1 << 12) /* CF0 buffer control */
6029+#define ASIC3_EXTCF_CF1_BUF_EN (1 << 13) /* CF1 buffer control */
6030+#define ASIC3_EXTCF_SD_MEM_ENABLE (1 << 14)
6031+#define ASIC3_EXTCF_CF_SLEEP (1 << 15) /* CF sleep mode control */
6032+
6033+/*****************************************************************************
6034+ * The Onewire interface registers
6035+ *
6036+ * OWM_CMD
6037+ * OWM_DAT
6038+ * OWM_INTR
6039+ * OWM_INTEN
6040+ * OWM_CLKDIV
6041+ *
6042+ *****************************************************************************/
6043+
6044+#define _IPAQ_ASIC3_OWM_Base 0xC00
6045+
6046+#define _IPAQ_ASIC3_OWM_CMD 0x00
6047+#define _IPAQ_ASIC3_OWM_DAT 0x04
6048+#define _IPAQ_ASIC3_OWM_INTR 0x08
6049+#define _IPAQ_ASIC3_OWM_INTEN 0x0C
6050+#define _IPAQ_ASIC3_OWM_CLKDIV 0x10
6051+
6052+#define ASIC3_OWM_CMD_ONEWR (1 << 0)
6053+#define ASIC3_OWM_CMD_SRA (1 << 1)
6054+#define ASIC3_OWM_CMD_DQO (1 << 2)
6055+#define ASIC3_OWM_CMD_DQI (1 << 3)
6056+
6057+#define ASIC3_OWM_INTR_PD (1 << 0)
6058+#define ASIC3_OWM_INTR_PDR (1 << 1)
6059+#define ASIC3_OWM_INTR_TBE (1 << 2)
6060+#define ASIC3_OWM_INTR_TEMP (1 << 3)
6061+#define ASIC3_OWM_INTR_RBF (1 << 4)
6062+
6063+#define ASIC3_OWM_INTEN_EPD (1 << 0)
6064+#define ASIC3_OWM_INTEN_IAS (1 << 1)
6065+#define ASIC3_OWM_INTEN_ETBE (1 << 2)
6066+#define ASIC3_OWM_INTEN_ETMT (1 << 3)
6067+#define ASIC3_OWM_INTEN_ERBF (1 << 4)
6068+
6069+#define ASIC3_OWM_CLKDIV_PRE (3 << 0) /* two bits wide at bit position 0 */
6070+#define ASIC3_OWM_CLKDIV_DIV (7 << 2) /* 3 bits wide at bit position 2 */
6071+
6072+
6073+/*****************************************************************************
6074+ * The SD configuration registers are at a completely different location
6075+ * in memory. They are divided into three sets of registers:
6076+ *
6077+ * SD_CONFIG Core configuration register
6078+ * SD_CTRL Control registers for SD operations
6079+ * SDIO_CTRL Control registers for SDIO operations
6080+ *
6081+ *****************************************************************************/
6082+
6083+#define IPAQ_ASIC3_SD_CONFIG(_b, s,x) \
6084+ (*((volatile s *) ((_b) + _IPAQ_ASIC3_SD_CONFIG_Base + (_IPAQ_ASIC3_SD_CONFIG_ ## x))))
6085+
6086+#define _IPAQ_ASIC3_SD_CONFIG_Base 0x0400 // Assumes 32 bit addressing
6087+
6088+#define _IPAQ_ASIC3_SD_CONFIG_Command 0x08 /* R/W: Command */
6089+#define _IPAQ_ASIC3_SD_CONFIG_Addr0 0x20 /* [9:31] SD Control Register Base Address */
6090+#define _IPAQ_ASIC3_SD_CONFIG_Addr1 0x24 /* [9:31] SD Control Register Base Address */
6091+#define _IPAQ_ASIC3_SD_CONFIG_IntPin 0x78 /* R/O: interrupt assigned to pin */
6092+#define _IPAQ_ASIC3_SD_CONFIG_ClkStop 0x80 /* Set to 0x1f to clock SD controller, 0 otherwise. */
6093+ /* at 0x82 - Gated Clock Control */
6094+#define _IPAQ_ASIC3_SD_CONFIG_ClockMode 0x84 /* Control clock of SD controller */
6095+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_PinStatus 0x88 /* R/0: read status of SD pins */
6096+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_Power1 0x90 /* Power1 - manual power control */
6097+ /* Power2 is at 0x92 - auto power up after card inserted */
6098+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_Power3 0x94 /* auto power down when card removed */
6099+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_CardDetect 0x98 /* */
6100+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_Slot 0xA0 /* R/O: define support slot number */
6101+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk1 0x1E0 /* Could be used for gated clock (don't use) */
6102+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk2 0x1E2 /* Could be used for gated clock (don't use) */
6103+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_GPIO_OutAndEnable 0x1E8 /* GPIO Output Reg. , at 0x1EA - GPIO Output Enable Reg. */
6104+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_GPIO_Status 0x1EC /* GPIO Status Reg. */
6105+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk3 0x1F0 /* Bit 1: double buffer/single buffer */
6106+
6107+#define IPAQ_ASIC3_SD_CONFIG_Command(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, Command )
6108+#define IPAQ_ASIC3_SD_CONFIG_Addr0(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, Addr0 )
6109+#define IPAQ_ASIC3_SD_CONFIG_Addr1(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, Addr1 )
6110+#define IPAQ_ASIC3_SD_CONFIG_IntPin(_b) IPAQ_ASIC3_SD_CONFIG(_b, u8, IntPin )
6111+#define IPAQ_ASIC3_SD_CONFIG_ClkStop(_b) IPAQ_ASIC3_SD_CONFIG(_b, u8, ClkStop )
6112+#define IPAQ_ASIC3_SD_CONFIG_ClockMode(_b) IPAQ_ASIC3_SD_CONFIG(_b, u8, ClockMode )
6113+#define IPAQ_ASIC3_SD_CONFIG_SDHC_PinStatus(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_PinStatus )
6114+#define IPAQ_ASIC3_SD_CONFIG_SDHC_Power1(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_Power1 )
6115+#define IPAQ_ASIC3_SD_CONFIG_SDHC_Power3(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_Power3 )
6116+#define IPAQ_ASIC3_SD_CONFIG_SDHC_CardDetect(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_CardDetect )
6117+#define IPAQ_ASIC3_SD_CONFIG_SDHC_Slot(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_Slot )
6118+#define IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk1(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_ExtGateClk1 )
6119+#define IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk3(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_ExtGateClk3 )
6120+
6121+#define SD_CONFIG_
6122+
6123+#define SD_CONFIG_COMMAND_MAE (1<<1) /* Memory access enable (set to 1 to access SD Controller) */
6124+
6125+#define SD_CONFIG_CLK_ENABLE_ALL 0x1f
6126+
6127+#define SD_CONFIG_POWER1_PC_33V 0x0200 /* Set for 3.3 volts */
6128+#define SD_CONFIG_POWER1_PC_OFF 0x0000 /* Turn off power */
6129+
6130+#define SD_CONFIG_CARDDETECTMODE_CLK ((x)&0x3) /* two bits - number of cycles for card detection */
6131+
6132+
6133+#define _IPAQ_ASIC3_SD_CTRL_Base 0x1000
6134+
6135+#define IPAQ_ASIC3_SD(_b, s,x) \
6136+ (*((volatile s *) ((_b) + _IPAQ_ASIC3_SD_CTRL_Base + (_IPAQ_ASIC3_SD_CTRL_ ## x))))
6137+
6138+#define _IPAQ_ASIC3_SD_CTRL_Cmd 0x00
6139+#define _IPAQ_ASIC3_SD_CTRL_Arg0 0x08
6140+#define _IPAQ_ASIC3_SD_CTRL_Arg1 0x0C
6141+#define _IPAQ_ASIC3_SD_CTRL_StopInternal 0x10
6142+#define _IPAQ_ASIC3_SD_CTRL_TransferSectorCount 0x14
6143+#define _IPAQ_ASIC3_SD_CTRL_Response0 0x18
6144+#define _IPAQ_ASIC3_SD_CTRL_Response1 0x1C
6145+#define _IPAQ_ASIC3_SD_CTRL_Response2 0x20
6146+#define _IPAQ_ASIC3_SD_CTRL_Response3 0x24
6147+#define _IPAQ_ASIC3_SD_CTRL_Response4 0x28
6148+#define _IPAQ_ASIC3_SD_CTRL_Response5 0x2C
6149+#define _IPAQ_ASIC3_SD_CTRL_Response6 0x30
6150+#define _IPAQ_ASIC3_SD_CTRL_Response7 0x34
6151+#define _IPAQ_ASIC3_SD_CTRL_CardStatus 0x38
6152+#define _IPAQ_ASIC3_SD_CTRL_BufferCtrl 0x3C
6153+#define _IPAQ_ASIC3_SD_CTRL_IntMaskCard 0x40
6154+#define _IPAQ_ASIC3_SD_CTRL_IntMaskBuffer 0x44
6155+#define _IPAQ_ASIC3_SD_CTRL_CardClockCtrl 0x48
6156+#define _IPAQ_ASIC3_SD_CTRL_MemCardXferDataLen 0x4C
6157+#define _IPAQ_ASIC3_SD_CTRL_MemCardOptionSetup 0x50
6158+#define _IPAQ_ASIC3_SD_CTRL_ErrorStatus0 0x58
6159+#define _IPAQ_ASIC3_SD_CTRL_ErrorStatus1 0x5C
6160+#define _IPAQ_ASIC3_SD_CTRL_DataPort 0x60
6161+#define _IPAQ_ASIC3_SD_CTRL_TransactionCtrl 0x68
6162+#define _IPAQ_ASIC3_SD_CTRL_SoftwareReset 0x1C0
6163+
6164+#define IPAQ_ASIC3_SD_CTRL_Cmd(_b) IPAQ_ASIC3_SD( _b, u16, Cmd ) /* */
6165+#define IPAQ_ASIC3_SD_CTRL_Arg0(_b) IPAQ_ASIC3_SD( _b, u16, Arg0 ) /* */
6166+#define IPAQ_ASIC3_SD_CTRL_Arg1(_b) IPAQ_ASIC3_SD( _b, u16, Arg1 ) /* */
6167+#define IPAQ_ASIC3_SD_CTRL_StopInternal(_b) IPAQ_ASIC3_SD( _b, u16, StopInternal ) /* */
6168+#define IPAQ_ASIC3_SD_CTRL_TransferSectorCount(_b) IPAQ_ASIC3_SD( _b, u16, TransferSectorCount ) /* */
6169+#define IPAQ_ASIC3_SD_CTRL_Response0(_b) IPAQ_ASIC3_SD( _b, u16, Response0 ) /* */
6170+#define IPAQ_ASIC3_SD_CTRL_Response1(_b) IPAQ_ASIC3_SD( _b, u16, Response1 ) /* */
6171+#define IPAQ_ASIC3_SD_CTRL_Response2(_b) IPAQ_ASIC3_SD( _b, u16, Response2 ) /* */
6172+#define IPAQ_ASIC3_SD_CTRL_Response3(_b) IPAQ_ASIC3_SD( _b, u16, Response3 ) /* */
6173+#define IPAQ_ASIC3_SD_CTRL_Response4(_b) IPAQ_ASIC3_SD( _b, u16, Response4 ) /* */
6174+#define IPAQ_ASIC3_SD_CTRL_Response5(_b) IPAQ_ASIC3_SD( _b, u16, Response5 ) /* */
6175+#define IPAQ_ASIC3_SD_CTRL_Response6(_b) IPAQ_ASIC3_SD( _b, u16, Response6 ) /* */
6176+#define IPAQ_ASIC3_SD_CTRL_Response7(_b) IPAQ_ASIC3_SD( _b, u16, Response7 ) /* */
6177+#define IPAQ_ASIC3_SD_CTRL_CardStatus(_b) IPAQ_ASIC3_SD( _b, u16, CardStatus ) /* */
6178+#define IPAQ_ASIC3_SD_CTRL_BufferCtrl(_b) IPAQ_ASIC3_SD( _b, u16, BufferCtrl ) /* and error status*/
6179+#define IPAQ_ASIC3_SD_CTRL_IntMaskCard(_b) IPAQ_ASIC3_SD( _b, u16, IntMaskCard ) /* */
6180+#define IPAQ_ASIC3_SD_CTRL_IntMaskBuffer(_b) IPAQ_ASIC3_SD( _b, u16, IntMaskBuffer ) /* */
6181+#define IPAQ_ASIC3_SD_CTRL_CardClockCtrl(_b) IPAQ_ASIC3_SD( _b, u16, CardClockCtrl ) /* */
6182+#define IPAQ_ASIC3_SD_CTRL_MemCardXferDataLen(_b) IPAQ_ASIC3_SD( _b, u16, MemCardXferDataLen ) /* */
6183+#define IPAQ_ASIC3_SD_CTRL_MemCardOptionSetup(_b) IPAQ_ASIC3_SD( _b, u16, MemCardOptionSetup ) /* */
6184+#define IPAQ_ASIC3_SD_CTRL_ErrorStatus0(_b) IPAQ_ASIC3_SD( _b, u16, ErrorStatus0 ) /* */
6185+#define IPAQ_ASIC3_SD_CTRL_ErrorStatus1(_b) IPAQ_ASIC3_SD( _b, u16, ErrorStatus1 ) /* */
6186+#define IPAQ_ASIC3_SD_CTRL_DataPort(_b) IPAQ_ASIC3_SD( _b, u16, DataPort ) /* */
6187+#define IPAQ_ASIC3_SD_CTRL_TransactionCtrl(_b) IPAQ_ASIC3_SD( _b, u16, TransactionCtrl ) /* */
6188+#define IPAQ_ASIC3_SD_CTRL_SoftwareReset(_b) IPAQ_ASIC3_SD( _b, u16, SoftwareReset ) /* */
6189+
6190+#define SD_CTRL_SOFTWARE_RESET_CLEAR (1<<0)
6191+
6192+#define SD_CTRL_TRANSACTIONCONTROL_SET (1<<8) // 0x0100
6193+
6194+#define SD_CTRL_CARDCLOCKCONTROL_FOR_SD_CARD (1<<15)// 0x8000
6195+#define SD_CTRL_CARDCLOCKCONTROL_ENABLE_CLOCK (1<<8) // 0x0100
6196+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_512 (1<<7) // 0x0080
6197+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_256 (1<<6) // 0x0040
6198+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_128 (1<<5) // 0x0020
6199+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_64 (1<<4) // 0x0010
6200+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_32 (1<<3) // 0x0008
6201+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_16 (1<<2) // 0x0004
6202+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_8 (1<<1) // 0x0002
6203+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_4 (1<<0) // 0x0001
6204+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_2 (0<<0) // 0x0000
6205+
6206+#define MEM_CARD_OPTION_REQUIRED 0x000e
6207+#define MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(x) (((x)&0x0f)<<4) /* Four bits */
6208+#define MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT (1<<14) // 0x4000
6209+#define MEM_CARD_OPTION_DATA_XFR_WIDTH_1 (1<<15) // 0x8000
6210+#define MEM_CARD_OPTION_DATA_XFR_WIDTH_4 (0<<15) //~0x8000
6211+
6212+#define SD_CTRL_COMMAND_INDEX(x) ((x)&0x3f) /* 0=CMD0, 1=CMD1, ..., 63=CMD63 */
6213+#define SD_CTRL_COMMAND_TYPE_CMD (0 << 6)
6214+#define SD_CTRL_COMMAND_TYPE_ACMD (1 << 6)
6215+#define SD_CTRL_COMMAND_TYPE_AUTHENTICATION (2 << 6)
6216+#define SD_CTRL_COMMAND_RESPONSE_TYPE_NORMAL (0 << 8)
6217+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1 (4 << 8)
6218+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1B (5 << 8)
6219+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R2 (6 << 8)
6220+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R3 (7 << 8)
6221+#define SD_CTRL_COMMAND_DATA_PRESENT (1 << 11)
6222+#define SD_CTRL_COMMAND_TRANSFER_READ (1 << 12)
6223+#define SD_CTRL_COMMAND_TRANSFER_WRITE (0 << 12)
6224+#define SD_CTRL_COMMAND_MULTI_BLOCK (1 << 13)
6225+#define SD_CTRL_COMMAND_SECURITY_CMD (1 << 14)
6226+
6227+#define SD_CTRL_STOP_INTERNAL_ISSSUE_CMD12 (1 << 0)
6228+#define SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12 (1 << 8)
6229+
6230+#define SD_CTRL_CARDSTATUS_RESPONSE_END (1 << 0)
6231+#define SD_CTRL_CARDSTATUS_RW_END (1 << 2)
6232+#define SD_CTRL_CARDSTATUS_CARD_REMOVED_0 (1 << 3)
6233+#define SD_CTRL_CARDSTATUS_CARD_INSERTED_0 (1 << 4)
6234+#define SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_0 (1 << 5)
6235+#define SD_CTRL_CARDSTATUS_WRITE_PROTECT (1 << 7)
6236+#define SD_CTRL_CARDSTATUS_CARD_REMOVED_3 (1 << 8)
6237+#define SD_CTRL_CARDSTATUS_CARD_INSERTED_3 (1 << 9)
6238+#define SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_3 (1 << 10)
6239+
6240+#define SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR (1 << 0) // 0x0001
6241+#define SD_CTRL_BUFFERSTATUS_CRC_ERROR (1 << 1) // 0x0002
6242+#define SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR (1 << 2) // 0x0004
6243+#define SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT (1 << 3) // 0x0008
6244+#define SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW (1 << 4) // 0x0010
6245+#define SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW (1 << 5) // 0x0020
6246+#define SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT (1 << 6) // 0x0040
6247+#define SD_CTRL_BUFFERSTATUS_UNK7 (1 << 7) // 0x0080
6248+#define SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE (1 << 8) // 0x0100
6249+#define SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE (1 << 9) // 0x0200
6250+#define SD_CTRL_BUFFERSTATUS_ILLEGAL_FUNCTION (1 << 13)// 0x2000
6251+#define SD_CTRL_BUFFERSTATUS_CMD_BUSY (1 << 14)// 0x4000
6252+#define SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS (1 << 15)// 0x8000
6253+
6254+#define SD_CTRL_INTMASKCARD_RESPONSE_END (1 << 0) // 0x0001
6255+#define SD_CTRL_INTMASKCARD_RW_END (1 << 2) // 0x0004
6256+#define SD_CTRL_INTMASKCARD_CARD_REMOVED_0 (1 << 3) // 0x0008
6257+#define SD_CTRL_INTMASKCARD_CARD_INSERTED_0 (1 << 4) // 0x0010
6258+#define SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_0 (1 << 5) // 0x0020
6259+#define SD_CTRL_INTMASKCARD_UNK6 (1 << 6) // 0x0040
6260+#define SD_CTRL_INTMASKCARD_WRITE_PROTECT (1 << 7) // 0x0080
6261+#define SD_CTRL_INTMASKCARD_CARD_REMOVED_3 (1 << 8) // 0x0100
6262+#define SD_CTRL_INTMASKCARD_CARD_INSERTED_3 (1 << 9) // 0x0200
6263+#define SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_3 (1 << 10)// 0x0400
6264+
6265+#define SD_CTRL_INTMASKBUFFER_CMD_INDEX_ERROR (1 << 0) // 0x0001
6266+#define SD_CTRL_INTMASKBUFFER_CRC_ERROR (1 << 1) // 0x0002
6267+#define SD_CTRL_INTMASKBUFFER_STOP_BIT_END_ERROR (1 << 2) // 0x0004
6268+#define SD_CTRL_INTMASKBUFFER_DATA_TIMEOUT (1 << 3) // 0x0008
6269+#define SD_CTRL_INTMASKBUFFER_BUFFER_OVERFLOW (1 << 4) // 0x0010
6270+#define SD_CTRL_INTMASKBUFFER_BUFFER_UNDERFLOW (1 << 5) // 0x0020
6271+#define SD_CTRL_INTMASKBUFFER_CMD_TIMEOUT (1 << 6) // 0x0040
6272+#define SD_CTRL_INTMASKBUFFER_UNK7 (1 << 7) // 0x0080
6273+#define SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE (1 << 8) // 0x0100
6274+#define SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE (1 << 9) // 0x0200
6275+#define SD_CTRL_INTMASKBUFFER_ILLEGAL_FUNCTION (1 << 13)// 0x2000
6276+#define SD_CTRL_INTMASKBUFFER_CMD_BUSY (1 << 14)// 0x4000
6277+#define SD_CTRL_INTMASKBUFFER_ILLEGAL_ACCESS (1 << 15)// 0x8000
6278+
6279+#define SD_CTRL_DETAIL0_RESPONSE_CMD_ERROR (1 << 0) // 0x0001
6280+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_RESPONSE_NON_CMD12 (1 << 2) // 0x0004
6281+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_RESPONSE_CMD12 (1 << 3) // 0x0008
6282+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_READ_DATA (1 << 4) // 0x0010
6283+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_WRITE_CRC_STATUS (1 << 5) // 0x0020
6284+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_RESPONSE_NON_CMD12 (1 << 8) // 0x0100
6285+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_RESPONSE_CMD12 (1 << 9) // 0x0200
6286+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_READ_DATA (1 << 10)// 0x0400
6287+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_WRITE_CMD (1 << 11)// 0x0800
6288+
6289+#define SD_CTRL_DETAIL1_NO_CMD_RESPONSE (1 << 0) // 0x0001
6290+#define SD_CTRL_DETAIL1_TIMEOUT_READ_DATA (1 << 4) // 0x0010
6291+#define SD_CTRL_DETAIL1_TIMEOUT_CRS_STATUS (1 << 5) // 0x0020
6292+#define SD_CTRL_DETAIL1_TIMEOUT_CRC_BUSY (1 << 6) // 0x0040
6293+
6294+#define _IPAQ_ASIC3_SDIO_CTRL_Base 0x1200
6295+
6296+#define IPAQ_ASIC3_SDIO(_b, s,x) \
6297+ (*((volatile s *) ((_b) + _IPAQ_ASIC3_SDIO_CTRL_Base + (_IPAQ_ASIC3_SDIO_CTRL_ ## x))))
6298+
6299+#define _IPAQ_ASIC3_SDIO_CTRL_Cmd 0x00
6300+#define _IPAQ_ASIC3_SDIO_CTRL_CardPortSel 0x04
6301+#define _IPAQ_ASIC3_SDIO_CTRL_Arg0 0x08
6302+#define _IPAQ_ASIC3_SDIO_CTRL_Arg1 0x0C
6303+#define _IPAQ_ASIC3_SDIO_CTRL_TransferBlockCount 0x14
6304+#define _IPAQ_ASIC3_SDIO_CTRL_Response0 0x18
6305+#define _IPAQ_ASIC3_SDIO_CTRL_Response1 0x1C
6306+#define _IPAQ_ASIC3_SDIO_CTRL_Response2 0x20
6307+#define _IPAQ_ASIC3_SDIO_CTRL_Response3 0x24
6308+#define _IPAQ_ASIC3_SDIO_CTRL_Response4 0x28
6309+#define _IPAQ_ASIC3_SDIO_CTRL_Response5 0x2C
6310+#define _IPAQ_ASIC3_SDIO_CTRL_Response6 0x30
6311+#define _IPAQ_ASIC3_SDIO_CTRL_Response7 0x34
6312+#define _IPAQ_ASIC3_SDIO_CTRL_CardStatus 0x38
6313+#define _IPAQ_ASIC3_SDIO_CTRL_BufferCtrl 0x3C
6314+#define _IPAQ_ASIC3_SDIO_CTRL_IntMaskCard 0x40
6315+#define _IPAQ_ASIC3_SDIO_CTRL_IntMaskBuffer 0x44
6316+#define _IPAQ_ASIC3_SDIO_CTRL_CardXferDataLen 0x4C
6317+#define _IPAQ_ASIC3_SDIO_CTRL_CardOptionSetup 0x50
6318+#define _IPAQ_ASIC3_SDIO_CTRL_ErrorStatus0 0x54
6319+#define _IPAQ_ASIC3_SDIO_CTRL_ErrorStatus1 0x58
6320+#define _IPAQ_ASIC3_SDIO_CTRL_DataPort 0x60
6321+#define _IPAQ_ASIC3_SDIO_CTRL_TransactionCtrl 0x68
6322+#define _IPAQ_ASIC3_SDIO_CTRL_CardIntCtrl 0x6C
6323+#define _IPAQ_ASIC3_SDIO_CTRL_ClocknWaitCtrl 0x70
6324+#define _IPAQ_ASIC3_SDIO_CTRL_HostInformation 0x74
6325+#define _IPAQ_ASIC3_SDIO_CTRL_ErrorCtrl 0x78
6326+#define _IPAQ_ASIC3_SDIO_CTRL_LEDCtrl 0x7C
6327+#define _IPAQ_ASIC3_SDIO_CTRL_SoftwareReset 0x1C0
6328+
6329+#define IPAQ_ASIC3_SDIO_CTRL_Cmd(_b) IPAQ_ASIC3_SDIO( _b, u16, Cmd ) /* */
6330+#define IPAQ_ASIC3_SDIO_CTRL_CardPortSel(_b) IPAQ_ASIC3_SDIO( _b, u16, CardPortSel ) /* */
6331+#define IPAQ_ASIC3_SDIO_CTRL_Arg0(_b) IPAQ_ASIC3_SDIO( _b, u16, Arg0 ) /* */
6332+#define IPAQ_ASIC3_SDIO_CTRL_Arg1(_b) IPAQ_ASIC3_SDIO( _b, u16, Arg1 ) /* */
6333+#define IPAQ_ASIC3_SDIO_CTRL_TransferBlockCount(_b) IPAQ_ASIC3_SDIO( _b, u16, TransferBlockCount ) /* */
6334+#define IPAQ_ASIC3_SDIO_CTRL_Response0(_b) IPAQ_ASIC3_SDIO( _b, u16, Response0 ) /* */
6335+#define IPAQ_ASIC3_SDIO_CTRL_Response1(_b) IPAQ_ASIC3_SDIO( _b, u16, Response1 ) /* */
6336+#define IPAQ_ASIC3_SDIO_CTRL_Response2(_b) IPAQ_ASIC3_SDIO( _b, u16, Response2 ) /* */
6337+#define IPAQ_ASIC3_SDIO_CTRL_Response3(_b) IPAQ_ASIC3_SDIO( _b, u16, Response3 ) /* */
6338+#define IPAQ_ASIC3_SDIO_CTRL_Response4(_b) IPAQ_ASIC3_SDIO( _b, u16, Response4 ) /* */
6339+#define IPAQ_ASIC3_SDIO_CTRL_Response5(_b) IPAQ_ASIC3_SDIO( _b, u16, Response5 ) /* */
6340+#define IPAQ_ASIC3_SDIO_CTRL_Response6(_b) IPAQ_ASIC3_SDIO( _b, u16, Response6 ) /* */
6341+#define IPAQ_ASIC3_SDIO_CTRL_Response7(_b) IPAQ_ASIC3_SDIO( _b, u16, Response7 ) /* */
6342+#define IPAQ_ASIC3_SDIO_CTRL_CardStatus(_b) IPAQ_ASIC3_SDIO( _b, u16, CardStatus ) /* */
6343+#define IPAQ_ASIC3_SDIO_CTRL_BufferCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, BufferCtrl ) /* and error status*/
6344+#define IPAQ_ASIC3_SDIO_CTRL_IntMaskCard(_b) IPAQ_ASIC3_SDIO( _b, u16, IntMaskCard ) /* */
6345+#define IPAQ_ASIC3_SDIO_CTRL_IntMaskBuffer(_b) IPAQ_ASIC3_SDIO( _b, u16, IntMaskBuffer ) /* */
6346+#define IPAQ_ASIC3_SDIO_CTRL_CardXferDataLen(_b) IPAQ_ASIC3_SDIO( _b, u16, CardXferDataLen ) /* */
6347+#define IPAQ_ASIC3_SDIO_CTRL_CardOptionSetup(_b) IPAQ_ASIC3_SDIO( _b, u16, CardOptionSetup ) /* */
6348+#define IPAQ_ASIC3_SDIO_CTRL_ErrorStatus0(_b) IPAQ_ASIC3_SDIO( _b, u16, ErrorStatus0 ) /* */
6349+#define IPAQ_ASIC3_SDIO_CTRL_ErrorStatus1(_b) IPAQ_ASIC3_SDIO( _b, u16, ErrorStatus1 ) /* */
6350+#define IPAQ_ASIC3_SDIO_CTRL_DataPort(_b) IPAQ_ASIC3_SDIO( _b, u16, DataPort ) /* */
6351+#define IPAQ_ASIC3_SDIO_CTRL_TransactionCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, TransactionCtrl ) /* */
6352+#define IPAQ_ASIC3_SDIO_CTRL_CardIntCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, CardIntCtrl ) /* */
6353+#define IPAQ_ASIC3_SDIO_CTRL_ClocknWaitCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, ClocknWaitCtrl ) /* */
6354+#define IPAQ_ASIC3_SDIO_CTRL_HostInformation(_b) IPAQ_ASIC3_SDIO( _b, u16, HostInformation ) /* */
6355+#define IPAQ_ASIC3_SDIO_CTRL_ErrorCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, ErrorCtrl ) /* */
6356+#define IPAQ_ASIC3_SDIO_CTRL_LEDCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, LEDCtrl ) /* */
6357+#define IPAQ_ASIC3_SDIO_CTRL_SoftwareReset(_b) IPAQ_ASIC3_SDIO( _b, u16, SoftwareReset ) /* */
6358+
6359+#define IPAQ_ASIC3_MAP_SIZE 0x2000
6360+
6361+#endif
6362Index: linux-2.6.22/include/linux/backlight.h
6363===================================================================
6364--- linux-2.6.22.orig/include/linux/backlight.h 2007-09-11 12:53:26.000000000 +0200
6365+++ linux-2.6.22/include/linux/backlight.h 2007-09-11 12:53:37.000000000 +0200
6366@@ -92,4 +92,11 @@
6367 return dev_get_drvdata(&bl_dev->dev);
6368 }
6369
6370+struct generic_bl_info {
6371+ int max_intensity;
6372+ int default_intensity;
6373+ int limit_mask;
6374+ void (*set_bl_intensity)(int intensity);
6375+};
6376+
6377 #endif
6378Index: linux-2.6.22/include/linux/gpiodev.h
6379===================================================================
6380--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6381+++ linux-2.6.22/include/linux/gpiodev.h 2007-09-11 12:53:37.000000000 +0200
6382@@ -0,0 +1,44 @@
6383+#ifndef __GPIODEV_H
6384+#define __GPIODEV_H
6385+
6386+#include <linux/device.h>
6387+#include <linux/platform_device.h>
6388+#include <asm/gpio.h>
6389+
6390+/* Interface */
6391+
6392+/* This structure must be first member of device platform_data structure
6393+ of a device which provides gpiodev interface. All method pointers
6394+ must be non-NULL, so stubs must be used for non-implemented ones. */
6395+struct gpiodev_ops {
6396+ int (*get)(struct device *this, unsigned gpio_no);
6397+ void (*set)(struct device *this, unsigned gpio_no, int val);
6398+ int (*to_irq)(struct device *this, unsigned gpio_no);
6399+};
6400+
6401+/* Generalized GPIO structure */
6402+
6403+struct gpio {
6404+ struct device *gpio_dev;
6405+ unsigned gpio_no;
6406+};
6407+
6408+/* API functions */
6409+
6410+static inline int gpiodev_get_value(struct gpio *gpio)
6411+{
6412+ struct gpiodev_ops *ops = gpio->gpio_dev->platform_data;
6413+ return ops->get(gpio->gpio_dev, gpio->gpio_no);
6414+}
6415+static inline void gpiodev_set_value(struct gpio *gpio, int val)
6416+{
6417+ struct gpiodev_ops *ops = gpio->gpio_dev->platform_data;
6418+ ops->set(gpio->gpio_dev, gpio->gpio_no, val);
6419+}
6420+static inline int gpiodev_to_irq(struct gpio *gpio)
6421+{
6422+ struct gpiodev_ops *ops = gpio->gpio_dev->platform_data;
6423+ return ops->to_irq(gpio->gpio_dev, gpio->gpio_no);
6424+}
6425+
6426+#endif /* __GPIODEV_H */
6427Index: linux-2.6.22/include/linux/input_pda.h
6428===================================================================
6429--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6430+++ linux-2.6.22/include/linux/input_pda.h 2007-09-11 12:53:37.000000000 +0200
6431@@ -0,0 +1,47 @@
6432+#ifndef _INPUT_PDA_H
6433+#define _INPUT_PDA_H
6434+
6435+/*
6436+ * This is temporary virtual button key codes map
6437+ * for keyboardless handheld computers.
6438+ * Its purpose is to provide map common to all devices
6439+ * and known to work with current software and its bugs
6440+ * and misfeatures. Once issues with the software are
6441+ * solved, codes from input.h will be used directly
6442+ * (missing key definitions will be added).
6443+ */
6444+
6445+/* Some directly usable keycodes:
6446+KEY_POWER - Power/suspend button
6447+KEY_ENTER - Enter/Action/Central button on joypad
6448+KEY_UP
6449+KEY_DOWN
6450+KEY_LEFT
6451+KEY_RIGHT
6452+*/
6453+
6454+/* XXX Instead of using any values in include/linux/input.h, we have to use
6455+ use values < 128 due to some munging that kdrive does to get keystrokes.
6456+ When kdrive gets its key events from evdev instead of the console,
6457+ we should be able to switch to using input.h values and get rid of
6458+ xmodmap. */
6459+
6460+#define _KEY_APP1 KEY_F9 // xmodmap sees 67 + 8 = 75
6461+#define _KEY_APP2 KEY_F10 // xmodmap 76
6462+#define _KEY_APP3 KEY_F11 // xmodmap 95
6463+#define _KEY_APP4 KEY_F12 // xmodmap 96
6464+
6465+#define _KEY_RECORD KEY_RO
6466+
6467+/* It is highly recommended to use exactly 4 codes above for
6468+ 4 buttons the device has. This will ensure that console and
6469+ framebuffer applications (e.g. games) will work ok on all
6470+ devices. If you'd like more distinguishable names, following
6471+ convenience defines are provided, suiting many devices. */
6472+
6473+#define _KEY_CALENDAR _KEY_APP1
6474+#define _KEY_CONTACTS _KEY_APP2
6475+#define _KEY_MAIL _KEY_APP3
6476+#define _KEY_HOMEPAGE _KEY_APP4
6477+
6478+#endif
6479Index: linux-2.6.22/include/linux/soc/asic3_base.h
6480===================================================================
6481--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6482+++ linux-2.6.22/include/linux/soc/asic3_base.h 2007-09-11 12:53:37.000000000 +0200
6483@@ -0,0 +1,104 @@
6484+#include <asm/types.h>
6485+#include <linux/gpiodev.h>
6486+
6487+/* Private API - for ASIC3 devices internal use only */
6488+#define HDR_IPAQ_ASIC3_ACTION(ACTION,action,fn,FN) \
6489+u32 asic3_get_gpio_ ## action ## _ ## fn (struct device *dev); \
6490+void asic3_set_gpio_ ## action ## _ ## fn (struct device *dev, u32 bits, u32 val);
6491+
6492+#define HDR_IPAQ_ASIC3_FN(fn,FN) \
6493+ HDR_IPAQ_ASIC3_ACTION ( MASK,mask,fn,FN) \
6494+ HDR_IPAQ_ASIC3_ACTION ( DIR, dir, fn, FN) \
6495+ HDR_IPAQ_ASIC3_ACTION ( OUT, out, fn, FN) \
6496+ HDR_IPAQ_ASIC3_ACTION ( LEVELTRI, trigtype, fn, FN) \
6497+ HDR_IPAQ_ASIC3_ACTION ( RISING, rising, fn, FN) \
6498+ HDR_IPAQ_ASIC3_ACTION ( LEVEL, triglevel, fn, FN) \
6499+ HDR_IPAQ_ASIC3_ACTION ( SLEEP_MASK, sleepmask, fn, FN) \
6500+ HDR_IPAQ_ASIC3_ACTION ( SLEEP_OUT, sleepout, fn, FN) \
6501+ HDR_IPAQ_ASIC3_ACTION ( BATT_FAULT_OUT, battfaultout, fn, FN) \
6502+ HDR_IPAQ_ASIC3_ACTION ( INT_STATUS, intstatus, fn, FN) \
6503+ HDR_IPAQ_ASIC3_ACTION ( ALT_FUNCTION, alt_fn, fn, FN) \
6504+ HDR_IPAQ_ASIC3_ACTION ( SLEEP_CONF, sleepconf, fn, FN) \
6505+ HDR_IPAQ_ASIC3_ACTION ( STATUS, status, fn, FN)
6506+
6507+/* Public API */
6508+
6509+#define ASIC3_GPIOA_IRQ_BASE 0
6510+#define ASIC3_GPIOB_IRQ_BASE 16
6511+#define ASIC3_GPIOC_IRQ_BASE 32
6512+#define ASIC3_GPIOD_IRQ_BASE 48
6513+#define ASIC3_LED0_IRQ 64
6514+#define ASIC3_LED1_IRQ 65
6515+#define ASIC3_LED2_IRQ 66
6516+#define ASIC3_SPI_IRQ 67
6517+#define ASIC3_SMBUS_IRQ 68
6518+#define ASIC3_OWM_IRQ 69
6519+
6520+#define ASIC3_NR_GPIO_IRQS 64 /* 16 bits each GPIO A...D banks */
6521+#define ASIC3_NR_IRQS (ASIC3_OWM_IRQ + 1)
6522+
6523+extern int asic3_irq_base(struct device *dev);
6524+
6525+extern void asic3_write_register(struct device *dev, unsigned int reg,
6526+ u32 value);
6527+extern u32 asic3_read_register(struct device *dev, unsigned int reg);
6528+
6529+/* old clock api */
6530+extern void asic3_set_clock_sel(struct device *dev, u32 bits, u32 val);
6531+extern u32 asic3_get_clock_cdex(struct device *dev);
6532+extern void asic3_set_clock_cdex(struct device *dev, u32 bits, u32 val);
6533+
6534+extern void asic3_set_extcf_select(struct device *dev, u32 bits, u32 val);
6535+extern void asic3_set_extcf_reset(struct device *dev, u32 bits, u32 val);
6536+extern void asic3_set_sdhwctrl(struct device *dev, u32 bits, u32 val);
6537+
6538+extern void asic3_set_led(struct device *dev, int led_num, int duty_time,
6539+ int cycle_time, int timebase);
6540+
6541+extern int asic3_register_mmc(struct device *dev);
6542+extern int asic3_unregister_mmc(struct device *dev);
6543+
6544+/* Accessors for GPIO banks */
6545+HDR_IPAQ_ASIC3_FN(a, A)
6546+HDR_IPAQ_ASIC3_FN(b, B)
6547+HDR_IPAQ_ASIC3_FN(c, C)
6548+HDR_IPAQ_ASIC3_FN(d, D)
6549+
6550+#define _IPAQ_ASIC3_GPIO_BANK_A 0
6551+#define _IPAQ_ASIC3_GPIO_BANK_B 1
6552+#define _IPAQ_ASIC3_GPIO_BANK_C 2
6553+#define _IPAQ_ASIC3_GPIO_BANK_D 3
6554+
6555+#define ASIC3_GPIO_bit(gpio) (1 << (gpio & 0xf))
6556+
6557+extern int asic3_get_gpio_bit(struct device *dev, int gpio);
6558+extern void asic3_set_gpio_bit(struct device *dev, int gpio, int val);
6559+extern int asic3_gpio_get_value(struct device *dev, unsigned gpio);
6560+extern void asic3_gpio_set_value(struct device *dev, unsigned gpio, int val);
6561+
6562+
6563+struct tmio_mmc_hwconfig;
6564+
6565+struct asic3_platform_data
6566+{
6567+ // Must be first member
6568+ struct gpiodev_ops gpiodev_ops;
6569+
6570+ struct {
6571+ u32 dir;
6572+ u32 init;
6573+ u32 sleep_mask;
6574+ u32 sleep_out;
6575+ u32 batt_fault_out;
6576+ u32 sleep_conf;
6577+ u32 alt_function;
6578+ } gpio_a, gpio_b, gpio_c, gpio_d;
6579+
6580+ int irq_base;
6581+ unsigned int bus_shift;
6582+
6583+ struct platform_device **child_platform_devs;
6584+ int num_child_platform_devs;
6585+
6586+ struct tmio_mmc_hwconfig *tmio_mmc_hwconfig;
6587+};
6588Index: linux-2.6.22/include/linux/soc/tmio_mmc.h
6589===================================================================
6590--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6591+++ linux-2.6.22/include/linux/soc/tmio_mmc.h 2007-09-11 12:53:37.000000000 +0200
6592@@ -0,0 +1,17 @@
6593+#include <linux/platform_device.h>
6594+
6595+#define MMC_CLOCK_DISABLED 0
6596+#define MMC_CLOCK_ENABLED 1
6597+
6598+#define TMIO_WP_ALWAYS_RW ((void*)-1)
6599+
6600+struct tmio_mmc_hwconfig {
6601+ void (*hwinit)(struct platform_device *sdev);
6602+ void (*set_mmc_clock)(struct platform_device *sdev, int state);
6603+
6604+ /* NULL - use ASIC3 signal,
6605+ TMIO_WP_ALWAYS_RW - assume always R/W (e.g. miniSD)
6606+ otherwise - machine-specific handler */
6607+ int (*mmc_get_ro)(struct platform_device *pdev);
6608+ short address_shift;
6609+};
6610Index: linux-2.6.22/include/asm-arm/arch-pxa/pxa-regs.h
6611===================================================================
6612--- linux-2.6.22.orig/include/asm-arm/arch-pxa/pxa-regs.h 2007-09-11 12:53:34.000000000 +0200
6613+++ linux-2.6.22/include/asm-arm/arch-pxa/pxa-regs.h 2007-09-11 12:53:37.000000000 +0200
6614@@ -2043,6 +2043,8 @@
6615 #define LDCMD_SOFINT (1 << 22)
6616 #define LDCMD_EOFINT (1 << 21)
6617
6618+#define LCCR4_13M_PCD_EN (1<<25) /* 13M PCD enable */
6619+#define LCCR4_PCDDIV (1<<31) /* PCD selection */
6620
6621 #define LCCR5_SOFM1 (1<<0) /* Start Of Frame Mask for Overlay 1 (channel 1) */
6622 #define LCCR5_SOFM2 (1<<1) /* Start Of Frame Mask for Overlay 2 (channel 2) */
6623Index: linux-2.6.22/drivers/mmc/host/Kconfig
6624===================================================================
6625--- linux-2.6.22.orig/drivers/mmc/host/Kconfig 2007-07-09 01:32:17.000000000 +0200
6626+++ linux-2.6.22/drivers/mmc/host/Kconfig 2007-09-11 12:53:37.000000000 +0200
6627@@ -100,3 +100,9 @@
6628 To compile this driver as a module, choose M here: the
6629 module will be called tifm_sd.
6630
6631+config MMC_ASIC3
6632+ tristate "HTC ASIC3 SD/MMC support"
6633+ depends on MMC && HTC_ASIC3
6634+ help
6635+ This provides support for the ASIC3 SD/MMC controller, used
6636+ in the iPAQ hx4700 and others.
6637Index: linux-2.6.22/drivers/mmc/host/Makefile
6638===================================================================
6639--- linux-2.6.22.orig/drivers/mmc/host/Makefile 2007-07-09 01:32:17.000000000 +0200
6640+++ linux-2.6.22/drivers/mmc/host/Makefile 2007-09-11 12:53:37.000000000 +0200
6641@@ -15,4 +15,4 @@
6642 obj-$(CONFIG_MMC_OMAP) += omap.o
6643 obj-$(CONFIG_MMC_AT91) += at91_mci.o
6644 obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
6645-
6646+obj-$(CONFIG_MMC_ASIC3) += asic3_mmc.o
6647Index: linux-2.6.22/drivers/mmc/host/asic3_mmc.c
6648===================================================================
6649--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6650+++ linux-2.6.22/drivers/mmc/host/asic3_mmc.c 2007-09-11 12:53:37.000000000 +0200
6651@@ -0,0 +1,900 @@
6652+/* Note that this driver can likely be merged into the tmio driver, so
6653+ * consider this code temporary. It works, though.
6654+ */
6655+/*
6656+ * linux/drivers/mmc/asic3_mmc.c
6657+ *
6658+ * Copyright (c) 2005 SDG Systems, LLC
6659+ *
6660+ * based on tmio_mmc.c
6661+ * Copyright (C) 2004 Ian Molton
6662+ *
6663+ * Refactored to support all ASIC3 devices, 2006 Paul Sokolovsky
6664+ *
6665+ * This program is free software; you can redistribute it and/or modify
6666+ * it under the terms of the GNU General Public License version 2 as
6667+ * published by the Free Software Foundation.
6668+ *
6669+ * Driver for the SD / SDIO cell found in:
6670+ *
6671+ * TC6393XB
6672+ *
6673+ * This driver draws mainly on scattered spec sheets, Reverse engineering
6674+ * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
6675+ * support).
6676+ *
6677+ * Supports MMC 1 bit transfers and SD 1 and 4 bit modes.
6678+ *
6679+ * TODO:
6680+ * Eliminate FIXMEs
6681+ * SDIO support
6682+ * Power management
6683+ * Handle MMC errors (at all)
6684+ *
6685+ */
6686+#include <linux/module.h>
6687+#include <linux/moduleparam.h>
6688+#include <linux/init.h>
6689+#include <linux/ioport.h>
6690+#include <linux/platform_device.h>
6691+#include <linux/interrupt.h>
6692+#include <linux/blkdev.h>
6693+#include <linux/delay.h>
6694+#include <linux/err.h>
6695+#include <linux/mmc/mmc.h>
6696+#include <linux/mmc/host.h>
6697+#include <linux/mmc/card.h>
6698+//#include <linux/mmc/protocol.h>
6699+#include <linux/mmc/sd.h>
6700+#include <linux/scatterlist.h>
6701+//#include <linux/soc-old.h>
6702+#include <linux/soc/asic3_base.h>
6703+#include <linux/soc/tmio_mmc.h>
6704+
6705+#include <asm/io.h>
6706+#include <asm/irq.h>
6707+#include <asm/mach/irq.h>
6708+#include <linux/clk.h>
6709+#include <asm/mach-types.h>
6710+
6711+#include <asm/hardware/ipaq-asic3.h>
6712+#include "asic3_mmc.h"
6713+
6714+struct asic3_mmc_host {
6715+ void *ctl_base;
6716+ struct device *asic3_dev; /* asic3 device */
6717+ struct tmio_mmc_hwconfig *hwconfig; /* HW config data/handlers, guaranteed != NULL */
6718+ unsigned long bus_shift;
6719+ struct mmc_command *cmd;
6720+ struct mmc_request *mrq;
6721+ struct mmc_data *data;
6722+ struct mmc_host *mmc;
6723+ int irq;
6724+ unsigned short clock_for_sd;
6725+
6726+ /* I/O related stuff */
6727+ struct scatterlist *sg_ptr;
6728+ unsigned int sg_len;
6729+ unsigned int sg_off;
6730+};
6731+
6732+static void
6733+mmc_finish_request(struct asic3_mmc_host *host)
6734+{
6735+ struct mmc_request *mrq = host->mrq;
6736+
6737+ /* Write something to end the command */
6738+ host->mrq = NULL;
6739+ host->cmd = NULL;
6740+ host->data = NULL;
6741+
6742+ mmc_request_done(host->mmc, mrq);
6743+}
6744+
6745+
6746+#define ASIC3_MMC_REG(host, block, reg) (*((volatile u16 *) ((host->ctl_base) + ((_IPAQ_ASIC3_## block ## _Base + _IPAQ_ASIC3_ ## block ## _ ## reg) >> (2 - host->bus_shift))) ))
6747+
6748+static void
6749+mmc_start_command(struct asic3_mmc_host *host, struct mmc_command *cmd)
6750+{
6751+ struct mmc_data *data = host->data;
6752+ int c = cmd->opcode;
6753+
6754+ DBG("Opcode: %d, base: %p\n", cmd->opcode, host->ctl_base);
6755+
6756+ if(cmd->opcode == MMC_STOP_TRANSMISSION) {
6757+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = SD_CTRL_STOP_INTERNAL_ISSSUE_CMD12;
6758+ cmd->resp[0] = cmd->opcode;
6759+ cmd->resp[1] = 0;
6760+ cmd->resp[2] = 0;
6761+ cmd->resp[3] = 0;
6762+ cmd->resp[4] = 0;
6763+ return;
6764+ }
6765+
6766+ switch(cmd->flags & 0x1f) {
6767+ case MMC_RSP_NONE: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_NORMAL; break;
6768+ case MMC_RSP_R1: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1; break;
6769+ case MMC_RSP_R1B: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1B; break;
6770+ case MMC_RSP_R2: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R2; break;
6771+ case MMC_RSP_R3: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R3; break;
6772+ default:
6773+ DBG("Unknown response type %d\n", cmd->flags & 0x1f);
6774+ break;
6775+ }
6776+
6777+ host->cmd = cmd;
6778+
6779+ if(cmd->opcode == MMC_APP_CMD) {
6780+ c |= APP_CMD;
6781+ }
6782+ if (cmd->opcode == MMC_GO_IDLE_STATE) {
6783+ c |= (3 << 8); /* This was removed from ipaq-asic3.h for some reason */
6784+ }
6785+ if(data) {
6786+ c |= SD_CTRL_COMMAND_DATA_PRESENT;
6787+ if(data->blocks > 1) {
6788+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12;
6789+ c |= SD_CTRL_COMMAND_MULTI_BLOCK;
6790+ }
6791+ if(data->flags & MMC_DATA_READ) {
6792+ c |= SD_CTRL_COMMAND_TRANSFER_READ;
6793+ }
6794+ /* MMC_DATA_WRITE does not require a bit to be set */
6795+ }
6796+
6797+ /* Enable the command and data interrupts */
6798+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
6799+ SD_CTRL_INTMASKCARD_RESPONSE_END
6800+ | SD_CTRL_INTMASKCARD_RW_END
6801+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_0
6802+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_0
6803+#if 0
6804+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_3
6805+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_3
6806+#endif
6807+ );
6808+
6809+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) = ~(
6810+ SD_CTRL_INTMASKBUFFER_UNK7
6811+ | SD_CTRL_INTMASKBUFFER_CMD_BUSY
6812+#if 0
6813+ | SD_CTRL_INTMASKBUFFER_CMD_INDEX_ERROR
6814+ | SD_CTRL_INTMASKBUFFER_CRC_ERROR
6815+ | SD_CTRL_INTMASKBUFFER_STOP_BIT_END_ERROR
6816+ | SD_CTRL_INTMASKBUFFER_DATA_TIMEOUT
6817+ | SD_CTRL_INTMASKBUFFER_BUFFER_OVERFLOW
6818+ | SD_CTRL_INTMASKBUFFER_BUFFER_UNDERFLOW
6819+ | SD_CTRL_INTMASKBUFFER_CMD_TIMEOUT
6820+ | SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE
6821+ | SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE
6822+ | SD_CTRL_INTMASKBUFFER_ILLEGAL_ACCESS
6823+#endif
6824+ );
6825+
6826+ /* Send the command */
6827+ ASIC3_MMC_REG(host, SD_CTRL, Arg1) = cmd->arg >> 16;
6828+ ASIC3_MMC_REG(host, SD_CTRL, Arg0) = cmd->arg & 0xffff;
6829+ ASIC3_MMC_REG(host, SD_CTRL, Cmd) = c;
6830+}
6831+
6832+/* This chip always returns (at least?) as much data as you ask for. I'm
6833+ * unsure what happens if you ask for less than a block. This should be looked
6834+ * into to ensure that a funny length read doesnt mess up the controller data
6835+ * state machine.
6836+ *
6837+ * Aric: Statement above may not apply to ASIC3.
6838+ *
6839+ * FIXME - this chip cannot do 1 and 2 byte data requests in 4 bit mode
6840+ *
6841+ * Aric: Statement above may not apply to ASIC3.
6842+ */
6843+
6844+static struct tasklet_struct mmc_data_read_tasklet;
6845+
6846+static void
6847+mmc_data_transfer(unsigned long h)
6848+{
6849+ struct asic3_mmc_host *host = (struct asic3_mmc_host *)h;
6850+ struct mmc_data *data = host->data;
6851+ unsigned short *buf;
6852+ int count;
6853+ /* unsigned long flags; */
6854+
6855+ if(!data){
6856+ printk(KERN_WARNING DRIVER_NAME ": Spurious Data IRQ\n");
6857+ return;
6858+ }
6859+
6860+ /* local_irq_save(flags); */
6861+ /* buf = kmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); */
6862+ buf = kmap(host->sg_ptr->page);
6863+ buf += host->sg_ptr->offset/2 + host->sg_off/2;
6864+
6865+ /*
6866+ * Ensure we dont read more than one block. The chip will interrupt us
6867+ * When the next block is available.
6868+ */
6869+ count = host->sg_ptr->length - host->sg_off;
6870+ if(count > data->blksz) {
6871+ count = data->blksz;
6872+ }
6873+
6874+ DBG("count: %08x, page: %p, offset: %08x flags %08x\n",
6875+ count, host->sg_ptr->page, host->sg_off, data->flags);
6876+
6877+ host->sg_off += count;
6878+
6879+ /* Transfer the data */
6880+ if(data->flags & MMC_DATA_READ) {
6881+ while(count > 0) {
6882+ /* Read two bytes from SD/MMC controller. */
6883+ *buf = ASIC3_MMC_REG(host, SD_CTRL, DataPort);
6884+ buf++;
6885+ count -= 2;
6886+ }
6887+ //flush_dcache_page(host->sg_ptr->page);
6888+ } else {
6889+ while(count > 0) {
6890+ /* Write two bytes to SD/MMC controller. */
6891+ ASIC3_MMC_REG(host, SD_CTRL, DataPort) = *buf;
6892+ buf++;
6893+ count -= 2;
6894+ }
6895+ }
6896+
6897+ /* kunmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); */
6898+ kunmap(host->sg_ptr->page);
6899+ /* local_irq_restore(flags); */
6900+ if(host->sg_off == host->sg_ptr->length) {
6901+ host->sg_ptr++;
6902+ host->sg_off = 0;
6903+ --host->sg_len;
6904+ }
6905+
6906+ return;
6907+}
6908+
6909+static void
6910+mmc_data_end_irq(struct asic3_mmc_host *host)
6911+{
6912+ struct mmc_data *data = host->data;
6913+
6914+ host->data = NULL;
6915+
6916+ if(!data){
6917+ printk(KERN_WARNING DRIVER_NAME ": Spurious data end IRQ\n");
6918+ return;
6919+ }
6920+
6921+ if (data->error == MMC_ERR_NONE) {
6922+ data->bytes_xfered = data->blocks * data->blksz;
6923+ } else {
6924+ data->bytes_xfered = 0;
6925+ }
6926+
6927+ DBG("Completed data request\n");
6928+
6929+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = 0;
6930+
6931+ /* Make sure read enable interrupt and write enable interrupt are disabled */
6932+ if(data->flags & MMC_DATA_READ) {
6933+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) |= SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE;
6934+ } else {
6935+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) |= SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE;
6936+ }
6937+
6938+ mmc_finish_request(host);
6939+}
6940+
6941+static void
6942+mmc_cmd_irq(struct asic3_mmc_host *host, unsigned int buffer_stat)
6943+{
6944+ struct mmc_command *cmd = host->cmd;
6945+ u8 *buf = (u8 *)cmd->resp;
6946+ u16 data;
6947+
6948+ if(!host->cmd) {
6949+ printk(KERN_WARNING DRIVER_NAME ": Spurious CMD irq\n");
6950+ return;
6951+ }
6952+
6953+ host->cmd = NULL;
6954+ if(cmd->flags & MMC_RSP_PRESENT && cmd->flags & MMC_RSP_136) {
6955+ /* R2 */
6956+ buf[12] = 0xff;
6957+ data = ASIC3_MMC_REG(host, SD_CTRL, Response0);
6958+ buf[13] = data & 0xff;
6959+ buf[14] = data >> 8;
6960+ data = ASIC3_MMC_REG(host, SD_CTRL, Response1);
6961+ buf[15] = data & 0xff;
6962+ buf[8] = data >> 8;
6963+ data = ASIC3_MMC_REG(host, SD_CTRL, Response2);
6964+ buf[9] = data & 0xff;
6965+ buf[10] = data >> 8;
6966+ data = ASIC3_MMC_REG(host, SD_CTRL, Response3);
6967+ buf[11] = data & 0xff;
6968+ buf[4] = data >> 8;
6969+ data = ASIC3_MMC_REG(host, SD_CTRL, Response4);
6970+ buf[5] = data & 0xff;
6971+ buf[6] = data >> 8;
6972+ data = ASIC3_MMC_REG(host, SD_CTRL, Response5);
6973+ buf[7] = data & 0xff;
6974+ buf[0] = data >> 8;
6975+ data = ASIC3_MMC_REG(host, SD_CTRL, Response6);
6976+ buf[1] = data & 0xff;
6977+ buf[2] = data >> 8;
6978+ data = ASIC3_MMC_REG(host, SD_CTRL, Response7);
6979+ buf[3] = data & 0xff;
6980+ } else if(cmd->flags & MMC_RSP_PRESENT) {
6981+ /* R1, R1B, R3 */
6982+ data = ASIC3_MMC_REG(host, SD_CTRL, Response0);
6983+ buf[0] = data & 0xff;
6984+ buf[1] = data >> 8;
6985+ data = ASIC3_MMC_REG(host, SD_CTRL, Response1);
6986+ buf[2] = data & 0xff;
6987+ buf[3] = data >> 8;
6988+ }
6989+ DBG("Response: %08x %08x %08x %08x\n", cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
6990+
6991+ if(buffer_stat & SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT) {
6992+ cmd->error = MMC_ERR_TIMEOUT;
6993+ } else if((buffer_stat & SD_CTRL_BUFFERSTATUS_CRC_ERROR) && (cmd->flags & MMC_RSP_CRC)) {
6994+ cmd->error = MMC_ERR_BADCRC;
6995+ } else if(buffer_stat &
6996+ (
6997+ SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS
6998+ | SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR
6999+ | SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR
7000+ | SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW
7001+ | SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW
7002+ | SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT
7003+ )
7004+ ) {
7005+ DBG("Buffer status ERROR 0x%04x - inside check buffer\n", buffer_stat);
7006+ DBG("detail0 error status 0x%04x\n", ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus0));
7007+ DBG("detail1 error status 0x%04x\n", ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus1));
7008+ cmd->error = MMC_ERR_FAILED;
7009+ }
7010+
7011+ if(cmd->error == MMC_ERR_NONE) {
7012+ switch (cmd->opcode) {
7013+ case SD_APP_SET_BUS_WIDTH:
7014+ if(cmd->arg == SD_BUS_WIDTH_4) {
7015+ host->clock_for_sd = SD_CTRL_CARDCLOCKCONTROL_FOR_SD_CARD;
7016+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
7017+ MEM_CARD_OPTION_REQUIRED
7018+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
7019+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
7020+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_4;
7021+ } else {
7022+ host->clock_for_sd = 0;
7023+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
7024+ MEM_CARD_OPTION_REQUIRED
7025+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
7026+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
7027+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_1;
7028+ }
7029+ break;
7030+ case MMC_SELECT_CARD:
7031+ if((cmd->arg >> 16) == 0) {
7032+ /* We have been deselected. */
7033+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
7034+ MEM_CARD_OPTION_REQUIRED
7035+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
7036+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
7037+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_1;
7038+ }
7039+ }
7040+ }
7041+
7042+ /*
7043+ * If there is data to handle we enable data IRQs here, and we will
7044+ * ultimatley finish the request in the mmc_data_end_irq handler.
7045+ */
7046+ if(host->data && (cmd->error == MMC_ERR_NONE)){
7047+ if(host->data->flags & MMC_DATA_READ) {
7048+ /* Enable the read enable interrupt */
7049+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) &=
7050+ ~SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE;
7051+ } else {
7052+ /* Enable the write enable interrupt */
7053+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) &=
7054+ ~SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE;
7055+ }
7056+ } else {
7057+ /* There's no data, or we encountered an error, so finish now. */
7058+ mmc_finish_request(host);
7059+ }
7060+
7061+ return;
7062+}
7063+
7064+static void hwinit2_irqsafe(struct asic3_mmc_host *host);
7065+
7066+static irqreturn_t
7067+mmc_irq(int irq, void *irq_desc)
7068+{
7069+ struct asic3_mmc_host *host;
7070+ unsigned int breg, bmask, bstatus, creg, cmask, cstatus;
7071+
7072+ host = irq_desc;
7073+
7074+ /* asic3 bstatus has errors */
7075+ bstatus = ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl);
7076+ bmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer);
7077+ cstatus = ASIC3_MMC_REG(host, SD_CTRL, CardStatus);
7078+ cmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard);
7079+ breg = bstatus & ~bmask & ~DONT_CARE_BUFFER_BITS;
7080+ creg = cstatus & ~cmask & ~DONT_CARE_CARD_BITS;
7081+
7082+ if (!breg && !creg) {
7083+ /* This occurs sometimes for no known reason. It doesn't hurt
7084+ * anything, so I don't print it. */
7085+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) &= ~breg;
7086+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) &= ~creg;
7087+ goto out;
7088+ }
7089+
7090+ while (breg || creg) {
7091+
7092+ /* XXX TODO: Need to handle errors in breg here. */
7093+
7094+ /*
7095+ * Card insert/remove. The mmc controlling code is stateless. That
7096+ * is, it doesn't care if it was an insert or a remove. It treats
7097+ * both the same.
7098+ */
7099+ /* XXX Asic3 has _3 versions of these status bits, too, for a second slot, perhaps? */
7100+ if (creg & (SD_CTRL_CARDSTATUS_CARD_INSERTED_0 | SD_CTRL_CARDSTATUS_CARD_REMOVED_0)) {
7101+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) &=
7102+ ~(SD_CTRL_CARDSTATUS_CARD_REMOVED_0 | SD_CTRL_CARDSTATUS_CARD_INSERTED_0);
7103+ if(creg & SD_CTRL_CARDSTATUS_CARD_INSERTED_0) {
7104+ hwinit2_irqsafe(host);
7105+ }
7106+ mmc_detect_change(host->mmc,1);
7107+ }
7108+
7109+ /* Command completion */
7110+ if (creg & SD_CTRL_CARDSTATUS_RESPONSE_END) {
7111+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) &=
7112+ ~(SD_CTRL_CARDSTATUS_RESPONSE_END);
7113+ mmc_cmd_irq(host, bstatus);
7114+ }
7115+
7116+ /* Data transfer */
7117+ if (breg & (SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE | SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE)) {
7118+ ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl) &=
7119+ ~(SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE | SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE);
7120+ tasklet_schedule(&mmc_data_read_tasklet);
7121+ }
7122+
7123+ /* Data transfer completion */
7124+ if (creg & SD_CTRL_CARDSTATUS_RW_END) {
7125+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) &= ~(SD_CTRL_CARDSTATUS_RW_END);
7126+ mmc_data_end_irq(host);
7127+ }
7128+
7129+ /* Check status - keep going until we've handled it all */
7130+ bstatus = ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl);
7131+ bmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer);
7132+ cstatus = ASIC3_MMC_REG(host, SD_CTRL, CardStatus);
7133+ cmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard);
7134+ breg = bstatus & ~bmask & ~DONT_CARE_BUFFER_BITS;
7135+ creg = cstatus & ~cmask & ~DONT_CARE_CARD_BITS;
7136+ }
7137+
7138+out:
7139+ /* Ensure all interrupt sources are cleared */
7140+ ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl) = 0;
7141+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) = 0;
7142+ return IRQ_HANDLED;
7143+}
7144+
7145+static void
7146+mmc_start_data(struct asic3_mmc_host *host, struct mmc_data *data)
7147+{
7148+ DBG("setup data transfer: blocksize %08x nr_blocks %d, page: %08x, offset: %08x\n", data->blksz,
7149+ data->blocks, (int)data->sg->page, data->sg->offset);
7150+
7151+ host->sg_len = data->sg_len;
7152+ host->sg_ptr = data->sg;
7153+ host->sg_off = 0;
7154+ host->data = data;
7155+
7156+ /* Set transfer length and blocksize */
7157+ ASIC3_MMC_REG(host, SD_CTRL, TransferSectorCount) = data->blocks;
7158+ ASIC3_MMC_REG(host, SD_CTRL, MemCardXferDataLen) = data->blksz;
7159+}
7160+
7161+/* Process requests from the MMC layer */
7162+static void
7163+mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
7164+{
7165+ struct asic3_mmc_host *host = mmc_priv(mmc);
7166+
7167+ WARN_ON(host->mrq != NULL);
7168+
7169+ host->mrq = mrq;
7170+
7171+ /* If we're performing a data request we need to setup some
7172+ extra information */
7173+ if(mrq->data) {
7174+ mmc_start_data(host, mrq->data);
7175+ }
7176+
7177+ mmc_start_command(host, mrq->cmd);
7178+}
7179+
7180+/* Set MMC clock / power.
7181+ * Note: This controller uses a simple divider scheme therefore it cannot run
7182+ * a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as MMC
7183+ * wont run that fast, it has to be clocked at 12MHz which is the next slowest
7184+ * setting. This is likely not an issue because we are doing single 16-bit
7185+ * writes for data I/O.
7186+ */
7187+static void
7188+mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
7189+{
7190+ struct asic3_mmc_host *host = mmc_priv(mmc);
7191+ u32 clk = 0;
7192+
7193+ DBG("clock %uHz busmode %u powermode %u Vdd %u\n",
7194+ ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
7195+
7196+ if (ios->clock) {
7197+ clk = 0x80; /* slowest by default */
7198+ if(ios->clock >= 24000000 / 256) clk >>= 1;
7199+ if(ios->clock >= 24000000 / 128) clk >>= 1;
7200+ if(ios->clock >= 24000000 / 64) clk >>= 1;
7201+ if(ios->clock >= 24000000 / 32) clk >>= 1;
7202+ if(ios->clock >= 24000000 / 16) clk >>= 1;
7203+ if(ios->clock >= 24000000 / 8) clk >>= 1;
7204+ if(ios->clock >= 24000000 / 4) clk >>= 1;
7205+ if(ios->clock >= 24000000 / 2) clk >>= 1;
7206+ if(ios->clock >= 24000000 / 1) clk >>= 1;
7207+ if(clk == 0) { /* For fastest speed we disable the divider. */
7208+ ASIC3_MMC_REG(host, SD_CONFIG, ClockMode) = 0;
7209+ } else {
7210+ ASIC3_MMC_REG(host, SD_CONFIG, ClockMode) = 1;
7211+ }
7212+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7213+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) =
7214+ host->clock_for_sd
7215+ | SD_CTRL_CARDCLOCKCONTROL_ENABLE_CLOCK
7216+ | clk;
7217+ msleep(10);
7218+ } else {
7219+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7220+ }
7221+
7222+ switch (ios->power_mode) {
7223+ case MMC_POWER_OFF:
7224+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_Power1) = 0;
7225+ msleep(1);
7226+ break;
7227+ case MMC_POWER_UP:
7228+ break;
7229+ case MMC_POWER_ON:
7230+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_Power1) = SD_CONFIG_POWER1_PC_33V;
7231+ msleep(20);
7232+ break;
7233+ }
7234+}
7235+
7236+static int
7237+mmc_get_ro(struct mmc_host *mmc)
7238+{
7239+ struct asic3_mmc_host *host = mmc_priv(mmc);
7240+
7241+ /* Call custom handler for RO status */
7242+ if(host->hwconfig->mmc_get_ro) {
7243+ /* Special case for cards w/o WP lock (like miniSD) */
7244+ if (host->hwconfig->mmc_get_ro == (void*)-1) {
7245+ return 0;
7246+ } else {
7247+ struct platform_device *pdev = to_platform_device(mmc_dev(mmc));
7248+ return host->hwconfig->mmc_get_ro(pdev);
7249+ }
7250+ }
7251+
7252+ /* WRITE_PROTECT is active low */
7253+ return (ASIC3_MMC_REG(host, SD_CTRL, CardStatus) & SD_CTRL_CARDSTATUS_WRITE_PROTECT)?0:1;
7254+}
7255+
7256+static struct mmc_host_ops mmc_ops = {
7257+ .request = mmc_request,
7258+ .set_ios = mmc_set_ios,
7259+ .get_ro = mmc_get_ro,
7260+};
7261+
7262+static void
7263+hwinit2_irqsafe(struct asic3_mmc_host *host)
7264+{
7265+ ASIC3_MMC_REG(host, SD_CONFIG, Addr1) = 0x0000;
7266+ ASIC3_MMC_REG(host, SD_CONFIG, Addr0) = 0x0800;
7267+
7268+ ASIC3_MMC_REG(host, SD_CONFIG, ClkStop) = SD_CONFIG_CLKSTOP_ENABLE_ALL;
7269+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_CardDetect) = 2;
7270+ ASIC3_MMC_REG(host, SD_CONFIG, Command) = SD_CONFIG_COMMAND_MAE;
7271+
7272+ ASIC3_MMC_REG(host, SD_CTRL, SoftwareReset) = 0; /* reset on */
7273+ mdelay(2);
7274+
7275+ ASIC3_MMC_REG(host, SD_CTRL, SoftwareReset) = 1; /* reset off */
7276+ mdelay(2);
7277+
7278+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
7279+ MEM_CARD_OPTION_REQUIRED
7280+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
7281+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
7282+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_1
7283+ ;
7284+ host->clock_for_sd = 0;
7285+
7286+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7287+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) = 0;
7288+ ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl) = 0;
7289+ ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus0) = 0;
7290+ ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus1) = 0;
7291+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = 0;
7292+
7293+ ASIC3_MMC_REG(host, SDIO_CTRL, ClocknWaitCtrl) = 0x100;
7294+ /* *((unsigned short *)(((char *)host->ctl_base) + 0x938)) = 0x100; */
7295+
7296+ ASIC3_MMC_REG(host, SD_CONFIG, ClockMode) = 0;
7297+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7298+
7299+ mdelay(1);
7300+
7301+
7302+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
7303+ SD_CTRL_INTMASKCARD_RESPONSE_END
7304+ | SD_CTRL_INTMASKCARD_RW_END
7305+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_0
7306+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_0
7307+#if 0
7308+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_3
7309+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_3
7310+#endif
7311+ )
7312+ ; /* check */
7313+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) = 0xffff; /* IRQs off */
7314+
7315+ /*
7316+ * ASIC3_MMC_REG(host, SD_CTRL, TransactionCtrl) = SD_CTRL_TRANSACTIONCONTROL_SET;
7317+ * Wince has 0x1000
7318+ */
7319+ /* ASIC3_MMC_REG(host, SD_CTRL, TransactionCtrl) = 0x1000; */
7320+
7321+
7322+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SDPWR, ASIC3_SDHWCTRL_SDPWR); /* turn on power at controller(?) */
7323+
7324+}
7325+
7326+static void
7327+hwinit(struct asic3_mmc_host *host, struct platform_device *pdev)
7328+{
7329+ /* Call custom handler for enabling clock (if needed) */
7330+ if(host->hwconfig->set_mmc_clock)
7331+ host->hwconfig->set_mmc_clock(pdev, MMC_CLOCK_ENABLED);
7332+
7333+ /* Not sure if it must be done bit by bit, but leaving as-is */
7334+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_LEVCD, ASIC3_SDHWCTRL_LEVCD);
7335+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_LEVWP, ASIC3_SDHWCTRL_LEVWP);
7336+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SUSPEND, 0);
7337+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_PCLR, 0);
7338+
7339+ asic3_set_clock_cdex (host->asic3_dev,
7340+ CLOCK_CDEX_EX1 | CLOCK_CDEX_EX0, CLOCK_CDEX_EX1 | CLOCK_CDEX_EX0);
7341+ msleep(1);
7342+
7343+ asic3_set_clock_sel (host->asic3_dev,
7344+ CLOCK_SEL_SD_HCLK_SEL | CLOCK_SEL_SD_BCLK_SEL,
7345+ CLOCK_SEL_SD_HCLK_SEL | 0); /* ? */
7346+
7347+ asic3_set_clock_cdex (host->asic3_dev,
7348+ CLOCK_CDEX_SD_HOST | CLOCK_CDEX_SD_BUS,
7349+ CLOCK_CDEX_SD_HOST | CLOCK_CDEX_SD_BUS);
7350+ msleep(1);
7351+
7352+ asic3_set_extcf_select(host->asic3_dev, ASIC3_EXTCF_SD_MEM_ENABLE, ASIC3_EXTCF_SD_MEM_ENABLE);
7353+
7354+ /* Long Delay */
7355+ if( !machine_is_h4700())
7356+ msleep(500);
7357+
7358+ hwinit2_irqsafe(host);
7359+}
7360+
7361+#ifdef CONFIG_PM
7362+static int
7363+mmc_suspend(struct platform_device *pdev, pm_message_t state)
7364+{
7365+ struct mmc_host *mmc = platform_get_drvdata(pdev);
7366+ struct asic3_mmc_host *host = mmc_priv(mmc);
7367+ int ret;
7368+
7369+ ret = mmc_suspend_host(mmc, state);
7370+
7371+ if (ret) {
7372+ printk(KERN_ERR DRIVER_NAME ": Could not suspend MMC host, hardware not suspended");
7373+ return ret;
7374+ }
7375+
7376+ /* disable the card insert / remove interrupt while sleeping */
7377+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
7378+ SD_CTRL_INTMASKCARD_RESPONSE_END
7379+ | SD_CTRL_INTMASKCARD_RW_END);
7380+
7381+ /* disable clock */
7382+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7383+ ASIC3_MMC_REG(host, SD_CONFIG, ClkStop) = 0;
7384+
7385+ /* power down */
7386+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_Power1) = 0;
7387+
7388+ asic3_set_clock_cdex (host->asic3_dev,
7389+ CLOCK_CDEX_SD_HOST | CLOCK_CDEX_SD_BUS, 0);
7390+
7391+ /* disable core clock */
7392+ if(host->hwconfig->set_mmc_clock)
7393+ host->hwconfig->set_mmc_clock(pdev, MMC_CLOCK_DISABLED);
7394+
7395+ /* Put in suspend mode */
7396+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SUSPEND, ASIC3_SDHWCTRL_SUSPEND);
7397+ return 0;
7398+}
7399+
7400+static int
7401+mmc_resume(struct platform_device *pdev)
7402+{
7403+ struct mmc_host *mmc = platform_get_drvdata(pdev);
7404+ struct asic3_mmc_host *host = mmc_priv(mmc);
7405+
7406+ printk(KERN_INFO "%s: starting resume\n", DRIVER_NAME);
7407+
7408+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SUSPEND, 0);
7409+ hwinit(host, pdev);
7410+
7411+ /* re-enable card remove / insert interrupt */
7412+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
7413+ SD_CTRL_INTMASKCARD_RESPONSE_END
7414+ | SD_CTRL_INTMASKCARD_RW_END
7415+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_0
7416+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_0 );
7417+
7418+ mmc_resume_host(mmc);
7419+
7420+ printk(KERN_INFO "%s: finished resume\n", DRIVER_NAME);
7421+ return 0;
7422+}
7423+#endif
7424+
7425+static int
7426+mmc_probe(struct platform_device *pdev)
7427+{
7428+ struct mmc_host *mmc;
7429+ struct asic3_mmc_host *host = NULL;
7430+ int retval = 0;
7431+ struct tmio_mmc_hwconfig *mmc_config = (struct tmio_mmc_hwconfig *)pdev->dev.platform_data;
7432+
7433+ /* bus_shift is mandatory */
7434+ if (!mmc_config) {
7435+ printk(KERN_ERR DRIVER_NAME ": Invalid configuration\n");
7436+ return -EINVAL;
7437+ }
7438+
7439+ mmc = mmc_alloc_host(sizeof(struct asic3_mmc_host) + 128, &pdev->dev);
7440+ if (!mmc) {
7441+ retval = -ENOMEM;
7442+ goto exceptional_return;
7443+ }
7444+
7445+ host = mmc_priv(mmc);
7446+ host->mmc = mmc;
7447+ platform_set_drvdata(pdev, mmc);
7448+
7449+ host->ctl_base = 0;
7450+ host->hwconfig = mmc_config;
7451+ host->bus_shift = mmc_config->address_shift;
7452+ host->asic3_dev = pdev->dev.parent;
7453+ host->clock_for_sd = 0;
7454+
7455+ tasklet_init(&mmc_data_read_tasklet, mmc_data_transfer, (unsigned long)host);
7456+
7457+ host->ctl_base = ioremap_nocache ((unsigned long)pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start);
7458+ if(!host->ctl_base){
7459+ printk(KERN_ERR DRIVER_NAME ": Could not map ASIC3 SD controller\n");
7460+ retval = -ENODEV;
7461+ goto exceptional_return;
7462+ }
7463+
7464+ printk(DRIVER_NAME ": ASIC3 MMC/SD Driver, controller at 0x%lx\n", (unsigned long)pdev->resource[0].start);
7465+
7466+ mmc->ops = &mmc_ops;
7467+ mmc->caps = MMC_CAP_4_BIT_DATA;
7468+ mmc->f_min = 46875; /* ARIC: not sure what these should be */
7469+ mmc->f_max = 24000000; /* ARIC: not sure what these should be */
7470+ mmc->ocr_avail = MMC_VDD_32_33;
7471+
7472+ hwinit(host, pdev);
7473+
7474+
7475+ host->irq = pdev->resource[1].start;
7476+
7477+ retval = request_irq(host->irq, mmc_irq, 0, DRIVER_NAME, host);
7478+ if(retval) {
7479+ printk(KERN_ERR DRIVER_NAME ": Unable to get interrupt\n");
7480+ retval = -ENODEV;
7481+ goto exceptional_return;
7482+ }
7483+ set_irq_type(host->irq, IRQT_FALLING);
7484+
7485+ mmc_add_host(mmc);
7486+
7487+#ifdef CONFIG_PM
7488+ // resume_timer.function = resume_timer_callback;
7489+ // resume_timer.data = 0;
7490+ // init_timer(&resume_timer);
7491+#endif
7492+
7493+ return 0;
7494+
7495+exceptional_return:
7496+ if (mmc) {
7497+ mmc_free_host(mmc);
7498+ }
7499+ if(host && host->ctl_base) iounmap(host->ctl_base);
7500+ return retval;
7501+}
7502+
7503+static int
7504+mmc_remove(struct platform_device *pdev)
7505+{
7506+ struct mmc_host *mmc = platform_get_drvdata(pdev);
7507+
7508+ platform_set_drvdata(pdev, NULL);
7509+
7510+ if (mmc) {
7511+ struct asic3_mmc_host *host = mmc_priv(mmc);
7512+ mmc_remove_host(mmc);
7513+ free_irq(host->irq, host);
7514+ /* FIXME - we might want to consider stopping the chip here... */
7515+ iounmap(host->ctl_base);
7516+ mmc_free_host(mmc); /* FIXME - why does this call hang? */
7517+ }
7518+ return 0;
7519+}
7520+
7521+/* ------------------- device registration ----------------------- */
7522+
7523+static struct platform_driver mmc_asic3_driver = {
7524+ .driver = {
7525+ .name = DRIVER_NAME,
7526+ },
7527+ .probe = mmc_probe,
7528+ .remove = mmc_remove,
7529+#ifdef CONFIG_PM
7530+ .suspend = mmc_suspend,
7531+ .resume = mmc_resume,
7532+#endif
7533+};
7534+
7535+static int __init mmc_init(void)
7536+{
7537+ return platform_driver_register(&mmc_asic3_driver);
7538+}
7539+
7540+static void __exit mmc_exit(void)
7541+{
7542+ platform_driver_unregister(&mmc_asic3_driver);
7543+}
7544+
7545+late_initcall(mmc_init);
7546+module_exit(mmc_exit);
7547+
7548+MODULE_DESCRIPTION("HTC ASIC3 SD/MMC driver");
7549+MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
7550+MODULE_LICENSE("GPL");
7551+
7552Index: linux-2.6.22/drivers/mmc/host/asic3_mmc.h
7553===================================================================
7554--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7555+++ linux-2.6.22/drivers/mmc/host/asic3_mmc.h 2007-09-11 12:53:37.000000000 +0200
7556@@ -0,0 +1,25 @@
7557+#ifndef __ASIC3_MMC_H
7558+#define __ASIC3_MMC_H
7559+
7560+#define DRIVER_NAME "asic3_mmc"
7561+
7562+#ifdef CONFIG_MMC_DEBUG
7563+#define DBG(x...) printk(DRIVER_NAME ": " x)
7564+#else
7565+#define DBG(x...) do { } while (0)
7566+#endif
7567+
7568+/* Response types */
7569+#define APP_CMD 0x0040
7570+
7571+#define SD_CONFIG_CLKSTOP_ENABLE_ALL 0x1f
7572+
7573+#define DONT_CARE_CARD_BITS ( \
7574+ SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_3 \
7575+ | SD_CTRL_INTMASKCARD_WRITE_PROTECT \
7576+ | SD_CTRL_INTMASKCARD_UNK6 \
7577+ | SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_0 \
7578+ )
7579+#define DONT_CARE_BUFFER_BITS ( SD_CTRL_INTMASKBUFFER_UNK7 | SD_CTRL_INTMASKBUFFER_CMD_BUSY )
7580+
7581+#endif // __ASIC3_MMC_H
7582Index: linux-2.6.22/drivers/input/keyboard/Makefile
7583===================================================================
7584--- linux-2.6.22.orig/drivers/input/keyboard/Makefile 2007-07-09 01:32:17.000000000 +0200
7585+++ linux-2.6.22/drivers/input/keyboard/Makefile 2007-09-11 12:53:37.000000000 +0200
7586@@ -21,4 +21,4 @@
7587 obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o
7588 obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
7589 obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
7590-
7591+obj-$(CONFIG_KEYBOARD_ASIC3) += asic3_keys.o
7592Index: linux-2.6.22/drivers/input/keyboard/asic3_keys.c
7593===================================================================
7594--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7595+++ linux-2.6.22/drivers/input/keyboard/asic3_keys.c 2007-09-11 12:53:37.000000000 +0200
7596@@ -0,0 +1,131 @@
7597+/*
7598+ * Generic buttons driver for ASIC3 SoC.
7599+ *
7600+ * This file is subject to the terms and conditions of the GNU General Public
7601+ * License. See the file COPYING in the main directory of this archive for
7602+ * more details.
7603+ *
7604+ * Copyright (C) 2003 Joshua Wise
7605+ * Copyright (C) 2005 Pawel Kolodziejski
7606+ * Copyright (C) 2006 Paul Sokolovsky
7607+ *
7608+ */
7609+
7610+#include <linux/input.h>
7611+#include <linux/module.h>
7612+#include <linux/init.h>
7613+#include <linux/interrupt.h>
7614+#include <linux/platform_device.h>
7615+#include <linux/irq.h>
7616+#include <linux/soc/asic3_base.h>
7617+#include <asm/mach/arch.h>
7618+#include <asm/mach/map.h>
7619+#include <asm/arch/irqs.h>
7620+#include <asm/hardware.h>
7621+#include <asm/hardware/ipaq-asic3.h>
7622+#include <asm/hardware/asic3_keys.h>
7623+
7624+static irqreturn_t asic3_keys_asic_handle(int irq, void *data)
7625+{
7626+ struct asic3_keys_platform_data *pdata = data;
7627+ int i, base_irq;
7628+
7629+ base_irq = asic3_irq_base(pdata->asic3_dev);
7630+ for (i = 0; i < pdata->nbuttons; i++) {
7631+ struct asic3_keys_button *b = &pdata->buttons[i];
7632+ if ((base_irq + b->gpio) == irq) {
7633+ int state = !!asic3_gpio_get_value(pdata->asic3_dev, b->gpio);
7634+
7635+ if (pdata->buttons[i].type == EV_SW)
7636+ input_report_switch(pdata->input, pdata->buttons[i].keycode, state ^ b->active_low);
7637+ else
7638+ input_report_key(pdata->input, b->keycode, state ^ b->active_low);
7639+ input_sync(pdata->input);
7640+ }
7641+ }
7642+
7643+ return IRQ_HANDLED;
7644+}
7645+
7646+static int __devinit asic3_keys_probe(struct platform_device *pdev)
7647+{
7648+ struct asic3_keys_platform_data *pdata = pdev->dev.platform_data;
7649+ int i, base_irq;
7650+ int j, ret;
7651+
7652+ pdata->input = input_allocate_device();
7653+
7654+ base_irq = asic3_irq_base(pdata->asic3_dev);
7655+
7656+ for (i = 0; i < pdata->nbuttons; i++) {
7657+ struct asic3_keys_button *b = &pdata->buttons[i];
7658+ set_bit(b->keycode, pdata->input->keybit);
7659+ ret=request_irq(base_irq + b->gpio, asic3_keys_asic_handle, SA_SAMPLE_RANDOM, b->desc, pdata);
7660+ if (ret)
7661+ {
7662+ printk(KERN_NOTICE "Failed to allocate asic3_keys irq=%d.\n",b->gpio);
7663+
7664+ for(j=0; j<i ; j++)
7665+ free_irq(base_irq + pdata->buttons[i].gpio, NULL);
7666+
7667+ input_unregister_device (pdata->input);
7668+
7669+ return -ENODEV;
7670+ }
7671+
7672+ set_irq_type(base_irq + b->gpio, IRQT_BOTHEDGE);
7673+ if (pdata->buttons[i].type == EV_SW) {
7674+ pdata->input->evbit[0] |= BIT(EV_SW);
7675+ set_bit(b->keycode, pdata->input->swbit);
7676+ } else {
7677+ pdata->input->evbit[0] |= BIT(EV_KEY);
7678+ set_bit(b->keycode, pdata->input->keybit);
7679+ }
7680+ }
7681+
7682+ pdata->input->name = pdev->name;
7683+ input_register_device(pdata->input);
7684+
7685+ return 0;
7686+}
7687+
7688+static int __devexit asic3_keys_remove(struct platform_device *pdev)
7689+{
7690+ struct asic3_keys_platform_data *pdata = pdev->dev.platform_data;
7691+ int i, base_irq;
7692+
7693+ base_irq = asic3_irq_base(pdata->asic3_dev);
7694+ for (i = 0; i < pdata->nbuttons; i++) {
7695+ free_irq(base_irq + pdata->buttons[i].gpio, NULL);
7696+ }
7697+
7698+ input_unregister_device(pdata->input);
7699+
7700+ return 0;
7701+}
7702+
7703+
7704+static struct platform_driver asic3_keys_driver = {
7705+ .probe = asic3_keys_probe,
7706+ .remove = __devexit_p(asic3_keys_remove),
7707+ .driver = {
7708+ .name = "asic3-keys",
7709+ },
7710+};
7711+
7712+static int __init asic3_keys_init(void)
7713+{
7714+ return platform_driver_register(&asic3_keys_driver);
7715+}
7716+
7717+static void __exit asic3_keys_exit(void)
7718+{
7719+ platform_driver_unregister(&asic3_keys_driver);
7720+}
7721+
7722+module_init(asic3_keys_init);
7723+module_exit(asic3_keys_exit);
7724+
7725+MODULE_AUTHOR("Joshua Wise, Pawel Kolodziejski, Paul Sokolovsky");
7726+MODULE_DESCRIPTION("Buttons driver for HTC ASIC3 SoC");
7727+MODULE_LICENSE("GPL");
7728Index: linux-2.6.22/include/asm-arm/arch-pxa/irqs.h
7729===================================================================
7730--- linux-2.6.22.orig/include/asm-arm/arch-pxa/irqs.h 2007-09-11 12:53:24.000000000 +0200
7731+++ linux-2.6.22/include/asm-arm/arch-pxa/irqs.h 2007-09-11 12:53:37.000000000 +0200
7732@@ -172,6 +172,8 @@
7733 defined(CONFIG_MACH_LOGICPD_PXA270) || \
7734 defined(CONFIG_MACH_MAINSTONE)
7735 #define NR_IRQS (IRQ_BOARD_END)
7736+#elif defined(CONFIG_MACH_HTCUNIVERSAL)
7737+#define NR_IRQS (IRQ_BOARD_START + 96)
7738 #else
7739 #define NR_IRQS (IRQ_BOARD_START)
7740 #endif
7741Index: linux-2.6.22/include/linux/ioport.h
7742===================================================================
7743--- linux-2.6.22.orig/include/linux/ioport.h 2007-07-09 01:32:17.000000000 +0200
7744+++ linux-2.6.22/include/linux/ioport.h 2007-09-11 12:53:37.000000000 +0200
7745@@ -56,6 +56,7 @@
7746 #define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
7747 #define IORESOURCE_IRQ_LOWLEVEL (1<<3)
7748 #define IORESOURCE_IRQ_SHAREABLE (1<<4)
7749+#define IORESOURCE_IRQ_SOC_SUBDEVICE (1<<5)
7750
7751 /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
7752 #define IORESOURCE_DMA_TYPE_MASK (3<<0)
7753Index: linux-2.6.22/drivers/video/backlight/Kconfig
7754===================================================================
7755--- linux-2.6.22.orig/drivers/video/backlight/Kconfig 2007-09-11 12:53:30.000000000 +0200
7756+++ linux-2.6.22/drivers/video/backlight/Kconfig 2007-09-11 12:53:37.000000000 +0200
7757@@ -40,7 +40,7 @@
7758
7759 config BACKLIGHT_CORGI
7760 tristate "Sharp Corgi Backlight Driver (SL Series)"
7761- depends on BACKLIGHT_CLASS_DEVICE && PXA_SHARPSL
7762+ depends on BACKLIGHT_CLASS_DEVICE
7763 default y
7764 help
7765 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
7766Index: linux-2.6.22/drivers/video/backlight/corgi_bl.c
7767===================================================================
7768--- linux-2.6.22.orig/drivers/video/backlight/corgi_bl.c 2007-07-09 01:32:17.000000000 +0200
7769+++ linux-2.6.22/drivers/video/backlight/corgi_bl.c 2007-09-11 12:53:37.000000000 +0200
7770@@ -24,7 +24,7 @@
7771 static int corgibl_intensity;
7772 static struct backlight_properties corgibl_data;
7773 static struct backlight_device *corgi_backlight_device;
7774-static struct corgibl_machinfo *bl_machinfo;
7775+static struct generic_bl_info *bl_machinfo;
7776
7777 static unsigned long corgibl_flags;
7778 #define CORGIBL_SUSPENDED 0x01
7779@@ -107,7 +107,7 @@
7780
7781 static int corgibl_probe(struct platform_device *pdev)
7782 {
7783- struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
7784+ struct generic_bl_info *machinfo = pdev->dev.platform_data;
7785
7786 bl_machinfo = machinfo;
7787 if (!machinfo->limit_mask)
7788Index: linux-2.6.22/arch/arm/mach-pxa/corgi.c
7789===================================================================
7790--- linux-2.6.22.orig/arch/arm/mach-pxa/corgi.c 2007-09-11 12:53:32.000000000 +0200
7791+++ linux-2.6.22/arch/arm/mach-pxa/corgi.c 2007-09-11 12:53:37.000000000 +0200
7792@@ -20,6 +20,7 @@
7793 #include <linux/interrupt.h>
7794 #include <linux/mmc/host.h>
7795 #include <linux/pm.h>
7796+#include <linux/backlight.h>
7797
7798 #include <asm/setup.h>
7799 #include <asm/memory.h>
7800@@ -143,7 +144,7 @@
7801 /*
7802 * Corgi Backlight Device
7803 */
7804-static struct corgibl_machinfo corgi_bl_machinfo = {
7805+static struct generic_bl_info corgi_bl_machinfo = {
7806 .max_intensity = 0x2f,
7807 .default_intensity = 0x1f,
7808 .limit_mask = 0x0b,
7809Index: linux-2.6.22/arch/arm/mach-pxa/spitz.c
7810===================================================================
7811--- linux-2.6.22.orig/arch/arm/mach-pxa/spitz.c 2007-09-11 12:53:33.000000000 +0200
7812+++ linux-2.6.22/arch/arm/mach-pxa/spitz.c 2007-09-11 12:53:37.000000000 +0200
7813@@ -222,7 +222,7 @@
7814 /*
7815 * Spitz Backlight Device
7816 */
7817-static struct corgibl_machinfo spitz_bl_machinfo = {
7818+static struct generic_bl_info spitz_bl_machinfo = {
7819 .default_intensity = 0x1f,
7820 .limit_mask = 0x0b,
7821 .max_intensity = 0x2f,
7822Index: linux-2.6.22/include/asm-arm/arch-pxa/serial.h
7823===================================================================
7824--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7825+++ linux-2.6.22/include/asm-arm/arch-pxa/serial.h 2007-09-11 12:53:37.000000000 +0200
7826@@ -0,0 +1,78 @@
7827+/*
7828+ * linux/include/asm-arm/arch-pxa/serial.h
7829+ *
7830+ * Author: Nicolas Pitre
7831+ * Copyright: (C) 2001 MontaVista Software Inc.
7832+ *
7833+ * This program is free software; you can redistribute it and/or modify
7834+ * it under the terms of the GNU General Public License version 2 as
7835+ * published by the Free Software Foundation.
7836+ */
7837+
7838+#include <asm/arch/pxa-regs.h>
7839+
7840+#define BAUD_BASE 921600
7841+
7842+/* Standard COM flags */
7843+#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
7844+
7845+#define STD_SERIAL_PORT_DEFNS \
7846+ { \
7847+ type: PORT_PXA, \
7848+ xmit_fifo_size: 64, \
7849+ baud_base: BAUD_BASE, \
7850+ iomem_base: &FFUART, \
7851+ iomem_reg_shift: 2, \
7852+ io_type: SERIAL_IO_MEM, \
7853+ irq: IRQ_FFUART, \
7854+ flags: STD_COM_FLAGS, \
7855+ }, { \
7856+ type: PORT_PXA, \
7857+ xmit_fifo_size: 64, \
7858+ baud_base: BAUD_BASE, \
7859+ iomem_base: &STUART, \
7860+ iomem_reg_shift: 2, \
7861+ io_type: SERIAL_IO_MEM, \
7862+ irq: IRQ_STUART, \
7863+ flags: STD_COM_FLAGS, \
7864+ }, { \
7865+ type: PORT_PXA, \
7866+ xmit_fifo_size: 64, \
7867+ baud_base: BAUD_BASE, \
7868+ iomem_base: &BTUART, \
7869+ iomem_reg_shift: 2, \
7870+ io_type: SERIAL_IO_MEM, \
7871+ irq: IRQ_BTUART, \
7872+ flags: STD_COM_FLAGS, \
7873+ }
7874+
7875+#define EXTRA_SERIAL_PORT_DEFNS
7876+
7877+struct platform_pxa_serial_funcs {
7878+
7879+ /* Initialize whatever is connected to this serial port. */
7880+ void (*configure)(int state);
7881+#define PXA_UART_CFG_PRE_STARTUP 0
7882+#define PXA_UART_CFG_POST_STARTUP 1
7883+#define PXA_UART_CFG_PRE_SHUTDOWN 2
7884+#define PXA_UART_CFG_POST_SHUTDOWN 3
7885+
7886+ /* Enable or disable the individual transmitter/receiver submodules.
7887+ * On transceivers without echo cancellation (e.g. SIR)
7888+ * transmitter always has priority; e.g. if both bits are set,
7889+ * only the transmitter is enabled. */
7890+ void (*set_txrx)(int txrx);
7891+#define PXA_SERIAL_TX 1
7892+#define PXA_SERIAL_RX 2
7893+
7894+ /* Get the current state of tx/rx. */
7895+ int (*get_txrx)(void);
7896+
7897+ int (*suspend)(struct platform_device *dev, pm_message_t state);
7898+ int (*resume)(struct platform_device *dev);
7899+};
7900+
7901+void pxa_set_ffuart_info(struct platform_pxa_serial_funcs *ffuart_funcs);
7902+void pxa_set_btuart_info(struct platform_pxa_serial_funcs *btuart_funcs);
7903+void pxa_set_stuart_info(struct platform_pxa_serial_funcs *stuart_funcs);
7904+void pxa_set_hwuart_info(struct platform_pxa_serial_funcs *hwuart_funcs);
7905Index: linux-2.6.22/drivers/serial/pxa.c
7906===================================================================
7907--- linux-2.6.22.orig/drivers/serial/pxa.c 2007-07-09 01:32:17.000000000 +0200
7908+++ linux-2.6.22/drivers/serial/pxa.c 2007-09-11 12:53:37.000000000 +0200
7909@@ -46,6 +46,7 @@
7910 #include <asm/io.h>
7911 #include <asm/hardware.h>
7912 #include <asm/irq.h>
7913+#include <asm/arch/serial.h>
7914 #include <asm/arch/pxa-regs.h>
7915
7916
7917@@ -59,6 +60,14 @@
7918 char *name;
7919 };
7920
7921+
7922+#define IS_METHOD(dev, method) (dev && (dev)->platform_data && ((struct platform_pxa_serial_funcs *)(dev)->platform_data)->method)
7923+#define METHOD_CALL(dev, method) \
7924+ ((struct platform_pxa_serial_funcs *)(dev)->platform_data)->method()
7925+#define SAFE_METHOD_CALL(dev, method, args...) \
7926+ if (IS_METHOD(dev, method)) \
7927+ ((struct platform_pxa_serial_funcs *)(dev)->platform_data)->method(args)
7928+
7929 static inline unsigned int serial_in(struct uart_pxa_port *up, int offset)
7930 {
7931 offset <<= 2;
7932@@ -346,6 +355,9 @@
7933 unsigned long flags;
7934 int retval;
7935
7936+ /* Perform platform-specific port initialization, if needed. */
7937+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_PRE_STARTUP);
7938+
7939 if (port->line == 3) /* HWUART */
7940 up->mcr |= UART_MCR_AFE;
7941 else
7942@@ -401,6 +413,12 @@
7943 (void) serial_in(up, UART_IIR);
7944 (void) serial_in(up, UART_MSR);
7945
7946+ /*
7947+ * Perform platform-specific port initialization if needed
7948+ */
7949+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_POST_STARTUP);
7950+ SAFE_METHOD_CALL(port->dev, set_txrx, PXA_SERIAL_RX);
7951+
7952 return 0;
7953 }
7954
7955@@ -409,6 +427,8 @@
7956 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
7957 unsigned long flags;
7958
7959+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_PRE_SHUTDOWN);
7960+
7961 free_irq(up->port.irq, up);
7962
7963 /*
7964@@ -430,6 +450,8 @@
7965 UART_FCR_CLEAR_RCVR |
7966 UART_FCR_CLEAR_XMIT);
7967 serial_out(up, UART_FCR, 0);
7968+
7969+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_POST_SHUTDOWN);
7970 }
7971
7972 static void
7973Index: linux-2.6.22/arch/arm/mach-pxa/generic.c
7974===================================================================
7975--- linux-2.6.22.orig/arch/arm/mach-pxa/generic.c 2007-09-11 12:53:11.000000000 +0200
7976+++ linux-2.6.22/arch/arm/mach-pxa/generic.c 2007-09-11 12:53:37.000000000 +0200
7977@@ -42,6 +42,7 @@
7978 #include <asm/arch/mmc.h>
7979 #include <asm/arch/irda.h>
7980 #include <asm/arch/i2c.h>
7981+#include <asm/arch/serial.h>
7982
7983 #include "devices.h"
7984 #include "generic.h"
7985@@ -346,6 +347,18 @@
7986 .id = 3,
7987 };
7988
7989+void __init pxa_set_ffuart_info(struct platform_pxa_serial_funcs *info)
7990+{
7991+ pxa_device_ffuart.dev.platform_data = info;
7992+}
7993+EXPORT_SYMBOL(pxa_set_ffuart_info);
7994+
7995+void __init pxa_set_btuart_info(struct platform_pxa_serial_funcs *info)
7996+{
7997+ pxa_device_btuart.dev.platform_data = info;
7998+}
7999+EXPORT_SYMBOL(pxa_set_btuart_info);
8000+
8001 static struct resource pxai2c_resources[] = {
8002 {
8003 .start = 0x40301680,
8004Index: linux-2.6.22/drivers/leds/Makefile
8005===================================================================
8006--- linux-2.6.22.orig/drivers/leds/Makefile 2007-09-11 12:53:14.000000000 +0200
8007+++ linux-2.6.22/drivers/leds/Makefile 2007-09-11 12:53:37.000000000 +0200
8008@@ -16,6 +16,7 @@
8009 obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
8010 obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
8011 obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o
8012+obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
8013 obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
8014
8015 # LED Triggers
8016Index: linux-2.6.22/arch/arm/Kconfig
8017===================================================================
8018--- linux-2.6.22.orig/arch/arm/Kconfig 2007-09-11 12:53:32.000000000 +0200
8019+++ linux-2.6.22/arch/arm/Kconfig 2007-09-11 12:53:37.000000000 +0200
8020@@ -1032,6 +1032,8 @@
8021
8022 source "drivers/w1/Kconfig"
8023
8024+source "drivers/power/Kconfig"
8025+
8026 source "drivers/hwmon/Kconfig"
8027
8028 #source "drivers/l3/Kconfig"
8029Index: linux-2.6.22/drivers/input/keyboard/Kconfig
8030===================================================================
8031--- linux-2.6.22.orig/drivers/input/keyboard/Kconfig 2007-09-11 14:28:45.000000000 +0200
8032+++ linux-2.6.22/drivers/input/keyboard/Kconfig 2007-09-11 14:29:05.000000000 +0200
8033@@ -253,4 +253,11 @@
8034 To compile this driver as a module, choose M here: the
8035 module will be called gpio-keys.
8036
8037+config KEYBOARD_ASIC3
8038+ tristate "Buttons on ASIC3 SoC GPIOs (iPaqs, etc.)"
8039+ depends on HTC_ASIC3
8040+ help
8041+ This enables support for the buttons attached to GPIOs of
8042+ HTC ASIC3 peripheral controller.
8043+
8044 endif
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/mtd-module.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/mtd-module.patch
new file mode 100644
index 0000000000..4aa2f22aee
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/mtd-module.patch
@@ -0,0 +1,13 @@
1Index: linux-2.6.23/drivers/mtd/maps/Kconfig
2===================================================================
3--- linux-2.6.23/drivers/mtd/maps/Kconfig
4+++ linux-2.6.23/drivers/mtd/maps/Kconfig
5@@ -600,7 +600,7 @@
6 default "4"
7
8 config MTD_SHARP_SL
9- bool "ROM mapped on Sharp SL Series"
10+ tristate "ROM mapped on Sharp SL Series"
11 depends on ARCH_PXA
12 help
13 This enables access to the flash chip on the Sharp SL Series of PDAs.
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/pxa-serial-hack.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/pxa-serial-hack.patch
new file mode 100644
index 0000000000..bf20f46a05
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/pxa-serial-hack.patch
@@ -0,0 +1,90 @@
1---
2 drivers/serial/8250.c | 5 +++++
3 drivers/serial/serial_core.c | 1 +
4 drivers/serial/serial_cs.c | 12 +++++++++---
5 include/linux/serial_core.h | 1 +
6 4 files changed, 16 insertions(+), 3 deletions(-)
7
8Index: linux-2.6.20/drivers/serial/8250.c
9===================================================================
10--- linux-2.6.20.orig/drivers/serial/8250.c 2007-04-27 13:37:26.000000000 +0100
11+++ linux-2.6.20/drivers/serial/8250.c 2007-04-27 13:38:16.000000000 +0100
12@@ -2429,7 +2429,12 @@
13 .driver_name = "serial",
14 .dev_name = "ttyS",
15 .major = TTY_MAJOR,
16+#ifdef CONFIG_SERIAL_PXA
17+ .minor = 64 + 4,
18+ .name_base = 4,
19+#else
20 .minor = 64,
21+#endif
22 .nr = UART_NR,
23 .cons = SERIAL8250_CONSOLE,
24 };
25Index: linux-2.6.20/drivers/serial/serial_core.c
26===================================================================
27--- linux-2.6.20.orig/drivers/serial/serial_core.c 2007-02-04 18:44:54.000000000 +0000
28+++ linux-2.6.20/drivers/serial/serial_core.c 2007-04-27 13:39:39.000000000 +0100
29@@ -2068,7 +2068,8 @@
30 printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
31 port->dev ? port->dev->bus_id : "",
32 port->dev ? ": " : "",
33- drv->dev_name, port->line, address, port->irq, uart_type(port));
34+ drv->dev_name, port->line + drv->name_base, address, port->irq,
35+ uart_type(port));
36 }
37
38 static void
39@@ -2183,6 +2184,7 @@
40 normal->owner = drv->owner;
41 normal->driver_name = drv->driver_name;
42 normal->name = drv->dev_name;
43+ normal->name_base = drv->name_base;
44 normal->major = drv->major;
45 normal->minor_start = drv->minor;
46 normal->type = TTY_DRIVER_TYPE_SERIAL;
47Index: linux-2.6.20/include/linux/serial_core.h
48===================================================================
49--- linux-2.6.20.orig/include/linux/serial_core.h 2007-02-04 18:44:54.000000000 +0000
50+++ linux-2.6.20/include/linux/serial_core.h 2007-04-27 13:37:27.000000000 +0100
51@@ -341,6 +341,7 @@
52 struct module *owner;
53 const char *driver_name;
54 const char *dev_name;
55+ int name_base;
56 int major;
57 int minor;
58 int nr;
59Index: linux-2.6.20/drivers/serial/serial_cs.c
60===================================================================
61--- linux-2.6.20.orig/drivers/serial/serial_cs.c 2007-02-04 18:44:54.000000000 +0000
62+++ linux-2.6.20/drivers/serial/serial_cs.c 2007-04-27 13:40:34.000000000 +0100
63@@ -390,7 +390,7 @@
64 kio_addr_t iobase, int irq)
65 {
66 struct uart_port port;
67- int line;
68+ int line, linestart;
69
70 memset(&port, 0, sizeof (struct uart_port));
71 port.iobase = iobase;
72@@ -411,10 +411,16 @@
73 return -EINVAL;
74 }
75
76+#if CONFIG_SERIAL_PXA
77+ linestart = 4;
78+#else
79+ linestart = 0;
80+#endif
81+
82 info->line[info->ndev] = line;
83- sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
84+ sprintf(info->node[info->ndev].dev_name, "ttyS%d", line+linestart);
85 info->node[info->ndev].major = TTY_MAJOR;
86- info->node[info->ndev].minor = 0x40 + line;
87+ info->node[info->ndev].minor = 0x40 + line + linestart;
88 if (info->ndev > 0)
89 info->node[info->ndev - 1].next = &info->node[info->ndev];
90 info->ndev++;
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/pxa_fb_overlay.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/pxa_fb_overlay.patch
new file mode 100644
index 0000000000..49c59b3275
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/pxa_fb_overlay.patch
@@ -0,0 +1,26 @@
1---
2 drivers/video/pxafb.h | 4 ++--
3 1 file changed, 2 insertions(+), 2 deletions(-)
4
5Index: linux-2.6.22/drivers/video/pxafb.h
6===================================================================
7--- linux-2.6.22.orig/drivers/video/pxafb.h 2007-09-25 15:44:42.000000000 +0200
8+++ linux-2.6.22/drivers/video/pxafb.h 2007-09-25 15:45:07.000000000 +0200
9@@ -36,7 +36,7 @@
10 struct fb_bitfield transp;
11 };
12
13-#ifdef CONFIG_PXA27x
14+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
15 /* PXA Overlay Framebuffer Support */
16 struct overlayfb_info
17 {
18@@ -142,7 +142,7 @@
19 wait_queue_head_t ctrlr_wait;
20 struct work_struct task;
21
22-#ifdef CONFIG_PXA27x
23+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
24 /* PXA Overlay Framebuffer Support */
25 struct overlayfb_info *overlay1fb;
26 struct overlayfb_info *overlay2fb;
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch
new file mode 100644
index 0000000000..b513ba1466
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/serial-add-support-for-non-standard-xtals-to-16c950-driver.patch
@@ -0,0 +1,155 @@
1
2From: Petr Vandrovec <vandrove@vc.cvut.cz>
3
4Patch below adds support for using different prescaler than 16 for 16c950
5chips. This is needed for using Fujitsu-Siemens Connect2Air compact-flash
6card, which comes (apparently) with 806kHz clocks, and so you have to
7program prescaler for division by 7, and DLAB to 1, to get 115200Bd.
8
9To get card properly running you also have to add lines below to
10/etc/pcmcia/serial.opts so kernel knows that base speed is not 115200 but
1150400 (50400 * 16 = 806400; 806400 / 7 = 115200). As I've found no code
12specifying baud_rate in serial_cs, I assume that specifying it in
13serial.opts is right way to do this type of things.
14
15Patch also fixes problem that for UPF_MAGIC_MULTIPLIER maximum possible
16baud rate passed to uart code was uartclk / 16 while correct value for
17these devices (and for 16c950) is uartclk / 4.
18
19Patch also fixes problem that for UPF_MAGIC_MULTIPLIER devices with
20baud_rate 19200 or 9600 spd_cust did not work correctly. Not that such
21devices exist, but we should not ignore spd_cust, user probably knows why
22he asked for spd_cust.
23
24serial.opts:
25
26case "$MANFID-$FUNCID-$PRODID_1-$PRODID_2-$PRODID_3-$PRODID_4" in
27'0279,950b-2-GPRS Modem---')
28 SERIAL_OPTS="baud_base 50400"
29 ;;
30esac
31
32Cc: David Woodhouse <dwmw2@infradead.org>
33Signed-off-by: Andrew Morton <akpm@osdl.org>
34---
35
36 drivers/serial/8250.c | 82 +++++++++++++++++++++++++++++++++++++++-----------
37 1 file changed, 64 insertions(+), 18 deletions(-)
38
39Index: linux-2.6.21/drivers/serial/8250.c
40===================================================================
41--- linux-2.6.21.orig/drivers/serial/8250.c 2007-07-01 16:59:52.000000000 +0100
42+++ linux-2.6.21/drivers/serial/8250.c 2007-07-01 17:01:21.000000000 +0100
43@@ -1964,24 +1964,58 @@ static void serial8250_shutdown(struct u
44 serial_unlink_irq_chain(up);
45 }
46
47-static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
48+static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud,
49+ unsigned int *prescaler)
50 {
51- unsigned int quot;
52-
53- /*
54- * Handle magic divisors for baud rates above baud_base on
55- * SMSC SuperIO chips.
56+ /*
57+ * Use special handling only if user did not supply its own divider.
58+ * spd_cust is defined in terms of baud_base, so always use default
59+ * prescaler when spd_cust is requested.
60 */
61- if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
62- baud == (port->uartclk/4))
63- quot = 0x8001;
64- else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
65- baud == (port->uartclk/8))
66- quot = 0x8002;
67- else
68- quot = uart_get_divisor(port, baud);
69
70- return quot;
71+ *prescaler = 16;
72+ if (baud != 38400 || (port->flags & UPF_SPD_MASK) != UPF_SPD_CUST) {
73+ unsigned int quot = port->uartclk / baud;
74+
75+ /*
76+ * Handle magic divisors for baud rates above baud_base on
77+ * SMSC SuperIO chips.
78+ */
79+ if (port->flags & UPF_MAGIC_MULTIPLIER) {
80+ if (quot == 4) {
81+ return 0x8001;
82+ } else if (quot == 8) {
83+ return 0x8002;
84+ }
85+ }
86+ if (port->type == PORT_16C950) {
87+ /*
88+ * This computes TCR value (4 to 16), not CPR value (which can
89+ * be between 1.000 and 31.875) - chip I have uses XTAL of
90+ * 806400Hz, and so a division by 7 is required to get 115200Bd.
91+ * I'm leaving CPR disabled for now, until someone will
92+ * hit even more exotic XTAL (it is needed to get 500kbps
93+ * or 1000kbps from 18.432MHz XTAL, but I have no device
94+ * which would benefit from doing that).
95+ *
96+ * If we can use divide by 16, use it. Otherwise look for
97+ * better prescaler, from 15 to 4. If quotient cannot
98+ * be divided by any integer value between 4 and 15, use 4.
99+ */
100+ if (quot & 0x0F) {
101+ unsigned int div;
102+
103+ for (div = 15; div > 4; div--) {
104+ if (quot % div == 0) {
105+ break;
106+ }
107+ }
108+ *prescaler = div;
109+ return quot / div;
110+ }
111+ }
112+ }
113+ return uart_get_divisor(port, baud);
114 }
115
116 static void
117@@ -1991,7 +2025,7 @@ serial8250_set_termios(struct uart_port
118 struct uart_8250_port *up = (struct uart_8250_port *)port;
119 unsigned char cval, fcr = 0;
120 unsigned long flags;
121- unsigned int baud, quot;
122+ unsigned int baud, quot, prescaler;
123
124 switch (termios->c_cflag & CSIZE) {
125 case CS5:
126@@ -2023,8 +2057,13 @@ serial8250_set_termios(struct uart_port
127 /*
128 * Ask the core to calculate the divisor for us.
129 */
130- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
131- quot = serial8250_get_divisor(port, baud);
132+ if (port->type == PORT_16C950 || (port->flags & UPF_MAGIC_MULTIPLIER)) {
133+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/4);
134+ } else {
135+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
136+ }
137+ quot = serial8250_get_divisor(port, baud, &prescaler);
138+
139
140 /*
141 * Oxford Semi 952 rev B workaround
142@@ -2139,6 +2178,13 @@ serial8250_set_termios(struct uart_port
143 serial_dl_write(up, quot);
144
145 /*
146+ * Program prescaler for 16C950 chips.
147+ */
148+ if (up->port.type == PORT_16C950) {
149+ serial_icr_write(up, UART_TCR, prescaler == 16 ? 0 : prescaler);
150+ }
151+
152+ /*
153 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
154 * is written without DLAB set, this mode will be disabled.
155 */
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/sharpsl-rc-r1.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/sharpsl-rc-r1.patch
new file mode 100644
index 0000000000..08f1f2e721
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/sharpsl-rc-r1.patch
@@ -0,0 +1,519 @@
1Index: linux-2.6.23/arch/arm/mach-pxa/spitz.c
2===================================================================
3--- linux-2.6.23.orig/arch/arm/mach-pxa/spitz.c
4+++ linux-2.6.23/arch/arm/mach-pxa/spitz.c
5@@ -245,6 +245,13 @@ static struct platform_device spitzkbd_d
6 .id = -1,
7 };
8
9+/*
10+ * Spitz Remote Control Device
11+ */
12+static struct platform_device sharpsl_rc_device = {
13+ .name = "sharpsl-remote-control",
14+ .id = -1,
15+};
16
17 /*
18 * Spitz LEDs
19@@ -477,6 +484,7 @@ static struct platform_device *devices[]
20 &spitzscoop_device,
21 &spitzssp_device,
22 &spitzkbd_device,
23+ &sharpsl_rc_device,
24 &spitzts_device,
25 &spitzbl_device,
26 &spitzled_device,
27Index: linux-2.6.23/drivers/input/keyboard/Kconfig
28===================================================================
29--- linux-2.6.23.orig/drivers/input/keyboard/Kconfig
30+++ linux-2.6.23/drivers/input/keyboard/Kconfig
31@@ -154,6 +154,17 @@ config KEYBOARD_SPITZ
32 To compile this driver as a module, choose M here: the
33 module will be called spitzkbd.
34
35+config SHARPSL_RC
36+ tristate "Sharp SL-Cxx00 Remote Control"
37+ depends on PXA_SHARPSL
38+ default y
39+ help
40+ Say Y here to enable the remote on the Sharp Zaurus SL-Cxx00,
41+ SL-C1000, SL-C3000 and Sl-C3100 series of PDAs.
42+
43+ To compile this driver as a module, choose M here: the
44+ module will be called sharpsl_rc.
45+
46 config KEYBOARD_AMIGA
47 tristate "Amiga keyboard"
48 depends on AMIGA
49Index: linux-2.6.23/drivers/input/keyboard/Makefile
50===================================================================
51--- linux-2.6.23.orig/drivers/input/keyboard/Makefile
52+++ linux-2.6.23/drivers/input/keyboard/Makefile
53@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_NEWTON) += newton
54 obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
55 obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
56 obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
57+obj-$(CONFIG_SHARPSL_RC) += sharpsl_rc.o
58 obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
59 obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
60 obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
61Index: linux-2.6.23/drivers/input/keyboard/sharpsl_rc.c
62===================================================================
63--- /dev/null
64+++ linux-2.6.23/drivers/input/keyboard/sharpsl_rc.c
65@@ -0,0 +1,291 @@
66+/*
67+ * Keyboard driver for Sharp Clamshell Models (SL-Cxx00)
68+ *
69+ * Copyright (c) 2004-2005 Richard Purdie
70+ *
71+ * Based on corgikbd.c and Sharp's RC driver
72+ *
73+ * This program is free software; you can redistribute it and/or modify
74+ * it under the terms of the GNU General Public License version 2 as
75+ * published by the Free Software Foundation.
76+ *
77+ */
78+
79+#define DEBUG 1
80+#include <linux/delay.h>
81+#include <linux/platform_device.h>
82+#include <linux/init.h>
83+#include <linux/input.h>
84+#include <linux/interrupt.h>
85+#include <linux/jiffies.h>
86+#include <linux/module.h>
87+#include <linux/slab.h>
88+
89+#ifdef CONFIG_MACH_SPITZ
90+#include <asm/arch/spitz.h>
91+#endif
92+#ifdef CONFIG_MACH_CORGI
93+#include <asm/arch/corgi.h>
94+#endif
95+
96+#include <asm/arch/hardware.h>
97+#include <asm/arch/pxa-regs.h>
98+#include <asm/hardware/scoop.h>
99+#include <asm/arch/sharpsl.h>
100+#include <asm/hardware/sharpsl_pm.h>
101+
102+#define DPRINTK(fmt, args...) dev_dbg(data->dev, fmt "\n", ##args)
103+
104+struct remote_control_key {
105+ unsigned char min;
106+ unsigned char max;
107+ unsigned char key;
108+};
109+
110+#ifdef CONFIG_MACH_SPITZ
111+#define REMOTE_AKIN_PULLUP SPITZ_SCP2_AKIN_PULLUP
112+#define REMOTE_SCOOP_DEVICE spitzscoop2_device
113+#define REMOTE_GPIO_INT SPITZ_GPIO_AK_INT
114+#define REMOTE_IRQ_INT SPITZ_IRQ_GPIO_AK_INT
115+static struct remote_control_key remote_keys[] = {
116+ { 25, 35, KEY_STOPCD},
117+ { 55, 65, KEY_PLAYPAUSE},
118+ { 85, 95, KEY_NEXTSONG},
119+ { 115, 125, KEY_VOLUMEUP},
120+ { 145, 155, KEY_PREVIOUSSONG},
121+ { 180, 190, KEY_MUTE},
122+ { 215, 225, KEY_VOLUMEDOWN},
123+};
124+#endif
125+#ifdef CONFIG_MACH_CORGI
126+#define REMOTE_AKIN_PULLUP CORGI_SCP_AKIN_PULLUP
127+#define REMOTE_SCOOP_DEVICE corgiscoop_device
128+#define REMOTE_GPIO_INT CORGI_GPIO_AK_INT
129+#define REMOTE_IRQ_INT CORGI_IRQ_GPIO_AK_INT
130+static struct remote_control_key remote_keys[] = {
131+ //These need to be fixed for the CE-RH1's values
132+ { 25, 35, KEY_STOPCD},
133+ { 55, 65, KEY_PLAYPAUSE},
134+ { 85, 95, KEY_NEXTSONG},
135+ { 115, 125, KEY_VOLUMEUP},
136+ { 145, 155, KEY_PREVIOUSSONG},
137+ { 180, 190, KEY_MUTE},
138+ { 215, 225, KEY_VOLUMEDOWN},
139+};
140+#endif
141+
142+#define RELEASE_HI 230
143+#define MAX_EARPHONE 6
144+#define RC_POLL_MS 10
145+#define RC_FINISH_MS 500
146+#define WAIT_STATE 3
147+#define NOISE_THRESHOLD 100
148+
149+struct sharpsl_rc {
150+ struct input_dev *input;
151+ struct device *dev;
152+
153+ spinlock_t lock;
154+ struct timer_list rctimer;
155+ struct timer_list rctimer_finish;
156+
157+ unsigned int handling_press;
158+ unsigned int noise;
159+ unsigned int state;
160+ unsigned int last_key;
161+};
162+
163+static int get_remocon_raw(void)
164+{
165+ int i, val;
166+
167+ val = sharpsl_pm_pxa_read_max1111(MAX1111_REMCOM);
168+ for (i = 0; i < ARRAY_SIZE(remote_keys); ++i) {
169+ if (val >= remote_keys[i].min
170+ && val <= remote_keys[i].max) {
171+ printk("get_remocon_raw: VAL=%i, KEY=%i\n", val, remote_keys[i].key);
172+ return remote_keys[i].key;
173+ }
174+ }
175+ return 0;
176+}
177+
178+static irqreturn_t sharpsl_rc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
179+{
180+ struct sharpsl_rc *data = dev_id;
181+ DPRINTK("sharpsl_rc_interrupt %d\n", irq);
182+ if (!data->handling_press) {
183+ DPRINTK("handling interrupt");
184+ data->handling_press = 1;
185+ data->noise = 0;
186+ data->state = 0;
187+ data->last_key = 0;
188+
189+ reset_scoop_gpio(&REMOTE_SCOOP_DEVICE.dev, REMOTE_AKIN_PULLUP);
190+
191+ mod_timer(&data->rctimer, jiffies + msecs_to_jiffies(RC_POLL_MS));
192+ }
193+ return IRQ_HANDLED;
194+}
195+
196+static void sharpsl_rc_timer_callback(unsigned long dataPtr)
197+{
198+ struct sharpsl_rc *data = (struct sharpsl_rc *) dataPtr;
199+ int timer = 1;
200+ int key = get_remocon_raw();
201+ DPRINTK("timer callback, key: %d", key);
202+
203+ //wait for value to stabilize
204+ if (data->state < WAIT_STATE) {
205+ if (data->last_key != key) {
206+ ++data->noise;
207+ if (data->noise > NOISE_THRESHOLD) {
208+ DPRINTK("too much noise, bailing");
209+ timer = 0;
210+ }
211+ data->state = 0;
212+ } else {
213+ ++data->state;
214+ }
215+ data->last_key = key;
216+
217+ //stable value, send event
218+ } else if (data->state == WAIT_STATE) {
219+ data->noise = 0;
220+ //non-key returned, skip the rest of the states and bail now
221+ if (data->last_key == 0) {
222+ DPRINTK("non-key detected %d, noise: %d", data->last_key, data->noise);
223+ timer = 0;
224+ //send button press
225+ } else {
226+ DPRINTK("key press detected %d, noise %d", data->last_key, data->noise);
227+ input_report_key(data->input, data->last_key, 1);
228+ }
229+ ++data->state;
230+
231+ //wait until key is released
232+ } else if (data->state < WAIT_STATE * 2) {
233+ if (key == data->last_key
234+ && data->noise < NOISE_THRESHOLD) {
235+ data->state = WAIT_STATE + 1;
236+ ++data->noise;
237+ } else {
238+ ++data->state;
239+ }
240+ //key is released, send event
241+ } else {
242+ //send button release
243+ DPRINTK("release key %d", data->last_key);
244+ input_report_key(data->input, data->last_key, 0);
245+ timer = 0;
246+ }
247+ if (timer) {
248+ mod_timer(&data->rctimer, jiffies + msecs_to_jiffies(RC_POLL_MS));
249+ } else {
250+ set_scoop_gpio(&REMOTE_SCOOP_DEVICE.dev, REMOTE_AKIN_PULLUP);
251+ data->handling_press = 0;
252+ }
253+}
254+
255+static int __init sharpsl_rc_probe(struct platform_device *pdev)
256+{
257+ struct sharpsl_rc *sharpsl_rc;
258+ struct input_dev *input_dev;
259+ int i, ret;
260+
261+ dev_dbg(&pdev->dev, "sharpsl_rc_probe\n");
262+
263+ sharpsl_rc = kzalloc(sizeof(struct sharpsl_rc), GFP_KERNEL);
264+ input_dev = input_allocate_device();
265+ if (!sharpsl_rc || !input_dev) {
266+ kfree(sharpsl_rc);
267+ input_free_device(input_dev);
268+ return -ENOMEM;
269+ }
270+
271+ platform_set_drvdata(pdev, sharpsl_rc);
272+
273+ sharpsl_rc->dev = &pdev->dev;
274+ sharpsl_rc->input = input_dev;
275+ spin_lock_init(&sharpsl_rc->lock);
276+
277+ /* Init Remote Control Timer */
278+ init_timer(&sharpsl_rc->rctimer);
279+ sharpsl_rc->rctimer.function = sharpsl_rc_timer_callback;
280+ sharpsl_rc->rctimer.data = (unsigned long) sharpsl_rc;
281+
282+ input_dev->name = "Sharp Remote Control CE-RHX";
283+ input_dev->phys = "sharpsl_rc/input0";
284+ input_dev->id.bustype = BUS_HOST;
285+ input_dev->id.vendor = 0x0001;
286+ input_dev->id.product = 0x0001;
287+ input_dev->id.version = 0x0100;
288+ input_dev->cdev.dev = &pdev->dev;
289+ input_dev->private = sharpsl_rc;
290+
291+ input_dev->evbit[0] = BIT(EV_KEY);
292+
293+ for (i = 0; i <= ARRAY_SIZE(remote_keys); i++)
294+ set_bit(remote_keys[i].key, input_dev->keybit);
295+
296+ input_register_device(sharpsl_rc->input);
297+
298+ pxa_gpio_mode(REMOTE_GPIO_INT | GPIO_IN);
299+ ret = request_irq(REMOTE_IRQ_INT,
300+ sharpsl_rc_interrupt,
301+ IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED,
302+ "sharpsl_rc",
303+ sharpsl_rc);
304+ if (ret < 0) {
305+ dev_dbg(&pdev->dev, "Can't get IRQ: %d!\n", i);
306+ kfree(sharpsl_rc);
307+ input_free_device(input_dev);
308+ return ret;
309+ }
310+
311+ return 0;
312+}
313+
314+static int sharpsl_rc_remove(struct platform_device *pdev)
315+{
316+ struct sharpsl_rc *sharpsl_rc = platform_get_drvdata(pdev);
317+
318+ dev_dbg(&pdev->dev, "sharpsl_rc_remove\n");
319+
320+ free_irq(REMOTE_IRQ_INT, sharpsl_rc);
321+ del_timer_sync(&sharpsl_rc->rctimer);
322+ input_unregister_device(sharpsl_rc->input);
323+ kfree(sharpsl_rc);
324+
325+ return 0;
326+}
327+
328+static struct platform_driver sharpsl_rc_driver = {
329+ .probe = sharpsl_rc_probe,
330+ .remove = sharpsl_rc_remove,
331+ .suspend = NULL,
332+ .resume = NULL,
333+ .driver = {
334+ .name = "sharpsl-remote-control",
335+ },
336+};
337+
338+static int __devinit sharpsl_rc_init(void)
339+{
340+ printk("sharpsl_rc_init\n");
341+ return platform_driver_register(&sharpsl_rc_driver);
342+}
343+
344+static void __exit sharpsl_rc_exit(void)
345+{
346+ printk("sharpsl_rc_exit\n");
347+ platform_driver_unregister(&sharpsl_rc_driver);
348+}
349+
350+module_init(sharpsl_rc_init);
351+module_exit(sharpsl_rc_exit);
352+
353+MODULE_AUTHOR("Justin Patrin <papercrane@reversefold.com>");
354+MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
355+MODULE_DESCRIPTION("SharpSL Remote Control Driver");
356+MODULE_LICENSE("GPL");
357Index: linux-2.6.23/drivers/input/keyboard/spitzkbd.c
358===================================================================
359--- linux-2.6.23.orig/drivers/input/keyboard/spitzkbd.c
360+++ linux-2.6.23/drivers/input/keyboard/spitzkbd.c
361@@ -19,6 +19,7 @@
362 #include <linux/jiffies.h>
363 #include <linux/module.h>
364 #include <linux/slab.h>
365+#include <linux/kmod.h>
366
367 #include <asm/arch/spitz.h>
368 #include <asm/arch/hardware.h>
369@@ -279,13 +280,21 @@ static irqreturn_t spitzkbd_hinge_isr(in
370 static int sharpsl_hinge_state;
371 static int hinge_count;
372
373+void spitzkbd_handle_sharpsl_rc(void *arg) {
374+ request_module("sharpsl_rc");
375+}
376+
377+DECLARE_WORK(spitzkbd_work, spitzkbd_handle_sharpsl_rc);
378+
379 static void spitzkbd_hinge_timer(unsigned long data)
380 {
381 struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
382 unsigned long state;
383 unsigned long flags;
384+ unsigned int headphone, remote;
385
386 state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB));
387+ state |= (GPLR(SPITZ_GPIO_HP_IN) & GPIO_bit(SPITZ_GPIO_HP_IN));
388 state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT));
389 if (state != sharpsl_hinge_state) {
390 hinge_count = 0;
391@@ -299,9 +308,18 @@ static void spitzkbd_hinge_timer(unsigne
392
393 input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
394 input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
395- input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0));
396+
397+ headphone = ((GPLR(SPITZ_GPIO_HP_IN) & GPIO_bit(SPITZ_GPIO_HP_IN)) != 0);
398+ input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, headphone);
399+
400+ remote = headphone && ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) == 0);
401+ input_report_switch(spitzkbd_data->input, SW_REMOTE_INSERT, remote);
402 input_sync(spitzkbd_data->input);
403
404+ if (remote) {
405+ schedule_work(&spitzkbd_work);
406+ }
407+
408 spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
409 } else {
410 mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
411@@ -393,6 +411,7 @@ static int __init spitzkbd_probe(struct
412 set_bit(SW_LID, input_dev->swbit);
413 set_bit(SW_TABLET_MODE, input_dev->swbit);
414 set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
415+ set_bit(SW_REMOTE_INSERT, input_dev->swbit);
416
417 err = input_register_device(input_dev);
418 if (err)
419@@ -430,9 +449,12 @@ static int __init spitzkbd_probe(struct
420 request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr,
421 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
422 "Spitzkbd SWB", spitzkbd);
423- request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr,
424+ request_irq(SPITZ_IRQ_GPIO_HP_IN, spitzkbd_hinge_isr,
425 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
426 "Spitzkbd HP", spitzkbd);
427+ request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr,
428+ IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED,
429+ "Spitzkbd HP Type", spitzkbd);
430
431 return 0;
432
433@@ -453,6 +475,7 @@ static int spitzkbd_remove(struct platfo
434 free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd);
435 free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd);
436 free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd);
437+ free_irq(SPITZ_IRQ_GPIO_HP_IN, spitzkbd);
438 free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd);
439
440 del_timer_sync(&spitzkbd->htimer);
441Index: linux-2.6.23/arch/arm/mach-pxa/sharpsl.h
442===================================================================
443--- linux-2.6.23.orig/arch/arm/mach-pxa/sharpsl.h
444+++ linux-2.6.23/arch/arm/mach-pxa/sharpsl.h
445@@ -50,15 +50,10 @@ void spitz_wait_hsync(void);
446
447 #define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
448
449-/* MAX1111 Channel Definitions */
450-#define MAX1111_BATT_VOLT 4u
451-#define MAX1111_BATT_TEMP 2u
452-#define MAX1111_ACIN_VOLT 6u
453-
454 extern struct battery_thresh spitz_battery_levels_acin[];
455 extern struct battery_thresh spitz_battery_levels_noac[];
456 void sharpsl_pm_pxa_init(void);
457 void sharpsl_pm_pxa_remove(void);
458-int sharpsl_pm_pxa_read_max1111(int channel);
459+
460
461
462Index: linux-2.6.23/arch/arm/mach-pxa/sharpsl_pm.c
463===================================================================
464--- linux-2.6.23.orig/arch/arm/mach-pxa/sharpsl_pm.c
465+++ linux-2.6.23/arch/arm/mach-pxa/sharpsl_pm.c
466@@ -135,6 +135,8 @@ int sharpsl_pm_pxa_read_max1111(int chan
467 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
468 }
469
470+EXPORT_SYMBOL(sharpsl_pm_pxa_read_max1111);
471+
472 void sharpsl_pm_pxa_init(void)
473 {
474 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
475Index: linux-2.6.23/include/asm-arm/hardware/sharpsl_pm.h
476===================================================================
477--- linux-2.6.23.orig/include/asm-arm/hardware/sharpsl_pm.h
478+++ linux-2.6.23/include/asm-arm/hardware/sharpsl_pm.h
479@@ -104,3 +104,10 @@ irqreturn_t sharpsl_ac_isr(int irq, void
480 irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id);
481 irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id);
482
483+/* MAX1111 Channel Definitions */
484+#define MAX1111_REMCOM 0u
485+#define MAX1111_BATT_VOLT 4u
486+#define MAX1111_BATT_TEMP 2u
487+#define MAX1111_ACIN_VOLT 6u
488+
489+int sharpsl_pm_pxa_read_max1111(int channel);
490Index: linux-2.6.23/include/linux/input.h
491===================================================================
492--- linux-2.6.23.orig/include/linux/input.h
493+++ linux-2.6.23/include/linux/input.h
494@@ -621,6 +621,7 @@ struct input_absinfo {
495 #define SW_TABLET_MODE 0x01 /* set = tablet mode */
496 #define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
497 #define SW_RADIO 0x03 /* set = radio enabled */
498+#define SW_REMOTE_INSERT 0x04 /* set = remote */
499 #define SW_MAX 0x0f
500
501 /*
502Index: linux-2.6.23/arch/arm/mach-pxa/spitz_pm.c
503===================================================================
504--- linux-2.6.23.orig/arch/arm/mach-pxa/spitz_pm.c
505+++ linux-2.6.23/arch/arm/mach-pxa/spitz_pm.c
506@@ -162,6 +162,13 @@ static int spitz_should_wakeup(unsigned
507 if (resume_on_alarm && (PEDR & PWER_RTC))
508 is_resume |= PWER_RTC;
509
510+ printk("wakeup: PEDR: %x, PKSR: %x, HP_IN: %x, AK_INT: %x\n", PEDR, PKSR, GPIO_bit(SPITZ_GPIO_HP_IN), GPIO_bit(SPITZ_GPIO_AK_INT));
511+
512+ //remote/headphone interrupt, wakeup
513+ if (PEDR == 0 && (PKSR & 0xc0d01) != 0) {
514+ is_resume |= PWER_RTC;
515+ }
516+
517 dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
518 return is_resume;
519 }
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/squashfs3.0-2.6.15.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/squashfs3.0-2.6.15.patch
new file mode 100644
index 0000000000..a210afcaf8
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/squashfs3.0-2.6.15.patch
@@ -0,0 +1,4189 @@
1 fs/Kconfig | 65 +
2 fs/Makefile | 1
3 fs/squashfs/Makefile | 7
4 fs/squashfs/inode.c | 2122 +++++++++++++++++++++++++++++++++++++++++
5 fs/squashfs/squashfs.h | 86 +
6 fs/squashfs/squashfs2_0.c | 757 ++++++++++++++
7 include/linux/squashfs_fs.h | 911 +++++++++++++++++
8 include/linux/squashfs_fs_i.h | 45
9 include/linux/squashfs_fs_sb.h | 74 +
10 init/do_mounts_rd.c | 13
11 10 files changed, 4081 insertions(+)
12
13Index: linux-2.6.22/fs/Kconfig
14===================================================================
15--- linux-2.6.22.orig/fs/Kconfig 2007-08-28 21:56:32.000000000 +0100
16+++ linux-2.6.22/fs/Kconfig 2007-08-28 21:56:34.000000000 +0100
17@@ -1394,6 +1394,71 @@ config CRAMFS
18
19 If unsure, say N.
20
21+config SQUASHFS
22+ tristate "SquashFS 3.0 - Squashed file system support"
23+ select ZLIB_INFLATE
24+ help
25+ Saying Y here includes support for SquashFS 3.0 (a Compressed Read-Only File
26+ System). Squashfs is a highly compressed read-only filesystem for Linux.
27+ It uses zlib compression to compress both files, inodes and directories.
28+ Inodes in the system are very small and all blocks are packed to minimise
29+ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
30+ SquashFS 3.0 supports 64 bit filesystems and files (larger than 4GB), full
31+ uid/gid information, hard links and timestamps.
32+
33+ Squashfs is intended for general read-only filesystem use, for archival
34+ use (i.e. in cases where a .tar.gz file may be used), and in embedded
35+ systems where low overhead is needed. Further information and filesystem tools
36+ are available from http://squashfs.sourceforge.net.
37+
38+ If you want to compile this as a module ( = code which can be
39+ inserted in and removed from the running kernel whenever you want),
40+ say M here and read <file:Documentation/modules.txt>. The module
41+ will be called squashfs. Note that the root file system (the one
42+ containing the directory /) cannot be compiled as a module.
43+
44+ If unsure, say N.
45+
46+config SQUASHFS_EMBEDDED
47+
48+ bool "Additional options for memory-constrained systems"
49+ depends on SQUASHFS
50+ default n
51+ help
52+ Saying Y here allows you to specify cache sizes and how Squashfs
53+ allocates memory. This is only intended for memory constrained
54+ systems.
55+
56+ If unsure, say N.
57+
58+config SQUASHFS_FRAGMENT_CACHE_SIZE
59+ int "Number of fragments cached" if SQUASHFS_EMBEDDED
60+ depends on SQUASHFS
61+ default "3"
62+ help
63+ By default SquashFS caches the last 3 fragments read from
64+ the filesystem. Increasing this amount may mean SquashFS
65+ has to re-read fragments less often from disk, at the expense
66+ of extra system memory. Decreasing this amount will mean
67+ SquashFS uses less memory at the expense of extra reads from disk.
68+
69+ Note there must be at least one cached fragment. Anything
70+ much more than three will probably not make much difference.
71+
72+config SQUASHFS_VMALLOC
73+ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
74+ depends on SQUASHFS
75+ default n
76+ help
77+ By default SquashFS uses kmalloc to obtain fragment cache memory.
78+ Kmalloc memory is the standard kernel allocator, but it can fail
79+ on memory constrained systems. Because of the way Vmalloc works,
80+ Vmalloc can succeed when kmalloc fails. Specifying this option
81+ will make SquashFS always use Vmalloc to allocate the
82+ fragment cache memory.
83+
84+ If unsure, say N.
85+
86 config VXFS_FS
87 tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
88 depends on BLOCK
89Index: linux-2.6.22/fs/Makefile
90===================================================================
91--- linux-2.6.22.orig/fs/Makefile 2007-08-28 21:54:14.000000000 +0100
92+++ linux-2.6.22/fs/Makefile 2007-08-28 21:56:34.000000000 +0100
93@@ -72,6 +72,7 @@ obj-$(CONFIG_JBD) += jbd/
94 obj-$(CONFIG_JBD2) += jbd2/
95 obj-$(CONFIG_EXT2_FS) += ext2/
96 obj-$(CONFIG_CRAMFS) += cramfs/
97+obj-$(CONFIG_SQUASHFS) += squashfs/
98 obj-$(CONFIG_RAMFS) += ramfs/
99 obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
100 obj-$(CONFIG_CODA_FS) += coda/
101Index: linux-2.6.22/fs/squashfs/inode.c
102===================================================================
103--- /dev/null 1970-01-01 00:00:00.000000000 +0000
104+++ linux-2.6.22/fs/squashfs/inode.c 2007-08-28 22:12:03.000000000 +0100
105@@ -0,0 +1,2122 @@
106+/*
107+ * Squashfs - a compressed read only filesystem for Linux
108+ *
109+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
110+ * Phillip Lougher <phillip@lougher.org.uk>
111+ *
112+ * This program is free software; you can redistribute it and/or
113+ * modify it under the terms of the GNU General Public License
114+ * as published by the Free Software Foundation; either version 2,
115+ * or (at your option) any later version.
116+ *
117+ * This program is distributed in the hope that it will be useful,
118+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
119+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
120+ * GNU General Public License for more details.
121+ *
122+ * You should have received a copy of the GNU General Public License
123+ * along with this program; if not, write to the Free Software
124+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
125+ *
126+ * inode.c
127+ */
128+
129+#include <linux/types.h>
130+#include <linux/squashfs_fs.h>
131+#include <linux/module.h>
132+#include <linux/errno.h>
133+#include <linux/slab.h>
134+#include <linux/fs.h>
135+#include <linux/smp_lock.h>
136+#include <linux/slab.h>
137+#include <linux/squashfs_fs_sb.h>
138+#include <linux/squashfs_fs_i.h>
139+#include <linux/buffer_head.h>
140+#include <linux/vfs.h>
141+#include <linux/init.h>
142+#include <linux/dcache.h>
143+#include <linux/wait.h>
144+#include <linux/zlib.h>
145+#include <linux/blkdev.h>
146+#include <linux/vmalloc.h>
147+#include <asm/uaccess.h>
148+#include <asm/semaphore.h>
149+
150+#include "squashfs.h"
151+
152+static void squashfs_put_super(struct super_block *);
153+static int squashfs_statfs(struct dentry *, struct kstatfs *);
154+static int squashfs_symlink_readpage(struct file *file, struct page *page);
155+static int squashfs_readpage(struct file *file, struct page *page);
156+static int squashfs_readpage4K(struct file *file, struct page *page);
157+static int squashfs_readdir(struct file *, void *, filldir_t);
158+static struct inode *squashfs_alloc_inode(struct super_block *sb);
159+static void squashfs_destroy_inode(struct inode *inode);
160+static int init_inodecache(void);
161+static void destroy_inodecache(void);
162+static struct dentry *squashfs_lookup(struct inode *, struct dentry *,
163+ struct nameidata *);
164+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode);
165+static long long read_blocklist(struct inode *inode, int index,
166+ int readahead_blks, char *block_list,
167+ unsigned short **block_p, unsigned int *bsize);
168+static int squashfs_get_sb(struct file_system_type *, int,
169+ const char *, void *, struct vfsmount *);
170+
171+
172+static z_stream stream;
173+
174+static struct file_system_type squashfs_fs_type = {
175+ .owner = THIS_MODULE,
176+ .name = "squashfs",
177+ .get_sb = squashfs_get_sb,
178+ .kill_sb = kill_block_super,
179+ .fs_flags = FS_REQUIRES_DEV
180+};
181+
182+static unsigned char squashfs_filetype_table[] = {
183+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
184+};
185+
186+static struct super_operations squashfs_ops = {
187+ .alloc_inode = squashfs_alloc_inode,
188+ .destroy_inode = squashfs_destroy_inode,
189+ .statfs = squashfs_statfs,
190+ .put_super = squashfs_put_super,
191+};
192+
193+SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = {
194+ .readpage = squashfs_symlink_readpage
195+};
196+
197+SQSH_EXTERN struct address_space_operations squashfs_aops = {
198+ .readpage = squashfs_readpage
199+};
200+
201+SQSH_EXTERN struct address_space_operations squashfs_aops_4K = {
202+ .readpage = squashfs_readpage4K
203+};
204+
205+static struct file_operations squashfs_dir_ops = {
206+ .read = generic_read_dir,
207+ .readdir = squashfs_readdir
208+};
209+
210+SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = {
211+ .lookup = squashfs_lookup
212+};
213+
214+
215+static struct buffer_head *get_block_length(struct super_block *s,
216+ int *cur_index, int *offset, int *c_byte)
217+{
218+ struct squashfs_sb_info *msblk = s->s_fs_info;
219+ unsigned short temp;
220+ struct buffer_head *bh;
221+
222+ if (!(bh = sb_bread(s, *cur_index)))
223+ goto out;
224+
225+ if (msblk->devblksize - *offset == 1) {
226+ if (msblk->swap)
227+ ((unsigned char *) &temp)[1] = *((unsigned char *)
228+ (bh->b_data + *offset));
229+ else
230+ ((unsigned char *) &temp)[0] = *((unsigned char *)
231+ (bh->b_data + *offset));
232+ brelse(bh);
233+ if (!(bh = sb_bread(s, ++(*cur_index))))
234+ goto out;
235+ if (msblk->swap)
236+ ((unsigned char *) &temp)[0] = *((unsigned char *)
237+ bh->b_data);
238+ else
239+ ((unsigned char *) &temp)[1] = *((unsigned char *)
240+ bh->b_data);
241+ *c_byte = temp;
242+ *offset = 1;
243+ } else {
244+ if (msblk->swap) {
245+ ((unsigned char *) &temp)[1] = *((unsigned char *)
246+ (bh->b_data + *offset));
247+ ((unsigned char *) &temp)[0] = *((unsigned char *)
248+ (bh->b_data + *offset + 1));
249+ } else {
250+ ((unsigned char *) &temp)[0] = *((unsigned char *)
251+ (bh->b_data + *offset));
252+ ((unsigned char *) &temp)[1] = *((unsigned char *)
253+ (bh->b_data + *offset + 1));
254+ }
255+ *c_byte = temp;
256+ *offset += 2;
257+ }
258+
259+ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
260+ if (*offset == msblk->devblksize) {
261+ brelse(bh);
262+ if (!(bh = sb_bread(s, ++(*cur_index))))
263+ goto out;
264+ *offset = 0;
265+ }
266+ if (*((unsigned char *) (bh->b_data + *offset)) !=
267+ SQUASHFS_MARKER_BYTE) {
268+ ERROR("Metadata block marker corrupt @ %x\n",
269+ *cur_index);
270+ brelse(bh);
271+ goto out;
272+ }
273+ (*offset)++;
274+ }
275+ return bh;
276+
277+out:
278+ return NULL;
279+}
280+
281+
282+SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
283+ long long index, unsigned int length,
284+ long long *next_index)
285+{
286+ struct squashfs_sb_info *msblk = s->s_fs_info;
287+ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
288+ msblk->devblksize_log2) + 2];
289+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
290+ unsigned int cur_index = index >> msblk->devblksize_log2;
291+ int bytes, avail_bytes, b = 0, k;
292+ char *c_buffer;
293+ unsigned int compressed;
294+ unsigned int c_byte = length;
295+
296+ if (c_byte) {
297+ bytes = msblk->devblksize - offset;
298+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
299+ c_buffer = compressed ? msblk->read_data : buffer;
300+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
301+
302+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
303+ ? "" : "un", (unsigned int) c_byte);
304+
305+ if (!(bh[0] = sb_getblk(s, cur_index)))
306+ goto block_release;
307+
308+ for (b = 1; bytes < c_byte; b++) {
309+ if (!(bh[b] = sb_getblk(s, ++cur_index)))
310+ goto block_release;
311+ bytes += msblk->devblksize;
312+ }
313+ ll_rw_block(READ, b, bh);
314+ } else {
315+ if (!(bh[0] = get_block_length(s, &cur_index, &offset,
316+ &c_byte)))
317+ goto read_failure;
318+
319+ bytes = msblk->devblksize - offset;
320+ compressed = SQUASHFS_COMPRESSED(c_byte);
321+ c_buffer = compressed ? msblk->read_data : buffer;
322+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
323+
324+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
325+ ? "" : "un", (unsigned int) c_byte);
326+
327+ for (b = 1; bytes < c_byte; b++) {
328+ if (!(bh[b] = sb_getblk(s, ++cur_index)))
329+ goto block_release;
330+ bytes += msblk->devblksize;
331+ }
332+ ll_rw_block(READ, b - 1, bh + 1);
333+ }
334+
335+ if (compressed)
336+ down(&msblk->read_data_mutex);
337+
338+ for (bytes = 0, k = 0; k < b; k++) {
339+ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
340+ msblk->devblksize - offset :
341+ c_byte - bytes;
342+ wait_on_buffer(bh[k]);
343+ if (!buffer_uptodate(bh[k]))
344+ goto block_release;
345+ memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes);
346+ bytes += avail_bytes;
347+ offset = 0;
348+ brelse(bh[k]);
349+ }
350+
351+ /*
352+ * uncompress block
353+ */
354+ if (compressed) {
355+ int zlib_err;
356+
357+ stream.next_in = c_buffer;
358+ stream.avail_in = c_byte;
359+ stream.next_out = buffer;
360+ stream.avail_out = msblk->read_size;
361+
362+ if (((zlib_err = zlib_inflateInit(&stream)) != Z_OK) ||
363+ ((zlib_err = zlib_inflate(&stream, Z_FINISH))
364+ != Z_STREAM_END) || ((zlib_err =
365+ zlib_inflateEnd(&stream)) != Z_OK)) {
366+ ERROR("zlib_fs returned unexpected result 0x%x\n",
367+ zlib_err);
368+ bytes = 0;
369+ } else
370+ bytes = stream.total_out;
371+
372+ up(&msblk->read_data_mutex);
373+ }
374+
375+ if (next_index)
376+ *next_index = index + c_byte + (length ? 0 :
377+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags)
378+ ? 3 : 2));
379+ return bytes;
380+
381+block_release:
382+ while (--b >= 0)
383+ brelse(bh[b]);
384+
385+read_failure:
386+ ERROR("sb_bread failed reading block 0x%x\n", cur_index);
387+ return 0;
388+}
389+
390+
391+SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,
392+ long long block, unsigned int offset,
393+ int length, long long *next_block,
394+ unsigned int *next_offset)
395+{
396+ struct squashfs_sb_info *msblk = s->s_fs_info;
397+ int n, i, bytes, return_length = length;
398+ long long next_index;
399+
400+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
401+
402+ while ( 1 ) {
403+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
404+ if (msblk->block_cache[i].block == block)
405+ break;
406+
407+ down(&msblk->block_cache_mutex);
408+
409+ if (i == SQUASHFS_CACHED_BLKS) {
410+ /* read inode header block */
411+ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;
412+ n ; n --, i = (i + 1) %
413+ SQUASHFS_CACHED_BLKS)
414+ if (msblk->block_cache[i].block !=
415+ SQUASHFS_USED_BLK)
416+ break;
417+
418+ if (n == 0) {
419+ wait_queue_t wait;
420+
421+ init_waitqueue_entry(&wait, current);
422+ add_wait_queue(&msblk->waitq, &wait);
423+ set_current_state(TASK_UNINTERRUPTIBLE);
424+ up(&msblk->block_cache_mutex);
425+ schedule();
426+ set_current_state(TASK_RUNNING);
427+ remove_wait_queue(&msblk->waitq, &wait);
428+ continue;
429+ }
430+ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;
431+
432+ if (msblk->block_cache[i].block ==
433+ SQUASHFS_INVALID_BLK) {
434+ if (!(msblk->block_cache[i].data =
435+ kmalloc(SQUASHFS_METADATA_SIZE,
436+ GFP_KERNEL))) {
437+ ERROR("Failed to allocate cache"
438+ "block\n");
439+ up(&msblk->block_cache_mutex);
440+ goto out;
441+ }
442+ }
443+
444+ msblk->block_cache[i].block = SQUASHFS_USED_BLK;
445+ up(&msblk->block_cache_mutex);
446+
447+ if (!(msblk->block_cache[i].length =
448+ squashfs_read_data(s,
449+ msblk->block_cache[i].data,
450+ block, 0, &next_index))) {
451+ ERROR("Unable to read cache block [%llx:%x]\n",
452+ block, offset);
453+ goto out;
454+ }
455+
456+ down(&msblk->block_cache_mutex);
457+ wake_up(&msblk->waitq);
458+ msblk->block_cache[i].block = block;
459+ msblk->block_cache[i].next_index = next_index;
460+ TRACE("Read cache block [%llx:%x]\n", block, offset);
461+ }
462+
463+ if (msblk->block_cache[i].block != block) {
464+ up(&msblk->block_cache_mutex);
465+ continue;
466+ }
467+
468+ if ((bytes = msblk->block_cache[i].length - offset) >= length) {
469+ if (buffer)
470+ memcpy(buffer, msblk->block_cache[i].data +
471+ offset, length);
472+ if (msblk->block_cache[i].length - offset == length) {
473+ *next_block = msblk->block_cache[i].next_index;
474+ *next_offset = 0;
475+ } else {
476+ *next_block = block;
477+ *next_offset = offset + length;
478+ }
479+ up(&msblk->block_cache_mutex);
480+ goto finish;
481+ } else {
482+ if (buffer) {
483+ memcpy(buffer, msblk->block_cache[i].data +
484+ offset, bytes);
485+ buffer += bytes;
486+ }
487+ block = msblk->block_cache[i].next_index;
488+ up(&msblk->block_cache_mutex);
489+ length -= bytes;
490+ offset = 0;
491+ }
492+ }
493+
494+finish:
495+ return return_length;
496+out:
497+ return 0;
498+}
499+
500+
501+static int get_fragment_location(struct super_block *s, unsigned int fragment,
502+ long long *fragment_start_block,
503+ unsigned int *fragment_size)
504+{
505+ struct squashfs_sb_info *msblk = s->s_fs_info;
506+ long long start_block =
507+ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
508+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
509+ struct squashfs_fragment_entry fragment_entry;
510+
511+ if (msblk->swap) {
512+ struct squashfs_fragment_entry sfragment_entry;
513+
514+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
515+ start_block, offset,
516+ sizeof(sfragment_entry), &start_block,
517+ &offset))
518+ goto out;
519+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
520+ } else
521+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
522+ start_block, offset,
523+ sizeof(fragment_entry), &start_block,
524+ &offset))
525+ goto out;
526+
527+ *fragment_start_block = fragment_entry.start_block;
528+ *fragment_size = fragment_entry.size;
529+
530+ return 1;
531+
532+out:
533+ return 0;
534+}
535+
536+
537+SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
538+ squashfs_fragment_cache *fragment)
539+{
540+ down(&msblk->fragment_mutex);
541+ fragment->locked --;
542+ wake_up(&msblk->fragment_wait_queue);
543+ up(&msblk->fragment_mutex);
544+}
545+
546+
547+SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block
548+ *s, long long start_block,
549+ int length)
550+{
551+ int i, n, nf;
552+ struct squashfs_sb_info *msblk = s->s_fs_info;
553+
554+ while ( 1 ) {
555+ down(&msblk->fragment_mutex);
556+
557+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
558+ msblk->fragment[i].block != start_block; i++);
559+
560+ if (i == SQUASHFS_CACHED_FRAGMENTS) {
561+ nf = (msblk->next_fragment + 1) %
562+ SQUASHFS_CACHED_FRAGMENTS;
563+ for (i = msblk->next_fragment, n =
564+ SQUASHFS_CACHED_FRAGMENTS; n &&
565+ msblk->fragment[i].locked; n--, i = (i + 1) %
566+ SQUASHFS_CACHED_FRAGMENTS);
567+
568+ if (n == 0) {
569+ wait_queue_t wait;
570+
571+ init_waitqueue_entry(&wait, current);
572+ add_wait_queue(&msblk->fragment_wait_queue,
573+ &wait);
574+ set_current_state(TASK_UNINTERRUPTIBLE);
575+ up(&msblk->fragment_mutex);
576+ schedule();
577+ set_current_state(TASK_RUNNING);
578+ remove_wait_queue(&msblk->fragment_wait_queue,
579+ &wait);
580+ continue;
581+ }
582+ msblk->next_fragment = nf;
583+
584+ if (msblk->fragment[i].data == NULL)
585+ if (!(msblk->fragment[i].data = SQUASHFS_ALLOC
586+ (SQUASHFS_FILE_MAX_SIZE))) {
587+ ERROR("Failed to allocate fragment "
588+ "cache block\n");
589+ up(&msblk->fragment_mutex);
590+ goto out;
591+ }
592+
593+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
594+ msblk->fragment[i].locked = 1;
595+ up(&msblk->fragment_mutex);
596+
597+ if (!(msblk->fragment[i].length = squashfs_read_data(s,
598+ msblk->fragment[i].data,
599+ start_block, length, NULL))) {
600+ ERROR("Unable to read fragment cache block "
601+ "[%llx]\n", start_block);
602+ msblk->fragment[i].locked = 0;
603+ goto out;
604+ }
605+
606+ msblk->fragment[i].block = start_block;
607+ TRACE("New fragment %d, start block %lld, locked %d\n",
608+ i, msblk->fragment[i].block,
609+ msblk->fragment[i].locked);
610+ break;
611+ }
612+
613+ msblk->fragment[i].locked++;
614+ up(&msblk->fragment_mutex);
615+ TRACE("Got fragment %d, start block %lld, locked %d\n", i,
616+ msblk->fragment[i].block,
617+ msblk->fragment[i].locked);
618+ break;
619+ }
620+
621+ return &msblk->fragment[i];
622+
623+out:
624+ return NULL;
625+}
626+
627+
628+static struct inode *squashfs_new_inode(struct super_block *s,
629+ struct squashfs_base_inode_header *inodeb)
630+{
631+ struct squashfs_sb_info *msblk = s->s_fs_info;
632+ struct inode *i = new_inode(s);
633+
634+ if (i) {
635+ i->i_ino = inodeb->inode_number;
636+ i->i_mtime.tv_sec = inodeb->mtime;
637+ i->i_atime.tv_sec = inodeb->mtime;
638+ i->i_ctime.tv_sec = inodeb->mtime;
639+ i->i_uid = msblk->uid[inodeb->uid];
640+ i->i_mode = inodeb->mode;
641+ i->i_size = 0;
642+ if (inodeb->guid == SQUASHFS_GUIDS)
643+ i->i_gid = i->i_uid;
644+ else
645+ i->i_gid = msblk->guid[inodeb->guid];
646+ }
647+
648+ return i;
649+}
650+
651+
652+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode)
653+{
654+ struct inode *i;
655+ struct squashfs_sb_info *msblk = s->s_fs_info;
656+ struct squashfs_super_block *sblk = &msblk->sblk;
657+ long long block = SQUASHFS_INODE_BLK(inode) +
658+ sblk->inode_table_start;
659+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
660+ long long next_block;
661+ unsigned int next_offset;
662+ union squashfs_inode_header id, sid;
663+ struct squashfs_base_inode_header *inodeb = &id.base,
664+ *sinodeb = &sid.base;
665+
666+ TRACE("Entered squashfs_iget\n");
667+
668+ if (msblk->swap) {
669+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
670+ offset, sizeof(*sinodeb), &next_block,
671+ &next_offset))
672+ goto failed_read;
673+ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb,
674+ sizeof(*sinodeb));
675+ } else
676+ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
677+ offset, sizeof(*inodeb), &next_block,
678+ &next_offset))
679+ goto failed_read;
680+
681+ switch(inodeb->inode_type) {
682+ case SQUASHFS_FILE_TYPE: {
683+ unsigned int frag_size;
684+ long long frag_blk;
685+ struct squashfs_reg_inode_header *inodep = &id.reg;
686+ struct squashfs_reg_inode_header *sinodep = &sid.reg;
687+
688+ if (msblk->swap) {
689+ if (!squashfs_get_cached_block(s, (char *)
690+ sinodep, block, offset,
691+ sizeof(*sinodep), &next_block,
692+ &next_offset))
693+ goto failed_read;
694+ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
695+ } else
696+ if (!squashfs_get_cached_block(s, (char *)
697+ inodep, block, offset,
698+ sizeof(*inodep), &next_block,
699+ &next_offset))
700+ goto failed_read;
701+
702+ frag_blk = SQUASHFS_INVALID_BLK;
703+ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
704+ !get_fragment_location(s,
705+ inodep->fragment, &frag_blk, &frag_size))
706+ goto failed_read;
707+
708+ if((i = squashfs_new_inode(s, inodeb)) == NULL)
709+ goto failed_read1;
710+
711+ i->i_nlink = 1;
712+ i->i_size = inodep->file_size;
713+ i->i_fop = &generic_ro_fops;
714+ i->i_mode |= S_IFREG;
715+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
716+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
717+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
718+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
719+ SQUASHFS_I(i)->start_block = inodep->start_block;
720+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
721+ SQUASHFS_I(i)->offset = next_offset;
722+ if (sblk->block_size > 4096)
723+ i->i_data.a_ops = &squashfs_aops;
724+ else
725+ i->i_data.a_ops = &squashfs_aops_4K;
726+
727+ TRACE("File inode %x:%x, start_block %llx, "
728+ "block_list_start %llx, offset %x\n",
729+ SQUASHFS_INODE_BLK(inode), offset,
730+ inodep->start_block, next_block,
731+ next_offset);
732+ break;
733+ }
734+ case SQUASHFS_LREG_TYPE: {
735+ unsigned int frag_size;
736+ long long frag_blk;
737+ struct squashfs_lreg_inode_header *inodep = &id.lreg;
738+ struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
739+
740+ if (msblk->swap) {
741+ if (!squashfs_get_cached_block(s, (char *)
742+ sinodep, block, offset,
743+ sizeof(*sinodep), &next_block,
744+ &next_offset))
745+ goto failed_read;
746+ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
747+ } else
748+ if (!squashfs_get_cached_block(s, (char *)
749+ inodep, block, offset,
750+ sizeof(*inodep), &next_block,
751+ &next_offset))
752+ goto failed_read;
753+
754+ frag_blk = SQUASHFS_INVALID_BLK;
755+ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
756+ !get_fragment_location(s,
757+ inodep->fragment, &frag_blk, &frag_size))
758+ goto failed_read;
759+
760+ if((i = squashfs_new_inode(s, inodeb)) == NULL)
761+ goto failed_read1;
762+
763+ i->i_nlink = inodep->nlink;
764+ i->i_size = inodep->file_size;
765+ i->i_fop = &generic_ro_fops;
766+ i->i_mode |= S_IFREG;
767+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
768+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
769+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
770+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
771+ SQUASHFS_I(i)->start_block = inodep->start_block;
772+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
773+ SQUASHFS_I(i)->offset = next_offset;
774+ if (sblk->block_size > 4096)
775+ i->i_data.a_ops = &squashfs_aops;
776+ else
777+ i->i_data.a_ops = &squashfs_aops_4K;
778+
779+ TRACE("File inode %x:%x, start_block %llx, "
780+ "block_list_start %llx, offset %x\n",
781+ SQUASHFS_INODE_BLK(inode), offset,
782+ inodep->start_block, next_block,
783+ next_offset);
784+ break;
785+ }
786+ case SQUASHFS_DIR_TYPE: {
787+ struct squashfs_dir_inode_header *inodep = &id.dir;
788+ struct squashfs_dir_inode_header *sinodep = &sid.dir;
789+
790+ if (msblk->swap) {
791+ if (!squashfs_get_cached_block(s, (char *)
792+ sinodep, block, offset,
793+ sizeof(*sinodep), &next_block,
794+ &next_offset))
795+ goto failed_read;
796+ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
797+ } else
798+ if (!squashfs_get_cached_block(s, (char *)
799+ inodep, block, offset,
800+ sizeof(*inodep), &next_block,
801+ &next_offset))
802+ goto failed_read;
803+
804+ if((i = squashfs_new_inode(s, inodeb)) == NULL)
805+ goto failed_read1;
806+
807+ i->i_nlink = inodep->nlink;
808+ i->i_size = inodep->file_size;
809+ i->i_op = &squashfs_dir_inode_ops;
810+ i->i_fop = &squashfs_dir_ops;
811+ i->i_mode |= S_IFDIR;
812+ SQUASHFS_I(i)->start_block = inodep->start_block;
813+ SQUASHFS_I(i)->offset = inodep->offset;
814+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
815+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
816+
817+ TRACE("Directory inode %x:%x, start_block %x, offset "
818+ "%x\n", SQUASHFS_INODE_BLK(inode),
819+ offset, inodep->start_block,
820+ inodep->offset);
821+ break;
822+ }
823+ case SQUASHFS_LDIR_TYPE: {
824+ struct squashfs_ldir_inode_header *inodep = &id.ldir;
825+ struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
826+
827+ if (msblk->swap) {
828+ if (!squashfs_get_cached_block(s, (char *)
829+ sinodep, block, offset,
830+ sizeof(*sinodep), &next_block,
831+ &next_offset))
832+ goto failed_read;
833+ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep,
834+ sinodep);
835+ } else
836+ if (!squashfs_get_cached_block(s, (char *)
837+ inodep, block, offset,
838+ sizeof(*inodep), &next_block,
839+ &next_offset))
840+ goto failed_read;
841+
842+ if((i = squashfs_new_inode(s, inodeb)) == NULL)
843+ goto failed_read1;
844+
845+ i->i_nlink = inodep->nlink;
846+ i->i_size = inodep->file_size;
847+ i->i_op = &squashfs_dir_inode_ops;
848+ i->i_fop = &squashfs_dir_ops;
849+ i->i_mode |= S_IFDIR;
850+ SQUASHFS_I(i)->start_block = inodep->start_block;
851+ SQUASHFS_I(i)->offset = inodep->offset;
852+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
853+ SQUASHFS_I(i)->u.s2.directory_index_offset =
854+ next_offset;
855+ SQUASHFS_I(i)->u.s2.directory_index_count =
856+ inodep->i_count;
857+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
858+
859+ TRACE("Long directory inode %x:%x, start_block %x, "
860+ "offset %x\n",
861+ SQUASHFS_INODE_BLK(inode), offset,
862+ inodep->start_block, inodep->offset);
863+ break;
864+ }
865+ case SQUASHFS_SYMLINK_TYPE: {
866+ struct squashfs_symlink_inode_header *inodep =
867+ &id.symlink;
868+ struct squashfs_symlink_inode_header *sinodep =
869+ &sid.symlink;
870+
871+ if (msblk->swap) {
872+ if (!squashfs_get_cached_block(s, (char *)
873+ sinodep, block, offset,
874+ sizeof(*sinodep), &next_block,
875+ &next_offset))
876+ goto failed_read;
877+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep,
878+ sinodep);
879+ } else
880+ if (!squashfs_get_cached_block(s, (char *)
881+ inodep, block, offset,
882+ sizeof(*inodep), &next_block,
883+ &next_offset))
884+ goto failed_read;
885+
886+ if((i = squashfs_new_inode(s, inodeb)) == NULL)
887+ goto failed_read1;
888+
889+ i->i_nlink = inodep->nlink;
890+ i->i_size = inodep->symlink_size;
891+ i->i_op = &page_symlink_inode_operations;
892+ i->i_data.a_ops = &squashfs_symlink_aops;
893+ i->i_mode |= S_IFLNK;
894+ SQUASHFS_I(i)->start_block = next_block;
895+ SQUASHFS_I(i)->offset = next_offset;
896+
897+ TRACE("Symbolic link inode %x:%x, start_block %llx, "
898+ "offset %x\n",
899+ SQUASHFS_INODE_BLK(inode), offset,
900+ next_block, next_offset);
901+ break;
902+ }
903+ case SQUASHFS_BLKDEV_TYPE:
904+ case SQUASHFS_CHRDEV_TYPE: {
905+ struct squashfs_dev_inode_header *inodep = &id.dev;
906+ struct squashfs_dev_inode_header *sinodep = &sid.dev;
907+
908+ if (msblk->swap) {
909+ if (!squashfs_get_cached_block(s, (char *)
910+ sinodep, block, offset,
911+ sizeof(*sinodep), &next_block,
912+ &next_offset))
913+ goto failed_read;
914+ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
915+ } else
916+ if (!squashfs_get_cached_block(s, (char *)
917+ inodep, block, offset,
918+ sizeof(*inodep), &next_block,
919+ &next_offset))
920+ goto failed_read;
921+
922+ if ((i = squashfs_new_inode(s, inodeb)) == NULL)
923+ goto failed_read1;
924+
925+ i->i_nlink = inodep->nlink;
926+ i->i_mode |= (inodeb->inode_type ==
927+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
928+ S_IFBLK;
929+ init_special_inode(i, i->i_mode,
930+ old_decode_dev(inodep->rdev));
931+
932+ TRACE("Device inode %x:%x, rdev %x\n",
933+ SQUASHFS_INODE_BLK(inode), offset,
934+ inodep->rdev);
935+ break;
936+ }
937+ case SQUASHFS_FIFO_TYPE:
938+ case SQUASHFS_SOCKET_TYPE: {
939+ struct squashfs_ipc_inode_header *inodep = &id.ipc;
940+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
941+
942+ if (msblk->swap) {
943+ if (!squashfs_get_cached_block(s, (char *)
944+ sinodep, block, offset,
945+ sizeof(*sinodep), &next_block,
946+ &next_offset))
947+ goto failed_read;
948+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
949+ } else
950+ if (!squashfs_get_cached_block(s, (char *)
951+ inodep, block, offset,
952+ sizeof(*inodep), &next_block,
953+ &next_offset))
954+ goto failed_read;
955+
956+ if ((i = squashfs_new_inode(s, inodeb)) == NULL)
957+ goto failed_read1;
958+
959+ i->i_nlink = inodep->nlink;
960+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
961+ ? S_IFIFO : S_IFSOCK;
962+ init_special_inode(i, i->i_mode, 0);
963+ break;
964+ }
965+ default:
966+ ERROR("Unknown inode type %d in squashfs_iget!\n",
967+ inodeb->inode_type);
968+ goto failed_read1;
969+ }
970+
971+ insert_inode_hash(i);
972+ return i;
973+
974+failed_read:
975+ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
976+
977+failed_read1:
978+ return NULL;
979+}
980+
981+
982+static int read_fragment_index_table(struct super_block *s)
983+{
984+ struct squashfs_sb_info *msblk = s->s_fs_info;
985+ struct squashfs_super_block *sblk = &msblk->sblk;
986+
987+ /* Allocate fragment index table */
988+ if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
989+ (sblk->fragments), GFP_KERNEL))) {
990+ ERROR("Failed to allocate uid/gid table\n");
991+ return 0;
992+ }
993+
994+ if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&
995+ !squashfs_read_data(s, (char *)
996+ msblk->fragment_index,
997+ sblk->fragment_table_start,
998+ SQUASHFS_FRAGMENT_INDEX_BYTES
999+ (sblk->fragments) |
1000+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1001+ ERROR("unable to read fragment index table\n");
1002+ return 0;
1003+ }
1004+
1005+ if (msblk->swap) {
1006+ int i;
1007+ long long fragment;
1008+
1009+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments);
1010+ i++) {
1011+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
1012+ &msblk->fragment_index[i], 1);
1013+ msblk->fragment_index[i] = fragment;
1014+ }
1015+ }
1016+
1017+ return 1;
1018+}
1019+
1020+
1021+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
1022+{
1023+ struct squashfs_super_block *sblk = &msblk->sblk;
1024+
1025+ msblk->iget = squashfs_iget;
1026+ msblk->read_blocklist = read_blocklist;
1027+ msblk->read_fragment_index_table = read_fragment_index_table;
1028+
1029+ if (sblk->s_major == 1) {
1030+ if (!squashfs_1_0_supported(msblk)) {
1031+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
1032+ "are unsupported\n");
1033+ SERROR("Please recompile with "
1034+ "Squashfs 1.0 support enabled\n");
1035+ return 0;
1036+ }
1037+ } else if (sblk->s_major == 2) {
1038+ if (!squashfs_2_0_supported(msblk)) {
1039+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
1040+ "are unsupported\n");
1041+ SERROR("Please recompile with "
1042+ "Squashfs 2.0 support enabled\n");
1043+ return 0;
1044+ }
1045+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
1046+ SQUASHFS_MINOR) {
1047+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
1048+ "filesystem\n", sblk->s_major, sblk->s_minor);
1049+ SERROR("Please update your kernel\n");
1050+ return 0;
1051+ }
1052+
1053+ return 1;
1054+}
1055+
1056+
1057+static int squashfs_fill_super(struct super_block *s, void *data, int silent)
1058+{
1059+ struct squashfs_sb_info *msblk;
1060+ struct squashfs_super_block *sblk;
1061+ int i;
1062+ char b[BDEVNAME_SIZE];
1063+ struct inode *root;
1064+
1065+ TRACE("Entered squashfs_read_superblock\n");
1066+
1067+ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),
1068+ GFP_KERNEL))) {
1069+ ERROR("Failed to allocate superblock\n");
1070+ goto failure;
1071+ }
1072+ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));
1073+ msblk = s->s_fs_info;
1074+ sblk = &msblk->sblk;
1075+
1076+ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
1077+ msblk->devblksize_log2 = ffz(~msblk->devblksize);
1078+
1079+ init_MUTEX(&msblk->read_data_mutex);
1080+ init_MUTEX(&msblk->read_page_mutex);
1081+ init_MUTEX(&msblk->block_cache_mutex);
1082+ init_MUTEX(&msblk->fragment_mutex);
1083+ init_MUTEX(&msblk->meta_index_mutex);
1084+
1085+ init_waitqueue_head(&msblk->waitq);
1086+ init_waitqueue_head(&msblk->fragment_wait_queue);
1087+
1088+ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
1089+ sizeof(struct squashfs_super_block) |
1090+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1091+ SERROR("unable to read superblock\n");
1092+ goto failed_mount;
1093+ }
1094+
1095+ /* Check it is a SQUASHFS superblock */
1096+ msblk->swap = 0;
1097+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
1098+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
1099+ struct squashfs_super_block ssblk;
1100+
1101+ WARNING("Mounting a different endian SQUASHFS "
1102+ "filesystem on %s\n", bdevname(s->s_bdev, b));
1103+
1104+ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
1105+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
1106+ msblk->swap = 1;
1107+ } else {
1108+ SERROR("Can't find a SQUASHFS superblock on %s\n",
1109+ bdevname(s->s_bdev, b));
1110+ goto failed_mount;
1111+ }
1112+ }
1113+
1114+ /* Check the MAJOR & MINOR versions */
1115+ if(!supported_squashfs_filesystem(msblk, silent))
1116+ goto failed_mount;
1117+
1118+ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
1119+ TRACE("Inodes are %scompressed\n",
1120+ SQUASHFS_UNCOMPRESSED_INODES
1121+ (sblk->flags) ? "un" : "");
1122+ TRACE("Data is %scompressed\n",
1123+ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
1124+ ? "un" : "");
1125+ TRACE("Check data is %s present in the filesystem\n",
1126+ SQUASHFS_CHECK_DATA(sblk->flags) ?
1127+ "" : "not");
1128+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
1129+ TRACE("Block size %d\n", sblk->block_size);
1130+ TRACE("Number of inodes %d\n", sblk->inodes);
1131+ if (sblk->s_major > 1)
1132+ TRACE("Number of fragments %d\n", sblk->fragments);
1133+ TRACE("Number of uids %d\n", sblk->no_uids);
1134+ TRACE("Number of gids %d\n", sblk->no_guids);
1135+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
1136+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
1137+ if (sblk->s_major > 1)
1138+ TRACE("sblk->fragment_table_start %llx\n",
1139+ sblk->fragment_table_start);
1140+ TRACE("sblk->uid_start %llx\n", sblk->uid_start);
1141+
1142+ s->s_flags |= MS_RDONLY;
1143+ s->s_op = &squashfs_ops;
1144+
1145+ /* Init inode_table block pointer array */
1146+ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
1147+ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {
1148+ ERROR("Failed to allocate block cache\n");
1149+ goto failed_mount;
1150+ }
1151+
1152+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
1153+ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
1154+
1155+ msblk->next_cache = 0;
1156+
1157+ /* Allocate read_data block */
1158+ msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?
1159+ SQUASHFS_METADATA_SIZE :
1160+ sblk->block_size;
1161+
1162+ if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {
1163+ ERROR("Failed to allocate read_data block\n");
1164+ goto failed_mount;
1165+ }
1166+
1167+ /* Allocate read_page block */
1168+ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
1169+ ERROR("Failed to allocate read_page block\n");
1170+ goto failed_mount;
1171+ }
1172+
1173+ /* Allocate uid and gid tables */
1174+ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *
1175+ sizeof(unsigned int), GFP_KERNEL))) {
1176+ ERROR("Failed to allocate uid/gid table\n");
1177+ goto failed_mount;
1178+ }
1179+ msblk->guid = msblk->uid + sblk->no_uids;
1180+
1181+ if (msblk->swap) {
1182+ unsigned int suid[sblk->no_uids + sblk->no_guids];
1183+
1184+ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
1185+ ((sblk->no_uids + sblk->no_guids) *
1186+ sizeof(unsigned int)) |
1187+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1188+ ERROR("unable to read uid/gid table\n");
1189+ goto failed_mount;
1190+ }
1191+
1192+ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids +
1193+ sblk->no_guids), (sizeof(unsigned int) * 8));
1194+ } else
1195+ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
1196+ ((sblk->no_uids + sblk->no_guids) *
1197+ sizeof(unsigned int)) |
1198+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1199+ ERROR("unable to read uid/gid table\n");
1200+ goto failed_mount;
1201+ }
1202+
1203+
1204+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
1205+ goto allocate_root;
1206+
1207+ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *
1208+ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {
1209+ ERROR("Failed to allocate fragment block cache\n");
1210+ goto failed_mount;
1211+ }
1212+
1213+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
1214+ msblk->fragment[i].locked = 0;
1215+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
1216+ msblk->fragment[i].data = NULL;
1217+ }
1218+
1219+ msblk->next_fragment = 0;
1220+
1221+ /* Allocate fragment index table */
1222+ if (msblk->read_fragment_index_table(s) == 0)
1223+ goto failed_mount;
1224+
1225+allocate_root:
1226+ if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL)
1227+ goto failed_mount;
1228+
1229+ if ((s->s_root = d_alloc_root(root)) == NULL) {
1230+ ERROR("Root inode create failed\n");
1231+ iput(root);
1232+ goto failed_mount;
1233+ }
1234+
1235+ TRACE("Leaving squashfs_read_super\n");
1236+ return 0;
1237+
1238+failed_mount:
1239+ kfree(msblk->fragment_index);
1240+ kfree(msblk->fragment);
1241+ kfree(msblk->uid);
1242+ kfree(msblk->read_page);
1243+ kfree(msblk->read_data);
1244+ kfree(msblk->block_cache);
1245+ kfree(msblk->fragment_index_2);
1246+ kfree(s->s_fs_info);
1247+ s->s_fs_info = NULL;
1248+ return -EINVAL;
1249+
1250+failure:
1251+ return -ENOMEM;
1252+}
1253+
1254+
1255+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1256+{
1257+ struct super_block *s = dentry->d_sb;
1258+ struct squashfs_sb_info *msblk = s->s_fs_info;
1259+ struct squashfs_super_block *sblk = &msblk->sblk;
1260+
1261+ TRACE("Entered squashfs_statfs\n");
1262+
1263+ buf->f_type = SQUASHFS_MAGIC;
1264+ buf->f_bsize = sblk->block_size;
1265+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
1266+ buf->f_bfree = buf->f_bavail = 0;
1267+ buf->f_files = sblk->inodes;
1268+ buf->f_ffree = 0;
1269+ buf->f_namelen = SQUASHFS_NAME_LEN;
1270+
1271+ return 0;
1272+}
1273+
1274+
1275+static int squashfs_symlink_readpage(struct file *file, struct page *page)
1276+{
1277+ struct inode *inode = page->mapping->host;
1278+ int index = page->index << PAGE_CACHE_SHIFT, length, bytes;
1279+ long long block = SQUASHFS_I(inode)->start_block;
1280+ int offset = SQUASHFS_I(inode)->offset;
1281+ void *pageaddr = kmap(page);
1282+
1283+ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
1284+ "%llx, offset %x\n", page->index,
1285+ SQUASHFS_I(inode)->start_block,
1286+ SQUASHFS_I(inode)->offset);
1287+
1288+ for (length = 0; length < index; length += bytes) {
1289+ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,
1290+ block, offset, PAGE_CACHE_SIZE, &block,
1291+ &offset))) {
1292+ ERROR("Unable to read symbolic link [%llx:%x]\n", block,
1293+ offset);
1294+ goto skip_read;
1295+ }
1296+ }
1297+
1298+ if (length != index) {
1299+ ERROR("(squashfs_symlink_readpage) length != index\n");
1300+ bytes = 0;
1301+ goto skip_read;
1302+ }
1303+
1304+ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :
1305+ i_size_read(inode) - length;
1306+
1307+ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,
1308+ offset, bytes, &block, &offset)))
1309+ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);
1310+
1311+skip_read:
1312+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
1313+ kunmap(page);
1314+ SetPageUptodate(page);
1315+ unlock_page(page);
1316+
1317+ return 0;
1318+}
1319+
1320+
1321+struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
1322+{
1323+ struct meta_index *meta = NULL;
1324+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
1325+ int i;
1326+
1327+ down(&msblk->meta_index_mutex);
1328+
1329+ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
1330+
1331+ if(msblk->meta_index == NULL)
1332+ goto not_allocated;
1333+
1334+ for (i = 0; i < SQUASHFS_META_NUMBER; i ++)
1335+ if (msblk->meta_index[i].inode_number == inode->i_ino &&
1336+ msblk->meta_index[i].offset >= offset &&
1337+ msblk->meta_index[i].offset <= index &&
1338+ msblk->meta_index[i].locked == 0) {
1339+ TRACE("locate_meta_index: entry %d, offset %d\n", i,
1340+ msblk->meta_index[i].offset);
1341+ meta = &msblk->meta_index[i];
1342+ offset = meta->offset;
1343+ }
1344+
1345+ if (meta)
1346+ meta->locked = 1;
1347+
1348+not_allocated:
1349+ up(&msblk->meta_index_mutex);
1350+
1351+ return meta;
1352+}
1353+
1354+
1355+struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
1356+{
1357+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
1358+ struct meta_index *meta = NULL;
1359+ int i;
1360+
1361+ down(&msblk->meta_index_mutex);
1362+
1363+ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
1364+
1365+ if(msblk->meta_index == NULL) {
1366+ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *
1367+ SQUASHFS_META_NUMBER, GFP_KERNEL))) {
1368+ ERROR("Failed to allocate meta_index\n");
1369+ goto failed;
1370+ }
1371+ for(i = 0; i < SQUASHFS_META_NUMBER; i++) {
1372+ msblk->meta_index[i].inode_number = 0;
1373+ msblk->meta_index[i].locked = 0;
1374+ }
1375+ msblk->next_meta_index = 0;
1376+ }
1377+
1378+ for(i = SQUASHFS_META_NUMBER; i &&
1379+ msblk->meta_index[msblk->next_meta_index].locked; i --)
1380+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
1381+ SQUASHFS_META_NUMBER;
1382+
1383+ if(i == 0) {
1384+ TRACE("empty_meta_index: failed!\n");
1385+ goto failed;
1386+ }
1387+
1388+ TRACE("empty_meta_index: returned meta entry %d, %p\n",
1389+ msblk->next_meta_index,
1390+ &msblk->meta_index[msblk->next_meta_index]);
1391+
1392+ meta = &msblk->meta_index[msblk->next_meta_index];
1393+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
1394+ SQUASHFS_META_NUMBER;
1395+
1396+ meta->inode_number = inode->i_ino;
1397+ meta->offset = offset;
1398+ meta->skip = skip;
1399+ meta->entries = 0;
1400+ meta->locked = 1;
1401+
1402+failed:
1403+ up(&msblk->meta_index_mutex);
1404+ return meta;
1405+}
1406+
1407+
1408+void release_meta_index(struct inode *inode, struct meta_index *meta)
1409+{
1410+ meta->locked = 0;
1411+}
1412+
1413+
1414+static int read_block_index(struct super_block *s, int blocks, char *block_list,
1415+ long long *start_block, int *offset)
1416+{
1417+ struct squashfs_sb_info *msblk = s->s_fs_info;
1418+ unsigned int *block_listp;
1419+ int block = 0;
1420+
1421+ if (msblk->swap) {
1422+ char sblock_list[blocks << 2];
1423+
1424+ if (!squashfs_get_cached_block(s, sblock_list, *start_block,
1425+ *offset, blocks << 2, start_block, offset)) {
1426+ ERROR("Unable to read block list [%llx:%x]\n",
1427+ *start_block, *offset);
1428+ goto failure;
1429+ }
1430+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
1431+ ((unsigned int *)sblock_list), blocks);
1432+ } else
1433+ if (!squashfs_get_cached_block(s, block_list, *start_block,
1434+ *offset, blocks << 2, start_block, offset)) {
1435+ ERROR("Unable to read block list [%llx:%x]\n",
1436+ *start_block, *offset);
1437+ goto failure;
1438+ }
1439+
1440+ for (block_listp = (unsigned int *) block_list; blocks;
1441+ block_listp++, blocks --)
1442+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
1443+
1444+ return block;
1445+
1446+failure:
1447+ return -1;
1448+}
1449+
1450+
1451+#define SIZE 256
1452+
1453+static inline int calculate_skip(int blocks) {
1454+ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
1455+ return skip >= 7 ? 7 : skip + 1;
1456+}
1457+
1458+
1459+static int get_meta_index(struct inode *inode, int index,
1460+ long long *index_block, int *index_offset,
1461+ long long *data_block, char *block_list)
1462+{
1463+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
1464+ struct squashfs_super_block *sblk = &msblk->sblk;
1465+ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
1466+ int offset = 0;
1467+ struct meta_index *meta;
1468+ struct meta_entry *meta_entry;
1469+ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
1470+ int cur_offset = SQUASHFS_I(inode)->offset;
1471+ long long cur_data_block = SQUASHFS_I(inode)->start_block;
1472+ int i;
1473+
1474+ index /= SQUASHFS_META_INDEXES * skip;
1475+
1476+ while ( offset < index ) {
1477+ meta = locate_meta_index(inode, index, offset + 1);
1478+
1479+ if (meta == NULL) {
1480+ if ((meta = empty_meta_index(inode, offset + 1,
1481+ skip)) == NULL)
1482+ goto all_done;
1483+ } else {
1484+ offset = index < meta->offset + meta->entries ? index :
1485+ meta->offset + meta->entries - 1;
1486+ meta_entry = &meta->meta_entry[offset - meta->offset];
1487+ cur_index_block = meta_entry->index_block + sblk->inode_table_start;
1488+ cur_offset = meta_entry->offset;
1489+ cur_data_block = meta_entry->data_block;
1490+ TRACE("get_meta_index: offset %d, meta->offset %d, "
1491+ "meta->entries %d\n", offset, meta->offset,
1492+ meta->entries);
1493+ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
1494+ " data_block 0x%llx\n", cur_index_block,
1495+ cur_offset, cur_data_block);
1496+ }
1497+
1498+ for (i = meta->offset + meta->entries; i <= index &&
1499+ i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
1500+ int blocks = skip * SQUASHFS_META_INDEXES;
1501+
1502+ while (blocks) {
1503+ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) :
1504+ blocks;
1505+ int res = read_block_index(inode->i_sb, block,
1506+ block_list, &cur_index_block,
1507+ &cur_offset);
1508+
1509+ if (res == -1)
1510+ goto failed;
1511+
1512+ cur_data_block += res;
1513+ blocks -= block;
1514+ }
1515+
1516+ meta_entry = &meta->meta_entry[i - meta->offset];
1517+ meta_entry->index_block = cur_index_block - sblk->inode_table_start;
1518+ meta_entry->offset = cur_offset;
1519+ meta_entry->data_block = cur_data_block;
1520+ meta->entries ++;
1521+ offset ++;
1522+ }
1523+
1524+ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
1525+ meta->offset, meta->entries);
1526+
1527+ release_meta_index(inode, meta);
1528+ }
1529+
1530+all_done:
1531+ *index_block = cur_index_block;
1532+ *index_offset = cur_offset;
1533+ *data_block = cur_data_block;
1534+
1535+ return offset * SQUASHFS_META_INDEXES * skip;
1536+
1537+failed:
1538+ release_meta_index(inode, meta);
1539+ return -1;
1540+}
1541+
1542+
1543+static long long read_blocklist(struct inode *inode, int index,
1544+ int readahead_blks, char *block_list,
1545+ unsigned short **block_p, unsigned int *bsize)
1546+{
1547+ long long block_ptr;
1548+ int offset;
1549+ long long block;
1550+ int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
1551+ block_list);
1552+
1553+ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
1554+ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset,
1555+ block);
1556+
1557+ if(res == -1)
1558+ goto failure;
1559+
1560+ index -= res;
1561+
1562+ while ( index ) {
1563+ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
1564+ int res = read_block_index(inode->i_sb, blocks, block_list,
1565+ &block_ptr, &offset);
1566+ if (res == -1)
1567+ goto failure;
1568+ block += res;
1569+ index -= blocks;
1570+ }
1571+
1572+ if (read_block_index(inode->i_sb, 1, block_list,
1573+ &block_ptr, &offset) == -1)
1574+ goto failure;
1575+ *bsize = *((unsigned int *) block_list);
1576+
1577+ return block;
1578+
1579+failure:
1580+ return 0;
1581+}
1582+
1583+
1584+static int squashfs_readpage(struct file *file, struct page *page)
1585+{
1586+ struct inode *inode = page->mapping->host;
1587+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
1588+ struct squashfs_super_block *sblk = &msblk->sblk;
1589+ unsigned char block_list[SIZE];
1590+ long long block;
1591+ unsigned int bsize, i = 0, bytes = 0, byte_offset = 0;
1592+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
1593+ void *pageaddr;
1594+ struct squashfs_fragment_cache *fragment = NULL;
1595+ char *data_ptr = msblk->read_page;
1596+
1597+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
1598+ int start_index = page->index & ~mask;
1599+ int end_index = start_index | mask;
1600+
1601+ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
1602+ page->index,
1603+ SQUASHFS_I(inode)->start_block);
1604+
1605+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
1606+ PAGE_CACHE_SHIFT))
1607+ goto skip_read;
1608+
1609+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
1610+ || index < (i_size_read(inode) >>
1611+ sblk->block_log)) {
1612+ if ((block = (msblk->read_blocklist)(inode, index, 1,
1613+ block_list, NULL, &bsize)) == 0)
1614+ goto skip_read;
1615+
1616+ down(&msblk->read_page_mutex);
1617+
1618+ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
1619+ block, bsize, NULL))) {
1620+ ERROR("Unable to read page, block %llx, size %x\n", block,
1621+ bsize);
1622+ up(&msblk->read_page_mutex);
1623+ goto skip_read;
1624+ }
1625+ } else {
1626+ if ((fragment = get_cached_fragment(inode->i_sb,
1627+ SQUASHFS_I(inode)->
1628+ u.s1.fragment_start_block,
1629+ SQUASHFS_I(inode)->u.s1.fragment_size))
1630+ == NULL) {
1631+ ERROR("Unable to read page, block %llx, size %x\n",
1632+ SQUASHFS_I(inode)->
1633+ u.s1.fragment_start_block,
1634+ (int) SQUASHFS_I(inode)->
1635+ u.s1.fragment_size);
1636+ goto skip_read;
1637+ }
1638+ bytes = SQUASHFS_I(inode)->u.s1.fragment_offset +
1639+ (i_size_read(inode) & (sblk->block_size
1640+ - 1));
1641+ byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset;
1642+ data_ptr = fragment->data;
1643+ }
1644+
1645+ for (i = start_index; i <= end_index && byte_offset < bytes;
1646+ i++, byte_offset += PAGE_CACHE_SIZE) {
1647+ struct page *push_page;
1648+ int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ?
1649+ PAGE_CACHE_SIZE : bytes - byte_offset;
1650+
1651+ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",
1652+ bytes, i, byte_offset, available_bytes);
1653+
1654+ if (i == page->index) {
1655+ pageaddr = kmap_atomic(page, KM_USER0);
1656+ memcpy(pageaddr, data_ptr + byte_offset,
1657+ available_bytes);
1658+ memset(pageaddr + available_bytes, 0,
1659+ PAGE_CACHE_SIZE - available_bytes);
1660+ kunmap_atomic(pageaddr, KM_USER0);
1661+ flush_dcache_page(page);
1662+ SetPageUptodate(page);
1663+ unlock_page(page);
1664+ } else if ((push_page =
1665+ grab_cache_page_nowait(page->mapping, i))) {
1666+ pageaddr = kmap_atomic(push_page, KM_USER0);
1667+
1668+ memcpy(pageaddr, data_ptr + byte_offset,
1669+ available_bytes);
1670+ memset(pageaddr + available_bytes, 0,
1671+ PAGE_CACHE_SIZE - available_bytes);
1672+ kunmap_atomic(pageaddr, KM_USER0);
1673+ flush_dcache_page(push_page);
1674+ SetPageUptodate(push_page);
1675+ unlock_page(push_page);
1676+ page_cache_release(push_page);
1677+ }
1678+ }
1679+
1680+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
1681+ || index < (i_size_read(inode) >>
1682+ sblk->block_log))
1683+ up(&msblk->read_page_mutex);
1684+ else
1685+ release_cached_fragment(msblk, fragment);
1686+
1687+ return 0;
1688+
1689+skip_read:
1690+ pageaddr = kmap_atomic(page, KM_USER0);
1691+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
1692+ kunmap_atomic(pageaddr, KM_USER0);
1693+ flush_dcache_page(page);
1694+ SetPageUptodate(page);
1695+ unlock_page(page);
1696+
1697+ return 0;
1698+}
1699+
1700+
1701+static int squashfs_readpage4K(struct file *file, struct page *page)
1702+{
1703+ struct inode *inode = page->mapping->host;
1704+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
1705+ struct squashfs_super_block *sblk = &msblk->sblk;
1706+ unsigned char block_list[SIZE];
1707+ long long block;
1708+ unsigned int bsize, bytes = 0;
1709+ void *pageaddr;
1710+
1711+ TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",
1712+ page->index,
1713+ SQUASHFS_I(inode)->start_block);
1714+
1715+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
1716+ PAGE_CACHE_SHIFT)) {
1717+ pageaddr = kmap_atomic(page, KM_USER0);
1718+ goto skip_read;
1719+ }
1720+
1721+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
1722+ || page->index < (i_size_read(inode) >>
1723+ sblk->block_log)) {
1724+ block = (msblk->read_blocklist)(inode, page->index, 1,
1725+ block_list, NULL, &bsize);
1726+
1727+ down(&msblk->read_page_mutex);
1728+ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
1729+ bsize, NULL);
1730+ pageaddr = kmap_atomic(page, KM_USER0);
1731+ if (bytes)
1732+ memcpy(pageaddr, msblk->read_page, bytes);
1733+ else
1734+ ERROR("Unable to read page, block %llx, size %x\n",
1735+ block, bsize);
1736+ up(&msblk->read_page_mutex);
1737+ } else {
1738+ struct squashfs_fragment_cache *fragment =
1739+ get_cached_fragment(inode->i_sb,
1740+ SQUASHFS_I(inode)->
1741+ u.s1.fragment_start_block,
1742+ SQUASHFS_I(inode)-> u.s1.fragment_size);
1743+ pageaddr = kmap_atomic(page, KM_USER0);
1744+ if (fragment) {
1745+ bytes = i_size_read(inode) & (sblk->block_size - 1);
1746+ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
1747+ u.s1.fragment_offset, bytes);
1748+ release_cached_fragment(msblk, fragment);
1749+ } else
1750+ ERROR("Unable to read page, block %llx, size %x\n",
1751+ SQUASHFS_I(inode)->
1752+ u.s1.fragment_start_block, (int)
1753+ SQUASHFS_I(inode)-> u.s1.fragment_size);
1754+ }
1755+
1756+skip_read:
1757+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
1758+ kunmap_atomic(pageaddr, KM_USER0);
1759+ flush_dcache_page(page);
1760+ SetPageUptodate(page);
1761+ unlock_page(page);
1762+
1763+ return 0;
1764+}
1765+
1766+
1767+static int get_dir_index_using_offset(struct super_block *s, long long
1768+ *next_block, unsigned int *next_offset,
1769+ long long index_start,
1770+ unsigned int index_offset, int i_count,
1771+ long long f_pos)
1772+{
1773+ struct squashfs_sb_info *msblk = s->s_fs_info;
1774+ struct squashfs_super_block *sblk = &msblk->sblk;
1775+ int i, length = 0;
1776+ struct squashfs_dir_index index;
1777+
1778+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
1779+ i_count, (unsigned int) f_pos);
1780+
1781+ f_pos =- 3;
1782+ if (f_pos == 0)
1783+ goto finish;
1784+
1785+ for (i = 0; i < i_count; i++) {
1786+ if (msblk->swap) {
1787+ struct squashfs_dir_index sindex;
1788+ squashfs_get_cached_block(s, (char *) &sindex,
1789+ index_start, index_offset,
1790+ sizeof(sindex), &index_start,
1791+ &index_offset);
1792+ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
1793+ } else
1794+ squashfs_get_cached_block(s, (char *) &index,
1795+ index_start, index_offset,
1796+ sizeof(index), &index_start,
1797+ &index_offset);
1798+
1799+ if (index.index > f_pos)
1800+ break;
1801+
1802+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
1803+ index.size + 1, &index_start,
1804+ &index_offset);
1805+
1806+ length = index.index;
1807+ *next_block = index.start_block + sblk->directory_table_start;
1808+ }
1809+
1810+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
1811+
1812+finish:
1813+ return length + 3;
1814+}
1815+
1816+
1817+static int get_dir_index_using_name(struct super_block *s, long long
1818+ *next_block, unsigned int *next_offset,
1819+ long long index_start,
1820+ unsigned int index_offset, int i_count,
1821+ const char *name, int size)
1822+{
1823+ struct squashfs_sb_info *msblk = s->s_fs_info;
1824+ struct squashfs_super_block *sblk = &msblk->sblk;
1825+ int i, length = 0;
1826+ char buffer[sizeof(struct squashfs_dir_index) + SQUASHFS_NAME_LEN + 1];
1827+ struct squashfs_dir_index *index = (struct squashfs_dir_index *) buffer;
1828+ char str[SQUASHFS_NAME_LEN + 1];
1829+
1830+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
1831+
1832+ strncpy(str, name, size);
1833+ str[size] = '\0';
1834+
1835+ for (i = 0; i < i_count; i++) {
1836+ if (msblk->swap) {
1837+ struct squashfs_dir_index sindex;
1838+ squashfs_get_cached_block(s, (char *) &sindex,
1839+ index_start, index_offset,
1840+ sizeof(sindex), &index_start,
1841+ &index_offset);
1842+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
1843+ } else
1844+ squashfs_get_cached_block(s, (char *) index,
1845+ index_start, index_offset,
1846+ sizeof(struct squashfs_dir_index),
1847+ &index_start, &index_offset);
1848+
1849+ squashfs_get_cached_block(s, index->name, index_start,
1850+ index_offset, index->size + 1,
1851+ &index_start, &index_offset);
1852+
1853+ index->name[index->size + 1] = '\0';
1854+
1855+ if (strcmp(index->name, str) > 0)
1856+ break;
1857+
1858+ length = index->index;
1859+ *next_block = index->start_block + sblk->directory_table_start;
1860+ }
1861+
1862+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
1863+ return length + 3;
1864+}
1865+
1866+
1867+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
1868+{
1869+ struct inode *i = file->f_dentry->d_inode;
1870+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
1871+ struct squashfs_super_block *sblk = &msblk->sblk;
1872+ long long next_block = SQUASHFS_I(i)->start_block +
1873+ sblk->directory_table_start;
1874+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
1875+ dir_count;
1876+ struct squashfs_dir_header dirh;
1877+ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1];
1878+ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
1879+
1880+ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
1881+
1882+ while(file->f_pos < 3) {
1883+ char *name;
1884+ int size, i_ino;
1885+
1886+ if(file->f_pos == 0) {
1887+ name = ".";
1888+ size = 1;
1889+ i_ino = i->i_ino;
1890+ } else {
1891+ name = "..";
1892+ size = 2;
1893+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
1894+ }
1895+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
1896+ (unsigned int) dirent, name, size, (int)
1897+ file->f_pos, i_ino,
1898+ squashfs_filetype_table[1]);
1899+
1900+ if (filldir(dirent, name, size,
1901+ file->f_pos, i_ino,
1902+ squashfs_filetype_table[1]) < 0) {
1903+ TRACE("Filldir returned less than 0\n");
1904+ goto finish;
1905+ }
1906+ file->f_pos += size;
1907+ dirs_read++;
1908+ }
1909+
1910+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
1911+ SQUASHFS_I(i)->u.s2.directory_index_start,
1912+ SQUASHFS_I(i)->u.s2.directory_index_offset,
1913+ SQUASHFS_I(i)->u.s2.directory_index_count,
1914+ file->f_pos);
1915+
1916+ while (length < i_size_read(i)) {
1917+ /* read directory header */
1918+ if (msblk->swap) {
1919+ struct squashfs_dir_header sdirh;
1920+
1921+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
1922+ next_block, next_offset, sizeof(sdirh),
1923+ &next_block, &next_offset))
1924+ goto failed_read;
1925+
1926+ length += sizeof(sdirh);
1927+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
1928+ } else {
1929+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
1930+ next_block, next_offset, sizeof(dirh),
1931+ &next_block, &next_offset))
1932+ goto failed_read;
1933+
1934+ length += sizeof(dirh);
1935+ }
1936+
1937+ dir_count = dirh.count + 1;
1938+ while (dir_count--) {
1939+ if (msblk->swap) {
1940+ struct squashfs_dir_entry sdire;
1941+ if (!squashfs_get_cached_block(i->i_sb, (char *)
1942+ &sdire, next_block, next_offset,
1943+ sizeof(sdire), &next_block,
1944+ &next_offset))
1945+ goto failed_read;
1946+
1947+ length += sizeof(sdire);
1948+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
1949+ } else {
1950+ if (!squashfs_get_cached_block(i->i_sb, (char *)
1951+ dire, next_block, next_offset,
1952+ sizeof(*dire), &next_block,
1953+ &next_offset))
1954+ goto failed_read;
1955+
1956+ length += sizeof(*dire);
1957+ }
1958+
1959+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
1960+ next_block, next_offset,
1961+ dire->size + 1, &next_block,
1962+ &next_offset))
1963+ goto failed_read;
1964+
1965+ length += dire->size + 1;
1966+
1967+ if (file->f_pos >= length)
1968+ continue;
1969+
1970+ dire->name[dire->size + 1] = '\0';
1971+
1972+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
1973+ (unsigned int) dirent, dire->name,
1974+ dire->size + 1, (int) file->f_pos,
1975+ dirh.start_block, dire->offset,
1976+ dirh.inode_number + dire->inode_number,
1977+ squashfs_filetype_table[dire->type]);
1978+
1979+ if (filldir(dirent, dire->name, dire->size + 1,
1980+ file->f_pos,
1981+ dirh.inode_number + dire->inode_number,
1982+ squashfs_filetype_table[dire->type])
1983+ < 0) {
1984+ TRACE("Filldir returned less than 0\n");
1985+ goto finish;
1986+ }
1987+ file->f_pos = length;
1988+ dirs_read++;
1989+ }
1990+ }
1991+
1992+finish:
1993+ return dirs_read;
1994+
1995+failed_read:
1996+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
1997+ next_offset);
1998+ return 0;
1999+}
2000+
2001+
2002+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
2003+ struct nameidata *nd)
2004+{
2005+ const unsigned char *name = dentry->d_name.name;
2006+ int len = dentry->d_name.len;
2007+ struct inode *inode = NULL;
2008+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
2009+ struct squashfs_super_block *sblk = &msblk->sblk;
2010+ long long next_block = SQUASHFS_I(i)->start_block +
2011+ sblk->directory_table_start;
2012+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
2013+ dir_count;
2014+ struct squashfs_dir_header dirh;
2015+ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN];
2016+ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
2017+
2018+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
2019+
2020+ if (len > SQUASHFS_NAME_LEN)
2021+ goto exit_loop;
2022+
2023+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
2024+ SQUASHFS_I(i)->u.s2.directory_index_start,
2025+ SQUASHFS_I(i)->u.s2.directory_index_offset,
2026+ SQUASHFS_I(i)->u.s2.directory_index_count, name,
2027+ len);
2028+
2029+ while (length < i_size_read(i)) {
2030+ /* read directory header */
2031+ if (msblk->swap) {
2032+ struct squashfs_dir_header sdirh;
2033+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
2034+ next_block, next_offset, sizeof(sdirh),
2035+ &next_block, &next_offset))
2036+ goto failed_read;
2037+
2038+ length += sizeof(sdirh);
2039+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
2040+ } else {
2041+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
2042+ next_block, next_offset, sizeof(dirh),
2043+ &next_block, &next_offset))
2044+ goto failed_read;
2045+
2046+ length += sizeof(dirh);
2047+ }
2048+
2049+ dir_count = dirh.count + 1;
2050+ while (dir_count--) {
2051+ if (msblk->swap) {
2052+ struct squashfs_dir_entry sdire;
2053+ if (!squashfs_get_cached_block(i->i_sb, (char *)
2054+ &sdire, next_block,next_offset,
2055+ sizeof(sdire), &next_block,
2056+ &next_offset))
2057+ goto failed_read;
2058+
2059+ length += sizeof(sdire);
2060+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
2061+ } else {
2062+ if (!squashfs_get_cached_block(i->i_sb, (char *)
2063+ dire, next_block,next_offset,
2064+ sizeof(*dire), &next_block,
2065+ &next_offset))
2066+ goto failed_read;
2067+
2068+ length += sizeof(*dire);
2069+ }
2070+
2071+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
2072+ next_block, next_offset, dire->size + 1,
2073+ &next_block, &next_offset))
2074+ goto failed_read;
2075+
2076+ length += dire->size + 1;
2077+
2078+ if (name[0] < dire->name[0])
2079+ goto exit_loop;
2080+
2081+ if ((len == dire->size + 1) && !strncmp(name,
2082+ dire->name, len)) {
2083+ squashfs_inode_t ino =
2084+ SQUASHFS_MKINODE(dirh.start_block,
2085+ dire->offset);
2086+
2087+ TRACE("calling squashfs_iget for directory "
2088+ "entry %s, inode %x:%x, %d\n", name,
2089+ dirh.start_block, dire->offset,
2090+ dirh.inode_number + dire->inode_number);
2091+
2092+ inode = (msblk->iget)(i->i_sb, ino);
2093+
2094+ goto exit_loop;
2095+ }
2096+ }
2097+ }
2098+
2099+exit_loop:
2100+ d_add(dentry, inode);
2101+ return ERR_PTR(0);
2102+
2103+failed_read:
2104+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
2105+ next_offset);
2106+ goto exit_loop;
2107+}
2108+
2109+
2110+static void squashfs_put_super(struct super_block *s)
2111+{
2112+ int i;
2113+
2114+ if (s->s_fs_info) {
2115+ struct squashfs_sb_info *sbi = s->s_fs_info;
2116+ if (sbi->block_cache)
2117+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
2118+ if (sbi->block_cache[i].block !=
2119+ SQUASHFS_INVALID_BLK)
2120+ kfree(sbi->block_cache[i].data);
2121+ if (sbi->fragment)
2122+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)
2123+ SQUASHFS_FREE(sbi->fragment[i].data);
2124+ kfree(sbi->fragment);
2125+ kfree(sbi->block_cache);
2126+ kfree(sbi->read_data);
2127+ kfree(sbi->read_page);
2128+ kfree(sbi->uid);
2129+ kfree(sbi->fragment_index);
2130+ kfree(sbi->fragment_index_2);
2131+ kfree(sbi->meta_index);
2132+ kfree(s->s_fs_info);
2133+ s->s_fs_info = NULL;
2134+ }
2135+}
2136+
2137+
2138+static int squashfs_get_sb(struct file_system_type *fs_type,
2139+ int flags, const char *dev_name, void *data, struct vfsmount *mnt)
2140+{
2141+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, mnt);
2142+}
2143+
2144+
2145+static int __init init_squashfs_fs(void)
2146+{
2147+ int err = init_inodecache();
2148+ if (err)
2149+ goto out;
2150+
2151+ printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) "
2152+ "Phillip Lougher\n");
2153+
2154+ if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
2155+ ERROR("Failed to allocate zlib workspace\n");
2156+ destroy_inodecache();
2157+ err = -ENOMEM;
2158+ goto out;
2159+ }
2160+
2161+ if ((err = register_filesystem(&squashfs_fs_type))) {
2162+ vfree(stream.workspace);
2163+ destroy_inodecache();
2164+ }
2165+
2166+out:
2167+ return err;
2168+}
2169+
2170+
2171+static void __exit exit_squashfs_fs(void)
2172+{
2173+ vfree(stream.workspace);
2174+ unregister_filesystem(&squashfs_fs_type);
2175+ destroy_inodecache();
2176+}
2177+
2178+
2179+static struct kmem_cache* squashfs_inode_cachep;
2180+
2181+
2182+static struct inode *squashfs_alloc_inode(struct super_block *sb)
2183+{
2184+ struct squashfs_inode_info *ei;
2185+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
2186+ if (!ei)
2187+ return NULL;
2188+ return &ei->vfs_inode;
2189+}
2190+
2191+
2192+static void squashfs_destroy_inode(struct inode *inode)
2193+{
2194+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
2195+}
2196+
2197+
2198+static void init_once(void * foo, struct kmem_cache *cachep, unsigned long flags)
2199+{
2200+ struct squashfs_inode_info *ei = foo;
2201+
2202+ inode_init_once(&ei->vfs_inode);
2203+}
2204+
2205+
2206+static int __init init_inodecache(void)
2207+{
2208+ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
2209+ sizeof(struct squashfs_inode_info),
2210+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
2211+ init_once);
2212+ if (squashfs_inode_cachep == NULL)
2213+ return -ENOMEM;
2214+ return 0;
2215+}
2216+
2217+
2218+static void destroy_inodecache(void)
2219+{
2220+ kmem_cache_destroy(squashfs_inode_cachep);
2221+}
2222+
2223+
2224+module_init(init_squashfs_fs);
2225+module_exit(exit_squashfs_fs);
2226+MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem");
2227+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.org.uk>");
2228Index: linux-2.6.22/fs/squashfs/Makefile
2229===================================================================
2230--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2231+++ linux-2.6.22/fs/squashfs/Makefile 2007-08-28 21:56:34.000000000 +0100
2232@@ -0,0 +1,7 @@
2233+#
2234+# Makefile for the linux squashfs routines.
2235+#
2236+
2237+obj-$(CONFIG_SQUASHFS) += squashfs.o
2238+squashfs-y += inode.o
2239+squashfs-y += squashfs2_0.o
2240Index: linux-2.6.22/fs/squashfs/squashfs2_0.c
2241===================================================================
2242--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2243+++ linux-2.6.22/fs/squashfs/squashfs2_0.c 2007-08-28 21:56:34.000000000 +0100
2244@@ -0,0 +1,757 @@
2245+/*
2246+ * Squashfs - a compressed read only filesystem for Linux
2247+ *
2248+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
2249+ * Phillip Lougher <phillip@lougher.org.uk>
2250+ *
2251+ * This program is free software; you can redistribute it and/or
2252+ * modify it under the terms of the GNU General Public License
2253+ * as published by the Free Software Foundation; either version 2,
2254+ * or (at your option) any later version.
2255+ *
2256+ * This program is distributed in the hope that it will be useful,
2257+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2258+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2259+ * GNU General Public License for more details.
2260+ *
2261+ * You should have received a copy of the GNU General Public License
2262+ * along with this program; if not, write to the Free Software
2263+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2264+ *
2265+ * squashfs2_0.c
2266+ */
2267+
2268+#include <linux/types.h>
2269+#include <linux/squashfs_fs.h>
2270+#include <linux/module.h>
2271+#include <linux/errno.h>
2272+#include <linux/slab.h>
2273+#include <linux/fs.h>
2274+#include <linux/smp_lock.h>
2275+#include <linux/slab.h>
2276+#include <linux/squashfs_fs_sb.h>
2277+#include <linux/squashfs_fs_i.h>
2278+#include <linux/buffer_head.h>
2279+#include <linux/vfs.h>
2280+#include <linux/init.h>
2281+#include <linux/dcache.h>
2282+#include <linux/wait.h>
2283+#include <linux/zlib.h>
2284+#include <linux/blkdev.h>
2285+#include <linux/vmalloc.h>
2286+#include <asm/uaccess.h>
2287+#include <asm/semaphore.h>
2288+
2289+#include "squashfs.h"
2290+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
2291+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
2292+ struct nameidata *);
2293+
2294+static struct file_operations squashfs_dir_ops_2 = {
2295+ .read = generic_read_dir,
2296+ .readdir = squashfs_readdir_2
2297+};
2298+
2299+static struct inode_operations squashfs_dir_inode_ops_2 = {
2300+ .lookup = squashfs_lookup_2
2301+};
2302+
2303+static unsigned char squashfs_filetype_table[] = {
2304+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
2305+};
2306+
2307+static int read_fragment_index_table_2(struct super_block *s)
2308+{
2309+ struct squashfs_sb_info *msblk = s->s_fs_info;
2310+ struct squashfs_super_block *sblk = &msblk->sblk;
2311+
2312+ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
2313+ (sblk->fragments), GFP_KERNEL))) {
2314+ ERROR("Failed to allocate uid/gid table\n");
2315+ return 0;
2316+ }
2317+
2318+ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
2319+ !squashfs_read_data(s, (char *)
2320+ msblk->fragment_index_2,
2321+ sblk->fragment_table_start,
2322+ SQUASHFS_FRAGMENT_INDEX_BYTES_2
2323+ (sblk->fragments) |
2324+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
2325+ ERROR("unable to read fragment index table\n");
2326+ return 0;
2327+ }
2328+
2329+ if (msblk->swap) {
2330+ int i;
2331+ unsigned int fragment;
2332+
2333+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
2334+ i++) {
2335+ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
2336+ &msblk->fragment_index_2[i], 1);
2337+ msblk->fragment_index_2[i] = fragment;
2338+ }
2339+ }
2340+
2341+ return 1;
2342+}
2343+
2344+
2345+static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
2346+ long long *fragment_start_block,
2347+ unsigned int *fragment_size)
2348+{
2349+ struct squashfs_sb_info *msblk = s->s_fs_info;
2350+ long long start_block =
2351+ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
2352+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
2353+ struct squashfs_fragment_entry_2 fragment_entry;
2354+
2355+ if (msblk->swap) {
2356+ struct squashfs_fragment_entry_2 sfragment_entry;
2357+
2358+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
2359+ start_block, offset,
2360+ sizeof(sfragment_entry), &start_block,
2361+ &offset))
2362+ goto out;
2363+ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
2364+ } else
2365+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
2366+ start_block, offset,
2367+ sizeof(fragment_entry), &start_block,
2368+ &offset))
2369+ goto out;
2370+
2371+ *fragment_start_block = fragment_entry.start_block;
2372+ *fragment_size = fragment_entry.size;
2373+
2374+ return 1;
2375+
2376+out:
2377+ return 0;
2378+}
2379+
2380+
2381+static struct inode *squashfs_new_inode(struct super_block *s,
2382+ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
2383+{
2384+ struct squashfs_sb_info *msblk = s->s_fs_info;
2385+ struct squashfs_super_block *sblk = &msblk->sblk;
2386+ struct inode *i = new_inode(s);
2387+
2388+ if (i) {
2389+ i->i_ino = ino;
2390+ i->i_mtime.tv_sec = sblk->mkfs_time;
2391+ i->i_atime.tv_sec = sblk->mkfs_time;
2392+ i->i_ctime.tv_sec = sblk->mkfs_time;
2393+ i->i_uid = msblk->uid[inodeb->uid];
2394+ i->i_mode = inodeb->mode;
2395+ i->i_nlink = 1;
2396+ i->i_size = 0;
2397+ if (inodeb->guid == SQUASHFS_GUIDS)
2398+ i->i_gid = i->i_uid;
2399+ else
2400+ i->i_gid = msblk->guid[inodeb->guid];
2401+ }
2402+
2403+ return i;
2404+}
2405+
2406+
2407+static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t inode)
2408+{
2409+ struct inode *i;
2410+ struct squashfs_sb_info *msblk = s->s_fs_info;
2411+ struct squashfs_super_block *sblk = &msblk->sblk;
2412+ unsigned int block = SQUASHFS_INODE_BLK(inode) +
2413+ sblk->inode_table_start;
2414+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
2415+ unsigned int ino = SQUASHFS_MK_VFS_INODE(block
2416+ - sblk->inode_table_start, offset);
2417+ long long next_block;
2418+ unsigned int next_offset;
2419+ union squashfs_inode_header_2 id, sid;
2420+ struct squashfs_base_inode_header_2 *inodeb = &id.base,
2421+ *sinodeb = &sid.base;
2422+
2423+ TRACE("Entered squashfs_iget\n");
2424+
2425+ if (msblk->swap) {
2426+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
2427+ offset, sizeof(*sinodeb), &next_block,
2428+ &next_offset))
2429+ goto failed_read;
2430+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
2431+ sizeof(*sinodeb));
2432+ } else
2433+ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
2434+ offset, sizeof(*inodeb), &next_block,
2435+ &next_offset))
2436+ goto failed_read;
2437+
2438+ switch(inodeb->inode_type) {
2439+ case SQUASHFS_FILE_TYPE: {
2440+ struct squashfs_reg_inode_header_2 *inodep = &id.reg;
2441+ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
2442+ long long frag_blk;
2443+ unsigned int frag_size;
2444+
2445+ if (msblk->swap) {
2446+ if (!squashfs_get_cached_block(s, (char *)
2447+ sinodep, block, offset,
2448+ sizeof(*sinodep), &next_block,
2449+ &next_offset))
2450+ goto failed_read;
2451+ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
2452+ } else
2453+ if (!squashfs_get_cached_block(s, (char *)
2454+ inodep, block, offset,
2455+ sizeof(*inodep), &next_block,
2456+ &next_offset))
2457+ goto failed_read;
2458+
2459+ frag_blk = SQUASHFS_INVALID_BLK;
2460+ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
2461+ !get_fragment_location_2(s,
2462+ inodep->fragment, &frag_blk, &frag_size))
2463+ goto failed_read;
2464+
2465+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
2466+ goto failed_read1;
2467+
2468+ i->i_size = inodep->file_size;
2469+ i->i_fop = &generic_ro_fops;
2470+ i->i_mode |= S_IFREG;
2471+ i->i_mtime.tv_sec = inodep->mtime;
2472+ i->i_atime.tv_sec = inodep->mtime;
2473+ i->i_ctime.tv_sec = inodep->mtime;
2474+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
2475+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
2476+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
2477+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
2478+ SQUASHFS_I(i)->start_block = inodep->start_block;
2479+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
2480+ SQUASHFS_I(i)->offset = next_offset;
2481+ if (sblk->block_size > 4096)
2482+ i->i_data.a_ops = &squashfs_aops;
2483+ else
2484+ i->i_data.a_ops = &squashfs_aops_4K;
2485+
2486+ TRACE("File inode %x:%x, start_block %x, "
2487+ "block_list_start %llx, offset %x\n",
2488+ SQUASHFS_INODE_BLK(inode), offset,
2489+ inodep->start_block, next_block,
2490+ next_offset);
2491+ break;
2492+ }
2493+ case SQUASHFS_DIR_TYPE: {
2494+ struct squashfs_dir_inode_header_2 *inodep = &id.dir;
2495+ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
2496+
2497+ if (msblk->swap) {
2498+ if (!squashfs_get_cached_block(s, (char *)
2499+ sinodep, block, offset,
2500+ sizeof(*sinodep), &next_block,
2501+ &next_offset))
2502+ goto failed_read;
2503+ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
2504+ } else
2505+ if (!squashfs_get_cached_block(s, (char *)
2506+ inodep, block, offset,
2507+ sizeof(*inodep), &next_block,
2508+ &next_offset))
2509+ goto failed_read;
2510+
2511+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
2512+ goto failed_read1;
2513+
2514+ i->i_size = inodep->file_size;
2515+ i->i_op = &squashfs_dir_inode_ops_2;
2516+ i->i_fop = &squashfs_dir_ops_2;
2517+ i->i_mode |= S_IFDIR;
2518+ i->i_mtime.tv_sec = inodep->mtime;
2519+ i->i_atime.tv_sec = inodep->mtime;
2520+ i->i_ctime.tv_sec = inodep->mtime;
2521+ SQUASHFS_I(i)->start_block = inodep->start_block;
2522+ SQUASHFS_I(i)->offset = inodep->offset;
2523+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
2524+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
2525+
2526+ TRACE("Directory inode %x:%x, start_block %x, offset "
2527+ "%x\n", SQUASHFS_INODE_BLK(inode),
2528+ offset, inodep->start_block,
2529+ inodep->offset);
2530+ break;
2531+ }
2532+ case SQUASHFS_LDIR_TYPE: {
2533+ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
2534+ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
2535+
2536+ if (msblk->swap) {
2537+ if (!squashfs_get_cached_block(s, (char *)
2538+ sinodep, block, offset,
2539+ sizeof(*sinodep), &next_block,
2540+ &next_offset))
2541+ goto failed_read;
2542+ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
2543+ sinodep);
2544+ } else
2545+ if (!squashfs_get_cached_block(s, (char *)
2546+ inodep, block, offset,
2547+ sizeof(*inodep), &next_block,
2548+ &next_offset))
2549+ goto failed_read;
2550+
2551+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
2552+ goto failed_read1;
2553+
2554+ i->i_size = inodep->file_size;
2555+ i->i_op = &squashfs_dir_inode_ops_2;
2556+ i->i_fop = &squashfs_dir_ops_2;
2557+ i->i_mode |= S_IFDIR;
2558+ i->i_mtime.tv_sec = inodep->mtime;
2559+ i->i_atime.tv_sec = inodep->mtime;
2560+ i->i_ctime.tv_sec = inodep->mtime;
2561+ SQUASHFS_I(i)->start_block = inodep->start_block;
2562+ SQUASHFS_I(i)->offset = inodep->offset;
2563+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
2564+ SQUASHFS_I(i)->u.s2.directory_index_offset =
2565+ next_offset;
2566+ SQUASHFS_I(i)->u.s2.directory_index_count =
2567+ inodep->i_count;
2568+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
2569+
2570+ TRACE("Long directory inode %x:%x, start_block %x, "
2571+ "offset %x\n",
2572+ SQUASHFS_INODE_BLK(inode), offset,
2573+ inodep->start_block, inodep->offset);
2574+ break;
2575+ }
2576+ case SQUASHFS_SYMLINK_TYPE: {
2577+ struct squashfs_symlink_inode_header_2 *inodep =
2578+ &id.symlink;
2579+ struct squashfs_symlink_inode_header_2 *sinodep =
2580+ &sid.symlink;
2581+
2582+ if (msblk->swap) {
2583+ if (!squashfs_get_cached_block(s, (char *)
2584+ sinodep, block, offset,
2585+ sizeof(*sinodep), &next_block,
2586+ &next_offset))
2587+ goto failed_read;
2588+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
2589+ sinodep);
2590+ } else
2591+ if (!squashfs_get_cached_block(s, (char *)
2592+ inodep, block, offset,
2593+ sizeof(*inodep), &next_block,
2594+ &next_offset))
2595+ goto failed_read;
2596+
2597+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
2598+ goto failed_read1;
2599+
2600+ i->i_size = inodep->symlink_size;
2601+ i->i_op = &page_symlink_inode_operations;
2602+ i->i_data.a_ops = &squashfs_symlink_aops;
2603+ i->i_mode |= S_IFLNK;
2604+ SQUASHFS_I(i)->start_block = next_block;
2605+ SQUASHFS_I(i)->offset = next_offset;
2606+
2607+ TRACE("Symbolic link inode %x:%x, start_block %llx, "
2608+ "offset %x\n",
2609+ SQUASHFS_INODE_BLK(inode), offset,
2610+ next_block, next_offset);
2611+ break;
2612+ }
2613+ case SQUASHFS_BLKDEV_TYPE:
2614+ case SQUASHFS_CHRDEV_TYPE: {
2615+ struct squashfs_dev_inode_header_2 *inodep = &id.dev;
2616+ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
2617+
2618+ if (msblk->swap) {
2619+ if (!squashfs_get_cached_block(s, (char *)
2620+ sinodep, block, offset,
2621+ sizeof(*sinodep), &next_block,
2622+ &next_offset))
2623+ goto failed_read;
2624+ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
2625+ } else
2626+ if (!squashfs_get_cached_block(s, (char *)
2627+ inodep, block, offset,
2628+ sizeof(*inodep), &next_block,
2629+ &next_offset))
2630+ goto failed_read;
2631+
2632+ if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
2633+ goto failed_read1;
2634+
2635+ i->i_mode |= (inodeb->inode_type ==
2636+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
2637+ S_IFBLK;
2638+ init_special_inode(i, i->i_mode,
2639+ old_decode_dev(inodep->rdev));
2640+
2641+ TRACE("Device inode %x:%x, rdev %x\n",
2642+ SQUASHFS_INODE_BLK(inode), offset,
2643+ inodep->rdev);
2644+ break;
2645+ }
2646+ case SQUASHFS_FIFO_TYPE:
2647+ case SQUASHFS_SOCKET_TYPE: {
2648+ if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
2649+ goto failed_read1;
2650+
2651+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
2652+ ? S_IFIFO : S_IFSOCK;
2653+ init_special_inode(i, i->i_mode, 0);
2654+ break;
2655+ }
2656+ default:
2657+ ERROR("Unknown inode type %d in squashfs_iget!\n",
2658+ inodeb->inode_type);
2659+ goto failed_read1;
2660+ }
2661+
2662+ insert_inode_hash(i);
2663+ return i;
2664+
2665+failed_read:
2666+ ERROR("Unable to read inode [%x:%x]\n", block, offset);
2667+
2668+failed_read1:
2669+ return NULL;
2670+}
2671+
2672+
2673+static int get_dir_index_using_offset(struct super_block *s, long long
2674+ *next_block, unsigned int *next_offset,
2675+ long long index_start,
2676+ unsigned int index_offset, int i_count,
2677+ long long f_pos)
2678+{
2679+ struct squashfs_sb_info *msblk = s->s_fs_info;
2680+ struct squashfs_super_block *sblk = &msblk->sblk;
2681+ int i, length = 0;
2682+ struct squashfs_dir_index_2 index;
2683+
2684+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
2685+ i_count, (unsigned int) f_pos);
2686+
2687+ if (f_pos == 0)
2688+ goto finish;
2689+
2690+ for (i = 0; i < i_count; i++) {
2691+ if (msblk->swap) {
2692+ struct squashfs_dir_index_2 sindex;
2693+ squashfs_get_cached_block(s, (char *) &sindex,
2694+ index_start, index_offset,
2695+ sizeof(sindex), &index_start,
2696+ &index_offset);
2697+ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
2698+ } else
2699+ squashfs_get_cached_block(s, (char *) &index,
2700+ index_start, index_offset,
2701+ sizeof(index), &index_start,
2702+ &index_offset);
2703+
2704+ if (index.index > f_pos)
2705+ break;
2706+
2707+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
2708+ index.size + 1, &index_start,
2709+ &index_offset);
2710+
2711+ length = index.index;
2712+ *next_block = index.start_block + sblk->directory_table_start;
2713+ }
2714+
2715+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
2716+
2717+finish:
2718+ return length;
2719+}
2720+
2721+
2722+static int get_dir_index_using_name(struct super_block *s, long long
2723+ *next_block, unsigned int *next_offset,
2724+ long long index_start,
2725+ unsigned int index_offset, int i_count,
2726+ const char *name, int size)
2727+{
2728+ struct squashfs_sb_info *msblk = s->s_fs_info;
2729+ struct squashfs_super_block *sblk = &msblk->sblk;
2730+ int i, length = 0;
2731+ char buffer[sizeof(struct squashfs_dir_index_2) + SQUASHFS_NAME_LEN + 1];
2732+ struct squashfs_dir_index_2 *index = (struct squashfs_dir_index_2 *) buffer;
2733+ char str[SQUASHFS_NAME_LEN + 1];
2734+
2735+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
2736+
2737+ strncpy(str, name, size);
2738+ str[size] = '\0';
2739+
2740+ for (i = 0; i < i_count; i++) {
2741+ if (msblk->swap) {
2742+ struct squashfs_dir_index_2 sindex;
2743+ squashfs_get_cached_block(s, (char *) &sindex,
2744+ index_start, index_offset,
2745+ sizeof(sindex), &index_start,
2746+ &index_offset);
2747+ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
2748+ } else
2749+ squashfs_get_cached_block(s, (char *) index,
2750+ index_start, index_offset,
2751+ sizeof(struct squashfs_dir_index_2),
2752+ &index_start, &index_offset);
2753+
2754+ squashfs_get_cached_block(s, index->name, index_start,
2755+ index_offset, index->size + 1,
2756+ &index_start, &index_offset);
2757+
2758+ index->name[index->size + 1] = '\0';
2759+
2760+ if (strcmp(index->name, str) > 0)
2761+ break;
2762+
2763+ length = index->index;
2764+ *next_block = index->start_block + sblk->directory_table_start;
2765+ }
2766+
2767+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
2768+ return length;
2769+}
2770+
2771+
2772+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
2773+{
2774+ struct inode *i = file->f_dentry->d_inode;
2775+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
2776+ struct squashfs_super_block *sblk = &msblk->sblk;
2777+ long long next_block = SQUASHFS_I(i)->start_block +
2778+ sblk->directory_table_start;
2779+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
2780+ dir_count;
2781+ struct squashfs_dir_header_2 dirh;
2782+ char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN + 1];
2783+ struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
2784+
2785+ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
2786+
2787+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
2788+ SQUASHFS_I(i)->u.s2.directory_index_start,
2789+ SQUASHFS_I(i)->u.s2.directory_index_offset,
2790+ SQUASHFS_I(i)->u.s2.directory_index_count,
2791+ file->f_pos);
2792+
2793+ while (length < i_size_read(i)) {
2794+ /* read directory header */
2795+ if (msblk->swap) {
2796+ struct squashfs_dir_header_2 sdirh;
2797+
2798+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
2799+ next_block, next_offset, sizeof(sdirh),
2800+ &next_block, &next_offset))
2801+ goto failed_read;
2802+
2803+ length += sizeof(sdirh);
2804+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
2805+ } else {
2806+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
2807+ next_block, next_offset, sizeof(dirh),
2808+ &next_block, &next_offset))
2809+ goto failed_read;
2810+
2811+ length += sizeof(dirh);
2812+ }
2813+
2814+ dir_count = dirh.count + 1;
2815+ while (dir_count--) {
2816+ if (msblk->swap) {
2817+ struct squashfs_dir_entry_2 sdire;
2818+ if (!squashfs_get_cached_block(i->i_sb, (char *)
2819+ &sdire, next_block, next_offset,
2820+ sizeof(sdire), &next_block,
2821+ &next_offset))
2822+ goto failed_read;
2823+
2824+ length += sizeof(sdire);
2825+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
2826+ } else {
2827+ if (!squashfs_get_cached_block(i->i_sb, (char *)
2828+ dire, next_block, next_offset,
2829+ sizeof(*dire), &next_block,
2830+ &next_offset))
2831+ goto failed_read;
2832+
2833+ length += sizeof(*dire);
2834+ }
2835+
2836+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
2837+ next_block, next_offset,
2838+ dire->size + 1, &next_block,
2839+ &next_offset))
2840+ goto failed_read;
2841+
2842+ length += dire->size + 1;
2843+
2844+ if (file->f_pos >= length)
2845+ continue;
2846+
2847+ dire->name[dire->size + 1] = '\0';
2848+
2849+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
2850+ (unsigned int) dirent, dire->name,
2851+ dire->size + 1, (int) file->f_pos,
2852+ dirh.start_block, dire->offset,
2853+ squashfs_filetype_table[dire->type]);
2854+
2855+ if (filldir(dirent, dire->name, dire->size + 1,
2856+ file->f_pos, SQUASHFS_MK_VFS_INODE(
2857+ dirh.start_block, dire->offset),
2858+ squashfs_filetype_table[dire->type])
2859+ < 0) {
2860+ TRACE("Filldir returned less than 0\n");
2861+ goto finish;
2862+ }
2863+ file->f_pos = length;
2864+ dirs_read++;
2865+ }
2866+ }
2867+
2868+finish:
2869+ return dirs_read;
2870+
2871+failed_read:
2872+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
2873+ next_offset);
2874+ return 0;
2875+}
2876+
2877+
2878+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
2879+ struct nameidata *nd)
2880+{
2881+ const unsigned char *name = dentry->d_name.name;
2882+ int len = dentry->d_name.len;
2883+ struct inode *inode = NULL;
2884+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
2885+ struct squashfs_super_block *sblk = &msblk->sblk;
2886+ long long next_block = SQUASHFS_I(i)->start_block +
2887+ sblk->directory_table_start;
2888+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
2889+ dir_count;
2890+ struct squashfs_dir_header_2 dirh;
2891+ char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN];
2892+ struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
2893+ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
2894+
2895+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
2896+
2897+ if (len > SQUASHFS_NAME_LEN)
2898+ goto exit_loop;
2899+
2900+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
2901+ SQUASHFS_I(i)->u.s2.directory_index_start,
2902+ SQUASHFS_I(i)->u.s2.directory_index_offset,
2903+ SQUASHFS_I(i)->u.s2.directory_index_count, name,
2904+ len);
2905+
2906+ while (length < i_size_read(i)) {
2907+ /* read directory header */
2908+ if (msblk->swap) {
2909+ struct squashfs_dir_header_2 sdirh;
2910+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
2911+ next_block, next_offset, sizeof(sdirh),
2912+ &next_block, &next_offset))
2913+ goto failed_read;
2914+
2915+ length += sizeof(sdirh);
2916+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
2917+ } else {
2918+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
2919+ next_block, next_offset, sizeof(dirh),
2920+ &next_block, &next_offset))
2921+ goto failed_read;
2922+
2923+ length += sizeof(dirh);
2924+ }
2925+
2926+ dir_count = dirh.count + 1;
2927+ while (dir_count--) {
2928+ if (msblk->swap) {
2929+ struct squashfs_dir_entry_2 sdire;
2930+ if (!squashfs_get_cached_block(i->i_sb, (char *)
2931+ &sdire, next_block,next_offset,
2932+ sizeof(sdire), &next_block,
2933+ &next_offset))
2934+ goto failed_read;
2935+
2936+ length += sizeof(sdire);
2937+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
2938+ } else {
2939+ if (!squashfs_get_cached_block(i->i_sb, (char *)
2940+ dire, next_block,next_offset,
2941+ sizeof(*dire), &next_block,
2942+ &next_offset))
2943+ goto failed_read;
2944+
2945+ length += sizeof(*dire);
2946+ }
2947+
2948+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
2949+ next_block, next_offset, dire->size + 1,
2950+ &next_block, &next_offset))
2951+ goto failed_read;
2952+
2953+ length += dire->size + 1;
2954+
2955+ if (sorted && name[0] < dire->name[0])
2956+ goto exit_loop;
2957+
2958+ if ((len == dire->size + 1) && !strncmp(name,
2959+ dire->name, len)) {
2960+ squashfs_inode_t ino =
2961+ SQUASHFS_MKINODE(dirh.start_block,
2962+ dire->offset);
2963+
2964+ TRACE("calling squashfs_iget for directory "
2965+ "entry %s, inode %x:%x, %lld\n", name,
2966+ dirh.start_block, dire->offset, ino);
2967+
2968+ inode = (msblk->iget)(i->i_sb, ino);
2969+
2970+ goto exit_loop;
2971+ }
2972+ }
2973+ }
2974+
2975+exit_loop:
2976+ d_add(dentry, inode);
2977+ return ERR_PTR(0);
2978+
2979+failed_read:
2980+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
2981+ next_offset);
2982+ goto exit_loop;
2983+}
2984+
2985+
2986+int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
2987+{
2988+ struct squashfs_super_block *sblk = &msblk->sblk;
2989+
2990+ msblk->iget = squashfs_iget_2;
2991+ msblk->read_fragment_index_table = read_fragment_index_table_2;
2992+
2993+ sblk->bytes_used = sblk->bytes_used_2;
2994+ sblk->uid_start = sblk->uid_start_2;
2995+ sblk->guid_start = sblk->guid_start_2;
2996+ sblk->inode_table_start = sblk->inode_table_start_2;
2997+ sblk->directory_table_start = sblk->directory_table_start_2;
2998+ sblk->fragment_table_start = sblk->fragment_table_start_2;
2999+
3000+ return 1;
3001+}
3002Index: linux-2.6.22/fs/squashfs/squashfs.h
3003===================================================================
3004--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3005+++ linux-2.6.22/fs/squashfs/squashfs.h 2007-08-28 21:56:34.000000000 +0100
3006@@ -0,0 +1,86 @@
3007+/*
3008+ * Squashfs - a compressed read only filesystem for Linux
3009+ *
3010+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
3011+ * Phillip Lougher <phillip@lougher.org.uk>
3012+ *
3013+ * This program is free software; you can redistribute it and/or
3014+ * modify it under the terms of the GNU General Public License
3015+ * as published by the Free Software Foundation; either version 2,
3016+ * or (at your option) any later version.
3017+ *
3018+ * This program is distributed in the hope that it will be useful,
3019+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3020+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3021+ * GNU General Public License for more details.
3022+ *
3023+ * You should have received a copy of the GNU General Public License
3024+ * along with this program; if not, write to the Free Software
3025+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3026+ *
3027+ * squashfs.h
3028+ */
3029+
3030+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3031+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3032+#endif
3033+
3034+#ifdef SQUASHFS_TRACE
3035+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
3036+#else
3037+#define TRACE(s, args...) {}
3038+#endif
3039+
3040+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args)
3041+
3042+#define SERROR(s, args...) do { \
3043+ if (!silent) \
3044+ printk(KERN_ERR "SQUASHFS error: "s, ## args);\
3045+ } while(0)
3046+
3047+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args)
3048+
3049+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
3050+{
3051+ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
3052+}
3053+
3054+#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
3055+#define SQSH_EXTERN
3056+extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
3057+ long long index, unsigned int length,
3058+ long long *next_index);
3059+extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
3060+ long long block, unsigned int offset,
3061+ int length, long long *next_block,
3062+ unsigned int *next_offset);
3063+extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
3064+ squashfs_fragment_cache *fragment);
3065+extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block
3066+ *s, long long start_block,
3067+ int length);
3068+extern struct address_space_operations squashfs_symlink_aops;
3069+extern struct address_space_operations squashfs_aops;
3070+extern struct address_space_operations squashfs_aops_4K;
3071+extern struct inode_operations squashfs_dir_inode_ops;
3072+#else
3073+#define SQSH_EXTERN static
3074+#endif
3075+
3076+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3077+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
3078+#else
3079+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
3080+{
3081+ return 0;
3082+}
3083+#endif
3084+
3085+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
3086+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
3087+#else
3088+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
3089+{
3090+ return 0;
3091+}
3092+#endif
3093Index: linux-2.6.22/include/linux/squashfs_fs.h
3094===================================================================
3095--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3096+++ linux-2.6.22/include/linux/squashfs_fs.h 2007-08-28 21:56:34.000000000 +0100
3097@@ -0,0 +1,911 @@
3098+#ifndef SQUASHFS_FS
3099+#define SQUASHFS_FS
3100+
3101+/*
3102+ * Squashfs
3103+ *
3104+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
3105+ * Phillip Lougher <phillip@lougher.org.uk>
3106+ *
3107+ * This program is free software; you can redistribute it and/or
3108+ * modify it under the terms of the GNU General Public License
3109+ * as published by the Free Software Foundation; either version 2,
3110+ * or (at your option) any later version.
3111+ *
3112+ * This program is distributed in the hope that it will be useful,
3113+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3114+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3115+ * GNU General Public License for more details.
3116+ *
3117+ * You should have received a copy of the GNU General Public License
3118+ * along with this program; if not, write to the Free Software
3119+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3120+ *
3121+ * squashfs_fs.h
3122+ */
3123+
3124+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
3125+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
3126+#endif
3127+
3128+#ifdef CONFIG_SQUASHFS_VMALLOC
3129+#define SQUASHFS_ALLOC(a) vmalloc(a)
3130+#define SQUASHFS_FREE(a) vfree(a)
3131+#else
3132+#define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL)
3133+#define SQUASHFS_FREE(a) kfree(a)
3134+#endif
3135+#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
3136+#define SQUASHFS_MAJOR 3
3137+#define SQUASHFS_MINOR 0
3138+#define SQUASHFS_MAGIC 0x73717368
3139+#define SQUASHFS_MAGIC_SWAP 0x68737173
3140+#define SQUASHFS_START 0
3141+
3142+/* size of metadata (inode and directory) blocks */
3143+#define SQUASHFS_METADATA_SIZE 8192
3144+#define SQUASHFS_METADATA_LOG 13
3145+
3146+/* default size of data blocks */
3147+#define SQUASHFS_FILE_SIZE 65536
3148+#define SQUASHFS_FILE_LOG 16
3149+
3150+#define SQUASHFS_FILE_MAX_SIZE 65536
3151+
3152+/* Max number of uids and gids */
3153+#define SQUASHFS_UIDS 256
3154+#define SQUASHFS_GUIDS 255
3155+
3156+/* Max length of filename (not 255) */
3157+#define SQUASHFS_NAME_LEN 256
3158+
3159+#define SQUASHFS_INVALID ((long long) 0xffffffffffff)
3160+#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
3161+#define SQUASHFS_INVALID_BLK ((long long) -1)
3162+#define SQUASHFS_USED_BLK ((long long) -2)
3163+
3164+/* Filesystem flags */
3165+#define SQUASHFS_NOI 0
3166+#define SQUASHFS_NOD 1
3167+#define SQUASHFS_CHECK 2
3168+#define SQUASHFS_NOF 3
3169+#define SQUASHFS_NO_FRAG 4
3170+#define SQUASHFS_ALWAYS_FRAG 5
3171+#define SQUASHFS_DUPLICATE 6
3172+
3173+#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
3174+
3175+#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
3176+ SQUASHFS_NOI)
3177+
3178+#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
3179+ SQUASHFS_NOD)
3180+
3181+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
3182+ SQUASHFS_NOF)
3183+
3184+#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
3185+ SQUASHFS_NO_FRAG)
3186+
3187+#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
3188+ SQUASHFS_ALWAYS_FRAG)
3189+
3190+#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
3191+ SQUASHFS_DUPLICATE)
3192+
3193+#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
3194+ SQUASHFS_CHECK)
3195+
3196+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
3197+ duplicate_checking) (noi | (nod << 1) | (check_data << 2) \
3198+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
3199+ (duplicate_checking << 6))
3200+
3201+/* Max number of types and file types */
3202+#define SQUASHFS_DIR_TYPE 1
3203+#define SQUASHFS_FILE_TYPE 2
3204+#define SQUASHFS_SYMLINK_TYPE 3
3205+#define SQUASHFS_BLKDEV_TYPE 4
3206+#define SQUASHFS_CHRDEV_TYPE 5
3207+#define SQUASHFS_FIFO_TYPE 6
3208+#define SQUASHFS_SOCKET_TYPE 7
3209+#define SQUASHFS_LDIR_TYPE 8
3210+#define SQUASHFS_LREG_TYPE 9
3211+
3212+/* 1.0 filesystem type definitions */
3213+#define SQUASHFS_TYPES 5
3214+#define SQUASHFS_IPC_TYPE 0
3215+
3216+/* Flag whether block is compressed or uncompressed, bit is set if block is
3217+ * uncompressed */
3218+#define SQUASHFS_COMPRESSED_BIT (1 << 15)
3219+
3220+#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
3221+ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
3222+
3223+#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
3224+
3225+#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
3226+
3227+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \
3228+ ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
3229+ ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
3230+
3231+#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
3232+
3233+/*
3234+ * Inode number ops. Inodes consist of a compressed block number, and an
3235+ * uncompressed offset within that block
3236+ */
3237+#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
3238+
3239+#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
3240+
3241+#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
3242+ << 16) + (B)))
3243+
3244+/* Compute 32 bit VFS inode number from squashfs inode number */
3245+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
3246+ ((b) >> 2) + 1))
3247+/* XXX */
3248+
3249+/* Translate between VFS mode and squashfs mode */
3250+#define SQUASHFS_MODE(a) ((a) & 0xfff)
3251+
3252+/* fragment and fragment table defines */
3253+#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry))
3254+
3255+#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
3256+ SQUASHFS_METADATA_SIZE)
3257+
3258+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
3259+ SQUASHFS_METADATA_SIZE)
3260+
3261+#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
3262+ SQUASHFS_METADATA_SIZE - 1) / \
3263+ SQUASHFS_METADATA_SIZE)
3264+
3265+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
3266+ sizeof(long long))
3267+
3268+/* cached data constants for filesystem */
3269+#define SQUASHFS_CACHED_BLKS 8
3270+
3271+#define SQUASHFS_MAX_FILE_SIZE_LOG 64
3272+
3273+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
3274+ (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
3275+
3276+#define SQUASHFS_MARKER_BYTE 0xff
3277+
3278+/* meta index cache */
3279+#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
3280+#define SQUASHFS_META_ENTRIES 31
3281+#define SQUASHFS_META_NUMBER 8
3282+#define SQUASHFS_SLOTS 4
3283+
3284+struct meta_entry {
3285+ long long data_block;
3286+ unsigned int index_block;
3287+ unsigned short offset;
3288+ unsigned short pad;
3289+};
3290+
3291+struct meta_index {
3292+ unsigned int inode_number;
3293+ unsigned int offset;
3294+ unsigned short entries;
3295+ unsigned short skip;
3296+ unsigned short locked;
3297+ unsigned short pad;
3298+ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
3299+};
3300+
3301+
3302+/*
3303+ * definitions for structures on disk
3304+ */
3305+
3306+typedef long long squashfs_block_t;
3307+typedef long long squashfs_inode_t;
3308+
3309+struct squashfs_super_block {
3310+ unsigned int s_magic;
3311+ unsigned int inodes;
3312+ unsigned int bytes_used_2;
3313+ unsigned int uid_start_2;
3314+ unsigned int guid_start_2;
3315+ unsigned int inode_table_start_2;
3316+ unsigned int directory_table_start_2;
3317+ unsigned int s_major:16;
3318+ unsigned int s_minor:16;
3319+ unsigned int block_size_1:16;
3320+ unsigned int block_log:16;
3321+ unsigned int flags:8;
3322+ unsigned int no_uids:8;
3323+ unsigned int no_guids:8;
3324+ unsigned int mkfs_time /* time of filesystem creation */;
3325+ squashfs_inode_t root_inode;
3326+ unsigned int block_size;
3327+ unsigned int fragments;
3328+ unsigned int fragment_table_start_2;
3329+ long long bytes_used;
3330+ long long uid_start;
3331+ long long guid_start;
3332+ long long inode_table_start;
3333+ long long directory_table_start;
3334+ long long fragment_table_start;
3335+ long long unused;
3336+} __attribute__ ((packed));
3337+
3338+struct squashfs_dir_index {
3339+ unsigned int index;
3340+ unsigned int start_block;
3341+ unsigned char size;
3342+ unsigned char name[0];
3343+} __attribute__ ((packed));
3344+
3345+#define SQUASHFS_BASE_INODE_HEADER \
3346+ unsigned int inode_type:4; \
3347+ unsigned int mode:12; \
3348+ unsigned int uid:8; \
3349+ unsigned int guid:8; \
3350+ unsigned int mtime; \
3351+ unsigned int inode_number;
3352+
3353+struct squashfs_base_inode_header {
3354+ SQUASHFS_BASE_INODE_HEADER;
3355+} __attribute__ ((packed));
3356+
3357+struct squashfs_ipc_inode_header {
3358+ SQUASHFS_BASE_INODE_HEADER;
3359+ unsigned int nlink;
3360+} __attribute__ ((packed));
3361+
3362+struct squashfs_dev_inode_header {
3363+ SQUASHFS_BASE_INODE_HEADER;
3364+ unsigned int nlink;
3365+ unsigned short rdev;
3366+} __attribute__ ((packed));
3367+
3368+struct squashfs_symlink_inode_header {
3369+ SQUASHFS_BASE_INODE_HEADER;
3370+ unsigned int nlink;
3371+ unsigned short symlink_size;
3372+ char symlink[0];
3373+} __attribute__ ((packed));
3374+
3375+struct squashfs_reg_inode_header {
3376+ SQUASHFS_BASE_INODE_HEADER;
3377+ squashfs_block_t start_block;
3378+ unsigned int fragment;
3379+ unsigned int offset;
3380+ unsigned int file_size;
3381+ unsigned short block_list[0];
3382+} __attribute__ ((packed));
3383+
3384+struct squashfs_lreg_inode_header {
3385+ SQUASHFS_BASE_INODE_HEADER;
3386+ unsigned int nlink;
3387+ squashfs_block_t start_block;
3388+ unsigned int fragment;
3389+ unsigned int offset;
3390+ long long file_size;
3391+ unsigned short block_list[0];
3392+} __attribute__ ((packed));
3393+
3394+struct squashfs_dir_inode_header {
3395+ SQUASHFS_BASE_INODE_HEADER;
3396+ unsigned int nlink;
3397+ unsigned int file_size:19;
3398+ unsigned int offset:13;
3399+ unsigned int start_block;
3400+ unsigned int parent_inode;
3401+} __attribute__ ((packed));
3402+
3403+struct squashfs_ldir_inode_header {
3404+ SQUASHFS_BASE_INODE_HEADER;
3405+ unsigned int nlink;
3406+ unsigned int file_size:27;
3407+ unsigned int offset:13;
3408+ unsigned int start_block;
3409+ unsigned int i_count:16;
3410+ unsigned int parent_inode;
3411+ struct squashfs_dir_index index[0];
3412+} __attribute__ ((packed));
3413+
3414+union squashfs_inode_header {
3415+ struct squashfs_base_inode_header base;
3416+ struct squashfs_dev_inode_header dev;
3417+ struct squashfs_symlink_inode_header symlink;
3418+ struct squashfs_reg_inode_header reg;
3419+ struct squashfs_lreg_inode_header lreg;
3420+ struct squashfs_dir_inode_header dir;
3421+ struct squashfs_ldir_inode_header ldir;
3422+ struct squashfs_ipc_inode_header ipc;
3423+};
3424+
3425+struct squashfs_dir_entry {
3426+ unsigned int offset:13;
3427+ unsigned int type:3;
3428+ unsigned int size:8;
3429+ int inode_number:16;
3430+ char name[0];
3431+} __attribute__ ((packed));
3432+
3433+struct squashfs_dir_header {
3434+ unsigned int count:8;
3435+ unsigned int start_block;
3436+ unsigned int inode_number;
3437+} __attribute__ ((packed));
3438+
3439+struct squashfs_fragment_entry {
3440+ long long start_block;
3441+ unsigned int size;
3442+ unsigned int unused;
3443+} __attribute__ ((packed));
3444+
3445+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
3446+extern int squashfs_uncompress_init(void);
3447+extern int squashfs_uncompress_exit(void);
3448+
3449+/*
3450+ * macros to convert each packed bitfield structure from little endian to big
3451+ * endian and vice versa. These are needed when creating or using a filesystem
3452+ * on a machine with different byte ordering to the target architecture.
3453+ *
3454+ */
3455+
3456+#define SQUASHFS_SWAP_START \
3457+ int bits;\
3458+ int b_pos;\
3459+ unsigned long long val;\
3460+ unsigned char *s;\
3461+ unsigned char *d;
3462+
3463+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
3464+ SQUASHFS_SWAP_START\
3465+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
3466+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
3467+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
3468+ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
3469+ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
3470+ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
3471+ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
3472+ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
3473+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
3474+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
3475+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
3476+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
3477+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\
3478+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
3479+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
3480+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
3481+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
3482+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
3483+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
3484+ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
3485+ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
3486+ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
3487+ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
3488+ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
3489+ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
3490+ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
3491+ SQUASHFS_SWAP((s)->unused, d, 888, 64);\
3492+}
3493+
3494+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
3495+ SQUASHFS_MEMSET(s, d, n);\
3496+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
3497+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
3498+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
3499+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
3500+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
3501+ SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
3502+
3503+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
3504+ SQUASHFS_SWAP_START\
3505+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
3506+}
3507+
3508+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
3509+ SQUASHFS_SWAP_START\
3510+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3511+ sizeof(struct squashfs_ipc_inode_header))\
3512+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
3513+}
3514+
3515+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
3516+ SQUASHFS_SWAP_START\
3517+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3518+ sizeof(struct squashfs_dev_inode_header)); \
3519+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
3520+ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
3521+}
3522+
3523+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
3524+ SQUASHFS_SWAP_START\
3525+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3526+ sizeof(struct squashfs_symlink_inode_header));\
3527+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
3528+ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
3529+}
3530+
3531+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
3532+ SQUASHFS_SWAP_START\
3533+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3534+ sizeof(struct squashfs_reg_inode_header));\
3535+ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
3536+ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
3537+ SQUASHFS_SWAP((s)->offset, d, 192, 32);\
3538+ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
3539+}
3540+
3541+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
3542+ SQUASHFS_SWAP_START\
3543+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3544+ sizeof(struct squashfs_lreg_inode_header));\
3545+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
3546+ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
3547+ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
3548+ SQUASHFS_SWAP((s)->offset, d, 224, 32);\
3549+ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
3550+}
3551+
3552+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
3553+ SQUASHFS_SWAP_START\
3554+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3555+ sizeof(struct squashfs_dir_inode_header));\
3556+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
3557+ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
3558+ SQUASHFS_SWAP((s)->offset, d, 147, 13);\
3559+ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
3560+ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
3561+}
3562+
3563+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
3564+ SQUASHFS_SWAP_START\
3565+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
3566+ sizeof(struct squashfs_ldir_inode_header));\
3567+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
3568+ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
3569+ SQUASHFS_SWAP((s)->offset, d, 155, 13);\
3570+ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
3571+ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
3572+ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
3573+}
3574+
3575+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
3576+ SQUASHFS_SWAP_START\
3577+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
3578+ SQUASHFS_SWAP((s)->index, d, 0, 32);\
3579+ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
3580+ SQUASHFS_SWAP((s)->size, d, 64, 8);\
3581+}
3582+
3583+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
3584+ SQUASHFS_SWAP_START\
3585+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
3586+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
3587+ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
3588+ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
3589+}
3590+
3591+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
3592+ SQUASHFS_SWAP_START\
3593+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
3594+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
3595+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
3596+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
3597+ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
3598+}
3599+
3600+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
3601+ SQUASHFS_SWAP_START\
3602+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
3603+ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
3604+ SQUASHFS_SWAP((s)->size, d, 64, 32);\
3605+}
3606+
3607+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
3608+ int entry;\
3609+ int bit_position;\
3610+ SQUASHFS_SWAP_START\
3611+ SQUASHFS_MEMSET(s, d, n * 2);\
3612+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
3613+ 16)\
3614+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
3615+}
3616+
3617+#define SQUASHFS_SWAP_INTS(s, d, n) {\
3618+ int entry;\
3619+ int bit_position;\
3620+ SQUASHFS_SWAP_START\
3621+ SQUASHFS_MEMSET(s, d, n * 4);\
3622+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
3623+ 32)\
3624+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
3625+}
3626+
3627+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
3628+ int entry;\
3629+ int bit_position;\
3630+ SQUASHFS_SWAP_START\
3631+ SQUASHFS_MEMSET(s, d, n * 8);\
3632+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
3633+ 64)\
3634+ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
3635+}
3636+
3637+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
3638+ int entry;\
3639+ int bit_position;\
3640+ SQUASHFS_SWAP_START\
3641+ SQUASHFS_MEMSET(s, d, n * bits / 8);\
3642+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
3643+ bits)\
3644+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
3645+}
3646+
3647+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
3648+
3649+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3650+
3651+struct squashfs_base_inode_header_1 {
3652+ unsigned int inode_type:4;
3653+ unsigned int mode:12; /* protection */
3654+ unsigned int uid:4; /* index into uid table */
3655+ unsigned int guid:4; /* index into guid table */
3656+} __attribute__ ((packed));
3657+
3658+struct squashfs_ipc_inode_header_1 {
3659+ unsigned int inode_type:4;
3660+ unsigned int mode:12; /* protection */
3661+ unsigned int uid:4; /* index into uid table */
3662+ unsigned int guid:4; /* index into guid table */
3663+ unsigned int type:4;
3664+ unsigned int offset:4;
3665+} __attribute__ ((packed));
3666+
3667+struct squashfs_dev_inode_header_1 {
3668+ unsigned int inode_type:4;
3669+ unsigned int mode:12; /* protection */
3670+ unsigned int uid:4; /* index into uid table */
3671+ unsigned int guid:4; /* index into guid table */
3672+ unsigned short rdev;
3673+} __attribute__ ((packed));
3674+
3675+struct squashfs_symlink_inode_header_1 {
3676+ unsigned int inode_type:4;
3677+ unsigned int mode:12; /* protection */
3678+ unsigned int uid:4; /* index into uid table */
3679+ unsigned int guid:4; /* index into guid table */
3680+ unsigned short symlink_size;
3681+ char symlink[0];
3682+} __attribute__ ((packed));
3683+
3684+struct squashfs_reg_inode_header_1 {
3685+ unsigned int inode_type:4;
3686+ unsigned int mode:12; /* protection */
3687+ unsigned int uid:4; /* index into uid table */
3688+ unsigned int guid:4; /* index into guid table */
3689+ unsigned int mtime;
3690+ unsigned int start_block;
3691+ unsigned int file_size:32;
3692+ unsigned short block_list[0];
3693+} __attribute__ ((packed));
3694+
3695+struct squashfs_dir_inode_header_1 {
3696+ unsigned int inode_type:4;
3697+ unsigned int mode:12; /* protection */
3698+ unsigned int uid:4; /* index into uid table */
3699+ unsigned int guid:4; /* index into guid table */
3700+ unsigned int file_size:19;
3701+ unsigned int offset:13;
3702+ unsigned int mtime;
3703+ unsigned int start_block:24;
3704+} __attribute__ ((packed));
3705+
3706+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
3707+ SQUASHFS_MEMSET(s, d, n);\
3708+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
3709+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
3710+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\
3711+ SQUASHFS_SWAP((s)->guid, d, 20, 4);
3712+
3713+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
3714+ SQUASHFS_SWAP_START\
3715+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
3716+}
3717+
3718+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
3719+ SQUASHFS_SWAP_START\
3720+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
3721+ sizeof(struct squashfs_ipc_inode_header_1));\
3722+ SQUASHFS_SWAP((s)->type, d, 24, 4);\
3723+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\
3724+}
3725+
3726+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
3727+ SQUASHFS_SWAP_START\
3728+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
3729+ sizeof(struct squashfs_dev_inode_header_1));\
3730+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
3731+}
3732+
3733+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
3734+ SQUASHFS_SWAP_START\
3735+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
3736+ sizeof(struct squashfs_symlink_inode_header_1));\
3737+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
3738+}
3739+
3740+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
3741+ SQUASHFS_SWAP_START\
3742+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
3743+ sizeof(struct squashfs_reg_inode_header_1));\
3744+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
3745+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
3746+ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
3747+}
3748+
3749+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
3750+ SQUASHFS_SWAP_START\
3751+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
3752+ sizeof(struct squashfs_dir_inode_header_1));\
3753+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
3754+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\
3755+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
3756+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
3757+}
3758+
3759+#endif
3760+
3761+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
3762+
3763+struct squashfs_dir_index_2 {
3764+ unsigned int index:27;
3765+ unsigned int start_block:29;
3766+ unsigned char size;
3767+ unsigned char name[0];
3768+} __attribute__ ((packed));
3769+
3770+struct squashfs_base_inode_header_2 {
3771+ unsigned int inode_type:4;
3772+ unsigned int mode:12; /* protection */
3773+ unsigned int uid:8; /* index into uid table */
3774+ unsigned int guid:8; /* index into guid table */
3775+} __attribute__ ((packed));
3776+
3777+struct squashfs_ipc_inode_header_2 {
3778+ unsigned int inode_type:4;
3779+ unsigned int mode:12; /* protection */
3780+ unsigned int uid:8; /* index into uid table */
3781+ unsigned int guid:8; /* index into guid table */
3782+} __attribute__ ((packed));
3783+
3784+struct squashfs_dev_inode_header_2 {
3785+ unsigned int inode_type:4;
3786+ unsigned int mode:12; /* protection */
3787+ unsigned int uid:8; /* index into uid table */
3788+ unsigned int guid:8; /* index into guid table */
3789+ unsigned short rdev;
3790+} __attribute__ ((packed));
3791+
3792+struct squashfs_symlink_inode_header_2 {
3793+ unsigned int inode_type:4;
3794+ unsigned int mode:12; /* protection */
3795+ unsigned int uid:8; /* index into uid table */
3796+ unsigned int guid:8; /* index into guid table */
3797+ unsigned short symlink_size;
3798+ char symlink[0];
3799+} __attribute__ ((packed));
3800+
3801+struct squashfs_reg_inode_header_2 {
3802+ unsigned int inode_type:4;
3803+ unsigned int mode:12; /* protection */
3804+ unsigned int uid:8; /* index into uid table */
3805+ unsigned int guid:8; /* index into guid table */
3806+ unsigned int mtime;
3807+ unsigned int start_block;
3808+ unsigned int fragment;
3809+ unsigned int offset;
3810+ unsigned int file_size:32;
3811+ unsigned short block_list[0];
3812+} __attribute__ ((packed));
3813+
3814+struct squashfs_dir_inode_header_2 {
3815+ unsigned int inode_type:4;
3816+ unsigned int mode:12; /* protection */
3817+ unsigned int uid:8; /* index into uid table */
3818+ unsigned int guid:8; /* index into guid table */
3819+ unsigned int file_size:19;
3820+ unsigned int offset:13;
3821+ unsigned int mtime;
3822+ unsigned int start_block:24;
3823+} __attribute__ ((packed));
3824+
3825+struct squashfs_ldir_inode_header_2 {
3826+ unsigned int inode_type:4;
3827+ unsigned int mode:12; /* protection */
3828+ unsigned int uid:8; /* index into uid table */
3829+ unsigned int guid:8; /* index into guid table */
3830+ unsigned int file_size:27;
3831+ unsigned int offset:13;
3832+ unsigned int mtime;
3833+ unsigned int start_block:24;
3834+ unsigned int i_count:16;
3835+ struct squashfs_dir_index_2 index[0];
3836+} __attribute__ ((packed));
3837+
3838+union squashfs_inode_header_2 {
3839+ struct squashfs_base_inode_header_2 base;
3840+ struct squashfs_dev_inode_header_2 dev;
3841+ struct squashfs_symlink_inode_header_2 symlink;
3842+ struct squashfs_reg_inode_header_2 reg;
3843+ struct squashfs_dir_inode_header_2 dir;
3844+ struct squashfs_ldir_inode_header_2 ldir;
3845+ struct squashfs_ipc_inode_header_2 ipc;
3846+};
3847+
3848+struct squashfs_dir_header_2 {
3849+ unsigned int count:8;
3850+ unsigned int start_block:24;
3851+} __attribute__ ((packed));
3852+
3853+struct squashfs_dir_entry_2 {
3854+ unsigned int offset:13;
3855+ unsigned int type:3;
3856+ unsigned int size:8;
3857+ char name[0];
3858+} __attribute__ ((packed));
3859+
3860+struct squashfs_fragment_entry_2 {
3861+ unsigned int start_block;
3862+ unsigned int size;
3863+} __attribute__ ((packed));
3864+
3865+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
3866+ SQUASHFS_MEMSET(s, d, n);\
3867+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
3868+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
3869+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
3870+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
3871+
3872+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
3873+ SQUASHFS_SWAP_START\
3874+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
3875+}
3876+
3877+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
3878+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
3879+
3880+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
3881+ SQUASHFS_SWAP_START\
3882+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
3883+ sizeof(struct squashfs_dev_inode_header_2)); \
3884+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
3885+}
3886+
3887+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
3888+ SQUASHFS_SWAP_START\
3889+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
3890+ sizeof(struct squashfs_symlink_inode_header_2));\
3891+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
3892+}
3893+
3894+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
3895+ SQUASHFS_SWAP_START\
3896+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
3897+ sizeof(struct squashfs_reg_inode_header_2));\
3898+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
3899+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
3900+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
3901+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\
3902+ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
3903+}
3904+
3905+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
3906+ SQUASHFS_SWAP_START\
3907+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
3908+ sizeof(struct squashfs_dir_inode_header_2));\
3909+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
3910+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\
3911+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
3912+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
3913+}
3914+
3915+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
3916+ SQUASHFS_SWAP_START\
3917+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
3918+ sizeof(struct squashfs_ldir_inode_header_2));\
3919+ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
3920+ SQUASHFS_SWAP((s)->offset, d, 59, 13);\
3921+ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
3922+ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
3923+ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
3924+}
3925+
3926+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
3927+ SQUASHFS_SWAP_START\
3928+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
3929+ SQUASHFS_SWAP((s)->index, d, 0, 27);\
3930+ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
3931+ SQUASHFS_SWAP((s)->size, d, 56, 8);\
3932+}
3933+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
3934+ SQUASHFS_SWAP_START\
3935+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
3936+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
3937+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
3938+}
3939+
3940+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
3941+ SQUASHFS_SWAP_START\
3942+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
3943+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
3944+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
3945+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
3946+}
3947+
3948+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
3949+ SQUASHFS_SWAP_START\
3950+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
3951+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
3952+ SQUASHFS_SWAP((s)->size, d, 32, 32);\
3953+}
3954+
3955+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
3956+
3957+/* fragment and fragment table defines */
3958+#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
3959+
3960+#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
3961+ SQUASHFS_METADATA_SIZE)
3962+
3963+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
3964+ SQUASHFS_METADATA_SIZE)
3965+
3966+#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
3967+ SQUASHFS_METADATA_SIZE - 1) / \
3968+ SQUASHFS_METADATA_SIZE)
3969+
3970+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
3971+ sizeof(int))
3972+
3973+#endif
3974+
3975+#ifdef __KERNEL__
3976+
3977+/*
3978+ * macros used to swap each structure entry, taking into account
3979+ * bitfields and different bitfield placing conventions on differing
3980+ * architectures
3981+ */
3982+
3983+#include <asm/byteorder.h>
3984+
3985+#ifdef __BIG_ENDIAN
3986+ /* convert from little endian to big endian */
3987+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
3988+ tbits, b_pos)
3989+#else
3990+ /* convert from big endian to little endian */
3991+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
3992+ tbits, 64 - tbits - b_pos)
3993+#endif
3994+
3995+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
3996+ b_pos = pos % 8;\
3997+ val = 0;\
3998+ s = (unsigned char *)p + (pos / 8);\
3999+ d = ((unsigned char *) &val) + 7;\
4000+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \
4001+ *d-- = *s++;\
4002+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
4003+}
4004+
4005+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
4006+
4007+#endif
4008+#endif
4009Index: linux-2.6.22/include/linux/squashfs_fs_i.h
4010===================================================================
4011--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4012+++ linux-2.6.22/include/linux/squashfs_fs_i.h 2007-08-28 21:56:34.000000000 +0100
4013@@ -0,0 +1,45 @@
4014+#ifndef SQUASHFS_FS_I
4015+#define SQUASHFS_FS_I
4016+/*
4017+ * Squashfs
4018+ *
4019+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
4020+ * Phillip Lougher <phillip@lougher.org.uk>
4021+ *
4022+ * This program is free software; you can redistribute it and/or
4023+ * modify it under the terms of the GNU General Public License
4024+ * as published by the Free Software Foundation; either version 2,
4025+ * or (at your option) any later version.
4026+ *
4027+ * This program is distributed in the hope that it will be useful,
4028+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4029+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4030+ * GNU General Public License for more details.
4031+ *
4032+ * You should have received a copy of the GNU General Public License
4033+ * along with this program; if not, write to the Free Software
4034+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4035+ *
4036+ * squashfs_fs_i.h
4037+ */
4038+
4039+struct squashfs_inode_info {
4040+ long long start_block;
4041+ unsigned int offset;
4042+ union {
4043+ struct {
4044+ long long fragment_start_block;
4045+ unsigned int fragment_size;
4046+ unsigned int fragment_offset;
4047+ long long block_list_start;
4048+ } s1;
4049+ struct {
4050+ long long directory_index_start;
4051+ unsigned int directory_index_offset;
4052+ unsigned int directory_index_count;
4053+ unsigned int parent_inode;
4054+ } s2;
4055+ } u;
4056+ struct inode vfs_inode;
4057+};
4058+#endif
4059Index: linux-2.6.22/include/linux/squashfs_fs_sb.h
4060===================================================================
4061--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4062+++ linux-2.6.22/include/linux/squashfs_fs_sb.h 2007-08-28 21:56:34.000000000 +0100
4063@@ -0,0 +1,74 @@
4064+#ifndef SQUASHFS_FS_SB
4065+#define SQUASHFS_FS_SB
4066+/*
4067+ * Squashfs
4068+ *
4069+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
4070+ * Phillip Lougher <phillip@lougher.org.uk>
4071+ *
4072+ * This program is free software; you can redistribute it and/or
4073+ * modify it under the terms of the GNU General Public License
4074+ * as published by the Free Software Foundation; either version 2,
4075+ * or (at your option) any later version.
4076+ *
4077+ * This program is distributed in the hope that it will be useful,
4078+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4079+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4080+ * GNU General Public License for more details.
4081+ *
4082+ * You should have received a copy of the GNU General Public License
4083+ * along with this program; if not, write to the Free Software
4084+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4085+ *
4086+ * squashfs_fs_sb.h
4087+ */
4088+
4089+#include <linux/squashfs_fs.h>
4090+
4091+struct squashfs_cache {
4092+ long long block;
4093+ int length;
4094+ long long next_index;
4095+ char *data;
4096+};
4097+
4098+struct squashfs_fragment_cache {
4099+ long long block;
4100+ int length;
4101+ unsigned int locked;
4102+ char *data;
4103+};
4104+
4105+struct squashfs_sb_info {
4106+ struct squashfs_super_block sblk;
4107+ int devblksize;
4108+ int devblksize_log2;
4109+ int swap;
4110+ struct squashfs_cache *block_cache;
4111+ struct squashfs_fragment_cache *fragment;
4112+ int next_cache;
4113+ int next_fragment;
4114+ int next_meta_index;
4115+ unsigned int *uid;
4116+ unsigned int *guid;
4117+ long long *fragment_index;
4118+ unsigned int *fragment_index_2;
4119+ unsigned int read_size;
4120+ char *read_data;
4121+ char *read_page;
4122+ struct semaphore read_data_mutex;
4123+ struct semaphore read_page_mutex;
4124+ struct semaphore block_cache_mutex;
4125+ struct semaphore fragment_mutex;
4126+ struct semaphore meta_index_mutex;
4127+ wait_queue_head_t waitq;
4128+ wait_queue_head_t fragment_wait_queue;
4129+ struct meta_index *meta_index;
4130+ struct inode *(*iget)(struct super_block *s, squashfs_inode_t \
4131+ inode);
4132+ long long (*read_blocklist)(struct inode *inode, int \
4133+ index, int readahead_blks, char *block_list, \
4134+ unsigned short **block_p, unsigned int *bsize);
4135+ int (*read_fragment_index_table)(struct super_block *s);
4136+};
4137+#endif
4138Index: linux-2.6.22/init/do_mounts_rd.c
4139===================================================================
4140--- linux-2.6.22.orig/init/do_mounts_rd.c 2007-08-28 21:54:14.000000000 +0100
4141+++ linux-2.6.22/init/do_mounts_rd.c 2007-08-28 21:56:34.000000000 +0100
4142@@ -5,6 +5,7 @@
4143 #include <linux/ext2_fs.h>
4144 #include <linux/romfs_fs.h>
4145 #include <linux/cramfs_fs.h>
4146+#include <linux/squashfs_fs.h>
4147 #include <linux/initrd.h>
4148 #include <linux/string.h>
4149
4150@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
4151 * numbers could not be found.
4152 *
4153 * We currently check for the following magic numbers:
4154+ * squashfs
4155 * minix
4156 * ext2
4157 * romfs
4158@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
4159 struct ext2_super_block *ext2sb;
4160 struct romfs_super_block *romfsb;
4161 struct cramfs_super *cramfsb;
4162+ struct squashfs_super_block *squashfsb;
4163 int nblocks = -1;
4164 unsigned char *buf;
4165
4166@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
4167 ext2sb = (struct ext2_super_block *) buf;
4168 romfsb = (struct romfs_super_block *) buf;
4169 cramfsb = (struct cramfs_super *) buf;
4170+ squashfsb = (struct squashfs_super_block *) buf;
4171 memset(buf, 0xe5, size);
4172
4173 /*
4174@@ -101,6 +105,15 @@ identify_ramdisk_image(int fd, int start
4175 goto done;
4176 }
4177
4178+ /* squashfs is at block zero too */
4179+ if (squashfsb->s_magic == SQUASHFS_MAGIC) {
4180+ printk(KERN_NOTICE
4181+ "RAMDISK: squashfs filesystem found at block %d\n",
4182+ start_block);
4183+ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
4184+ goto done;
4185+ }
4186+
4187 /*
4188 * Read block 1 to test for minix and ext2 superblock
4189 */
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch
new file mode 100644
index 0000000000..711375114f
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch
@@ -0,0 +1,2590 @@
1---
2 Documentation/fb/uvesafb.txt | 188 +++
3 drivers/video/Kconfig | 18
4 drivers/video/Makefile | 1
5 drivers/video/modedb.c | 28
6 drivers/video/uvesafb.c | 2058 +++++++++++++++++++++++++++++++++++++++++++
7 include/linux/connector.h | 7
8 include/video/Kbuild | 2
9 include/video/uvesafb.h | 193 ++++
10 8 files changed, 2479 insertions(+), 16 deletions(-)
11
12Index: linux-2.6.22/Documentation/fb/uvesafb.txt
13===================================================================
14--- /dev/null 1970-01-01 00:00:00.000000000 +0000
15+++ linux-2.6.22/Documentation/fb/uvesafb.txt 2007-08-28 21:56:34.000000000 +0100
16@@ -0,0 +1,188 @@
17+
18+uvesafb - A Generic Driver for VBE2+ compliant video cards
19+==========================================================
20+
21+1. Requirements
22+---------------
23+
24+uvesafb should work with any video card that has a Video BIOS compliant
25+with the VBE 2.0 standard.
26+
27+Unlike other drivers, uvesafb makes use of a userspace helper called
28+v86d. v86d is used to run the x86 Video BIOS code in a simulated and
29+controlled environment. This allows uvesafb to function on arches other
30+than x86. Check the v86d documentation for a list of currently supported
31+arches.
32+
33+v86d source code can be downloaded from the following website:
34+ http://dev.gentoo.org/~spock/projects/uvesafb
35+
36+Please refer to the v86d documentation for detailed configuration and
37+installation instructions.
38+
39+Note that the v86d userspace helper has to be available at all times in
40+order for uvesafb to work properly. If you want to use uvesafb during
41+early boot, you will have to include v86d into an initramfs image, and
42+either compile it into the kernel or use it as an initrd.
43+
44+2. Caveats and limitations
45+--------------------------
46+
47+uvesafb is a _generic_ driver which supports a wide variety of video
48+cards, but which is ultimately limited by the Video BIOS interface.
49+The most important limitations are:
50+
51+- Lack of any type of acceleration.
52+- A strict and limited set of supported video modes. Often the native
53+ or most optimal resolution/refresh rate for your setup will not work
54+ with uvesafb, simply because the Video BIOS doesn't support the
55+ video mode you want to use. This can be especially painful with
56+ widescreen panels, where native video modes don't have the 4:3 aspect
57+ ratio, which is what most BIOS-es are limited to.
58+- Adjusting the refresh rate is only possible with a VBE 3.0 compliant
59+ Video BIOS. Note that many nVidia Video BIOS-es claim to be VBE 3.0
60+ compliant, while they simply ignore any refresh rate settings.
61+
62+3. Configuration
63+----------------
64+
65+uvesafb can be compiled either as a module, or directly into the kernel.
66+In both cases it supports the same set of configuration options, which
67+are either given on the kernel command line or as module parameters, e.g.:
68+
69+ video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
70+
71+ # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap (module)
72+
73+Accepted options:
74+
75+ypan Enable display panning using the VESA protected mode
76+ interface. The visible screen is just a window of the
77+ video memory, console scrolling is done by changing the
78+ start of the window. Available on x86 only.
79+
80+ywrap Same as ypan, but assumes your gfx board can wrap-around
81+ the video memory (i.e. starts reading from top if it
82+ reaches the end of video memory). Faster than ypan.
83+ Available on x86 only.
84+
85+redraw Scroll by redrawing the affected part of the screen, this
86+ is the safe (and slow) default.
87+
88+(If you're using uvesafb as a module, the above three options are
89+ used a parameter of the scroll option, e.g. scroll=ypan.)
90+
91+vgapal Use the standard VGA registers for palette changes.
92+
93+pmipal Use the protected mode interface for palette changes.
94+ This is the default if the protected mode interface is
95+ available. Available on x86 only.
96+
97+mtrr:n Setup memory type range registers for the framebuffer
98+ where n:
99+ 0 - disabled (equivalent to nomtrr) (default)
100+ 1 - uncachable
101+ 2 - write-back
102+ 3 - write-combining
103+ 4 - write-through
104+
105+ If you see the following in dmesg, choose the type that matches
106+ the old one. In this example, use "mtrr:2".
107+...
108+mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
109+...
110+
111+nomtrr Do not use memory type range registers.
112+
113+vremap:n
114+ Remap 'n' MiB of video RAM. If 0 or not specified, remap memory
115+ according to video mode.
116+
117+vtotal:n
118+ If the video BIOS of your card incorrectly determines the total
119+ amount of video RAM, use this option to override the BIOS (in MiB).
120+
121+<mode> The mode you want to set, in the standard modedb format. Refer to
122+ modedb.txt for a detailed description. When uvesafb is compiled as
123+ a module, the mode string should be provided as a value of the
124+ 'mode' option.
125+
126+vbemode:x
127+ Force the use of VBE mode x. The mode will only be set if it's
128+ found in the VBE-provided list of supported modes.
129+ NOTE: The mode number 'x' should be specified in VESA mode number
130+ notation, not the Linux kernel one (eg. 257 instead of 769).
131+ HINT: If you use this option because normal <mode> parameter does
132+ not work for you and you use a X server, you'll probably want to
133+ set the 'nocrtc' option to ensure that the video mode is properly
134+ restored after console <-> X switches.
135+
136+nocrtc Do not use CRTC timings while setting the video mode. This option
137+ has any effect only if the Video BIOS is VBE 3.0 compliant. Use it
138+ if you have problems with modes set the standard way. Note that
139+ using this option implies that any refresh rate adjustments will
140+ be ignored and the refresh rate will stay at your BIOS default (60 Hz).
141+
142+noedid Do not try to fetch and use EDID-provided modes.
143+
144+noblank Disable hardware blanking.
145+
146+v86d:path
147+ Set path to the v86d executable. This option is only available as
148+ a module parameter, and not as a part of the video= string. If you
149+ need to use it and have uvesafb built into the kernel, use
150+ uvesafb.v86d="path".
151+
152+Additionally, the following parameters may be provided. They all override the
153+EDID-provided values and BIOS defaults. Refer to your monitor's specs to get
154+the correct values for maxhf, maxvf and maxclk for your hardware.
155+
156+maxhf:n Maximum horizontal frequency (in kHz).
157+maxvf:n Maximum vertical frequency (in Hz).
158+maxclk:n Maximum pixel clock (in MHz).
159+
160+4. The sysfs interface
161+----------------------
162+
163+uvesafb provides several sysfs nodes for configurable parameters and
164+additional information.
165+
166+Driver attributes:
167+
168+/sys/bus/platform/drivers/uvesafb
169+ - v86d (default: /sbin/v86d)
170+ Path to the v86d executable. v86d is started by uvesafb
171+ if an instance of the daemon isn't already running.
172+
173+Device attributes:
174+
175+/sys/bus/platform/drivers/uvesafb/uvesafb.0
176+ - nocrtc
177+ Use the default refresh rate (60 Hz) if set to 1.
178+
179+ - oem_product_name
180+ - oem_product_rev
181+ - oem_string
182+ - oem_vendor
183+ Information about the card and its maker.
184+
185+ - vbe_modes
186+ A list of video modes supported by the Video BIOS along with their
187+ VBE mode numbers in hex.
188+
189+ - vbe_version
190+ A BCD value indicating the implemented VBE standard.
191+
192+5. Miscellaneous
193+----------------
194+
195+Uvesafb will set a video mode with the default refresh rate and timings
196+from the Video BIOS if you set pixclock to 0 in fb_var_screeninfo.
197+
198+
199+--
200+ Michal Januszewski <spock@gentoo.org>
201+ Last updated: 2007-06-16
202+
203+ Documentation of the uvesafb options is loosely based on vesafb.txt.
204+
205Index: linux-2.6.22/drivers/video/Kconfig
206===================================================================
207--- linux-2.6.22.orig/drivers/video/Kconfig 2007-08-28 21:56:33.000000000 +0100
208+++ linux-2.6.22/drivers/video/Kconfig 2007-08-28 21:56:34.000000000 +0100
209@@ -592,6 +592,24 @@ config FB_TGA
210
211 Say Y if you have one of those.
212
213+config FB_UVESA
214+ tristate "Userspace VESA VGA graphics support"
215+ depends on FB && CONNECTOR
216+ select FB_CFB_FILLRECT
217+ select FB_CFB_COPYAREA
218+ select FB_CFB_IMAGEBLIT
219+ select FB_MODE_HELPERS
220+ help
221+ This is the frame buffer driver for generic VBE 2.0 compliant
222+ graphic cards. It can also take advantage of VBE 3.0 features,
223+ such as refresh rate adjustment.
224+
225+ This driver generally provides more features than vesafb but
226+ requires a userspace helper application called 'v86d'. See
227+ <file:Documentation/fb/uvesafb.txt> for more information.
228+
229+ If unsure, say N.
230+
231 config FB_VESA
232 bool "VESA VGA graphics support"
233 depends on (FB = y) && X86
234Index: linux-2.6.22/drivers/video/Makefile
235===================================================================
236--- linux-2.6.22.orig/drivers/video/Makefile 2007-08-28 21:56:33.000000000 +0100
237+++ linux-2.6.22/drivers/video/Makefile 2007-08-28 21:56:34.000000000 +0100
238@@ -116,6 +116,7 @@ obj-$(CONFIG_FB_XILINX) += xil
239 obj-$(CONFIG_FB_OMAP) += omap/
240
241 # Platform or fallback drivers go here
242+obj-$(CONFIG_FB_UVESA) += uvesafb.o
243 obj-$(CONFIG_FB_VESA) += vesafb.o
244 obj-$(CONFIG_FB_IMAC) += imacfb.o
245 obj-$(CONFIG_FB_VGA16) += vga16fb.o
246Index: linux-2.6.22/drivers/video/modedb.c
247===================================================================
248--- linux-2.6.22.orig/drivers/video/modedb.c 2007-08-28 21:54:13.000000000 +0100
249+++ linux-2.6.22/drivers/video/modedb.c 2007-08-28 21:56:34.000000000 +0100
250@@ -606,26 +606,29 @@ done:
251 DPRINTK("Trying specified video mode%s %ix%i\n",
252 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
253
254- diff = refresh;
255+ if (!refresh_specified)
256+ diff = 0;
257+ else
258+ diff = refresh;
259+
260 best = -1;
261 for (i = 0; i < dbsize; i++) {
262- if (name_matches(db[i], name, namelen) ||
263- (res_specified && res_matches(db[i], xres, yres))) {
264- if(!fb_try_mode(var, info, &db[i], bpp)) {
265- if(!refresh_specified || db[i].refresh == refresh)
266- return 1;
267- else {
268- if(diff > abs(db[i].refresh - refresh)) {
269- diff = abs(db[i].refresh - refresh);
270- best = i;
271- }
272+ if ((name_matches(db[i], name, namelen) ||
273+ (res_specified && res_matches(db[i], xres, yres))) &&
274+ !fb_try_mode(var, info, &db[i], bpp)) {
275+ if (refresh_specified && db[i].refresh == refresh) {
276+ return 1;
277+ } else {
278+ if (diff < db[i].refresh) {
279+ diff = db[i].refresh;
280+ best = i;
281 }
282 }
283 }
284 }
285 if (best != -1) {
286 fb_try_mode(var, info, &db[best], bpp);
287- return 2;
288+ return (refresh_specified) ? 2 : 1;
289 }
290
291 diff = xres + yres;
292@@ -938,6 +941,7 @@ void fb_destroy_modelist(struct list_hea
293 kfree(pos);
294 }
295 }
296+EXPORT_SYMBOL_GPL(fb_destroy_modelist);
297
298 /**
299 * fb_videomode_to_modelist: convert mode array to mode list
300Index: linux-2.6.22/drivers/video/uvesafb.c
301===================================================================
302--- /dev/null 1970-01-01 00:00:00.000000000 +0000
303+++ linux-2.6.22/drivers/video/uvesafb.c 2007-08-28 21:56:34.000000000 +0100
304@@ -0,0 +1,2058 @@
305+/*
306+ * A framebuffer driver for VBE 2.0+ compliant video cards
307+ *
308+ * (c) 2007 Michal Januszewski <spock@gentoo.org>
309+ * Loosely based upon the vesafb driver.
310+ *
311+ */
312+#include <linux/init.h>
313+#include <linux/module.h>
314+#include <linux/moduleparam.h>
315+#include <linux/skbuff.h>
316+#include <linux/timer.h>
317+#include <linux/completion.h>
318+#include <linux/connector.h>
319+#include <linux/random.h>
320+#include <linux/platform_device.h>
321+#include <linux/limits.h>
322+#include <linux/fb.h>
323+#include <linux/io.h>
324+#include <linux/mutex.h>
325+#include <video/edid.h>
326+#include <video/vga.h>
327+#include <video/uvesafb.h>
328+#ifdef CONFIG_MTRR
329+#include <asm/mtrr.h>
330+#endif
331+#include "edid.h"
332+
333+static struct cb_id uvesafb_cn_id = {
334+ .idx = CN_IDX_V86D,
335+ .val = CN_VAL_V86D_UVESAFB
336+};
337+static char v86d_path[PATH_MAX] = "/sbin/v86d";
338+static char v86d_started; /* has v86d been started by uvesafb? */
339+
340+static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
341+ .id = "VESA VGA",
342+ .type = FB_TYPE_PACKED_PIXELS,
343+ .accel = FB_ACCEL_NONE,
344+ .visual = FB_VISUAL_TRUECOLOR,
345+};
346+
347+static int mtrr __devinitdata = 3; /* enable mtrr by default */
348+static int blank __devinitdata = 1; /* enable blanking by default */
349+static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
350+static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
351+static int nocrtc __devinitdata; /* ignore CRTC settings */
352+static int noedid __devinitdata; /* don't try DDC transfers */
353+static int vram_remap __devinitdata; /* set amt. of memory to be used */
354+static int vram_total __devinitdata; /* set total amount of memory */
355+static u16 maxclk __devinitdata; /* maximum pixel clock */
356+static u16 maxvf __devinitdata; /* maximum vertical frequency */
357+static u16 maxhf __devinitdata; /* maximum horizontal frequency */
358+static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
359+static char *mode_option __devinitdata;
360+
361+static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
362+static DEFINE_MUTEX(uvfb_lock);
363+
364+/*
365+ * A handler for replies from userspace.
366+ *
367+ * Make sure each message passes consistency checks and if it does,
368+ * find the kernel part of the task struct, copy the registers and
369+ * the buffer contents and then complete the task.
370+ */
371+static void uvesafb_cn_callback(void *data)
372+{
373+ struct cn_msg *msg = data;
374+ struct uvesafb_task *utask;
375+ struct uvesafb_ktask *task;
376+
377+ if (msg->seq >= UVESAFB_TASKS_MAX)
378+ return;
379+
380+ mutex_lock(&uvfb_lock);
381+ task = uvfb_tasks[msg->seq];
382+
383+ if (!task || msg->ack != task->ack) {
384+ mutex_unlock(&uvfb_lock);
385+ return;
386+ }
387+
388+ utask = (struct uvesafb_task *)msg->data;
389+
390+ /* Sanity checks for the buffer length. */
391+ if (task->t.buf_len < utask->buf_len ||
392+ utask->buf_len > msg->len - sizeof(*utask)) {
393+ mutex_unlock(&uvfb_lock);
394+ return;
395+ }
396+
397+ uvfb_tasks[msg->seq] = NULL;
398+ mutex_unlock(&uvfb_lock);
399+
400+ memcpy(&task->t, utask, sizeof(*utask));
401+
402+ if (task->t.buf_len && task->buf)
403+ memcpy(task->buf, utask + 1, task->t.buf_len);
404+
405+ complete(task->done);
406+ return;
407+}
408+
409+static int uvesafb_helper_start(void)
410+{
411+ char *envp[] = {
412+ "HOME=/",
413+ "PATH=/sbin:/bin",
414+ NULL,
415+ };
416+
417+ char *argv[] = {
418+ v86d_path,
419+ NULL,
420+ };
421+
422+ return call_usermodehelper(v86d_path, argv, envp, 1);
423+}
424+
425+/*
426+ * Execute a uvesafb task.
427+ *
428+ * Returns 0 if the task is executed successfully.
429+ *
430+ * A message sent to the userspace consists of the uvesafb_task
431+ * struct and (optionally) a buffer. The uvesafb_task struct is
432+ * a simplified version of uvesafb_ktask (its kernel counterpart)
433+ * containing only the register values, flags and the length of
434+ * the buffer.
435+ *
436+ * Each message is assigned a sequence number (increased linearly)
437+ * and a random ack number. The sequence number is used as a key
438+ * for the uvfb_tasks array which holds pointers to uvesafb_ktask
439+ * structs for all requests.
440+ */
441+static int uvesafb_exec(struct uvesafb_ktask *task)
442+{
443+ static int seq;
444+ struct cn_msg *m;
445+ int err;
446+ int len = sizeof(task->t) + task->t.buf_len;
447+
448+ /*
449+ * Check whether the message isn't longer than the maximum
450+ * allowed by connector.
451+ */
452+ if (sizeof(*m) + len > CONNECTOR_MAX_MSG_SIZE) {
453+ printk(KERN_WARNING "uvesafb: message too long (%d), "
454+ "can't execute task\n", (int)(sizeof(*m) + len));
455+ return -E2BIG;
456+ }
457+
458+ m = kzalloc(sizeof(*m) + len, GFP_KERNEL);
459+ if (!m)
460+ return -ENOMEM;
461+
462+ init_completion(task->done);
463+
464+ memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
465+ m->seq = seq;
466+ m->len = len;
467+ m->ack = random32();
468+
469+ /* uvesafb_task structure */
470+ memcpy(m + 1, &task->t, sizeof(task->t));
471+
472+ /* Buffer */
473+ memcpy((u8 *)(m + 1) + sizeof(task->t), task->buf, task->t.buf_len);
474+
475+ /*
476+ * Save the message ack number so that we can find the kernel
477+ * part of this task when a reply is received from userspace.
478+ */
479+ task->ack = m->ack;
480+
481+ mutex_lock(&uvfb_lock);
482+
483+ /* If all slots are taken -- bail out. */
484+ if (uvfb_tasks[seq]) {
485+ mutex_unlock(&uvfb_lock);
486+ return -EBUSY;
487+ }
488+
489+ /* Save a pointer to the kernel part of the task struct. */
490+ uvfb_tasks[seq] = task;
491+ mutex_unlock(&uvfb_lock);
492+
493+ err = cn_netlink_send(m, 0, gfp_any());
494+ if (err == -ESRCH) {
495+ /*
496+ * Try to start the userspace helper if sending
497+ * the request failed the first time.
498+ */
499+ err = uvesafb_helper_start();
500+ if (err) {
501+ printk(KERN_ERR "uvesafb: failed to execute %s\n",
502+ v86d_path);
503+ printk(KERN_ERR "uvesafb: make sure that the v86d "
504+ "helper is installed and executable\n");
505+ } else {
506+ v86d_started = 1;
507+ err = cn_netlink_send(m, 0, gfp_any());
508+ }
509+ }
510+ kfree(m);
511+
512+ if (!err && !(task->t.flags & TF_EXIT))
513+ err = !wait_for_completion_timeout(task->done,
514+ msecs_to_jiffies(UVESAFB_TIMEOUT));
515+
516+ mutex_lock(&uvfb_lock);
517+ uvfb_tasks[seq] = NULL;
518+ mutex_unlock(&uvfb_lock);
519+
520+ seq++;
521+ if (seq >= UVESAFB_TASKS_MAX)
522+ seq = 0;
523+
524+ return err;
525+}
526+
527+/*
528+ * Free a uvesafb_ktask struct.
529+ */
530+static void uvesafb_free(struct uvesafb_ktask *task)
531+{
532+ if (task) {
533+ if (task->done)
534+ kfree(task->done);
535+ kfree(task);
536+ }
537+}
538+
539+/*
540+ * Prepare a uvesafb_ktask struct to be used again.
541+ */
542+static void uvesafb_reset(struct uvesafb_ktask *task)
543+{
544+ struct completion *cpl = task->done;
545+
546+ memset(task, 0, sizeof(*task));
547+ task->done = cpl;
548+}
549+
550+/*
551+ * Allocate and prepare a uvesafb_ktask struct.
552+ */
553+static struct uvesafb_ktask *uvesafb_prep(void)
554+{
555+ struct uvesafb_ktask *task;
556+
557+ task = kzalloc(sizeof(*task), GFP_KERNEL);
558+ if (task) {
559+ task->done = kzalloc(sizeof(*task->done), GFP_KERNEL);
560+ if (!task->done) {
561+ kfree(task);
562+ task = NULL;
563+ }
564+ }
565+ return task;
566+}
567+
568+static void uvesafb_setup_var(struct fb_var_screeninfo *var,
569+ struct fb_info *info, struct vbe_mode_ib *mode)
570+{
571+ struct uvesafb_par *par = info->par;
572+
573+ var->vmode = FB_VMODE_NONINTERLACED;
574+ var->sync = FB_SYNC_VERT_HIGH_ACT;
575+
576+ var->xres = mode->x_res;
577+ var->yres = mode->y_res;
578+ var->xres_virtual = mode->x_res;
579+ var->yres_virtual = (par->ypan) ?
580+ info->fix.smem_len / mode->bytes_per_scan_line :
581+ mode->y_res;
582+ var->xoffset = 0;
583+ var->yoffset = 0;
584+ var->bits_per_pixel = mode->bits_per_pixel;
585+
586+ if (var->bits_per_pixel == 15)
587+ var->bits_per_pixel = 16;
588+
589+ if (var->bits_per_pixel > 8) {
590+ var->red.offset = mode->red_off;
591+ var->red.length = mode->red_len;
592+ var->green.offset = mode->green_off;
593+ var->green.length = mode->green_len;
594+ var->blue.offset = mode->blue_off;
595+ var->blue.length = mode->blue_len;
596+ var->transp.offset = mode->rsvd_off;
597+ var->transp.length = mode->rsvd_len;
598+ } else {
599+ var->red.offset = 0;
600+ var->green.offset = 0;
601+ var->blue.offset = 0;
602+ var->transp.offset = 0;
603+
604+ /*
605+ * We're assuming that we can switch the DAC to 8 bits. If
606+ * this proves to be incorrect, we'll update the fields
607+ * later in set_par().
608+ */
609+ if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
610+ var->red.length = 8;
611+ var->green.length = 8;
612+ var->blue.length = 8;
613+ var->transp.length = 0;
614+ } else {
615+ var->red.length = 6;
616+ var->green.length = 6;
617+ var->blue.length = 6;
618+ var->transp.length = 0;
619+ }
620+ }
621+}
622+
623+static int uvesafb_vbe_find_mode(struct uvesafb_par *par,
624+ int xres, int yres, int depth, unsigned char flags)
625+{
626+ int i, match = -1, h = 0, d = 0x7fffffff;
627+
628+ for (i = 0; i < par->vbe_modes_cnt; i++) {
629+ h = abs(par->vbe_modes[i].x_res - xres) +
630+ abs(par->vbe_modes[i].y_res - yres) +
631+ abs(depth - par->vbe_modes[i].depth);
632+
633+ /*
634+ * We have an exact match in terms of resolution
635+ * and depth.
636+ */
637+ if (h == 0)
638+ return i;
639+
640+ if (h < d || (h == d && par->vbe_modes[i].depth > depth)) {
641+ d = h;
642+ match = i;
643+ }
644+ }
645+ i = 1;
646+
647+ if (flags & UVESAFB_EXACT_DEPTH &&
648+ par->vbe_modes[match].depth != depth)
649+ i = 0;
650+
651+ if (flags & UVESAFB_EXACT_RES && d > 24)
652+ i = 0;
653+
654+ if (i != 0)
655+ return match;
656+ else
657+ return -1;
658+}
659+
660+static u8 *uvesafb_vbe_state_save(struct uvesafb_par *par)
661+{
662+ struct uvesafb_ktask *task;
663+ u8 *state;
664+ int err;
665+
666+ if (!par->vbe_state_size)
667+ return NULL;
668+
669+ state = kmalloc(par->vbe_state_size, GFP_KERNEL);
670+ if (!state)
671+ return NULL;
672+
673+ task = uvesafb_prep();
674+ if (!task) {
675+ kfree(state);
676+ return NULL;
677+ }
678+
679+ task->t.regs.eax = 0x4f04;
680+ task->t.regs.ecx = 0x000f;
681+ task->t.regs.edx = 0x0001;
682+ task->t.flags = TF_BUF_RET | TF_BUF_ESBX;
683+ task->t.buf_len = par->vbe_state_size;
684+ task->buf = state;
685+ err = uvesafb_exec(task);
686+
687+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
688+ printk(KERN_WARNING "uvesafb: VBE get state call "
689+ "failed (eax=0x%x, err=%d)\n",
690+ task->t.regs.eax, err);
691+ kfree(state);
692+ state = NULL;
693+ }
694+
695+ uvesafb_free(task);
696+ return state;
697+}
698+
699+static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
700+{
701+ struct uvesafb_ktask *task;
702+ int err;
703+
704+ if (!state_buf)
705+ return;
706+
707+ task = uvesafb_prep();
708+ if (!task)
709+ return;
710+
711+ task->t.regs.eax = 0x4f04;
712+ task->t.regs.ecx = 0x000f;
713+ task->t.regs.edx = 0x0002;
714+ task->t.buf_len = par->vbe_state_size;
715+ task->t.flags = TF_BUF_ESBX;
716+ task->buf = state_buf;
717+
718+ err = uvesafb_exec(task);
719+ if (err || (task->t.regs.eax & 0xffff) != 0x004f)
720+ printk(KERN_WARNING "uvesafb: VBE state restore call "
721+ "failed (eax=0x%x, err=%d)\n",
722+ task->t.regs.eax, err);
723+
724+ uvesafb_free(task);
725+}
726+
727+static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
728+ struct uvesafb_par *par)
729+{
730+ int err;
731+
732+ task->t.regs.eax = 0x4f00;
733+ task->t.flags = TF_VBEIB;
734+ task->t.buf_len = sizeof(struct vbe_ib);
735+ task->buf = &par->vbe_ib;
736+ strncpy(par->vbe_ib.vbe_signature, "VBE2", 4);
737+
738+ err = uvesafb_exec(task);
739+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
740+ printk(KERN_ERR "uvesafb: Getting VBE info block failed "
741+ "(eax=0x%x, err=%d)\n", (u32)task->t.regs.eax,
742+ err);
743+ return -EINVAL;
744+ }
745+
746+ if (par->vbe_ib.vbe_version < 0x0200) {
747+ printk(KERN_ERR "uvesafb: Sorry, pre-VBE 2.0 cards are "
748+ "not supported.\n");
749+ return -EINVAL;
750+ }
751+
752+ if (!par->vbe_ib.mode_list_ptr) {
753+ printk(KERN_ERR "uvesafb: Missing mode list!\n");
754+ return -EINVAL;
755+ }
756+
757+ printk(KERN_INFO "uvesafb: ");
758+
759+ /*
760+ * Convert string pointers and the mode list pointer into
761+ * usable addresses. Print informational messages about the
762+ * video adapter and its vendor.
763+ */
764+ if (par->vbe_ib.oem_vendor_name_ptr)
765+ printk("%s, ",
766+ ((char *)task->buf) + par->vbe_ib.oem_vendor_name_ptr);
767+
768+ if (par->vbe_ib.oem_product_name_ptr)
769+ printk("%s, ",
770+ ((char *)task->buf) + par->vbe_ib.oem_product_name_ptr);
771+
772+ if (par->vbe_ib.oem_product_rev_ptr)
773+ printk("%s, ",
774+ ((char *)task->buf) + par->vbe_ib.oem_product_rev_ptr);
775+
776+ if (par->vbe_ib.oem_string_ptr)
777+ printk("OEM: %s, ",
778+ ((char *)task->buf) + par->vbe_ib.oem_string_ptr);
779+
780+ printk("VBE v%d.%d\n", ((par->vbe_ib.vbe_version & 0xff00) >> 8),
781+ par->vbe_ib.vbe_version & 0xff);
782+
783+ return 0;
784+}
785+
786+static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
787+ struct uvesafb_par *par)
788+{
789+ int off = 0, err;
790+ u16 *mode;
791+
792+ par->vbe_modes_cnt = 0;
793+
794+ /* Count available modes. */
795+ mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
796+ while (*mode != 0xffff) {
797+ par->vbe_modes_cnt++;
798+ mode++;
799+ }
800+
801+ par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) *
802+ par->vbe_modes_cnt, GFP_KERNEL);
803+ if (!par->vbe_modes)
804+ return -ENOMEM;
805+
806+ /* Get info about all available modes. */
807+ mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
808+ while (*mode != 0xffff) {
809+ struct vbe_mode_ib *mib;
810+
811+ uvesafb_reset(task);
812+ task->t.regs.eax = 0x4f01;
813+ task->t.regs.ecx = (u32) *mode;
814+ task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
815+ task->t.buf_len = sizeof(struct vbe_mode_ib);
816+ task->buf = par->vbe_modes + off;
817+
818+ err = uvesafb_exec(task);
819+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
820+ printk(KERN_ERR "uvesafb: Getting mode info block "
821+ "for mode 0x%x failed (eax=0x%x, err=%d)\n",
822+ *mode, (u32)task->t.regs.eax, err);
823+ return -EINVAL;
824+ }
825+
826+ mib = task->buf;
827+ mib->mode_id = *mode;
828+
829+ /*
830+ * We only want modes that are supported with the current
831+ * hardware configuration, color, graphics and that have
832+ * support for the LFB.
833+ */
834+ if ((mib->mode_attr & VBE_MODE_MASK) == VBE_MODE_MASK &&
835+ mib->bits_per_pixel >= 8)
836+ off++;
837+ else
838+ par->vbe_modes_cnt--;
839+
840+ mode++;
841+ mib->depth = mib->red_len + mib->green_len + mib->blue_len;
842+
843+ /*
844+ * Handle 8bpp modes and modes with broken color component
845+ * lengths.
846+ */
847+ if (mib->depth == 0 || (mib->depth == 24 &&
848+ mib->bits_per_pixel == 32))
849+ mib->depth = mib->bits_per_pixel;
850+ }
851+
852+ return 0;
853+}
854+
855+/*
856+ * The Protected Mode Interface is 32-bit x86 code, so we only run it on
857+ * x86 and not x86_64.
858+ */
859+#ifdef CONFIG_X86_32
860+static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
861+ struct uvesafb_par *par)
862+{
863+ int i, err;
864+
865+ uvesafb_reset(task);
866+ task->t.regs.eax = 0x4f0a;
867+ task->t.regs.ebx = 0x0;
868+ err = uvesafb_exec(task);
869+
870+ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
871+ par->pmi_setpal = par->ypan = 0;
872+ } else {
873+ par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
874+ + task->t.regs.edi);
875+ par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
876+ par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
877+ printk(KERN_INFO "uvesafb: protected mode interface info at "
878+ "%04x:%04x\n",
879+ (u16)task->t.regs.es, (u16)task->t.regs.edi);
880+ printk(KERN_INFO "uvesafb: pmi: set display start = %p, "
881+ "set palette = %p\n", par->pmi_start,
882+ par->pmi_pal);
883+
884+ if (par->pmi_base[3]) {
885+ printk(KERN_INFO "uvesafb: pmi: ports = ");
886+ for (i = par->pmi_base[3]/2;
887+ par->pmi_base[i] != 0xffff; i++)
888+ printk("%x ", par->pmi_base[i]);
889+ printk("\n");
890+
891+ if (par->pmi_base[i] != 0xffff) {
892+ printk(KERN_INFO "uvesafb: can't handle memory"
893+ " requests, pmi disabled\n");
894+ par->ypan = par->pmi_setpal = 0;
895+ }
896+ }
897+ }
898+ return 0;
899+}
900+#endif /* CONFIG_X86_32 */
901+
902+/*
903+ * Check whether a video mode is supported by the Video BIOS and is
904+ * compatible with the monitor limits.
905+ */
906+static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
907+ struct fb_info *info)
908+{
909+ if (info->monspecs.gtf) {
910+ fb_videomode_to_var(&info->var, mode);
911+ if (fb_validate_mode(&info->var, info))
912+ return 0;
913+ }
914+
915+ if (uvesafb_vbe_find_mode(info->par, mode->xres, mode->yres, 8,
916+ UVESAFB_EXACT_RES) == -1)
917+ return 0;
918+
919+ return 1;
920+}
921+
922+static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
923+ struct fb_info *info)
924+{
925+ struct uvesafb_par *par = info->par;
926+ int err = 0;
927+
928+ if (noedid || par->vbe_ib.vbe_version < 0x0300)
929+ return -EINVAL;
930+
931+ task->t.regs.eax = 0x4f15;
932+ task->t.regs.ebx = 0;
933+ task->t.regs.ecx = 0;
934+ task->t.buf_len = 0;
935+ task->t.flags = 0;
936+
937+ err = uvesafb_exec(task);
938+
939+ if ((task->t.regs.eax & 0xffff) != 0x004f || err)
940+ return -EINVAL;
941+
942+ if ((task->t.regs.ebx & 0x3) == 3) {
943+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports both "
944+ "DDC1 and DDC2 transfers\n");
945+ } else if ((task->t.regs.ebx & 0x3) == 2) {
946+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC2 "
947+ "transfers\n");
948+ } else if ((task->t.regs.ebx & 0x3) == 1) {
949+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC1 "
950+ "transfers\n");
951+ } else {
952+ printk(KERN_INFO "uvesafb: VBIOS/hardware doesn't support "
953+ "DDC transfers\n");
954+ return -EINVAL;
955+ }
956+
957+ task->t.regs.eax = 0x4f15;
958+ task->t.regs.ebx = 1;
959+ task->t.regs.ecx = task->t.regs.edx = 0;
960+ task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
961+ task->t.buf_len = EDID_LENGTH;
962+ task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
963+
964+ err = uvesafb_exec(task);
965+
966+ if ((task->t.regs.eax & 0xffff) == 0x004f && !err) {
967+ fb_edid_to_monspecs(task->buf, &info->monspecs);
968+
969+ if (info->monspecs.vfmax && info->monspecs.hfmax) {
970+ /*
971+ * If the maximum pixel clock wasn't specified in
972+ * the EDID block, set it to 300 MHz.
973+ */
974+ if (info->monspecs.dclkmax == 0)
975+ info->monspecs.dclkmax = 300 * 1000000;
976+ info->monspecs.gtf = 1;
977+ }
978+ } else {
979+ err = -EINVAL;
980+ }
981+
982+ kfree(task->buf);
983+ return err;
984+}
985+
986+static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
987+ struct fb_info *info)
988+{
989+ struct uvesafb_par *par = info->par;
990+ int i;
991+
992+ memset(&info->monspecs, 0, sizeof(info->monspecs));
993+
994+ /*
995+ * If we don't get all necessary data from the EDID block,
996+ * mark it as incompatible with the GTF and set nocrtc so
997+ * that we always use the default BIOS refresh rate.
998+ */
999+ if (uvesafb_vbe_getedid(task, info)) {
1000+ info->monspecs.gtf = 0;
1001+ par->nocrtc = 1;
1002+ }
1003+
1004+ /* Kernel command line overrides. */
1005+ if (maxclk)
1006+ info->monspecs.dclkmax = maxclk * 1000000;
1007+ if (maxvf)
1008+ info->monspecs.vfmax = maxvf;
1009+ if (maxhf)
1010+ info->monspecs.hfmax = maxhf * 1000;
1011+
1012+ /*
1013+ * In case DDC transfers are not supported, the user can provide
1014+ * monitor limits manually. Lower limits are set to "safe" values.
1015+ */
1016+ if (info->monspecs.gtf == 0 && maxclk && maxvf && maxhf) {
1017+ info->monspecs.dclkmin = 0;
1018+ info->monspecs.vfmin = 60;
1019+ info->monspecs.hfmin = 29000;
1020+ info->monspecs.gtf = 1;
1021+ par->nocrtc = 0;
1022+ }
1023+
1024+ if (info->monspecs.gtf)
1025+ printk(KERN_INFO
1026+ "uvesafb: monitor limits: vf = %d Hz, hf = %d kHz, "
1027+ "clk = %d MHz\n", info->monspecs.vfmax,
1028+ (int)(info->monspecs.hfmax / 1000),
1029+ (int)(info->monspecs.dclkmax / 1000000));
1030+ else
1031+ printk(KERN_INFO "uvesafb: no monitor limits have been set, "
1032+ "default refresh rate will be used\n");
1033+
1034+ /* Add VBE modes to the modelist. */
1035+ for (i = 0; i < par->vbe_modes_cnt; i++) {
1036+ struct fb_var_screeninfo var;
1037+ struct vbe_mode_ib *mode;
1038+ struct fb_videomode vmode;
1039+
1040+ mode = &par->vbe_modes[i];
1041+ memset(&var, 0, sizeof(var));
1042+
1043+ var.xres = mode->x_res;
1044+ var.yres = mode->y_res;
1045+
1046+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, &var, info);
1047+ fb_var_to_videomode(&vmode, &var);
1048+ fb_add_videomode(&vmode, &info->modelist);
1049+ }
1050+
1051+ /* Add valid VESA modes to our modelist. */
1052+ for (i = 0; i < VESA_MODEDB_SIZE; i++) {
1053+ if (uvesafb_is_valid_mode((struct fb_videomode *)
1054+ &vesa_modes[i], info))
1055+ fb_add_videomode(&vesa_modes[i], &info->modelist);
1056+ }
1057+
1058+ for (i = 0; i < info->monspecs.modedb_len; i++) {
1059+ if (uvesafb_is_valid_mode(&info->monspecs.modedb[i], info))
1060+ fb_add_videomode(&info->monspecs.modedb[i],
1061+ &info->modelist);
1062+ }
1063+
1064+ return;
1065+}
1066+
1067+static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
1068+ struct uvesafb_par *par)
1069+{
1070+ int err;
1071+
1072+ uvesafb_reset(task);
1073+
1074+ /*
1075+ * Get the VBE state buffer size. We want all available
1076+ * hardware state data (CL = 0x0f).
1077+ */
1078+ task->t.regs.eax = 0x4f04;
1079+ task->t.regs.ecx = 0x000f;
1080+ task->t.regs.edx = 0x0000;
1081+ task->t.flags = 0;
1082+
1083+ err = uvesafb_exec(task);
1084+
1085+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
1086+ printk(KERN_WARNING "uvesafb: VBE state buffer size "
1087+ "cannot be determined (eax=0x%x, err=%d)\n",
1088+ task->t.regs.eax, err);
1089+ par->vbe_state_size = 0;
1090+ return;
1091+ }
1092+
1093+ par->vbe_state_size = 64 * (task->t.regs.ebx & 0xffff);
1094+}
1095+
1096+static int __devinit uvesafb_vbe_init(struct fb_info *info)
1097+{
1098+ struct uvesafb_ktask *task = NULL;
1099+ struct uvesafb_par *par = info->par;
1100+ int err;
1101+
1102+ task = uvesafb_prep();
1103+ if (!task)
1104+ return -ENOMEM;
1105+
1106+ err = uvesafb_vbe_getinfo(task, par);
1107+ if (err)
1108+ goto out;
1109+
1110+ err = uvesafb_vbe_getmodes(task, par);
1111+ if (err)
1112+ goto out;
1113+
1114+ par->nocrtc = nocrtc;
1115+#ifdef CONFIG_X86_32
1116+ par->pmi_setpal = pmi_setpal;
1117+ par->ypan = ypan;
1118+
1119+ if (par->pmi_setpal || par->ypan)
1120+ uvesafb_vbe_getpmi(task, par);
1121+#else
1122+ /* The protected mode interface is not available on non-x86. */
1123+ par->pmi_setpal = par->ypan = 0;
1124+#endif
1125+
1126+ INIT_LIST_HEAD(&info->modelist);
1127+ uvesafb_vbe_getmonspecs(task, info);
1128+ uvesafb_vbe_getstatesize(task, par);
1129+
1130+out: uvesafb_free(task);
1131+ return err;
1132+}
1133+
1134+static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
1135+{
1136+ struct list_head *pos;
1137+ struct fb_modelist *modelist;
1138+ struct fb_videomode *mode;
1139+ struct uvesafb_par *par = info->par;
1140+ int i, modeid;
1141+
1142+ /* Has the user requested a specific VESA mode? */
1143+ if (vbemode) {
1144+ for (i = 0; i < par->vbe_modes_cnt; i++) {
1145+ if (par->vbe_modes[i].mode_id == vbemode) {
1146+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
1147+ &info->var, info);
1148+ /*
1149+ * With pixclock set to 0, the default BIOS
1150+ * timings will be used in set_par().
1151+ */
1152+ info->var.pixclock = 0;
1153+ modeid = i;
1154+ goto gotmode;
1155+ }
1156+ }
1157+ printk(KERN_INFO "uvesafb: requested VBE mode 0x%x is "
1158+ "unavailable\n", vbemode);
1159+ vbemode = 0;
1160+ }
1161+
1162+ /* Count the modes in the modelist */
1163+ i = 0;
1164+ list_for_each(pos, &info->modelist)
1165+ i++;
1166+
1167+ /*
1168+ * Convert the modelist into a modedb so that we can use it with
1169+ * fb_find_mode().
1170+ */
1171+ mode = kzalloc(i * sizeof(*mode), GFP_KERNEL);
1172+ if (mode) {
1173+ i = 0;
1174+ list_for_each(pos, &info->modelist) {
1175+ modelist = list_entry(pos, struct fb_modelist, list);
1176+ mode[i] = modelist->mode;
1177+ i++;
1178+ }
1179+
1180+ if (!mode_option)
1181+ mode_option = UVESAFB_DEFAULT_MODE;
1182+
1183+ i = fb_find_mode(&info->var, info, mode_option, mode, i,
1184+ NULL, 8);
1185+
1186+ kfree(mode);
1187+ }
1188+
1189+ /* fb_find_mode() failed */
1190+ if (i == 0 || i >= 3) {
1191+ info->var.xres = 640;
1192+ info->var.yres = 480;
1193+ mode = (struct fb_videomode *)
1194+ fb_find_best_mode(&info->var, &info->modelist);
1195+
1196+ if (mode) {
1197+ fb_videomode_to_var(&info->var, mode);
1198+ } else {
1199+ modeid = par->vbe_modes[0].mode_id;
1200+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
1201+ &info->var, info);
1202+ goto gotmode;
1203+ }
1204+ }
1205+
1206+ /* Look for a matching VBE mode. */
1207+ modeid = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres,
1208+ info->var.bits_per_pixel, UVESAFB_EXACT_RES);
1209+
1210+ if (modeid == -1)
1211+ return -EINVAL;
1212+
1213+gotmode:
1214+ uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
1215+
1216+ /*
1217+ * If we are not VBE3.0+ compliant, we're done -- the BIOS will
1218+ * ignore our timings anyway.
1219+ */
1220+ if (par->vbe_ib.vbe_version < 0x0300 || par->nocrtc)
1221+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
1222+ &info->var, info);
1223+
1224+ return modeid;
1225+}
1226+
1227+static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
1228+ int start, struct fb_info *info)
1229+{
1230+ struct uvesafb_ktask *task;
1231+ struct uvesafb_par *par = info->par;
1232+ int i = par->mode_idx;
1233+ int err = 0;
1234+
1235+ /*
1236+ * We support palette modifications for 8 bpp modes only, so
1237+ * there can never be more than 256 entries.
1238+ */
1239+ if (start + count > 256)
1240+ return -EINVAL;
1241+
1242+ /* Use VGA registers if mode is VGA-compatible. */
1243+ if (i >= 0 && i < par->vbe_modes_cnt &&
1244+ par->vbe_modes[i].mode_attr & VBE_MODE_VGACOMPAT) {
1245+ for (i = 0; i < count; i++) {
1246+ outb_p(start + i, dac_reg);
1247+ outb_p(entries[i].red, dac_val);
1248+ outb_p(entries[i].green, dac_val);
1249+ outb_p(entries[i].blue, dac_val);
1250+ }
1251+ }
1252+#ifdef CONFIG_X86_32
1253+ else if (par->pmi_setpal) {
1254+ __asm__ __volatile__(
1255+ "call *(%%esi)"
1256+ : /* no return value */
1257+ : "a" (0x4f09), /* EAX */
1258+ "b" (0), /* EBX */
1259+ "c" (count), /* ECX */
1260+ "d" (start), /* EDX */
1261+ "D" (entries), /* EDI */
1262+ "S" (&par->pmi_pal)); /* ESI */
1263+ }
1264+#endif
1265+ else {
1266+ task = uvesafb_prep();
1267+ if (!task)
1268+ return -ENOMEM;
1269+
1270+ task->t.regs.eax = 0x4f09;
1271+ task->t.regs.ebx = 0x0;
1272+ task->t.regs.ecx = count;
1273+ task->t.regs.edx = start;
1274+ task->t.flags = TF_BUF_ESDI;
1275+ task->t.buf_len = sizeof(struct uvesafb_pal_entry) * count;
1276+ task->buf = entries;
1277+
1278+ err = uvesafb_exec(task);
1279+ if ((task->t.regs.eax & 0xffff) != 0x004f)
1280+ err = 1;
1281+
1282+ uvesafb_free(task);
1283+ }
1284+ return err;
1285+}
1286+
1287+static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1288+ unsigned blue, unsigned transp,
1289+ struct fb_info *info)
1290+{
1291+ struct uvesafb_pal_entry entry;
1292+ int shift = 16 - info->var.green.length;
1293+ int err = 0;
1294+
1295+ if (regno >= info->cmap.len)
1296+ return -EINVAL;
1297+
1298+ if (info->var.bits_per_pixel == 8) {
1299+ entry.red = red >> shift;
1300+ entry.green = green >> shift;
1301+ entry.blue = blue >> shift;
1302+ entry.pad = 0;
1303+
1304+ err = uvesafb_setpalette(&entry, 1, regno, info);
1305+ } else if (regno < 16) {
1306+ switch (info->var.bits_per_pixel) {
1307+ case 16:
1308+ if (info->var.red.offset == 10) {
1309+ /* 1:5:5:5 */
1310+ ((u32 *) (info->pseudo_palette))[regno] =
1311+ ((red & 0xf800) >> 1) |
1312+ ((green & 0xf800) >> 6) |
1313+ ((blue & 0xf800) >> 11);
1314+ } else {
1315+ /* 0:5:6:5 */
1316+ ((u32 *) (info->pseudo_palette))[regno] =
1317+ ((red & 0xf800) ) |
1318+ ((green & 0xfc00) >> 5) |
1319+ ((blue & 0xf800) >> 11);
1320+ }
1321+ break;
1322+
1323+ case 24:
1324+ case 32:
1325+ red >>= 8;
1326+ green >>= 8;
1327+ blue >>= 8;
1328+ ((u32 *)(info->pseudo_palette))[regno] =
1329+ (red << info->var.red.offset) |
1330+ (green << info->var.green.offset) |
1331+ (blue << info->var.blue.offset);
1332+ break;
1333+ }
1334+ }
1335+ return err;
1336+}
1337+
1338+static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
1339+{
1340+ struct uvesafb_pal_entry *entries;
1341+ int shift = 16 - info->var.green.length;
1342+ int i, err = 0;
1343+
1344+ if (info->var.bits_per_pixel == 8) {
1345+ if (cmap->start + cmap->len > info->cmap.start +
1346+ info->cmap.len || cmap->start < info->cmap.start)
1347+ return -EINVAL;
1348+
1349+ entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL);
1350+ if (!entries)
1351+ return -ENOMEM;
1352+
1353+ for (i = 0; i < cmap->len; i++) {
1354+ entries[i].red = cmap->red[i] >> shift;
1355+ entries[i].green = cmap->green[i] >> shift;
1356+ entries[i].blue = cmap->blue[i] >> shift;
1357+ entries[i].pad = 0;
1358+ }
1359+ err = uvesafb_setpalette(entries, cmap->len, cmap->start, info);
1360+ kfree(entries);
1361+ } else {
1362+ /*
1363+ * For modes with bpp > 8, we only set the pseudo palette in
1364+ * the fb_info struct. We rely on uvesafb_setcolreg to do all
1365+ * sanity checking.
1366+ */
1367+ for (i = 0; i < cmap->len; i++) {
1368+ err |= uvesafb_setcolreg(cmap->start + i, cmap->red[i],
1369+ cmap->green[i], cmap->blue[i],
1370+ 0, info);
1371+ }
1372+ }
1373+ return err;
1374+}
1375+
1376+static int uvesafb_pan_display(struct fb_var_screeninfo *var,
1377+ struct fb_info *info)
1378+{
1379+#ifdef CONFIG_X86_32
1380+ int offset;
1381+ struct uvesafb_par *par = info->par;
1382+
1383+ offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
1384+
1385+ /*
1386+ * It turns out it's not the best idea to do panning via vm86,
1387+ * so we only allow it if we have a PMI.
1388+ */
1389+ if (par->pmi_start) {
1390+ __asm__ __volatile__(
1391+ "call *(%%edi)"
1392+ : /* no return value */
1393+ : "a" (0x4f07), /* EAX */
1394+ "b" (0), /* EBX */
1395+ "c" (offset), /* ECX */
1396+ "d" (offset >> 16), /* EDX */
1397+ "D" (&par->pmi_start)); /* EDI */
1398+ }
1399+#endif
1400+ return 0;
1401+}
1402+
1403+static int uvesafb_blank(int blank, struct fb_info *info)
1404+{
1405+ struct uvesafb_par *par = info->par;
1406+ struct uvesafb_ktask *task;
1407+ int err = 1;
1408+
1409+ if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
1410+ int loop = 10000;
1411+ u8 seq = 0, crtc17 = 0;
1412+
1413+ if (blank == FB_BLANK_POWERDOWN) {
1414+ seq = 0x20;
1415+ crtc17 = 0x00;
1416+ err = 0;
1417+ } else {
1418+ seq = 0x00;
1419+ crtc17 = 0x80;
1420+ err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
1421+ }
1422+
1423+ vga_wseq(NULL, 0x00, 0x01);
1424+ seq |= vga_rseq(NULL, 0x01) & ~0x20;
1425+ vga_wseq(NULL, 0x00, seq);
1426+
1427+ crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
1428+ while (loop--);
1429+ vga_wcrt(NULL, 0x17, crtc17);
1430+ vga_wseq(NULL, 0x00, 0x03);
1431+ } else {
1432+ task = uvesafb_prep();
1433+ if (!task)
1434+ return -ENOMEM;
1435+
1436+ task->t.regs.eax = 0x4f10;
1437+ switch (blank) {
1438+ case FB_BLANK_UNBLANK:
1439+ task->t.regs.ebx = 0x0001;
1440+ break;
1441+ case FB_BLANK_NORMAL:
1442+ task->t.regs.ebx = 0x0101; /* standby */
1443+ break;
1444+ case FB_BLANK_POWERDOWN:
1445+ task->t.regs.ebx = 0x0401; /* powerdown */
1446+ break;
1447+ default:
1448+ goto out;
1449+ }
1450+
1451+ err = uvesafb_exec(task);
1452+ if (err || (task->t.regs.eax & 0xffff) != 0x004f)
1453+ err = 1;
1454+out: uvesafb_free(task);
1455+ }
1456+ return err;
1457+}
1458+
1459+static int uvesafb_open(struct fb_info *info, int user)
1460+{
1461+ struct uvesafb_par *par = info->par;
1462+ int cnt = atomic_read(&par->ref_count);
1463+
1464+ if (!cnt && par->vbe_state_size)
1465+ par->vbe_state_orig = uvesafb_vbe_state_save(par);
1466+
1467+ atomic_inc(&par->ref_count);
1468+ return 0;
1469+}
1470+
1471+static int uvesafb_release(struct fb_info *info, int user)
1472+{
1473+ struct uvesafb_ktask *task = NULL;
1474+ struct uvesafb_par *par = info->par;
1475+ int cnt = atomic_read(&par->ref_count);
1476+
1477+ if (!cnt)
1478+ return -EINVAL;
1479+
1480+ if (cnt != 1)
1481+ goto out;
1482+
1483+ task = uvesafb_prep();
1484+ if (!task)
1485+ goto out;
1486+
1487+ /* First, try to set the standard 80x25 text mode. */
1488+ task->t.regs.eax = 0x0003;
1489+ uvesafb_exec(task);
1490+
1491+ /*
1492+ * Now try to restore whatever hardware state we might have
1493+ * saved when the fb device was first opened.
1494+ */
1495+ uvesafb_vbe_state_restore(par, par->vbe_state_orig);
1496+out:
1497+ atomic_dec(&par->ref_count);
1498+ if (task)
1499+ uvesafb_free(task);
1500+ return 0;
1501+}
1502+
1503+static int uvesafb_set_par(struct fb_info *info)
1504+{
1505+ struct uvesafb_par *par = info->par;
1506+ struct uvesafb_ktask *task = NULL;
1507+ struct vbe_crtc_ib *crtc = NULL;
1508+ struct vbe_mode_ib *mode = NULL;
1509+ int i, err = 0, depth = info->var.bits_per_pixel;
1510+
1511+ if (depth > 8 && depth != 32)
1512+ depth = info->var.red.length + info->var.green.length +
1513+ info->var.blue.length;
1514+
1515+ i = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres, depth,
1516+ UVESAFB_EXACT_RES | UVESAFB_EXACT_DEPTH);
1517+ if (i >= 0)
1518+ mode = &par->vbe_modes[i];
1519+ else
1520+ return -EINVAL;
1521+
1522+ task = uvesafb_prep();
1523+ if (!task)
1524+ return -ENOMEM;
1525+setmode:
1526+ task->t.regs.eax = 0x4f02;
1527+ task->t.regs.ebx = mode->mode_id | 0x4000; /* use LFB */
1528+
1529+ if (par->vbe_ib.vbe_version >= 0x0300 && !par->nocrtc &&
1530+ info->var.pixclock != 0) {
1531+ task->t.regs.ebx |= 0x0800; /* use CRTC data */
1532+ task->t.flags = TF_BUF_ESDI;
1533+ crtc = kzalloc(sizeof(struct vbe_crtc_ib), GFP_KERNEL);
1534+ if (!crtc) {
1535+ err = -ENOMEM;
1536+ goto out;
1537+ }
1538+ crtc->horiz_start = info->var.xres + info->var.right_margin;
1539+ crtc->horiz_end = crtc->horiz_start + info->var.hsync_len;
1540+ crtc->horiz_total = crtc->horiz_end + info->var.left_margin;
1541+
1542+ crtc->vert_start = info->var.yres + info->var.lower_margin;
1543+ crtc->vert_end = crtc->vert_start + info->var.vsync_len;
1544+ crtc->vert_total = crtc->vert_end + info->var.upper_margin;
1545+
1546+ crtc->pixel_clock = PICOS2KHZ(info->var.pixclock) * 1000;
1547+ crtc->refresh_rate = (u16)(100 * (crtc->pixel_clock /
1548+ (crtc->vert_total * crtc->horiz_total)));
1549+
1550+ if (info->var.vmode & FB_VMODE_DOUBLE)
1551+ crtc->flags |= 0x1;
1552+ if (info->var.vmode & FB_VMODE_INTERLACED)
1553+ crtc->flags |= 0x2;
1554+ if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
1555+ crtc->flags |= 0x4;
1556+ if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
1557+ crtc->flags |= 0x8;
1558+ memcpy(&par->crtc, crtc, sizeof(*crtc));
1559+ } else {
1560+ memset(&par->crtc, 0, sizeof(*crtc));
1561+ }
1562+
1563+ task->t.buf_len = sizeof(struct vbe_crtc_ib);
1564+ task->buf = &par->crtc;
1565+
1566+ err = uvesafb_exec(task);
1567+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
1568+ /*
1569+ * The mode switch might have failed because we tried to
1570+ * use our own timings. Try again with the default timings.
1571+ */
1572+ if (crtc != NULL) {
1573+ printk(KERN_WARNING "uvesafb: mode switch failed "
1574+ "(eax=0x%x, err=%d). Trying again with "
1575+ "default timings.\n", task->t.regs.eax, err);
1576+ uvesafb_reset(task);
1577+ kfree(crtc);
1578+ crtc = NULL;
1579+ info->var.pixclock = 0;
1580+ goto setmode;
1581+ } else {
1582+ printk(KERN_ERR "uvesafb: mode switch failed (eax="
1583+ "0x%x, err=%d)\n", task->t.regs.eax, err);
1584+ err = -EINVAL;
1585+ goto out;
1586+ }
1587+ }
1588+ par->mode_idx = i;
1589+
1590+ /* For 8bpp modes, always try to set the DAC to 8 bits. */
1591+ if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC &&
1592+ mode->bits_per_pixel <= 8) {
1593+ uvesafb_reset(task);
1594+ task->t.regs.eax = 0x4f08;
1595+ task->t.regs.ebx = 0x0800;
1596+
1597+ err = uvesafb_exec(task);
1598+ if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
1599+ ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
1600+ /*
1601+ * We've failed to set the DAC palette format -
1602+ * time to correct var.
1603+ */
1604+ info->var.red.length = 6;
1605+ info->var.green.length = 6;
1606+ info->var.blue.length = 6;
1607+ }
1608+ }
1609+
1610+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
1611+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1612+ info->fix.line_length = mode->bytes_per_scan_line;
1613+
1614+out: if (crtc != NULL)
1615+ kfree(crtc);
1616+ uvesafb_free(task);
1617+
1618+ return err;
1619+}
1620+
1621+static void uvesafb_check_limits(struct fb_var_screeninfo *var,
1622+ struct fb_info *info)
1623+{
1624+ const struct fb_videomode *mode;
1625+ struct uvesafb_par *par = info->par;
1626+
1627+ /*
1628+ * If pixclock is set to 0, then we're using default BIOS timings
1629+ * and thus don't have to perform any checks here.
1630+ */
1631+ if (!var->pixclock)
1632+ return;
1633+
1634+ if (par->vbe_ib.vbe_version < 0x0300) {
1635+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, var, info);
1636+ return;
1637+ }
1638+
1639+ if (!fb_validate_mode(var, info))
1640+ return;
1641+
1642+ mode = fb_find_best_mode(var, &info->modelist);
1643+ if (mode) {
1644+ if (mode->xres == var->xres && mode->yres == var->yres &&
1645+ !(mode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))) {
1646+ fb_videomode_to_var(var, mode);
1647+ return;
1648+ }
1649+ }
1650+
1651+ if (info->monspecs.gtf && !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1652+ return;
1653+ /* Use default refresh rate */
1654+ var->pixclock = 0;
1655+}
1656+
1657+static int uvesafb_check_var(struct fb_var_screeninfo *var,
1658+ struct fb_info *info)
1659+{
1660+ struct uvesafb_par *par = info->par;
1661+ struct vbe_mode_ib *mode = NULL;
1662+ int match = -1;
1663+ int depth = var->red.length + var->green.length + var->blue.length;
1664+
1665+ /*
1666+ * Various apps will use bits_per_pixel to set the color depth,
1667+ * which is theoretically incorrect, but which we'll try to handle
1668+ * here.
1669+ */
1670+ if (depth == 0 || abs(depth - var->bits_per_pixel) >= 8)
1671+ depth = var->bits_per_pixel;
1672+
1673+ match = uvesafb_vbe_find_mode(par, var->xres, var->yres, depth,
1674+ UVESAFB_EXACT_RES);
1675+ if (match == -1)
1676+ return -EINVAL;
1677+
1678+ mode = &par->vbe_modes[match];
1679+ uvesafb_setup_var(var, info, mode);
1680+
1681+ /*
1682+ * Check whether we have remapped enough memory for this mode.
1683+ * We might be called at an early stage, when we haven't remapped
1684+ * any memory yet, in which case we simply skip the check.
1685+ */
1686+ if (var->yres * mode->bytes_per_scan_line > info->fix.smem_len
1687+ && info->fix.smem_len)
1688+ return -EINVAL;
1689+
1690+ if ((var->vmode & FB_VMODE_DOUBLE) &&
1691+ !(par->vbe_modes[match].mode_attr & 0x100))
1692+ var->vmode &= ~FB_VMODE_DOUBLE;
1693+
1694+ if ((var->vmode & FB_VMODE_INTERLACED) &&
1695+ !(par->vbe_modes[match].mode_attr & 0x200))
1696+ var->vmode &= ~FB_VMODE_INTERLACED;
1697+
1698+ uvesafb_check_limits(var, info);
1699+
1700+ var->xres_virtual = var->xres;
1701+ var->yres_virtual = (par->ypan) ?
1702+ info->fix.smem_len / mode->bytes_per_scan_line :
1703+ var->yres;
1704+ return 0;
1705+}
1706+
1707+static void uvesafb_save_state(struct fb_info *info)
1708+{
1709+ struct uvesafb_par *par = info->par;
1710+
1711+ if (par->vbe_state_saved)
1712+ kfree(par->vbe_state_saved);
1713+
1714+ par->vbe_state_saved = uvesafb_vbe_state_save(par);
1715+}
1716+
1717+static void uvesafb_restore_state(struct fb_info *info)
1718+{
1719+ struct uvesafb_par *par = info->par;
1720+
1721+ uvesafb_vbe_state_restore(par, par->vbe_state_saved);
1722+}
1723+
1724+static struct fb_ops uvesafb_ops = {
1725+ .owner = THIS_MODULE,
1726+ .fb_open = uvesafb_open,
1727+ .fb_release = uvesafb_release,
1728+ .fb_setcolreg = uvesafb_setcolreg,
1729+ .fb_setcmap = uvesafb_setcmap,
1730+ .fb_pan_display = uvesafb_pan_display,
1731+ .fb_blank = uvesafb_blank,
1732+ .fb_fillrect = cfb_fillrect,
1733+ .fb_copyarea = cfb_copyarea,
1734+ .fb_imageblit = cfb_imageblit,
1735+ .fb_check_var = uvesafb_check_var,
1736+ .fb_set_par = uvesafb_set_par,
1737+ .fb_save_state = uvesafb_save_state,
1738+ .fb_restore_state = uvesafb_restore_state,
1739+};
1740+
1741+static void __devinit uvesafb_init_info(struct fb_info *info,
1742+ struct vbe_mode_ib *mode)
1743+{
1744+ unsigned int size_vmode;
1745+ unsigned int size_remap;
1746+ unsigned int size_total;
1747+ struct uvesafb_par *par = info->par;
1748+ int i, h;
1749+
1750+ info->pseudo_palette = ((u8 *)info->par + sizeof(struct uvesafb_par));
1751+ info->fix = uvesafb_fix;
1752+ info->fix.ypanstep = par->ypan ? 1 : 0;
1753+ info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
1754+
1755+ /*
1756+ * If we were unable to get the state buffer size, disable
1757+ * functions for saving and restoring the hardware state.
1758+ */
1759+ if (par->vbe_state_size == 0) {
1760+ info->fbops->fb_save_state = NULL;
1761+ info->fbops->fb_restore_state = NULL;
1762+ }
1763+
1764+ /* Disable blanking if the user requested so. */
1765+ if (!blank)
1766+ info->fbops->fb_blank = NULL;
1767+
1768+ /*
1769+ * Find out how much IO memory is required for the mode with
1770+ * the highest resolution.
1771+ */
1772+ size_remap = 0;
1773+ for (i = 0; i < par->vbe_modes_cnt; i++) {
1774+ h = par->vbe_modes[i].bytes_per_scan_line *
1775+ par->vbe_modes[i].y_res;
1776+ if (h > size_remap)
1777+ size_remap = h;
1778+ }
1779+ size_remap *= 2;
1780+
1781+ /*
1782+ * size_vmode -- that is the amount of memory needed for the
1783+ * used video mode, i.e. the minimum amount of
1784+ * memory we need.
1785+ */
1786+ if (mode != NULL) {
1787+ size_vmode = info->var.yres * mode->bytes_per_scan_line;
1788+ } else {
1789+ size_vmode = info->var.yres * info->var.xres *
1790+ ((info->var.bits_per_pixel + 7) >> 3);
1791+ }
1792+
1793+ /*
1794+ * size_total -- all video memory we have. Used for mtrr
1795+ * entries, resource allocation and bounds
1796+ * checking.
1797+ */
1798+ size_total = par->vbe_ib.total_memory * 65536;
1799+ if (vram_total)
1800+ size_total = vram_total * 1024 * 1024;
1801+ if (size_total < size_vmode)
1802+ size_total = size_vmode;
1803+
1804+ /*
1805+ * size_remap -- the amount of video memory we are going to
1806+ * use for vesafb. With modern cards it is no
1807+ * option to simply use size_total as th
1808+ * wastes plenty of kernel address space.
1809+ */
1810+ if (vram_remap)
1811+ size_remap = vram_remap * 1024 * 1024;
1812+ if (size_remap < size_vmode)
1813+ size_remap = size_vmode;
1814+ if (size_remap > size_total)
1815+ size_remap = size_total;
1816+
1817+ info->fix.smem_len = size_remap;
1818+ info->fix.smem_start = mode->phys_base_ptr;
1819+
1820+ /*
1821+ * We have to set yres_virtual here because when setup_var() was
1822+ * called, smem_len wasn't defined yet.
1823+ */
1824+ info->var.yres_virtual = info->fix.smem_len /
1825+ mode->bytes_per_scan_line;
1826+
1827+ if (par->ypan && info->var.yres_virtual > info->var.yres) {
1828+ printk(KERN_INFO "uvesafb: scrolling: %s "
1829+ "using protected mode interface, "
1830+ "yres_virtual=%d\n",
1831+ (par->ypan > 1) ? "ywrap" : "ypan",
1832+ info->var.yres_virtual);
1833+ } else {
1834+ printk(KERN_INFO "uvesafb: scrolling: redraw\n");
1835+ info->var.yres_virtual = info->var.yres;
1836+ par->ypan = 0;
1837+ }
1838+
1839+ info->flags = FBINFO_FLAG_DEFAULT |
1840+ (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
1841+
1842+ if (!par->ypan)
1843+ info->fbops->fb_pan_display = NULL;
1844+}
1845+
1846+static void uvesafb_init_mtrr(struct fb_info *info)
1847+{
1848+#ifdef CONFIG_MTRR
1849+ if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
1850+ int temp_size = info->fix.smem_len;
1851+ unsigned int type = 0;
1852+
1853+ switch (mtrr) {
1854+ case 1:
1855+ type = MTRR_TYPE_UNCACHABLE;
1856+ break;
1857+ case 2:
1858+ type = MTRR_TYPE_WRBACK;
1859+ break;
1860+ case 3:
1861+ type = MTRR_TYPE_WRCOMB;
1862+ break;
1863+ case 4:
1864+ type = MTRR_TYPE_WRTHROUGH;
1865+ break;
1866+ default:
1867+ type = 0;
1868+ break;
1869+ }
1870+
1871+ if (type) {
1872+ int rc;
1873+
1874+ /* Find the largest power-of-two */
1875+ while (temp_size & (temp_size - 1))
1876+ temp_size &= (temp_size - 1);
1877+
1878+ /* Try and find a power of two to add */
1879+ do {
1880+ rc = mtrr_add(info->fix.smem_start,
1881+ temp_size, type, 1);
1882+ temp_size >>= 1;
1883+ } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
1884+ }
1885+ }
1886+#endif /* CONFIG_MTRR */
1887+}
1888+
1889+
1890+static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1891+ struct device_attribute *attr, char *buf)
1892+{
1893+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1894+ struct uvesafb_par *par = info->par;
1895+
1896+ return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);
1897+}
1898+
1899+static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);
1900+
1901+static ssize_t uvesafb_show_vbe_modes(struct device *dev,
1902+ struct device_attribute *attr, char *buf)
1903+{
1904+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1905+ struct uvesafb_par *par = info->par;
1906+ int ret = 0, i;
1907+
1908+ for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {
1909+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
1910+ "%dx%d-%d, 0x%.4x\n",
1911+ par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,
1912+ par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);
1913+ }
1914+
1915+ return ret;
1916+}
1917+
1918+static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);
1919+
1920+static ssize_t uvesafb_show_vendor(struct device *dev,
1921+ struct device_attribute *attr, char *buf)
1922+{
1923+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1924+ struct uvesafb_par *par = info->par;
1925+
1926+ if (par->vbe_ib.oem_vendor_name_ptr)
1927+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1928+ (&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr);
1929+ else
1930+ return 0;
1931+}
1932+
1933+static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);
1934+
1935+static ssize_t uvesafb_show_product_name(struct device *dev,
1936+ struct device_attribute *attr, char *buf)
1937+{
1938+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1939+ struct uvesafb_par *par = info->par;
1940+
1941+ if (par->vbe_ib.oem_product_name_ptr)
1942+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1943+ (&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr);
1944+ else
1945+ return 0;
1946+}
1947+
1948+static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);
1949+
1950+static ssize_t uvesafb_show_product_rev(struct device *dev,
1951+ struct device_attribute *attr, char *buf)
1952+{
1953+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1954+ struct uvesafb_par *par = info->par;
1955+
1956+ if (par->vbe_ib.oem_product_rev_ptr)
1957+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1958+ (&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr);
1959+ else
1960+ return 0;
1961+}
1962+
1963+static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);
1964+
1965+static ssize_t uvesafb_show_oem_string(struct device *dev,
1966+ struct device_attribute *attr, char *buf)
1967+{
1968+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1969+ struct uvesafb_par *par = info->par;
1970+
1971+ if (par->vbe_ib.oem_string_ptr)
1972+ return snprintf(buf, PAGE_SIZE, "%s\n",
1973+ (char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr);
1974+ else
1975+ return 0;
1976+}
1977+
1978+static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);
1979+
1980+static ssize_t uvesafb_show_nocrtc(struct device *dev,
1981+ struct device_attribute *attr, char *buf)
1982+{
1983+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1984+ struct uvesafb_par *par = info->par;
1985+
1986+ return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);
1987+}
1988+
1989+static ssize_t uvesafb_store_nocrtc(struct device *dev,
1990+ struct device_attribute *attr, const char *buf, size_t count)
1991+{
1992+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1993+ struct uvesafb_par *par = info->par;
1994+
1995+ if (count > 0) {
1996+ if (buf[0] == '0')
1997+ par->nocrtc = 0;
1998+ else
1999+ par->nocrtc = 1;
2000+ }
2001+ return count;
2002+}
2003+
2004+static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,
2005+ uvesafb_store_nocrtc);
2006+
2007+static struct attribute *uvesafb_dev_attrs[] = {
2008+ &dev_attr_vbe_version.attr,
2009+ &dev_attr_vbe_modes.attr,
2010+ &dev_attr_oem_vendor.attr,
2011+ &dev_attr_oem_product_name.attr,
2012+ &dev_attr_oem_product_rev.attr,
2013+ &dev_attr_oem_string.attr,
2014+ &dev_attr_nocrtc.attr,
2015+ NULL,
2016+};
2017+
2018+static struct attribute_group uvesafb_dev_attgrp = {
2019+ .name = NULL,
2020+ .attrs = uvesafb_dev_attrs,
2021+};
2022+
2023+static int __devinit uvesafb_probe(struct platform_device *dev)
2024+{
2025+ struct fb_info *info;
2026+ struct vbe_mode_ib *mode = NULL;
2027+ struct uvesafb_par *par;
2028+ int err = 0, i;
2029+
2030+ info = framebuffer_alloc(sizeof(*par) + sizeof(u32) * 256, &dev->dev);
2031+ if (!info)
2032+ return -ENOMEM;
2033+
2034+ par = info->par;
2035+
2036+ err = uvesafb_vbe_init(info);
2037+ if (err) {
2038+ printk(KERN_ERR "uvesafb: vbe_init() failed with %d\n", err);
2039+ goto out;
2040+ }
2041+
2042+ info->fbops = &uvesafb_ops;
2043+
2044+ i = uvesafb_vbe_init_mode(info);
2045+ if (i < 0) {
2046+ err = -EINVAL;
2047+ goto out;
2048+ } else {
2049+ mode = &par->vbe_modes[i];
2050+ }
2051+
2052+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
2053+ err = -ENXIO;
2054+ goto out;
2055+ }
2056+
2057+ uvesafb_init_info(info, mode);
2058+
2059+ if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
2060+ "uvesafb")) {
2061+ printk(KERN_ERR "uvesafb: cannot reserve video memory at "
2062+ "0x%lx\n", info->fix.smem_start);
2063+ err = -EIO;
2064+ goto out_mode;
2065+ }
2066+
2067+ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
2068+
2069+ if (!info->screen_base) {
2070+ printk(KERN_ERR
2071+ "uvesafb: abort, cannot ioremap 0x%x bytes of video "
2072+ "memory at 0x%lx\n",
2073+ info->fix.smem_len, info->fix.smem_start);
2074+ err = -EIO;
2075+ goto out_mem;
2076+ }
2077+
2078+ if (!request_region(0x3c0, 32, "uvesafb")) {
2079+ printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
2080+ err = -EIO;
2081+ goto out_unmap;
2082+ }
2083+
2084+ uvesafb_init_mtrr(info);
2085+ platform_set_drvdata(dev, info);
2086+
2087+ if (register_framebuffer(info) < 0) {
2088+ printk(KERN_ERR
2089+ "uvesafb: failed to register framebuffer device\n");
2090+ err = -EINVAL;
2091+ goto out_reg;
2092+ }
2093+
2094+ printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
2095+ "using %dk, total %dk\n", info->fix.smem_start,
2096+ info->screen_base, info->fix.smem_len/1024,
2097+ par->vbe_ib.total_memory * 64);
2098+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
2099+ info->fix.id);
2100+
2101+ err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
2102+ if (err != 0)
2103+ printk(KERN_WARNING "fb%d: failed to register attributes\n",
2104+ info->node);
2105+
2106+ return 0;
2107+
2108+out_reg:
2109+ release_region(0x3c0, 32);
2110+out_unmap:
2111+ iounmap(info->screen_base);
2112+out_mem:
2113+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
2114+out_mode:
2115+ if (!list_empty(&info->modelist))
2116+ fb_destroy_modelist(&info->modelist);
2117+ fb_destroy_modedb(info->monspecs.modedb);
2118+ fb_dealloc_cmap(&info->cmap);
2119+out:
2120+ if (par->vbe_modes)
2121+ kfree(par->vbe_modes);
2122+
2123+ framebuffer_release(info);
2124+ return err;
2125+}
2126+
2127+static int uvesafb_remove(struct platform_device *dev)
2128+{
2129+ struct fb_info *info = platform_get_drvdata(dev);
2130+
2131+ if (info) {
2132+ struct uvesafb_par *par = info->par;
2133+
2134+ sysfs_remove_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
2135+ unregister_framebuffer(info);
2136+ release_region(0x3c0, 32);
2137+ iounmap(info->screen_base);
2138+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
2139+ fb_destroy_modedb(info->monspecs.modedb);
2140+ fb_dealloc_cmap(&info->cmap);
2141+
2142+ if (par) {
2143+ if (par->vbe_modes)
2144+ kfree(par->vbe_modes);
2145+ if (par->vbe_state_orig)
2146+ kfree(par->vbe_state_orig);
2147+ if (par->vbe_state_saved)
2148+ kfree(par->vbe_state_saved);
2149+ }
2150+
2151+ framebuffer_release(info);
2152+ }
2153+ return 0;
2154+}
2155+
2156+static struct platform_driver uvesafb_driver = {
2157+ .probe = uvesafb_probe,
2158+ .remove = uvesafb_remove,
2159+ .driver = {
2160+ .name = "uvesafb",
2161+ },
2162+};
2163+
2164+static struct platform_device *uvesafb_device;
2165+
2166+#ifndef MODULE
2167+static int __devinit uvesafb_setup(char *options)
2168+{
2169+ char *this_opt;
2170+
2171+ if (!options || !*options)
2172+ return 0;
2173+
2174+ while ((this_opt = strsep(&options, ",")) != NULL) {
2175+ if (!*this_opt) continue;
2176+
2177+ if (!strcmp(this_opt, "redraw"))
2178+ ypan = 0;
2179+ else if (!strcmp(this_opt, "ypan"))
2180+ ypan = 1;
2181+ else if (!strcmp(this_opt, "ywrap"))
2182+ ypan = 2;
2183+ else if (!strcmp(this_opt, "vgapal"))
2184+ pmi_setpal = 0;
2185+ else if (!strcmp(this_opt, "pmipal"))
2186+ pmi_setpal = 1;
2187+ else if (!strncmp(this_opt, "mtrr:", 5))
2188+ mtrr = simple_strtoul(this_opt+5, NULL, 0);
2189+ else if (!strcmp(this_opt, "nomtrr"))
2190+ mtrr = 0;
2191+ else if (!strcmp(this_opt, "nocrtc"))
2192+ nocrtc = 1;
2193+ else if (!strcmp(this_opt, "noedid"))
2194+ noedid = 1;
2195+ else if (!strcmp(this_opt, "noblank"))
2196+ blank = 0;
2197+ else if (!strncmp(this_opt, "vtotal:", 7))
2198+ vram_total = simple_strtoul(this_opt + 7, NULL, 0);
2199+ else if (!strncmp(this_opt, "vremap:", 7))
2200+ vram_remap = simple_strtoul(this_opt + 7, NULL, 0);
2201+ else if (!strncmp(this_opt, "maxhf:", 6))
2202+ maxhf = simple_strtoul(this_opt + 6, NULL, 0);
2203+ else if (!strncmp(this_opt, "maxvf:", 6))
2204+ maxvf = simple_strtoul(this_opt + 6, NULL, 0);
2205+ else if (!strncmp(this_opt, "maxclk:", 7))
2206+ maxclk = simple_strtoul(this_opt + 7, NULL, 0);
2207+ else if (!strncmp(this_opt, "vbemode:", 8))
2208+ vbemode = simple_strtoul(this_opt + 8, NULL, 0);
2209+ else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
2210+ mode_option = this_opt;
2211+ } else {
2212+ printk(KERN_WARNING
2213+ "uvesafb: unrecognized option %s\n", this_opt);
2214+ }
2215+ }
2216+
2217+ return 0;
2218+}
2219+#endif /* !MODULE */
2220+
2221+static ssize_t show_v86d(struct device_driver *dev, char *buf)
2222+{
2223+ return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
2224+}
2225+
2226+static ssize_t store_v86d(struct device_driver *dev, const char *buf,
2227+ size_t count)
2228+{
2229+ strncpy(v86d_path, buf, PATH_MAX);
2230+ return count;
2231+}
2232+
2233+static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
2234+
2235+static int __devinit uvesafb_init(void)
2236+{
2237+ int err;
2238+
2239+#ifndef MODULE
2240+ char *option = NULL;
2241+
2242+ if (fb_get_options("uvesafb", &option))
2243+ return -ENODEV;
2244+ uvesafb_setup(option);
2245+#endif
2246+ err = cn_add_callback(&uvesafb_cn_id, "uvesafb", uvesafb_cn_callback);
2247+ if (err)
2248+ return err;
2249+
2250+ err = platform_driver_register(&uvesafb_driver);
2251+
2252+ if (!err) {
2253+ uvesafb_device = platform_device_alloc("uvesafb", 0);
2254+ if (uvesafb_device)
2255+ err = platform_device_add(uvesafb_device);
2256+ else
2257+ err = -ENOMEM;
2258+
2259+ if (err) {
2260+ platform_device_put(uvesafb_device);
2261+ platform_driver_unregister(&uvesafb_driver);
2262+ cn_del_callback(&uvesafb_cn_id);
2263+ return err;
2264+ }
2265+
2266+ err = driver_create_file(&uvesafb_driver.driver,
2267+ &driver_attr_v86d);
2268+ if (err) {
2269+ printk(KERN_WARNING "uvesafb: failed to register "
2270+ "attributes\n");
2271+ err = 0;
2272+ }
2273+ }
2274+ return err;
2275+}
2276+
2277+module_init(uvesafb_init);
2278+
2279+static void __devexit uvesafb_exit(void)
2280+{
2281+ struct uvesafb_ktask *task;
2282+
2283+ if (v86d_started) {
2284+ task = uvesafb_prep();
2285+ if (task) {
2286+ task->t.flags = TF_EXIT;
2287+ uvesafb_exec(task);
2288+ uvesafb_free(task);
2289+ }
2290+ }
2291+
2292+ cn_del_callback(&uvesafb_cn_id);
2293+ driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
2294+ platform_device_unregister(uvesafb_device);
2295+ platform_driver_unregister(&uvesafb_driver);
2296+}
2297+
2298+module_exit(uvesafb_exit);
2299+
2300+static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
2301+{
2302+ return 0;
2303+}
2304+
2305+static inline int param_set_scroll(const char *val, struct kernel_param *kp)
2306+{
2307+ ypan = 0;
2308+
2309+ if (!strcmp(val, "redraw"))
2310+ ypan = 0;
2311+ else if (!strcmp(val, "ypan"))
2312+ ypan = 1;
2313+ else if (!strcmp(val, "ywrap"))
2314+ ypan = 2;
2315+
2316+ return 0;
2317+}
2318+
2319+#define param_check_scroll(name, p) __param_check(name, p, void);
2320+
2321+module_param_named(scroll, ypan, scroll, 0);
2322+MODULE_PARM_DESC(scroll,
2323+ "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'");
2324+module_param_named(vgapal, pmi_setpal, invbool, 0);
2325+MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
2326+module_param_named(pmipal, pmi_setpal, bool, 0);
2327+MODULE_PARM_DESC(pmipal, "Set palette using PMI calls");
2328+module_param(mtrr, uint, 0);
2329+MODULE_PARM_DESC(mtrr,
2330+ "Memory Type Range Registers setting. Use 0 to disable.");
2331+module_param(blank, bool, 0);
2332+MODULE_PARM_DESC(blank, "Enable hardware blanking");
2333+module_param(nocrtc, bool, 0);
2334+MODULE_PARM_DESC(nocrtc, "Ignore CRTC timings when setting modes");
2335+module_param(noedid, bool, 0);
2336+MODULE_PARM_DESC(noedid,
2337+ "Ignore EDID-provided monitor limits when setting modes");
2338+module_param(vram_remap, uint, 0);
2339+MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");
2340+module_param(vram_total, uint, 0);
2341+MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]");
2342+module_param(maxclk, ushort, 0);
2343+MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");
2344+module_param(maxhf, ushort, 0);
2345+MODULE_PARM_DESC(maxhf,
2346+ "Maximum horizontal frequency [kHz], overrides EDID data");
2347+module_param(maxvf, ushort, 0);
2348+MODULE_PARM_DESC(maxvf,
2349+ "Maximum vertical frequency [Hz], overrides EDID data");
2350+module_param_named(mode, mode_option, charp, 0);
2351+MODULE_PARM_DESC(mode,
2352+ "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
2353+module_param(vbemode, ushort, 0);
2354+MODULE_PARM_DESC(vbemode,
2355+ "VBE mode number to set, overrides the 'mode' option");
2356+module_param_string(v86d, v86d_path, PATH_MAX, 0660);
2357+MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");
2358+
2359+MODULE_LICENSE("GPL");
2360+MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");
2361+MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");
2362+
2363Index: linux-2.6.22/include/linux/connector.h
2364===================================================================
2365--- linux-2.6.22.orig/include/linux/connector.h 2007-08-28 21:54:13.000000000 +0100
2366+++ linux-2.6.22/include/linux/connector.h 2007-08-28 21:56:34.000000000 +0100
2367@@ -36,14 +36,15 @@
2368 #define CN_VAL_CIFS 0x1
2369 #define CN_W1_IDX 0x3 /* w1 communication */
2370 #define CN_W1_VAL 0x1
2371+#define CN_IDX_V86D 0x4
2372+#define CN_VAL_V86D_UVESAFB 0x1
2373
2374-
2375-#define CN_NETLINK_USERS 4
2376+#define CN_NETLINK_USERS 5
2377
2378 /*
2379 * Maximum connector's message size.
2380 */
2381-#define CONNECTOR_MAX_MSG_SIZE 1024
2382+#define CONNECTOR_MAX_MSG_SIZE 16384
2383
2384 /*
2385 * idx and val are unique identifiers which
2386Index: linux-2.6.22/include/video/Kbuild
2387===================================================================
2388--- linux-2.6.22.orig/include/video/Kbuild 2007-08-28 21:54:13.000000000 +0100
2389+++ linux-2.6.22/include/video/Kbuild 2007-08-28 21:56:34.000000000 +0100
2390@@ -1 +1 @@
2391-unifdef-y += sisfb.h
2392+unifdef-y += sisfb.h uvesafb.h
2393Index: linux-2.6.22/include/video/uvesafb.h
2394===================================================================
2395--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2396+++ linux-2.6.22/include/video/uvesafb.h 2007-08-28 21:56:34.000000000 +0100
2397@@ -0,0 +1,193 @@
2398+#ifndef _UVESAFB_H
2399+#define _UVESAFB_H
2400+
2401+struct v86_regs {
2402+ __u32 ebx;
2403+ __u32 ecx;
2404+ __u32 edx;
2405+ __u32 esi;
2406+ __u32 edi;
2407+ __u32 ebp;
2408+ __u32 eax;
2409+ __u32 eip;
2410+ __u32 eflags;
2411+ __u32 esp;
2412+ __u16 cs;
2413+ __u16 ss;
2414+ __u16 es;
2415+ __u16 ds;
2416+ __u16 fs;
2417+ __u16 gs;
2418+};
2419+
2420+/* Task flags */
2421+#define TF_VBEIB 0x01
2422+#define TF_BUF_ESDI 0x02
2423+#define TF_BUF_ESBX 0x04
2424+#define TF_BUF_RET 0x08
2425+#define TF_EXIT 0x10
2426+
2427+struct uvesafb_task {
2428+ __u8 flags;
2429+ int buf_len;
2430+ struct v86_regs regs;
2431+};
2432+
2433+/* Constants for the capabilities field
2434+ * in vbe_ib */
2435+#define VBE_CAP_CAN_SWITCH_DAC 0x01
2436+#define VBE_CAP_VGACOMPAT 0x02
2437+
2438+/* The VBE Info Block */
2439+struct vbe_ib {
2440+ char vbe_signature[4];
2441+ __u16 vbe_version;
2442+ __u32 oem_string_ptr;
2443+ __u32 capabilities;
2444+ __u32 mode_list_ptr;
2445+ __u16 total_memory;
2446+ __u16 oem_software_rev;
2447+ __u32 oem_vendor_name_ptr;
2448+ __u32 oem_product_name_ptr;
2449+ __u32 oem_product_rev_ptr;
2450+ __u8 reserved[222];
2451+ char oem_data[256];
2452+ char misc_data[512];
2453+} __attribute__ ((packed));
2454+
2455+#ifdef __KERNEL__
2456+
2457+/* VBE CRTC Info Block */
2458+struct vbe_crtc_ib {
2459+ u16 horiz_total;
2460+ u16 horiz_start;
2461+ u16 horiz_end;
2462+ u16 vert_total;
2463+ u16 vert_start;
2464+ u16 vert_end;
2465+ u8 flags;
2466+ u32 pixel_clock;
2467+ u16 refresh_rate;
2468+ u8 reserved[40];
2469+} __attribute__ ((packed));
2470+
2471+#define VBE_MODE_VGACOMPAT 0x20
2472+#define VBE_MODE_COLOR 0x08
2473+#define VBE_MODE_SUPPORTEDHW 0x01
2474+#define VBE_MODE_GRAPHICS 0x10
2475+#define VBE_MODE_LFB 0x80
2476+
2477+#define VBE_MODE_MASK (VBE_MODE_COLOR | VBE_MODE_SUPPORTEDHW | \
2478+ VBE_MODE_GRAPHICS | VBE_MODE_LFB)
2479+
2480+/* VBE Mode Info Block */
2481+struct vbe_mode_ib {
2482+ /* for all VBE revisions */
2483+ u16 mode_attr;
2484+ u8 winA_attr;
2485+ u8 winB_attr;
2486+ u16 win_granularity;
2487+ u16 win_size;
2488+ u16 winA_seg;
2489+ u16 winB_seg;
2490+ u32 win_func_ptr;
2491+ u16 bytes_per_scan_line;
2492+
2493+ /* for VBE 1.2+ */
2494+ u16 x_res;
2495+ u16 y_res;
2496+ u8 x_char_size;
2497+ u8 y_char_size;
2498+ u8 planes;
2499+ u8 bits_per_pixel;
2500+ u8 banks;
2501+ u8 memory_model;
2502+ u8 bank_size;
2503+ u8 image_pages;
2504+ u8 reserved1;
2505+
2506+ /* Direct color fields for direct/6 and YUV/7 memory models. */
2507+ /* Offsets are bit positions of lsb in the mask. */
2508+ u8 red_len;
2509+ u8 red_off;
2510+ u8 green_len;
2511+ u8 green_off;
2512+ u8 blue_len;
2513+ u8 blue_off;
2514+ u8 rsvd_len;
2515+ u8 rsvd_off;
2516+ u8 direct_color_info; /* direct color mode attributes */
2517+
2518+ /* for VBE 2.0+ */
2519+ u32 phys_base_ptr;
2520+ u8 reserved2[6];
2521+
2522+ /* for VBE 3.0+ */
2523+ u16 lin_bytes_per_scan_line;
2524+ u8 bnk_image_pages;
2525+ u8 lin_image_pages;
2526+ u8 lin_red_len;
2527+ u8 lin_red_off;
2528+ u8 lin_green_len;
2529+ u8 lin_green_off;
2530+ u8 lin_blue_len;
2531+ u8 lin_blue_off;
2532+ u8 lin_rsvd_len;
2533+ u8 lin_rsvd_off;
2534+ u32 max_pixel_clock;
2535+ u16 mode_id;
2536+ u8 depth;
2537+} __attribute__ ((packed));
2538+
2539+#define UVESAFB_DEFAULT_MODE "640x480-16"
2540+
2541+/* How long to wait for a reply from userspace [ms] */
2542+#define UVESAFB_TIMEOUT 5000
2543+
2544+/* Max number of concurrent tasks */
2545+#define UVESAFB_TASKS_MAX 16
2546+
2547+#define dac_reg (0x3c8)
2548+#define dac_val (0x3c9)
2549+
2550+struct uvesafb_pal_entry {
2551+ u_char blue, green, red, pad;
2552+} __attribute__ ((packed));
2553+
2554+struct uvesafb_ktask {
2555+ struct uvesafb_task t;
2556+ void *buf;
2557+ struct completion *done;
2558+ u32 ack;
2559+};
2560+
2561+static int uvesafb_exec(struct uvesafb_ktask *tsk);
2562+
2563+#define UVESAFB_EXACT_RES 1
2564+#define UVESAFB_EXACT_DEPTH 2
2565+
2566+struct uvesafb_par {
2567+ struct vbe_ib vbe_ib; /* VBE Info Block */
2568+ struct vbe_mode_ib *vbe_modes; /* list of supported VBE modes */
2569+ int vbe_modes_cnt;
2570+
2571+ u8 nocrtc;
2572+ u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
2573+ u8 pmi_setpal; /* PMI for palette changes */
2574+ u16 *pmi_base; /* protected mode interface location */
2575+ void *pmi_start;
2576+ void *pmi_pal;
2577+ u8 *vbe_state_orig; /*
2578+ * original hardware state, before the
2579+ * driver was loaded
2580+ */
2581+ u8 *vbe_state_saved; /* state saved by fb_save_state */
2582+ int vbe_state_size;
2583+ atomic_t ref_count;
2584+
2585+ int mode_idx;
2586+ struct vbe_crtc_ib crtc;
2587+};
2588+
2589+#endif /* __KERNEL__ */
2590+#endif /* _UVESAFB_H */
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/versatile-armv6.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/versatile-armv6.patch
new file mode 100644
index 0000000000..e2d0060ac3
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/versatile-armv6.patch
@@ -0,0 +1,19 @@
1---
2 arch/arm/mm/Kconfig | 2 +-
3 1 file changed, 1 insertion(+), 1 deletion(-)
4
5--- linux-2.6.23.orig/arch/arm/mm/Kconfig
6+++ linux-2.6.23/arch/arm/mm/Kconfig
7@@ -343,11 +343,11 @@ config CPU_XSC3
8 select IO_36
9
10 # ARMv6
11 config CPU_V6
12 bool "Support ARM V6 processor"
13- depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3
14+ depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_VERSATILE_PB
15 default y if ARCH_MX3
16 select CPU_32v6
17 select CPU_ABRT_EV6
18 select CPU_CACHE_V6
19 select CPU_CACHE_VIPT
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/wm8750-treble.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm8750-treble.patch
new file mode 100644
index 0000000000..07a8d8e141
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm8750-treble.patch
@@ -0,0 +1,11 @@
1--- linux-2.6.23/sound/soc/codecs/wm8750.c 2007-10-09 22:31:38.000000000 +0200
2+++ linux-2.6.23/sound/soc/codecs/wm8750.c 2007-11-02 16:47:35.000000000 +0100
3@@ -189,7 +189,7 @@
4 SOC_ENUM("Bass Filter", wm8750_enum[1]),
5 SOC_SINGLE("Bass Volume", WM8750_BASS, 0, 15, 1),
6
7-SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 0),
8+SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 1),
9 SOC_ENUM("Treble Cut-off", wm8750_enum[2]),
10
11 SOC_SINGLE("3D Switch", WM8750_3D, 0, 1, 0),
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-reset-loop-r2.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-reset-loop-r2.patch
new file mode 100644
index 0000000000..78e81ea83a
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-reset-loop-r2.patch
@@ -0,0 +1,44 @@
1 sound/soc/codecs/wm9712.c | 28 ++++++++++++++++++----------
2 1 file changed, 18 insertions(+), 10 deletions(-)
3
4Index: git/sound/soc/codecs/wm9712.c
5===================================================================
6--- git.orig/sound/soc/codecs/wm9712.c 2006-11-07 22:10:01.000000000 +0000
7+++ git/sound/soc/codecs/wm9712.c 2006-11-07 22:11:50.000000000 +0000
8@@ -618,18 +618,26 @@ static int wm9712_dapm_event(struct snd_
9
10 static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
11 {
12- if (try_warm && soc_ac97_ops.warm_reset) {
13- soc_ac97_ops.warm_reset(codec->ac97);
14- if (!(ac97_read(codec, 0) & 0x8000))
15- return 1;
16- }
17+ int retry = 3;
18
19- soc_ac97_ops.reset(codec->ac97);
20- if (ac97_read(codec, 0) & 0x8000)
21- goto err;
22- return 0;
23+ while (retry--)
24+ {
25+ if(try_warm && soc_ac97_ops.warm_reset) {
26+ soc_ac97_ops.warm_reset(codec->ac97);
27+ if(ac97_read(codec, 0) & 0x8000)
28+ continue;
29+ else
30+ return 1;
31+ }
32+
33+ soc_ac97_ops.reset(codec->ac97);
34+ if(ac97_read(codec, 0) & 0x8000)
35+ continue;
36+ else
37+ return 0;
38+
39+ }
40
41-err:
42 printk(KERN_ERR "WM9712 AC97 reset failed\n");
43 return -EIO;
44 }
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-suspend-cold-res-r2.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-suspend-cold-res-r2.patch
new file mode 100644
index 0000000000..5179b47cc4
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm9712-suspend-cold-res-r2.patch
@@ -0,0 +1,16 @@
1 sound/soc/codecs/wm9712.c | 2 +-
2 1 file changed, 1 insertion(+), 1 deletion(-)
3
4Index: git/sound/soc/codecs/wm9712.c
5===================================================================
6--- git.orig/sound/soc/codecs/wm9712.c 2006-11-07 21:57:34.000000000 +0000
7+++ git/sound/soc/codecs/wm9712.c 2006-11-07 21:59:30.000000000 +0000
8@@ -651,7 +651,7 @@ static int wm9712_soc_resume(struct plat
9 int i, ret;
10 u16 *cache = codec->reg_cache;
11
12- ret = wm9712_reset(codec, 1);
13+ ret = wm9712_reset(codec, 0);
14 if (ret < 0){
15 printk(KERN_ERR "could not reset AC97 codec\n");
16 return ret;
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0-fix-r0.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0-fix-r0.patch
new file mode 100644
index 0000000000..5ad0d8703d
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0-fix-r0.patch
@@ -0,0 +1,128 @@
1 drivers/input/power.c | 2 +-
2 drivers/input/touchscreen/Kconfig | 2 +-
3 drivers/input/touchscreen/wm97xx-core.c | 35 ++++++++++++++++---------------
4 include/linux/wm97xx.h | 2 +-
5 4 files changed, 21 insertions(+), 20 deletions(-)
6
7diff --git a/drivers/input/power.c b/drivers/input/power.c
8index 4443e34..7aac875 100644
9--- a/drivers/input/power.c
10+++ b/drivers/input/power.c
11@@ -156,7 +156,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
12 }
13 }
14
15-static struct input_handle *power_connect(struct input_handler *handler,
16+static int power_connect(struct input_handler *handler,
17 struct input_dev *dev,
18 const struct input_device_id *id)
19 {
20diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
21index 6862e8f..9b532e9 100644
22--- a/drivers/input/touchscreen/Kconfig
23+++ b/drivers/input/touchscreen/Kconfig
24@@ -247,7 +247,7 @@ config TOUCHSCREEN_TSC2101
25
26 config TOUCHSCREEN_WM97XX
27 tristate "Support for WM97xx AC97 touchscreen controllers"
28- depends SND_AC97_BUS
29+ depends AC97_BUS
30
31 choice
32 prompt "WM97xx codec type"
33diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
34index 9b2710e..d3ce3f3 100644
35--- a/drivers/input/touchscreen/wm97xx-core.c
36+++ b/drivers/input/touchscreen/wm97xx-core.c
37@@ -84,6 +84,7 @@
38 #include <linux/bitops.h>
39 #include <linux/workqueue.h>
40 #include <linux/device.h>
41+#include <linux/freezer.h>
42 #include <linux/wm97xx.h>
43 #include <asm/uaccess.h>
44 #include <asm/io.h>
45@@ -241,14 +242,15 @@ WM97XX_STATUS_ATTR(gpio);
46
47 static int wm97xx_sys_add(struct device *dev)
48 {
49+ int err;
50 if (aux_sys) {
51- device_create_file(dev, &dev_attr_aux1);
52- device_create_file(dev, &dev_attr_aux2);
53- device_create_file(dev, &dev_attr_aux3);
54- device_create_file(dev, &dev_attr_aux4);
55+ err = device_create_file(dev, &dev_attr_aux1);
56+ err = device_create_file(dev, &dev_attr_aux2);
57+ err = device_create_file(dev, &dev_attr_aux3);
58+ err = device_create_file(dev, &dev_attr_aux4);
59 }
60 if (status_sys)
61- device_create_file(dev, &dev_attr_gpio);
62+ err = device_create_file(dev, &dev_attr_gpio);
63 return 0;
64 }
65
66@@ -366,12 +368,12 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, wm97xx_gpio_dir_t dir,
67
68 /*
69 * Handle a pen down interrupt.
70- */
71-static void wm97xx_pen_irq_worker(void *ptr)
72-{
73- struct wm97xx *wm = (struct wm97xx *) ptr;
74-
75- /* do we need to enable the touch panel reader */
76+ */
77+static void wm97xx_pen_irq_worker(struct work_struct *work)
78+{
79+ struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work);
80+
81+ /* do we need to enable the touch panel reader */
82 if (wm->id == WM9705_ID2) {
83 if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & WM97XX_PEN_DOWN)
84 wm->pen_is_down = 1;
85@@ -411,9 +413,8 @@ static void wm97xx_pen_irq_worker(void *ptr)
86 * We have to disable the codec interrupt in the handler because it can
87 * take upto 1ms to clear the interrupt source. The interrupt is then enabled
88 * again in the slow handler when the source has been cleared.
89- */
90-static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id,
91- struct pt_regs *regs)
92+ */
93+static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id)
94 {
95 struct wm97xx *wm = (struct wm97xx *) dev_id;
96 disable_irq(wm->pen_irq);
97@@ -428,15 +429,15 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm)
98 {
99 u16 reg;
100
101- INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker, wm);
102- if ((wm->pen_irq_workq =
103+ INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker);
104+ if ((wm->pen_irq_workq =
105 create_singlethread_workqueue("kwm97pen")) == NULL) {
106 err("could not create pen irq work queue");
107 wm->pen_irq = 0;
108 return -EINVAL;
109 }
110
111- if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) {
112+ if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, "wm97xx-pen", wm)) {
113 err("could not register codec pen down interrupt, will poll for pen down");
114 destroy_workqueue(wm->pen_irq_workq);
115 wm->pen_irq = 0;
116diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h
117index b1c1740..a9bd57e 100644
118--- a/include/linux/wm97xx.h
119+++ b/include/linux/wm97xx.h
120@@ -243,7 +243,7 @@ struct wm97xx {
121 u16 dig_save[3]; /* saved during aux reading */
122 struct wm97xx_codec_drv *codec; /* attached codec driver*/
123 struct input_dev* input_dev; /* touchscreen input device */
124- ac97_t *ac97; /* ALSA codec access */
125+ struct snd_ac97 *ac97; /* ALSA codec access */
126 struct device *dev; /* ALSA device */
127 struct device *battery_dev;
128 struct device *touch_dev;
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch
new file mode 100644
index 0000000000..c918c5daff
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/wm97xx-lg13-r0.patch
@@ -0,0 +1,2899 @@
1Index: linux-2.6.17/drivers/input/touchscreen/Kconfig
2===================================================================
3--- linux-2.6.17.orig/drivers/input/touchscreen/Kconfig 2006-09-19 20:35:35.060495500 +0200
4+++ linux-2.6.17/drivers/input/touchscreen/Kconfig 2006-09-19 20:36:47.965051750 +0200
5@@ -121,4 +121,57 @@ config TOUCHSCREEN_TSC2101
6 To compile this driver as a module, choose M here: the
7 module will be called ads7846_ts.
8
9+config TOUCHSCREEN_WM97XX
10+ tristate "Support for WM97xx AC97 touchscreen controllers"
11+ depends SND_AC97_BUS
12+
13+choice
14+ prompt "WM97xx codec type"
15+
16+config TOUCHSCREEN_WM9705
17+ bool "WM9705 Touchscreen interface support"
18+ depends on TOUCHSCREEN_WM97XX
19+ help
20+ Say Y here if you have the wm9705 touchscreen.
21+
22+ If unsure, say N.
23+
24+ To compile this driver as a module, choose M here: the
25+ module will be called wm9705.
26+
27+config TOUCHSCREEN_WM9712
28+ bool "WM9712 Touchscreen interface support"
29+ depends on TOUCHSCREEN_WM97XX
30+ help
31+ Say Y here if you have the wm9712 touchscreen.
32+
33+ If unsure, say N.
34+
35+ To compile this driver as a module, choose M here: the
36+ module will be called wm9712.
37+
38+config TOUCHSCREEN_WM9713
39+ bool "WM9713 Touchscreen interface support"
40+ depends on TOUCHSCREEN_WM97XX
41+ help
42+ Say Y here if you have the wm9713 touchscreen.
43+
44+ If unsure, say N.
45+
46+ To compile this driver as a module, choose M here: the
47+ module will be called wm9713.
48+
49+endchoice
50+
51+config TOUCHSCREEN_WM97XX_PXA
52+ tristate "WM97xx PXA accelerated touch"
53+ depends on TOUCHSCREEN_WM97XX && ARCH_PXA
54+ help
55+ Say Y here for continuous mode touch on the PXA
56+
57+ If unsure, say N
58+
59+ To compile this driver as a module, choose M here: the
60+ module will be called pxa-wm97xx
61+
62 endif
63Index: linux-2.6.17/drivers/input/touchscreen/Makefile
64===================================================================
65--- linux-2.6.17.orig/drivers/input/touchscreen/Makefile 2006-09-19 20:35:35.072496250 +0200
66+++ linux-2.6.17/drivers/input/touchscreen/Makefile 2006-09-19 20:37:40.540337500 +0200
67@@ -4,6 +4,8 @@
68
69 # Each configuration option enables a list of files.
70
71+wm97xx-ts-objs := wm97xx-core.o
72+
73 obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
74 obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
75 obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
76@@ -13,3 +15,16 @@ obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtou
77 obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
78 obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
79 obj-$(CONFIG_TOUCHSCREEN_TSC2101) += tsc2101_ts.o
80+obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
81+obj-$(CONFIG_TOUCHSCREEN_WM97XX_PXA) += pxa-wm97xx.o
82+
83+ifeq ($(CONFIG_TOUCHSCREEN_WM9713),y)
84+wm97xx-ts-objs += wm9713.o
85+endif
86+
87+ifeq ($(CONFIG_TOUCHSCREEN_WM9712),y)
88+wm97xx-ts-objs += wm9712.o
89+endif
90+ifeq ($(CONFIG_TOUCHSCREEN_WM9705),y)
91+wm97xx-ts-objs += wm9705.o
92+endif
93Index: linux-2.6.17/drivers/input/touchscreen/pxa-wm97xx.c
94===================================================================
95--- /dev/null 1970-01-01 00:00:00.000000000 +0000
96+++ linux-2.6.17/drivers/input/touchscreen/pxa-wm97xx.c 2006-09-19 20:36:47.965051750 +0200
97@@ -0,0 +1,289 @@
98+/*
99+ * pxa-wm97xx.c -- pxa-wm97xx Continuous Touch screen driver for
100+ * Wolfson WM97xx AC97 Codecs.
101+ *
102+ * Copyright 2004 Wolfson Microelectronics PLC.
103+ * Author: Liam Girdwood
104+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
105+ * Parts Copyright : Ian Molton <spyro@f2s.com>
106+ * Andrew Zabolotny <zap@homelink.ru>
107+ *
108+ * This program is free software; you can redistribute it and/or modify it
109+ * under the terms of the GNU General Public License as published by the
110+ * Free Software Foundation; either version 2 of the License, or (at your
111+ * option) any later version.
112+ *
113+ * Notes:
114+ * This is a wm97xx extended touch driver to capture touch
115+ * data in a continuous manner on the Intel XScale archictecture
116+ *
117+ * Features:
118+ * - codecs supported:- WM9705, WM9712, WM9713
119+ * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
120+ *
121+ * Revision history
122+ * 18th Aug 2004 Initial version.
123+ * 26th Jul 2005 Improved continous read back and added FIFO flushing.
124+ * 06th Sep 2005 Mike Arthur <linux@wolfsonmicro.com>
125+ * Moved to using the wm97xx bus
126+ *
127+ */
128+
129+#include <linux/module.h>
130+#include <linux/moduleparam.h>
131+#include <linux/version.h>
132+#include <linux/kernel.h>
133+#include <linux/init.h>
134+#include <linux/delay.h>
135+#include <linux/irq.h>
136+#include <linux/wm97xx.h>
137+#include <asm/io.h>
138+#include <asm/arch/pxa-regs.h>
139+
140+#define VERSION "0.13"
141+
142+struct continuous {
143+ u16 id; /* codec id */
144+ u8 code; /* continuous code */
145+ u8 reads; /* number of coord reads per read cycle */
146+ u32 speed; /* number of coords per second */
147+};
148+
149+#define WM_READS(sp) ((sp / HZ) + 1)
150+
151+static const struct continuous cinfo[] = {
152+ {WM9705_ID2, 0, WM_READS(94), 94},
153+ {WM9705_ID2, 1, WM_READS(188), 188},
154+ {WM9705_ID2, 2, WM_READS(375), 375},
155+ {WM9705_ID2, 3, WM_READS(750), 750},
156+ {WM9712_ID2, 0, WM_READS(94), 94},
157+ {WM9712_ID2, 1, WM_READS(188), 188},
158+ {WM9712_ID2, 2, WM_READS(375), 375},
159+ {WM9712_ID2, 3, WM_READS(750), 750},
160+ {WM9713_ID2, 0, WM_READS(94), 94},
161+ {WM9713_ID2, 1, WM_READS(120), 120},
162+ {WM9713_ID2, 2, WM_READS(154), 154},
163+ {WM9713_ID2, 3, WM_READS(188), 188},
164+};
165+
166+/* continuous speed index */
167+static int sp_idx = 0;
168+static u16 last = 0, tries = 0;
169+
170+/*
171+ * Pen sampling frequency (Hz) in continuous mode.
172+ */
173+static int cont_rate = 200;
174+module_param(cont_rate, int, 0);
175+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
176+
177+/*
178+ * Pen down detection.
179+ *
180+ * This driver can either poll or use an interrupt to indicate a pen down
181+ * event. If the irq request fails then it will fall back to polling mode.
182+ */
183+static int pen_int = 1;
184+module_param(pen_int, int, 0);
185+MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
186+
187+/*
188+ * Pressure readback.
189+ *
190+ * Set to 1 to read back pen down pressure
191+ */
192+static int pressure = 0;
193+module_param(pressure, int, 0);
194+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
195+
196+/*
197+ * AC97 touch data slot.
198+ *
199+ * Touch screen readback data ac97 slot
200+ */
201+static int ac97_touch_slot = 5;
202+module_param(ac97_touch_slot, int, 0);
203+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
204+
205+
206+/* flush AC97 slot 5 FIFO on pxa machines */
207+#ifdef CONFIG_PXA27x
208+void wm97xx_acc_pen_up (struct wm97xx* wm)
209+{
210+ set_current_state(TASK_INTERRUPTIBLE);
211+ schedule_timeout(1);
212+
213+ while (MISR & (1 << 2))
214+ MODR;
215+}
216+#else
217+void wm97xx_acc_pen_up (struct wm97xx* wm)
218+{
219+ int count = 16;
220+ set_current_state(TASK_INTERRUPTIBLE);
221+ schedule_timeout(1);
222+
223+ while (count < 16) {
224+ MODR;
225+ count--;
226+ }
227+}
228+#endif
229+
230+int wm97xx_acc_pen_down (struct wm97xx* wm)
231+{
232+ u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
233+ int reads = 0;
234+
235+ /* data is never immediately available after pen down irq */
236+ set_current_state(TASK_INTERRUPTIBLE);
237+ schedule_timeout(1);
238+
239+ if (tries > 5){
240+ tries = 0;
241+ return RC_PENUP;
242+ }
243+
244+ x = MODR;
245+ if (x == last) {
246+ tries++;
247+ return RC_AGAIN;
248+ }
249+ last = x;
250+ do {
251+ if (reads)
252+ x= MODR;
253+ y= MODR;
254+ if (pressure)
255+ p = MODR;
256+
257+ /* are samples valid */
258+ if ((x & 0x7000) != WM97XX_ADCSEL_X ||
259+ (y & 0x7000) != WM97XX_ADCSEL_Y ||
260+ (p & 0x7000) != WM97XX_ADCSEL_PRES)
261+ goto up;
262+
263+ /* coordinate is good */
264+ tries = 0;
265+ //printk("x %x y %x p %x\n", x,y,p);
266+ input_report_abs (wm->input_dev, ABS_X, x & 0xfff);
267+ input_report_abs (wm->input_dev, ABS_Y, y & 0xfff);
268+ input_report_abs (wm->input_dev, ABS_PRESSURE, p & 0xfff);
269+ input_sync (wm->input_dev);
270+ reads++;
271+ } while (reads < cinfo[sp_idx].reads);
272+up:
273+ return RC_PENDOWN | RC_AGAIN;
274+}
275+
276+int wm97xx_acc_startup(struct wm97xx* wm)
277+{
278+ int idx = 0;
279+
280+ /* check we have a codec */
281+ if (wm->ac97 == NULL)
282+ return -ENODEV;
283+
284+ /* Go you big red fire engine */
285+ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
286+ if (wm->id != cinfo[idx].id)
287+ continue;
288+ sp_idx = idx;
289+ if (cont_rate <= cinfo[idx].speed)
290+ break;
291+ }
292+ wm->acc_rate = cinfo[sp_idx].code;
293+ wm->acc_slot = ac97_touch_slot;
294+ printk(KERN_INFO "pxa2xx accelerated touchscreen driver, %d samples (sec)\n",
295+ cinfo[sp_idx].speed);
296+
297+ /* codec specific irq config */
298+ if (pen_int) {
299+ switch (wm->id) {
300+ case WM9705_ID2:
301+ wm->pen_irq = IRQ_GPIO(4);
302+ set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE);
303+ break;
304+ case WM9712_ID2:
305+ case WM9713_ID2:
306+ /* enable pen down interrupt */
307+ /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
308+ wm->pen_irq = MAINSTONE_AC97_IRQ;
309+ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
310+ WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_STICKY, WM97XX_GPIO_WAKE);
311+ wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
312+ WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_NOTSTICKY, WM97XX_GPIO_NOWAKE);
313+ break;
314+ default:
315+ printk(KERN_WARNING "pen down irq not supported on this device\n");
316+ pen_int = 0;
317+ break;
318+ }
319+ }
320+
321+ return 0;
322+}
323+
324+void wm97xx_acc_shutdown(struct wm97xx* wm)
325+{
326+ /* codec specific deconfig */
327+ if (pen_int) {
328+ switch (wm->id & 0xffff) {
329+ case WM9705_ID2:
330+ wm->pen_irq = 0;
331+ break;
332+ case WM9712_ID2:
333+ case WM9713_ID2:
334+ /* disable interrupt */
335+ wm->pen_irq = 0;
336+ break;
337+ }
338+ }
339+}
340+
341+static struct wm97xx_mach_ops pxa_mach_ops = {
342+ .acc_enabled = 1,
343+ .acc_pen_up = wm97xx_acc_pen_up,
344+ .acc_pen_down = wm97xx_acc_pen_down,
345+ .acc_startup = wm97xx_acc_startup,
346+ .acc_shutdown = wm97xx_acc_shutdown,
347+};
348+
349+int pxa_wm97xx_probe(struct device *dev)
350+{
351+ struct wm97xx *wm = dev->driver_data;
352+ return wm97xx_register_mach_ops (wm, &pxa_mach_ops);
353+}
354+
355+int pxa_wm97xx_remove(struct device *dev)
356+{
357+ struct wm97xx *wm = dev->driver_data;
358+ wm97xx_unregister_mach_ops (wm);
359+ return 0;
360+}
361+
362+static struct device_driver pxa_wm97xx_driver = {
363+ .name = "wm97xx-touchscreen",
364+ .bus = &wm97xx_bus_type,
365+ .owner = THIS_MODULE,
366+ .probe = pxa_wm97xx_probe,
367+ .remove = pxa_wm97xx_remove
368+};
369+
370+static int __init pxa_wm97xx_init(void)
371+{
372+ return driver_register(&pxa_wm97xx_driver);
373+}
374+
375+static void __exit pxa_wm97xx_exit(void)
376+{
377+ driver_unregister(&pxa_wm97xx_driver);
378+}
379+
380+module_init(pxa_wm97xx_init);
381+module_exit(pxa_wm97xx_exit);
382+
383+/* Module information */
384+MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
385+MODULE_DESCRIPTION("wm97xx continuous touch driver for pxa2xx");
386+MODULE_LICENSE("GPL");
387Index: linux-2.6.17/drivers/input/touchscreen/wm9705.c
388===================================================================
389--- /dev/null 1970-01-01 00:00:00.000000000 +0000
390+++ linux-2.6.17/drivers/input/touchscreen/wm9705.c 2006-09-19 20:36:47.969052000 +0200
391@@ -0,0 +1,360 @@
392+/*
393+ * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
394+ *
395+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
396+ * Author: Liam Girdwood
397+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
398+ * Parts Copyright : Ian Molton <spyro@f2s.com>
399+ * Andrew Zabolotny <zap@homelink.ru>
400+ * Russell King <rmk@arm.linux.org.uk>
401+ *
402+ * This program is free software; you can redistribute it and/or modify it
403+ * under the terms of the GNU General Public License as published by the
404+ * Free Software Foundation; either version 2 of the License, or (at your
405+ * option) any later version.
406+ *
407+ * Revision history
408+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
409+ * Added pre and post sample calls.
410+ *
411+ */
412+
413+#include <linux/module.h>
414+#include <linux/moduleparam.h>
415+#include <linux/version.h>
416+#include <linux/kernel.h>
417+#include <linux/input.h>
418+#include <linux/delay.h>
419+#include <linux/bitops.h>
420+#include <linux/wm97xx.h>
421+
422+#define TS_NAME "wm97xx"
423+#define WM9705_VERSION "0.62"
424+#define DEFAULT_PRESSURE 0xb0c0
425+
426+/*
427+ * Debug
428+ */
429+#if 0
430+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
431+#else
432+#define dbg(format, arg...)
433+#endif
434+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
435+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
436+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
437+
438+/*
439+ * Module parameters
440+ */
441+
442+/*
443+ * Set current used for pressure measurement.
444+ *
445+ * Set pil = 2 to use 400uA
446+ * pil = 1 to use 200uA and
447+ * pil = 0 to disable pressure measurement.
448+ *
449+ * This is used to increase the range of values returned by the adc
450+ * when measureing touchpanel pressure.
451+ */
452+static int pil = 0;
453+module_param(pil, int, 0);
454+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
455+
456+/*
457+ * Set threshold for pressure measurement.
458+ *
459+ * Pen down pressure below threshold is ignored.
460+ */
461+static int pressure = DEFAULT_PRESSURE & 0xfff;
462+module_param(pressure, int, 0);
463+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
464+
465+/*
466+ * Set adc sample delay.
467+ *
468+ * For accurate touchpanel measurements, some settling time may be
469+ * required between the switch matrix applying a voltage across the
470+ * touchpanel plate and the ADC sampling the signal.
471+ *
472+ * This delay can be set by setting delay = n, where n is the array
473+ * position of the delay in the array delay_table below.
474+ * Long delays > 1ms are supported for completeness, but are not
475+ * recommended.
476+ */
477+static int delay = 4;
478+module_param(delay, int, 0);
479+MODULE_PARM_DESC(delay, "Set adc sample delay.");
480+
481+/*
482+ * Pen detect comparator threshold.
483+ *
484+ * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold
485+ * i.e. 1 = Vmid/15 threshold
486+ * 15 = Vmid/1 threshold
487+ *
488+ * Adjust this value if you are having problems with pen detect not
489+ * detecting any down events.
490+ */
491+static int pdd = 8;
492+module_param(pdd, int, 0);
493+MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold");
494+
495+/*
496+ * Set adc mask function.
497+ *
498+ * Sources of glitch noise, such as signals driving an LCD display, may feed
499+ * through to the touch screen plates and affect measurement accuracy. In
500+ * order to minimise this, a signal may be applied to the MASK pin to delay or
501+ * synchronise the sampling.
502+ *
503+ * 0 = No delay or sync
504+ * 1 = High on pin stops conversions
505+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
506+ * 3 = Edge triggered, edge on pin starts conversion after delay param
507+ */
508+static int mask = 0;
509+module_param(mask, int, 0);
510+MODULE_PARM_DESC(mask, "Set adc mask function.");
511+
512+/*
513+ * ADC sample delay times in uS
514+ */
515+static const int delay_table[] = {
516+ 21, // 1 AC97 Link frames
517+ 42, // 2
518+ 84, // 4
519+ 167, // 8
520+ 333, // 16
521+ 667, // 32
522+ 1000, // 48
523+ 1333, // 64
524+ 2000, // 96
525+ 2667, // 128
526+ 3333, // 160
527+ 4000, // 192
528+ 4667, // 224
529+ 5333, // 256
530+ 6000, // 288
531+ 0 // No delay, switch matrix always on
532+};
533+
534+/*
535+ * Delay after issuing a POLL command.
536+ *
537+ * The delay is 3 AC97 link frames + the touchpanel settling delay
538+ */
539+static inline void poll_delay(int d)
540+{
541+ udelay (3 * AC97_LINK_FRAME + delay_table [d]);
542+}
543+
544+/*
545+ * set up the physical settings of the WM9705
546+ */
547+static void init_wm9705_phy(struct wm97xx* wm)
548+{
549+ u16 dig1 = 0, dig2 = WM97XX_RPR;
550+
551+ /*
552+ * mute VIDEO and AUX as they share X and Y touchscreen
553+ * inputs on the WM9705
554+ */
555+ wm97xx_reg_write(wm, AC97_AUX, 0x8000);
556+ wm97xx_reg_write(wm, AC97_VIDEO, 0x8000);
557+
558+ /* touchpanel pressure current*/
559+ if (pil == 2) {
560+ dig2 |= WM9705_PIL;
561+ dbg("setting pressure measurement current to 400uA.");
562+ } else if (pil)
563+ dbg("setting pressure measurement current to 200uA.");
564+ if(!pil)
565+ pressure = 0;
566+
567+ /* polling mode sample settling delay */
568+ if (delay!=4) {
569+ if (delay < 0 || delay > 15) {
570+ dbg("supplied delay out of range.");
571+ delay = 4;
572+ }
573+ }
574+ dig1 &= 0xff0f;
575+ dig1 |= WM97XX_DELAY(delay);
576+ dbg("setting adc sample delay to %d u Secs.", delay_table[delay]);
577+
578+ /* WM9705 pdd */
579+ dig2 |= (pdd & 0x000f);
580+ dbg("setting pdd to Vmid/%d", 1 - (pdd & 0x000f));
581+
582+ /* mask */
583+ dig2 |= ((mask & 0x3) << 4);
584+
585+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
586+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
587+}
588+
589+static int wm9705_digitiser_ioctl(struct wm97xx* wm, int cmd)
590+{
591+ switch(cmd) {
592+ case WM97XX_DIG_START:
593+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] | WM97XX_PRP_DET_DIG);
594+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
595+ break;
596+ case WM97XX_DIG_STOP:
597+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] & ~WM97XX_PRP_DET_DIG);
598+ break;
599+ case WM97XX_AUX_PREPARE:
600+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
601+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
602+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
603+ break;
604+ case WM97XX_DIG_RESTORE:
605+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
606+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
607+ break;
608+ case WM97XX_PHY_INIT:
609+ init_wm9705_phy(wm);
610+ break;
611+ default:
612+ return -EINVAL;
613+ }
614+ return 0;
615+}
616+
617+static inline int is_pden (struct wm97xx* wm)
618+{
619+ return wm->dig[2] & WM9705_PDEN;
620+}
621+
622+/*
623+ * Read a sample from the WM9705 adc in polling mode.
624+ */
625+static int wm9705_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
626+{
627+ int timeout = 5 * delay;
628+
629+ if (!wm->pen_probably_down) {
630+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
631+ if (!(data & WM97XX_PEN_DOWN))
632+ return RC_PENUP;
633+ wm->pen_probably_down = 1;
634+ }
635+
636+ /* set up digitiser */
637+ if (adcsel & 0x8000)
638+ adcsel = ((adcsel & 0x7fff) + 3) << 12;
639+
640+ if (wm->mach_ops && wm->mach_ops->pre_sample)
641+ wm->mach_ops->pre_sample(adcsel);
642+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
643+
644+ /* wait 3 AC97 time slots + delay for conversion */
645+ poll_delay (delay);
646+
647+ /* wait for POLL to go low */
648+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
649+ udelay(AC97_LINK_FRAME);
650+ timeout--;
651+ }
652+
653+ if (timeout <= 0) {
654+ /* If PDEN is set, we can get a timeout when pen goes up */
655+ if (is_pden(wm))
656+ wm->pen_probably_down = 0;
657+ else
658+ dbg ("adc sample timeout");
659+ return RC_PENUP;
660+ }
661+
662+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
663+ if (wm->mach_ops && wm->mach_ops->post_sample)
664+ wm->mach_ops->post_sample(adcsel);
665+
666+ /* check we have correct sample */
667+ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
668+ dbg ("adc wrong sample, read %x got %x", adcsel,
669+ *sample & WM97XX_ADCSEL_MASK);
670+ return RC_PENUP;
671+ }
672+
673+ if (!(*sample & WM97XX_PEN_DOWN)) {
674+ wm->pen_probably_down = 0;
675+ return RC_PENUP;
676+ }
677+
678+ return RC_VALID;
679+}
680+
681+/*
682+ * Sample the WM9705 touchscreen in polling mode
683+ */
684+static int wm9705_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
685+{
686+ int rc;
687+
688+ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
689+ return rc;
690+ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
691+ return rc;
692+ if (pil) {
693+ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
694+ return rc;
695+ } else
696+ data->p = DEFAULT_PRESSURE;
697+
698+ return RC_VALID;
699+}
700+
701+/*
702+ * Enable WM9705 continuous mode, i.e. touch data is streamed across an AC97 slot
703+ */
704+static int wm9705_acc_enable (struct wm97xx* wm, int enable)
705+{
706+ u16 dig1, dig2;
707+ int ret = 0;
708+
709+ dig1 = wm->dig[1];
710+ dig2 = wm->dig[2];
711+
712+ if (enable) {
713+ /* continous mode */
714+ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0)
715+ return ret;
716+ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
717+ WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
718+ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
719+ WM97XX_DELAY (delay) |
720+ WM97XX_SLT (wm->acc_slot) |
721+ WM97XX_RATE (wm->acc_rate);
722+ if (pil)
723+ dig1 |= WM97XX_ADCSEL_PRES;
724+ dig2 |= WM9705_PDEN;
725+ } else {
726+ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
727+ dig2 &= ~WM9705_PDEN;
728+ if (wm->mach_ops->acc_shutdown)
729+ wm->mach_ops->acc_shutdown(wm);
730+ }
731+
732+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
733+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
734+ return ret;
735+}
736+
737+struct wm97xx_codec_drv wm97xx_codec = {
738+ .id = WM9705_ID2,
739+ .name = "wm9705",
740+ .poll_sample = wm9705_poll_sample,
741+ .poll_touch = wm9705_poll_touch,
742+ .acc_enable = wm9705_acc_enable,
743+ .digitiser_ioctl = wm9705_digitiser_ioctl,
744+};
745+
746+EXPORT_SYMBOL_GPL(wm97xx_codec);
747+
748+/* Module information */
749+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
750+MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
751+MODULE_LICENSE("GPL");
752Index: linux-2.6.17/drivers/input/touchscreen/wm9712.c
753===================================================================
754--- /dev/null 1970-01-01 00:00:00.000000000 +0000
755+++ linux-2.6.17/drivers/input/touchscreen/wm9712.c 2006-09-19 20:36:47.969052000 +0200
756@@ -0,0 +1,464 @@
757+/*
758+ * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
759+ *
760+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
761+ * Author: Liam Girdwood
762+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
763+ * Parts Copyright : Ian Molton <spyro@f2s.com>
764+ * Andrew Zabolotny <zap@homelink.ru>
765+ * Russell King <rmk@arm.linux.org.uk>
766+ *
767+ * This program is free software; you can redistribute it and/or modify it
768+ * under the terms of the GNU General Public License as published by the
769+ * Free Software Foundation; either version 2 of the License, or (at your
770+ * option) any later version.
771+ *
772+ * Revision history
773+ * 4th Jul 2005 Initial version.
774+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
775+ * Added pre and post sample calls.
776+ *
777+ */
778+
779+#include <linux/module.h>
780+#include <linux/moduleparam.h>
781+#include <linux/version.h>
782+#include <linux/kernel.h>
783+#include <linux/input.h>
784+#include <linux/delay.h>
785+#include <linux/bitops.h>
786+#include <linux/wm97xx.h>
787+
788+#define TS_NAME "wm97xx"
789+#define WM9712_VERSION "0.61"
790+#define DEFAULT_PRESSURE 0xb0c0
791+
792+/*
793+ * Debug
794+ */
795+#if 0
796+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
797+#else
798+#define dbg(format, arg...)
799+#endif
800+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
801+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
802+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
803+
804+/*
805+ * Module parameters
806+ */
807+
808+/*
809+ * Set internal pull up for pen detect.
810+ *
811+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
812+ * i.e. pull up resistance = 64k Ohms / rpu.
813+ *
814+ * Adjust this value if you are having problems with pen detect not
815+ * detecting any down event.
816+ */
817+static int rpu = 3;
818+module_param(rpu, int, 0);
819+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
820+
821+/*
822+ * Set current used for pressure measurement.
823+ *
824+ * Set pil = 2 to use 400uA
825+ * pil = 1 to use 200uA and
826+ * pil = 0 to disable pressure measurement.
827+ *
828+ * This is used to increase the range of values returned by the adc
829+ * when measureing touchpanel pressure.
830+ */
831+static int pil = 0;
832+module_param(pil, int, 0);
833+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
834+
835+/*
836+ * Set threshold for pressure measurement.
837+ *
838+ * Pen down pressure below threshold is ignored.
839+ */
840+static int pressure = DEFAULT_PRESSURE & 0xfff;
841+module_param(pressure, int, 0);
842+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
843+
844+/*
845+ * Set adc sample delay.
846+ *
847+ * For accurate touchpanel measurements, some settling time may be
848+ * required between the switch matrix applying a voltage across the
849+ * touchpanel plate and the ADC sampling the signal.
850+ *
851+ * This delay can be set by setting delay = n, where n is the array
852+ * position of the delay in the array delay_table below.
853+ * Long delays > 1ms are supported for completeness, but are not
854+ * recommended.
855+ */
856+static int delay = 3;
857+module_param(delay, int, 0);
858+MODULE_PARM_DESC(delay, "Set adc sample delay.");
859+
860+/*
861+ * Set five_wire = 1 to use a 5 wire touchscreen.
862+ *
863+ * NOTE: Five wire mode does not allow for readback of pressure.
864+ */
865+static int five_wire;
866+module_param(five_wire, int, 0);
867+MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
868+
869+/*
870+ * Set adc mask function.
871+ *
872+ * Sources of glitch noise, such as signals driving an LCD display, may feed
873+ * through to the touch screen plates and affect measurement accuracy. In
874+ * order to minimise this, a signal may be applied to the MASK pin to delay or
875+ * synchronise the sampling.
876+ *
877+ * 0 = No delay or sync
878+ * 1 = High on pin stops conversions
879+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
880+ * 3 = Edge triggered, edge on pin starts conversion after delay param
881+ */
882+static int mask = 0;
883+module_param(mask, int, 0);
884+MODULE_PARM_DESC(mask, "Set adc mask function.");
885+
886+/*
887+ * Coordinate Polling Enable.
888+ *
889+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
890+ * for every poll.
891+ */
892+static int coord = 0;
893+module_param(coord, int, 0);
894+MODULE_PARM_DESC(coord, "Polling coordinate mode");
895+
896+/*
897+ * ADC sample delay times in uS
898+ */
899+static const int delay_table[] = {
900+ 21, // 1 AC97 Link frames
901+ 42, // 2
902+ 84, // 4
903+ 167, // 8
904+ 333, // 16
905+ 667, // 32
906+ 1000, // 48
907+ 1333, // 64
908+ 2000, // 96
909+ 2667, // 128
910+ 3333, // 160
911+ 4000, // 192
912+ 4667, // 224
913+ 5333, // 256
914+ 6000, // 288
915+ 0 // No delay, switch matrix always on
916+};
917+
918+/*
919+ * Delay after issuing a POLL command.
920+ *
921+ * The delay is 3 AC97 link frames + the touchpanel settling delay
922+ */
923+static inline void poll_delay(int d)
924+{
925+ udelay (3 * AC97_LINK_FRAME + delay_table [d]);
926+}
927+
928+/*
929+ * set up the physical settings of the WM9712
930+ */
931+static void init_wm9712_phy(struct wm97xx* wm)
932+{
933+ u16 dig1 = 0;
934+ u16 dig2 = WM97XX_RPR | WM9712_RPU(1);
935+
936+ /* WM9712 rpu */
937+ if (rpu) {
938+ dig2 &= 0xffc0;
939+ dig2 |= WM9712_RPU(rpu);
940+ dbg("setting pen detect pull-up to %d Ohms",64000 / rpu);
941+ }
942+
943+ /* touchpanel pressure current*/
944+ if (pil == 2) {
945+ dig2 |= WM9712_PIL;
946+ dbg("setting pressure measurement current to 400uA.");
947+ } else if (pil)
948+ dbg("setting pressure measurement current to 200uA.");
949+ if(!pil)
950+ pressure = 0;
951+
952+ /* WM9712 five wire */
953+ if (five_wire) {
954+ dig2 |= WM9712_45W;
955+ dbg("setting 5-wire touchscreen mode.");
956+ }
957+
958+ /* polling mode sample settling delay */
959+ if (delay < 0 || delay > 15) {
960+ dbg("supplied delay out of range.");
961+ delay = 4;
962+ }
963+ dig1 &= 0xff0f;
964+ dig1 |= WM97XX_DELAY(delay);
965+ dbg("setting adc sample delay to %d u Secs.", delay_table[delay]);
966+
967+ /* mask */
968+ dig2 |= ((mask & 0x3) << 6);
969+ if (mask) {
970+ u16 reg;
971+ /* Set GPIO4 as Mask Pin*/
972+ reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
973+ wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4);
974+ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
975+ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4);
976+ }
977+
978+ /* wait - coord mode */
979+ if(coord)
980+ dig2 |= WM9712_WAIT;
981+
982+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
983+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
984+}
985+
986+static int wm9712_digitiser_ioctl(struct wm97xx* wm, int cmd)
987+{
988+ u16 dig2 = wm->dig[2];
989+
990+ switch(cmd) {
991+ case WM97XX_DIG_START:
992+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 | WM97XX_PRP_DET_DIG);
993+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
994+ break;
995+ case WM97XX_DIG_STOP:
996+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 & ~WM97XX_PRP_DET_DIG);
997+ break;
998+ case WM97XX_AUX_PREPARE:
999+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
1000+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
1001+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
1002+ break;
1003+ case WM97XX_DIG_RESTORE:
1004+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
1005+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
1006+ break;
1007+ case WM97XX_PHY_INIT:
1008+ init_wm9712_phy(wm);
1009+ break;
1010+ default:
1011+ return -EINVAL;
1012+ }
1013+ return 0;
1014+}
1015+
1016+static inline int is_pden (struct wm97xx* wm)
1017+{
1018+ return wm->dig[2] & WM9712_PDEN;
1019+}
1020+
1021+/*
1022+ * Read a sample from the WM9712 adc in polling mode.
1023+ */
1024+static int wm9712_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
1025+{
1026+ int timeout = 5 * delay;
1027+
1028+ if (!wm->pen_probably_down) {
1029+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1030+ if (!(data & WM97XX_PEN_DOWN))
1031+ return RC_PENUP;
1032+ wm->pen_probably_down = 1;
1033+ }
1034+
1035+ /* set up digitiser */
1036+ if (adcsel & 0x8000)
1037+ adcsel = ((adcsel & 0x7fff) + 3) << 12;
1038+
1039+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1040+ wm->mach_ops->pre_sample(adcsel);
1041+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
1042+
1043+ /* wait 3 AC97 time slots + delay for conversion */
1044+ poll_delay (delay);
1045+
1046+ /* wait for POLL to go low */
1047+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
1048+ udelay(AC97_LINK_FRAME);
1049+ timeout--;
1050+ }
1051+
1052+ if (timeout <= 0) {
1053+ /* If PDEN is set, we can get a timeout when pen goes up */
1054+ if (is_pden(wm))
1055+ wm->pen_probably_down = 0;
1056+ else
1057+ dbg ("adc sample timeout");
1058+ return RC_PENUP;
1059+ }
1060+
1061+ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1062+ if (wm->mach_ops && wm->mach_ops->post_sample)
1063+ wm->mach_ops->post_sample(adcsel);
1064+
1065+ /* check we have correct sample */
1066+ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
1067+ dbg ("adc wrong sample, read %x got %x", adcsel,
1068+ *sample & WM97XX_ADCSEL_MASK);
1069+ return RC_PENUP;
1070+ }
1071+
1072+ if (!(*sample & WM97XX_PEN_DOWN)) {
1073+ wm->pen_probably_down = 0;
1074+ return RC_PENUP;
1075+ }
1076+
1077+ return RC_VALID;
1078+}
1079+
1080+/*
1081+ * Read a coord from the WM9712 adc in polling mode.
1082+ */
1083+static int wm9712_poll_coord (struct wm97xx* wm, struct wm97xx_data *data)
1084+{
1085+ int timeout = 5 * delay;
1086+
1087+ if (!wm->pen_probably_down) {
1088+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1089+ if (!(data & WM97XX_PEN_DOWN))
1090+ return RC_PENUP;
1091+ wm->pen_probably_down = 1;
1092+ }
1093+
1094+ /* set up digitiser */
1095+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1096+ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1097+
1098+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
1099+ WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay));
1100+
1101+ /* wait 3 AC97 time slots + delay for conversion and read x */
1102+ poll_delay(delay);
1103+ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1104+ /* wait for POLL to go low */
1105+ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
1106+ udelay(AC97_LINK_FRAME);
1107+ timeout--;
1108+ }
1109+
1110+ if (timeout <= 0) {
1111+ /* If PDEN is set, we can get a timeout when pen goes up */
1112+ if (is_pden(wm))
1113+ wm->pen_probably_down = 0;
1114+ else
1115+ dbg ("adc sample timeout");
1116+ return RC_PENUP;
1117+ }
1118+
1119+ /* read back y data */
1120+ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1121+ if (pil)
1122+ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1123+ else
1124+ data->p = DEFAULT_PRESSURE;
1125+
1126+ if (wm->mach_ops && wm->mach_ops->post_sample)
1127+ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1128+
1129+ /* check we have correct sample */
1130+ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
1131+ goto err;
1132+ if(pil && !(data->p & WM97XX_ADCSEL_PRES))
1133+ goto err;
1134+
1135+ if (!(data->x & WM97XX_PEN_DOWN)) {
1136+ wm->pen_probably_down = 0;
1137+ return RC_PENUP;
1138+ }
1139+ return RC_VALID;
1140+err:
1141+ return RC_PENUP;
1142+}
1143+
1144+/*
1145+ * Sample the WM9712 touchscreen in polling mode
1146+ */
1147+static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
1148+{
1149+ int rc;
1150+
1151+ if(coord) {
1152+ if((rc = wm9712_poll_coord(wm, data)) != RC_VALID)
1153+ return rc;
1154+ } else {
1155+ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID)
1156+ return rc;
1157+
1158+ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID)
1159+ return rc;
1160+
1161+ if (pil && !five_wire) {
1162+ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID)
1163+ return rc;
1164+ } else
1165+ data->p = DEFAULT_PRESSURE;
1166+ }
1167+ return RC_VALID;
1168+}
1169+
1170+/*
1171+ * Enable WM9712 continuous mode, i.e. touch data is streamed across an AC97 slot
1172+ */
1173+static int wm9712_acc_enable (struct wm97xx* wm, int enable)
1174+{
1175+ u16 dig1, dig2;
1176+ int ret = 0;
1177+
1178+ dig1 = wm->dig[1];
1179+ dig2 = wm->dig[2];
1180+
1181+ if (enable) {
1182+ /* continous mode */
1183+ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0)
1184+ return ret;
1185+ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
1186+ WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
1187+ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
1188+ WM97XX_DELAY (delay) |
1189+ WM97XX_SLT (wm->acc_slot) |
1190+ WM97XX_RATE (wm->acc_rate);
1191+ if (pil)
1192+ dig1 |= WM97XX_ADCSEL_PRES;
1193+ dig2 |= WM9712_PDEN;
1194+ } else {
1195+ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
1196+ dig2 &= ~WM9712_PDEN;
1197+ if (wm->mach_ops->acc_shutdown)
1198+ wm->mach_ops->acc_shutdown(wm);
1199+ }
1200+
1201+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
1202+ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
1203+ return 0;
1204+}
1205+
1206+struct wm97xx_codec_drv wm97xx_codec = {
1207+ .id = WM9712_ID2,
1208+ .name = "wm9712",
1209+ .poll_sample = wm9712_poll_sample,
1210+ .poll_touch = wm9712_poll_touch,
1211+ .acc_enable = wm9712_acc_enable,
1212+ .digitiser_ioctl = wm9712_digitiser_ioctl,
1213+};
1214+
1215+EXPORT_SYMBOL_GPL(wm97xx_codec);
1216+
1217+/* Module information */
1218+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
1219+MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
1220+MODULE_LICENSE("GPL");
1221Index: linux-2.6.17/drivers/input/touchscreen/wm9713.c
1222===================================================================
1223--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1224+++ linux-2.6.17/drivers/input/touchscreen/wm9713.c 2006-09-19 20:36:47.969052000 +0200
1225@@ -0,0 +1,461 @@
1226+/*
1227+ * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
1228+ *
1229+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
1230+ * Author: Liam Girdwood
1231+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
1232+ * Parts Copyright : Ian Molton <spyro@f2s.com>
1233+ * Andrew Zabolotny <zap@homelink.ru>
1234+ * Russell King <rmk@arm.linux.org.uk>
1235+ *
1236+ * This program is free software; you can redistribute it and/or modify it
1237+ * under the terms of the GNU General Public License as published by the
1238+ * Free Software Foundation; either version 2 of the License, or (at your
1239+ * option) any later version.
1240+ *
1241+ * Revision history
1242+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
1243+ * Added pre and post sample calls.
1244+ *
1245+ */
1246+
1247+#include <linux/module.h>
1248+#include <linux/moduleparam.h>
1249+#include <linux/version.h>
1250+#include <linux/kernel.h>
1251+#include <linux/input.h>
1252+#include <linux/delay.h>
1253+#include <linux/bitops.h>
1254+#include <linux/wm97xx.h>
1255+
1256+#define TS_NAME "wm97xx"
1257+#define WM9713_VERSION "0.53"
1258+#define DEFAULT_PRESSURE 0xb0c0
1259+
1260+/*
1261+ * Debug
1262+ */
1263+#if 0
1264+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
1265+#else
1266+#define dbg(format, arg...)
1267+#endif
1268+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
1269+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
1270+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
1271+
1272+/*
1273+ * Module parameters
1274+ */
1275+
1276+/*
1277+ * Set internal pull up for pen detect.
1278+ *
1279+ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
1280+ * i.e. pull up resistance = 64k Ohms / rpu.
1281+ *
1282+ * Adjust this value if you are having problems with pen detect not
1283+ * detecting any down event.
1284+ */
1285+static int rpu = 1;
1286+module_param(rpu, int, 0);
1287+MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
1288+
1289+/*
1290+ * Set current used for pressure measurement.
1291+ *
1292+ * Set pil = 2 to use 400uA
1293+ * pil = 1 to use 200uA and
1294+ * pil = 0 to disable pressure measurement.
1295+ *
1296+ * This is used to increase the range of values returned by the adc
1297+ * when measureing touchpanel pressure.
1298+ */
1299+static int pil = 0;
1300+module_param(pil, int, 0);
1301+MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
1302+
1303+/*
1304+ * Set threshold for pressure measurement.
1305+ *
1306+ * Pen down pressure below threshold is ignored.
1307+ */
1308+static int pressure = DEFAULT_PRESSURE & 0xfff;
1309+module_param(pressure, int, 0);
1310+MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
1311+
1312+/*
1313+ * Set adc sample delay.
1314+ *
1315+ * For accurate touchpanel measurements, some settling time may be
1316+ * required between the switch matrix applying a voltage across the
1317+ * touchpanel plate and the ADC sampling the signal.
1318+ *
1319+ * This delay can be set by setting delay = n, where n is the array
1320+ * position of the delay in the array delay_table below.
1321+ * Long delays > 1ms are supported for completeness, but are not
1322+ * recommended.
1323+ */
1324+static int delay = 4;
1325+module_param(delay, int, 0);
1326+MODULE_PARM_DESC(delay, "Set adc sample delay.");
1327+
1328+/*
1329+ * Set adc mask function.
1330+ *
1331+ * Sources of glitch noise, such as signals driving an LCD display, may feed
1332+ * through to the touch screen plates and affect measurement accuracy. In
1333+ * order to minimise this, a signal may be applied to the MASK pin to delay or
1334+ * synchronise the sampling.
1335+ *
1336+ * 0 = No delay or sync
1337+ * 1 = High on pin stops conversions
1338+ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
1339+ * 3 = Edge triggered, edge on pin starts conversion after delay param
1340+ */
1341+static int mask = 0;
1342+module_param(mask, int, 0);
1343+MODULE_PARM_DESC(mask, "Set adc mask function.");
1344+
1345+/*
1346+ * Coordinate Polling Enable.
1347+ *
1348+ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
1349+ * for every poll.
1350+ */
1351+static int coord = 1;
1352+module_param(coord, int, 0);
1353+MODULE_PARM_DESC(coord, "Polling coordinate mode");
1354+
1355+/*
1356+ * ADC sample delay times in uS
1357+ */
1358+static const int delay_table[] = {
1359+ 21, // 1 AC97 Link frames
1360+ 42, // 2
1361+ 84, // 4
1362+ 167, // 8
1363+ 333, // 16
1364+ 667, // 32
1365+ 1000, // 48
1366+ 1333, // 64
1367+ 2000, // 96
1368+ 2667, // 128
1369+ 3333, // 160
1370+ 4000, // 192
1371+ 4667, // 224
1372+ 5333, // 256
1373+ 6000, // 288
1374+ 0 // No delay, switch matrix always on
1375+};
1376+
1377+/*
1378+ * Delay after issuing a POLL command.
1379+ *
1380+ * The delay is 3 AC97 link frames + the touchpanel settling delay
1381+ */
1382+static inline void poll_delay(int d)
1383+{
1384+ udelay (3 * AC97_LINK_FRAME + delay_table [d]);
1385+}
1386+
1387+/*
1388+ * set up the physical settings of the WM9713
1389+ */
1390+static void init_wm9713_phy(struct wm97xx* wm)
1391+{
1392+ u16 dig1 = 0, dig2, dig3;
1393+
1394+ /* default values */
1395+ dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5);
1396+ dig3= WM9712_RPU(1);
1397+
1398+ /* rpu */
1399+ if (rpu) {
1400+ dig3 &= 0xffc0;
1401+ dig3 |= WM9712_RPU(rpu);
1402+ info("setting pen detect pull-up to %d Ohms",64000 / rpu);
1403+ }
1404+
1405+ /* touchpanel pressure */
1406+ if (pil == 2) {
1407+ dig3 |= WM9712_PIL;
1408+ info("setting pressure measurement current to 400uA.");
1409+ } else if (pil)
1410+ info ("setting pressure measurement current to 200uA.");
1411+ if(!pil)
1412+ pressure = 0;
1413+
1414+ /* sample settling delay */
1415+ if (delay < 0 || delay > 15) {
1416+ info ("supplied delay out of range.");
1417+ delay = 4;
1418+ info("setting adc sample delay to %d u Secs.", delay_table[delay]);
1419+ }
1420+ dig2 &= 0xff0f;
1421+ dig2 |= WM97XX_DELAY(delay);
1422+
1423+ /* mask */
1424+ dig3 |= ((mask & 0x3) << 4);
1425+ if(coord)
1426+ dig3 |= WM9713_WAIT;
1427+
1428+ wm->misc = wm97xx_reg_read(wm, 0x5a);
1429+
1430+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
1431+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
1432+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
1433+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0);
1434+}
1435+
1436+static int wm9713_digitiser_ioctl(struct wm97xx* wm, int cmd)
1437+{
1438+ u16 val = 0;
1439+
1440+ switch(cmd){
1441+ case WM97XX_DIG_START:
1442+ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
1443+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff);
1444+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | WM97XX_PRP_DET_DIG);
1445+ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
1446+ break;
1447+ case WM97XX_DIG_STOP:
1448+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & ~WM97XX_PRP_DET_DIG);
1449+ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
1450+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000);
1451+ break;
1452+ case WM97XX_AUX_PREPARE:
1453+ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
1454+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0);
1455+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0);
1456+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG);
1457+ break;
1458+ case WM97XX_DIG_RESTORE:
1459+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]);
1460+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]);
1461+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]);
1462+ break;
1463+ case WM97XX_PHY_INIT:
1464+ init_wm9713_phy(wm);
1465+ break;
1466+ default:
1467+ return -EINVAL;
1468+ }
1469+ return 0;
1470+}
1471+
1472+static inline int is_pden (struct wm97xx* wm)
1473+{
1474+ return wm->dig[2] & WM9713_PDEN;
1475+}
1476+
1477+/*
1478+ * Read a sample from the WM9713 adc in polling mode.
1479+ */
1480+static int wm9713_poll_sample (struct wm97xx* wm, int adcsel, int *sample)
1481+{
1482+ u16 dig1;
1483+ int timeout = 5 * delay;
1484+
1485+ if (!wm->pen_probably_down) {
1486+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1487+ if (!(data & WM97XX_PEN_DOWN))
1488+ return RC_PENUP;
1489+ wm->pen_probably_down = 1;
1490+ }
1491+
1492+ /* set up digitiser */
1493+ if (adcsel & 0x8000)
1494+ adcsel = 1 << ((adcsel & 0x7fff) + 3);
1495+
1496+ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
1497+ dig1 &= ~WM9713_ADCSEL_MASK;
1498+
1499+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1500+ wm->mach_ops->pre_sample(adcsel);
1501+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel |WM9713_POLL);
1502+
1503+ /* wait 3 AC97 time slots + delay for conversion */
1504+ poll_delay(delay);
1505+
1506+ /* wait for POLL to go low */
1507+ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) {
1508+ udelay(AC97_LINK_FRAME);
1509+ timeout--;
1510+ }
1511+
1512+ if (timeout <= 0) {
1513+ /* If PDEN is set, we can get a timeout when pen goes up */
1514+ if (is_pden(wm))
1515+ wm->pen_probably_down = 0;
1516+ else
1517+ dbg ("adc sample timeout");
1518+ return RC_PENUP;
1519+ }
1520+
1521+ *sample =wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1522+ if (wm->mach_ops && wm->mach_ops->post_sample)
1523+ wm->mach_ops->post_sample(adcsel);
1524+
1525+ /* check we have correct sample */
1526+ if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) {
1527+ dbg ("adc wrong sample, read %x got %x", adcsel,
1528+ *sample & WM97XX_ADCSRC_MASK);
1529+ return RC_PENUP;
1530+ }
1531+
1532+ if (!(*sample & WM97XX_PEN_DOWN)) {
1533+ wm->pen_probably_down = 0;
1534+ return RC_PENUP;
1535+ }
1536+
1537+ return RC_VALID;
1538+}
1539+
1540+/*
1541+ * Read a coordinate from the WM9713 adc in polling mode.
1542+ */
1543+static int wm9713_poll_coord (struct wm97xx* wm, struct wm97xx_data *data)
1544+{
1545+ u16 dig1;
1546+ int timeout = 5 * delay;
1547+
1548+ if (!wm->pen_probably_down) {
1549+ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1550+ if (!(data & WM97XX_PEN_DOWN))
1551+ return RC_PENUP;
1552+ wm->pen_probably_down = 1;
1553+ }
1554+
1555+ /* set up digitiser */
1556+ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
1557+ dig1 &= ~WM9713_ADCSEL_MASK;
1558+ if(pil)
1559+ dig1 |= WM97XX_ADCSEL_PRES;
1560+
1561+ if (wm->mach_ops && wm->mach_ops->pre_sample)
1562+ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1563+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL | WM9713_COO);
1564+
1565+ /* wait 3 AC97 time slots + delay for conversion */
1566+ poll_delay(delay);
1567+ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1568+ /* wait for POLL to go low */
1569+ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) {
1570+ udelay(AC97_LINK_FRAME);
1571+ timeout--;
1572+ }
1573+
1574+ if (timeout <= 0) {
1575+ /* If PDEN is set, we can get a timeout when pen goes up */
1576+ if (is_pden(wm))
1577+ wm->pen_probably_down = 0;
1578+ else
1579+ dbg ("adc sample timeout");
1580+ return RC_PENUP;
1581+ }
1582+
1583+ /* read back data */
1584+ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1585+ if (pil)
1586+ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
1587+ else
1588+ data->p = DEFAULT_PRESSURE;
1589+
1590+ if (wm->mach_ops && wm->mach_ops->post_sample)
1591+ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
1592+
1593+ /* check we have correct sample */
1594+ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
1595+ goto err;
1596+ if(pil && !(data->p & WM97XX_ADCSEL_PRES))
1597+ goto err;
1598+
1599+ if (!(data->x & WM97XX_PEN_DOWN)) {
1600+ wm->pen_probably_down = 0;
1601+ return RC_PENUP;
1602+ }
1603+ return RC_VALID;
1604+err:
1605+ return RC_PENUP;
1606+}
1607+
1608+/*
1609+ * Sample the WM9713 touchscreen in polling mode
1610+ */
1611+static int wm9713_poll_touch(struct wm97xx* wm, struct wm97xx_data *data)
1612+{
1613+ int rc;
1614+
1615+ if(coord) {
1616+ if((rc = wm9713_poll_coord(wm, data)) != RC_VALID)
1617+ return rc;
1618+ } else {
1619+ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x)) != RC_VALID)
1620+ return rc;
1621+ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y)) != RC_VALID)
1622+ return rc;
1623+ if (pil) {
1624+ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, &data->p)) != RC_VALID)
1625+ return rc;
1626+ } else
1627+ data->p = DEFAULT_PRESSURE;
1628+ }
1629+ return RC_VALID;
1630+}
1631+
1632+/*
1633+ * Enable WM9713 continuous mode, i.e. touch data is streamed across an AC97 slot
1634+ */
1635+static int wm9713_acc_enable (struct wm97xx* wm, int enable)
1636+{
1637+ u16 dig1, dig2, dig3;
1638+ int ret = 0;
1639+
1640+ dig1 = wm->dig[0];
1641+ dig2 = wm->dig[1];
1642+ dig3 = wm->dig[2];
1643+
1644+ if (enable) {
1645+ /* continous mode */
1646+ if (wm->mach_ops->acc_startup &&
1647+ (ret = wm->mach_ops->acc_startup(wm)) < 0)
1648+ return ret;
1649+
1650+ dig1 &= ~WM9713_ADCSEL_MASK;
1651+ dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | WM9713_ADCSEL_Y;
1652+ if (pil)
1653+ dig1 |= WM9713_ADCSEL_PRES;
1654+ dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK | WM97XX_CM_RATE_MASK);
1655+ dig2 |= WM97XX_SLEN | WM97XX_DELAY (delay) |
1656+ WM97XX_SLT (wm->acc_slot) | WM97XX_RATE (wm->acc_rate);
1657+ dig3 |= WM9713_PDEN;
1658+ } else {
1659+ dig1 &= ~(WM9713_CTC | WM9713_COO);
1660+ dig2 &= ~WM97XX_SLEN;
1661+ dig3 &= ~WM9713_PDEN;
1662+ if (wm->mach_ops->acc_shutdown)
1663+ wm->mach_ops->acc_shutdown(wm);
1664+ }
1665+
1666+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
1667+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
1668+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
1669+ return ret;
1670+}
1671+
1672+struct wm97xx_codec_drv wm97xx_codec = {
1673+ .id = WM9713_ID2,
1674+ .name = "wm9713",
1675+ .poll_sample = wm9713_poll_sample,
1676+ .poll_touch = wm9713_poll_touch,
1677+ .acc_enable = wm9713_acc_enable,
1678+ .digitiser_ioctl = wm9713_digitiser_ioctl,
1679+};
1680+
1681+EXPORT_SYMBOL_GPL(wm97xx_codec);
1682+
1683+/* Module information */
1684+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
1685+MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
1686+MODULE_LICENSE("GPL");
1687Index: linux-2.6.17/drivers/input/touchscreen/wm97xx-core.c
1688===================================================================
1689--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1690+++ linux-2.6.17/drivers/input/touchscreen/wm97xx-core.c 2006-09-19 20:36:47.969052000 +0200
1691@@ -0,0 +1,912 @@
1692+/*
1693+ * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712
1694+ * and WM9713 AC97 Codecs.
1695+ *
1696+ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC.
1697+ * Author: Liam Girdwood
1698+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
1699+ * Parts Copyright : Ian Molton <spyro@f2s.com>
1700+ * Andrew Zabolotny <zap@homelink.ru>
1701+ * Russell King <rmk@arm.linux.org.uk>
1702+ *
1703+ * This program is free software; you can redistribute it and/or modify it
1704+ * under the terms of the GNU General Public License as published by the
1705+ * Free Software Foundation; either version 2 of the License, or (at your
1706+ * option) any later version.
1707+ *
1708+ * Notes:
1709+ *
1710+ * Features:
1711+ * - supports WM9705, WM9712, WM9713
1712+ * - polling mode
1713+ * - continuous mode (arch-dependent)
1714+ * - adjustable rpu/dpp settings
1715+ * - adjustable pressure current
1716+ * - adjustable sample settle delay
1717+ * - 4 and 5 wire touchscreens (5 wire is WM9712 only)
1718+ * - pen down detection
1719+ * - battery monitor
1720+ * - sample AUX adc's
1721+ * - power management
1722+ * - codec GPIO
1723+ * - codec event notification
1724+ * Todo
1725+ * - Support for async sampling control for noisy LCD's.
1726+ *
1727+ * Revision history
1728+ * 7th May 2003 Initial version.
1729+ * 6th June 2003 Added non module support and AC97 registration.
1730+ * 18th June 2003 Added AUX adc sampling.
1731+ * 23rd June 2003 Did some minimal reformatting, fixed a couple of
1732+ * codec_mutexing bugs and noted a race to fix.
1733+ * 24th June 2003 Added power management and fixed race condition.
1734+ * 10th July 2003 Changed to a misc device.
1735+ * 31st July 2003 Moved TS_EVENT and TS_CAL to wm97xx.h
1736+ * 8th Aug 2003 Added option for read() calling wm97xx_sample_touch()
1737+ * because some ac97_read/ac_97_write call schedule()
1738+ * 7th Nov 2003 Added Input touch event interface, stanley.cai@intel.com
1739+ * 13th Nov 2003 Removed h3600 touch interface, added interrupt based
1740+ * pen down notification and implemented continous mode
1741+ * on XScale arch.
1742+ * 16th Nov 2003 Ian Molton <spyro@f2s.com>
1743+ * Modified so that it suits the new 2.6 driver model.
1744+ * 25th Jan 2004 Andrew Zabolotny <zap@homelink.ru>
1745+ * Implemented IRQ-driven pen down detection, implemented
1746+ * the private API meant to be exposed to platform-specific
1747+ * drivers, reorganized the driver so that it supports
1748+ * an arbitrary number of devices.
1749+ * 1st Feb 2004 Moved continuous mode handling to a separate
1750+ * architecture-dependent file. For now only PXA
1751+ * built-in AC97 controller is supported (pxa-ac97-wm97xx.c).
1752+ * 11th Feb 2004 Reduced CPU usage by keeping a cached copy of both
1753+ * digitizer registers instead of reading them every time.
1754+ * A reorganization of the whole code for better
1755+ * error handling.
1756+ * 17th Apr 2004 Added BMON support.
1757+ * 17th Nov 2004 Added codec GPIO, codec event handling (real and virtual
1758+ * GPIOs) and 2.6 power management.
1759+ * 29th Nov 2004 Added WM9713 support.
1760+ * 4th Jul 2005 Moved codec specific code out to seperate files.
1761+ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com>
1762+ * Added bus interface.
1763+ */
1764+
1765+#include <linux/module.h>
1766+#include <linux/moduleparam.h>
1767+#include <linux/version.h>
1768+#include <linux/kernel.h>
1769+#include <linux/init.h>
1770+#include <linux/delay.h>
1771+#include <linux/string.h>
1772+#include <linux/proc_fs.h>
1773+#include <linux/pm.h>
1774+#include <linux/interrupt.h>
1775+#include <linux/bitops.h>
1776+#include <linux/workqueue.h>
1777+#include <linux/device.h>
1778+#include <linux/wm97xx.h>
1779+#include <asm/uaccess.h>
1780+#include <asm/io.h>
1781+
1782+#define TS_NAME "wm97xx"
1783+#define WM_CORE_VERSION "0.63"
1784+#define DEFAULT_PRESSURE 0xb0c0
1785+
1786+/*
1787+ * WM97xx - enable/disable AUX ADC sysfs
1788+ */
1789+static int aux_sys = 1;
1790+module_param(aux_sys, int, 0);
1791+MODULE_PARM_DESC(aux_sys, "enable AUX ADC sysfs entries");
1792+
1793+/*
1794+ * WM97xx - enable/disable codec status sysfs
1795+ */
1796+static int status_sys = 1;
1797+module_param(status_sys, int, 0);
1798+MODULE_PARM_DESC(status_sys, "enable codec status sysfs entries");
1799+
1800+/*
1801+ * Touchscreen absolute values
1802+ *
1803+ * These parameters are used to help the input layer discard out of
1804+ * range readings and reduce jitter etc.
1805+ *
1806+ * o min, max:- indicate the min and max values your touch screen returns
1807+ * o fuzz:- use a higher number to reduce jitter
1808+ *
1809+ * The default values correspond to Mainstone II in QVGA mode
1810+ *
1811+ * Please read
1812+ * Documentation/input/input-programming.txt for more details.
1813+ */
1814+
1815+static int abs_x[3] = {350,3900,5};
1816+module_param_array(abs_x, int, NULL, 0);
1817+MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");
1818+
1819+static int abs_y[3] = {320,3750,40};
1820+module_param_array(abs_y, int, NULL, 0);
1821+MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");
1822+
1823+static int abs_p[3] = {0,150,4};
1824+module_param_array(abs_p, int, NULL, 0);
1825+MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");
1826+
1827+/*
1828+ * Debug
1829+ */
1830+#if 0
1831+#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg)
1832+#else
1833+#define dbg(format, arg...)
1834+#endif
1835+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
1836+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
1837+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
1838+
1839+/* codec AC97 IO access */
1840+int wm97xx_reg_read(struct wm97xx *wm, u16 reg)
1841+{
1842+ if (wm->ac97)
1843+ return wm->ac97->bus->ops->read(wm->ac97, reg);
1844+ else
1845+ return -1;
1846+}
1847+
1848+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val)
1849+{
1850+ /* cache digitiser registers */
1851+ if(reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3)
1852+ wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val;
1853+
1854+ /* cache gpio regs */
1855+ if(reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE)
1856+ wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val;
1857+
1858+ /* wm9713 irq reg */
1859+ if(reg == 0x5a)
1860+ wm->misc = val;
1861+
1862+ if (wm->ac97)
1863+ wm->ac97->bus->ops->write(wm->ac97, reg, val);
1864+}
1865+
1866+
1867+/**
1868+ * wm97xx_read_aux_adc - Read the aux adc.
1869+ * @wm: wm97xx device.
1870+ * @adcsel: codec ADC to be read
1871+ *
1872+ * Reads the selected AUX ADC.
1873+ */
1874+
1875+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
1876+{
1877+ int power_adc = 0, auxval;
1878+ u16 power = 0;
1879+
1880+ /* get codec */
1881+ mutex_lock(&wm->codec_mutex);
1882+
1883+ /* When the touchscreen is not in use, we may have to power up the AUX ADC
1884+ * before we can use sample the AUX inputs->
1885+ */
1886+ if (wm->id == WM9713_ID2 &&
1887+ (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) {
1888+ power_adc = 1;
1889+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff);
1890+ }
1891+
1892+ /* Prepare the codec for AUX reading */
1893+ wm->codec->digitiser_ioctl(wm, WM97XX_AUX_PREPARE);
1894+
1895+ /* Turn polling mode on to read AUX ADC */
1896+ wm->pen_probably_down = 1;
1897+ wm->codec->poll_sample(wm, adcsel, &auxval);
1898+
1899+ if (power_adc)
1900+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000);
1901+
1902+ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_RESTORE);
1903+
1904+ wm->pen_probably_down = 0;
1905+
1906+ mutex_unlock(&wm->codec_mutex);
1907+ return auxval & 0xfff;
1908+}
1909+
1910+#define WM97XX_AUX_ATTR(name,input) \
1911+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
1912+{ \
1913+ struct wm97xx *wm = (struct wm97xx*)dev->driver_data; \
1914+ return sprintf(buf, "%d\n", wm97xx_read_aux_adc(wm, input)); \
1915+} \
1916+static DEVICE_ATTR(name, 0444, name##_show, NULL)
1917+
1918+WM97XX_AUX_ATTR(aux1, WM97XX_AUX_ID1);
1919+WM97XX_AUX_ATTR(aux2, WM97XX_AUX_ID2);
1920+WM97XX_AUX_ATTR(aux3, WM97XX_AUX_ID3);
1921+WM97XX_AUX_ATTR(aux4, WM97XX_AUX_ID4);
1922+
1923+#define WM97XX_STATUS_ATTR(name) \
1924+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
1925+{ \
1926+ struct wm97xx *wm = (struct wm97xx*)dev->driver_data; \
1927+ return sprintf(buf, "%d\n", wm97xx_reg_read(wm, AC97_GPIO_STATUS)); \
1928+} \
1929+static DEVICE_ATTR(name, 0444, name##_show, NULL)
1930+
1931+WM97XX_STATUS_ATTR(gpio);
1932+
1933+static int wm97xx_sys_add(struct device *dev)
1934+{
1935+ if (aux_sys) {
1936+ device_create_file(dev, &dev_attr_aux1);
1937+ device_create_file(dev, &dev_attr_aux2);
1938+ device_create_file(dev, &dev_attr_aux3);
1939+ device_create_file(dev, &dev_attr_aux4);
1940+ }
1941+ if (status_sys)
1942+ device_create_file(dev, &dev_attr_gpio);
1943+ return 0;
1944+}
1945+
1946+static void wm97xx_sys_remove(struct device *dev)
1947+{
1948+ if (status_sys)
1949+ device_remove_file(dev, &dev_attr_gpio);
1950+ if (aux_sys) {
1951+ device_remove_file(dev, &dev_attr_aux1);
1952+ device_remove_file(dev, &dev_attr_aux2);
1953+ device_remove_file(dev, &dev_attr_aux3);
1954+ device_remove_file(dev, &dev_attr_aux4);
1955+ }
1956+}
1957+
1958+/**
1959+ * wm97xx_get_gpio - Get the status of a codec GPIO.
1960+ * @wm: wm97xx device.
1961+ * @gpio: gpio
1962+ *
1963+ * Get the status of a codec GPIO pin
1964+ */
1965+
1966+wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio)
1967+{
1968+ u16 status;
1969+ wm97xx_gpio_status_t ret;
1970+
1971+ mutex_lock(&wm->codec_mutex);
1972+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
1973+
1974+ if (status & gpio)
1975+ ret = WM97XX_GPIO_HIGH;
1976+ else
1977+ ret = WM97XX_GPIO_LOW;
1978+
1979+ mutex_unlock(&wm->codec_mutex);
1980+ return ret;
1981+}
1982+
1983+/**
1984+ * wm97xx_set_gpio - Set the status of a codec GPIO.
1985+ * @wm: wm97xx device.
1986+ * @gpio: gpio
1987+ *
1988+ *
1989+ * Set the status of a codec GPIO pin
1990+ */
1991+
1992+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
1993+ wm97xx_gpio_status_t status)
1994+{
1995+ u16 reg;
1996+
1997+ mutex_lock(&wm->codec_mutex);
1998+ reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
1999+
2000+ if (status & WM97XX_GPIO_HIGH)
2001+ reg |= gpio;
2002+ else
2003+ reg &= ~gpio;
2004+
2005+ if (wm->id == WM9712_ID2)
2006+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
2007+ else
2008+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
2009+ mutex_unlock(&wm->codec_mutex);
2010+}
2011+
2012+/*
2013+ * Codec GPIO pin configuration, this set's pin direction, polarity,
2014+ * stickyness and wake up.
2015+ */
2016+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, wm97xx_gpio_dir_t dir,
2017+ wm97xx_gpio_pol_t pol, wm97xx_gpio_sticky_t sticky,
2018+ wm97xx_gpio_wake_t wake)
2019+{
2020+ u16 reg;
2021+
2022+ mutex_lock(&wm->codec_mutex);
2023+ reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
2024+
2025+ if (pol == WM97XX_GPIO_POL_HIGH)
2026+ reg |= gpio;
2027+ else
2028+ reg &= ~gpio;
2029+
2030+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg);
2031+ reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
2032+
2033+ if (sticky == WM97XX_GPIO_STICKY)
2034+ reg |= gpio;
2035+ else
2036+ reg &= ~gpio;
2037+
2038+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg);
2039+ reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
2040+
2041+ if (wake == WM97XX_GPIO_WAKE)
2042+ reg |= gpio;
2043+ else
2044+ reg &= ~gpio;
2045+
2046+ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg);
2047+ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
2048+
2049+ if (dir == WM97XX_GPIO_IN)
2050+ reg |= gpio;
2051+ else
2052+ reg &= ~gpio;
2053+
2054+ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg);
2055+ mutex_unlock(&wm->codec_mutex);
2056+}
2057+
2058+/*
2059+ * Handle a pen down interrupt.
2060+ */
2061+static void wm97xx_pen_irq_worker(void *ptr)
2062+{
2063+ struct wm97xx *wm = (struct wm97xx *) ptr;
2064+
2065+ /* do we need to enable the touch panel reader */
2066+ if (wm->id == WM9705_ID2) {
2067+ if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & WM97XX_PEN_DOWN)
2068+ wm->pen_is_down = 1;
2069+ else
2070+ wm->pen_is_down = 0;
2071+ wake_up_interruptible(&wm->pen_irq_wait);
2072+ } else {
2073+ u16 status, pol;
2074+ mutex_lock(&wm->codec_mutex);
2075+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
2076+ pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
2077+
2078+ if (WM97XX_GPIO_13 & pol & status) {
2079+ wm->pen_is_down = 1;
2080+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol & ~WM97XX_GPIO_13);
2081+ } else {
2082+ wm->pen_is_down = 0;
2083+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol | WM97XX_GPIO_13);
2084+ }
2085+
2086+ if (wm->id == WM9712_ID2)
2087+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status & ~WM97XX_GPIO_13) << 1);
2088+ else
2089+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, status & ~WM97XX_GPIO_13);
2090+ mutex_unlock(&wm->codec_mutex);
2091+ wake_up_interruptible(&wm->pen_irq_wait);
2092+ }
2093+
2094+ if (!wm->pen_is_down && wm->mach_ops && wm->mach_ops->acc_enabled)
2095+ wm->mach_ops->acc_pen_up(wm);
2096+ enable_irq(wm->pen_irq);
2097+}
2098+
2099+/*
2100+ * Codec PENDOWN irq handler
2101+ *
2102+ * We have to disable the codec interrupt in the handler because it can
2103+ * take upto 1ms to clear the interrupt source. The interrupt is then enabled
2104+ * again in the slow handler when the source has been cleared.
2105+ */
2106+static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id,
2107+ struct pt_regs *regs)
2108+{
2109+ struct wm97xx *wm = (struct wm97xx *) dev_id;
2110+ disable_irq(wm->pen_irq);
2111+ queue_work(wm->pen_irq_workq, &wm->pen_event_work);
2112+ return IRQ_HANDLED;
2113+}
2114+
2115+/*
2116+ * initialise pen IRQ handler and workqueue
2117+ */
2118+static int wm97xx_init_pen_irq(struct wm97xx *wm)
2119+{
2120+ u16 reg;
2121+
2122+ INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker, wm);
2123+ if ((wm->pen_irq_workq =
2124+ create_singlethread_workqueue("kwm97pen")) == NULL) {
2125+ err("could not create pen irq work queue");
2126+ wm->pen_irq = 0;
2127+ return -EINVAL;
2128+ }
2129+
2130+ if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) {
2131+ err("could not register codec pen down interrupt, will poll for pen down");
2132+ destroy_workqueue(wm->pen_irq_workq);
2133+ wm->pen_irq = 0;
2134+ return -EINVAL;
2135+ }
2136+
2137+ /* enable PEN down on wm9712/13 */
2138+ if (wm->id != WM9705_ID2) {
2139+ reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
2140+ wm97xx_reg_write(wm, AC97_MISC_AFE, reg & 0xfffb);
2141+ reg = wm97xx_reg_read(wm, 0x5a);
2142+ wm97xx_reg_write(wm, 0x5a, reg & ~0x0001);
2143+ }
2144+
2145+ return 0;
2146+}
2147+
2148+/* Private struct for communication between struct wm97xx_tshread
2149+ * and wm97xx_read_samples */
2150+struct ts_state {
2151+ int sleep_time;
2152+ int min_sleep_time;
2153+};
2154+
2155+static int wm97xx_read_samples(struct wm97xx *wm, struct ts_state *state)
2156+{
2157+ struct wm97xx_data data;
2158+ int rc;
2159+
2160+ mutex_lock(&wm->codec_mutex);
2161+
2162+ if (wm->mach_ops && wm->mach_ops->acc_enabled)
2163+ rc = wm->mach_ops->acc_pen_down(wm);
2164+ else
2165+ rc = wm->codec->poll_touch(wm, &data);
2166+
2167+ if (rc & RC_PENUP) {
2168+ if (wm->pen_is_down) {
2169+ wm->pen_is_down = 0;
2170+ dbg("pen up");
2171+ input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
2172+ input_sync(wm->input_dev);
2173+ } else if (!(rc & RC_AGAIN)) {
2174+ /* We need high frequency updates only while pen is down,
2175+ * the user never will be able to touch screen faster than
2176+ * a few times per second... On the other hand, when the
2177+ * user is actively working with the touchscreen we don't
2178+ * want to lose the quick response. So we will slowly
2179+ * increase sleep time after the pen is up and quicky
2180+ * restore it to ~one task switch when pen is down again.
2181+ */
2182+ if (state->sleep_time < HZ / 10)
2183+ state->sleep_time++;
2184+ }
2185+
2186+ } else if (rc & RC_VALID) {
2187+ dbg("pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n",
2188+ data.x >> 12, data.x & 0xfff, data.y >> 12,
2189+ data.y & 0xfff, data.p >> 12, data.p & 0xfff);
2190+ input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
2191+ input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
2192+ input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
2193+ input_sync(wm->input_dev);
2194+ wm->pen_is_down = 1;
2195+ state->sleep_time = state->min_sleep_time;
2196+ } else if (rc & RC_PENDOWN) {
2197+ dbg("pen down");
2198+ wm->pen_is_down = 1;
2199+ state->sleep_time = state->min_sleep_time;
2200+ }
2201+
2202+ mutex_unlock(&wm->codec_mutex);
2203+ return rc;
2204+}
2205+
2206+/*
2207+* The touchscreen sample reader thread.
2208+*/
2209+static int wm97xx_ts_read(void *data)
2210+{
2211+ int rc;
2212+ struct ts_state state;
2213+ struct wm97xx *wm = (struct wm97xx *) data;
2214+
2215+ /* set up thread context */
2216+ wm->ts_task = current;
2217+ daemonize("kwm97xxts");
2218+
2219+ if (wm->codec == NULL) {
2220+ wm->ts_task = NULL;
2221+ printk(KERN_ERR "codec is NULL, bailing\n");
2222+ }
2223+
2224+ complete(&wm->ts_init);
2225+ wm->pen_is_down = 0;
2226+ state.min_sleep_time = HZ >= 100 ? HZ / 100 : 1;
2227+ if (state.min_sleep_time < 1)
2228+ state.min_sleep_time = 1;
2229+ state.sleep_time = state.min_sleep_time;
2230+
2231+ /* touch reader loop */
2232+ while (wm->ts_task) {
2233+ do {
2234+ try_to_freeze();
2235+ rc = wm97xx_read_samples(wm, &state);
2236+ } while (rc & RC_AGAIN);
2237+ if (!wm->pen_is_down && wm->pen_irq) {
2238+ /* Nice, we don't have to poll for pen down event */
2239+ wait_event_interruptible(wm->pen_irq_wait, wm->pen_is_down);
2240+ } else {
2241+ set_task_state(current, TASK_INTERRUPTIBLE);
2242+ schedule_timeout(state.sleep_time);
2243+ }
2244+ }
2245+ complete_and_exit(&wm->ts_exit, 0);
2246+}
2247+
2248+/**
2249+ * wm97xx_ts_input_open - Open the touch screen input device.
2250+ * @idev: Input device to be opened.
2251+ *
2252+ * Called by the input sub system to open a wm97xx touchscreen device.
2253+ * Starts the touchscreen thread and touch digitiser.
2254+ */
2255+static int wm97xx_ts_input_open(struct input_dev *idev)
2256+{
2257+ int ret = 0;
2258+ struct wm97xx *wm = (struct wm97xx *) idev->private;
2259+
2260+ mutex_lock(&wm->codec_mutex);
2261+ /* first time opened ? */
2262+ if (wm->ts_use_count++ == 0) {
2263+ /* start touchscreen thread */
2264+ init_completion(&wm->ts_init);
2265+ init_completion(&wm->ts_exit);
2266+ ret = kernel_thread(wm97xx_ts_read, wm, CLONE_KERNEL);
2267+
2268+ if (ret >= 0) {
2269+ wait_for_completion(&wm->ts_init);
2270+ if (wm->ts_task == NULL)
2271+ ret = -EINVAL;
2272+ } else {
2273+ mutex_unlock(&wm->codec_mutex);
2274+ return ret;
2275+ }
2276+
2277+ /* start digitiser */
2278+ if (wm->mach_ops && wm->mach_ops->acc_enabled)
2279+ wm->codec->acc_enable(wm, 1);
2280+ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_START);
2281+
2282+ /* init pen down/up irq handling */
2283+ if (wm->pen_irq) {
2284+ wm97xx_init_pen_irq(wm);
2285+
2286+ if (wm->pen_irq == 0) {
2287+ /* we failed to get an irq for pen down events,
2288+ * so we resort to polling. kickstart the reader */
2289+ wm->pen_is_down = 1;
2290+ wake_up_interruptible(&wm->pen_irq_wait);
2291+ }
2292+ }
2293+ }
2294+
2295+ mutex_unlock(&wm->codec_mutex);
2296+ return 0;
2297+}
2298+
2299+/**
2300+ * wm97xx_ts_input_close - Close the touch screen input device.
2301+ * @idev: Input device to be closed.
2302+ *
2303+ * Called by the input sub system to close a wm97xx touchscreen device.
2304+ * Kills the touchscreen thread and stops the touch digitiser.
2305+ */
2306+
2307+static void wm97xx_ts_input_close(struct input_dev *idev)
2308+{
2309+ struct wm97xx *wm = (struct wm97xx *) idev->private;
2310+
2311+ mutex_lock(&wm->codec_mutex);
2312+ if (--wm->ts_use_count == 0) {
2313+ /* destroy workqueues and free irqs */
2314+ if (wm->pen_irq) {
2315+ free_irq(wm->pen_irq, wm);
2316+ destroy_workqueue(wm->pen_irq_workq);
2317+ }
2318+
2319+ /* kill thread */
2320+ if (wm->ts_task) {
2321+ wm->ts_task = NULL;
2322+ wm->pen_is_down = 1;
2323+ wake_up_interruptible(&wm->pen_irq_wait);
2324+ wait_for_completion(&wm->ts_exit);
2325+ wm->pen_is_down = 0;
2326+ }
2327+
2328+ /* stop digitiser */
2329+ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_STOP);
2330+ if (wm->mach_ops && wm->mach_ops->acc_enabled)
2331+ wm->codec->acc_enable(wm, 0);
2332+ }
2333+ mutex_unlock(&wm->codec_mutex);
2334+}
2335+
2336+static int wm97xx_bus_match(struct device *dev, struct device_driver *drv)
2337+{
2338+ return !(strcmp(dev->bus_id,drv->name));
2339+}
2340+
2341+/*
2342+ * The AC97 audio driver will do all the Codec suspend and resume
2343+ * tasks. This is just for anything machine specific or extra.
2344+ */
2345+static int wm97xx_bus_suspend(struct device *dev, pm_message_t state)
2346+{
2347+ int ret = 0;
2348+
2349+ if (dev->driver && dev->driver->suspend)
2350+ ret = dev->driver->suspend(dev, state);
2351+
2352+ return ret;
2353+}
2354+
2355+static int wm97xx_bus_resume(struct device *dev)
2356+{
2357+ int ret = 0;
2358+
2359+ if (dev->driver && dev->driver->resume)
2360+ ret = dev->driver->resume(dev);
2361+
2362+ return ret;
2363+}
2364+
2365+struct bus_type wm97xx_bus_type = {
2366+ .name = "wm97xx",
2367+ .match = wm97xx_bus_match,
2368+ .suspend = wm97xx_bus_suspend,
2369+ .resume = wm97xx_bus_resume,
2370+};
2371+
2372+static void wm97xx_release(struct device *dev)
2373+{
2374+ kfree(dev);
2375+}
2376+
2377+static int wm97xx_probe(struct device *dev)
2378+{
2379+ struct wm97xx* wm;
2380+ int ret = 0, id = 0;
2381+
2382+ if (!(wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL)))
2383+ return -ENOMEM;
2384+ mutex_init(&wm->codec_mutex);
2385+
2386+ init_waitqueue_head(&wm->pen_irq_wait);
2387+ wm->dev = dev;
2388+ dev->driver_data = wm;
2389+ wm->ac97 = to_ac97_t(dev);
2390+
2391+ /* check that we have a supported codec */
2392+ if ((id = wm97xx_reg_read(wm, AC97_VENDOR_ID1)) != WM97XX_ID1) {
2393+ err("could not find a wm97xx, found a %x instead\n", id);
2394+ kfree(wm);
2395+ return -ENODEV;
2396+ }
2397+
2398+ wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
2399+ if(wm->id != wm97xx_codec.id) {
2400+ err("could not find a the selected codec, please build for wm97%2x", wm->id & 0xff);
2401+ kfree(wm);
2402+ return -ENODEV;
2403+ }
2404+
2405+ if((wm->input_dev = input_allocate_device()) == NULL) {
2406+ kfree(wm);
2407+ return -ENOMEM;
2408+ }
2409+
2410+ /* set up touch configuration */
2411+ info("detected a wm97%2x codec", wm->id & 0xff);
2412+ wm->input_dev->name = "wm97xx touchscreen";
2413+ wm->input_dev->open = wm97xx_ts_input_open;
2414+ wm->input_dev->close = wm97xx_ts_input_close;
2415+ set_bit(EV_ABS, wm->input_dev->evbit);
2416+ set_bit(ABS_X, wm->input_dev->absbit);
2417+ set_bit(ABS_Y, wm->input_dev->absbit);
2418+ set_bit(ABS_PRESSURE, wm->input_dev->absbit);
2419+ wm->input_dev->absmax[ABS_X] = abs_x[1];
2420+ wm->input_dev->absmax[ABS_Y] = abs_y[1];
2421+ wm->input_dev->absmax[ABS_PRESSURE] = abs_p[1];
2422+ wm->input_dev->absmin[ABS_X] = abs_x[0];
2423+ wm->input_dev->absmin[ABS_Y] = abs_y[0];
2424+ wm->input_dev->absmin[ABS_PRESSURE] = abs_p[0];
2425+ wm->input_dev->absfuzz[ABS_X] = abs_x[2];
2426+ wm->input_dev->absfuzz[ABS_Y] = abs_y[2];
2427+ wm->input_dev->absfuzz[ABS_PRESSURE] = abs_p[2];
2428+ wm->input_dev->private = wm;
2429+ wm->codec = &wm97xx_codec;
2430+ if((ret = input_register_device(wm->input_dev)) < 0) {
2431+ kfree(wm);
2432+ return -ENOMEM;
2433+ }
2434+
2435+ if(aux_sys)
2436+ wm97xx_sys_add(dev);
2437+
2438+ /* set up physical characteristics */
2439+ wm->codec->digitiser_ioctl(wm, WM97XX_PHY_INIT);
2440+
2441+ /* load gpio cache */
2442+ wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG);
2443+ wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
2444+ wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
2445+ wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
2446+ wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
2447+ wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
2448+
2449+ /* register our battery device */
2450+ if (!(wm->battery_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) {
2451+ ret = -ENOMEM;
2452+ goto batt_err;
2453+ }
2454+ wm->battery_dev->bus = &wm97xx_bus_type;
2455+ strcpy(wm->battery_dev->bus_id,"wm97xx-battery");
2456+ wm->battery_dev->driver_data = wm;
2457+ wm->battery_dev->parent = dev;
2458+ wm->battery_dev->release = wm97xx_release;
2459+ if((ret = device_register(wm->battery_dev)) < 0)
2460+ goto batt_reg_err;
2461+
2462+ /* register our extended touch device (for machine specific extensions) */
2463+ if (!(wm->touch_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) {
2464+ ret = -ENOMEM;
2465+ goto touch_err;
2466+ }
2467+ wm->touch_dev->bus = &wm97xx_bus_type;
2468+ strcpy(wm->touch_dev->bus_id,"wm97xx-touchscreen");
2469+ wm->touch_dev->driver_data = wm;
2470+ wm->touch_dev->parent = dev;
2471+ wm->touch_dev->release = wm97xx_release;
2472+ if((ret = device_register(wm->touch_dev)) < 0)
2473+ goto touch_reg_err;
2474+
2475+ return ret;
2476+
2477+touch_reg_err:
2478+ kfree(wm->touch_dev);
2479+touch_err:
2480+ device_unregister(wm->battery_dev);
2481+batt_reg_err:
2482+ kfree(wm->battery_dev);
2483+batt_err:
2484+ input_unregister_device(wm->input_dev);
2485+ kfree(wm);
2486+ return ret;
2487+}
2488+
2489+static int wm97xx_remove(struct device *dev)
2490+{
2491+ struct wm97xx *wm = dev_get_drvdata(dev);
2492+
2493+ /* Stop touch reader thread */
2494+ if (wm->ts_task) {
2495+ wm->ts_task = NULL;
2496+ wm->pen_is_down = 1;
2497+ wake_up_interruptible(&wm->pen_irq_wait);
2498+ wait_for_completion(&wm->ts_exit);
2499+ }
2500+ device_unregister(wm->battery_dev);
2501+ device_unregister(wm->touch_dev);
2502+ input_unregister_device(wm->input_dev);
2503+
2504+ if(aux_sys)
2505+ wm97xx_sys_remove(dev);
2506+
2507+ kfree(wm);
2508+ return 0;
2509+}
2510+
2511+#ifdef CONFIG_PM
2512+int wm97xx_resume(struct device* dev)
2513+{
2514+ struct wm97xx *wm = dev_get_drvdata(dev);
2515+
2516+ /* restore digitiser and gpio's */
2517+ if(wm->id == WM9713_ID2) {
2518+ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
2519+ wm97xx_reg_write(wm, 0x5a, wm->misc);
2520+ if(wm->ts_use_count) {
2521+ u16 reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
2522+ wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
2523+ }
2524+ }
2525+
2526+ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]);
2527+ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]);
2528+
2529+ wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]);
2530+ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]);
2531+ wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]);
2532+ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]);
2533+ wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
2534+ wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
2535+
2536+ return 0;
2537+}
2538+
2539+#else
2540+#define wm97xx_resume NULL
2541+#endif
2542+
2543+int wm97xx_register_mach_ops(struct wm97xx *wm, struct wm97xx_mach_ops *mach_ops)
2544+{
2545+ mutex_lock(&wm->codec_mutex);
2546+ if(wm->mach_ops) {
2547+ mutex_unlock(&wm->codec_mutex);
2548+ return -EINVAL;
2549+ }
2550+ wm->mach_ops = mach_ops;
2551+ mutex_unlock(&wm->codec_mutex);
2552+ return 0;
2553+}
2554+
2555+void wm97xx_unregister_mach_ops(struct wm97xx *wm)
2556+{
2557+ mutex_lock(&wm->codec_mutex);
2558+ wm->mach_ops = NULL;
2559+ mutex_unlock(&wm->codec_mutex);
2560+}
2561+
2562+static struct device_driver wm97xx_driver = {
2563+ .name = "ac97",
2564+ .bus = &ac97_bus_type,
2565+ .owner = THIS_MODULE,
2566+ .probe = wm97xx_probe,
2567+ .remove = wm97xx_remove,
2568+ .resume = wm97xx_resume,
2569+};
2570+
2571+static int __init wm97xx_init(void)
2572+{
2573+ int ret;
2574+
2575+ info("version %s liam.girdwood@wolfsonmicro.com", WM_CORE_VERSION);
2576+ if((ret = bus_register(&wm97xx_bus_type)) < 0)
2577+ return ret;
2578+ return driver_register(&wm97xx_driver);
2579+}
2580+
2581+static void __exit wm97xx_exit(void)
2582+{
2583+ driver_unregister(&wm97xx_driver);
2584+ bus_unregister(&wm97xx_bus_type);
2585+}
2586+
2587+EXPORT_SYMBOL_GPL(wm97xx_get_gpio);
2588+EXPORT_SYMBOL_GPL(wm97xx_set_gpio);
2589+EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
2590+EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
2591+EXPORT_SYMBOL_GPL(wm97xx_reg_read);
2592+EXPORT_SYMBOL_GPL(wm97xx_reg_write);
2593+EXPORT_SYMBOL_GPL(wm97xx_bus_type);
2594+EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops);
2595+EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
2596+
2597+module_init(wm97xx_init);
2598+module_exit(wm97xx_exit);
2599+
2600+/* Module information */
2601+MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
2602+MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
2603+MODULE_LICENSE("GPL");
2604Index: linux-2.6.17/include/linux/wm97xx.h
2605===================================================================
2606--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2607+++ linux-2.6.17/include/linux/wm97xx.h 2006-09-19 20:36:47.973052250 +0200
2608@@ -0,0 +1,291 @@
2609+
2610+/*
2611+ * Register bits and API for Wolfson WM97xx series of codecs
2612+ */
2613+
2614+#ifndef _LINUX_WM97XX_H
2615+#define _LINUX_WM97XX_H
2616+
2617+#include <sound/driver.h>
2618+#include <sound/core.h>
2619+#include <sound/pcm.h>
2620+#include <sound/ac97_codec.h>
2621+#include <sound/initval.h>
2622+#include <linux/types.h>
2623+#include <linux/list.h>
2624+#include <linux/input.h> /* Input device layer */
2625+
2626+/*
2627+ * WM97xx AC97 Touchscreen registers
2628+ */
2629+#define AC97_WM97XX_DIGITISER1 0x76
2630+#define AC97_WM97XX_DIGITISER2 0x78
2631+#define AC97_WM97XX_DIGITISER_RD 0x7a
2632+#define AC97_WM9713_DIG1 0x74
2633+#define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1
2634+#define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2
2635+
2636+/*
2637+ * WM97xx register bits
2638+ */
2639+#define WM97XX_POLL 0x8000 /* initiate a polling measurement */
2640+#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */
2641+#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */
2642+#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */
2643+#define WM97XX_ADCSEL_MASK 0x7000
2644+#define WM97XX_COO 0x0800 /* enable coordinate mode */
2645+#define WM97XX_CTC 0x0400 /* enable continuous mode */
2646+#define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */
2647+#define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */
2648+#define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */
2649+#define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */
2650+#define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */
2651+#define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */
2652+#define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */
2653+#define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */
2654+#define WM97XX_CM_RATE_MASK 0x03f0
2655+#define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0))
2656+#define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */
2657+#define WM97XX_DELAY_MASK 0x00f0
2658+#define WM97XX_SLEN 0x0008 /* slot read back enable */
2659+#define WM97XX_SLT(i) ((i - 5) & 0x7) /* touchpanel slot selection (5-11) */
2660+#define WM97XX_SLT_MASK 0x0007
2661+#define WM97XX_PRP_DETW 0x4000 /* pen detect on, digitiser off, wake up */
2662+#define WM97XX_PRP_DET 0x8000 /* pen detect on, digitiser off, no wake up */
2663+#define WM97XX_PRP_DET_DIG 0xc000 /* pen detect on, digitiser on */
2664+#define WM97XX_RPR 0x2000 /* wake up on pen down */
2665+#define WM97XX_PEN_DOWN 0x8000 /* pen is down */
2666+#define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */
2667+
2668+#define WM97XX_AUX_ID1 0x8001
2669+#define WM97XX_AUX_ID2 0x8002
2670+#define WM97XX_AUX_ID3 0x8003
2671+#define WM97XX_AUX_ID4 0x8004
2672+
2673+
2674+/* WM9712 Bits */
2675+#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */
2676+#define WM9712_PDEN 0x0800 /* measure only when pen down */
2677+#define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */
2678+#define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */
2679+#define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */
2680+#define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */
2681+#define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */
2682+#define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */
2683+#define WM9712_PD(i) (0x1 << i) /* power management */
2684+
2685+/* WM9712 Registers */
2686+#define AC97_WM9712_POWER 0x24
2687+#define AC97_WM9712_REV 0x58
2688+
2689+/* WM9705 Bits */
2690+#define WM9705_PDEN 0x1000 /* measure only when pen is down */
2691+#define WM9705_PINV 0x0800 /* inverts sense of pen down output */
2692+#define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */
2693+#define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */
2694+#define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */
2695+#define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */
2696+#define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */
2697+#define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */
2698+#define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */
2699+#define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */
2700+#define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */
2701+
2702+
2703+/* WM9713 Bits */
2704+#define WM9713_PDPOL 0x0400 /* Pen down polarity */
2705+#define WM9713_POLL 0x0200 /* initiate a polling measurement */
2706+#define WM9713_CTC 0x0100 /* enable continuous mode */
2707+#define WM9713_ADCSEL_X 0x0002 /* X measurement */
2708+#define WM9713_ADCSEL_Y 0x0004 /* Y measurement */
2709+#define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */
2710+#define WM9713_COO 0x0001 /* enable coordinate mode */
2711+#define WM9713_PDEN 0x0800 /* measure only when pen down */
2712+#define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */
2713+#define WM9713_WAIT 0x0200 /* coordinate wait */
2714+
2715+/* AUX ADC ID's */
2716+#define TS_COMP1 0x0
2717+#define TS_COMP2 0x1
2718+#define TS_BMON 0x2
2719+#define TS_WIPER 0x3
2720+
2721+/* ID numbers */
2722+#define WM97XX_ID1 0x574d
2723+#define WM9712_ID2 0x4c12
2724+#define WM9705_ID2 0x4c05
2725+#define WM9713_ID2 0x4c13
2726+
2727+/* Codec GPIO's */
2728+#define WM97XX_MAX_GPIO 16
2729+#define WM97XX_GPIO_1 (1 << 1)
2730+#define WM97XX_GPIO_2 (1 << 2)
2731+#define WM97XX_GPIO_3 (1 << 3)
2732+#define WM97XX_GPIO_4 (1 << 4)
2733+#define WM97XX_GPIO_5 (1 << 5)
2734+#define WM97XX_GPIO_6 (1 << 6)
2735+#define WM97XX_GPIO_7 (1 << 7)
2736+#define WM97XX_GPIO_8 (1 << 8)
2737+#define WM97XX_GPIO_9 (1 << 9)
2738+#define WM97XX_GPIO_10 (1 << 10)
2739+#define WM97XX_GPIO_11 (1 << 11)
2740+#define WM97XX_GPIO_12 (1 << 12)
2741+#define WM97XX_GPIO_13 (1 << 13)
2742+#define WM97XX_GPIO_14 (1 << 14)
2743+#define WM97XX_GPIO_15 (1 << 15)
2744+
2745+
2746+#define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */
2747+
2748+
2749+/*---------------- Return codes from sample reading functions ---------------*/
2750+
2751+/* More data is available; call the sample gathering function again */
2752+#define RC_AGAIN 0x00000001
2753+/* The returned sample is valid */
2754+#define RC_VALID 0x00000002
2755+/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */
2756+#define RC_PENUP 0x00000004
2757+/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful
2758+ to tell the handler that the pen is down but we don't know yet his coords,
2759+ so the handler should not sleep or wait for pendown irq) */
2760+#define RC_PENDOWN 0x00000008
2761+
2762+/* The wm97xx driver provides a private API for writing platform-specific
2763+ * drivers.
2764+ */
2765+
2766+/* The structure used to return arch specific sampled data into */
2767+struct wm97xx_data {
2768+ int x;
2769+ int y;
2770+ int p;
2771+};
2772+
2773+/* Codec GPIO status
2774+ */
2775+typedef enum {
2776+ WM97XX_GPIO_HIGH,
2777+ WM97XX_GPIO_LOW
2778+} wm97xx_gpio_status_t;
2779+
2780+/* Codec GPIO direction
2781+ */
2782+typedef enum {
2783+ WM97XX_GPIO_IN,
2784+ WM97XX_GPIO_OUT
2785+} wm97xx_gpio_dir_t;
2786+
2787+/* Codec GPIO polarity
2788+ */
2789+typedef enum {
2790+ WM97XX_GPIO_POL_HIGH,
2791+ WM97XX_GPIO_POL_LOW
2792+} wm97xx_gpio_pol_t;
2793+
2794+/* Codec GPIO sticky
2795+ */
2796+typedef enum {
2797+ WM97XX_GPIO_STICKY,
2798+ WM97XX_GPIO_NOTSTICKY
2799+} wm97xx_gpio_sticky_t;
2800+
2801+/* Codec GPIO wake
2802+ */
2803+typedef enum {
2804+ WM97XX_GPIO_WAKE,
2805+ WM97XX_GPIO_NOWAKE
2806+} wm97xx_gpio_wake_t;
2807+
2808+
2809+/*
2810+ * Digitiser ioctl commands
2811+ */
2812+#define WM97XX_DIG_START 0x1
2813+#define WM97XX_DIG_STOP 0x2
2814+#define WM97XX_PHY_INIT 0x3
2815+#define WM97XX_AUX_PREPARE 0x4
2816+#define WM97XX_DIG_RESTORE 0x5
2817+
2818+struct wm97xx;
2819+extern struct wm97xx_codec_drv wm97xx_codec;
2820+
2821+/*
2822+ * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs
2823+ */
2824+struct wm97xx_codec_drv {
2825+ u16 id;
2826+ char *name;
2827+ int (*poll_sample) (struct wm97xx *, int adcsel, int *sample); /* read 1 sample */
2828+ int (*poll_touch) (struct wm97xx *, struct wm97xx_data *); /* read X,Y,[P] in poll */
2829+ int (*digitiser_ioctl) (struct wm97xx *, int cmd);
2830+ int (*acc_enable) (struct wm97xx *, int enable);
2831+};
2832+
2833+
2834+/* Machine specific and accelerated touch operations */
2835+struct wm97xx_mach_ops {
2836+
2837+ /* accelerated touch readback - coords are transmited on AC97 link */
2838+ int acc_enabled;
2839+ void (*acc_pen_up) (struct wm97xx *);
2840+ int (*acc_pen_down) (struct wm97xx *);
2841+ int (*acc_startup) (struct wm97xx *);
2842+ void (*acc_shutdown) (struct wm97xx *);
2843+
2844+ /* pre and post sample - can be used to minimise any analog noise */
2845+ void (*pre_sample) (int); /* function to run before sampling */
2846+ void (*post_sample) (int); /* function to run after sampling */
2847+};
2848+
2849+struct wm97xx {
2850+ u16 dig[3], id, gpio[6], misc; /* Cached codec registers */
2851+ u16 dig_save[3]; /* saved during aux reading */
2852+ struct wm97xx_codec_drv *codec; /* attached codec driver*/
2853+ struct input_dev* input_dev; /* touchscreen input device */
2854+ ac97_t *ac97; /* ALSA codec access */
2855+ struct device *dev; /* ALSA device */
2856+ struct device *battery_dev;
2857+ struct device *touch_dev;
2858+ struct wm97xx_mach_ops *mach_ops;
2859+ struct mutex codec_mutex;
2860+ struct completion ts_init;
2861+ struct completion ts_exit;
2862+ struct task_struct *ts_task;
2863+ unsigned int pen_irq; /* Pen IRQ number in use */
2864+ wait_queue_head_t pen_irq_wait; /* Pen IRQ wait queue */
2865+ struct workqueue_struct *pen_irq_workq;
2866+ struct work_struct pen_event_work;
2867+ u16 acc_slot; /* AC97 slot used for acc touch data */
2868+ u16 acc_rate; /* acc touch data rate */
2869+ unsigned int ts_use_count;
2870+ unsigned pen_is_down:1; /* Pen is down */
2871+ unsigned aux_waiting:1; /* aux measurement waiting */
2872+ unsigned pen_probably_down:1; /* used in polling mode */
2873+};
2874+
2875+/* Codec GPIO access (not supported on WM9705)
2876+ * This can be used to set/get codec GPIO and Virtual GPIO status.
2877+ */
2878+wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio);
2879+void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
2880+ wm97xx_gpio_status_t status);
2881+void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio,
2882+ wm97xx_gpio_dir_t dir,
2883+ wm97xx_gpio_pol_t pol,
2884+ wm97xx_gpio_sticky_t sticky,
2885+ wm97xx_gpio_wake_t wake);
2886+
2887+/* codec AC97 IO access */
2888+int wm97xx_reg_read(struct wm97xx *wm, u16 reg);
2889+void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val);
2890+
2891+/* aux adc readback */
2892+int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel);
2893+
2894+/* machine ops */
2895+int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *);
2896+void wm97xx_unregister_mach_ops(struct wm97xx *);
2897+
2898+extern struct bus_type wm97xx_bus_type;
2899+#endif
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite-boot.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite-boot.patch
new file mode 100644
index 0000000000..f41928eca5
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite-boot.patch
@@ -0,0 +1,45 @@
1From 04c42f566c68b757fdadf54e0e0f9dfe9f3f9b06 Mon Sep 17 00:00:00 2001
2From: eric miao <eric.miao@marvell.com>
3Date: Tue, 19 Jun 2007 16:42:53 +0800
4Subject: [PATCH] [PATCH] make zylonite boot
5
61. reuse head-xscale.S for XSC3
7
82. add a workaround for machine ID assignment, which should be done
9 by boot loader
10---
11 arch/arm/boot/compressed/Makefile | 4 ++++
12 arch/arm/boot/compressed/head-xscale.S | 5 +++++
13 2 files changed, 9 insertions(+)
14
15Index: linux-2.6-pxa3/arch/arm/boot/compressed/Makefile
16===================================================================
17--- linux-2.6-pxa3.orig/arch/arm/boot/compressed/Makefile 2007-09-24 11:25:57.000000000 +0200
18+++ linux-2.6-pxa3/arch/arm/boot/compressed/Makefile 2007-09-24 12:26:53.000000000 +0200
19@@ -40,6 +40,10 @@
20 OBJS += head-xscale.o
21 endif
22
23+ifeq ($(CONFIG_CPU_XSC3),y)
24+OBJS += head-xscale.o
25+endif
26+
27 ifeq ($(CONFIG_PXA_SHARPSL),y)
28 OBJS += head-sharpsl.o
29 endif
30Index: linux-2.6-pxa3/arch/arm/boot/compressed/head-xscale.S
31===================================================================
32--- linux-2.6-pxa3.orig/arch/arm/boot/compressed/head-xscale.S 2007-09-24 11:42:27.000000000 +0200
33+++ linux-2.6-pxa3/arch/arm/boot/compressed/head-xscale.S 2007-09-24 12:26:02.000000000 +0200
34@@ -33,6 +33,11 @@
35 bic r0, r0, #0x1000 @ clear Icache
36 mcr p15, 0, r0, c1, c0, 0
37
38+#ifdef CONFIG_MACH_ZYLONITE
39+ mov r7, #(MACH_TYPE_ZYLONITE & 0xff)
40+ orr r7, r7, #(MACH_TYPE_ZYLONITE & 0xff00)
41+#endif
42+
43 #ifdef CONFIG_ARCH_COTULLA_IDP
44 mov r7, #MACH_TYPE_COTULLA_IDP
45 #endif
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_keypad-r0.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_keypad-r0.patch
new file mode 100644
index 0000000000..1889b3884e
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_keypad-r0.patch
@@ -0,0 +1,1187 @@
1Eric Miao's pxa keypad patchset backport.
2---
3 arch/arm/mach-pxa/devices.h | 1
4 arch/arm/mach-pxa/generic.c | 31 +
5 arch/arm/mach-pxa/pxa27x.c | 2
6 arch/arm/mach-pxa/pxa300.c | 6
7 arch/arm/mach-pxa/pxa3xx.c | 1
8 arch/arm/mach-pxa/zylonite.c | 68 +++
9 drivers/input/keyboard/Kconfig | 8
10 drivers/input/keyboard/Makefile | 2
11 drivers/input/keyboard/pxa27x_keyboard.c | 273 -------------
12 drivers/input/keyboard/pxa27x_keypad.c | 575 +++++++++++++++++++++++++++++
13 include/asm-arm/arch-pxa/irqs.h | 2
14 include/asm-arm/arch-pxa/pxa27x_keyboard.h | 13
15 include/asm-arm/arch-pxa/pxa27x_keypad.h | 58 ++
16 13 files changed, 745 insertions(+), 295 deletions(-)
17
18Index: linux-2.6.23-z-input/drivers/input/keyboard/Kconfig
19===================================================================
20--- linux-2.6.23-z-input.orig/drivers/input/keyboard/Kconfig 2008-02-18 01:43:28.000000000 +0100
21+++ linux-2.6.23-z-input/drivers/input/keyboard/Kconfig 2008-02-18 01:43:28.000000000 +0100
22@@ -218,13 +218,13 @@
23 module will be called omap-keypad.
24
25 config KEYBOARD_PXA27x
26- tristate "PXA27x keyboard support"
27- depends on PXA27x
28+ tristate "PXA27x/PXA3xx keypad support"
29+ depends on PXA27x || PXA3xx
30 help
31- Enable support for PXA27x matrix keyboard controller
32+ Enable support for PXA27x/PXA3xx keypad controller
33
34 To compile this driver as a module, choose M here: the
35- module will be called pxa27x_keyboard.
36+ module will be called pxa27x_keypad.
37
38 config KEYBOARD_AAED2000
39 tristate "AAED-2000 keyboard"
40Index: linux-2.6.23-z-input/drivers/input/keyboard/Makefile
41===================================================================
42--- linux-2.6.23-z-input.orig/drivers/input/keyboard/Makefile 2008-02-18 01:43:28.000000000 +0100
43+++ linux-2.6.23-z-input/drivers/input/keyboard/Makefile 2008-02-18 01:43:28.000000000 +0100
44@@ -18,7 +18,7 @@
45 obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
46 obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
47 obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
48-obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o
49+obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
50 obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
51 obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
52 obj-$(CONFIG_KEYBOARD_ASIC3) += asic3_keys.o
53Index: linux-2.6.23-z-input/drivers/input/keyboard/pxa27x_keypad.c
54===================================================================
55--- /dev/null 1970-01-01 00:00:00.000000000 +0000
56+++ linux-2.6.23-z-input/drivers/input/keyboard/pxa27x_keypad.c 2008-02-19 01:40:04.000000000 +0100
57@@ -0,0 +1,575 @@
58+/*
59+ * linux/drivers/input/keyboard/pxa27x_keypad.c
60+ *
61+ * Driver for the pxa27x matrix keyboard controller.
62+ *
63+ * Created: Feb 22, 2007
64+ * Author: Rodolfo Giometti <giometti@linux.it>
65+ *
66+ * Based on a previous implementations by Kevin O'Connor
67+ * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and
68+ * on some suggestions by Nicolas Pitre <nico@cam.org>.
69+ *
70+ * This program is free software; you can redistribute it and/or modify
71+ * it under the terms of the GNU General Public License version 2 as
72+ * published by the Free Software Foundation.
73+ */
74+
75+
76+#include <linux/kernel.h>
77+#include <linux/module.h>
78+#include <linux/init.h>
79+#include <linux/interrupt.h>
80+#include <linux/input.h>
81+#include <linux/device.h>
82+#include <linux/platform_device.h>
83+#include <linux/clk.h>
84+#include <linux/err.h>
85+
86+#include <asm/mach-types.h>
87+#include <asm/mach/arch.h>
88+#include <asm/mach/map.h>
89+
90+#include <asm/arch/hardware.h>
91+#include <asm/arch/mfp.h>
92+#include <asm/arch/pxa27x_keypad.h>
93+
94+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
95+
96+/*
97+ * Keypad Controller registers
98+ */
99+#define KPC 0x0000 /* Keypad Control register */
100+#define KPDK 0x0008 /* Keypad Direct Key register */
101+#define KPREC 0x0010 /* Keypad Rotary Encoder register */
102+#define KPMK 0x0018 /* Keypad Matrix Key register */
103+#define KPAS 0x0020 /* Keypad Automatic Scan register */
104+
105+/* Keypad Automatic Scan Multiple Key Presser register 0-3 */
106+#define KPASMKP0 0x0028
107+#define KPASMKP1 0x0030
108+#define KPASMKP2 0x0038
109+#define KPASMKP3 0x0040
110+#define KPKDI 0x0048
111+
112+/* bit definitions */
113+#define KPC_MKRN(n) ((((n) - 1) & 0x7) << 26) /* matrix key row number */
114+#define KPC_MKCN(n) ((((n) - 1) & 0x7) << 23) /* matrix key column number */
115+#define KPC_DKN(n) ((((n) - 1) & 0x7) << 6) /* direct key number */
116+
117+#define KPC_AS (0x1 << 30) /* Automatic Scan bit */
118+#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */
119+#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */
120+#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */
121+
122+#define KPC_MS(n) (0x1 << (13 + (n))) /* Matrix scan line 'n' */
123+#define KPC_MS_ALL (0xff << 13)
124+
125+#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */
126+#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */
127+#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */
128+#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */
129+#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */
130+#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */
131+#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */
132+#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */
133+#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */
134+
135+#define KPDK_DKP (0x1 << 31)
136+#define KPDK_DK(n) ((n) & 0xff)
137+
138+#define KPREC_OF1 (0x1 << 31)
139+#define kPREC_UF1 (0x1 << 30)
140+#define KPREC_OF0 (0x1 << 15)
141+#define KPREC_UF0 (0x1 << 14)
142+
143+#define KPREC_RECOUNT0(n) ((n) & 0xff)
144+#define KPREC_RECOUNT1(n) (((n) >> 16) & 0xff)
145+
146+#define KPMK_MKP (0x1 << 31)
147+#define KPAS_SO (0x1 << 31)
148+#define KPASMKPx_SO (0x1 << 31)
149+
150+#define KPAS_MUKP(n) (((n) >> 26) & 0x1f)
151+#define KPAS_RP(n) (((n) >> 4) & 0xf)
152+#define KPAS_CP(n) ((n) & 0xf)
153+
154+#define KPASMKP_MKC_MASK (0xff)
155+
156+#define keypad_readl(off) __raw_readl(keypad->mmio_base + (off))
157+#define keypad_writel(off, v) __raw_writel((v), keypad->mmio_base + (off))
158+
159+#define MAX_MATRIX_KEY_NUM (8 * 8)
160+
161+struct pxa27x_keypad {
162+ struct pxa27x_keypad_platform_data *pdata;
163+
164+ struct clk *clk;
165+ struct input_dev *input_dev;
166+ void __iomem *mmio_base;
167+
168+ /* matrix key code map */
169+ unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
170+
171+ /* state row bits of each column scan */
172+ uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
173+ uint32_t direct_key_state;
174+
175+ unsigned int direct_key_mask;
176+
177+ int rotary_rel_code[2];
178+ int rotary_up_key[2];
179+ int rotary_down_key[2];
180+};
181+
182+static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
183+{
184+ struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
185+ struct input_dev *input_dev = keypad->input_dev;
186+ unsigned int *key;
187+ int i;
188+
189+ key = &pdata->matrix_key_map[0];
190+ for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
191+ int row = ((*key) >> 28) & 0xf;
192+ int col = ((*key) >> 24) & 0xf;
193+ int code = (*key) & 0xffffff;
194+
195+ keypad->matrix_keycodes[(row << 3) + col] = code;
196+ set_bit(code, input_dev->keybit);
197+ }
198+
199+ keypad->rotary_up_key[0] = pdata->rotary0_up_key;
200+ keypad->rotary_up_key[1] = pdata->rotary1_up_key;
201+ keypad->rotary_down_key[0] = pdata->rotary0_down_key;
202+ keypad->rotary_down_key[1] = pdata->rotary1_down_key;
203+ keypad->rotary_rel_code[0] = pdata->rotary0_rel_code;
204+ keypad->rotary_rel_code[1] = pdata->rotary1_rel_code;
205+
206+ if (pdata->rotary0_up_key && pdata->rotary0_down_key) {
207+ set_bit(pdata->rotary0_up_key, input_dev->keybit);
208+ set_bit(pdata->rotary0_down_key, input_dev->keybit);
209+ } else
210+ set_bit(pdata->rotary0_rel_code, input_dev->relbit);
211+
212+ if (pdata->rotary1_up_key && pdata->rotary1_down_key) {
213+ set_bit(pdata->rotary1_up_key, input_dev->keybit);
214+ set_bit(pdata->rotary1_down_key, input_dev->keybit);
215+ } else
216+ set_bit(pdata->rotary1_rel_code, input_dev->relbit);
217+}
218+
219+static inline unsigned int lookup_matrix_keycode(
220+ struct pxa27x_keypad *keypad, int row, int col)
221+{
222+ return keypad->matrix_keycodes[(row << 3) + col];
223+}
224+
225+static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
226+{
227+ struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
228+ int row, col, num_keys_pressed = 0;
229+ uint32_t new_state[MAX_MATRIX_KEY_COLS];
230+ uint32_t kpas = keypad_readl(KPAS);
231+
232+ num_keys_pressed = KPAS_MUKP(kpas);
233+
234+ memset(new_state, 0, sizeof(new_state));
235+
236+ if (num_keys_pressed == 0)
237+ goto scan;
238+
239+ if (num_keys_pressed == 1) {
240+ col = KPAS_CP(kpas);
241+ row = KPAS_RP(kpas);
242+
243+ /* if invalid row/col, treat as no key pressed */
244+ if (col >= pdata->matrix_key_cols ||
245+ row >= pdata->matrix_key_rows)
246+ goto scan;
247+
248+ new_state[col] = (1 << row);
249+ goto scan;
250+ }
251+
252+ if (num_keys_pressed > 1) {
253+ uint32_t kpasmkp0 = keypad_readl(KPASMKP0);
254+ uint32_t kpasmkp1 = keypad_readl(KPASMKP1);
255+ uint32_t kpasmkp2 = keypad_readl(KPASMKP2);
256+ uint32_t kpasmkp3 = keypad_readl(KPASMKP3);
257+
258+ new_state[0] = kpasmkp0 & KPASMKP_MKC_MASK;
259+ new_state[1] = (kpasmkp0 >> 16) & KPASMKP_MKC_MASK;
260+ new_state[2] = kpasmkp1 & KPASMKP_MKC_MASK;
261+ new_state[3] = (kpasmkp1 >> 16) & KPASMKP_MKC_MASK;
262+ new_state[4] = kpasmkp2 & KPASMKP_MKC_MASK;
263+ new_state[5] = (kpasmkp2 >> 16) & KPASMKP_MKC_MASK;
264+ new_state[6] = kpasmkp3 & KPASMKP_MKC_MASK;
265+ new_state[7] = (kpasmkp3 >> 16) & KPASMKP_MKC_MASK;
266+ }
267+scan:
268+ for (col = 0; col < pdata->matrix_key_cols; col++) {
269+ uint32_t bits_changed;
270+
271+ bits_changed = keypad->matrix_key_state[col] ^ new_state[col];
272+ if (bits_changed == 0)
273+ continue;
274+
275+ for (row = 0; row < pdata->matrix_key_rows; row++) {
276+ if ((bits_changed & (1 << row)) == 0)
277+ continue;
278+
279+ input_report_key(keypad->input_dev,
280+ lookup_matrix_keycode(keypad, row, col),
281+ new_state[col] & (1 << row));
282+ }
283+ }
284+ input_sync(keypad->input_dev);
285+ memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
286+}
287+
288+#define DEFAULT_KPREC (0x007f007f)
289+
290+static inline int rotary_delta(uint32_t kprec)
291+{
292+ if (kprec & KPREC_OF0)
293+ return (kprec & 0xff) + 0x7f;
294+ else if (kprec & KPREC_UF0)
295+ return (kprec & 0xff) - 0x7f - 0xff;
296+ else
297+ return (kprec & 0xff) - 0x7f;
298+}
299+
300+static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta)
301+{
302+ struct input_dev *dev = keypad->input_dev;
303+
304+ if (delta == 0)
305+ return;
306+
307+ if (keypad->rotary_up_key[r] && keypad->rotary_down_key[r]) {
308+ int keycode = (delta > 0) ? keypad->rotary_up_key[r] :
309+ keypad->rotary_down_key[r];
310+
311+ /* simulate a press-n-release */
312+ input_report_key(dev, keycode, 1);
313+ input_sync(dev);
314+ input_report_key(dev, keycode, 0);
315+ input_sync(dev);
316+ } else {
317+ input_report_rel(dev, keypad->rotary_rel_code[r], delta);
318+ input_sync(dev);
319+ }
320+}
321+
322+static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
323+{
324+ struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
325+ uint32_t kprec;
326+
327+ /* read and reset to default count value */
328+ kprec = keypad_readl(KPREC);
329+ keypad_writel(KPREC, DEFAULT_KPREC);
330+
331+ if (pdata->enable_rotary0)
332+ report_rotary_event(keypad, 0, rotary_delta(kprec));
333+
334+ if (pdata->enable_rotary1)
335+ report_rotary_event(keypad, 1, rotary_delta(kprec >> 16));
336+}
337+
338+static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
339+{
340+ struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
341+ unsigned int new_state;
342+ uint32_t kpdk, bits_changed;
343+ int i;
344+
345+ kpdk = keypad_readl(KPDK);
346+
347+ if (pdata->enable_rotary0 || pdata->enable_rotary1)
348+ pxa27x_keypad_scan_rotary(keypad);
349+
350+ if (pdata->direct_key_map == NULL)
351+ return;
352+
353+ new_state = KPDK_DK(kpdk) & keypad->direct_key_mask;
354+ bits_changed = keypad->direct_key_state ^ new_state;
355+
356+ if (bits_changed == 0)
357+ return;
358+
359+ for (i = 0; i < pdata->direct_key_num; i++) {
360+ if (bits_changed & (1 << i))
361+ input_report_key(keypad->input_dev,
362+ pdata->direct_key_map[i],
363+ (new_state & (1 << i)));
364+ }
365+ input_sync(keypad->input_dev);
366+ keypad->direct_key_state = new_state;
367+}
368+
369+static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
370+{
371+ struct pxa27x_keypad *keypad = dev_id;
372+ unsigned long kpc = keypad_readl(KPC);
373+
374+ if (kpc & KPC_DI)
375+ pxa27x_keypad_scan_direct(keypad);
376+
377+ if (kpc & KPC_MI)
378+ pxa27x_keypad_scan_matrix(keypad);
379+
380+ return IRQ_HANDLED;
381+}
382+
383+static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
384+{
385+ struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
386+ unsigned int mask = 0, direct_key_num = 0;
387+ unsigned long kpc = 0;
388+
389+ /* enable matrix keys with automatic scan */
390+ if (pdata->matrix_key_rows && pdata->matrix_key_cols) {
391+ kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL;
392+ kpc |= KPC_MKRN(pdata->matrix_key_rows) |
393+ KPC_MKCN(pdata->matrix_key_cols);
394+ }
395+
396+ /* enable rotary key, debounce interval same as direct keys */
397+ if (pdata->enable_rotary0) {
398+ mask |= 0x03;
399+ direct_key_num = 2;
400+ kpc |= KPC_REE0;
401+ }
402+
403+ if (pdata->enable_rotary1) {
404+ mask |= 0x0c;
405+ direct_key_num = 4;
406+ kpc |= KPC_REE1;
407+ }
408+
409+ if (pdata->direct_key_num > direct_key_num)
410+ direct_key_num = pdata->direct_key_num;
411+
412+ keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask;
413+
414+ /* enable direct key */
415+ if (direct_key_num)
416+ kpc |= KPC_DE | KPC_DIE | KPC_DKN(direct_key_num);
417+
418+ keypad_writel(KPC, kpc | KPC_RE_ZERO_DEB);
419+ keypad_writel(KPREC, DEFAULT_KPREC);
420+ keypad_writel(KPKDI, pdata->debounce_interval);
421+}
422+
423+static int pxa27x_keypad_open(struct input_dev *dev)
424+{
425+ struct pxa27x_keypad *keypad = input_get_drvdata(dev);
426+
427+ /* Enable unit clock */
428+ clk_enable(keypad->clk);
429+ pxa27x_keypad_config(keypad);
430+
431+ return 0;
432+}
433+
434+static void pxa27x_keypad_close(struct input_dev *dev)
435+{
436+ struct pxa27x_keypad *keypad = input_get_drvdata(dev);
437+
438+ /* Disable clock unit */
439+ clk_disable(keypad->clk);
440+}
441+
442+#ifdef CONFIG_PM
443+static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
444+{
445+ struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
446+
447+ clk_disable(keypad->clk);
448+ return 0;
449+}
450+
451+static int pxa27x_keypad_resume(struct platform_device *pdev)
452+{
453+ struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
454+ struct input_dev *input_dev = keypad->input_dev;
455+
456+ mutex_lock(&input_dev->mutex);
457+
458+ if (input_dev->users) {
459+ /* Enable unit clock */
460+ clk_enable(keypad->clk);
461+ pxa27x_keypad_config(keypad);
462+ }
463+
464+ mutex_unlock(&input_dev->mutex);
465+
466+ return 0;
467+}
468+#else
469+#define pxa27x_keypad_suspend NULL
470+#define pxa27x_keypad_resume NULL
471+#endif
472+
473+#define res_size(res) ((res)->end - (res)->start + 1)
474+
475+static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
476+{
477+ struct pxa27x_keypad *keypad;
478+ struct input_dev *input_dev;
479+ struct resource *res;
480+ int irq, error;
481+
482+ keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
483+ if (keypad == NULL) {
484+ dev_err(&pdev->dev, "failed to allocate driver data\n");
485+ return -ENOMEM;
486+ }
487+
488+ keypad->pdata = pdev->dev.platform_data;
489+ if (keypad->pdata == NULL) {
490+ dev_err(&pdev->dev, "no platform data defined\n");
491+ error = -EINVAL;
492+ goto failed_free;
493+ }
494+
495+ irq = platform_get_irq(pdev, 0);
496+ if (irq < 0) {
497+ dev_err(&pdev->dev, "failed to get keypad irq\n");
498+ error = -ENXIO;
499+ goto failed_free;
500+ }
501+
502+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
503+ if (res == NULL) {
504+ dev_err(&pdev->dev, "failed to get I/O memory\n");
505+ error = -ENXIO;
506+ goto failed_free;
507+ }
508+
509+ res = request_mem_region(res->start, res_size(res), pdev->name);
510+ if (res == NULL) {
511+ dev_err(&pdev->dev, "failed to request I/O memory\n");
512+ error = -EBUSY;
513+ goto failed_free;
514+ }
515+
516+ keypad->mmio_base = ioremap(res->start, res_size(res));
517+ if (keypad->mmio_base == NULL) {
518+ dev_err(&pdev->dev, "failed to remap I/O memory\n");
519+ error = -ENXIO;
520+ goto failed_free_mem;
521+ }
522+
523+ keypad->clk = clk_get(&pdev->dev, "KBDCLK");
524+ if (IS_ERR(keypad->clk)) {
525+ dev_err(&pdev->dev, "failed to get keypad clock\n");
526+ error = PTR_ERR(keypad->clk);
527+ goto failed_free_io;
528+ }
529+
530+ /* Create and register the input driver. */
531+ input_dev = input_allocate_device();
532+ if (!input_dev) {
533+ dev_err(&pdev->dev, "failed to allocate input device\n");
534+ error = -ENOMEM;
535+ goto failed_put_clk;
536+ }
537+
538+ input_dev->name = pdev->name;
539+ input_dev->id.bustype = BUS_HOST;
540+ input_dev->open = pxa27x_keypad_open;
541+ input_dev->close = pxa27x_keypad_close;
542+ input_dev->dev.parent = &pdev->dev;
543+
544+ keypad->input_dev = input_dev;
545+ input_set_drvdata(input_dev, keypad);
546+
547+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
548+ BIT_MASK(EV_REL);
549+
550+ pxa27x_keypad_build_keycode(keypad);
551+ platform_set_drvdata(pdev, keypad);
552+
553+ error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED,
554+ pdev->name, keypad);
555+ if (error) {
556+ dev_err(&pdev->dev, "failed to request IRQ\n");
557+ goto failed_free_dev;
558+ }
559+
560+ /* Register the input device */
561+ error = input_register_device(input_dev);
562+ if (error) {
563+ dev_err(&pdev->dev, "failed to register input device\n");
564+ goto failed_free_irq;
565+ }
566+
567+ return 0;
568+
569+failed_free_irq:
570+ free_irq(irq, pdev);
571+ platform_set_drvdata(pdev, NULL);
572+failed_free_dev:
573+ input_free_device(input_dev);
574+failed_put_clk:
575+ clk_put(keypad->clk);
576+failed_free_io:
577+ iounmap(keypad->mmio_base);
578+failed_free_mem:
579+ release_mem_region(res->start, res_size(res));
580+failed_free:
581+ kfree(keypad);
582+ return error;
583+}
584+
585+static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
586+{
587+ struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
588+ struct resource *res;
589+
590+ free_irq(platform_get_irq(pdev, 0), pdev);
591+
592+ clk_disable(keypad->clk);
593+ clk_put(keypad->clk);
594+
595+ input_unregister_device(keypad->input_dev);
596+ input_free_device(keypad->input_dev);
597+
598+ iounmap(keypad->mmio_base);
599+
600+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
601+ release_mem_region(res->start, res_size(res));
602+
603+ platform_set_drvdata(pdev, NULL);
604+ kfree(keypad);
605+ return 0;
606+}
607+
608+static struct platform_driver pxa27x_keypad_driver = {
609+ .probe = pxa27x_keypad_probe,
610+ .remove = __devexit_p(pxa27x_keypad_remove),
611+ .suspend = pxa27x_keypad_suspend,
612+ .resume = pxa27x_keypad_resume,
613+ .driver = {
614+ .name = "pxa27x-keypad",
615+ },
616+};
617+
618+static int __init pxa27x_keypad_init(void)
619+{
620+ return platform_driver_register(&pxa27x_keypad_driver);
621+}
622+
623+static void __exit pxa27x_keypad_exit(void)
624+{
625+ platform_driver_unregister(&pxa27x_keypad_driver);
626+}
627+
628+module_init(pxa27x_keypad_init);
629+module_exit(pxa27x_keypad_exit);
630+
631+MODULE_DESCRIPTION("PXA27x Keypad Controller Driver");
632+MODULE_LICENSE("GPL");
633Index: linux-2.6.23-z-input/include/asm-arm/arch-pxa/pxa27x_keyboard.h
634===================================================================
635--- linux-2.6.23-z-input.orig/include/asm-arm/arch-pxa/pxa27x_keyboard.h 2007-10-09 22:31:38.000000000 +0200
636+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
637@@ -1,13 +0,0 @@
638-#define PXAKBD_MAXROW 8
639-#define PXAKBD_MAXCOL 8
640-
641-struct pxa27x_keyboard_platform_data {
642- int nr_rows, nr_cols;
643- int keycodes[PXAKBD_MAXROW][PXAKBD_MAXCOL];
644- int gpio_modes[PXAKBD_MAXROW + PXAKBD_MAXCOL];
645-
646-#ifdef CONFIG_PM
647- u32 reg_kpc;
648- u32 reg_kprec;
649-#endif
650-};
651Index: linux-2.6.23-z-input/include/asm-arm/arch-pxa/pxa27x_keypad.h
652===================================================================
653--- /dev/null 1970-01-01 00:00:00.000000000 +0000
654+++ linux-2.6.23-z-input/include/asm-arm/arch-pxa/pxa27x_keypad.h 2008-02-18 01:43:28.000000000 +0100
655@@ -0,0 +1,58 @@
656+#ifndef __ASM_ARCH_PXA27x_KEYPAD_H
657+#define __ASM_ARCH_PXA27x_KEYPAD_H
658+
659+#include <linux/input.h>
660+
661+#define MAX_MATRIX_KEY_ROWS (8)
662+#define MAX_MATRIX_KEY_COLS (8)
663+
664+/* pxa3xx keypad platform specific parameters
665+ *
666+ * NOTE:
667+ * 1. direct_key_num indicates the number of keys in the direct keypad
668+ * _plus_ the number of rotary-encoder sensor inputs, this can be
669+ * left as 0 if only rotary encoders are enabled, the driver will
670+ * automatically calculate this
671+ *
672+ * 2. direct_key_map is the key code map for the direct keys, if rotary
673+ * encoder(s) are enabled, direct key 0/1(2/3) will be ignored
674+ *
675+ * 3. rotary can be either interpreted as a relative input event (e.g.
676+ * REL_WHEEL/REL_HWHEEL) or specific keys (e.g. UP/DOWN/LEFT/RIGHT)
677+ *
678+ * 4. matrix key and direct key will use the same debounce_interval by
679+ * default, which should be sufficient in most cases
680+ */
681+struct pxa27x_keypad_platform_data {
682+
683+ /* code map for the matrix keys */
684+ unsigned int matrix_key_rows;
685+ unsigned int matrix_key_cols;
686+ unsigned int *matrix_key_map;
687+ int matrix_key_map_size;
688+
689+ /* direct keys */
690+ int direct_key_num;
691+ unsigned int direct_key_map[8];
692+
693+ /* rotary encoders 0 */
694+ int enable_rotary0;
695+ int rotary0_rel_code;
696+ int rotary0_up_key;
697+ int rotary0_down_key;
698+
699+ /* rotary encoders 1 */
700+ int enable_rotary1;
701+ int rotary1_rel_code;
702+ int rotary1_up_key;
703+ int rotary1_down_key;
704+
705+ /* key debounce interval */
706+ unsigned int debounce_interval;
707+};
708+
709+#define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val))
710+
711+extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
712+
713+#endif /* __ASM_ARCH_PXA27x_KEYPAD_H */
714Index: linux-2.6.23-z-input/drivers/input/keyboard/pxa27x_keyboard.c
715===================================================================
716--- linux-2.6.23-z-input.orig/drivers/input/keyboard/pxa27x_keyboard.c 2008-02-18 01:43:28.000000000 +0100
717+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
718@@ -1,273 +0,0 @@
719-/*
720- * linux/drivers/input/keyboard/pxa27x_keyboard.c
721- *
722- * Driver for the pxa27x matrix keyboard controller.
723- *
724- * Created: Feb 22, 2007
725- * Author: Rodolfo Giometti <giometti@linux.it>
726- *
727- * Based on a previous implementations by Kevin O'Connor
728- * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and
729- * on some suggestions by Nicolas Pitre <nico@cam.org>.
730- *
731- * This program is free software; you can redistribute it and/or modify
732- * it under the terms of the GNU General Public License version 2 as
733- * published by the Free Software Foundation.
734- */
735-
736-
737-#include <linux/kernel.h>
738-#include <linux/module.h>
739-#include <linux/init.h>
740-#include <linux/interrupt.h>
741-#include <linux/input.h>
742-#include <linux/device.h>
743-#include <linux/platform_device.h>
744-#include <linux/clk.h>
745-#include <linux/err.h>
746-
747-#include <asm/mach-types.h>
748-#include <asm/mach/arch.h>
749-#include <asm/mach/map.h>
750-
751-#include <asm/arch/hardware.h>
752-#include <asm/arch/pxa-regs.h>
753-#include <asm/arch/irqs.h>
754-#include <asm/arch/pxa27x_keyboard.h>
755-
756-#define DRIVER_NAME "pxa27x-keyboard"
757-
758-#define KPASMKP(col) (col/2 == 0 ? KPASMKP0 : \
759- col/2 == 1 ? KPASMKP1 : \
760- col/2 == 2 ? KPASMKP2 : KPASMKP3)
761-#define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2)))
762-
763-static struct clk *pxakbd_clk;
764-
765-static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id)
766-{
767- struct platform_device *pdev = dev_id;
768- struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data;
769- struct input_dev *input_dev = platform_get_drvdata(pdev);
770- unsigned long kpc = KPC;
771- int p, row, col, rel;
772-
773- if (kpc & KPC_DI) {
774- unsigned long kpdk = KPDK;
775-
776- if (!(kpdk & KPDK_DKP)) {
777- /* better luck next time */
778- } else if (kpc & KPC_REE0) {
779- unsigned long kprec = KPREC;
780- KPREC = 0x7f;
781-
782- if (kprec & KPREC_OF0)
783- rel = (kprec & 0xff) + 0x7f;
784- else if (kprec & KPREC_UF0)
785- rel = (kprec & 0xff) - 0x7f - 0xff;
786- else
787- rel = (kprec & 0xff) - 0x7f;
788-
789- if (rel) {
790- input_report_rel(input_dev, REL_WHEEL, rel);
791- input_sync(input_dev);
792- }
793- }
794- }
795-
796- if (kpc & KPC_MI) {
797- /* report the status of every button */
798- for (row = 0; row < pdata->nr_rows; row++) {
799- for (col = 0; col < pdata->nr_cols; col++) {
800- p = KPASMKP(col) & KPASMKPx_MKC(row, col) ?
801- 1 : 0;
802- pr_debug("keycode %x - pressed %x\n",
803- pdata->keycodes[row][col], p);
804- input_report_key(input_dev,
805- pdata->keycodes[row][col], p);
806- }
807- }
808- input_sync(input_dev);
809- }
810-
811- return IRQ_HANDLED;
812-}
813-
814-static int pxakbd_open(struct input_dev *dev)
815-{
816- /* Set keypad control register */
817- KPC |= (KPC_ASACT |
818- KPC_MS_ALL |
819- (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL |
820- KPC_ME | KPC_MIE | KPC_DE | KPC_DIE);
821-
822- KPC &= ~KPC_AS; /* disable automatic scan */
823- KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */
824-
825- /* Set rotary count to mid-point value */
826- KPREC = 0x7F;
827-
828- /* Enable unit clock */
829- clk_enable(pxakbd_clk);
830-
831- return 0;
832-}
833-
834-static void pxakbd_close(struct input_dev *dev)
835-{
836- /* Disable clock unit */
837- clk_disable(pxakbd_clk);
838-}
839-
840-#ifdef CONFIG_PM
841-static int pxakbd_suspend(struct platform_device *pdev, pm_message_t state)
842-{
843- struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data;
844-
845- /* Save controller status */
846- pdata->reg_kpc = KPC;
847- pdata->reg_kprec = KPREC;
848-
849- return 0;
850-}
851-
852-static int pxakbd_resume(struct platform_device *pdev)
853-{
854- struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data;
855- struct input_dev *input_dev = platform_get_drvdata(pdev);
856-
857- mutex_lock(&input_dev->mutex);
858-
859- if (input_dev->users) {
860- /* Restore controller status */
861- KPC = pdata->reg_kpc;
862- KPREC = pdata->reg_kprec;
863-
864- /* Enable unit clock */
865- clk_disable(pxakbd_clk);
866- clk_enable(pxakbd_clk);
867- }
868-
869- mutex_unlock(&input_dev->mutex);
870-
871- return 0;
872-}
873-#else
874-#define pxakbd_suspend NULL
875-#define pxakbd_resume NULL
876-#endif
877-
878-static int __devinit pxakbd_probe(struct platform_device *pdev)
879-{
880- struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data;
881- struct input_dev *input_dev;
882- int i, row, col, error;
883-
884- pxakbd_clk = clk_get(&pdev->dev, "KBDCLK");
885- if (IS_ERR(pxakbd_clk)) {
886- error = PTR_ERR(pxakbd_clk);
887- goto err_clk;
888- }
889-
890- /* Create and register the input driver. */
891- input_dev = input_allocate_device();
892- if (!input_dev) {
893- printk(KERN_ERR "Cannot request keypad device\n");
894- error = -ENOMEM;
895- goto err_alloc;
896- }
897-
898- input_dev->name = DRIVER_NAME;
899- input_dev->id.bustype = BUS_HOST;
900- input_dev->open = pxakbd_open;
901- input_dev->close = pxakbd_close;
902- input_dev->dev.parent = &pdev->dev;
903-
904- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
905- input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL);
906- for (row = 0; row < pdata->nr_rows; row++) {
907- for (col = 0; col < pdata->nr_cols; col++) {
908- int code = pdata->keycodes[row][col];
909- if (code > 0)
910- set_bit(code, input_dev->keybit);
911- }
912- }
913-
914- error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, IRQF_DISABLED,
915- DRIVER_NAME, pdev);
916- if (error) {
917- printk(KERN_ERR "Cannot request keypad IRQ\n");
918- goto err_free_dev;
919- }
920-
921- platform_set_drvdata(pdev, input_dev);
922-
923- /* Register the input device */
924- error = input_register_device(input_dev);
925- if (error)
926- goto err_free_irq;
927-
928- /* Setup GPIOs. */
929- for (i = 0; i < pdata->nr_rows + pdata->nr_cols; i++)
930- pxa_gpio_mode(pdata->gpio_modes[i]);
931-
932- /*
933- * Store rows/cols info into keyboard registers.
934- */
935-
936- KPC |= (pdata->nr_rows - 1) << 26;
937- KPC |= (pdata->nr_cols - 1) << 23;
938-
939- for (col = 0; col < pdata->nr_cols; col++)
940- KPC |= KPC_MS0 << col;
941-
942- return 0;
943-
944- err_free_irq:
945- platform_set_drvdata(pdev, NULL);
946- free_irq(IRQ_KEYPAD, pdev);
947- err_free_dev:
948- input_free_device(input_dev);
949- err_alloc:
950- clk_put(pxakbd_clk);
951- err_clk:
952- return error;
953-}
954-
955-static int __devexit pxakbd_remove(struct platform_device *pdev)
956-{
957- struct input_dev *input_dev = platform_get_drvdata(pdev);
958-
959- input_unregister_device(input_dev);
960- free_irq(IRQ_KEYPAD, pdev);
961- clk_put(pxakbd_clk);
962- platform_set_drvdata(pdev, NULL);
963-
964- return 0;
965-}
966-
967-static struct platform_driver pxakbd_driver = {
968- .probe = pxakbd_probe,
969- .remove = __devexit_p(pxakbd_remove),
970- .suspend = pxakbd_suspend,
971- .resume = pxakbd_resume,
972- .driver = {
973- .name = DRIVER_NAME,
974- },
975-};
976-
977-static int __init pxakbd_init(void)
978-{
979- return platform_driver_register(&pxakbd_driver);
980-}
981-
982-static void __exit pxakbd_exit(void)
983-{
984- platform_driver_unregister(&pxakbd_driver);
985-}
986-
987-module_init(pxakbd_init);
988-module_exit(pxakbd_exit);
989-
990-MODULE_DESCRIPTION("PXA27x Matrix Keyboard Driver");
991-MODULE_LICENSE("GPL");
992Index: linux-2.6.23-z-input/arch/arm/mach-pxa/zylonite.c
993===================================================================
994--- linux-2.6.23-z-input.orig/arch/arm/mach-pxa/zylonite.c 2008-02-18 01:43:28.000000000 +0100
995+++ linux-2.6.23-z-input/arch/arm/mach-pxa/zylonite.c 2008-02-19 01:31:33.000000000 +0100
996@@ -25,6 +25,7 @@
997 #include <asm/arch/gpio.h>
998 #include <asm/arch/pxafb.h>
999 #include <asm/arch/zylonite.h>
1000+#include <asm/arch/pxa27x_keypad.h>
1001
1002 #include "generic.h"
1003
1004@@ -173,6 +174,72 @@
1005 static inline void zylonite_init_lcd(void) {}
1006 #endif
1007
1008+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
1009+static unsigned int zylonite_matrix_key_map[] = {
1010+ /* KEY(row, col, key_code) */
1011+ KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D),
1012+ KEY(1, 0, KEY_E), KEY(1, 1, KEY_F), KEY(1, 2, KEY_G), KEY(1, 5, KEY_H),
1013+ KEY(2, 0, KEY_I), KEY(2, 1, KEY_J), KEY(2, 2, KEY_K), KEY(2, 5, KEY_L),
1014+ KEY(3, 0, KEY_M), KEY(3, 1, KEY_N), KEY(3, 2, KEY_O), KEY(3, 5, KEY_P),
1015+ KEY(5, 0, KEY_Q), KEY(5, 1, KEY_R), KEY(5, 2, KEY_S), KEY(5, 5, KEY_T),
1016+ KEY(6, 0, KEY_U), KEY(6, 1, KEY_V), KEY(6, 2, KEY_W), KEY(6, 5, KEY_X),
1017+ KEY(7, 1, KEY_Y), KEY(7, 2, KEY_Z),
1018+
1019+ KEY(4, 4, KEY_0), KEY(1, 3, KEY_1), KEY(4, 1, KEY_2), KEY(1, 4, KEY_3),
1020+ KEY(2, 3, KEY_4), KEY(4, 2, KEY_5), KEY(2, 4, KEY_6), KEY(3, 3, KEY_7),
1021+ KEY(4, 3, KEY_8), KEY(3, 4, KEY_9),
1022+
1023+ KEY(4, 5, KEY_SPACE),
1024+ KEY(5, 3, KEY_KPASTERISK), /* * */
1025+ KEY(5, 4, KEY_KPDOT), /* #" */
1026+
1027+ KEY(0, 7, KEY_UP),
1028+ KEY(1, 7, KEY_DOWN),
1029+ KEY(2, 7, KEY_LEFT),
1030+ KEY(3, 7, KEY_RIGHT),
1031+ KEY(2, 6, KEY_HOME),
1032+ KEY(3, 6, KEY_END),
1033+ KEY(6, 4, KEY_DELETE),
1034+ KEY(6, 6, KEY_BACK),
1035+ KEY(6, 3, KEY_CAPSLOCK), /* KEY_LEFTSHIFT), */
1036+
1037+ KEY(4, 6, KEY_ENTER), /* scroll push */
1038+ KEY(5, 7, KEY_ENTER), /* keypad action */
1039+
1040+ KEY(0, 4, KEY_EMAIL),
1041+ KEY(5, 6, KEY_SEND),
1042+ KEY(4, 0, KEY_CALENDAR),
1043+ KEY(7, 6, KEY_RECORD),
1044+ KEY(6, 7, KEY_VOLUMEUP),
1045+ KEY(7, 7, KEY_VOLUMEDOWN),
1046+
1047+ KEY(0, 6, KEY_F22), /* soft1 */
1048+ KEY(1, 6, KEY_F23), /* soft2 */
1049+ KEY(0, 3, KEY_AUX), /* contact */
1050+};
1051+
1052+static struct pxa27x_keypad_platform_data zylonite_keypad_info = {
1053+ .matrix_key_rows = 8,
1054+ .matrix_key_cols = 8,
1055+ .matrix_key_map = zylonite_matrix_key_map,
1056+ .matrix_key_map_size = ARRAY_SIZE(zylonite_matrix_key_map),
1057+
1058+ .enable_rotary0 = 1,
1059+ .rotary0_up_key = KEY_UP,
1060+ .rotary0_down_key = KEY_DOWN,
1061+
1062+ .debounce_interval = 30,
1063+};
1064+
1065+static void __init zylonite_init_keypad(void)
1066+{
1067+ pxa_set_keypad_info(&zylonite_keypad_info);
1068+}
1069+#else
1070+static inline void zylonite_init_keypad(void) {}
1071+#endif
1072+
1073+
1074 static void __init zylonite_init(void)
1075 {
1076 /* board-processor specific initialization */
1077@@ -190,6 +257,7 @@
1078 platform_device_register(&touch_device);
1079
1080 zylonite_init_lcd();
1081+ zylonite_init_keypad();
1082 }
1083
1084 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
1085Index: linux-2.6.23-z-input/arch/arm/mach-pxa/devices.h
1086===================================================================
1087--- linux-2.6.23-z-input.orig/arch/arm/mach-pxa/devices.h 2008-02-18 01:43:28.000000000 +0100
1088+++ linux-2.6.23-z-input/arch/arm/mach-pxa/devices.h 2008-02-18 01:43:28.000000000 +0100
1089@@ -12,3 +12,4 @@
1090
1091 extern struct platform_device pxa27x_device_i2c_power;
1092 extern struct platform_device pxa27x_device_ohci;
1093+extern struct platform_device pxa27x_device_keypad;
1094Index: linux-2.6.23-z-input/arch/arm/mach-pxa/generic.c
1095===================================================================
1096--- linux-2.6.23-z-input.orig/arch/arm/mach-pxa/generic.c 2008-02-18 01:43:28.000000000 +0100
1097+++ linux-2.6.23-z-input/arch/arm/mach-pxa/generic.c 2008-02-18 01:43:28.000000000 +0100
1098@@ -450,3 +450,34 @@
1099 .name = "sa1100-rtc",
1100 .id = -1,
1101 };
1102+
1103+static struct resource pxa27x_resource_keypad[] = {
1104+ [0] = {
1105+ .start = 0x41500000,
1106+ .end = 0x4150004c,
1107+ .flags = IORESOURCE_MEM,
1108+ },
1109+ [1] = {
1110+ .start = IRQ_KEYPAD,
1111+ .end = IRQ_KEYPAD,
1112+ .flags = IORESOURCE_IRQ,
1113+ },
1114+};
1115+
1116+struct platform_device pxa27x_device_keypad = {
1117+ .name = "pxa27x-keypad",
1118+ .id = -1,
1119+ .resource = pxa27x_resource_keypad,
1120+ .num_resources = ARRAY_SIZE(pxa27x_resource_keypad),
1121+};
1122+
1123+void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info)
1124+{
1125+ int ret;
1126+
1127+ pxa27x_device_keypad.dev.platform_data = info;
1128+
1129+ ret = platform_device_register(&pxa27x_device_keypad);
1130+ if (ret)
1131+ dev_err(&pxa27x_device_keypad.dev, "unable to register device: %d\n", ret);
1132+}
1133Index: linux-2.6.23-z-input/arch/arm/mach-pxa/pxa27x.c
1134===================================================================
1135--- linux-2.6.23-z-input.orig/arch/arm/mach-pxa/pxa27x.c 2008-02-18 01:43:28.000000000 +0100
1136+++ linux-2.6.23-z-input/arch/arm/mach-pxa/pxa27x.c 2008-02-18 01:43:28.000000000 +0100
1137@@ -148,7 +148,7 @@
1138
1139 INIT_CKEN("USBCLK", USB, 48000000, 0, &pxa27x_device_ohci.dev),
1140 INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
1141- INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
1142+ INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev),
1143
1144 /*
1145 INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
1146Index: linux-2.6.23-z-input/arch/arm/mach-pxa/pxa3xx.c
1147===================================================================
1148--- linux-2.6.23-z-input.orig/arch/arm/mach-pxa/pxa3xx.c 2008-02-18 01:43:28.000000000 +0100
1149+++ linux-2.6.23-z-input/arch/arm/mach-pxa/pxa3xx.c 2008-02-19 01:32:40.000000000 +0100
1150@@ -159,6 +159,7 @@
1151 static struct clk pxa3xx_clks[] = {
1152 INIT_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
1153 INIT_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
1154+ INIT_CK("KBDCLK", KEYPAD, &clk_pxa3xx_hsio_ops, &pxa27x_device_keypad.dev),
1155
1156 INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
1157 INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
1158Index: linux-2.6.23-z-input/include/asm-arm/arch-pxa/irqs.h
1159===================================================================
1160--- linux-2.6.23-z-input.orig/include/asm-arm/arch-pxa/irqs.h 2008-02-18 01:43:28.000000000 +0100
1161+++ linux-2.6.23-z-input/include/asm-arm/arch-pxa/irqs.h 2008-02-18 01:43:28.000000000 +0100
1162@@ -13,7 +13,7 @@
1163
1164 #define PXA_IRQ(x) (x)
1165
1166-#ifdef CONFIG_PXA27x
1167+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
1168 #define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
1169 #define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
1170 #define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI) */
1171Index: linux-2.6.23-z-input/arch/arm/mach-pxa/pxa300.c
1172===================================================================
1173--- linux-2.6.23-z-input.orig/arch/arm/mach-pxa/pxa300.c 2008-02-19 01:33:58.000000000 +0100
1174+++ linux-2.6.23-z-input/arch/arm/mach-pxa/pxa300.c 2008-02-19 01:34:35.000000000 +0100
1175@@ -23,8 +23,10 @@
1176
1177 MFP_ADDR_X(GPIO0, GPIO2, 0x00b4),
1178 MFP_ADDR_X(GPIO3, GPIO26, 0x027c),
1179- MFP_ADDR_X(GPIO27, GPIO127, 0x0400),
1180- MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec),
1181+ MFP_ADDR_X(GPIO27, GPIO98, 0x0400),
1182+ MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
1183+ MFP_ADDR_X(GPIO0_2, GPIO1_2, 0x0674),
1184+ MFP_ADDR_X(GPIO2_2, GPIO6_2, 0x02dc),
1185
1186 MFP_ADDR(nBE0, 0x0204),
1187 MFP_ADDR(nBE1, 0x0208),
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch
new file mode 100644
index 0000000000..cb5a9c5f72
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch
@@ -0,0 +1,4093 @@
1Gross hacks to make the Zylonite boot from flash in VGA.
2
3Flash driver forward ported to 2.6.14
4
5Index: linux-2.6.23/drivers/mtd/nand/Kconfig
6===================================================================
7--- linux-2.6.23.orig/drivers/mtd/nand/Kconfig 2007-10-09 21:31:38.000000000 +0100
8+++ linux-2.6.23/drivers/mtd/nand/Kconfig 2008-02-13 00:59:45.000000000 +0000
9@@ -223,6 +223,10 @@
10 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
11 depends on ARCH_PXA
12
13+config MTD_NAND_ZYLONITE
14+ tristate "Support for NAND Flash on Zylonite"
15+ depends on ARCH_PXA
16+
17 config MTD_NAND_BASLER_EXCITE
18 tristate "Support for NAND Flash on Basler eXcite"
19 depends on BASLER_EXCITE
20Index: linux-2.6.23/drivers/mtd/nand/Makefile
21===================================================================
22--- linux-2.6.23.orig/drivers/mtd/nand/Makefile 2007-10-09 21:31:38.000000000 +0100
23+++ linux-2.6.23/drivers/mtd/nand/Makefile 2008-02-13 00:59:45.000000000 +0000
24@@ -19,6 +19,7 @@
25 obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
26 obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
27 obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o
28+obj-$(CONFIG_MTD_NAND_ZYLONITE) += mhn_nand.o
29 obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o
30 obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
31 obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
32Index: linux-2.6.23/drivers/mtd/nand/mhn_nand.c
33===================================================================
34--- /dev/null 1970-01-01 00:00:00.000000000 +0000
35+++ linux-2.6.23/drivers/mtd/nand/mhn_nand.c 2008-02-13 00:59:45.000000000 +0000
36@@ -0,0 +1,3869 @@
37+/*
38+ * drivers/mtd/nand/mhn_nand.c
39+ *
40+ * Copyright (C) 2005 Intel Coporation (chao.xie@intel.com)
41+ *
42+ * This program is free software; you can redistribute it and/or modify
43+ * it under the terms of the GNU General Public License version 2 as
44+ * published by the Free Software Foundation.
45+ *
46+ * Overview:
47+ * This is a device driver for the NAND flash device on zylonite board
48+ * which utilizes the Samsung K9K1216Q0C parts. This is a 64Mibit NAND
49+ * flash device.
50+
51+ *(C) Copyright 2006 Marvell International Ltd.
52+ * All Rights Reserved
53+ */
54+
55+#include <linux/slab.h>
56+#include <linux/module.h>
57+#include <linux/mtd/mtd.h>
58+#include <linux/mtd/nand.h>
59+#include <linux/mtd/partitions.h>
60+#include <linux/interrupt.h>
61+#include <linux/device.h>
62+#include <linux/platform_device.h>
63+#include <linux/delay.h>
64+#include <linux/dma-mapping.h>
65+#include <asm/hardware.h>
66+#include <asm/io.h>
67+#include <asm/irq.h>
68+#include <asm/delay.h>
69+#include <asm/dma.h>
70+#include <asm/arch/mfp.h>
71+//#include <asm/arch/cpu-freq-voltage-mhn.h>
72+
73+//#define NDCR 0xf0000000
74+//#define NDCR (*((volatile u32 *)0xf0000000))
75+//#define NDCR __REG_2(0x43100000) /* Data Flash Control register */
76+#define NDCR_SPARE_EN (0x1<<31)
77+#define NDCR_ECC_EN (0x1<<30)
78+#define NDCR_DMA_EN (0x1<<29)
79+#define NDCR_ND_RUN (0x1<<28)
80+#define NDCR_DWIDTH_C (0x1<<27)
81+#define NDCR_DWIDTH_M (0x1<<26)
82+#define NDCR_PAGE_SZ (0x1<<24)
83+#define NDCR_NCSX (0x1<<23)
84+#define NDCR_ND_MODE (0x3<<21)
85+#define NDCR_NAND_MODE 0x0
86+#define NDCR_CLR_PG_CNT (0x1<<20)
87+#define NDCR_CLR_ECC ( 0x1<<19)
88+#define NDCR_RD_ID_CNT_MASK (0x7<<16)
89+#define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK)
90+#define NDCR_RA_START (0x1<<15)
91+#define NDCR_PG_PER_BLK (0x1<<14)
92+#define NDCR_ND_ARB_EN (0x1<<12)
93+
94+//#define NDSR (*((volatile u32 *)0xf0000014))
95+//#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */
96+#define NDSR_RDY (0x1<<11)
97+#define NDSR_CS0_PAGED (0x1<<10)
98+#define NDSR_CS1_PAGED (0x1<<9)
99+#define NDSR_CS0_CMDD (0x1<<8)
100+#define NDSR_CS1_CMDD (0x1<<7)
101+#define NDSR_CS0_BBD (0x1<<6)
102+#define NDSR_CS1_BBD (0x1<<5)
103+#define NDSR_DBERR (0x1<<4)
104+#define NDSR_SBERR (0x1<<3)
105+#define NDSR_WRDREQ (0x1<<2)
106+#define NDSR_RDDREQ (0x1<<1)
107+#define NDSR_WRCMDREQ (0x1)
108+
109+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
110+//#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */
111+//#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */
112+//#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */
113+#define NDCB0_AUTO_RS (0x1<<25)
114+#define NDCB0_CSEL (0x1<<24)
115+#define NDCB0_CMD_TYPE_MASK (0x7<<21)
116+#define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK)
117+#define NDCB0_NC (0x1<<20)
118+#define NDCB0_DBC (0x1<<19)
119+#define NDCB0_ADDR_CYC_MASK (0x7<<16)
120+#define NDCB0_ADDR_CYC(x) (((x) << 16) & NDCB0_ADDR_CYC_MASK)
121+#define NDCB0_CMD2_MASK (0xff<<8)
122+#define NDCB0_CMD1_MASK (0xff)
123+#define NDCB0_ADDR_CYC_SHIFT (16)
124+#define DCMD0 __REG(0x4000020c) /* DMA Command Address Register Channel 0 */
125+#define DCMD1 __REG(0x4000021c) /* DMA Command Address Register Channel 1 */
126+#define DCMD2 __REG(0x4000022c) /* DMA Command Address Register Channel 2 */
127+#define DCMD3 __REG(0x4000023c) /* DMA Command Address Register Channel 3 */
128+#define DCMD4 __REG(0x4000024c) /* DMA Command Address Register Channel 4 */
129+#define DCMD5 __REG(0x4000025c) /* DMA Command Address Register Channel 5 */
130+#define DCMD6 __REG(0x4000026c) /* DMA Command Address Register Channel 6 */
131+#define DCMD7 __REG(0x4000027c) /* DMA Command Address Register Channel 7 */
132+#define DCMD8 __REG(0x4000028c) /* DMA Command Address Register Channel 8 */
133+#define DCMD9 __REG(0x4000029c) /* DMA Command Address Register Channel 9 */
134+#define DCMD10 __REG(0x400002ac) /* DMA Command Address Register Channel 10 */
135+#define DCMD11 __REG(0x400002bc) /* DMA Command Address Register Channel 11 */
136+#define DCMD12 __REG(0x400002cc) /* DMA Command Address Register Channel 12 */
137+#define DCMD13 __REG(0x400002dc) /* DMA Command Address Register Channel 13 */
138+#define DCMD14 __REG(0x400002ec) /* DMA Command Address Register Channel 14 */
139+#define DCMD15 __REG(0x400002fc) /* DMA Command Address Register Channel 15 */
140+#define DCMD(x) __REG2(0x4000020c, (x) << 4)
141+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
142+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
143+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
144+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
145+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
146+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
147+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
148+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
149+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
150+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
151+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
152+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
153+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
154+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
155+#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
156+#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
157+#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4)
158+#define DRCMR(n) __REG2(0x40000100, (n)<<2)
159+#define DRCMR97 __REG(0x40001184) /* Request to Channel Map Register for NAND interface data transmit & receive Request */
160+#define DRCMR98 __REG(0x40001188) /* Reserved */
161+#define DRCMR99 __REG(0x4000118C) /* Request to Channel Map Register for NAND interface command transmit Request */
162+#define DRCMRRXSADR DRCMR2
163+#define DRCMRTXSADR DRCMR3
164+#define DRCMRRXBTRBR DRCMR4
165+#define DRCMRTXBTTHR DRCMR5
166+#define DRCMRRXFFRBR DRCMR6
167+#define DRCMRTXFFTHR DRCMR7
168+#define DRCMRRXMCDR DRCMR8
169+#define DRCMRRXMODR DRCMR9
170+#define DRCMRTXMODR DRCMR10
171+#define DRCMRRXPCDR DRCMR11
172+#define DRCMRTXPCDR DRCMR12
173+#define DRCMRRXSSDR DRCMR13
174+#define DRCMRTXSSDR DRCMR14
175+#define DRCMRRXICDR DRCMR17
176+#define DRCMRTXICDR DRCMR18
177+#define DRCMRRXSTRBR DRCMR19
178+#define DRCMRTXSTTHR DRCMR20
179+#define DRCMRRXMMC DRCMR21
180+#define DRCMRTXMMC DRCMR22
181+#define DRCMRRXMMC2 DRCMR93
182+#define DRCMRTXMMC2 DRCMR94
183+#define DRCMRRXMMC3 DRCMR100
184+#define DRCMRTXMMC3 DRCMR101
185+#define DRCMRUDC(x) DRCMR((x) + 24)
186+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
187+#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
188+#define DCSR0 __REG(0x40000000) /* DMA Control / Status Register for Channel 0 */
189+#define DCSR1 __REG(0x40000004) /* DMA Control / Status Register for Channel 1 */
190+#define DCSR2 __REG(0x40000008) /* DMA Control / Status Register for Channel 2 */
191+#define DCSR3 __REG(0x4000000c) /* DMA Control / Status Register for Channel 3 */
192+#define DCSR4 __REG(0x40000010) /* DMA Control / Status Register for Channel 4 */
193+#define DCSR5 __REG(0x40000014) /* DMA Control / Status Register for Channel 5 */
194+#define DCSR6 __REG(0x40000018) /* DMA Control / Status Register for Channel 6 */
195+#define DCSR7 __REG(0x4000001c) /* DMA Control / Status Register for Channel 7 */
196+#define DCSR8 __REG(0x40000020) /* DMA Control / Status Register for Channel 8 */
197+#define DCSR9 __REG(0x40000024) /* DMA Control / Status Register for Channel 9 */
198+#define DCSR10 __REG(0x40000028) /* DMA Control / Status Register for Channel 10 */
199+#define DCSR11 __REG(0x4000002c) /* DMA Control / Status Register for Channel 11 */
200+#define DCSR12 __REG(0x40000030) /* DMA Control / Status Register for Channel 12 */
201+#define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */
202+#define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */
203+#define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */
204+#define DCSR16 __REG(0x40000040) /* DMA Control / Status Register for Channel 16 */
205+#define DCSR17 __REG(0x40000044) /* DMA Control / Status Register for Channel 17 */
206+#define DCSR18 __REG(0x40000048) /* DMA Control / Status Register for Channel 18 */
207+#define DCSR19 __REG(0x4000004c) /* DMA Control / Status Register for Channel 19 */
208+#define DCSR20 __REG(0x40000050) /* DMA Control / Status Register for Channel 20 */
209+#define DCSR21 __REG(0x40000054) /* DMA Control / Status Register for Channel 21 */
210+#define DCSR22 __REG(0x40000058) /* DMA Control / Status Register for Channel 22 */
211+#define DCSR23 __REG(0x4000005c) /* DMA Control / Status Register for Channel 23 */
212+#define DCSR24 __REG(0x40000060) /* DMA Control / Status Register for Channel 24 */
213+#define DCSR25 __REG(0x40000064) /* DMA Control / Status Register for Channel 25 */
214+#define DCSR26 __REG(0x40000068) /* DMA Control / Status Register for Channel 26 */
215+#define DCSR27 __REG(0x4000006c) /* DMA Control / Status Register for Channel 27 */
216+#define DCSR28 __REG(0x40000070) /* DMA Control / Status Register for Channel 28 */
217+#define DCSR29 __REG(0x40000074) /* DMA Control / Status Register for Channel 29 */
218+#define DCSR30 __REG(0x40000078) /* DMA Control / Status Register for Channel 30 */
219+#define DCSR31 __REG(0x4000007c) /* DMA Control / Status Register for Channel 31 */
220+#define DCSR(x) __REG2(0x40000000, (x) << 2)
221+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
222+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
223+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
224+#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
225+#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
226+#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
227+#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
228+#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
229+#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
230+#define DCSR_EORINTR (1 << 9) /* The end of Receive */
231+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
232+#define DCSR_RASINTR (1 << 4) /* Request After Channel Stopped */
233+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
234+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
235+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
236+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
237+#define DDADR(x) __REG2(0x40000200, (x) << 4)
238+//#define __REG_2(x) (*((volatile u32 *)io_p2v_2(x)))
239+#define IRQ_NAND PXA_IRQ(45)
240+#define CKEN_NAND 4 ///< NAND Flash Controller Clock Enable
241+
242+/* #define CONFIG_MTD_NAND_MONAHANS_DEBUG */
243+#ifdef CONFIG_MTD_NAND_MONAHANS_DEBUG
244+#define D1(x) do { \
245+ printk(KERN_DEBUG "%s: ", __FUNCTION__); \
246+ x; \
247+ }while(0)
248+
249+#define DPRINTK(fmt,args...) printk(KERN_DEBUG fmt, ##args )
250+#define PRINT_BUF(buf, num) print_buf(buf, num)
251+#else
252+#define D1(x)
253+#define DPRINTK(fmt,args...)
254+#define PRINT_BUF(buf, num)
255+#endif
256+
257+/* DFC timing 0 register */
258+#define DFC_TIMING_tRP 0
259+#define DFC_TIMING_tRH 3
260+#define DFC_TIMING_tWP 8
261+#define DFC_TIMING_tWH 11
262+#define DFC_TIMING_tCS 16
263+#define DFC_TIMING_tCH 19
264+
265+/* DFC timing 1 register */
266+#define DFC_TIMING_tAR 0
267+#define DFC_TIMING_tWHR 4
268+#define DFC_TIMING_tR 16
269+
270+/* max value for each timing setting in DFC */
271+#define DFC_TIMING_MAX_tCH 7
272+#define DFC_TIMING_MAX_tCS 7
273+#define DFC_TIMING_MAX_tWH 7
274+#define DFC_TIMING_MAX_tWP 7
275+#define DFC_TIMING_MAX_tRH 7
276+#define DFC_TIMING_MAX_tRP 7
277+#define DFC_TIMING_MAX_tR 65535
278+#define DFC_TIMING_MAX_tWHR 15
279+#define DFC_TIMING_MAX_tAR 15
280+
281+/*
282+ * The Data Flash Controller Flash timing structure
283+ * For NAND flash used on Zylonite board(Samsung K9K1216Q0C),
284+ * user should use value at end of each row of following member
285+ * bracketed.
286+ */
287+struct dfc_flash_timing {
288+ uint32_t tCH; /* Enable signal hold time */
289+ uint32_t tCS; /* Enable signal setup time */
290+ uint32_t tWH; /* ND_nWE high duration */
291+ uint32_t tWP; /* ND_nWE pulse time */
292+ uint32_t tRH; /* ND_nRE high duration */
293+ uint32_t tRP; /* ND_nRE pulse width */
294+ uint32_t tR; /* ND_nWE high to ND_nRE low for read */
295+ uint32_t tWHR;/* ND_nWE high to ND_nRE low delay for status read */
296+ uint32_t tAR; /* ND_ALE low to ND_nRE low delay */
297+};
298+
299+/* DFC command type */
300+enum {
301+ DFC_CMD_READ = 0x00000000,
302+ DFC_CMD_PROGRAM = 0x00200000,
303+ DFC_CMD_ERASE = 0x00400000,
304+ DFC_CMD_READ_ID = 0x00600000,
305+ DFC_CMD_STATUS_READ = 0x00800000,
306+ DFC_CMD_RESET = 0x00a00000
307+};
308+
309+/*
310+ * The Data Flash Controller Flash specification structure
311+ * For NAND flash used on Zylonite board(Samsung K9K1216Q0C),
312+ * user should use value at end of each row of following member
313+ * bracketed.
314+ */
315+struct dfc_flash_info {
316+ struct dfc_flash_timing timing; /* NAND Flash timing */
317+
318+ int enable_arbiter;/* Data flash bus arbiter enable (ND_ARB_EN) */
319+ uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
320+ uint32_t row_addr_start;/* Row address start position (RA_START) */
321+ uint32_t read_id_bytes; /* returned ID bytes(RD_ID_CNT) */
322+ uint32_t dfc_mode; /* NAND, CARBONDALE, PIXLEY... (ND_MODE) */
323+ uint32_t ncsx; /* Chip select don't care bit (NCSX) */
324+ uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
325+ uint32_t oob_size; /* OOB size */
326+ uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
327+ uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
328+ uint32_t num_blocks; /* Number of physical blocks in Flash */
329+ uint32_t chip_id;
330+
331+ /* command codes */
332+ uint32_t read1; /* Read */
333+ uint32_t read2; /* unused, DFC don't support yet */
334+ uint32_t program; /* two cycle command */
335+ uint32_t read_status;
336+ uint32_t read_id;
337+ uint32_t erase; /* two cycle command */
338+ uint32_t reset;
339+ uint32_t lock; /* lock whole flash */
340+ uint32_t unlock; /* two cycle command, supporting partial unlock */
341+ uint32_t lock_status; /* read block lock status */
342+
343+ /* addr2ndcb1 - encode address cycles into register NDCB1 */
344+ /* ndbbr2addr - convert register NDBBR to bad block address */
345+ int (*addr2ndcb1)(uint16_t cmd, uint32_t addr, uint32_t *p);
346+ int (*ndbbr2addr)(uint16_t cmd, uint32_t ndbbr,uint32_t *p);
347+};
348+
349+enum {
350+ DFC_FLASH_NULL = 0 ,
351+ DFC_FLASH_Samsung_512Mb_X_16 = 1,
352+ DFC_FLASH_Micron_1Gb_X_8 = 2,
353+ DFC_FLASH_Micron_1Gb_X_16 = 3,
354+ DFC_FLASH_STM_1Gb_X_16 = 4,
355+ DFC_FLASH_STM_2Gb_X_16 = 5,
356+ DFC_FLASH_END,
357+};
358+
359+static int dfc_get_flash_info(int type, struct dfc_flash_info **flash_info);
360+
361+#define DFC_NDCR 0
362+#define DFC_NDTR0CS0 1
363+#define DFC_NDTR1CS0 3
364+#define DFC_NDSR 5
365+#define DFC_NDPCR 6
366+#define DFC_NDBDR0 7
367+#define DFC_NDBDR1 8
368+#define DFC_NDDB 16
369+#define DFC_NDCB0 18
370+#define DFC_NDCB1 19
371+#define DFC_NDCB2 20
372+
373+/* The Data Flash Controller Mode structure */
374+struct dfc_mode {
375+ int enable_dma; /* DMA, or nonDMA mode */
376+ int enable_ecc; /* ECC on/off */
377+ int enable_spare; /* Spare enable */
378+ int chip_select; /* CS0 or CS1 */
379+};
380+
381+/* The Data Flash Controller Context structure */
382+struct dfc_context {
383+ unsigned char __iomem *membase; /* DFC register base */
384+ struct dfc_mode *dfc_mode; /* DFC mode */
385+ int data_dma_ch; /* Data DMA channel number */
386+ int cmd_dma_ch; /* CMD DMA channel number */
387+ struct dfc_flash_info *flash_info; /* Flash Spec */
388+ struct mtd_info *mtd;
389+};
390+
391+#define NDCB0_DMA_ADDR 0x43100048
392+#define NDDB_DMA_ADDR 0x43100040
393+
394+#define NDSR_MASK 0xFFF
395+
396+/* The following data is a rough evaluation */
397+
398+/* microsecond, for readID/readStatus/reset */
399+#define NAND_OTHER_TIMEOUT 10
400+/* microsecond, for readID/readStatus/reset */
401+#define NAND_CMD_TIMEOUT 10
402+
403+#define BBT_BLOCK_BAD 0x03
404+#define BBT_BLOCK_GOOD 0x00
405+#define BBT_BLOCK_REV1 0x01
406+#define BBT_BLOCK_REV2 0x02
407+
408+#define BUFLEN (2048 + 64)
409+
410+/*
411+ * DFC data size enumeration transfered from/to controller,
412+ * including padding (zero)to be a multiple of 32.
413+ */
414+enum {
415+ DFC_DATA_SIZE_STATUS = 8, /* ReadStatus/ReadBlockLockStatus */
416+ DFC_DATA_SIZE_ID = 7, /* ReadID */
417+
418+ DFC_DATA_SIZE_32 = 32,
419+ DFC_DATA_SIZE_512 = 512, /* R/W disabling spare area */
420+ DFC_DATA_SIZE_520 = 520, /* Spare=1, ECC=1 */
421+ DFC_DATA_SIZE_528 = 528, /* Spare=1, ECC=0 */
422+ DFC_DATA_SIZE_544 = 544, /* R/W enabling spare area.(DMA mode)*/
423+
424+ DFC_DATA_SIZE_64 = 64,
425+ DFC_DATA_SIZE_2048 = 2048, /* R/W disabling spare area */
426+ DFC_DATA_SIZE_2088 = 2088, /* R/W enabling spare area with ecc */
427+ DFC_DATA_SIZE_2112 = 2112, /* R/W enabling spare area without ecc*/
428+ DFC_DATA_SIZE_2096 = 2096, /* R/W enabling spare area */
429+ DFC_DATA_SIZE_UNUSED = 0xFFFF
430+};
431+
432+/* DFC padding size enumeration transfered from/to controller */
433+enum {
434+ /*
435+ * ReadStatus/ReadBlockLockStatus/ReadID/
436+ * Read/Program disabling spare area(Both 512 and 2048)
437+ * Read/Program enabling spare area, disabling ECC
438+ */
439+ DFC_PADDING_SIZE_0 = 0,
440+
441+ /* Read/program with SPARE_EN=1, ECC_EN=0, pgSize=512 */
442+ DFC_PADDING_SIZE_16 = 16,
443+ /* for read/program with SPARE_EN=1, ECC_EN=1, pgSize=512 and 2048 */
444+ DFC_PADDING_SIZE_24 = 24,
445+ DFC_PADDING_SIZE_UNUSED = 0xFFFF
446+};
447+
448+static unsigned int flash_config = DFC_FLASH_NULL;
449+
450+void dfc_set_timing(struct dfc_context *context, struct dfc_flash_timing *t);
451+void dfc_set_dma(struct dfc_context *context);
452+void dfc_set_ecc(struct dfc_context *context);
453+void dfc_set_spare(struct dfc_context *context);
454+
455+int dfc_get_pattern(struct dfc_context *context, uint16_t cmd,
456+ int *data_size, int *padding);
457+
458+static int dfc_wait_event(struct dfc_context *context, uint32_t event,
459+ uint32_t *event_out, uint32_t timeout, int enable_int);
460+
461+int dfc_send_cmd(struct dfc_context *context, uint16_t cmd,
462+ uint32_t addr, int num_pages);
463+
464+void dfc_stop(struct dfc_context *context);
465+void dfc_read_fifo_partial(struct dfc_context *context, uint8_t *buffer,
466+ int nbytes, int data_size);
467+void dfc_write_fifo_partial(struct dfc_context *context, uint8_t *buffer,
468+ int nbytes, int data_size);
469+
470+void dfc_read_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes);
471+void dfc_write_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes);
472+
473+void dfc_read_badblock_addr(struct dfc_context *context, uint32_t *bbaddr);
474+
475+void dfc_clear_int(struct dfc_context *context, uint32_t int_mask);
476+void dfc_enable_int(struct dfc_context *context, uint32_t int_mask);
477+void dfc_disable_int(struct dfc_context *context, uint32_t int_mask);
478+
479+/* high level primitives */
480+int dfc_init(struct dfc_context *context, int type);
481+int dfc_init_no_gpio(struct dfc_context *context, int type);
482+
483+int dfc_reset_flash(struct dfc_context *context);
484+
485+int dfc_setup_cmd_dma(struct dfc_context *context,
486+ uint16_t cmd, uint32_t addr, int num_pages,
487+ uint32_t *buf, uint32_t buf_phys,
488+ uint32_t next_desc_phys, uint32_t dma_int_en,
489+ struct pxa_dma_desc *dma_desc);
490+
491+int dfc_setup_data_dma(struct dfc_context *context,
492+ uint16_t cmd, uint32_t buf_phys,
493+ uint32_t next_desc_phys, uint32_t dma_int_en,
494+ struct pxa_dma_desc *dma_desc);
495+
496+void dfc_start_cmd_dma(struct dfc_context *context,
497+ struct pxa_dma_desc *dma_desc);
498+void dfc_start_data_dma(struct dfc_context *context,
499+ struct pxa_dma_desc *dma_desc);
500+static int monahans_df_dev_ready(struct mtd_info *mtd);
501+
502+#ifdef CONFIG_DVFM
503+static int mhn_nand_dvfm_notifier(unsigned cmd, void *client_data, void *info);
504+static struct mhn_fv_notifier dvfm_notifier = {
505+ .name = "monahans-nand-flash",
506+ .priority = 0,
507+ .notifier_call = mhn_nand_dvfm_notifier,
508+};
509+#endif
510+
511+static unsigned short search_rel_block(int block, struct mtd_info *mtd);
512+
513+/*****************************************************************************
514+ * The DFC registers read/write routines
515+ *****************************************************************************/
516+static inline void dfc_write(struct dfc_context *context, int offset,
517+ unsigned long value)
518+{
519+ offset <<= 2;
520+ writel(value, context->membase + offset);
521+}
522+
523+static inline unsigned int dfc_read(struct dfc_context *context, int offset)
524+{
525+ offset <<= 2;
526+ return __raw_readl(context->membase + offset);
527+}
528+
529+/****************************************************************************
530+ * Flash Information
531+ ***************************************************************************/
532+
533+static int Samsung512MbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
534+static int Samsung512MbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
535+
536+static struct dfc_flash_info samsung512MbX16 =
537+{
538+ .timing = {
539+ .tCH = 10, /* tCH, Enable signal hold time */
540+ .tCS = 0, /* tCS, Enable signal setup time */
541+ .tWH = 20, /* tWH, ND_nWE high duration */
542+ .tWP = 40, /* tWP, ND_nWE pulse time */
543+ .tRH = 30, /* tRH, ND_nRE high duration */
544+ .tRP = 40, /* tRP, ND_nRE pulse width */
545+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
546+ .tR = 11123,
547+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
548+ .tWHR = 110,
549+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
550+ },
551+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
552+ .page_per_block = 32, /* Pages per block */
553+ .row_addr_start = 0, /* Second cycle start, Row address start position */
554+ .read_id_bytes = 2, /* 2 bytes, returned ID bytes */
555+ .dfc_mode = 0, /* NAND mode */
556+ .ncsx = 0,
557+ .page_size = 512, /* Page size in bytes */
558+ .oob_size = 16, /* OOB size in bytes */
559+ .flash_width = 16, /* Width of Flash memory */
560+ .dfc_width = 16, /* Width of flash controller */
561+ .num_blocks = 4096, /* Number of physical blocks in Flash */
562+ .chip_id = 0x46ec,
563+
564+ /* command codes */
565+ .read1 = 0x0000, /* Read */
566+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
567+ .program = 0x1080, /* Write, two cycle command */
568+ .read_status = 0x0070, /* Read status */
569+ .read_id = 0x0090, /* Read ID */
570+ .erase = 0xD060, /* Erase, two cycle command */
571+ .reset = 0x00FF, /* Reset */
572+ .lock = 0x002A, /* Lock whole flash */
573+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
574+ .lock_status = 0x007A, /* Read block lock status */
575+ .addr2ndcb1 = Samsung512MbX16Addr2NDCB1,
576+ .ndbbr2addr = Samsung512MbX16NDBBR2Addr,
577+};
578+
579+static int Samsung512MbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
580+{
581+ uint32_t ndcb1 = 0;
582+
583+ if (addr >= 0x4000000) return -EINVAL;
584+
585+ if (cmd == samsung512MbX16.read1 || cmd == samsung512MbX16.program) {
586+ ndcb1 = (addr & 0xFF) | ((addr >> 1) & 0x01FFFF00);
587+ } else if (cmd == samsung512MbX16.erase) {
588+ ndcb1 = ((addr >> 9) & 0x00FFFFFF);
589+ }
590+
591+ *p = ndcb1;
592+ return 0;
593+
594+}
595+
596+static int Samsung512MbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
597+{
598+ *p = ndbbr << 9;
599+ return 0;
600+}
601+
602+static int Micron1GbX8Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
603+static int Micron1GbX8NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
604+
605+static struct dfc_flash_info micron1GbX8 =
606+{
607+ .timing = {
608+ .tCH = 10, /* tCH, Enable signal hold time */
609+ .tCS = 25, /* tCS, Enable signal setup time */
610+ .tWH = 15, /* tWH, ND_nWE high duration */
611+ .tWP = 25, /* tWP, ND_nWE pulse time */
612+ .tRH = 15, /* tRH, ND_nRE high duration */
613+ .tRP = 25, /* tRP, ND_nRE pulse width */
614+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
615+ .tR = 25000,
616+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
617+ .tWHR = 60,
618+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
619+ },
620+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
621+ .page_per_block = 64, /* Pages per block */
622+ .row_addr_start = 1, /* Second cycle start, Row address start position */
623+ .read_id_bytes = 4, /* Returned ID bytes */
624+ .dfc_mode = 0, /* NAND mode */
625+ .ncsx = 0,
626+ .page_size = 2048, /* Page size in bytes */
627+ .oob_size = 64, /* OOB size in bytes */
628+ .flash_width = 8, /* Width of Flash memory */
629+ .dfc_width = 8, /* Width of flash controller */
630+ .num_blocks = 1024, /* Number of physical blocks in Flash */
631+ .chip_id = 0xa12c,
632+ /* command codes */
633+ .read1 = 0x3000, /* Read */
634+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
635+ .program = 0x1080, /* Write, two cycle command */
636+ .read_status = 0x0070, /* Read status */
637+ .read_id = 0x0090, /* Read ID */
638+ .erase = 0xD060, /* Erase, two cycle command */
639+ .reset = 0x00FF, /* Reset */
640+ .lock = 0x002A, /* Lock whole flash */
641+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
642+ .lock_status = 0x007A, /* Read block lock status */
643+ .addr2ndcb1 = Micron1GbX8Addr2NDCB1,
644+ .ndbbr2addr = Micron1GbX8NDBBR2Addr,
645+};
646+
647+static int Micron1GbX8Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
648+{
649+ uint32_t ndcb1 = 0;
650+ uint32_t page;
651+
652+ if (addr >= 0x8000000)
653+ return -EINVAL;
654+ page = addr / micron1GbX8.page_size;
655+ addr = (page / micron1GbX8.page_per_block) << 18 |
656+ (page % micron1GbX8.page_per_block) << 12;
657+
658+ if (cmd == micron1GbX8.read1 || cmd == micron1GbX8.program) {
659+ ndcb1 = (addr & 0xFFF) | ((addr << 4) & 0xFFFF0000);
660+ }
661+ else if (cmd == micron1GbX8.erase) {
662+ ndcb1 = ((addr >> 18) << 6) & 0xFFFF;
663+ }
664+
665+ *p = ndcb1;
666+ return 0;
667+}
668+
669+static int Micron1GbX8NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
670+{
671+ if (cmd == micron1GbX8.read1 || cmd == micron1GbX8.program) {
672+ *p = ((ndbbr & 0xF) << 8) | ((ndbbr >> 8) << 16);
673+ }
674+ else if (cmd == micron1GbX8.erase) {
675+ *p = (ndbbr >> 6) << 18;
676+ }
677+
678+
679+ return 0;
680+}
681+
682+
683+static int Micron1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
684+static int Micron1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
685+
686+static struct dfc_flash_info micron1GbX16 =
687+{
688+ .timing = {
689+ .tCH = 10, /* tCH, Enable signal hold time */
690+ .tCS = 25, /* tCS, Enable signal setup time */
691+ .tWH = 15, /* tWH, ND_nWE high duration */
692+ .tWP = 25, /* tWP, ND_nWE pulse time */
693+ .tRH = 15, /* tRH, ND_nRE high duration */
694+ .tRP = 25, /* tRP, ND_nRE pulse width */
695+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
696+ .tR = 25000,
697+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
698+ .tWHR = 60,
699+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
700+ },
701+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
702+ .page_per_block = 64, /* Pages per block */
703+ .row_addr_start = 1, /* Second cycle start, Row address start position */
704+ .read_id_bytes = 4, /* Returned ID bytes */
705+ .dfc_mode = 0, /* NAND mode */
706+ .ncsx = 0,
707+ .page_size = 2048, /* Page size in bytes */
708+ .oob_size = 64, /* OOB size in bytes */
709+ .flash_width = 16, /* Width of Flash memory */
710+ .dfc_width = 16, /* Width of flash controller */
711+ .num_blocks = 1024, /* Number of physical blocks in Flash */
712+ .chip_id = 0xb12c,
713+
714+ /* command codes */
715+ .read1 = 0x3000, /* Read */
716+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
717+ .program = 0x1080, /* Write, two cycle command */
718+ .read_status = 0x0070, /* Read status */
719+ .read_id = 0x0090, /* Read ID */
720+ .erase = 0xD060, /* Erase, two cycle command */
721+ .reset = 0x00FF, /* Reset */
722+ .lock = 0x002A, /* Lock whole flash */
723+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
724+ .lock_status = 0x007A, /* Read block lock status */
725+ .addr2ndcb1 = Micron1GbX16Addr2NDCB1,
726+ .ndbbr2addr = Micron1GbX16NDBBR2Addr,
727+};
728+
729+static int Micron1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
730+{
731+ uint32_t ndcb1 = 0;
732+ uint32_t page;
733+
734+ if (addr >= 0x8000000)
735+ return -EINVAL;
736+ page = addr / micron1GbX16.page_size;
737+ addr = (page / micron1GbX16.page_per_block) << 17 |
738+ (page % micron1GbX16.page_per_block) << 11;
739+
740+ if (cmd == micron1GbX16.read1 || cmd == micron1GbX16.program) {
741+ ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
742+ }
743+ else if (cmd == micron1GbX16.erase) {
744+ ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
745+ }
746+ *p = ndcb1;
747+ return 0;
748+}
749+
750+static int Micron1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
751+{
752+ if (cmd == micron1GbX16.read1 || cmd == micron1GbX16.program) {
753+ *p = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
754+ }
755+ else if (cmd == micron1GbX16.erase) {
756+ *p = (ndbbr >> 6) << 17;
757+ }
758+
759+ return 0;
760+}
761+
762+static int STM1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
763+static int STM1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
764+
765+static struct dfc_flash_info stm1GbX16 =
766+{
767+ .timing = {
768+ .tCH = 10, /* tCH, Enable signal hold time */
769+ .tCS = 10, /* tCS, Enable signal setup time */
770+ .tWH = 20, /* tWH, ND_nWE high duration */
771+ .tWP = 25, /* tWP, ND_nWE pulse time */
772+ .tRH = 20, /* tRH, ND_nRE high duration */
773+ .tRP = 25, /* tRP, ND_nRE pulse width */
774+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
775+ .tR = 25000,
776+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
777+ .tWHR = 60,
778+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
779+ },
780+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
781+ .page_per_block = 64, /* Pages per block */
782+ .row_addr_start = 1, /* Second cycle start, Row address start position */
783+ .read_id_bytes = 4, /* Returned ID bytes */
784+ .dfc_mode = 0, /* NAND mode */
785+ .ncsx = 0,
786+ .page_size = 2048, /* Page size in bytes */
787+ .oob_size = 64, /* OOB size in bytes */
788+ .flash_width = 16, /* Width of Flash memory */
789+ .dfc_width = 16, /* Width of flash controller */
790+ .num_blocks = 1024, /* Number of physical blocks in Flash */
791+ .chip_id = 0xb120,
792+
793+ /* command codes */
794+ .read1 = 0x3000, /* Read */
795+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
796+ .program = 0x1080, /* Write, two cycle command */
797+ .read_status = 0x0070, /* Read status */
798+ .read_id = 0x0090, /* Read ID */
799+ .erase = 0xD060, /* Erase, two cycle command */
800+ .reset = 0x00FF, /* Reset */
801+ .lock = 0x002A, /* Lock whole flash */
802+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
803+ .lock_status = 0x007A, /* Read block lock status */
804+ .addr2ndcb1 = STM1GbX16Addr2NDCB1,
805+ .ndbbr2addr = STM1GbX16NDBBR2Addr,
806+};
807+
808+static int STM1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
809+{
810+ uint32_t ndcb1 = 0;
811+ uint32_t page;
812+
813+ if (addr >= 0x8000000)
814+ return -EINVAL;
815+ page = addr / stm1GbX16.page_size;
816+ addr = (page / stm1GbX16.page_per_block) << 17 |
817+ (page % stm1GbX16.page_per_block) << 11;
818+
819+ if (cmd == stm1GbX16.read1 || cmd == stm1GbX16.program) {
820+ ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
821+ }
822+ else if (cmd == stm1GbX16.erase) {
823+ ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
824+ }
825+ *p = ndcb1;
826+ return 0;
827+}
828+
829+static int STM1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
830+{
831+ if (cmd == stm1GbX16.read1 || cmd == stm1GbX16.program) {
832+ *p = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
833+ }
834+ else if (cmd == stm1GbX16.erase) {
835+ *p = (ndbbr >> 6) << 17;
836+ }
837+
838+ return 0;
839+}
840+
841+static int STM2GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
842+static int STM2GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
843+
844+static struct dfc_flash_info stm2GbX16 =
845+{
846+ .timing = {
847+ .tCH = 10, /* tCH, Enable signal hold time */
848+ .tCS = 10, /* tCS, Enable signal setup time */
849+ .tWH = 20, /* tWH, ND_nWE high duration */
850+ .tWP = 25, /* tWP, ND_nWE pulse time */
851+ .tRH = 20, /* tRH, ND_nRE high duration */
852+ .tRP = 25, /* tRP, ND_nRE pulse width */
853+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
854+ .tR = 25000,
855+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
856+ .tWHR = 60,
857+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
858+ },
859+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
860+ .page_per_block = 64, /* Pages per block */
861+ .row_addr_start = 1, /* Second cycle start, Row address start position */
862+ .read_id_bytes = 4, /* Returned ID bytes */
863+ .dfc_mode = 0, /* NAND mode */
864+ .ncsx = 0,
865+ .page_size = 2048, /* Page size in bytes */
866+ .oob_size = 64, /* OOB size in bytes */
867+ .flash_width = 16, /* Width of Flash memory */
868+ .dfc_width = 16, /* Width of flash controller */
869+ .num_blocks = 2048, /* Number of physical blocks in Flash */
870+ .chip_id = 0xca20,
871+
872+ /* command codes */
873+ .read1 = 0x3000, /* Read */
874+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
875+ .program = 0x1080, /* Write, two cycle command */
876+ .read_status = 0x0070, /* Read status */
877+ .read_id = 0x0090, /* Read ID */
878+ .erase = 0xD060, /* Erase, two cycle command */
879+ .reset = 0x00FF, /* Reset */
880+ .lock = 0x002A, /* Lock whole flash */
881+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
882+ .lock_status = 0x007A, /* Read block lock status */
883+ .addr2ndcb1 = STM2GbX16Addr2NDCB1,
884+ .ndbbr2addr = STM2GbX16NDBBR2Addr,
885+};
886+
887+static int STM2GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
888+{
889+ uint32_t ndcb1 = 0;
890+ uint32_t page;
891+
892+ if (addr >= 0x8000000)
893+ return -EINVAL;
894+ page = addr / stm2GbX16.page_size;
895+ addr = (page / stm2GbX16.page_per_block) << 17 |
896+ (page % stm2GbX16.page_per_block) << 11;
897+
898+ if (cmd == stm2GbX16.read1 || cmd == stm2GbX16.program) {
899+ ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
900+ }
901+ else if (cmd == stm2GbX16.erase) {
902+ ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
903+ }
904+ *p = ndcb1;
905+ return 0;
906+}
907+
908+static int STM2GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
909+{
910+ if (cmd == stm2GbX16.read1 || cmd == stm2GbX16.program) {
911+ *p = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
912+ }
913+ else if (cmd == stm2GbX16.erase) {
914+ *p = (ndbbr >> 6) << 17;
915+ }
916+
917+ return 0;
918+}
919+
920+static struct {
921+ int type;
922+ struct dfc_flash_info *flash_info;
923+} type_info[] = {
924+ { DFC_FLASH_Samsung_512Mb_X_16, &samsung512MbX16},
925+ { DFC_FLASH_Micron_1Gb_X_8, &micron1GbX8},
926+ { DFC_FLASH_Micron_1Gb_X_16, &micron1GbX16},
927+ { DFC_FLASH_STM_1Gb_X_16, &stm1GbX16},
928+ { DFC_FLASH_STM_2Gb_X_16, &stm2GbX16},
929+ { DFC_FLASH_NULL, NULL},
930+};
931+
932+int dfc_get_flash_info(int type, struct dfc_flash_info **flash_info)
933+{
934+ uint32_t i = 0;
935+
936+ while(type_info[i].type != DFC_FLASH_NULL) {
937+ if (type_info[i].type == type) {
938+ *flash_info = type_info[i].flash_info;
939+ return 0;
940+ }
941+ i++;
942+ }
943+ *flash_info = NULL;
944+ return -EINVAL;
945+}
946+
947+/******************************************************************************
948+ dfc_set_timing
949+
950+ Description:
951+ This function sets flash timing property in DFC timing register
952+ according to input timing value embodied in context structure.
953+ It is called once during the hardware initialization.
954+ Input Parameters:
955+ Output Parameters:
956+ None
957+ Returns:
958+ None
959+*******************************************************************************/
960+//#if defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
961+#define DFC_CLOCK 208
962+//#else
963+//#define DFC_CLOCK 104
964+//#endif
965+#define CLOCK_NS DFC_CLOCK/1000
966+
967+void dfc_set_timing(struct dfc_context *context, struct dfc_flash_timing *t)
968+{
969+ struct dfc_flash_timing timing = *t;
970+
971+ uint32_t r0 = 0;
972+ uint32_t r1 = 0;
973+
974+ /*
975+ * num of clock cycles = time (ns) / one clock sycle (ns) + 1
976+ * - integer division will truncate the result, so add a 1 in all cases
977+ * - subtract the extra 1 cycle added to all register timing values
978+ */
979+ timing.tCH = min(((int) (timing.tCH * CLOCK_NS) + 1),
980+ DFC_TIMING_MAX_tCH);
981+ timing.tCS = min(((int) (timing.tCS * CLOCK_NS) + 1),
982+ DFC_TIMING_MAX_tCS);
983+ timing.tWH = min(((int) (timing.tWH * CLOCK_NS) + 1),
984+ DFC_TIMING_MAX_tWH);
985+ timing.tWP = min(((int) (timing.tWP * CLOCK_NS) + 1),
986+ DFC_TIMING_MAX_tWP);
987+ timing.tRH = min(((int) (timing.tRH * CLOCK_NS) + 1),
988+ DFC_TIMING_MAX_tRH);
989+ timing.tRP = min(((int) (timing.tRP * CLOCK_NS) + 1),
990+ DFC_TIMING_MAX_tRP);
991+
992+ r0 = (timing.tCH << DFC_TIMING_tCH) |
993+ (timing.tCS << DFC_TIMING_tCS) |
994+ (timing.tWH << DFC_TIMING_tWH) |
995+ (timing.tWP << DFC_TIMING_tWP) |
996+ (timing.tRH << DFC_TIMING_tRH) |
997+ (timing.tRP << DFC_TIMING_tRP);
998+
999+ dfc_write(context, DFC_NDTR0CS0, r0);
1000+
1001+ timing.tR = min(((int) (timing.tR * CLOCK_NS) + 1),
1002+ DFC_TIMING_MAX_tR);
1003+ timing.tWHR = min(((int) (timing.tWHR * CLOCK_NS) + 1),
1004+ DFC_TIMING_MAX_tWHR);
1005+ timing.tAR = min(((int) (timing.tAR * CLOCK_NS) + 1),
1006+ DFC_TIMING_MAX_tAR);
1007+
1008+ r1 = (timing.tR << DFC_TIMING_tR) |
1009+ (timing.tWHR << DFC_TIMING_tWHR) |
1010+ (timing.tAR << DFC_TIMING_tAR);
1011+
1012+ dfc_write(context, DFC_NDTR1CS0, r1);
1013+ return;
1014+}
1015+
1016+/******************************************************************************
1017+ dfc_set_dma
1018+
1019+ Description:
1020+ Enables or Disables DMA in line with setting in DFC mode of context
1021+ structure. DMA mode of DFC. Performs a read-modify-write operation that
1022+ only changes the driven DMA_EN bit field In DMA mode, all commands and
1023+ data are transferred by DMA. DMA can be enable/disable on the fly.
1024+ Input Parameters:
1025+ context -Pointer to DFC context structure
1026+ Output Parameters:
1027+ None
1028+ Returns:
1029+ None
1030+*******************************************************************************/
1031+void
1032+dfc_set_dma(struct dfc_context* context)
1033+{
1034+ uint32_t ndcr;
1035+
1036+ ndcr = dfc_read(context, DFC_NDCR);
1037+ if (context->dfc_mode->enable_dma)
1038+ ndcr |= NDCR_DMA_EN;
1039+ else
1040+ ndcr &= ~NDCR_DMA_EN;
1041+
1042+ dfc_write(context, DFC_NDCR, ndcr);
1043+
1044+ /* Read again to make sure write work */
1045+ ndcr = dfc_read(context, DFC_NDCR);
1046+ return;
1047+}
1048+
1049+
1050+/******************************************************************************
1051+ dfc_set_ecc
1052+
1053+ Description:
1054+ This function enables or disables hardware ECC capability of DFC in line
1055+ with setting in DFC mode of context structure.
1056+ Input Parameters:
1057+ context -Pointer to DFC context structure
1058+ Output Parameters:
1059+ None
1060+ Returns:
1061+ None
1062+*******************************************************************************/
1063+void
1064+dfc_set_ecc(struct dfc_context* context)
1065+{
1066+ uint32_t ndcr;
1067+
1068+ ndcr = dfc_read(context, DFC_NDCR);
1069+ if (context->dfc_mode->enable_ecc)
1070+ ndcr |= NDCR_ECC_EN;
1071+ else
1072+ ndcr &= ~NDCR_ECC_EN;
1073+
1074+ dfc_write(context, DFC_NDCR, ndcr);
1075+
1076+ /* Read again to make sure write work */
1077+ ndcr = dfc_read(context, DFC_NDCR);
1078+ return;
1079+}
1080+
1081+/******************************************************************************
1082+ dfc_set_spare
1083+
1084+ Description:
1085+ This function enables or disables accesses to spare area of NAND Flash
1086+ through DFC in line with setting in DFC mode of context structure.
1087+ Input Parameters:
1088+ context -Pointer to DFC context structure
1089+ Output Parameters:
1090+ None
1091+ Returns:
1092+ None
1093+*******************************************************************************/
1094+void
1095+dfc_set_spare(struct dfc_context* context)
1096+{
1097+ uint32_t ndcr;
1098+
1099+ ndcr = dfc_read(context, DFC_NDCR);
1100+ if (context->dfc_mode->enable_spare)
1101+ ndcr |= NDCR_SPARE_EN;
1102+ else
1103+ ndcr &= ~NDCR_SPARE_EN;
1104+
1105+ dfc_write(context, DFC_NDCR, ndcr);
1106+
1107+ /* Read again to make sure write work */
1108+ ndcr = dfc_read(context, DFC_NDCR);
1109+ return;
1110+}
1111+
1112+static unsigned int get_delta (unsigned int start)
1113+{
1114+ unsigned int stop = OSCR;
1115+ return (stop - start);
1116+}
1117+
1118+static int dfc_wait_event(struct dfc_context *context, uint32_t event,
1119+ uint32_t *event_out, uint32_t timeout, int enable_int)
1120+{
1121+ uint32_t ndsr;
1122+ uint32_t to = 3 * timeout; /* 3 ticks ~ 1us */
1123+ int status;
1124+ int start = OSCR;
1125+
1126+ if (enable_int)
1127+ dfc_enable_int(context, event);
1128+
1129+ while (1) {
1130+ ndsr = dfc_read(context, DFC_NDSR);
1131+ ndsr &= NDSR_MASK;
1132+ if (ndsr & event) {
1133+ /* event happened */
1134+ *event_out = ndsr & event;
1135+ dfc_clear_int(context, *event_out);
1136+ status = 0;
1137+ break;
1138+ } else if (get_delta(start) > to) {
1139+ status = -ETIME;
1140+ break;
1141+ }
1142+ }
1143+
1144+ if (enable_int)
1145+ dfc_disable_int(context, event);
1146+ return status;
1147+}
1148+
1149+/******************************************************************************
1150+ dfc_get_pattern
1151+
1152+ Description:
1153+ This function is used to retrieve buffer size setting for a transaction
1154+ based on cmd.
1155+ Input Parameters:
1156+ context - Pointer to DFC context structure
1157+ cmd
1158+ Specifies type of command to be sent to NAND flash .The LSB of this
1159+ parameter defines the first command code for 2-cycles command. The
1160+ MSB defines the second command code for 2-cycles command. If MSB is
1161+ set to zero, this indicates that one cycle command
1162+ Output Parameters:
1163+ data_size
1164+ It is used to retrieve length of data transferred to/from DFC,
1165+ which includes padding bytes
1166+ padding
1167+ It is used to retrieve how many padding bytes there should be
1168+ in buffer of data_size.
1169+ Returns:
1170+ 0
1171+ If size setting is returned successfully
1172+ -EINVAL
1173+ If page size specified in flash spec of context structure is not 512 or
1174+ 2048;If specified command index is not read1/program/erase/reset/readID/
1175+ readStatus.
1176+*******************************************************************************/
1177+int dfc_get_pattern(struct dfc_context *context, uint16_t cmd,
1178+ int *data_size, int *padding)
1179+{
1180+ struct dfc_mode* dfc_mode = context->dfc_mode;
1181+ struct dfc_flash_info * flash_info = context->flash_info;
1182+ uint32_t page_size = context->flash_info->page_size; /* 512 or 2048 */
1183+
1184+ if (cmd == flash_info->read1 ||
1185+ cmd == flash_info->program) {
1186+ if (512 == page_size) {
1187+ /* add for DMA */
1188+ if (dfc_mode->enable_dma) {
1189+ *data_size = DFC_DATA_SIZE_544;
1190+ if (dfc_mode->enable_ecc)
1191+ *padding = DFC_PADDING_SIZE_24;
1192+ else
1193+ *padding = DFC_PADDING_SIZE_16;
1194+ } else if (!dfc_mode->enable_spare) {
1195+ *data_size = DFC_DATA_SIZE_512;
1196+ *padding = DFC_PADDING_SIZE_0;
1197+ } else {
1198+
1199+ if (dfc_mode->enable_ecc)
1200+ *data_size = DFC_DATA_SIZE_520;
1201+ else
1202+ *data_size = DFC_DATA_SIZE_528;
1203+
1204+ *padding = DFC_PADDING_SIZE_0;
1205+ }
1206+ } else if (2048 == page_size) {
1207+ /* add for DMA */
1208+ if (dfc_mode->enable_dma) {
1209+ *data_size = DFC_DATA_SIZE_2112;
1210+ if (dfc_mode->enable_ecc)
1211+ *padding = DFC_PADDING_SIZE_24;
1212+ else
1213+ *padding = DFC_PADDING_SIZE_0;
1214+ } else if (!dfc_mode->enable_spare) {
1215+ *data_size = DFC_DATA_SIZE_2048;
1216+ *padding = DFC_PADDING_SIZE_0;
1217+ } else {
1218+
1219+ if (dfc_mode->enable_ecc)
1220+ *data_size = DFC_DATA_SIZE_2088;
1221+ else
1222+ *data_size = DFC_DATA_SIZE_2112;
1223+
1224+ *padding = DFC_PADDING_SIZE_0;
1225+ }
1226+ } else /* if the page_size is neither 512 or 2048 */
1227+ return -EINVAL;
1228+ } else if (cmd == flash_info->read_id) {
1229+ *data_size = DFC_DATA_SIZE_ID;
1230+ *padding = DFC_PADDING_SIZE_0;
1231+ } else if(cmd == flash_info->read_status) {
1232+ *data_size = DFC_DATA_SIZE_STATUS;
1233+ *padding = DFC_PADDING_SIZE_0;
1234+ } else if (cmd == flash_info->erase || cmd == flash_info->reset) {
1235+ *data_size = DFC_DATA_SIZE_UNUSED;
1236+ *padding = DFC_PADDING_SIZE_UNUSED;
1237+ } else
1238+ return -EINVAL;
1239+ return 0;
1240+}
1241+
1242+
1243+/******************************************************************************
1244+ dfc_send_cmd
1245+
1246+ Description:
1247+ This function configures DFC to send command through DFC to NAND flash
1248+ Input Parameters:
1249+ context
1250+ Pointer to DFC context structure
1251+ cmd
1252+ Specifies type of command to be sent to NAND flash .The LSB of this
1253+ parameter defines the first command code for 2-cycles command. The
1254+ MSB defines the second command code for 2-cycles command. If MSB is
1255+ set to zero, this indicates that one cycle command
1256+ addr
1257+ Address sent out to the flash device withthis command. For page read/
1258+ program commands , 4-cycles address is sent. For erase command only
1259+ 3-cycles address is sent. If it is equal to 0xFFFFFFFF, the address
1260+ should not be used.
1261+ num_pages
1262+ It specifies the number of pages of data to be transferred for
1263+ a program or read commands. Unused for any other commands than
1264+ read/program.
1265+
1266+ Output Parameters:
1267+ None
1268+ Returns:
1269+ 0
1270+ If size setting is returned successfully
1271+ -EINVAL
1272+ If specified command index is not read1/program/erase/reset/readID/
1273+ readStatus.
1274+*******************************************************************************/
1275+int dfc_send_cmd(struct dfc_context *context, uint16_t cmd,
1276+ uint32_t addr, int num_pages)
1277+{
1278+ struct dfc_flash_info *flash_info = context->flash_info;
1279+ struct dfc_mode *dfc_mode = context->dfc_mode;
1280+ uint8_t cmd2;
1281+ uint32_t event_out;
1282+ uint32_t ndcb0=0, ndcb1=0, ndcb2=0, ndcr;
1283+ int status;
1284+
1285+ /* It is a must to set ND_RUN firstly, then write command buffer
1286+ * If conversely,it does not work
1287+ */
1288+ dfc_write(context, DFC_NDSR, NDSR_MASK);
1289+
1290+ /* Set ND_RUN */
1291+ ndcr = dfc_read(context, DFC_NDCR);
1292+ dfc_write(context, DFC_NDCR, (ndcr | NDCR_ND_RUN));
1293+
1294+ // Wait for write command request
1295+ status = dfc_wait_event(context, NDSR_WRCMDREQ,
1296+ &event_out, NAND_CMD_TIMEOUT, 0);
1297+
1298+ if (status) /* Timeout */
1299+ return status;
1300+
1301+ cmd2 = (cmd>>8) & 0xFF;
1302+ ndcb0 = cmd | (dfc_mode->chip_select<<24) | ((cmd2?1:0)<<19);
1303+
1304+ if (cmd == flash_info->read1) {
1305+ if (0xFFFFFFFF != addr) {
1306+ ndcb0 |= NDCB0_ADDR_CYC(4);
1307+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1308+ if (status)
1309+ return status;
1310+ ndcb2 = (num_pages - 1) << 8;
1311+ }
1312+ } else if (cmd == flash_info->program) {
1313+ ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS;
1314+ ndcb0 |= NDCB0_ADDR_CYC(4);
1315+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1316+ if (status)
1317+ return status;
1318+ ndcb2 = (num_pages-1) << 8;
1319+ } else if (cmd == flash_info->erase) {
1320+ ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS;
1321+ ndcb0 |= NDCB0_ADDR_CYC(3);
1322+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1323+ if (status)
1324+ return status;
1325+ } else if (cmd == flash_info->read_id) {
1326+ ndcb0 |= NDCB0_CMD_TYPE(3);
1327+ } else if(cmd == flash_info->read_status) {
1328+ ndcb0 |= NDCB0_CMD_TYPE(4);
1329+ } else if(cmd == flash_info->reset) {
1330+ ndcb0 |= NDCB0_CMD_TYPE(5);
1331+ } else if (cmd == flash_info->lock) {
1332+ ndcb0 |= NDCB0_CMD_TYPE(5);
1333+ } else
1334+ return -EINVAL;
1335+
1336+ /* Write to DFC command register */
1337+ dfc_write(context, DFC_NDCB0, ndcb0);
1338+ dfc_write(context, DFC_NDCB0, ndcb1);
1339+ dfc_write(context, DFC_NDCB0, ndcb2);
1340+
1341+ return 0;
1342+}
1343+
1344+/******************************************************************************
1345+ dfc_stop
1346+
1347+ Description:
1348+ This function clears ND_RUN bit of NDCR.
1349+ Input Parameters:
1350+ context--Pointer to DFC context structure
1351+ Output Parameters:
1352+ None
1353+ Returns:
1354+ None
1355+*******************************************************************************/
1356+void dfc_stop(struct dfc_context *context)
1357+{
1358+ unsigned int ndcr;
1359+ ndcr = dfc_read(context, DFC_NDCR);
1360+ dfc_write(context, DFC_NDCR, (ndcr & ~NDCR_ND_RUN));
1361+ ndcr = dfc_read(context, DFC_NDCR);
1362+
1363+ return;
1364+}
1365+
1366+int dfc_setup_cmd_dma(struct dfc_context *context,
1367+ uint16_t cmd, uint32_t addr, int num_pages,
1368+ uint32_t *buf, uint32_t buf_phys,
1369+ uint32_t next_desc_phys, uint32_t dma_int_en,
1370+ struct pxa_dma_desc *dma_desc)
1371+{
1372+ struct dfc_flash_info *flash_info = context->flash_info;
1373+ struct dfc_mode *dfc_mode = context->dfc_mode;
1374+ uint8_t cmd2;
1375+ uint32_t event_out;
1376+ uint32_t ndcb0=0, ndcb1=0, ndcb2=0, ndcr;
1377+ int status;
1378+
1379+ /*
1380+ * It is a must to set ND_RUN firstly, then write command buffer
1381+ * If conversely,it does not work
1382+ */
1383+ dfc_write(context, DFC_NDSR, NDSR_MASK);
1384+
1385+ /* Set ND_RUN */
1386+ ndcr = dfc_read(context, DFC_NDCR);
1387+ ndcr |= NDCR_ND_RUN;
1388+ dfc_write(context, DFC_NDCR, ndcr);
1389+
1390+ /* Wait for write command request */
1391+ status = dfc_wait_event(context, NDSR_WRCMDREQ,
1392+ &event_out, NAND_CMD_TIMEOUT, 0);
1393+
1394+ if (status)
1395+ return status; /* Timeout */
1396+
1397+ cmd2 = (cmd>>8) & 0xFF;
1398+ ndcb0 = cmd | (dfc_mode->chip_select<<24) | ((cmd2?1:0)<<19);
1399+
1400+ if (cmd == flash_info->read1) {
1401+ if (0xFFFFFFFF != addr) {
1402+ ndcb0 |= NDCB0_ADDR_CYC(4);
1403+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1404+ if (status)
1405+ return status;
1406+ ndcb2 = (num_pages-1) << 8;
1407+ }
1408+ } else if (cmd == flash_info->program) {
1409+ ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS;
1410+ ndcb0 |= NDCB0_ADDR_CYC(4);
1411+
1412+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1413+ if (status)
1414+ return status;
1415+ ndcb2 = (num_pages-1) << 8;
1416+ } else if (cmd == flash_info->erase) {
1417+ ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS;
1418+ ndcb0 |= NDCB0_ADDR_CYC(3);
1419+
1420+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1421+ if (status)
1422+ return status;
1423+ } else if (cmd == flash_info->read_id) {
1424+ ndcb0 |= NDCB0_CMD_TYPE(3);
1425+ } else if (cmd == flash_info->read_status) {
1426+ ndcb0 |= NDCB0_CMD_TYPE(4);
1427+ } else if (cmd == flash_info->reset) {
1428+ ndcb0 |= NDCB0_CMD_TYPE(5);
1429+ } else if (cmd == flash_info->lock) {
1430+ ndcb0 |= NDCB0_CMD_TYPE(5);
1431+ } else
1432+ return -EINVAL;
1433+
1434+ *((uint32_t *)buf) = ndcb0;
1435+ *((uint32_t *)buf + 1) = ndcb1;
1436+ *((uint32_t *)buf + 2) = ndcb2;
1437+
1438+ dma_int_en &= (DCMD_STARTIRQEN | DCMD_ENDIRQEN);
1439+
1440+ dma_desc->ddadr = next_desc_phys;
1441+ dma_desc->dsadr = buf_phys;
1442+ dma_desc->dtadr = NDCB0_DMA_ADDR;
1443+ dma_desc->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | dma_int_en |
1444+ DCMD_WIDTH4 | DCMD_BURST16 | 12;
1445+ return 0;
1446+}
1447+
1448+int dfc_setup_data_dma(struct dfc_context* context,
1449+ uint16_t cmd, uint32_t buf_phys,
1450+ uint32_t next_desc_phys, uint32_t dma_int_en,
1451+ struct pxa_dma_desc* dma_desc)
1452+{
1453+ struct dfc_flash_info * flash_info = context->flash_info;
1454+ int data_size, padding;
1455+
1456+ dfc_get_pattern(context, cmd, &data_size, &padding);
1457+
1458+ dma_desc->ddadr = next_desc_phys;
1459+ dma_int_en &= (DCMD_STARTIRQEN | DCMD_ENDIRQEN);
1460+
1461+ if (cmd == flash_info->program) {
1462+
1463+ dma_desc->dsadr = buf_phys;
1464+ dma_desc->dtadr = NDDB_DMA_ADDR;
1465+ dma_desc->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | dma_int_en |
1466+ DCMD_WIDTH4 | DCMD_BURST32 | data_size;
1467+
1468+ } else if (cmd == flash_info->read1 || cmd == flash_info->read_id ||
1469+ cmd == flash_info->read_status) {
1470+
1471+ dma_desc->dsadr = NDDB_DMA_ADDR;
1472+ dma_desc->dtadr = buf_phys;
1473+ dma_desc->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | dma_int_en |
1474+ DCMD_WIDTH4 | DCMD_BURST32 | data_size;
1475+ }
1476+ else
1477+ return -EINVAL;
1478+ return 0;
1479+}
1480+
1481+void dfc_start_cmd_dma(struct dfc_context* context, struct pxa_dma_desc* dma_desc)
1482+{
1483+ DRCMR99 = DRCMR_MAPVLD | context->cmd_dma_ch; /* NAND CMD DRCMR */
1484+ DDADR(context->cmd_dma_ch) = (uint32_t)dma_desc;
1485+ DCSR(context->cmd_dma_ch) |= DCSR_RUN;
1486+}
1487+
1488+void dfc_start_data_dma(struct dfc_context* context, struct pxa_dma_desc* dma_desc)
1489+{
1490+ DRCMR97 = DRCMR_MAPVLD | context->data_dma_ch;
1491+ DDADR(context->data_dma_ch) = (uint32_t)dma_desc;
1492+ DCSR(context->data_dma_ch) |= DCSR_RUN;
1493+}
1494+
1495+/******************************************************************************
1496+ dfc_read_fifo_partial
1497+
1498+ Description:
1499+ This function reads data from data buffer of DFC.Bytes can be any less than
1500+ or equal to data_size, the left is ignored by ReadFIFO though they will be
1501+ read from NDDB to clear data buffer.
1502+ Input Parameters:
1503+ context
1504+ Pointer to DFC context structure
1505+ nbytes
1506+ Indicating how much data should be read into buffer.
1507+ data_size
1508+ Specifing length of data transferred to/from DFC, which includes
1509+ padding bytes
1510+ Output Parameters:
1511+ pBuffer
1512+ Pointer to the data buffer where data should be placed.
1513+ Returns:
1514+ None
1515+*******************************************************************************/
1516+void dfc_read_fifo_partial(struct dfc_context *context, uint8_t *buffer,
1517+ int nbytes, int data_size)
1518+{
1519+ uint32_t data = 0;
1520+ uint32_t i = 0;
1521+ uint32_t bytes_multi;
1522+ uint32_t bytes_remain;
1523+
1524+
1525+ if (1 == data_size) {
1526+ data = dfc_read(context, DFC_NDDB) & 0xFF;
1527+ *buffer++ = (uint8_t)data;
1528+ } else if (2 == data_size) {
1529+ data = dfc_read(context, DFC_NDDB) & 0xFFFF;
1530+ *buffer++ = data & 0xFF;
1531+ *buffer++ = (data >> 8) & 0xFF;
1532+ } else {
1533+ bytes_multi = (nbytes & 0xFFFFFFFC);
1534+ bytes_remain = nbytes & 0x03;
1535+
1536+ i = 0;
1537+ /* Read the bytes_multi*4 bytes data */
1538+ while (i < bytes_multi) {
1539+ data = dfc_read(context, DFC_NDDB);
1540+ /* FIXME: we don't know whether the buffer
1541+ * align to 4 bytes or not. Cast the buffer
1542+ * to int is not safe here. Especially under
1543+ * gcc 4.x. Used memcpy here. But the memcpy
1544+ * may be not correct on BE architecture.
1545+ * --by Yin, Fengwei
1546+ */
1547+ memcpy(buffer, &data, sizeof(data));
1548+ i += sizeof(data);
1549+ buffer += sizeof(data);
1550+ }
1551+
1552+ /* Read the left bytes_remain bytes data */
1553+ if (bytes_remain) {
1554+ data = dfc_read(context, DFC_NDDB);
1555+ for (i = 0; i < bytes_remain; i++)
1556+ *buffer++ = (uint8_t)((data >> (8*i)) & 0xFF);
1557+ }
1558+
1559+ /* When read the remain bytes, we always read 4 bytes data
1560+ * to DFC. So the data_size should subtract following number.
1561+ */
1562+ data_size -= bytes_multi + (bytes_remain ? sizeof(data) : 0);
1563+
1564+ /* We need Read data_size bytes data totally */
1565+ while (data_size > 0) {
1566+ data = dfc_read(context, DFC_NDDB);
1567+ data_size -= sizeof(data);
1568+ }
1569+
1570+/*
1571+ while(i < ((uint32_t)data_size) ) {
1572+ if (i < bytes_multi) {
1573+ temp = (uint32_t *)buffer;
1574+ *temp = dfc_reg->nddb;
1575+ } else if (i == bytes_multi && bytes_remain){
1576+ uint32_t j = 0;
1577+ data = dfc_reg->nddb;
1578+ while (j++ < bytes_remain) {
1579+ *buffer++ = (uint8_t) \
1580+ ((data>>(8*j)) & 0xFF);
1581+ }
1582+ } else {
1583+ data = dfc_reg->nddb;
1584+ }
1585+ i += 4;
1586+ buffer += 4;
1587+ }
1588+*/
1589+ }
1590+ return;
1591+}
1592+
1593+/******************************************************************************
1594+ dfc_write_fifo_partial
1595+
1596+ Description:
1597+ Write to data buffer of DFC from a buffer. Bytes can be same as
1598+ data_size, also can be data_size-padding, but can¡¯t be random value,
1599+ the left will be automatically padded by WriteFIFO.
1600+ Input Parameters:
1601+ context
1602+ Pointer to DFC context structure
1603+ bytes
1604+ Indicating how much data should be read into buffer.
1605+ data_size
1606+ Specifing length of data transferred to/from DFC, which includes
1607+ padding bytes
1608+ buffer
1609+ Pointer to the data buffer where data will be taken from to be written
1610+ to DFC data buffer
1611+ Output Parameters:
1612+ None
1613+ Returns:
1614+ None
1615+*******************************************************************************/
1616+void dfc_write_fifo_partial(struct dfc_context *context, uint8_t *buffer,
1617+ int nbytes, int data_size)
1618+{
1619+ uint32_t i = 0;
1620+
1621+ uint32_t bytes_multi = (nbytes & 0xFFFFFFFC);
1622+ uint32_t bytes_remain = nbytes & 0x03;
1623+ uint32_t temp;
1624+ /*
1625+ * caller guarantee buffer contains appropriate data thereby
1626+ * it is impossible for nbytes not to be a multiple of 4 byte
1627+ */
1628+
1629+ /* Write the bytes_multi*4 bytes data */
1630+ while (i < bytes_multi) {
1631+ temp = buffer[0] | buffer[1] << 8 |
1632+ buffer[2] << 16 | buffer[3] << 24;
1633+ dfc_write(context, DFC_NDDB, temp);
1634+ buffer += 4;
1635+ i += 4;
1636+ }
1637+
1638+ /* Write the left bytes_remain bytes data */
1639+ if (bytes_remain) {
1640+ temp = 0xFFFFFFFF;
1641+ for (i = 0; i < bytes_remain; i++)
1642+ temp &= *buffer++ << i*8;
1643+
1644+ dfc_write(context, DFC_NDDB, temp);
1645+ }
1646+
1647+ /* When write the remain bytes, we always write 4 bytes data
1648+ * to DFC. So the data_size should subtract following number.
1649+ */
1650+ data_size -= bytes_multi + (bytes_remain ? sizeof(temp) : 0);
1651+
1652+ while (data_size > 0) {
1653+ dfc_write(context, DFC_NDDB, 0xFFFFFFFF);
1654+ data_size -= 4;
1655+ }
1656+
1657+/*
1658+ while (i < ((uint32_t)data_size)) {
1659+ if (i < bytes_multi) {
1660+ temp = (uint32_t *)buffer;
1661+ dfc_reg->nddb = *temp;
1662+ }
1663+ else if (i == bytes_multi && bytes_remain) {
1664+ uint32_t j = 0, data = 0xFFFFFFFF;
1665+ while (j < bytes_remain) {
1666+ data &= (uint8_t)(*buffer) << j;
1667+ buffer++;
1668+ j++;
1669+ }
1670+ dfc_reg->nddb = data;
1671+ }
1672+ else {
1673+ dfc_reg->nddb = 0xFFFFFFFF;
1674+ }
1675+ i += 4;
1676+ buffer += 4;
1677+ }
1678+*/
1679+
1680+ return;
1681+}
1682+
1683+/******************************************************************************
1684+ dfc_read_fifo
1685+ Description:
1686+ This function reads data from data buffer of DFC.Bytes can be any less
1687+ than or equal to data_size, the left is ignored by ReadFIFO though they
1688+ will be read from NDDB to clear data buffer.
1689+ Input Parameters:
1690+ context
1691+ Pointer to DFC context structure
1692+ nbytes
1693+ Indicating how much data should be read into buffer.
1694+ data_size
1695+ Specifing length of data transferred to/from DFC, which includes
1696+ padding bytes
1697+ Output Parameters:
1698+ buffer
1699+ Pointer to the data buffer where data should be placed.
1700+ Returns:
1701+ None
1702+*******************************************************************************/
1703+
1704+void dfc_read_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes)
1705+{
1706+ uint32_t i = 0;
1707+
1708+ uint32_t bytes_multi = (nbytes & 0xFFFFFFFC);
1709+ uint32_t bytes_remain = nbytes & 0x03;
1710+ uint32_t temp;
1711+
1712+ /* Read the bytes_multi*4 bytes data */
1713+ while (i < bytes_multi) {
1714+ temp = dfc_read(context, DFC_NDDB);
1715+ /* FIXME: we don't know whether the buffer
1716+ * align to 4 bytes or not. Cast the buffer
1717+ * to int is not safe here. Especially under
1718+ * gcc 4.x. Used memcpy here. But the memcpy
1719+ * may be not correct on BE architecture.
1720+ * --by Yin, Fengwei
1721+ */
1722+ memcpy(buffer, &temp, sizeof(temp));
1723+ i += sizeof(temp);
1724+ buffer += sizeof(temp);
1725+ }
1726+
1727+ /* Read the left bytes_remain bytes data */
1728+ temp = dfc_read(context, DFC_NDDB);
1729+ for (i = 0; i < bytes_remain; i++) {
1730+ *buffer++ = (uint8_t)((temp >> (8*i)) & 0xFF);
1731+ }
1732+
1733+/*
1734+ while (i < bytes_multi) {
1735+ temp = (uint32_t *)buffer;
1736+ *temp = dfc_reg->nddb;
1737+ i += 4;
1738+ buffer += 4;
1739+ }
1740+
1741+ if (bytes_remain) {
1742+ data = dfc_reg->nddb;
1743+ for (i = 0; i < bytes_remain; i++) {
1744+ *buffer++ = (uint8_t)((data>>(8*i)) & 0xFF);
1745+ }
1746+ }
1747+*/
1748+
1749+ return;
1750+}
1751+
1752+/******************************************************************************
1753+ dfc_write_fifo
1754+ Description:
1755+ Write to data buffer of DFC from a buffer.Bytes can be same as data_size,
1756+ also can be data_size-padding, but can¡¯t be random value, the left will
1757+ be automatically padded by WriteFIFO.
1758+ Input Parameters:
1759+ context
1760+ Pointer to DFC context structure
1761+ nbytes
1762+ Indicating how much data should be read into buffer.
1763+ data_size
1764+ Specifing length of data transferred to/from DFC, which includes
1765+ padding bytes
1766+ buffer
1767+ Pointer to the data buffer where data will be taken from to be written to
1768+ DFC data buffer
1769+ Output Parameters:
1770+ None
1771+ Returns:
1772+ None
1773+*******************************************************************************/
1774+void dfc_write_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes)
1775+{
1776+ uint32_t bytes_multi = (nbytes & 0xFFFFFFFC);
1777+ uint32_t bytes_remain = nbytes & 0x03;
1778+ uint32_t i=0;
1779+ uint32_t temp;
1780+
1781+ /* Write the bytes_multi*4 bytes data */
1782+ while (i < bytes_multi) {
1783+ temp = buffer[0] | buffer[1] << 8 |
1784+ buffer[2] << 16 | buffer[3] << 24;
1785+ dfc_write(context, DFC_NDDB, temp);
1786+ buffer += 4;
1787+ i += 4;
1788+ }
1789+
1790+ /* Write the left bytes_remain bytes data */
1791+ temp = 0xFFFFFFFF;
1792+ for (i = 0; i < bytes_remain; i++)
1793+ temp &= *buffer++ << i*8;
1794+ dfc_write(context, DFC_NDDB, temp);
1795+
1796+/*
1797+ while (i < nbytes) {
1798+ temp = (uint32_t *)buffer;
1799+ dfc_reg->nddb = *temp;
1800+ i += 4;
1801+ buffer += 4;
1802+ }
1803+*/
1804+}
1805+
1806+/******************************************************************************
1807+ dfc_read_badblock_addr
1808+
1809+ Description:
1810+ This function reads bad block address in units of block starting from 0
1811+ if bad block is detected. It takes into the account if the operation is
1812+ for CS0 or CS1 depending on settings of chip_select parameter of DFC
1813+ Mode structure.
1814+ Input Parameters:
1815+ context
1816+ Pointer to DFC context structure
1817+ Output Parameters:
1818+ pBadBlockAddr
1819+ Used to retrieve bad block address back to caller if bad block is
1820+ detected
1821+ Returns:
1822+ None
1823+*******************************************************************************/
1824+void dfc_read_badblock_addr(struct dfc_context *context, uint32_t *bbaddr)
1825+{
1826+ uint32_t ndbdr;
1827+ if (0 == context->dfc_mode->chip_select)
1828+ ndbdr = dfc_read(context, DFC_NDBDR0);
1829+ else
1830+ ndbdr = dfc_read(context, DFC_NDBDR1);
1831+
1832+ if (512 == context->flash_info->page_size) {
1833+ ndbdr = (ndbdr >> 5) & 0xFFF;
1834+ *bbaddr = ndbdr;
1835+ } else if (2048 == context->flash_info->page_size) {
1836+ /* 16 bits LB */
1837+ ndbdr = (ndbdr >> 8);
1838+ *bbaddr = ndbdr;
1839+ }
1840+ return;
1841+}
1842+
1843+/******************************************************************************
1844+ dfc_enable_int
1845+
1846+ Description:
1847+ This function is used to enable DFC interrupts. The bits in int_mask
1848+ will be used to unmask NDCR register to enable corresponding interrupts.
1849+ Input Parameters:
1850+ context
1851+ Pointer to DFC context structure
1852+ int_mask
1853+ Specifies what interrupts to enable
1854+ Output Parameters:
1855+ None
1856+ Returns:
1857+ None
1858+*******************************************************************************/
1859+void dfc_enable_int(struct dfc_context *context, uint32_t int_mask)
1860+{
1861+ uint32_t ndcr;
1862+
1863+ ndcr = dfc_read(context, DFC_NDCR);
1864+ ndcr &= ~int_mask;
1865+ dfc_write(context, DFC_NDCR, ndcr);
1866+
1867+ ndcr = dfc_read(context, DFC_NDCR);
1868+ return;
1869+}
1870+
1871+/******************************************************************************
1872+ dfc_disable_int
1873+
1874+ Description:
1875+ This function is used to disable DFC interrupts.
1876+ The bits inint_mask will be used to mask NDCR register to disable
1877+ corresponding interrupts.
1878+ Input Parameters:
1879+ context
1880+ Pointer to DFC context structure
1881+ int_mask
1882+ Specifies what interrupts to disable
1883+ Output Parameters:
1884+ None
1885+ Returns:
1886+ None
1887+*******************************************************************************/
1888+void dfc_disable_int(struct dfc_context *context, uint32_t int_mask)
1889+{
1890+ uint32_t ndcr;
1891+
1892+ ndcr = dfc_read(context, DFC_NDCR);
1893+ ndcr |= int_mask;
1894+ dfc_write(context, DFC_NDCR, ndcr);
1895+
1896+ ndcr = dfc_read(context, DFC_NDCR);
1897+ return;
1898+}
1899+
1900+/******************************************************************************
1901+ dfc_clear_int
1902+
1903+ Description:
1904+ This function is used to disable DFC interrupts.
1905+ The bits in int_mask will be used to clear corresponding interrupts
1906+ in NDCR register
1907+ Input Parameters:
1908+ context
1909+ Pointer to DFC context structure
1910+ int_mask
1911+ Specifies what interrupts to clear
1912+ Output Parameters:
1913+ None
1914+ Returns:
1915+ None
1916+*******************************************************************************/
1917+void dfc_clear_int(struct dfc_context *context, uint32_t int_mask)
1918+{
1919+ dfc_write(context, DFC_NDSR, int_mask);
1920+
1921+ dfc_read(context, DFC_NDSR);
1922+ return;
1923+}
1924+
1925+/*
1926+ * high level primitives
1927+ */
1928+
1929+/******************************************************************************
1930+ dfc_init
1931+
1932+ Description:
1933+ This function does entire DFC initialization according to the NAND
1934+ flash type currently used with platform, including setting MFP, set
1935+ flash timing, set DFC mode, configuring specified flash parameters
1936+ in DFC, clear ECC logic and page count register.
1937+ Input Parameters:
1938+ context
1939+ Pointer to DFC context structure
1940+ Output Parameters:
1941+ None
1942+ Returns:
1943+ 0
1944+ if MFPRs are set correctly
1945+ -EINVAL
1946+ if specified flash is not support by check bytes per page and pages per
1947+ block
1948+******************************************************************************/
1949+
1950+static mfp_cfg_t pxa300_nand_cfg[] = {
1951+ /* NAND */
1952+ MFP_CFG_X(DF_INT_RnB, AF0, DS10X, PULL_LOW),
1953+ MFP_CFG_X(DF_nRE_nOE, AF1, DS10X, PULL_LOW),
1954+ MFP_CFG_X(DF_nWE, AF1, DS10X, PULL_LOW),
1955+ MFP_CFG_X(DF_CLE_nOE, AF0, DS10X, PULL_LOW),
1956+ MFP_CFG_X(DF_nADV1_ALE, AF1, DS10X, PULL_LOW),
1957+ MFP_CFG_X(DF_nCS0, AF1, DS10X, PULL_LOW),
1958+ MFP_CFG_X(DF_nCS1, AF0, DS10X, PULL_LOW),
1959+ MFP_CFG_X(DF_IO0, AF1, DS08X, PULL_LOW),
1960+ MFP_CFG_X(DF_IO1, AF1, DS08X, PULL_LOW),
1961+ MFP_CFG_X(DF_IO2, AF1, DS08X, PULL_LOW),
1962+ MFP_CFG_X(DF_IO3, AF1, DS08X, PULL_LOW),
1963+ MFP_CFG_X(DF_IO4, AF1, DS08X, PULL_LOW),
1964+ MFP_CFG_X(DF_IO5, AF1, DS08X, PULL_LOW),
1965+ MFP_CFG_X(DF_IO6, AF1, DS08X, PULL_LOW),
1966+ MFP_CFG_X(DF_IO7, AF1, DS08X, PULL_LOW),
1967+ MFP_CFG_X(DF_IO8, AF1, DS08X, PULL_LOW),
1968+ MFP_CFG_X(DF_IO9, AF1, DS08X, PULL_LOW),
1969+ MFP_CFG_X(DF_IO10, AF1, DS08X, PULL_LOW),
1970+ MFP_CFG_X(DF_IO11, AF1, DS08X, PULL_LOW),
1971+ MFP_CFG_X(DF_IO12, AF1, DS08X, PULL_LOW),
1972+ MFP_CFG_X(DF_IO13, AF1, DS08X, PULL_LOW),
1973+ MFP_CFG_X(DF_IO14, AF1, DS08X, PULL_LOW),
1974+};
1975+
1976+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
1977+
1978+int dfc_init(struct dfc_context* context, int type)
1979+{
1980+ int status;
1981+ struct dfc_flash_info * flash_info;
1982+ uint32_t ndcr = 0x00000FFF; /* disable all interrupts */
1983+
1984+ status = dfc_get_flash_info(type, &flash_info);
1985+ if (status)
1986+ return status;
1987+ context->flash_info = flash_info;
1988+
1989+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_nand_cfg));
1990+ //enable_dfc_pins();
1991+
1992+ dfc_set_timing(context, &context->flash_info->timing);
1993+
1994+ if (flash_info->enable_arbiter)
1995+ ndcr |= NDCR_ND_ARB_EN;
1996+
1997+ if (64 == flash_info->page_per_block)
1998+ ndcr |= NDCR_PG_PER_BLK;
1999+ else if (32 != flash_info->page_per_block)
2000+ return -EINVAL;
2001+
2002+ if (flash_info->row_addr_start)
2003+ ndcr |= NDCR_RA_START;
2004+
2005+ ndcr |= (flash_info->read_id_bytes)<<16;
2006+
2007+ ndcr |= (flash_info->dfc_mode) << 21;
2008+
2009+ if (flash_info->ncsx)
2010+ ndcr |= NDCR_NCSX;
2011+
2012+ if (2048 == flash_info->page_size)
2013+ ndcr |= NDCR_PAGE_SZ;
2014+ else if (512 != flash_info->page_size)
2015+ return -EINVAL;
2016+
2017+ if (16 == flash_info->flash_width)
2018+ ndcr |= NDCR_DWIDTH_M;
2019+ else if (8 != flash_info->flash_width)
2020+ return -EINVAL;
2021+
2022+ if (16 == flash_info->dfc_width)
2023+ ndcr |= NDCR_DWIDTH_C;
2024+ else if (8 != flash_info->dfc_width)
2025+ return -EINVAL;
2026+
2027+ dfc_write(context, DFC_NDCR, ndcr);
2028+
2029+ dfc_set_dma(context);
2030+ dfc_set_ecc(context);
2031+ dfc_set_spare(context);
2032+
2033+ return 0;
2034+}
2035+
2036+/******************************************************************************
2037+ dfc_init_no_gpio
2038+
2039+ Description:
2040+ This function does entire DFC initialization according to the NAND
2041+ flash type currently used with platform, including set flash timing,
2042+ set DFC mode, configuring specified flash parameters in DFC, clear
2043+ ECC logic and page count register. The only difference with dfc_init
2044+ is that it does not set MFP&GPIO, very useful in OS loader
2045+ Input Parameters:
2046+ context
2047+ Pointer to DFC context structure
2048+ Output Parameters:
2049+ None
2050+ Returns:
2051+ 0
2052+ if MFPRs are set correctly
2053+ -EINVAL
2054+ if specified flash is not support by check bytes per page and pages
2055+ per block
2056+******************************************************************************/
2057+int dfc_init_no_gpio(struct dfc_context* context, int type)
2058+{
2059+ struct dfc_flash_info * flash_info;
2060+ uint32_t ndcr = 0x00000FFF; /* disable all interrupts */
2061+ int status;
2062+
2063+ status = dfc_get_flash_info(type, &flash_info);
2064+ if (status)
2065+ return status;
2066+ context->flash_info = flash_info;
2067+
2068+ dfc_set_timing(context, &context->flash_info->timing);
2069+
2070+ if (flash_info->enable_arbiter)
2071+ ndcr |= NDCR_ND_ARB_EN;
2072+
2073+ if (64 == flash_info->page_per_block)
2074+ ndcr |= NDCR_PG_PER_BLK;
2075+ else if (32 != flash_info->page_per_block)
2076+ return -EINVAL;
2077+
2078+ if (flash_info->row_addr_start)
2079+ ndcr |= NDCR_RA_START;
2080+
2081+ ndcr |= (flash_info->read_id_bytes)<<16;
2082+
2083+ ndcr |= (flash_info->dfc_mode) << 21;
2084+
2085+ if (flash_info->ncsx)
2086+ ndcr |= NDCR_NCSX;
2087+
2088+ if (2048 == flash_info->page_size)
2089+ ndcr |= NDCR_PAGE_SZ;
2090+ else if (512 != flash_info->page_size)
2091+ return -EINVAL;
2092+
2093+ if (16 == flash_info->flash_width)
2094+ ndcr |= NDCR_DWIDTH_M;
2095+ else if (8 != flash_info->flash_width)
2096+ return -EINVAL;
2097+
2098+ if (16 == flash_info->dfc_width)
2099+ ndcr |= NDCR_DWIDTH_C;
2100+ else if (8 != flash_info->dfc_width)
2101+ return -EINVAL;
2102+
2103+ dfc_write(context, DFC_NDCR, ndcr);
2104+
2105+ dfc_set_dma(context);
2106+ dfc_set_ecc(context);
2107+ dfc_set_spare(context);
2108+
2109+ return 0;
2110+}
2111+
2112+/*
2113+ * This macro will be used in following NAND operation functions.
2114+ * It is used to clear command buffer to ensure cmd buffer is empty
2115+ * in case of operation is timeout
2116+ */
2117+#define ClearCMDBuf() do { \
2118+ dfc_stop(context); \
2119+ udelay(NAND_OTHER_TIMEOUT); \
2120+ } while (0)
2121+
2122+/******************************************************************************
2123+ dfc_reset_flash
2124+
2125+ Description:
2126+ It reset the flash. The function can be called at any time when the
2127+ device is in Busy state during random read/program/erase mode and
2128+ reset operation will abort all these operations. After reset operation
2129+ the device is ready to wait for next command
2130+ Input Parameters:
2131+ context
2132+ Pointer to DFC context structure
2133+ Output Parameters:
2134+ None
2135+ Returns:
2136+ 0
2137+ execution succeeds
2138+ -ETIME
2139+ if timeout
2140+*******************************************************************************/
2141+int dfc_reset_flash(struct dfc_context *context)
2142+{
2143+ struct dfc_flash_info *flash_info = context->flash_info;
2144+ uint32_t event, event_out;
2145+ unsigned long timeo;
2146+ int status;
2147+
2148+ /* Send command */
2149+ dfc_send_cmd(context, (uint16_t)flash_info->reset, 0xFFFFFFFF, 0);
2150+
2151+ event = (context->dfc_mode->chip_select)? \
2152+ NDSR_CS1_CMDD : NDSR_CS0_CMDD;
2153+
2154+ /* Wait for CMDDM(command done successfully) */
2155+ status = dfc_wait_event(context, event, &event_out,
2156+ NAND_OTHER_TIMEOUT, 0);
2157+
2158+ if (status) {
2159+ ClearCMDBuf();
2160+ return status;
2161+ }
2162+
2163+
2164+ /* Wait until flash device is stable or timeout (10ms) */
2165+ timeo = jiffies + HZ;
2166+ do {
2167+ if (monahans_df_dev_ready(context->mtd))
2168+ break;
2169+ } while (time_before(jiffies, timeo));
2170+
2171+ return 0;
2172+}
2173+
2174+int dfc_readid(struct dfc_context *context, uint32_t *id)
2175+{
2176+ struct dfc_flash_info *flash_info = context->flash_info;
2177+ uint32_t event_out;
2178+ int status;
2179+ char tmp[DFC_DATA_SIZE_ID];
2180+
2181+ /* Send command */
2182+ status = dfc_send_cmd(context, (uint16_t)flash_info->read_id,
2183+ 0xFFFFFFFF, 0);
2184+ if (status) {
2185+ ClearCMDBuf();
2186+ return status;
2187+ }
2188+
2189+ /* Wait for CMDDM(command done successfully) */
2190+ status = dfc_wait_event(context, NDSR_RDDREQ, &event_out,
2191+ NAND_OTHER_TIMEOUT, 0);
2192+ if (status) {
2193+ ClearCMDBuf();
2194+ return status;
2195+ }
2196+ dfc_read_fifo_partial(context, (unsigned char *)tmp,
2197+ context->flash_info->read_id_bytes, DFC_DATA_SIZE_ID);
2198+
2199+ *id = tmp[0] | (tmp[1] << 8);
2200+ return 0;
2201+}
2202+
2203+#define ERR_NONE 0x0
2204+#define ERR_DMABUSERR (-0x01)
2205+#define ERR_SENDCMD (-0x02)
2206+#define ERR_DBERR (-0x03)
2207+#define ERR_BBERR (-0x04)
2208+#define ERR_BUSY (-0x05)
2209+
2210+#define STATE_CMD_SEND 0x1
2211+#define STATE_CMD_HANDLE 0x2
2212+#define STATE_DMA_TRANSFER 0x3
2213+#define STATE_DMA_DONE 0x4
2214+#define STATE_READY 0x5
2215+#define STATE_SUSPENDED 0x6
2216+#define STATE_DATA_TRANSFER 0x7
2217+
2218+#define NAND_RELOC_MAX 127
2219+#define NAND_RELOC_HEADER 0x524e
2220+#define MAX_CHIP 1
2221+#define NAND_CMD_DMA_LEN 12
2222+
2223+#define MAX_TIM_SIZE 0x1000
2224+#define MAX_BBT_SLOTS 24
2225+
2226+struct reloc_item {
2227+ unsigned short from;
2228+ unsigned short to;
2229+};
2230+
2231+struct reloc_table {
2232+ unsigned short header;
2233+ unsigned short total;
2234+ struct reloc_item reloc[NAND_RELOC_MAX];
2235+};
2236+
2237+struct monahans_dfc_info {
2238+ unsigned int state;
2239+ struct dfc_context *context;
2240+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2241+ dma_addr_t data_buf_addr;
2242+ char *data_buf;
2243+ int data_dma;
2244+ struct pxa_dma_desc *data_desc;
2245+ dma_addr_t data_desc_addr;
2246+ dma_addr_t cmd_buf_addr;
2247+ char *cmd_buf;
2248+ int cmd_dma;
2249+ struct pxa_dma_desc *cmd_desc;
2250+ dma_addr_t cmd_desc_addr;
2251+ u64 dma_mask;
2252+#else
2253+ char *data_buf;
2254+#endif
2255+ u32 current_slot;
2256+ struct reloc_table table;
2257+ unsigned int table_init;
2258+ /* relate to the command */
2259+ unsigned int cmd;
2260+ unsigned int addr;
2261+ unsigned int column;
2262+ int retcode;
2263+ unsigned int buf_count;
2264+ struct completion cmd_complete;
2265+};
2266+
2267+static struct dfc_mode dfc_mode =
2268+{
2269+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2270+ 1, /* enable DMA */
2271+#else
2272+ 0,
2273+#endif
2274+ 1, /* enable ECC */
2275+ 1, /* enable SPARE */
2276+ 0, /* CS0 */
2277+};
2278+
2279+
2280+struct dfc_context dfc_context =
2281+{
2282+ 0, /* Initialized at function monahans_df_init() */
2283+ &dfc_mode,
2284+ 0, /* data dma channel */
2285+ 0, /* cmd dma channel */
2286+ NULL, /* &zylonite_flashinfo */
2287+};
2288+
2289+
2290+/*
2291+ * MTD structure for Zylonite board
2292+ */
2293+static struct mtd_info *monahans_mtd = NULL;
2294+
2295+/*
2296+ * BootRom and XDB will use last 127 block, and they will keep all the status
2297+ * of the bootloader and image, so skip the first 2M size and last 2M size
2298+ */
2299+static struct mtd_partition partition_info[] = {
2300+ {
2301+ name: "Bootloader",
2302+//#ifdef CONFIG_CPU_MONAHANS_LV
2303+ size: 0x00060000,
2304+//#else
2305+// size: 0x00040000,
2306+//#endif
2307+ offset: 0,
2308+ mask_flags: MTD_WRITEABLE /* force read-only */
2309+ },{
2310+ name: "Kernel",
2311+ size: 0x00200000,
2312+//#ifdef CONFIG_CPU_MONAHANS_LV
2313+ offset: 0x00060000,
2314+//#else
2315+// offset: 0x00040000,
2316+//#endif
2317+ mask_flags: MTD_WRITEABLE /* force read-only */
2318+ },{
2319+ name: "Filesystem",
2320+ size: 0x05000000,
2321+//#ifdef CONFIG_CPU_MONAHANS_LV
2322+ offset: 0x00260000,
2323+//#else
2324+// offset: 0x00240000,
2325+//#endif
2326+ }, {
2327+ name: "MassStorage",
2328+ size: 0x0, /* It will be set at probe function */
2329+ offset: MTDPART_OFS_APPEND /* Append after fs section */
2330+ }, {
2331+ name: "BBT",
2332+ size: 0x0, /* It will be set at probe function */
2333+ offset: MTDPART_OFS_APPEND,/* Append after fs section */
2334+ mask_flags: MTD_WRITEABLE /* force read-only */
2335+ }
2336+};
2337+
2338+#define PART_NUM ARRAY_SIZE(partition_info)
2339+
2340+/* MHN_OBM_V2 is related to BBT in MOBM V2
2341+ * MHN_OBM_V3 is related to BBT in MOBM V3
2342+ */
2343+enum {
2344+ MHN_OBM_NULL = 0,
2345+ MHN_OBM_V1,
2346+ MHN_OBM_V2,
2347+ MHN_OBM_V3,
2348+ MHN_OBM_INVAL
2349+} MHN_OBM_TYPE;
2350+
2351+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
2352+static uint8_t scan_main_bbt_pattern[] = { 'p', 'x', 'a', '1' };
2353+static uint8_t scan_mirror_bbt_pattern[] = { '0', 'a', 'x', 'p' };
2354+
2355+static struct nand_bbt_descr monahans_bbt_default = {
2356+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2357+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2358+ .maxblocks = 2,
2359+ .len = 2,
2360+ .offs = 0,
2361+ .pattern = scan_ff_pattern,
2362+};
2363+
2364+static struct nand_bbt_descr monahans_bbt_main = {
2365+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2366+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2367+ .veroffs = 6,
2368+ .maxblocks = 2,
2369+ .offs = 2,
2370+ .len = 4,
2371+ .pattern = scan_main_bbt_pattern,
2372+};
2373+
2374+static struct nand_bbt_descr monahans_bbt_mirror = {
2375+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2376+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2377+ .veroffs = 6,
2378+ .maxblocks = 2,
2379+ .offs = 2,
2380+ .len = 4,
2381+ .pattern = scan_mirror_bbt_pattern,
2382+};
2383+
2384+#if 0
2385+static struct nand_bbt_descr monahans_bbt_main = {
2386+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2387+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2388+ .veroffs = 2,
2389+ .maxblocks = 2,
2390+ .offs = 0x0,
2391+ .len = 2,
2392+ .pattern = scan_ff_pattern
2393+};
2394+static struct nand_bbt_descr monahans_bbt_mirror = {
2395+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2396+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2397+ .veroffs = 2,
2398+ .maxblocks = 2,
2399+ .offs = 0x0,
2400+ .len = 2,
2401+ .pattern = scan_ff_pattern
2402+};
2403+#endif
2404+
2405+static struct nand_ecclayout monahans_lb_nand_oob = {
2406+ .eccbytes = 24,
2407+ .eccpos = {
2408+ 40, 41, 42, 43, 44, 45, 46, 47,
2409+ 48, 49, 50, 51, 52, 53, 54, 55,
2410+ 56, 57, 58, 59, 60, 61, 62, 63},
2411+ .oobfree = { {2, 38} }
2412+};
2413+
2414+/*
2415+ * Monahans OOB size is only 8 bytes, and the rest 8 bytes is controlled by
2416+ * hardware for ECC. We construct virutal ECC buffer. Acutally, ECC is 6 bytes
2417+ * and the remain 2 bytes are reserved.
2418+ */
2419+static struct nand_ecclayout monahans_sb_nand_oob = {
2420+ .eccbytes = 6,
2421+ .eccpos = {8, 9, 10, 11, 12, 13 },
2422+ .oobfree = { {2, 6} }
2423+};
2424+
2425+
2426+static inline int is_buf_blank(u8 * buf, int size)
2427+{
2428+ int i = 0;
2429+ while(i < size) {
2430+ if (*((unsigned long *)(buf + i)) != 0xFFFFFFFF)
2431+ return 0;
2432+ i += 4;
2433+ }
2434+ if (i > size) {
2435+ i -= 4;
2436+ while( i < size) {
2437+ if(*(buf + i) != 0xFF)
2438+ return 0;
2439+ i++;
2440+ }
2441+ }
2442+ return 1;
2443+}
2444+
2445+static void print_buf(char *buf, int num)
2446+{
2447+ int i = 0;
2448+
2449+ while (i < num) {
2450+ printk(KERN_ERR "0x%08x: %02x %02x %02x %02x %02x %02x %02x"
2451+ " %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2452+ (unsigned int) (i), buf[i], buf[i+1], buf[i+2],
2453+ buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7],
2454+ buf[i+8], buf[i+9], buf[i+10],buf[i+11], buf[i+12],
2455+ buf[i+13], buf[i+14], buf[i+15]);
2456+ i += 16;
2457+ }
2458+}
2459+
2460+static int inline enable_dfc_dma(struct dfc_context *context, int enable)
2461+{
2462+ int ret = dfc_mode.enable_dma;
2463+ unsigned long ndcr;
2464+
2465+ if (!enable) {
2466+ ndcr = dfc_read(context, DFC_NDCR);
2467+ ndcr &= ~NDCR_DMA_EN;
2468+ dfc_write(context, DFC_NDCR, ndcr);
2469+ dfc_mode.enable_dma = 0;
2470+ } else {
2471+ ndcr = dfc_read(context, DFC_NDCR);
2472+ ndcr |= NDCR_DMA_EN;
2473+ dfc_write(context, DFC_NDCR, ndcr);
2474+ dfc_mode.enable_dma = 1;
2475+ }
2476+ return ret;
2477+}
2478+
2479+
2480+static void inline dump_info(struct monahans_dfc_info *info)
2481+{
2482+ if (!info)
2483+ return;
2484+
2485+ printk(KERN_ERR "cmd:0x%x; addr:0x%x; retcode:%d; state:%d \n",
2486+ info->cmd, info->addr, info->retcode, info->state);
2487+}
2488+
2489+static void inline enable_hw_ecc(struct dfc_context* context, int enable)
2490+{
2491+ unsigned long ndcr;
2492+
2493+ if (!enable) {
2494+ ndcr = dfc_read(context, DFC_NDCR);
2495+ ndcr &= ~NDCR_ECC_EN;
2496+ dfc_write(context, DFC_NDCR, ndcr);
2497+ dfc_mode.enable_ecc = 0;
2498+ }
2499+ else {
2500+ ndcr = dfc_read(context, DFC_NDCR);
2501+ ndcr |= NDCR_ECC_EN;
2502+ dfc_write(context, DFC_NDCR, ndcr);
2503+ dfc_mode.enable_ecc = 1;
2504+ }
2505+}
2506+
2507+/*
2508+ * Now, we are not sure that the NDSR_RDY mean the flash is ready.
2509+ * Need more test.
2510+ */
2511+static int monahans_df_dev_ready(struct mtd_info *mtd)
2512+{
2513+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2514+ (((struct nand_chip *)(mtd->priv))->priv);
2515+
2516+ struct dfc_context* context = info->context;
2517+
2518+ return ((dfc_read(context, DFC_NDSR) & NDSR_RDY));
2519+}
2520+
2521+/* each read, we can only read 4bytes from NDDB, we must buffer it */
2522+static u_char monahans_df_read_byte(struct mtd_info *mtd)
2523+{
2524+ char retval = 0xFF;
2525+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2526+ (((struct nand_chip *)(mtd->priv))->priv);
2527+
2528+ if (info->column < info->buf_count) {
2529+ /* Has just send a new command? */
2530+ retval = info->data_buf[info->column++];
2531+ }
2532+ return retval;
2533+}
2534+
2535+static void monahans_df_write_byte(struct mtd_info *mtd, u8 byte)
2536+{
2537+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2538+ (((struct nand_chip *)(mtd->priv))->priv);
2539+ info->data_buf[info->column++] = byte;
2540+}
2541+
2542+static u16 monahans_df_read_word(struct mtd_info *mtd)
2543+{
2544+ u16 retval = 0xFFFF;
2545+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2546+ (((struct nand_chip *)(mtd->priv))->priv);
2547+
2548+ if (!(info->column & 0x01) && info->column < info->buf_count) {
2549+ retval = *((u16 *)(info->data_buf+info->column));
2550+ info->column += 2;
2551+ }
2552+ return retval;
2553+}
2554+
2555+static void monahans_df_write_word(struct mtd_info *mtd, u16 word)
2556+{
2557+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2558+ (((struct nand_chip *)(mtd->priv))->priv);
2559+
2560+ if (!(info->column & 0x01) && info->column < info->buf_count) {
2561+ *((u16 *)(info->data_buf+info->column)) = word;
2562+ info->column += 2;
2563+ }
2564+}
2565+
2566+static void monahans_df_read_buf(struct mtd_info *mtd, u_char *buf, int len)
2567+{
2568+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2569+ (((struct nand_chip *)(mtd->priv))->priv);
2570+ int real_len = min((unsigned int)len, info->buf_count - info->column);
2571+
2572+ memcpy(buf, info->data_buf + info->column, real_len);
2573+ info->column += real_len;
2574+}
2575+
2576+static void monahans_df_write_buf(struct mtd_info *mtd,
2577+ const u_char *buf, int len)
2578+{
2579+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2580+ (((struct nand_chip *)(mtd->priv))->priv);
2581+ int real_len = min((unsigned int)len, info->buf_count - info->column);
2582+
2583+ memcpy(info->data_buf + info->column, buf, real_len);
2584+ info->column += real_len;
2585+}
2586+
2587+static int monahans_df_verify_buf(struct mtd_info *mtd,
2588+ const u_char *buf, int len)
2589+{
2590+ return 0;
2591+}
2592+
2593+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2594+static void monahans_dfc_cmd_dma_irq(int channel, void *data,
2595+ struct pt_regs *regs)
2596+{
2597+ unsigned int dcsr;
2598+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)data;
2599+ struct dfc_context* context = info->context;
2600+ struct dfc_mode* dfc_mode = context->dfc_mode;
2601+ unsigned int intm;
2602+
2603+ dcsr = DCSR(channel);
2604+ DCSR(channel) = dcsr;
2605+
2606+ intm = (dfc_mode->chip_select) ? \
2607+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2608+
2609+ D1(printk("cmd dma interrupt, channel:%d, DCSR:0x%08x\n", \
2610+ channel, dcsr));
2611+
2612+ if (dcsr & DCSR_BUSERR) {
2613+ info->retcode = ERR_DMABUSERR;
2614+ complete(&info->cmd_complete);
2615+ } else {
2616+ if ((info->cmd == NAND_CMD_READ0) ||
2617+ (info->cmd == NAND_CMD_READOOB)|| \
2618+ (info->cmd == NAND_CMD_READID) || \
2619+ (info->cmd == NAND_CMD_STATUS)) {
2620+ dfc_enable_int(context, NDSR_RDDREQ | NDSR_DBERR);
2621+ } else if (info->cmd == NAND_CMD_PAGEPROG)
2622+ dfc_enable_int(context, NDSR_WRDREQ);
2623+ else if (info->cmd == NAND_CMD_ERASE1)
2624+ dfc_enable_int(context, intm);
2625+ }
2626+
2627+ return;
2628+}
2629+
2630+
2631+static void monahans_dfc_data_dma_irq(int channel, void *data,
2632+ struct pt_regs *regs)
2633+{
2634+ unsigned int dcsr, intm;
2635+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)data;
2636+ struct dfc_context* context = info->context;
2637+ struct dfc_mode* dfc_mode = context->dfc_mode;
2638+
2639+ dcsr = DCSR(channel);
2640+ DCSR(channel) = dcsr;
2641+
2642+ intm = (dfc_mode->chip_select) ? \
2643+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2644+
2645+ D1(printk("data dma interrupt, channel:%d, DCSR:0x%08x\n",
2646+ channel, dcsr));
2647+ if (dcsr & DCSR_BUSERR) {
2648+ info->retcode = ERR_DMABUSERR;
2649+ complete(&info->cmd_complete);
2650+ }
2651+
2652+ if (info->cmd == NAND_CMD_PAGEPROG) {
2653+ /* DMA interrupt may be interrupted by other IRQs*/
2654+ info->state = STATE_DMA_DONE;
2655+ dfc_enable_int(context, intm);
2656+ } else {
2657+ info->state = STATE_READY;
2658+ complete(&info->cmd_complete);
2659+ }
2660+
2661+}
2662+#endif
2663+
2664+static irqreturn_t monahans_dfc_irq(int irq, void *devid)
2665+{
2666+ unsigned int status, event, intm, cmd;
2667+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)devid;
2668+ struct dfc_context* context = info->context;
2669+ struct dfc_mode* dfc_mode = context->dfc_mode;
2670+
2671+ intm = (dfc_mode->chip_select) ? \
2672+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2673+ event = (dfc_mode->chip_select) ? \
2674+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2675+
2676+ status = dfc_read(context, DFC_NDSR);
2677+ D1(printk("DFC irq, NDSR:0x%x\n", status));
2678+ if (status & (NDSR_RDDREQ | NDSR_DBERR)) {
2679+ if (status & NDSR_DBERR) {
2680+ info->retcode = ERR_DBERR;
2681+ }
2682+
2683+ dfc_disable_int(context, NDSR_RDDREQ | NDSR_DBERR);
2684+ dfc_clear_int(context, NDSR_RDDREQ | NDSR_DBERR);
2685+ if (info->cmd == NAND_CMD_READID)
2686+ cmd = context->flash_info->read_id;
2687+ else if (info->cmd == NAND_CMD_STATUS)
2688+ cmd = context->flash_info->read_status;
2689+ else if (info->cmd == NAND_CMD_READ0 ||
2690+ info->cmd == NAND_CMD_READOOB)
2691+ cmd = context->flash_info->read1;
2692+ else {
2693+ printk(KERN_ERR "No according command:0x%x happens\n",
2694+ info->cmd);
2695+ goto out;
2696+ }
2697+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2698+ info->state = STATE_DMA_TRANSFER;
2699+ dfc_start_data_dma(context,
2700+ (struct pxa_dma_desc*)info->data_desc_addr);
2701+#else
2702+ info->state = STATE_DATA_TRANSFER;
2703+ complete(&info->cmd_complete);
2704+#endif
2705+ } else if (status & NDSR_WRDREQ) {
2706+ dfc_disable_int(context, NDSR_WRDREQ);
2707+ dfc_clear_int(context, NDSR_WRDREQ);
2708+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2709+ info->state = STATE_DMA_TRANSFER;
2710+ dfc_start_data_dma(context,
2711+ (struct pxa_dma_desc*)info->data_desc_addr);
2712+#else
2713+ info->state = STATE_DATA_TRANSFER;
2714+ complete(&info->cmd_complete);
2715+#endif
2716+ } else if (status & event) {
2717+ if (status & NDSR_CS0_BBD) {
2718+ info->retcode = ERR_BBERR;
2719+ }
2720+
2721+ dfc_disable_int(context, intm);
2722+ dfc_clear_int(context, event);
2723+ info->state = STATE_READY;
2724+ complete(&info->cmd_complete);
2725+ }
2726+out:
2727+ return IRQ_HANDLED;
2728+}
2729+
2730+static int dfc_send_command(struct mtd_info *mtd, unsigned int cmd,
2731+ unsigned int addr, unsigned int num_pages,
2732+ unsigned int event)
2733+{
2734+
2735+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2736+ (((struct nand_chip *)(mtd->priv))->priv);
2737+ struct dfc_context* context = info->context;
2738+ int status;
2739+ int ret;
2740+
2741+ D1(printk("ready send command, cmd:0x%x, at address:0x%x,"
2742+ " num_pages:%d, wait event:0x%x\n", cmd, addr, num_pages, event));
2743+
2744+ info->state = STATE_CMD_SEND;
2745+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2746+ status = dfc_setup_cmd_dma(context, cmd, addr, num_pages,
2747+ (uint32_t *)info->cmd_buf, info->cmd_buf_addr,
2748+ DDADR_STOP, DCMD_ENDIRQEN, info->cmd_desc);
2749+#else
2750+ status = dfc_send_cmd(context, cmd, addr, num_pages);
2751+#endif
2752+ if (status) {
2753+ info->retcode = ERR_SENDCMD;
2754+ dfc_stop(context);
2755+ udelay(20);
2756+ printk(KERN_ERR "fail send command\n");
2757+ return info->retcode;
2758+ }
2759+ info->state = STATE_CMD_HANDLE;
2760+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2761+ dfc_setup_data_dma(context, cmd, info->data_buf_addr,
2762+ DDADR_STOP, DCMD_ENDIRQEN, info->data_desc);
2763+ dfc_start_cmd_dma(context, (struct pxa_dma_desc*)info->cmd_desc_addr);
2764+#endif
2765+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2766+ dfc_enable_int(context, event);
2767+#endif
2768+ ret = wait_for_completion_timeout(&info->cmd_complete, 2*HZ);
2769+ if (!ret){
2770+ printk(KERN_ERR "Command time out\n");
2771+ dump_info(info);
2772+ }
2773+ D1(printk("command return, cmd:0x%x, retcode:%d\n",
2774+ info->cmd, info->retcode));
2775+ return 0;
2776+}
2777+
2778+static void monahans_df_command(struct mtd_info *mtd, unsigned command,
2779+ int column, int page_addr )
2780+{
2781+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
2782+ struct monahans_dfc_info *info =
2783+ (struct monahans_dfc_info *)(this->priv);
2784+ struct dfc_context *context = info->context;
2785+ struct dfc_flash_info * flash_info = context->flash_info;
2786+ int ret, pages_shift;
2787+ int status;
2788+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2789+ int datasize;
2790+ int paddingsize;
2791+#endif
2792+ unsigned int to;
2793+
2794+ D1(printk("command:0x%x at address:0x%x, column:0x%x\n",
2795+ command, page_addr, column));
2796+
2797+ if (info->state != STATE_READY) {
2798+ printk(KERN_ERR "CHIP is not ready.\n");
2799+ dump_info(info);
2800+ info->retcode = ERR_BUSY;
2801+ return;
2802+ }
2803+ info->retcode = ERR_NONE;
2804+ pages_shift = this->phys_erase_shift - this->page_shift;
2805+ if (info->table_init) {
2806+ to = search_rel_block((page_addr >> pages_shift), mtd);
2807+ if (to) {
2808+ page_addr = (to << pages_shift) | (page_addr
2809+ & ((1 << pages_shift) - 1));
2810+ }
2811+ }
2812+
2813+ switch ( command ) {
2814+ case NAND_CMD_READOOB:
2815+ /*
2816+ * DFC has mark the last 8 bytes OOB data if HARDEARE_ECC is
2817+ * enabled. We must first disable the HARDWARE_ECC for getting
2818+ * all the 16 bytes OOB
2819+ */
2820+ enable_hw_ecc(context, 0);
2821+ info->buf_count = mtd->writesize + mtd->oobsize;
2822+ info->column = mtd->writesize + column;
2823+ info->cmd = command;
2824+ info->addr = page_addr << this->page_shift;
2825+ ret = dfc_send_command(mtd, flash_info->read1, info->addr,
2826+ 1, NDSR_RDDREQ | NDSR_DBERR);
2827+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2828+ dfc_get_pattern(info->context, flash_info->read1, &datasize,
2829+ &paddingsize);
2830+ dfc_read_fifo_partial(info->context, info->data_buf,
2831+ min(info->buf_count, datasize), datasize);
2832+ info->state = STATE_READY;
2833+#endif
2834+ /* We only are OOB, so if the data has error, does not matter */
2835+ if (info->retcode == ERR_DBERR)
2836+ info->retcode = ERR_NONE;
2837+ enable_hw_ecc(context, 1);
2838+ break;
2839+
2840+ case NAND_CMD_READ0:
2841+ enable_hw_ecc(context, 1);
2842+ info->column = column;
2843+ info->cmd = command;
2844+ info->buf_count = mtd->writesize + mtd->oobsize;
2845+ memset(info->data_buf, 0xFF, info->buf_count);
2846+ info->addr = page_addr << this->page_shift;
2847+
2848+ ret = dfc_send_command(mtd, flash_info->read1, info->addr,
2849+ 1, NDSR_RDDREQ | NDSR_DBERR);
2850+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2851+ dfc_get_pattern(info->context, flash_info->read1, &datasize,
2852+ &paddingsize);
2853+ dfc_read_fifo_partial(info->context, info->data_buf,
2854+ min(info->buf_count, datasize), datasize);
2855+ info->state = STATE_READY;
2856+#endif
2857+ /* When the data buf is blank, the DFC will report DB error */
2858+ if (info->retcode == ERR_DBERR && is_buf_blank(info->data_buf,
2859+ mtd->writesize))
2860+ info->retcode = ERR_NONE;
2861+
2862+ if (info->retcode == ERR_DBERR) {
2863+ printk(KERN_ERR "DB error at address 0x%x\n",
2864+ info->addr);
2865+ print_buf(info->data_buf, info->buf_count);
2866+ }
2867+ break;
2868+ case NAND_CMD_SEQIN:
2869+ /* Write only OOB? */
2870+
2871+ info->cmd = command;
2872+ if (column >= mtd->writesize) {
2873+ info->buf_count = mtd->writesize + mtd->oobsize;
2874+ enable_hw_ecc(context, 0);
2875+ } else {
2876+ info->buf_count = mtd->writesize + mtd->oobsize;
2877+ enable_hw_ecc(context, 1);
2878+ }
2879+ memset(info->data_buf, 0xFF, mtd->writesize + mtd->oobsize);
2880+ info->column = column;
2881+ info->addr = page_addr << this->page_shift;
2882+ break;
2883+ case NAND_CMD_PAGEPROG:
2884+ /* prevois command is NAND_CMD_SEIN ?*/
2885+ if (info->cmd != NAND_CMD_SEQIN) {
2886+ info->cmd = command;
2887+ info->retcode = ERR_SENDCMD;
2888+ printk(KERN_ERR "Monahans NAND device: "
2889+ "No NAND_CMD_SEQIN executed before.\n");
2890+ enable_hw_ecc(context, 1);
2891+ break;
2892+ }
2893+ info->cmd = command;
2894+ ret = dfc_send_command(mtd, flash_info->program, info->addr,
2895+ 1, NDSR_WRDREQ);
2896+
2897+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2898+ if (ret != 0)
2899+ break;
2900+
2901+ dfc_get_pattern(info->context, flash_info->program, &datasize,
2902+ &paddingsize);
2903+ dfc_write_fifo_partial(info->context, info->data_buf, datasize,
2904+ datasize);
2905+
2906+ if (info->context->dfc_mode->chip_select)
2907+ dfc_enable_int(info->context,
2908+ NDSR_CS1_BBD | NDSR_CS1_CMDD);
2909+ else
2910+ dfc_enable_int(info->context,
2911+ NDSR_CS0_BBD | NDSR_CS0_CMDD);
2912+
2913+ ret = wait_for_completion_timeout(&info->cmd_complete, 2*HZ);
2914+ if (!ret){
2915+ printk(KERN_ERR "Programm Command time out\n");
2916+ dump_info(info);
2917+ }
2918+
2919+ if (info->retcode == ERR_BBERR) {
2920+ mtd->block_markbad(mtd, info->addr);
2921+ }
2922+#endif
2923+ break;
2924+ case NAND_CMD_ERASE1:
2925+ info->cmd = command;
2926+ info->addr = (page_addr >> pages_shift) << this->phys_erase_shift;
2927+
2928+ if (info->context->dfc_mode->chip_select)
2929+ ret = dfc_send_command(mtd, flash_info->erase,
2930+ info->addr, 0, NDSR_CS1_BBD | NDSR_CS1_CMDD);
2931+ else
2932+ ret = dfc_send_command(mtd, flash_info->erase,
2933+ info->addr, 0, NDSR_CS0_BBD | NDSR_CS0_CMDD);
2934+
2935+ if (info->retcode == ERR_BBERR) {
2936+ mtd->block_markbad(mtd, info->addr);
2937+ }
2938+ break;
2939+ case NAND_CMD_ERASE2:
2940+ break;
2941+ case NAND_CMD_READID:
2942+ info->cmd = command;
2943+ info->buf_count = flash_info->read_id_bytes;
2944+ info->column = 0;
2945+ info->addr = 0xFFFFFFFF;
2946+ ret = dfc_send_command(mtd, flash_info->read_id, info->addr,
2947+ 0, NDSR_RDDREQ);
2948+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2949+ dfc_get_pattern(info->context, flash_info->read_id, &datasize,
2950+ &paddingsize);
2951+ dfc_read_fifo_partial(info->context, info->data_buf,
2952+ info->buf_count, datasize);
2953+ info->state = STATE_READY;
2954+#endif
2955+ D1(printk("ReadID, [1]:0x%x, [2]:0x%x\n",
2956+ info->data_buf[0], info->data_buf[1]));
2957+ break;
2958+ case NAND_CMD_STATUS:
2959+ info->cmd = command;
2960+ info->buf_count = 1;
2961+ info->column = 0;
2962+ info->addr = 0xFFFFFFFF;
2963+ ret = dfc_send_command(mtd, flash_info->read_status,
2964+ info->addr, 0, NDSR_RDDREQ);
2965+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2966+ dfc_get_pattern(info->context, flash_info->read_status,
2967+ &datasize, &paddingsize);
2968+ dfc_read_fifo_partial(info->context, info->data_buf,
2969+ info->buf_count, datasize);
2970+ info->state = STATE_READY;
2971+#endif
2972+ break;
2973+
2974+ case NAND_CMD_RESET:
2975+ status = dfc_reset_flash(&dfc_context);
2976+ if (status) {
2977+ printk(KERN_WARNING "Monahans NAND device:"
2978+ "NAND_CMD_RESET error\n");
2979+ }
2980+ break;
2981+ default:
2982+ printk(KERN_WARNING "Monahans NAND device:"
2983+ "Non-support the command.\n");
2984+ break;
2985+ }
2986+
2987+ if (info->retcode != ERR_NONE)
2988+ dfc_stop(info->context);
2989+}
2990+
2991+static void monahans_df_select_chip(struct mtd_info *mtd, int chip)
2992+{
2993+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2994+ (((struct nand_chip *)(mtd->priv))->priv);
2995+
2996+ if (chip <= MAX_CHIP)
2997+ info->context->dfc_mode->chip_select = chip;
2998+ else
2999+ printk(KERN_ERR "Monahans NAND device:"
3000+ "not select the NAND chips!\n");
3001+}
3002+
3003+static int monahans_df_waitfunc(struct mtd_info *mtd,
3004+ struct nand_chip *this)
3005+{
3006+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3007+ (((struct nand_chip *)(mtd->priv))->priv);
3008+
3009+ /* monahans_df_send_command has waited for command complete */
3010+ if (this->state == FL_WRITING || this->state == FL_ERASING) {
3011+ if (info->retcode == ERR_NONE)
3012+ return 0;
3013+ else {
3014+ /*
3015+ * any error make it return 0x01 which will tell
3016+ * the caller the erase and write fail
3017+ */
3018+ return 0x01;
3019+ }
3020+ }
3021+
3022+ return 0;
3023+}
3024+
3025+static int monahans_df_calculate_ecc(struct mtd_info *mtd,
3026+ const u_char *dat, u_char *ecc_code)
3027+{
3028+ return 0;
3029+}
3030+
3031+static int monahans_df_correct_data(struct mtd_info *mtd,
3032+ u_char *dat, u_char *read_ecc, u_char *calc_ecc)
3033+{
3034+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3035+ (((struct nand_chip *)(mtd->priv))->priv);
3036+
3037+ /*
3038+ * Any error include ERR_SEND_CMD, ERR_DBERR, ERR_BUSERR, we
3039+ * consider it as a ecc error which will tell the caller the
3040+ * read fail We have distinguish all the errors, but the
3041+ * nand_read_ecc only check this function return value
3042+ */
3043+ if (info->retcode != ERR_NONE)
3044+ return -1;
3045+
3046+ return 0;
3047+}
3048+
3049+static void monahans_df_enable_hwecc(struct mtd_info *mtd, int mode)
3050+{
3051+ return;
3052+}
3053+
3054+/*
3055+ * The relocation table management is different between MOBM V2 and V3.
3056+ *
3057+ * MOBM V2 is applied on chips taped out before MhnLV A0.
3058+ * MOBM V3 is applied on chips taped out after MhnLV A0. It's also applied
3059+ * on MhnLV A0.
3060+ */
3061+static int calc_obm_ver(void)
3062+{
3063+ unsigned int cpuid;
3064+ /* read CPU ID */
3065+ __asm__ (
3066+ "mrc p15, 0, %0, c0, c0, 0\n"
3067+ : "=r" (cpuid)
3068+ );
3069+ /* It's not xscale chip. */
3070+ if ((cpuid & 0xFFFF0000) != 0x69050000)
3071+ return MHN_OBM_INVAL;
3072+ /* It's MhnP Ax */
3073+ if ((cpuid & 0x0000FFF0) == 0x00006420)
3074+ return MHN_OBM_V2;
3075+ /* It's MhnP Bx */
3076+ if ((cpuid & 0x0000FFF0) == 0x00006820) {
3077+ if ((cpuid & 0x0F) <= 5)
3078+ return MHN_OBM_V2;
3079+ else
3080+ return MHN_OBM_V3;
3081+ }
3082+ /* It's MhnL Ax */
3083+ if ((cpuid & 0x0000FFF0) == 0x00006880) {
3084+ if ((cpuid & 0x0F) == 0)
3085+ return MHN_OBM_V2;
3086+ else
3087+ return MHN_OBM_V3;
3088+ }
3089+ /* It's MhnLV Ax */
3090+ if ((cpuid & 0x0000FFF0) == 0x00006890)
3091+ return MHN_OBM_V3;
3092+ return MHN_OBM_INVAL;
3093+}
3094+
3095+
3096+/*
3097+ * MOBM maintains a relocation table. It's used to replace bad blocks.
3098+ * If block A is bad, it will use block B instead.
3099+ * There're 127 relocated blocks. All of them reside in the bottom of NAND
3100+ * flash. So they're reserved and can't be calculated in mtd size and chip
3101+ * size.
3102+ */
3103+static int read_reloc_table(struct mtd_info *mtd)
3104+{
3105+ struct nand_chip *this = NULL;
3106+ struct monahans_dfc_info *info = NULL;
3107+ struct dfc_context *context = NULL;
3108+ struct reloc_table *table = NULL;
3109+ int page, maxslot;
3110+ int obm, valid;
3111+
3112+ obm = calc_obm_ver();
3113+ this = (struct nand_chip *)(mtd->priv);
3114+ info = (struct monahans_dfc_info *)(this->priv);
3115+ context = info->context;
3116+
3117+ mtd->size -= (NAND_RELOC_MAX * mtd->erasesize);
3118+ this->chipsize -= (NAND_RELOC_MAX << this->phys_erase_shift);
3119+ page = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
3120+
3121+ this->select_chip(mtd, 0);
3122+ valid = 0;
3123+ if (obm == MHN_OBM_V2) {
3124+ /* On MOBM V2, the relocation table resides in the last page
3125+ * of the first block.
3126+ */
3127+ memset(info->data_buf, 0, BUFLEN);
3128+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3129+ memcpy(((unsigned char *)&(info->table)), info->data_buf,
3130+ sizeof(struct reloc_table));
3131+ if (info->table.header == NAND_RELOC_HEADER)
3132+ valid = 1;
3133+ } else if (obm == MHN_OBM_V3) {
3134+ /* On MOBM V3, there're several relocation tables in the first
3135+ * block.
3136+ * When new bad blocks are found, a new relocation table will
3137+ * be generated and written back to the first block. But the
3138+ * original relocation table won't be erased. Even if the new
3139+ * relocation table is written wrong, system can still find an
3140+ * old one.
3141+ * One page contains one slot.
3142+ */
3143+ maxslot = 1 << (this->phys_erase_shift - this->page_shift);
3144+ page = maxslot - MAX_BBT_SLOTS;
3145+ for (; page < maxslot; page++) {
3146+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3147+ table = (struct reloc_table *)info->data_buf;
3148+ if (info->retcode == ERR_NONE) {
3149+ if (table->header != NAND_RELOC_HEADER) {
3150+ continue;
3151+ } else {
3152+ memcpy(((unsigned char *)&(info->table)),
3153+ table, sizeof(struct reloc_table));
3154+ valid = 1;
3155+ break;
3156+ }
3157+ }
3158+ }
3159+
3160+ } else {
3161+ printk(KERN_ERR "The version of MOBM isn't supported\n");
3162+ }
3163+ if (valid) {
3164+ memcpy(((unsigned char *)&(info->table)), info->data_buf,
3165+ sizeof(struct reloc_table));
3166+ printk(KERN_DEBUG "relocation table at page:%d\n", page);
3167+ PRINT_BUF((unsigned char *)&(info->table),
3168+ sizeof(struct reloc_table));
3169+ info->table_init = 1;
3170+ } else {
3171+ /* There should be a valid relocation table slot at least. */
3172+ printk(KERN_ERR "NO VALID relocation table can be \
3173+ recognized\n");
3174+ printk(KERN_ERR "CAUTION: It may cause unpredicated error\n");
3175+ printk(KERN_ERR "Please re-initialize the NAND flash.\n");
3176+ memset((unsigned char *)&(info->table), 0,
3177+ sizeof(struct reloc_table));
3178+ info->table_init = 0;
3179+ return -EINVAL;
3180+ }
3181+ return 0;
3182+}
3183+
3184+/* add the relocation entry into the relocation table
3185+ * It's valid on MOBM V3.
3186+ * If the relocated block is bad, an new entry will be added into the
3187+ * bottom of the relocation table.
3188+ */
3189+static int update_rel_table(struct mtd_info *mtd, int block)
3190+{
3191+ struct nand_chip *this = NULL;
3192+ struct monahans_dfc_info *info = NULL;
3193+ struct reloc_table *table = NULL;
3194+ int obm, reloc_block;
3195+
3196+ this = (struct nand_chip *)(mtd->priv);
3197+ info = (struct monahans_dfc_info *)(this->priv);
3198+ obm = calc_obm_ver();
3199+ if (obm == MHN_OBM_V3) {
3200+ table = &info->table;
3201+ if (info->table_init == 0) {
3202+ printk(KERN_ERR "Error: the initial relocation \
3203+ table can't be read\n");
3204+ memset(table, 0, sizeof(struct reloc_table));
3205+ table->header = NAND_RELOC_HEADER;
3206+ info->table_init = 1;
3207+ }
3208+ if (table->total == 0) {
3209+ /* Point to the first relocated block.
3210+ * It resides in the last block of flash.
3211+ * the relocation entry has calculated in
3212+ * chipsize
3213+ */
3214+ reloc_block = (this->chipsize
3215+ >> this->phys_erase_shift)
3216+ + NAND_RELOC_MAX - 1;
3217+ } else if (table->total < NAND_RELOC_MAX) {
3218+ reloc_block = table->reloc[table->total - 1].to - 1;
3219+ } else {
3220+ printk(KERN_ERR "Relocation table exceed max number, \
3221+ cannot mark block 0x%x as bad block\n", block);
3222+ return -ENOSPC;
3223+ }
3224+ /* Make sure that reloc_block is pointing to a valid block */
3225+ for (; ; reloc_block--) {
3226+ /* The relocate table is full */
3227+ if (reloc_block < (this->chipsize
3228+ >> this->phys_erase_shift))
3229+ return -ENOSPC;
3230+ this->cmdfunc(mtd, NAND_CMD_ERASE1, 0, reloc_block
3231+ << (this->phys_erase_shift
3232+ - this->page_shift));
3233+ if (info->retcode == ERR_NONE)
3234+ break;
3235+ }
3236+ /* Create the relocated block information in the table */
3237+ table->reloc[table->total].from = block;
3238+ table->reloc[table->total].to = reloc_block;
3239+ table->total++;
3240+ }
3241+ return 0;
3242+}
3243+
3244+/* Write the relocation table back to device, if there's room. */
3245+static int sync_rel_table(struct mtd_info *mtd, int *idx)
3246+{
3247+ struct nand_chip *this = NULL;
3248+ struct monahans_dfc_info *info = NULL;
3249+ int obm, start_page, len;
3250+
3251+ if (*idx >= MAX_BBT_SLOTS) {
3252+ printk(KERN_ERR "Can't write relocation table to device \
3253+ any more.\n");
3254+ return -1;
3255+ }
3256+ if (*idx < 0) {
3257+ printk(KERN_ERR "Wrong Slot is specified.\n");
3258+ return -1;
3259+ }
3260+ this = (struct nand_chip *)(mtd->priv);
3261+ info = (struct monahans_dfc_info *)(this->priv);
3262+ len = 4;
3263+ len += info->table.total << 2;
3264+ obm = calc_obm_ver();
3265+ if (obm == MHN_OBM_V3) {
3266+ /* write to device */
3267+ start_page = 1 << (this->phys_erase_shift - this->page_shift);
3268+ start_page = start_page - 1 - *idx;
3269+ memset(&(info->data_buf), 0xFF, BUFLEN);
3270+ memcpy(&(info->data_buf), &(info->table), len);
3271+
3272+ printk(KERN_DEBUG "DUMP relocation table before write. \
3273+ page:0x%x\n", start_page);
3274+ monahans_df_command(mtd, NAND_CMD_SEQIN, 0, start_page);
3275+ monahans_df_command(mtd, NAND_CMD_PAGEPROG, 0, start_page);
3276+ /* write to idx */
3277+ (*idx)++;
3278+ /* dump it */
3279+ memset(&(info->data_buf), 0, BUFLEN);
3280+ monahans_df_command(mtd, NAND_CMD_READOOB, 0, start_page);
3281+ PRINT_BUF(info->data_buf, len);
3282+ }
3283+ return 0;
3284+}
3285+
3286+
3287+/* Find the relocated block of the bad one.
3288+ * If it's a good block, return 0. Otherwise, return a relocated one.
3289+ * idx points to the next relocation entry
3290+ * If the relocated block is bad, an new entry will be added into the
3291+ * bottom of the relocation table.
3292+ */
3293+static unsigned short search_rel_block(int block, struct mtd_info *mtd)
3294+{
3295+ struct nand_chip *this = NULL;
3296+ struct monahans_dfc_info *info = NULL;
3297+ struct reloc_table *table = NULL;
3298+ int i, max, reloc_block = 0;
3299+
3300+ this = (struct nand_chip *)(mtd->priv);
3301+ info = (struct monahans_dfc_info *)(this->priv);
3302+ table = &(info->table);
3303+ if ((block <= 0) || (block > this->chipsize)
3304+ || (info->table_init == 0) || (table->total == 0))
3305+ return 0;
3306+ if (table->total > NAND_RELOC_MAX)
3307+ table->total = NAND_RELOC_MAX;
3308+ max = table->total;
3309+ for (i = 0; i < max; i++) {
3310+ if (block == table->reloc[i].from)
3311+ reloc_block = table->reloc[i].to;
3312+ }
3313+ return reloc_block;
3314+}
3315+
3316+/*
3317+ * Check whether the block is a bad one.
3318+ * At first, it will search the relocation table.
3319+ * If necessary, it will search the BBT. Because relocation table can only
3320+ * maintain limited record. If there're more bad blocks, they can't be
3321+ * recorded in relocation table. They can only be recorded in BBT.
3322+ */
3323+static int monahans_df_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
3324+{
3325+ struct nand_chip *this = NULL;
3326+ int page, block, reloc_block, chipnr, res = 0;
3327+ u16 bad;
3328+
3329+ /* At here, we only support one flash chip */
3330+ this = (struct nand_chip *)mtd->priv;
3331+ block = (int)(ofs >> this->phys_erase_shift);
3332+ /* search the block in the relocation table */
3333+ reloc_block = search_rel_block(block, mtd);
3334+ if (reloc_block) {
3335+ ofs = ((reloc_block << this->phys_erase_shift) |
3336+ (ofs & ((1 << this->phys_erase_shift) - 1)));
3337+ }
3338+
3339+ /* search BBT
3340+ * Maybe the relocation table is full, but some bad blocks aren't
3341+ * recordered in it.
3342+ * The below code are copied from nand_block_bad().
3343+ */
3344+ if (getchip) {
3345+ page = (int)(ofs >> this->page_shift);
3346+ chipnr = (int)(ofs >> this->chip_shift);
3347+
3348+ /* Select the NAND chips */
3349+ this->select_chip(mtd, chipnr);
3350+ } else
3351+ page = (int)ofs;
3352+
3353+ if (this->options & NAND_BUSWIDTH_16) {
3354+ this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE,
3355+ page & this->pagemask);
3356+ bad = cpu_to_le16(this->read_word(mtd));
3357+ if (this->badblockpos & 0x1)
3358+ bad >>= 1;
3359+ if ((bad & 0xFF) != 0xFF)
3360+ res = 1;
3361+ } else {
3362+ this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos,
3363+ page & this->pagemask);
3364+ if (this->read_byte(mtd) != 0xFF)
3365+ res = 1;
3366+ }
3367+
3368+ return res;
3369+}
3370+
3371+static int monahans_df_block_markbad(struct mtd_info *mtd, loff_t ofs)
3372+{
3373+ struct nand_chip *this = NULL;
3374+ struct monahans_dfc_info *info = NULL;
3375+ unsigned char buf[2] = {0, 0};
3376+ int block, reloc_block, page, ret;
3377+
3378+ this = (struct nand_chip *)mtd->priv;
3379+ info = (struct monahans_dfc_info *)(this->priv);
3380+ /* Get block number */
3381+ block = ((int)ofs) >> this->bbt_erase_shift;
3382+ ret = update_rel_table(mtd, block);
3383+ if (!ret) {
3384+ sync_rel_table(mtd, &(info->current_slot));
3385+ return 0;
3386+ } else {
3387+ reloc_block = search_rel_block(block, mtd);
3388+ if (reloc_block)
3389+ block = reloc_block;
3390+ if (this->bbt)
3391+ this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
3392+ }
3393+
3394+ /* Do we have a flash based bad block table ? */
3395+ if (this->options & NAND_USE_FLASH_BBT)
3396+ return nand_update_bbt(mtd, ofs);
3397+
3398+ /* mark the bad block flag at the first two pages */
3399+ page = block << (this->phys_erase_shift - this->page_shift);
3400+ ofs = mtd->writesize + this->badblockpos;
3401+ this->cmdfunc(mtd, NAND_CMD_SEQIN, ofs, page);
3402+ this->write_buf(mtd, buf, 2);
3403+ this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
3404+ page++;
3405+ this->cmdfunc(mtd, NAND_CMD_SEQIN, ofs, page);
3406+ this->write_buf(mtd, buf, 2);
3407+ this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
3408+ return 0;
3409+}
3410+
3411+static int dump_bbt_flash(struct mtd_info *mtd)
3412+{
3413+ struct nand_chip *this = NULL;
3414+ struct monahans_dfc_info *info = NULL;
3415+ int block, page, totlen;
3416+
3417+ this = (struct nand_chip *)mtd->priv;
3418+ info = (struct monahans_dfc_info *)this->priv;
3419+ block = (this->chipsize >> this->phys_erase_shift) - 1;
3420+ totlen = (this->chipsize >> this->phys_erase_shift) >> 2;
3421+ printk(KERN_ERR "totlen:0x%x\n", totlen);
3422+ this->select_chip(mtd, 0);
3423+ if (this->bbt_td) {
3424+ printk(KERN_ERR "BBT page:0x%x\n", this->bbt_td->pages[0]);
3425+ page = this->bbt_td->pages[0];
3426+ if (this->bbt_td->pages[0] <= 0) {
3427+ page = block << (this->phys_erase_shift
3428+ - this->page_shift);
3429+ }
3430+ while (totlen > 0) {
3431+ printk(KERN_ERR "page:0x%x\n", page);
3432+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3433+ printk(KERN_ERR "read result:0x%x\n", info->retcode);
3434+ PRINT_BUF(info->data_buf, BUFLEN);
3435+ totlen -= (1 << this->page_shift);
3436+ page++;
3437+ }
3438+ }
3439+ if (this->bbt_md) {
3440+ printk(KERN_ERR "BBT page:0x%x\n", this->bbt_md->pages[0]);
3441+ page = this->bbt_md->pages[0];
3442+ if (this->bbt_td->pages[0] <= 0) {
3443+ page = block << (this->phys_erase_shift
3444+ - this->page_shift);
3445+ }
3446+ while (totlen > 0) {
3447+ printk(KERN_ERR "page:0x%x\n", page);
3448+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3449+ printk(KERN_ERR "read result:0x%x\n", info->retcode);
3450+ PRINT_BUF(info->data_buf, BUFLEN);
3451+ totlen -= (1 << this->page_shift);
3452+ page++;
3453+ }
3454+
3455+ }
3456+ return 0;
3457+}
3458+
3459+static int dump_bbt_mem(struct mtd_info *mtd)
3460+{
3461+ struct nand_chip *this = NULL;
3462+
3463+ this = (struct nand_chip *)mtd->priv;
3464+ PRINT_BUF(this->bbt, 225);
3465+ return 0;
3466+}
3467+
3468+static int monahans_df_scan_bbt(struct mtd_info *mtd)
3469+{
3470+ struct nand_chip *this = NULL;
3471+ int ret;
3472+
3473+ this = (struct nand_chip *)mtd->priv;
3474+ ret = read_reloc_table(mtd);
3475+ if (ret) {
3476+ printk(KERN_ERR "Failed to get relocation table\n");
3477+ printk(KERN_ERR "Try to build a new BBT. It may result \
3478+ unpredicated error.\n");
3479+ /* Create new memory based and flash based BBT */
3480+ }
3481+ nand_scan_bbt(mtd, &monahans_bbt_default);
3482+ //dump_bbt_flash(mtd);
3483+ dump_bbt_mem(mtd);
3484+ return 0;
3485+#if 0
3486+ /* Read flashed based BBT from device */
3487+ return (nand_scan_bbt(mtd, &monahans_bbt_main));
3488+#endif
3489+}
3490+
3491+
3492+static int monahans_df_probe(struct platform_device *pdev)
3493+{
3494+ struct nand_chip *this;
3495+ struct monahans_dfc_info *info;
3496+ int status = -1;
3497+ unsigned int data_buf_len;
3498+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3499+ unsigned int buf_len;
3500+#endif
3501+ int i, ret = 0;
3502+
3503+ printk(KERN_ERR "Nand driver probe\n");
3504+
3505+ dfc_context.membase = ioremap_nocache(0x43100000, 0x100000);
3506+ if (!dfc_context.membase)
3507+ printk(KERN_ERR "Couldn't ioremap\n");
3508+
3509+ pxa_set_cken(CKEN_NAND, 1);
3510+
3511+ for (i = DFC_FLASH_NULL + 1; i < DFC_FLASH_END; i++)
3512+ {
3513+ uint32_t id;
3514+
3515+ status = dfc_init(&dfc_context, i);
3516+ if (status)
3517+ continue;
3518+ status = dfc_readid(&dfc_context, &id);
3519+ if (status)
3520+ continue;
3521+ printk(KERN_DEBUG "id:0x%x, chipid:0x%x\n",
3522+ id, dfc_context.flash_info->chip_id);
3523+ if (id == dfc_context.flash_info->chip_id)
3524+ break;
3525+ }
3526+
3527+ if(i == DFC_FLASH_END) {
3528+ printk(KERN_ALERT "Monahans NAND device:"
3529+ "Nand Flash initialize failure!\n");
3530+ ret = -ENXIO;
3531+ goto out;
3532+ }
3533+ flash_config = i;
3534+
3535+ monahans_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) +
3536+ sizeof(struct monahans_dfc_info) , GFP_KERNEL);
3537+ if (!monahans_mtd) {
3538+ printk (KERN_ERR "Monahans NAND device:"
3539+ "Unable to allocate NAND MTD device structure.\n");
3540+ ret = -ENOMEM;
3541+ goto out;
3542+ }
3543+
3544+ /* Get pointer to private data */
3545+ this = (struct nand_chip *)((void *)monahans_mtd + sizeof(struct mtd_info));
3546+ info = (struct monahans_dfc_info *)((void *)this + sizeof(struct nand_chip));
3547+ dfc_context.mtd = monahans_mtd;
3548+
3549+ monahans_mtd->priv = this;
3550+ this->priv = info;
3551+ data_buf_len = dfc_context.flash_info->page_size +
3552+ dfc_context.flash_info->oob_size;
3553+ info->state = STATE_READY;
3554+ init_completion(&info->cmd_complete);
3555+ info->table_init = 0;
3556+ memset(&info->table, 0x0, sizeof(struct reloc_table));
3557+ printk(KERN_DEBUG "%s: this->controller: 0x%x, &this->controller: 0x%x\n",__func__, (unsigned int)this->controller, (unsigned int)&(this->controller));
3558+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3559+ info->dma_mask = 0xffffffffUL;
3560+
3561+ dev->dma_mask = &info->dma_mask;
3562+ dev->coherent_dma_mask = 0xffffffffUL;
3563+
3564+ /* alloc dma data buffer for data
3565+ * buffer + 2*descriptor + command buffer
3566+ */
3567+ buf_len = ALIGN(2*sizeof(struct pxa_dma_desc), 32) +
3568+ ALIGN(data_buf_len, 32) + ALIGN(NAND_CMD_DMA_LEN, 32);
3569+
3570+ printk(KERN_INFO "Try to allocate dma buffer(len:%d)"
3571+ "for data buffer + 2*descriptor + command buffer\n", buf_len);
3572+ info->data_desc = (struct pxa_dma_desc*)dma_alloc_writecombine(dev,
3573+ buf_len, &info->data_desc_addr, GFP_KERNEL);
3574+ if (!info->data_desc) {
3575+ printk(KERN_ERR "Monahans NAND device:"
3576+ "Unable to alloc dma buffer\n");
3577+ ret = -ENOMEM;
3578+ goto free_mtd;
3579+ }
3580+
3581+ info->cmd_desc = (struct pxa_dma_desc*)((char *)info->data_desc +
3582+ sizeof(struct pxa_dma_desc));
3583+ info->cmd_desc_addr = (dma_addr_t)((char *)info->data_desc_addr +
3584+ sizeof(struct pxa_dma_desc));
3585+ info->data_buf = (char *)info->data_desc +
3586+ ALIGN(2*sizeof(struct pxa_dma_desc), 32);
3587+ info->data_buf_addr = (dma_addr_t)((char *)info->data_desc_addr +
3588+ ALIGN(2*sizeof(struct pxa_dma_desc), 32));
3589+ info->cmd_buf = (char *)info->data_buf + ALIGN(data_buf_len, 32);
3590+ info->cmd_buf_addr = (dma_addr_t)((char *)info->data_buf_addr +
3591+ ALIGN(data_buf_len, 32));
3592+
3593+ D1(printk("Get dma buffer for data dma descriptor, virt:0x%x, phys0x:%x\n",
3594+ (unsigned int)info->data_desc, info->data_desc_addr));
3595+ D1(printk("Get dma buffer for command dma descriptors, virt:0x%x,"
3596+ "phys0x:%x\n", (unsigned int)info->cmd_desc, info->cmd_desc_addr));
3597+ D1(printk("Get dma buffer for data, virt:0x%x, phys0x:%x\n",
3598+ (unsigned int)info->data_buf, info->data_buf_addr));
3599+ D1(printk("Get dma buffer for command, virt:0x%x, phys0x:%x\n",
3600+ (unsigned int)info->cmd_buf, info->cmd_buf_addr));
3601+
3602+ D1(printk("Try to allocate dma channel for data\n"));
3603+
3604+ info->data_dma = pxa_request_dma("NAND DATA", DMA_PRIO_LOW,
3605+ monahans_dfc_data_dma_irq, info);
3606+ if (info->data_dma < 0) {
3607+ printk(KERN_ERR "Monahans NAND device:"
3608+ "Unable to alloc dma channel for data\n");
3609+ ret = info->data_dma;
3610+ goto free_buf;
3611+ }
3612+ D1(printk("Get dma channel:%d for data\n", info->data_dma));
3613+
3614+ D1(printk("Try to allocate dma channel for command\n"));
3615+ info->cmd_dma = pxa_request_dma("NAND CMD", DMA_PRIO_LOW,
3616+ monahans_dfc_cmd_dma_irq, info);
3617+ if (info->cmd_dma < 0) {
3618+ printk(KERN_ERR "Monahans NAND device:"
3619+ "Unable to alloc dma channel for command\n");
3620+ ret = info->cmd_dma;
3621+ goto free_data_dma;
3622+ }
3623+ D1(printk("Get dma channel:%d for command\n", info->cmd_dma));
3624+
3625+ dfc_context.cmd_dma_ch = info->cmd_dma;
3626+ dfc_context.data_dma_ch = info->data_dma;
3627+#else
3628+ printk(KERN_DEBUG "Try to allocate data buffer(len:%d)\n", data_buf_len);
3629+ info->data_buf = kmalloc(data_buf_len, GFP_KERNEL);
3630+ if (!info->data_buf) {
3631+ printk(KERN_ERR "Monahans NAND device:"
3632+ "Unable to alloc data buffer\n");
3633+ ret = -ENOMEM;
3634+ goto free_mtd;
3635+ }
3636+#endif
3637+
3638+ D1(printk("Try to request irq:%d\n", IRQ_NAND));
3639+ ret = request_irq(IRQ_NAND, monahans_dfc_irq, 0, pdev->name, info);
3640+ if (ret < 0) {
3641+ printk(KERN_ERR "Monahans NAND device: Unable to request irq\n");
3642+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3643+ goto free_cmd_dma;
3644+#else
3645+ goto free_buf;
3646+#endif
3647+ }
3648+
3649+ D1(printk("Success request irq\n"));
3650+
3651+ /* set address of NAND IO lines */
3652+ this->options = (dfc_context.flash_info->flash_width == 16)? \
3653+ NAND_BUSWIDTH_16: 0 | NAND_USE_FLASH_BBT;
3654+
3655+ /* this->IO_ADDR_R = this->IO_ADDR_W = NDDB */
3656+ this->waitfunc = monahans_df_waitfunc;
3657+ this->select_chip = monahans_df_select_chip;
3658+ this->dev_ready = monahans_df_dev_ready;
3659+ this->cmdfunc = monahans_df_command;
3660+ this->read_word= monahans_df_read_word;
3661+ /*this->write_word= monahans_df_write_word;*/
3662+ this->read_byte = monahans_df_read_byte;
3663+ this->read_buf = monahans_df_read_buf;
3664+ this->write_buf = monahans_df_write_buf;
3665+ this->verify_buf = monahans_df_verify_buf;
3666+ this->ecc.hwctl = monahans_df_enable_hwecc;
3667+ this->ecc.calculate = monahans_df_calculate_ecc;
3668+ this->ecc.correct = monahans_df_correct_data;
3669+ this->block_bad = monahans_df_block_bad;
3670+ this->block_markbad = monahans_df_block_markbad;
3671+ this->scan_bbt = monahans_df_scan_bbt;
3672+ this->chip_delay= 25;
3673+ this->bbt_td = &monahans_bbt_main;
3674+ this->bbt_md = &monahans_bbt_mirror;
3675+
3676+ /* If the NAND flash is small block flash, only 512-byte pagesize
3677+ * is supported.
3678+ * Adjust parameters of BBT what is depended on large block nand
3679+ * flash or small block nand flash.
3680+ */
3681+ if (dfc_context.flash_info->oob_size > 16) {
3682+ this->ecc.layout = &monahans_lb_nand_oob;
3683+ this->ecc.mode = NAND_ECC_HW;
3684+ this->ecc.size = 2048;
3685+ this->ecc.bytes = 24;
3686+ this->bbt_td->offs = 2;
3687+ this->bbt_td->veroffs = 6;
3688+ this->bbt_md->offs = 2;
3689+ this->bbt_md->veroffs = 6;
3690+ this->badblockpos = NAND_LARGE_BADBLOCK_POS;
3691+ monahans_bbt_default.offs = NAND_LARGE_BADBLOCK_POS;
3692+ monahans_bbt_default.len = 2;
3693+ /* when scan_bbt() is executed, bbt version can get */
3694+ monahans_bbt_default.veroffs = 2;
3695+ } else {
3696+ this->ecc.layout = &monahans_sb_nand_oob;
3697+ this->ecc.mode = NAND_ECC_HW;
3698+ this->ecc.size = 512;
3699+ this->ecc.bytes = 6;
3700+ this->bbt_td->offs = 8;
3701+ this->bbt_td->veroffs = 12;
3702+ this->bbt_md->offs = 8;
3703+ this->bbt_md->veroffs = 12;
3704+ this->badblockpos = NAND_SMALL_BADBLOCK_POS;
3705+ monahans_bbt_default.offs = NAND_SMALL_BADBLOCK_POS;
3706+ monahans_bbt_default.len = 1;
3707+ monahans_bbt_default.veroffs = 8;
3708+ }
3709+
3710+ info->context = &dfc_context;
3711+ /* TODO: allocate dma buffer and channel */
3712+
3713+ platform_set_drvdata(pdev, monahans_mtd);
3714+
3715+ if (nand_scan(monahans_mtd, 1)) {
3716+ printk(KERN_ERR "Nand scan failed\n");
3717+ ret = -ENXIO;
3718+ goto free_irq;
3719+ }
3720+
3721+ /* There is a potential limitation that no more partition can be
3722+ * added between MassStorage and BBT(last block).
3723+ *
3724+ * The last 127 blocks is reserved for relocation table, they aren't
3725+ * statistical data of mtd size and chip size.
3726+ *
3727+ * BBT partitions contains 4 blocks. Two blocks are used to store
3728+ * main descriptor, the other two are used to store mirror descriptor.
3729+ */
3730+ partition_info[PART_NUM - 1].size = (monahans_bbt_main.maxblocks
3731+ + monahans_bbt_mirror.maxblocks)
3732+ << this->phys_erase_shift;
3733+ partition_info[PART_NUM - 1].offset = this->chipsize
3734+ - partition_info[PART_NUM - 1].size;
3735+ partition_info[PART_NUM - 2].offset = partition_info[PART_NUM - 3].offset
3736+ + partition_info[PART_NUM - 3].size;
3737+ partition_info[PART_NUM - 2].size = this->chipsize
3738+ - partition_info[PART_NUM - 2].offset
3739+ - partition_info[PART_NUM - 1].size;
3740+ add_mtd_partitions(monahans_mtd, partition_info, PART_NUM);
3741+
3742+#ifdef CONFIG_DVFM
3743+ dvfm_notifier.client_data = info;
3744+ mhn_fv_register_notifier(&dvfm_notifier);
3745+#endif
3746+
3747+ return 0;
3748+
3749+free_irq:
3750+ free_irq(IRQ_NAND, info);
3751+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3752+free_cmd_dma:
3753+ pxa_free_dma(info->cmd_dma);
3754+free_data_dma:
3755+ pxa_free_dma(info->data_dma);
3756+free_buf:
3757+ dma_free_writecombine(dev, buf_len, info->data_desc, info->data_desc_addr);
3758+#else
3759+free_buf:
3760+ kfree(info->data_buf);
3761+#endif
3762+free_mtd:
3763+ kfree(monahans_mtd);
3764+out:
3765+ return ret;
3766+
3767+}
3768+
3769+static int __devexit monahans_df_remove(struct platform_device *dev)
3770+{
3771+ struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(dev);
3772+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3773+ (((struct nand_chip *)(mtd->priv))->priv);
3774+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3775+ unsigned int data_buf_len = dfc_context.flash_info->page_size +
3776+ dfc_context.flash_info->oob_size;
3777+ unsigned int buf_len = ALIGN(2*sizeof(struct pxa_dma_desc), 32) +
3778+ ALIGN(data_buf_len, 32) + ALIGN(NAND_CMD_DMA_LEN, 32);
3779+#endif
3780+
3781+#ifdef CONFIG_DVFM
3782+ mhn_fv_unregister_notifier(&dvfm_notifier);
3783+#endif
3784+
3785+ platform_set_drvdata(dev, NULL);
3786+
3787+ del_mtd_device(mtd);
3788+ del_mtd_partitions(mtd);
3789+ free_irq(IRQ_NAND, info);
3790+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3791+ pxa_free_dma(info->cmd_dma);
3792+ pxa_free_dma(info->data_dma);
3793+ dma_free_writecombine(dev, buf_len, info->data_desc,
3794+ info->data_desc_addr);
3795+#else
3796+ kfree(info->data_buf);
3797+#endif
3798+ kfree(mtd);
3799+
3800+ return 0;
3801+}
3802+
3803+#ifdef CONFIG_PM
3804+static int monahans_df_suspend(struct platform_device *dev, pm_message_t state, u32 level)
3805+{
3806+ struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(dev);
3807+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3808+ (((struct nand_chip *)(mtd->priv))->priv);
3809+
3810+ if( SUSPEND_DISABLE == level){ /*SUSPEND_NOTIFY*/
3811+ if (info->state != STATE_READY) {
3812+ printk(KERN_ERR "current state is %d\n", info->state);
3813+ return -EAGAIN;
3814+ }
3815+ info->state = STATE_SUSPENDED;
3816+ /*
3817+ * The PM code need read the mobm from NAND.
3818+ * So the NAND clock can't be stop here.
3819+ * The PM code will cover this.
3820+ */
3821+ /* pxa_set_cken(CKEN_NAND, 0); */
3822+ }
3823+ return 0;
3824+}
3825+
3826+static int monahans_df_resume(struct platform_device *dev, u32 level)
3827+{
3828+ struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(dev);
3829+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3830+ (((struct nand_chip *)(mtd->priv))->priv);
3831+ int status;
3832+
3833+ if(RESUME_ENABLE == level){
3834+ if (info->state != STATE_SUSPENDED)
3835+ printk(KERN_WARNING "Error State after resume back\n");
3836+
3837+ info->state = STATE_READY;
3838+
3839+ pxa_set_cken(CKEN_NAND, 1);
3840+
3841+ status = dfc_init(&dfc_context, flash_config);
3842+ if (status) {
3843+ printk(KERN_ALERT "Monahans NAND device:"
3844+ "Nand Flash initialize failure!\n");
3845+ return -ENXIO;
3846+ }
3847+ }
3848+ return 0;
3849+}
3850+#endif
3851+
3852+#ifdef CONFIG_DVFM
3853+static int mhn_nand_dvfm_notifier(unsigned cmd, void *client_data, void *info)
3854+{
3855+ struct monahans_dfc_info *dfc_info =
3856+ (struct monahans_dfc_info *)client_data;
3857+
3858+ switch (cmd) {
3859+ case FV_NOTIFIER_QUERY_SET :
3860+ if (dfc_info->state != STATE_READY)
3861+ return -1;
3862+ break;
3863+
3864+ case FV_NOTIFIER_PRE_SET :
3865+ break;
3866+
3867+ case FV_NOTIFIER_POST_SET :
3868+ break;
3869+ }
3870+
3871+ return 0;
3872+}
3873+#endif
3874+
3875+static struct platform_driver monahans_df_driver = {
3876+ .probe = monahans_df_probe,
3877+ .remove = __devexit_p(monahans_df_remove),
3878+#ifdef CONFIG_PM
3879+ .suspend = monahans_df_suspend,
3880+ .resume = monahans_df_resume,
3881+#endif
3882+ .driver = {
3883+ .name = "monahans-nand-flash",
3884+ }
3885+};
3886+
3887+static void __exit monahans_df_cleanup(void)
3888+{
3889+ printk(KERN_ERR "Nand driver registered\n");
3890+ platform_driver_unregister(&monahans_df_driver);
3891+}
3892+
3893+static int __init monahans_df_init(void)
3894+{
3895+ return platform_driver_register(&monahans_df_driver);
3896+}
3897+
3898+module_init(monahans_df_init);
3899+module_exit(monahans_df_cleanup);
3900+
3901+MODULE_LICENSE("GPL");
3902+MODULE_AUTHOR("Jingqing.xu (jingqing.xu@intel.com)");
3903+MODULE_DESCRIPTION("Glue logic layer for NAND flash on monahans DFC");
3904+
3905+
3906Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c
3907===================================================================
3908--- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite.c 2008-02-13 00:59:45.000000000 +0000
3909+++ linux-2.6.23/arch/arm/mach-pxa/zylonite.c 2008-02-13 09:11:02.000000000 +0000
3910@@ -29,6 +29,8 @@
3911 #include "generic.h"
3912
3913 int gpio_backlight;
3914+int gpio_vsync;
3915+int gpio_vsync1;
3916 int gpio_eth_irq;
3917
3918 int lcd_id;
3919@@ -54,6 +56,16 @@
3920 .resource = smc91x_resources,
3921 };
3922
3923+static struct platform_device nand_device = {
3924+ .name = "monahans-nand-flash",
3925+ .id = -1,
3926+};
3927+
3928+static struct platform_device touch_device = {
3929+ .name = "pxa2xx-touch",
3930+ .id = -1,
3931+};
3932+
3933 #if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
3934 static void zylonite_backlight_power(int on)
3935 {
3936@@ -96,7 +108,7 @@
3937 };
3938
3939 static struct pxafb_mode_info sharp_ls037_modes[] = {
3940- [0] = {
3941+ [1] = {
3942 .pixclock = 158000,
3943 .xres = 240,
3944 .yres = 320,
3945@@ -109,8 +121,8 @@
3946 .lower_margin = 3,
3947 .sync = 0,
3948 },
3949- [1] = {
3950- .pixclock = 39700,
3951+ [0] = {
3952+ .pixclock = 45000,
3953 .xres = 480,
3954 .yres = 640,
3955 .bpp = 16,
3956@@ -137,6 +149,11 @@
3957 /* backlight GPIO: output, default on */
3958 gpio_direction_output(gpio_backlight, 1);
3959
3960+ gpio_direction_output(gpio_vsync, 0);
3961+ gpio_direction_output(gpio_vsync1, 0);
3962+
3963+ printk(KERN_ERR "LCD ID is %x\n", lcd_id);
3964+
3965 if (lcd_id & 0x20) {
3966 set_pxa_fb_info(&zylonite_sharp_lcd_info);
3967 return;
3968@@ -169,6 +186,8 @@
3969 smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
3970 smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
3971 platform_device_register(&smc91x_device);
3972+ platform_device_register(&nand_device);
3973+ platform_device_register(&touch_device);
3974
3975 zylonite_init_lcd();
3976 }
3977Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c
3978===================================================================
3979--- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-13 00:59:45.000000000 +0000
3980+++ linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-13 14:01:13.000000000 +0000
3981@@ -62,12 +62,12 @@
3982 GPIO110_UART3_RXD,
3983
3984 /* AC97 */
3985- GPIO23_AC97_nACRESET,
3986+ /*GPIO23_AC97_nACRESET,
3987 GPIO24_AC97_SYSCLK,
3988 GPIO29_AC97_BITCLK,
3989 GPIO25_AC97_SDATA_IN_0,
3990 GPIO27_AC97_SDATA_OUT,
3991- GPIO28_AC97_SYNC,
3992+ GPIO28_AC97_SYNC,*/
3993
3994 /* Keypad */
3995 GPIO107_KP_DKIN_0,
3996@@ -104,6 +104,41 @@
3997 /* Ethernet */
3998 GPIO2_nCS3,
3999 GPIO99_GPIO,
4000+
4001+ /* NAND */
4002+ MFP_CFG_X(DF_INT_RnB, AF0, DS10X, PULL_LOW),
4003+ MFP_CFG_X(DF_nRE_nOE, AF1, DS10X, PULL_LOW),
4004+ MFP_CFG_X(DF_nWE, AF1, DS10X, PULL_LOW),
4005+ MFP_CFG_X(DF_CLE_nOE, AF0, DS10X, PULL_LOW),
4006+ MFP_CFG_X(DF_nADV1_ALE, AF1, DS10X, PULL_LOW),
4007+ MFP_CFG_X(DF_nCS0, AF1, DS10X, PULL_LOW),
4008+ MFP_CFG_X(DF_nCS1, AF0, DS10X, PULL_LOW),
4009+ MFP_CFG_X(DF_IO0, AF1, DS08X, PULL_LOW),
4010+ MFP_CFG_X(DF_IO1, AF1, DS08X, PULL_LOW),
4011+ MFP_CFG_X(DF_IO2, AF1, DS08X, PULL_LOW),
4012+ MFP_CFG_X(DF_IO3, AF1, DS08X, PULL_LOW),
4013+ MFP_CFG_X(DF_IO4, AF1, DS08X, PULL_LOW),
4014+ MFP_CFG_X(DF_IO5, AF1, DS08X, PULL_LOW),
4015+ MFP_CFG_X(DF_IO6, AF1, DS08X, PULL_LOW),
4016+ MFP_CFG_X(DF_IO7, AF1, DS08X, PULL_LOW),
4017+ MFP_CFG_X(DF_IO8, AF1, DS08X, PULL_LOW),
4018+ MFP_CFG_X(DF_IO9, AF1, DS08X, PULL_LOW),
4019+ MFP_CFG_X(DF_IO10, AF1, DS08X, PULL_LOW),
4020+ MFP_CFG_X(DF_IO11, AF1, DS08X, PULL_LOW),
4021+ MFP_CFG_X(DF_IO12, AF1, DS08X, PULL_LOW),
4022+ MFP_CFG_X(DF_IO13, AF1, DS08X, PULL_LOW),
4023+ MFP_CFG_X(DF_IO14, AF1, DS08X, PULL_LOW),
4024+
4025+ /* AC97 */
4026+ MFP_CFG_X(GPIO23, AF1, DS03X, PULL_LOW),
4027+ MFP_CFG_X(GPIO27, AF1, DS03X, PULL_LOW),
4028+ MFP_CFG_X(GPIO28, AF1, DS03X, PULL_LOW),
4029+ MFP_CFG_X(GPIO29, AF1, DS03X, PULL_LOW),
4030+ MFP_CFG_X(GPIO25, AF1, DS03X, PULL_LOW),
4031+
4032+ MFP_CFG_X(GPIO26, AF0, DS01X, PULL_LOW), /* Interrupt */
4033+ MFP_CFG_X(GPIO24, AF0, DS03X, PULL_LOW), /*SYSCLK external */
4034+ MFP_CFG_X(GPIO11, AF0, DS01X, PULL_LOW),
4035 };
4036
4037 static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
4038@@ -163,6 +198,9 @@
4039 pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
4040 }
4041
4042+extern int gpio_vsync;
4043+extern int gpio_vsync1;
4044+
4045 void __init zylonite_pxa300_init(void)
4046 {
4047 if (cpu_is_pxa300() || cpu_is_pxa310()) {
4048@@ -174,6 +212,8 @@
4049
4050 /* GPIO pin assignment */
4051 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
4052+ gpio_vsync = mfp_to_gpio(GPIO76_LCD_VSYNC);
4053+ gpio_vsync1 = mfp_to_gpio(GPIO71_LCD_LDD_17);
4054 }
4055
4056 if (cpu_is_pxa300()) {
4057Index: linux-2.6.23/drivers/video/pxafb.c
4058===================================================================
4059--- linux-2.6.23.orig/drivers/video/pxafb.c 2008-02-13 00:59:45.000000000 +0000
4060+++ linux-2.6.23/drivers/video/pxafb.c 2008-02-13 00:59:45.000000000 +0000
4061@@ -1543,9 +1543,9 @@
4062 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
4063 dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n",
4064 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
4065- if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
4066- dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n",
4067- inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
4068+ //if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
4069+ // dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n",
4070+ // inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
4071 if (inf->lccr0 & LCCR0_DPD &&
4072 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
4073 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
4074Index: linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h
4075===================================================================
4076--- linux-2.6.23.orig/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:59:45.000000000 +0000
4077+++ linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:59:45.000000000 +0000
4078@@ -175,13 +175,13 @@
4079 #define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X)
4080 #define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X)
4081 #define GPIO70_LCD_LDD_16 MFP_CFG_DRV(GPIO70, AF1, DS01X)
4082-#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF1, DS01X)
4083+#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF0, DS01X)
4084 #define GPIO62_LCD_CS_N MFP_CFG_DRV(GPIO62, AF2, DS01X)
4085 #define GPIO72_LCD_FCLK MFP_CFG_DRV(GPIO72, AF1, DS01X)
4086 #define GPIO73_LCD_LCLK MFP_CFG_DRV(GPIO73, AF1, DS01X)
4087 #define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS01X)
4088 #define GPIO75_LCD_BIAS MFP_CFG_DRV(GPIO75, AF1, DS01X)
4089-#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF2, DS01X)
4090+#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF0, DS01X)
4091
4092 #define GPIO15_LCD_CS_N MFP_CFG_DRV(GPIO15, AF2, DS01X)
4093 #define GPIO127_LCD_CS_N MFP_CFG_DRV(GPIO127, AF1, DS01X)
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_touch-r0.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_touch-r0.patch
new file mode 100644
index 0000000000..1c00696051
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/zylonite_touch-r0.patch
@@ -0,0 +1,1548 @@
1Index: linux-2.6.23/drivers/input/touchscreen/Kconfig
2===================================================================
3--- linux-2.6.23.orig/drivers/input/touchscreen/Kconfig 2008-02-13 01:12:29.000000000 +0000
4+++ linux-2.6.23/drivers/input/touchscreen/Kconfig 2008-02-13 01:13:20.000000000 +0000
5@@ -54,6 +54,12 @@
6 To compile this driver as a module, choose M here: the
7 module will be called corgi_ts.
8
9+config TOUCHSCREEN_ZYLONITE
10+ tristate "Zylonite touchscreen driver"
11+ default y
12+ help
13+ Say Y here for the Zylonite touchscreen driver
14+
15 config TOUCHSCREEN_FUJITSU
16 tristate "Fujitsu serial touchscreen"
17 select SERIO
18Index: linux-2.6.23/drivers/input/touchscreen/Makefile
19===================================================================
20--- linux-2.6.23.orig/drivers/input/touchscreen/Makefile 2008-02-13 01:12:29.000000000 +0000
21+++ linux-2.6.23/drivers/input/touchscreen/Makefile 2008-02-13 01:13:38.000000000 +0000
22@@ -19,3 +19,4 @@
23 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
24 obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
25 obj-$(CONFIG_TOUCHSCREEN_TSC2101) += tsc2101_ts.o
26+obj-$(CONFIG_TOUCHSCREEN_ZYLONITE) += zylonite-ts.o
27Index: linux-2.6.23/drivers/input/touchscreen/zylonite-ts.c
28===================================================================
29--- /dev/null 1970-01-01 00:00:00.000000000 +0000
30+++ linux-2.6.23/drivers/input/touchscreen/zylonite-ts.c 2008-02-13 16:19:15.000000000 +0000
31@@ -0,0 +1,1517 @@
32+/*
33+ * drivers/input/touchscreen/mhn_audio_touch.c.
34+ *
35+ * Author: bridge.wu@marvell.com
36+ * Created: Nov 17, 2006
37+ * Copyright: Marvell Corporation.
38+ *
39+ * This program is free software; you can redistribute it and/or modify
40+ * it under the terms of the GNU General Public License version 2 as
41+ * published by the Free Software Foundation.
42+ */
43+#include <linux/init.h>
44+#include <linux/module.h>
45+#include <linux/kernel.h>
46+#include <linux/device.h>
47+#include <linux/platform_device.h>
48+#include <linux/interrupt.h>
49+#include <linux/delay.h>
50+
51+#include <sound/driver.h>
52+#include <sound/core.h>
53+#include <sound/pcm.h>
54+#include <sound/initval.h>
55+
56+#include <asm/semaphore.h>
57+#include <asm/hardware.h>
58+#include <asm/arch/pxa-regs.h>
59+#include <asm/arch/gpio.h>
60+#include <asm/arch/mfp.h>
61+//#include <asm/arch/ipmc.h>
62+#include <linux/suspend.h>
63+#include <linux/spinlock.h>
64+
65+//#include <asm/arch/codec/acodec.h>
66+//#include <asm/arch/mhn_audio_plat.h>
67+
68+#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */
69+#define AC97_DIV __REG(0x41340014)
70+
71+#define ALSA_ZY_CARD_DEBUG
72+#undef ALSA_ZY_CARD_DEBUG
73+
74+#define WM_9713_ID 0x4C13 /* this should be the 7E register value */
75+
76+#ifdef ALSA_ZY_CARD_DEBUG
77+#define dbg(format, arg...) printk(KERN_DEBUG format, ##arg)
78+#else
79+#define dbg(format, arg...)
80+#endif
81+
82+#define DEBUG
83+#undef DEBUG
84+#ifdef DEBUG
85+unsigned int start_time;
86+unsigned int end_time;
87+unsigned int time;
88+#define PRINT_TIME() do {\
89+ time = ((end_time > start_time))?\
90+ (end_time - start_time)*100/325:\
91+ (0xffffffff - start_time + end_time)*100/325;\
92+ printk("\n%s:%dus\n", __FUNCTION__, time);\
93+} while(0)
94+#endif
95+
96+
97+
98+
99+/* 9713 specific
100+ * Register Name Index
101+ */
102+#define RESET 0X00
103+#define SPEAKER_VOLUME 0X02
104+#define HEADPHONE_VOLUME 0X04
105+#define OUT3_OUT4_VOLUME 0X06
106+#define MONOVOL_MONOINPGA_ROUTE 0X08
107+#define LINE_IN_PGA_VOL_ROUTE 0X0A
108+#define DAC_PGA_VOL_ROUTE 0X0C
109+#define MIC_PGA_VOLUME 0X0E
110+#define MIC_ROUTING 0X10
111+#define REC_PGA_VOL 0X12
112+#define REC_ROUTE_MUX_SEL 0X14
113+#define PCBEEP_VOL_ROUTE 0X16
114+#define VXDAC_VOLUME_ROUTE 0X18
115+#define AUX_DAC_VOL_ROUTE 0X1A
116+#define OUTPUT_PGA_MUX 0X1C
117+#define DAC_3D_CTRL_INV_MUX_SEL 0X1E
118+#define DAC_TONE_CTRL 0X20
119+#define MIC_BIAS 0X22
120+#define OUTPUT_VOL_MAPPING_JACK 0X24
121+#define POWERDOWN_CTRL_STAT 0X26
122+#define EXTENDED_AUD_ID 0X28
123+#define EXTENDED_AUD_STAT_CTRL 0X2A
124+#define AUDIO_DAC_RATE 0X2C
125+#define AUX_DAC_RATE 0X2E
126+#define AUDIO_ADC_RATE 0X32
127+#define PCM_CODEC_CTRL 0X36
128+#define SPDIF_CTRL 0X3A
129+#define POWER_DOWN_1 0X3C
130+#define POWER_DOWN_2 0X3E
131+#define GENERAL_PURPOSE_WM_13 0X40
132+#define FAST_POWERUP_CTRL 0X42
133+#define MCLK_PLL_CTRL_1 0X44
134+#define MCLK_PLL_CTRL_2 0X46
135+#define GPIO_PIN_CFG 0X4C
136+#define GPIO_PIN_POL_TYPE 0X4E
137+#define GPIO_PIN_STICKY 0X50
138+#define GPIO_PIN_WAKEUP 0X52
139+#define GPIO_PIN_STATUS 0X54
140+#define GPIO_PIN_SHARING 0X56
141+#define GPIO_PULL_UP_DOWN_CTRL 0X58
142+#define ADD_FUNC_1 0X5A
143+#define ADD_FUNC_2 0X5C
144+#define ALC_CTRL 0X60
145+#define ALC_NOISE_GATE_CTRL 0X62
146+#define AUX_DAC_INPUT_CTRL 0X64
147+#define TEST_REG_1 0X68
148+#define TEST_REG_2 0X6A
149+#define TEST_REG_3 0X6C
150+#define TEST_REG_4 0X6E
151+#define DIGITIZER_1_WM13 0x74
152+#define DIGITIZER_2_WM13 0x76
153+#define DIGITIZER_3_WM13 0x78
154+#define DIGITIZER_READ_BACK 0x7a
155+#define VENDOR_ID1 0x7c
156+#define VENDOR_ID2 0x7e
157+
158+#define ZY_TOUCH_SAMPLE_X 1
159+#define ZY_TOUCH_SAMPLE_Y 2
160+
161+#define ZY_EVENT_TYPE_NONE 0
162+#define ZY_EVENT_TYPE_PDN 1
163+
164+
165+typedef enum _zy_acodec_error_t {
166+ ZY_ACODEC_SUCCESS = 0, /* successful completion of a function */
167+ ZY_ACODEC_GENERAL_SW_ERR, /* null pointer to registers or other software error */
168+ ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT, /* time-out for waiting for respponse */
169+ ZY_ACODEC_SAMPLERATE_NOT_SUPPORTED, /* the sample rate is not supported either in controller or codec */
170+ ZY_ACODEC_FEATURE_NO_SUPPORTED, /* this codec feature is not supported */
171+ ZY_ACODEC_GENERAL_HW_ERR ,/* other hardware error besides time out */
172+ ZY_ACODEC_ROUTE_NO_SUPPORTED, /* the codec can not set the route required */
173+ ZY_ACODEC_SLEEP /* the codec is sleep */
174+} zy_acodec_error_t;
175+
176+typedef unsigned int zy_acodec_device_id_t;
177+
178+typedef enum _codec_state {
179+ ZY_CODEC_SLEEP = 0,
180+ ZY_CODEC_WAKEUP = 1
181+} acodec_state_t;
182+
183+typedef enum {
184+ ZY_FM = 0,
185+ ZY_MIC1 = 1,
186+ ZY_MIC2 = 2,
187+ ZY_SPEAKER =3,
188+ ZY_HEADSET =4,
189+ ZY_HANDSET =5,
190+} vol_port_type_t;
191+
192+typedef struct _context_t {
193+ int use_count; /* probe/remove and suspend/resume usage count, sync among multiple devices */
194+ zy_acodec_device_id_t acodec_id;/* - an ID that uniquely identifies the codec to be used */
195+ unsigned long init_number; /* used by driver to track whether it is inited or not */
196+
197+ void *p_voice_reg; /* pointer to Monahans registers that has PCM interface to codec */
198+ void *p_hifi_reg; /* pointer to Monahans registers that has hifi interface to codec */
199+ void *p_ctrl_reg; /* pointer to Monahans registers that has control interface to codec */
200+ int *p_ost_regs; /* needed for time out */
201+ void *p_save_memory; /* pointer to a memory region to save context while suspend */
202+ void *p_zy_scenario; /* pointer to the scenario data structure */
203+ long u_max_read_write_time_out_ms;/* input the max time to wait in milliseconds before giving up on a read or write operation */
204+ long u_max_setup_time_out_ms; /* input the maximum time in milliseconds to wait during initial setup of the ACODEC controller and codec */
205+
206+ /* member functions these pointers must be set by */
207+ zy_acodec_error_t (* g_pfn_codec_specific_init) (struct _context_t *p_device_context);
208+ zy_acodec_error_t (* g_pfn_codec_specific_dinit) (struct _context_t *p_device_context);
209+ zy_acodec_error_t (* g_pfn_acodec_read) (struct _context_t *p_dev_context, unsigned short reg_addr, unsigned short *p_reg_value);
210+ zy_acodec_error_t (* g_pfn_acodec_write) (struct _context_t *p_dev_context, unsigned short reg_addr, unsigned short reg_value);
211+
212+ /* add for route */
213+ zy_acodec_error_t (* g_pfn_set_route) (struct _context_t *p_device_context, unsigned short * rout_map ,unsigned short* current_map);
214+ /* add for sleep the codec */
215+ zy_acodec_error_t (* g_pfn_sleep_codec) (struct _context_t *p_device_context);
216+ /* add for Wake up the codec */
217+ zy_acodec_error_t (* g_pfn_wake_codec) (struct _context_t *p_device_context);
218+ /* add for get codec state */
219+ zy_acodec_error_t (* g_pfn_get_state) (struct _context_t *p_device_context, acodec_state_t *p_state);
220+ /* add for volume */
221+ zy_acodec_error_t (* g_pfn_get_vol)(struct _context_t *p_device_context, vol_port_type_t port, unsigned short *gain_in_db);
222+ zy_acodec_error_t (* g_pfn_set_vol)(struct _context_t *p_device_context, vol_port_type_t port, unsigned short gain_in_db);
223+
224+ void (* g_pfn_get_event)(struct _context_t *p_device_context, unsigned char * event_type);
225+ void (* g_pfn_event_ack)(struct _context_t *p_device_context, unsigned char event_type);
226+ zy_acodec_error_t (* g_pfn_enable_touch)(struct _context_t *p_device_context);
227+ zy_acodec_error_t (* g_pfn_disable_touch)(struct _context_t *p_device_context);
228+} zy_acocec_context_t, *p_zy_acocec_context_t;
229+
230+
231+
232+
233+
234+static p_zy_acocec_context_t p_zy_codec_ctxt = NULL;
235+
236+#include <linux/input.h>
237+//#include <asm/arch/codec/wm9713.h>
238+
239+#define PEN_DOWN 1
240+#define PEN_UP 0
241+#define TS_SAMPLE_INTERVAL 1
242+
243+typedef struct {
244+ struct input_dev *idev;
245+ struct timer_list *timer;
246+ int use_count;
247+} codec_zy_ts_t;
248+
249+codec_zy_ts_t codec_zy_ts;
250+
251+static struct input_dev *codec_zy_ts_input;
252+
253+#ifdef CONFIG_PM
254+static volatile int touch_suspend = 0 ;
255+#endif
256+
257+#define ZY_AC97_CODEC_REGS_NUM 0x40
258+
259+typedef struct
260+{ // Register symbol // Usage
261+ volatile unsigned long pocr; // PCM Out Control Register
262+ volatile unsigned long picr; // PCM In Control Register
263+ volatile unsigned long mccr; // Mic In Control Register
264+ volatile unsigned long gcr; // Global Control Register
265+ volatile unsigned long posr; // PCM Out Status Register
266+ volatile unsigned long pisr; // PCM In Status Register
267+ volatile unsigned long mcsr; // Mic In Status Register
268+ volatile unsigned long gsr; // Global Status Register
269+ volatile unsigned long car; // CODEC Access Register
270+ volatile unsigned long pcscr; // PCM Surround Out Control
271+ volatile unsigned long pcssr; // PCM Surround Out Status
272+ volatile unsigned long pcsdr; // PCM Surround Out Data
273+ volatile unsigned long pcclcr; // PCM Center/LFE Out Control
274+ volatile unsigned long pcclsr; // PCM Center/LFE Out Status
275+ volatile unsigned long pccldr; // PCM Center/LFE Out Data
276+ volatile unsigned long reserved1; //
277+ volatile unsigned long pcdr; // PCM FIFO Data Register
278+ volatile unsigned long reserved2 [0x7]; // 0x4050-0044 through 0x4050-005C
279+ volatile unsigned long mcdr; // Mic-in FIFO Data Register
280+ volatile unsigned long reserved3 [0x27]; // 0x4050-0064 through 0x4050-00FC
281+ volatile unsigned long mocr; // MODEM Out Control Register
282+ volatile unsigned long reserved4;
283+ volatile unsigned long micr; // MODEM In Control Register
284+ volatile unsigned long reserved5;
285+ volatile unsigned long mosr; // MODEM Out Status Register
286+ volatile unsigned long reserved6;
287+ volatile unsigned long misr; // MODEM In Status Register
288+ volatile unsigned long reserved7 [0x9]; // 0x4050-011C through 0x4050-013C
289+ volatile unsigned long modr; // MODEM FIFO Data Register
290+ volatile unsigned long reserved8 [0x2F]; // 0x4050-0144 through 0x4050-01FC
291+ // Primary Audio CODEC registers access
292+ volatile unsigned long codec_regs_primary_aud [ZY_AC97_CODEC_REGS_NUM];
293+ // Secondary ID 01 Audio CODEC registers access
294+ volatile unsigned long codec_regs_secondary_aud [ZY_AC97_CODEC_REGS_NUM];
295+ // Primary MODEM CODEC registers access
296+ volatile unsigned long codec_regs_primary_mdm [ZY_AC97_CODEC_REGS_NUM];
297+ // Secondary ID 01 MODEM CODEC registers access
298+ volatile unsigned long codec_regs_secondary_mdm [ZY_AC97_CODEC_REGS_NUM];
299+ // Secondary ID 10 MODEM CODEC registers access
300+ volatile unsigned long codec_regs_third_mdm [ZY_AC97_CODEC_REGS_NUM];
301+ // Secondary ID 11 MODEM CODEC registers access
302+ volatile unsigned long codec_regs_fouth_mdm [ZY_AC97_CODEC_REGS_NUM];
303+ // Secondary ID 10 Audio CODEC registers access
304+ volatile unsigned long codec_regs_third_aud [ZY_AC97_CODEC_REGS_NUM];
305+ // Secondary ID 11 Audio CODEC registers access
306+ volatile unsigned long codec_regs_fouth_aud [ZY_AC97_CODEC_REGS_NUM];
307+} zy_ac97_acodec_t, *p_zy_ac97acodec_t ;
308+
309+
310+/* Constants for the Global Control Register and Global Status Register */
311+
312+// AC97 Global Control Register bit mask constants
313+
314+#define ZY_AC97_GCR_GIE_MSK (1u << 0 )
315+#define ZY_AC97_GCR_COLD_RESET_MSK (1u << 1 )
316+#define ZY_AC97_GCR_WARM_RESET_MSK (1u << 2 )
317+#define ZY_AC97_GCR_LINK_OFF_MSK (1u << 3 )
318+#define ZY_AC97_GCR_PCRSM_IEN_MSK (1u << 4 )
319+#define ZY_AC97_GCR_SCRSM_IEN_MSK (1u << 5 )
320+#define ZY_AC97_GCR_PCRDY_IEN_MSK (1u << 8 )
321+#define ZY_AC97_GCR_SCRDY_IEN_MSK (1u << 9 )
322+#define ZY_AC97_GCR_SDONE_IE_MSK (1u << 18)
323+#define ZY_AC97_GCR_CDONE_IE_MSK (1u << 19)
324+#define ZY_AC97_GCR_nDMAEN_MSK (1u << 24)
325+#define ZY_AC97_GCR_CLKBPB_MSK (1u << 31)
326+#define ZY_AC97_GCR_FRCRST_MSK (1u << 30)
327+// Global Status Register bit mask constants
328+
329+#define ZY_AC97_GSR_GSCI_MSK (1u << 0 )
330+#define ZY_AC97_GSR_MIINT_MSK (1u << 1 )
331+#define ZY_AC97_GSR_MOINT_MSK (1u << 2 )
332+#define ZY_AC97_GSR_ACOFFD_MSK (1u << 3 )
333+#define ZY_AC97_GSR_PIINT_MSK (1u << 5 )
334+#define ZY_AC97_GSR_POINT_MSK (1u << 6 )
335+#define ZY_AC97_GSR_MINT_MSK (1u << 7 )
336+#define ZY_AC97_GSR_PCRDY_MSK (1u << 8 )
337+#define ZY_AC97_GSR_SCRDY_MSK (1u << 9 )
338+#define ZY_AC97_GSR_PCRSM_MSK (1u << 10)
339+#define ZY_AC97_GSR_SCRSM_MSK (1u << 11)
340+#define ZY_AC97_GSR_SLT12_BITS_MSK (7u << 12)
341+#define ZY_AC97_GSR_RCS_ERR_MSK (1u << 15)
342+#define ZY_AC97_GSR_SDONE_MSK (1u << 18)
343+#define ZY_AC97_GSR_CDONE_MSK (1u << 19)
344+
345+
346+// Bit mask and values for CAIP bit in car register.
347+#define ZY_AC97_CAR_CAIP_MSK (0x1<<0)
348+#define ZY_AC97_CAR_CAIP_LOCKED (0x1<<0)
349+#define ZY_AC97_CAR_CAIP_CLEAR (0<<0)
350+
351+/* Constants for FIFO status reporting and control */
352+
353+// One bit location is used to report FIFO error conditions and clear
354+// interrupts on those conditions in the various non-global status registers.
355+
356+// ZY_AC97_FIFOSTAT_FIFOE is used in:
357+ // posr
358+ // pisr
359+ // mcsr
360+ // mosr
361+ // misr
362+
363+#define ZY_AC97_FIFOSTAT_FIFOE (1u << 4)
364+#define ZY_AC97_FIFOSTAT_EOC (1u << 3)
365+#define ZY_AC97_FIFOSTAT_FSR (1u << 2)
366+
367+// A different bit location is used to enable or disable interrupts based on
368+// FIFO error conditions in the various non-global control registers.
369+
370+// ZY_AC97_FIFOCTRL_FEIE is used in:
371+ // pocr
372+ // picr
373+ // mccr
374+ // mocr
375+ // micr
376+
377+#define ZY_AC97_FIFOCTRL_FEIE (1u << 3)
378+#define ZY_AC97_FIFOCTRL_FSRIE (1u << 1)
379+
380+/*
381+*******************************************************************************
382+ AC'97 Codec Registers Location and Bit Definition
383+*******************************************************************************
384+*/
385+
386+/* */
387+
388+ // Includes symbolic values for certain proprietary register asssignments
389+ // in AC'97 devices that might be used with ZY_AC97.
390+
391+ // Valid for subset of R 2.1 specification.
392+ // Leading "e" in comment means it is an "expanded" register definition as
393+ // found in one or more of the Appendices A-D of the R 2.1 specification.
394+ // Appendix identifier will immediately follow the "e", such as "eA"
395+ // R/O indicates read-only
396+ // Registers not supported by the assumed controller will be commented out.
397+
398+#define ZY_AC97_CR_RESET_ID 0x00 // RESET CODEC TO DEFAULT, get ID info
399+#define ZY_AC97_CR_MASTER_VOLUME 0x02 // LINE OUT VOLUME
400+#define ZY_AC97_CR_HEADPHONE_VOLUME 0x04 //
401+#define ZY_AC97_CR_MASTER_VOLUME_MONO 0x06 //
402+#define ZY_AC97_CR_MASTER_TONE_R_L 0x08 //
403+#define ZY_AC97_CR_PC_BEEP_VOLUME 0x0A //
404+#define ZY_AC97_CR_PHONE_VOLUME 0x0C //
405+#define ZY_AC97_CR_MIC_VOLUME 0x0E // micrOPHONE VOLUME/ AGC
406+#define ZY_AC97_CR_LINE_IN_VOLUME 0x10 // LINE IN VOLUME
407+#define ZY_AC97_CR_CD_VOLUME 0x12 //
408+#define ZY_AC97_CR_VIDEO_VOLUME 0x14 //
409+#define ZY_AC97_CR_AUX_VOLUME 0x16 //
410+#define ZY_AC97_CR_PCM_OUT_VOLUME 0x18 //
411+#define ZY_AC97_CR_RECORD_SELECT 0x1A // SELECT LINE IN OR micrOPHONE
412+#define ZY_AC97_CR_RECORD_GAIN 0x1C //
413+#define ZY_AC97_CR_RECORD_GAIN_MIC 0x1E //
414+#define ZY_AC97_CR_GENERAL_PURPOSE 0x20 //
415+#define ZY_AC97_CR_CONTROL_3D 0x22 //
416+#define ZY_AC97_CR_POWERDOWN_CTRL_STAT 0x26 // POWER MANAGEMENT
417+#define ZY_AC97_CR_E_AUDIO_ID 0x28 // eA Extended audio sprt info, R/O
418+#define ZY_AC97_CR_E_AUDIO_CTRL_STAT 0x2A // eA Extended audio stat + control
419+
420+//
421+// Audio Sample Rate Control Registers, 0x2C - 0x34
422+//
423+ // eA PCM Front DAC rate control
424+#define ZY_AC97_CR_E_ASR_PCM_FRNT_DAC_RT 0x2C // (output slots 3, 4, 6)
425+#define ZY_AC97_CR_E_ASR_PCM_LR_ADC_RT 0x32 // eA PCM L+R ADC rate control (3+4)
426+#define ZY_AC97_CR_E_ASR_MIC_ADC_RT 0x34 // eA PCM Mic ADC rate control (5)
427+
428+
429+#define ZY_AC97_CR_E_MDM_GPIO_PIN_STAT 0x54
430+//
431+// 5Ah-7Ah: Vendor Reserved
432+//
433+//
434+// 7Ch-7Eh: Vendor ID registers. Optional but standardized for Plug'n'Play
435+//
436+#define ZY_AC97_CR_VENDOR_ID1 0x7C
437+#define ZY_AC97_CR_VENDOR_ID2 0x7E
438+
439+#define ZY_AC97_CR_MAX ZY_AC97_CR_VENDOR_ID2
440+
441+#define ZY_AC97_CR_END_OF_LIST (ZY_AC97_CR_MAX + 2)
442+
443+
444+
445+/* Other Constants */
446+
447+// For accessing the Codec mixer registers, each increment of one 32-bit word
448+// in processor space increments the addressed mixer register by two.
449+// This does not cause any ambiguities because only even mixer register
450+// addresses are currently supported (AC '97 spec, R 2.2)
451+#define ZY_AC97_CODEC_REGS_PER_WORD 2
452+
453+/* Default timeout and holdtime settings */
454+
455+// timeout in reading and writing codec registers through AC link
456+#define ZY_AC97_RW_TIMEOUT_DEF 200 //unit is us
457+
458+// timeout in waiting for codec's ready signal during setup process
459+#define ZY_AC97_SETUP_TIMEOUT_DEF 500 //unit is us
460+
461+// timeout in waiting for locking the link successfully
462+#define ZY_AC97_LOCK_TIMEOUT_DEF 300 //unit is us
463+
464+// timeout in shutting down the link
465+#define ZY_AC97_LINKOFF_TIMEOUT_DEF 500 //unit is us
466+
467+// holdtime for keeping nReset signal active(low) in AC link
468+#define ZY_AC97_COLD_HOLDTIME 100 //unit is us
469+
470+/*
471+*******************************************************************************
472+ ZY AC97 data structure used in function interface
473+*******************************************************************************
474+*/
475+
476+typedef struct
477+{
478+ unsigned long pocr; // PCM Out Control Register
479+ unsigned long picr; // PCM In Control Register
480+ unsigned long mccr; // Mic In Control Register
481+ unsigned long gcr; // Global Control Register
482+ unsigned long pcscr; // PCM Surround Out Control
483+ unsigned long pcclcr; // PCM Center/LFE Out Control
484+ unsigned long mocr; // MODEM Out Control Register
485+ unsigned long micr; // MODEM In Control Register
486+}zy_ac97_save_context_t;
487+
488+
489+#define AC97_SAVE_CONTEXT_SIZE (sizeof(zy_ac97_save_context_t))
490+
491+static int zy_ac97_acodec_link_lock(p_zy_ac97acodec_t p_ac97_reg)
492+{
493+ int status = 1;
494+ volatile unsigned long car_tmp;
495+
496+ car_tmp = p_ac97_reg->car;
497+ if (car_tmp & ZY_AC97_CAR_CAIP_MSK) /* "1" in CAIP bit means lock failed. */
498+ {
499+ status = 0;
500+ }
501+ return (status);
502+}
503+
504+
505+zy_acodec_error_t zy_ac97_acodec_write (zy_acocec_context_t *p_dev_context, unsigned short offset, unsigned short data)
506+{
507+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
508+ int got_link;
509+ unsigned long time_remaining;
510+ volatile unsigned long * p_codec_reg;
511+ p_zy_ac97acodec_t p_ac97_reg = (p_zy_ac97acodec_t)(p_dev_context->p_ctrl_reg);
512+ unsigned long max_rw_time_out_us = (p_dev_context->u_max_read_write_time_out_ms) * 1000;
513+
514+
515+ if(offset == ZY_AC97_CR_E_MDM_GPIO_PIN_STAT)
516+ {/* it is a special register and sent out on slot 12 */
517+ p_codec_reg = &(p_ac97_reg->codec_regs_primary_mdm[0]);
518+ p_codec_reg += offset / ZY_AC97_CODEC_REGS_PER_WORD;
519+ /* The data will be sent out on slot 12. */
520+ *p_codec_reg = (unsigned long)data;
521+ goto done;
522+ }
523+
524+ /* Point to specified register within area mapped to target codec regs */
525+ p_codec_reg = &(p_ac97_reg->codec_regs_primary_aud[0]);
526+ p_codec_reg += offset / ZY_AC97_CODEC_REGS_PER_WORD;
527+
528+
529+ /* Lock the ACLINK */
530+ time_remaining = ZY_AC97_LOCK_TIMEOUT_DEF;
531+ do
532+ {
533+ got_link = zy_ac97_acodec_link_lock(p_ac97_reg);
534+ if (0 == got_link) /* 1 usec is a long time. Skip delay if possible. */
535+ {
536+ udelay(1);
537+ }
538+ } /* Wait while time remaining and ACLINK not available */
539+ while (time_remaining-- && (0 == got_link));
540+
541+ if (0 == got_link) /* Didn't get the ACLINK */
542+ {
543+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
544+ printk(KERN_ERR "AC97 Write Link Timeout\n");
545+ }
546+ else /* We got the link. Perform the write operation and don't wait. */
547+ {
548+ /* First, clear old write status indication CDONE by writing a ONE to that bit. */
549+ p_ac97_reg->gsr = ZY_AC97_GSR_CDONE_MSK;
550+
551+ *p_codec_reg = (unsigned long)data; /* Now the write! */
552+
553+ /* Wait until write cycle is complete. There should be a way
554+ * to do this speculatively at the beginning of the procedure.
555+ * Need to discover it. Too inefficient to always wait.
556+ */
557+
558+ time_remaining = max_rw_time_out_us;
559+ do
560+ {
561+ udelay(1);
562+ } /* Wait while time remaining and command I/O still incomplete. */
563+ while ( (time_remaining--) && !(p_ac97_reg->gsr & ZY_AC97_GSR_CDONE_MSK));
564+ if (!(p_ac97_reg->gsr & ZY_AC97_GSR_CDONE_MSK))
565+ {
566+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
567+ p_ac97_reg->car = ZY_AC97_CAR_CAIP_CLEAR;
568+ }
569+ } /* Got AC link */
570+
571+done:
572+ return(status);
573+} /* Ac97CtrlCodecWrite() */
574+
575+#define CKENA __REG(0x4134000C) /* A Clock Enable Register */
576+#define CKENB __REG(0x41340010)
577+
578+zy_acodec_error_t zy_ac97_acodec_read (zy_acocec_context_t *p_dev_context, unsigned short offset, unsigned short *pdata)
579+{
580+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
581+ int got_link;
582+ unsigned long time_remaining;
583+ volatile unsigned long * p_codec_reg;
584+ p_zy_ac97acodec_t p_ac97_reg = (p_zy_ac97acodec_t)(p_dev_context->p_ctrl_reg);
585+ unsigned long max_rw_time_out_us = (p_dev_context->u_max_read_write_time_out_ms) * 1000;
586+
587+ /* Point to specified register within area mapped to target codec regs */
588+ p_codec_reg = &(p_ac97_reg->codec_regs_primary_aud[0]);
589+ p_codec_reg += offset / ZY_AC97_CODEC_REGS_PER_WORD;
590+
591+ /* Lock the ACLINK */
592+ time_remaining = ZY_AC97_LOCK_TIMEOUT_DEF;
593+ do
594+ {
595+ got_link = zy_ac97_acodec_link_lock(p_ac97_reg);
596+ if (0 == got_link) /* 1 usec is a long time. Skip delay if possible. */
597+ {
598+ udelay(1);
599+ }
600+ } /* Wait while time remaining and ACLINK not available */
601+ while (time_remaining-- && (0 == got_link));
602+
603+ if (0 == got_link) /* Didn't get the ACLINK */
604+ {
605+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
606+ printk(KERN_ERR "AC97 Read Link Timeout\n");
607+ }
608+ else /* We got the link. Perform the write operation and don't wait. */
609+ {
610+ /* First, clear old read status indications. */
611+ p_ac97_reg->gsr = ZY_AC97_GSR_SDONE_MSK | ZY_AC97_GSR_RCS_ERR_MSK;
612+
613+ *pdata = (unsigned short)(*p_codec_reg); /* This is THE DUMMY READ. */
614+
615+ /* Wait for read I/O with codec to complete before doing real read. */
616+ time_remaining = max_rw_time_out_us;
617+ do
618+ {
619+ udelay(1);
620+ } /* Wait while time remaining and read I/O still incomplete */
621+ while( (time_remaining--) && (!(p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK)) );
622+
623+ if ((p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK) && (!(p_ac97_reg->gsr & ZY_AC97_GSR_RCS_ERR_MSK)) )
624+ {
625+ if (p_ac97_reg->gsr & ZY_AC97_GSR_RCS_ERR_MSK)
626+ {/* timeout indicated by RCS bit */
627+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
628+ }
629+ /* succeed in reading. clear status bits first. */
630+ p_ac97_reg->gsr = ZY_AC97_GSR_SDONE_MSK | ZY_AC97_GSR_RCS_ERR_MSK;
631+ *pdata = (unsigned short)(*p_codec_reg); /* THE REAL READ. */
632+ if (*pdata == 0xffff)
633+ {/* timeout indicated by returned value */
634+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
635+ }
636+ /* check later: is second waiting really needed? */
637+ time_remaining = max_rw_time_out_us;
638+ do
639+ {
640+ udelay(1);
641+ } /* Wait while time remaining and read I/O still incomplete */
642+ while( (time_remaining--) && (!(p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK)) );
643+ //printk(KERN_ERR "AC97 Read Result %d\n", (p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK) );
644+ }
645+ else /* failed */
646+ {
647+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
648+ p_ac97_reg->car = ZY_AC97_CAR_CAIP_CLEAR;
649+ //printk(KERN_ERR "AC97 Read Link Timeout2 %x %x %x\n", CKENA, OSCC, CKENB);
650+ } /* else (OK to do real read) */
651+
652+ } /* else (We got the link. Perform the read operations.) */
653+
654+ return (status);
655+}
656+
657+
658+
659+zy_acodec_error_t zy_acodec_get_adc_sample(zy_acocec_context_t *p_device_context, unsigned short *p_sample_data, unsigned short adc_type, int *p_pen_down)
660+{
661+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
662+ unsigned short value;
663+ unsigned long wait;
664+
665+ if (adc_type == ZY_TOUCH_SAMPLE_X)
666+ {
667+ value = 0x202;
668+ }
669+ else
670+ {/* Y sample */
671+ value = 0x204;
672+ }
673+
674+ status = zy_ac97_acodec_write(p_device_context, DIGITIZER_1_WM13, value);
675+
676+ wait = 0;
677+ do
678+ {
679+ status = zy_ac97_acodec_read(p_device_context, DIGITIZER_1_WM13, &value);
680+ if ( !(value & 0x200 ) )
681+ {
682+ break;
683+ }
684+ }while ( 100 > wait++ );
685+
686+ status = zy_ac97_acodec_read(p_device_context, DIGITIZER_READ_BACK, &value);
687+ if (value & 0x8000)
688+ {/* means pen down */
689+ *p_pen_down = 1;
690+ }
691+ else
692+ {
693+ *p_pen_down = 0;
694+ }
695+ *p_sample_data = value & 0xfff;
696+
697+ return status;
698+}
699+
700+
701+
702+/*
703+ * add a touch event
704+ */
705+static int codec_zy_ts_evt_add(codec_zy_ts_t* ts, u16 pressure, u16 x, u16 y)
706+{
707+ /* add event and remove adc src bits */
708+ static u16 pre_press = 0;
709+
710+ input_report_abs(ts->idev, ABS_X, x & 0xfff);
711+ input_report_abs(ts->idev, ABS_Y, y & 0xfff);
712+ if (pressure == pre_press){
713+ pressure--;
714+ }
715+ pre_press = pressure;
716+ input_report_abs(ts->idev, ABS_PRESSURE, pressure & 0xfff);
717+ input_sync(ts->idev);
718+#ifdef CONFIG_IPM
719+ ipm_event_notify(IPM_EVENT_UI, IPM_EVENT_DEVICE_TSI, NULL, 0);
720+#endif
721+ return 0;
722+}
723+
724+/*
725+ * add a pen up event
726+ */
727+static void codec_zy_ts_evt_release(codec_zy_ts_t* ts)
728+{
729+ input_report_abs(ts->idev, ABS_PRESSURE, 0);
730+ input_sync(ts->idev);
731+
732+#ifdef CONFIG_IPM
733+ ipm_event_notify(IPM_EVENT_UI, IPM_EVENT_DEVICE_TSI, NULL, 0);
734+#endif
735+ p_zy_codec_ctxt->g_pfn_event_ack(p_zy_codec_ctxt,ZY_EVENT_TYPE_PDN);
736+}
737+
738+/*
739+ * Kill the touchscreen thread and stop
740+ * the touch digitiser.
741+ */
742+static void codec_zy_ts_input_close(struct input_dev *idev)
743+{
744+ codec_zy_ts_t *ts = (codec_zy_ts_t *) &codec_zy_ts;
745+
746+#ifdef CONFIG_PM
747+ if(touch_suspend){
748+ pr_info("touch is suspended!\n");
749+ return -1;
750+ }
751+#endif
752+ dbg("close ts input!\n");
753+ if (--ts->use_count == 0) {
754+ del_timer(ts->timer);
755+ if (ts->timer != NULL)
756+ kfree(ts->timer);
757+ p_zy_codec_ctxt->g_pfn_disable_touch(p_zy_codec_ctxt);
758+ }
759+}
760+
761+/*
762+ * Sample the touchscreen
763+ */
764+int ac97_poll_touch(codec_zy_ts_t *ts)
765+{
766+ unsigned short x=0, y=0;
767+ int if_down= 0;
768+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
769+
770+#ifdef DEBUG
771+ start_time = OSCR;
772+#endif
773+
774+ /* get x value */
775+ status = zy_acodec_get_adc_sample(p_zy_codec_ctxt, &x, ZY_TOUCH_SAMPLE_X, &if_down);
776+ if (ZY_ACODEC_SUCCESS != status ){
777+ return -EIO;
778+ }
779+ dbg("x:0x%x\n", x);
780+
781+ /* the pen is up */
782+ if (1 != if_down){
783+ return PEN_UP;
784+ }
785+
786+ /* get y vaule */
787+ status = zy_acodec_get_adc_sample(p_zy_codec_ctxt, &y, ZY_TOUCH_SAMPLE_Y, &if_down);
788+ if (ZY_ACODEC_SUCCESS != status ){
789+ return -EIO;
790+ }
791+ dbg("y:0x%x\n",y);
792+
793+ /* the pen is up */
794+ if (1 != if_down){
795+ return PEN_UP;
796+ }
797+
798+ /* the pen is down, can not get the pressure value,
799+ * so if pen is down, give the max pressure value
800+ */
801+ codec_zy_ts_evt_add(ts,0xfff, x, y);
802+
803+#ifdef DEBUG
804+ end_time = OSCR;
805+ PRINT_TIME();
806+#endif
807+
808+ return PEN_DOWN;
809+}
810+
811+static void touch_timer_handler(unsigned long unused)
812+{
813+ int event;
814+ codec_zy_ts_t *ts = &codec_zy_ts;
815+
816+ event = ac97_poll_touch(ts);
817+
818+ if (event == PEN_DOWN) {
819+ dbg("pen down!\n");
820+ ts->timer->expires = jiffies + TS_SAMPLE_INTERVAL;
821+ add_timer(ts->timer);
822+ } else if(event == PEN_UP) {
823+ dbg("pen up!\n");
824+ codec_zy_ts_evt_release(ts);
825+ } else if(event == -EIO) {
826+ printk(KERN_ERR "Access touch interface error!\n");
827+ }
828+ return;
829+}
830+
831+static zy_acodec_error_t zy_ac97_acodec_cold_reset(zy_acocec_context_t * p_ac97_ctxt)
832+{
833+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
834+ p_zy_ac97acodec_t p_ac97 = (p_zy_ac97acodec_t)(p_ac97_ctxt->p_ctrl_reg);
835+ int pri_codec_ready;
836+ unsigned long time_remaining;
837+
838+ p_ac97->gcr = 0;
839+ p_ac97->gcr |= ZY_AC97_GCR_CLKBPB_MSK;
840+ /* Hold reset active for a minimum time */
841+ udelay(ZY_AC97_COLD_HOLDTIME);
842+ p_ac97->gcr &= ~ZY_AC97_GCR_CLKBPB_MSK;
843+
844+ /* Deactivate cold reset condition */
845+ p_ac97->gcr |= (ZY_AC97_GCR_COLD_RESET_MSK | ZY_AC97_GCR_WARM_RESET_MSK);
846+
847+
848+ pri_codec_ready = 0;
849+ time_remaining = (p_ac97_ctxt->u_max_setup_time_out_ms) * 10;
850+ do
851+ {
852+ udelay(1);
853+ if (p_ac97->gsr & ZY_AC97_GSR_PCRDY_MSK)
854+ pri_codec_ready = 1;
855+ }
856+ while (time_remaining-- && (pri_codec_ready == 0));
857+
858+ /* Timeout status if some of the devices weren't ready. */
859+ if (pri_codec_ready == 0)
860+ {
861+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
862+ }
863+
864+ return (status);
865+}
866+
867+
868+zy_acodec_error_t zy_ac97_acodec_init(zy_acocec_context_t *p_ac97_ctxt)
869+{
870+ zy_acodec_error_t status ;
871+
872+ status = zy_ac97_acodec_cold_reset(p_ac97_ctxt);
873+
874+ return (status);
875+}
876+
877+
878+/*
879+ * Start the touchscreen thread and
880+ * the touch digitiser.
881+ */
882+static int codec_zy_ts_input_open(struct input_dev *idev)
883+{
884+ codec_zy_ts_t *ts = (codec_zy_ts_t *) &codec_zy_ts;
885+
886+#ifdef CONFIG_PM
887+ if(touch_suspend){
888+ pr_info("touch is suspended!\n");
889+ return -1;
890+ }
891+#endif
892+
893+ if (ts->use_count++ > 0)
894+ return 0;
895+
896+ dbg("Touch is opened. Use count: %d\n", ts->use_count);
897+ ts->idev = idev;
898+ ts->timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
899+ if (!ts->timer) {
900+ printk(KERN_ERR "Alloc memory error for timer!\n");
901+ return -ENOMEM;
902+ }
903+
904+ init_timer(ts->timer);
905+ ts->timer->function = touch_timer_handler;
906+ ts->timer->data = 0;
907+ p_zy_codec_ctxt->g_pfn_enable_touch(p_zy_codec_ctxt);
908+
909+ return 0;
910+}
911+
912+/*
913+ * initilze the pxa touch screen
914+ */
915+static int alsa_ts_init( void )
916+{
917+ codec_zy_ts_t* ts = &codec_zy_ts;
918+
919+ memset(ts, 0, sizeof(codec_zy_ts_t));
920+
921+ codec_zy_ts_input = input_allocate_device();
922+ if (!codec_zy_ts_input)
923+ return -ENOMEM;
924+
925+
926+ /* tell input system what we events we accept and register */
927+ codec_zy_ts_input->name = "codec zy touchscreen";
928+ codec_zy_ts_input->open = codec_zy_ts_input_open;
929+ codec_zy_ts_input->close = codec_zy_ts_input_close;
930+ __set_bit(EV_ABS, codec_zy_ts_input->evbit);
931+ __set_bit(ABS_X, codec_zy_ts_input->absbit);
932+ __set_bit(ABS_Y, codec_zy_ts_input->absbit);
933+ __set_bit(ABS_PRESSURE, codec_zy_ts_input->absbit);
934+ input_register_device(codec_zy_ts_input);
935+
936+ return 0;
937+}
938+
939+static irqreturn_t pxa_touch_irq(int irq, void *dev)
940+{
941+ unsigned char event_type;
942+
943+ //printk(KERN_ERR "%s: enter codec event handler\n", __FUNCTION__);
944+
945+ dbg("%s: enter codec event handler\n", __FUNCTION__);
946+ p_zy_codec_ctxt->g_pfn_get_event(p_zy_codec_ctxt, &event_type);
947+ switch (event_type) {
948+ case ZY_EVENT_TYPE_PDN:
949+ {
950+ codec_zy_ts_t *ts = &codec_zy_ts;
951+ /*if the touch is not open need not acknowledge the event*/
952+ if (ts->use_count <= 0)
953+ break;
954+ ts->timer->expires = jiffies + TS_SAMPLE_INTERVAL;
955+ add_timer(ts->timer);
956+ break;
957+ }
958+ default:
959+ printk("unsupported codec event:0x%x\n", event_type);
960+ }
961+
962+ return IRQ_HANDLED;
963+}
964+
965+
966+
967+
968+
969+
970+
971+
972+
973+static mfp_cfg_t extra_cfg[] = {
974+ MFP_CFG_X(GPIO17, AF3, DS03X, PULL_LOW),
975+ MFP_CFG_X(GPIO25, AF0, DS01X, PULL_LOW),
976+};
977+
978+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
979+
980+extern void dump_mfp(void);
981+
982+zy_acodec_error_t zy_ac97_acodec_mfp_init(zy_acocec_context_t *p_device_context)
983+{
984+ unsigned short codec_id;
985+
986+ //mhn_mfp_set_afds(MFP_RSVD_AC97_SDATA_IN_0, MFP_AF0, MFP_DS03X);
987+ //enable_ac97_pins();
988+ zy_ac97_acodec_init(p_device_context);
989+ if (zy_ac97_acodec_read(p_device_context, 0x0, &codec_id)){
990+
991+ /*
992+ * there is a bug on MonahansL/MonhansPL PC card: AC97_SDATA_IN is not connected to CODEC
993+ * ECO 72: Connect PWM_0(MFP_RSVD_AC97_SDATA_IN_0) to CODEC as AC97_SDATA_IN
994+ */
995+
996+ //mhn_mfp_set_afds(MFP_RSVD_AC97_SDATA_IN_0, MFP_RSVD_AC97_SDATA_IN_0_AF, MFP_DS03X);
997+ //mhn_mfp_set_afds(MFP_AC97_SDATA_IN_0, MFP_AF0, MFP_DS01X);
998+
999+ gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO17), 0);
1000+ pxa3xx_mfp_config(ARRAY_AND_SIZE(extra_cfg));
1001+ gpio_direction_input(mfp_to_gpio(MFP_PIN_GPIO25));
1002+ }
1003+
1004+
1005+ return ZY_ACODEC_SUCCESS;
1006+}
1007+
1008+#define ZY_AC97_WM9713_GPIO_PIN_PDN ( 0x1 << 13 ) /* Pen down */
1009+
1010+/*power enable bit in 3ch and 3eh */
1011+/*3ch */
1012+#define ZY_AC97_9713_PWR_PADCPD ( 0x1 << 15 )
1013+#define ZY_AC97_9713_PWR_VMID ( 0x1 << 14 )
1014+#define ZY_AC97_9713_PWR_TSHUT ( 0x1 << 13 )
1015+#define ZY_AC97_9713_PWR_VXDAC ( 0x1 << 12 )
1016+#define ZY_AC97_9713_PWR_AUXDAC ( 0x1 << 11 )
1017+#define ZY_AC97_9713_PWR_MBIAS ( 0x1 << 10 )
1018+#define ZY_AC97_9713_PWR_PLL ( 0x1 << 9 )
1019+#define ZY_AC97_9713_PWR_DACL ( 0x1 << 7 )
1020+#define ZY_AC97_9713_PWR_DACR ( 0x1 << 6 )
1021+#define ZY_AC97_9713_PWR_ADCL ( 0x1 << 5 )
1022+#define ZY_AC97_9713_PWR_ADCR ( 0x1 << 4 )
1023+#define ZY_AC97_9713_PWR_HPLX ( 0x1 << 3 )
1024+#define ZY_AC97_9713_PWR_HPRX ( 0x1 << 2 )
1025+#define ZY_AC97_9713_PWR_SPKX ( 0x1 << 1 )
1026+#define ZY_AC97_9713_PWR_MX ( 0x1 << 0 )
1027+
1028+/*3EH */
1029+#define ZY_AC97_9713_PWR_MCD ( 0x1 << 15 )
1030+#define ZY_AC97_9713_PWR_MICBIAS ( 0x1 << 14 )
1031+#define ZY_AC97_9713_PWR_MONO ( 0x1 << 13 )
1032+#define ZY_AC97_9713_PWR_OUT4 ( 0x1 << 12 )
1033+#define ZY_AC97_9713_PWR_OUT3 ( 0x1 << 11 )
1034+#define ZY_AC97_9713_PWR_HPL ( 0x1 << 10 )
1035+#define ZY_AC97_9713_PWR_HPR ( 0x1 << 9 )
1036+#define ZY_AC97_9713_PWR_SPKL ( 0x1 << 8 )
1037+#define ZY_AC97_9713_PWR_SPKR ( 0x1 << 7 )
1038+#define ZY_AC97_9713_PWR_LL ( 0x1 << 6 )
1039+#define ZY_AC97_9713_PWR_LR ( 0x1 << 5 )
1040+#define ZY_AC97_9713_PWR_MOIN ( 0x1 << 4 )
1041+#define ZY_AC97_9713_PWR_MA ( 0x1 << 3 )
1042+#define ZY_AC97_9713_PWR_MB ( 0x1 << 2 )
1043+#define ZY_AC97_9713_PWR_MPA ( 0x1 << 1 )
1044+#define ZY_AC97_9713_PWR_MPB ( 0x1 << 0 )
1045+
1046+
1047+void zy_wm9713_get_event(zy_acocec_context_t *p_device_context, unsigned char * event_type)
1048+{
1049+ unsigned short event_state = 0;
1050+ zy_ac97_acodec_read(p_device_context, GPIO_PIN_STATUS, &event_state);
1051+ if(event_state & ZY_AC97_WM9713_GPIO_PIN_PDN){
1052+ *event_type = ZY_EVENT_TYPE_PDN;
1053+ return;
1054+ }
1055+ return;
1056+}
1057+
1058+void zy_wm9713_event_ack(zy_acocec_context_t *p_device_context, unsigned char event_type)
1059+{
1060+ unsigned short event_state = 0;
1061+ zy_ac97_acodec_read(p_device_context, GPIO_PIN_STATUS, &event_state);
1062+ if( event_type == ZY_EVENT_TYPE_PDN){
1063+ zy_ac97_acodec_write(p_device_context,
1064+ GPIO_PIN_STATUS,
1065+ (event_state & (~ZY_AC97_WM9713_GPIO_PIN_PDN)));
1066+ }
1067+
1068+ zy_ac97_acodec_read(p_device_context, GPIO_PIN_STATUS, &event_state);
1069+ return;
1070+}
1071+
1072+static void * p_saved_memory = NULL;
1073+static void * p_zy_scenario = NULL;
1074+static p_zy_acocec_context_t p_zy_ctxt = NULL;
1075+
1076+#define WM9713_SAVE_REGISTER_NO (64-11)
1077+typedef struct {
1078+ unsigned short wm9713RegisterContext [WM9713_SAVE_REGISTER_NO + 1]; /* Fixed (data misalignment error) */
1079+}ZY_9713_CONTEXT_SAVE_T;
1080+
1081+
1082+/**
1083+ * alsa_prepare_for_zy - create and initialize the p_zy_acocec_context_t
1084+ * open the clock of data link
1085+ * @p_p_zy_ctxt: return the data structure p_zy_acocec_context_t
1086+ * return: 0 success ; -ENOMEM
1087+ **/
1088+int alsa_prepare_for_zy(p_zy_acocec_context_t * p_p_zy_ctxt)
1089+{
1090+ if (p_zy_ctxt) {
1091+ p_zy_ctxt->use_count++;
1092+ *p_p_zy_ctxt = p_zy_ctxt;
1093+ return 0;
1094+ }
1095+
1096+ p_zy_ctxt = kzalloc(sizeof(zy_acocec_context_t), GFP_KERNEL);
1097+ if (!p_zy_ctxt)
1098+ return -ENOMEM;
1099+
1100+ /* enable CLK_POUT as CODEC clock input */
1101+ OSCC |= 0x800;
1102+
1103+ p_saved_memory = kzalloc(sizeof(ZY_9713_CONTEXT_SAVE_T) +
1104+ sizeof(zy_ac97_save_context_t), GFP_KERNEL);
1105+ if (NULL == p_saved_memory) {
1106+ if (p_zy_ctxt)
1107+ kfree(p_zy_ctxt);
1108+ return -ENOMEM;
1109+ }
1110+
1111+ p_zy_ctxt->acodec_id = (zy_acodec_device_id_t) (WM_9713_ID);
1112+ p_zy_ctxt->use_count++;
1113+ /*
1114+ p_zy_ctxt->pMfpRegBase = (unsigned long) (MFP_BASE);
1115+ p_zy_ctxt->pMfpRmDb = ZY_MFP_RM_DATABASE;
1116+ p_zy_ctxt->p_ost_regs = OST_BASE;
1117+ */
1118+ p_zy_ctxt->p_voice_reg = NULL;
1119+ p_zy_ctxt->p_hifi_reg = (void *) (&POCR);
1120+ p_zy_ctxt->p_ctrl_reg = (void *) (&POCR);
1121+ p_zy_ctxt->u_max_read_write_time_out_ms = ZY_AC97_RW_TIMEOUT_DEF;
1122+ p_zy_ctxt->u_max_setup_time_out_ms = ZY_AC97_SETUP_TIMEOUT_DEF;
1123+ p_zy_ctxt->p_save_memory = p_saved_memory;
1124+ p_zy_ctxt->p_zy_scenario = p_zy_scenario;
1125+// pxa_set_cken(24, 1);
1126+ CKENA |= (1 << 24);
1127+ AC97_DIV = 1625<<12 | 128;
1128+#ifdef DEBUG_ALSA_ZY
1129+ debug_pac97ctxt = p_zy_ctxt;
1130+ misc_register(&audio_dev);
1131+#endif
1132+
1133+ (*p_p_zy_ctxt) = p_zy_ctxt;
1134+
1135+ return 0;
1136+}
1137+
1138+
1139+/* this is platform specific */
1140+/* do later: not to enable recording route and playback route in this function,
1141+ * leave it to driver to call other function
1142+ */
1143+zy_acodec_error_t zy_wm9713_specific_init (zy_acocec_context_t *p_device_context)
1144+{
1145+
1146+ unsigned short value;
1147+
1148+ /* this assumes that the aclink is initialized wait some time and then
1149+ * do a warm reset to enabled the ACLINK, required for wm9713
1150+ * (not wm9712 or ucb1400)
1151+ */
1152+
1153+ /* pay attention: whether the workaround is still needed? */
1154+ p_zy_ac97acodec_t p_ac97_reg = (p_zy_ac97acodec_t)(p_device_context->p_ctrl_reg);
1155+
1156+ p_ac97_reg->gcr |= ZY_AC97_GCR_WARM_RESET_MSK;
1157+
1158+ mdelay(5);
1159+
1160+ /* power on all the necessary unit */
1161+ zy_ac97_acodec_write(p_device_context,POWERDOWN_CTRL_STAT, 0x000); /*26*/
1162+ /* open left headphone mixer */
1163+ /* open right headphone mixer */
1164+ /* open right/left dac */
1165+ /* open right/left adc */
1166+ /* open temperature sensor */
1167+ /* enable reference generator */
1168+ zy_ac97_acodec_write(p_device_context,POWER_DOWN_1, 0xda00); /*3c */
1169+ /* open microphone bias */
1170+ /* open HPL output PGA */
1171+ /* open HPR output PGA */
1172+ /* open mic PGA MA */
1173+ /* open mic pre-amp MPA */
1174+ /* if here we enable SPKL and SPKR PGA, then Touch screen will doesn't work */
1175+ zy_ac97_acodec_write(p_device_context,POWER_DOWN_2,0xb9f5); /*3e */
1176+
1177+ /* recording route and microphone input */
1178+ /* microphone selection, now fixed to MIC1 input and mic bias output */
1179+ /* MIC1 only, MICBIAS enable */
1180+ zy_ac97_acodec_write (p_device_context, MIC_BIAS, 0xC440); /*0x22h*/
1181+
1182+ /* mic pga setting to mixer (side tone) */
1183+ /* comment the below code to make MICA/B play back volume gain + 0db */
1184+ /* zy_ac97_acodec_write (p_device_context, MIC_PGA_VOLUME, 0x0000); */ /*0x0eh*/
1185+
1186+ /* recording side tone and ADC boost, now fixed to default (14h) */
1187+ /* recording volume 0dB */
1188+ zy_ac97_acodec_write(p_device_context, REC_PGA_VOL, 0x0); /*12*/
1189+
1190+ /* hifi playback route and output mixer */
1191+ /* by default, fixed to enable headphone only */
1192+
1193+ /* comment the below code to make SPEAKER default MUTE */
1194+ zy_ac97_acodec_write (p_device_context, SPEAKER_VOLUME, 0x0); /*02*/
1195+
1196+ /* comment the below code to make OUT3_OUT4 default MUTE */
1197+ /* zy_ac97_acodec_write (p_device_context, OUT3_OUT4_VOLUME, 0x8000); */ /*06*/
1198+
1199+ /* remove all the mute bit volume gain + 0db */
1200+ zy_ac97_acodec_write(p_device_context, HEADPHONE_VOLUME, 0x0); /*04*/
1201+
1202+ /* DAC route */
1203+ /* open DAC to headphone mixer path */
1204+ /* left DAC gain +0db */
1205+ /* right DAC gain +0db */
1206+ zy_ac97_acodec_write(p_device_context, DAC_PGA_VOL_ROUTE,0x0808); /*0c*/
1207+
1208+ /* out3 configure, invert to HPMIXR */
1209+ /* zy_ac97_acodec_write(p_device_context,DAC_3D_CTRL_INV_MUX_SEL, 0x8000); */ /*1e*/
1210+
1211+ /* output control */
1212+ /* select HPMIXR HPMIXL out */
1213+ /* other out are all VIM */
1214+ zy_ac97_acodec_write(p_device_context,OUTPUT_PGA_MUX, 0x9BA8); /*1c*/
1215+
1216+ /* set sample rates */
1217+ /* enable variable rate conversion */
1218+ zy_ac97_acodec_write(p_device_context, EXTENDED_AUD_STAT_CTRL , 0x1); /*2a*/
1219+ /* DAC 44kHZ */
1220+ zy_ac97_acodec_write(p_device_context,AUDIO_DAC_RATE,0xac44); /*2c*/
1221+ /* ADC 16KHZ */
1222+ zy_ac97_acodec_write(p_device_context,AUDIO_ADC_RATE,0x3E80); /*32*/
1223+
1224+ /* clock scheme, use external clock, it is 24MHZ from MCLK_A */
1225+
1226+
1227+ zy_ac97_acodec_read(p_device_context, MCLK_PLL_CTRL_1, &value);
1228+ zy_ac97_acodec_write(p_device_context, MCLK_PLL_CTRL_1, value | 0x2);
1229+
1230+ return ZY_ACODEC_SUCCESS;
1231+}
1232+
1233+zy_acodec_error_t zy_wm9713_specific_deinit (zy_acocec_context_t *p_device_context)
1234+{/* do later: shut down all power */
1235+ unsigned short value = 0;
1236+
1237+ /* close the power of all units */
1238+ zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, 0xffff);
1239+ zy_ac97_acodec_write(p_device_context, POWER_DOWN_2, 0xffff);
1240+ zy_ac97_acodec_read(p_device_context, POWER_DOWN_1, &value);
1241+ value &= ~(ZY_AC97_9713_PWR_MBIAS);
1242+ zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, value);
1243+
1244+ return ZY_ACODEC_SUCCESS;
1245+}
1246+
1247+zy_acodec_error_t zy_acodec_set_pen_down_interrupt(zy_acocec_context_t *p_device_context, int enable)
1248+{/* disable/enable pen down interrupt in the codec. This function is not implemented for Wm9713 */
1249+ /* because the pen down detection could not be disabled in codec */
1250+ return ZY_ACODEC_SUCCESS;
1251+}
1252+
1253+zy_acodec_error_t zy_wm9713_enable_touch(zy_acocec_context_t *p_device_context)
1254+{/* enable touch functionality in the codec */
1255+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
1256+ unsigned short value;
1257+
1258+ /* power setting */
1259+ status = zy_ac97_acodec_read(p_device_context, POWER_DOWN_1, &value);
1260+ value &= ~(ZY_AC97_9713_PWR_PADCPD);
1261+ status = zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, value);
1262+
1263+ /* basic touch setting */
1264+ status = zy_ac97_acodec_write(p_device_context, DIGITIZER_3_WM13, 0xc008);
1265+ status = zy_ac97_acodec_write(p_device_context, DIGITIZER_2_WM13, 0x6);
1266+
1267+
1268+ /* 9713 powerdown virtual gpio setting (polarity, sticky, wakeup) */
1269+ /* 9713 gpio 2(pin45) route to IRQ */
1270+ /* Notes: Can use defaults for IRQ polarity, PENDOWN polarity in IRQ, */
1271+ /* sticky for PENDOWN in IRQ and wakeup for PENDOWN. */
1272+ status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_CFG, &value);
1273+ value &= ~(0x4);
1274+ status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_CFG, value);
1275+
1276+ status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_SHARING, &value);
1277+ value &= ~(0x4);
1278+ status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_SHARING, value);
1279+
1280+ status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_WAKEUP, &value);
1281+ value |= (0x2000);
1282+ status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_WAKEUP, value);
1283+
1284+ status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_STICKY, &value);
1285+ value |= (0x2000);
1286+ status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_STICKY, value);
1287+
1288+ return status;
1289+}
1290+
1291+zy_acodec_error_t zy_wm9713_disable_touch(zy_acocec_context_t *p_device_context)
1292+{/* disable touch functionality in the codec */
1293+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
1294+ unsigned short value;
1295+
1296+ /* power setting */
1297+ status = zy_ac97_acodec_read(p_device_context, POWER_DOWN_1, &value);
1298+ value |= (ZY_AC97_9713_PWR_PADCPD);
1299+ status = zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, value);
1300+
1301+ return status;
1302+}
1303+zy_acodec_error_t zy_ac97_acodec_mfp_deinit(zy_acocec_context_t *p_device_context)
1304+{/* do later: free all MFP resources. */
1305+ return ZY_ACODEC_SUCCESS;
1306+}
1307+
1308+static zy_acodec_error_t zy_ac97_acodec_shut_down_aclink(p_zy_ac97acodec_t p_ac97_reg, int * p_ost_regs)
1309+{
1310+ zy_acodec_error_t status = ZY_ACODEC_SUCCESS;
1311+ unsigned long time_remaining = ZY_AC97_LINKOFF_TIMEOUT_DEF;
1312+
1313+ p_ac97_reg->gcr |= ZY_AC97_GCR_LINK_OFF_MSK;
1314+ p_ac97_reg->gcr |= ZY_AC97_GCR_CLKBPB_MSK;
1315+
1316+ while (!(p_ac97_reg->gsr & ZY_AC97_GSR_ACOFFD_MSK))
1317+ {
1318+ time_remaining --;
1319+ if (0 == time_remaining)
1320+ {
1321+ status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT;
1322+ break;
1323+ }
1324+ udelay(1);
1325+ }
1326+ p_ac97_reg->gcr |= ZY_AC97_GCR_FRCRST_MSK;
1327+ /* check later: any delay needed */
1328+ p_ac97_reg->gcr &= ~ZY_AC97_GCR_FRCRST_MSK;
1329+ p_ac97_reg->gcr &= ~ZY_AC97_GCR_CLKBPB_MSK;
1330+
1331+ return(status);
1332+}
1333+
1334+
1335+zy_acodec_error_t zy_ac97_acodec_deinit(zy_acocec_context_t * p_ac97_ctxt)
1336+{
1337+ zy_acodec_error_t status ;
1338+
1339+ status = zy_ac97_acodec_shut_down_aclink((p_zy_ac97acodec_t)(p_ac97_ctxt->p_ctrl_reg), p_ac97_ctxt->p_ost_regs);
1340+
1341+ return (status);
1342+}
1343+
1344+zy_acodec_error_t zy_acodec_deinit(zy_acocec_context_t *p_device_context)
1345+{
1346+ /* power down codec by codec specific power down function */
1347+ if (p_device_context->g_pfn_codec_specific_dinit)
1348+ {
1349+ p_device_context->g_pfn_codec_specific_dinit(p_device_context);
1350+ }
1351+ /* call bus deinit function */
1352+ zy_ac97_acodec_deinit(p_device_context);
1353+ /* restore MFP, set GPIO to suitable value */
1354+ zy_ac97_acodec_mfp_deinit(p_device_context);
1355+
1356+ return ZY_ACODEC_SUCCESS;
1357+}
1358+
1359+void alsa_zy_codec_put(p_zy_acocec_context_t p_acodectxt)
1360+{
1361+
1362+ zy_acodec_deinit(p_acodectxt);
1363+ //pxa_set_cken(24, 0);
1364+ CKENA &= ~(1 << 24);
1365+
1366+ if(p_acodectxt->p_save_memory){
1367+ kfree(p_saved_memory);
1368+ }
1369+ if(p_acodectxt->p_zy_scenario){
1370+ kfree(p_zy_scenario);
1371+ }
1372+}
1373+
1374+
1375+zy_acodec_error_t zy_acodec_init(zy_acocec_context_t *p_device_context, int hw_init)
1376+{
1377+ /* set codec specific functions
1378+ * set mfp for Zylonite platform
1379+ * call bus init function (AC97, I2S, I2C, SSP)
1380+ * call specific init of codec
1381+ */
1382+ zy_acodec_error_t retval = ZY_ACODEC_SUCCESS;
1383+
1384+ if (p_device_context->acodec_id != WM_9713_ID)
1385+ {/* on Zylonite, it is Wolfson 9713 codec only */
1386+ return ZY_ACODEC_GENERAL_SW_ERR;
1387+ }
1388+
1389+ if (1 == hw_init)
1390+ {
1391+ zy_ac97_acodec_mfp_init(p_device_context);
1392+ zy_ac97_acodec_init(p_device_context); /* codec init common to ac97 */
1393+ }
1394+
1395+ /* wm9713-specific functions */
1396+ (p_device_context->g_pfn_codec_specific_init) = zy_wm9713_specific_init;
1397+ (p_device_context->g_pfn_codec_specific_dinit) = zy_wm9713_specific_deinit;
1398+ (p_device_context->g_pfn_acodec_read) = zy_ac97_acodec_read;
1399+ (p_device_context->g_pfn_acodec_write) = zy_ac97_acodec_write;
1400+
1401+ (p_device_context->g_pfn_event_ack) = zy_wm9713_event_ack;
1402+ (p_device_context->g_pfn_get_event) = zy_wm9713_get_event;
1403+ (p_device_context->g_pfn_disable_touch) = zy_wm9713_disable_touch;
1404+ (p_device_context->g_pfn_enable_touch) = zy_wm9713_enable_touch;
1405+
1406+ if (1 == hw_init)
1407+ {
1408+ retval = p_device_context->g_pfn_codec_specific_init(p_device_context);
1409+ }
1410+
1411+ return retval;
1412+}
1413+
1414+static int __devinit touch_codec_zy_probe(struct platform_device *dev)
1415+{
1416+ int ret = 0;
1417+ struct snd_card *card = NULL;
1418+ zy_acodec_error_t status;
1419+
1420+ /* will increase codec context use count */
1421+ ret = alsa_prepare_for_zy(&p_zy_codec_ctxt);
1422+ if (ret)
1423+ goto err;
1424+
1425+ /* codec specific initialization, audio will do it either */
1426+ if (1 == p_zy_codec_ctxt->use_count) {
1427+ status = zy_acodec_init(p_zy_codec_ctxt, 1);
1428+ if (ZY_ACODEC_SUCCESS != status) {
1429+ printk(KERN_ERR "initialize codec error\n");
1430+ ret = -EIO;
1431+ goto err;
1432+ }
1433+
1434+ /* power down the units of the acodec, sleep the acodec, zy_acodec_init()
1435+ * will open all the units' power of the codec while ALSA need all the codec
1436+ * units power down and the codec should sleep if it can.
1437+ * So on the zylonite platform we call below function to power down and sleep
1438+ * wm9713 codec.
1439+ */
1440+ p_zy_codec_ctxt->g_pfn_codec_specific_dinit(p_zy_codec_ctxt);
1441+
1442+ }
1443+
1444+ alsa_ts_init();
1445+
1446+ //mhn_mfp_set_afds(MFP_AC97_INT_N_GPIO,0,0);
1447+ //mhn_gpio_set_direction(MFP_AC97_INT_N_GPIO, GPIO_DIR_IN);
1448+ //mhn_gpio_clear_edge_detect_status(MFP_AC97_INT_N_GPIO);
1449+ gpio_direction_input(mfp_to_gpio(MFP_PIN_GPIO26));
1450+ ret = request_irq(IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO26)),
1451+ pxa_touch_irq, IRQF_TRIGGER_RISING,
1452+ "wm9713 touch event interrupt", NULL);
1453+ if (ret) {
1454+ printk(KERN_ERR "Request IRQ for touch failed (%d).\n", ret);
1455+ goto err;
1456+ }
1457+
1458+ return 0;
1459+err:
1460+ if (p_zy_codec_ctxt && (!--p_zy_codec_ctxt->use_count)) {
1461+ zy_acodec_deinit(p_zy_codec_ctxt);
1462+ //pxa_set_cken(24, 0);
1463+ CKENA &= ~(1 << 24);
1464+ kfree(p_zy_codec_ctxt);
1465+ p_zy_codec_ctxt = NULL;
1466+ }
1467+
1468+ if (card)
1469+ snd_card_free(card);
1470+
1471+ return ret;
1472+}
1473+
1474+static int __devexit touch_codec_zy_remove(struct platform_device *dev)
1475+{
1476+ struct snd_card *card = platform_get_drvdata(dev);
1477+
1478+ input_unregister_device(codec_zy_ts_input);
1479+
1480+ if (p_zy_codec_ctxt && (!--p_zy_codec_ctxt->use_count)) {
1481+ alsa_zy_codec_put(p_zy_codec_ctxt);
1482+ kfree(p_zy_codec_ctxt);
1483+ p_zy_codec_ctxt = NULL;
1484+ }
1485+
1486+ if (card) {
1487+ snd_card_free(card);
1488+ platform_set_drvdata(dev, NULL);
1489+ }
1490+
1491+ return 0;
1492+}
1493+
1494+#ifdef CONFIG_PM
1495+static int touch_codec_zy_suspend(struct platform_device *_dev, pm_message_t state, u32 level)
1496+{
1497+ int ret=0;
1498+
1499+ if (level == SUSPEND_DISABLE) {
1500+ ret = audio_codec_zy_do_suspend(NULL, SNDRV_CTL_POWER_D3cold, p_zy_codec_ctxt);
1501+ touch_suspend = 1;
1502+ }
1503+ return ret;
1504+}
1505+
1506+static int touch_codec_zy_resume(struct platform_device *_dev, u32 level)
1507+{
1508+ int ret = 0;
1509+
1510+ if (level == RESUME_ENABLE) {
1511+ ret = audio_codec_zy_do_resume(NULL, SNDRV_CTL_POWER_D0, p_zy_codec_ctxt);
1512+ touch_suspend = 0;
1513+ }
1514+ return ret;
1515+}
1516+#else
1517+#define touch_codec_zy_suspend NULL
1518+#define touch_codec_zy_resume NULL
1519+#endif
1520+
1521+static struct platform_driver touch_codec_zy_driver = {
1522+ .probe = touch_codec_zy_probe,
1523+ .remove = __devexit_p(touch_codec_zy_remove),
1524+ .suspend= touch_codec_zy_suspend,
1525+ .resume = touch_codec_zy_resume,
1526+ .driver = {
1527+ .name = "pxa2xx-touch",
1528+ },
1529+};
1530+
1531+static int __init touch_codec_zy_init(void)
1532+{
1533+ return platform_driver_register(&touch_codec_zy_driver);
1534+}
1535+
1536+static void __exit touch_code_zy_exit(void)
1537+{
1538+ platform_driver_unregister(&touch_codec_zy_driver);
1539+}
1540+module_init(touch_codec_zy_init);
1541+module_exit(touch_code_zy_exit);
1542+
1543+EXPORT_SYMBOL(p_zy_codec_ctxt);
1544+
1545+MODULE_AUTHOR("bridge.wu@marvell.com");
1546+MODULE_DESCRIPTION("zylonite audio touch codec driver on ALSA");
1547+MODULE_LICENSE("GPL");
1548+